/ src / context.py
context.py
 1  from __future__ import annotations
 2  
 3  from dataclasses import dataclass
 4  from pathlib import Path
 5  
 6  
 7  @dataclass(frozen=True)
 8  class PortContext:
 9      source_root: Path
10      tests_root: Path
11      assets_root: Path
12      archive_root: Path
13      python_file_count: int
14      test_file_count: int
15      asset_file_count: int
16      archive_available: bool
17  
18  
19  def build_port_context(base: Path | None = None) -> PortContext:
20      root = base or Path(__file__).resolve().parent.parent
21      source_root = root / 'src'
22      tests_root = root / 'tests'
23      assets_root = root / 'assets'
24      archive_root = root / 'archive' / 'claw_code_ts_snapshot' / 'src'
25      return PortContext(
26          source_root=source_root,
27          tests_root=tests_root,
28          assets_root=assets_root,
29          archive_root=archive_root,
30          python_file_count=sum(1 for path in source_root.rglob('*.py') if path.is_file()),
31          test_file_count=sum(1 for path in tests_root.rglob('*.py') if path.is_file()),
32          asset_file_count=sum(1 for path in assets_root.rglob('*') if path.is_file()),
33          archive_available=archive_root.exists(),
34      )
35  
36  
37  def render_context(context: PortContext) -> str:
38      return '\n'.join([
39          f'Source root: {context.source_root}',
40          f'Test root: {context.tests_root}',
41          f'Assets root: {context.assets_root}',
42          f'Archive root: {context.archive_root}',
43          f'Python files: {context.python_file_count}',
44          f'Test files: {context.test_file_count}',
45          f'Assets: {context.asset_file_count}',
46          f'Archive available: {context.archive_available}',
47      ])