diff --git a/src/QueryEngine.py b/src/QueryEngine.py new file mode 100644 index 0000000..a9684d5 --- /dev/null +++ b/src/QueryEngine.py @@ -0,0 +1,19 @@ +from __future__ import annotations + +from .query_engine import QueryEnginePort +from .runtime import PortRuntime + + +class QueryEngineRuntime(QueryEnginePort): + def route(self, prompt: str, limit: int = 5) -> str: + matches = PortRuntime().route_prompt(prompt, limit=limit) + lines = ['# Query Engine Route', '', f'Prompt: {prompt}', ''] + if not matches: + lines.append('No mirrored command/tool matches found.') + return '\n'.join(lines) + lines.append('Matches:') + lines.extend(f'- [{match.kind}] {match.name} ({match.score}) — {match.source_hint}' for match in matches) + return '\n'.join(lines) + + +__all__ = ['QueryEnginePort', 'QueryEngineRuntime'] diff --git a/src/Tool.py b/src/Tool.py new file mode 100644 index 0000000..16b77aa --- /dev/null +++ b/src/Tool.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class ToolDefinition: + name: str + purpose: str + + +DEFAULT_TOOLS = ( + ToolDefinition('port_manifest', 'Summarize the active Python workspace'), + ToolDefinition('query_engine', 'Render a Python-first porting summary'), +) diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..1360a1c --- /dev/null +++ b/src/__init__.py @@ -0,0 +1,29 @@ +"""Python porting workspace for the Claw Code rewrite effort.""" + +from .commands import PORTED_COMMANDS, build_command_backlog +from .parity_audit import ParityAuditResult, run_parity_audit +from .port_manifest import PortManifest, build_port_manifest +from .query_engine import QueryEnginePort, TurnResult +from .runtime import PortRuntime, RuntimeSession +from .session_store import StoredSession, load_session, save_session +from .system_init import build_system_init_message +from .tools import PORTED_TOOLS, build_tool_backlog + +__all__ = [ + 'ParityAuditResult', + 'PortManifest', + 'PortRuntime', + 'QueryEnginePort', + 'RuntimeSession', + 'StoredSession', + 'TurnResult', + 'PORTED_COMMANDS', + 'PORTED_TOOLS', + 'build_command_backlog', + 'build_port_manifest', + 'build_system_init_message', + 'build_tool_backlog', + 'load_session', + 'run_parity_audit', + 'save_session', +] diff --git a/src/assistant/__init__.py b/src/assistant/__init__.py new file mode 100644 index 0000000..a41389e --- /dev/null +++ b/src/assistant/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `assistant` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'assistant.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/bootstrap/__init__.py b/src/bootstrap/__init__.py new file mode 100644 index 0000000..133345e --- /dev/null +++ b/src/bootstrap/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `bootstrap` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'bootstrap.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/bootstrap_graph.py b/src/bootstrap_graph.py new file mode 100644 index 0000000..a716e83 --- /dev/null +++ b/src/bootstrap_graph.py @@ -0,0 +1,27 @@ +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class BootstrapGraph: + stages: tuple[str, ...] + + def as_markdown(self) -> str: + lines = ['# Bootstrap Graph', ''] + lines.extend(f'- {stage}' for stage in self.stages) + return '\n'.join(lines) + + +def build_bootstrap_graph() -> BootstrapGraph: + return BootstrapGraph( + stages=( + 'top-level prefetch side effects', + 'warning handler and environment guards', + 'CLI parser and pre-action trust gate', + 'setup() + commands/agents parallel load', + 'deferred init after trust', + 'mode routing: local / remote / ssh / teleport / direct-connect / deep-link', + 'query engine submit loop', + ) + ) diff --git a/src/bridge/__init__.py b/src/bridge/__init__.py new file mode 100644 index 0000000..43f54f0 --- /dev/null +++ b/src/bridge/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `bridge` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'bridge.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/buddy/__init__.py b/src/buddy/__init__.py new file mode 100644 index 0000000..88ce77d --- /dev/null +++ b/src/buddy/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `buddy` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'buddy.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/cli/__init__.py b/src/cli/__init__.py new file mode 100644 index 0000000..9142899 --- /dev/null +++ b/src/cli/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `cli` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'cli.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/command_graph.py b/src/command_graph.py new file mode 100644 index 0000000..20ef859 --- /dev/null +++ b/src/command_graph.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from .commands import get_commands +from .models import PortingModule + + +@dataclass(frozen=True) +class CommandGraph: + builtins: tuple[PortingModule, ...] + plugin_like: tuple[PortingModule, ...] + skill_like: tuple[PortingModule, ...] + + def flattened(self) -> tuple[PortingModule, ...]: + return self.builtins + self.plugin_like + self.skill_like + + def as_markdown(self) -> str: + lines = [ + '# Command Graph', + '', + f'Builtins: {len(self.builtins)}', + f'Plugin-like commands: {len(self.plugin_like)}', + f'Skill-like commands: {len(self.skill_like)}', + ] + return '\n'.join(lines) + + +def build_command_graph() -> CommandGraph: + commands = get_commands() + builtins = tuple(module for module in commands if 'plugin' not in module.source_hint.lower() and 'skills' not in module.source_hint.lower()) + plugin_like = tuple(module for module in commands if 'plugin' in module.source_hint.lower()) + skill_like = tuple(module for module in commands if 'skills' in module.source_hint.lower()) + return CommandGraph(builtins=builtins, plugin_like=plugin_like, skill_like=skill_like) diff --git a/src/commands.py b/src/commands.py new file mode 100644 index 0000000..b327977 --- /dev/null +++ b/src/commands.py @@ -0,0 +1,90 @@ +from __future__ import annotations + +import json +from dataclasses import dataclass +from functools import lru_cache +from pathlib import Path + +from .models import PortingBacklog, PortingModule + +SNAPSHOT_PATH = Path(__file__).resolve().parent / 'reference_data' / 'commands_snapshot.json' + + +@dataclass(frozen=True) +class CommandExecution: + name: str + source_hint: str + prompt: str + handled: bool + message: str + + +@lru_cache(maxsize=1) +def load_command_snapshot() -> tuple[PortingModule, ...]: + raw_entries = json.loads(SNAPSHOT_PATH.read_text()) + return tuple( + PortingModule( + name=entry['name'], + responsibility=entry['responsibility'], + source_hint=entry['source_hint'], + status='mirrored', + ) + for entry in raw_entries + ) + + +PORTED_COMMANDS = load_command_snapshot() + + +@lru_cache(maxsize=1) +def built_in_command_names() -> frozenset[str]: + return frozenset(module.name for module in PORTED_COMMANDS) + + +def build_command_backlog() -> PortingBacklog: + return PortingBacklog(title='Command surface', modules=list(PORTED_COMMANDS)) + + +def command_names() -> list[str]: + return [module.name for module in PORTED_COMMANDS] + + +def get_command(name: str) -> PortingModule | None: + needle = name.lower() + for module in PORTED_COMMANDS: + if module.name.lower() == needle: + return module + return None + + +def get_commands(cwd: str | None = None, include_plugin_commands: bool = True, include_skill_commands: bool = True) -> tuple[PortingModule, ...]: + commands = list(PORTED_COMMANDS) + if not include_plugin_commands: + commands = [module for module in commands if 'plugin' not in module.source_hint.lower()] + if not include_skill_commands: + commands = [module for module in commands if 'skills' not in module.source_hint.lower()] + return tuple(commands) + + +def find_commands(query: str, limit: int = 20) -> list[PortingModule]: + needle = query.lower() + matches = [module for module in PORTED_COMMANDS if needle in module.name.lower() or needle in module.source_hint.lower()] + return matches[:limit] + + +def execute_command(name: str, prompt: str = '') -> CommandExecution: + module = get_command(name) + if module is None: + return CommandExecution(name=name, source_hint='', prompt=prompt, handled=False, message=f'Unknown mirrored command: {name}') + action = f"Mirrored command '{module.name}' from {module.source_hint} would handle prompt {prompt!r}." + return CommandExecution(name=module.name, source_hint=module.source_hint, prompt=prompt, handled=True, message=action) + + +def render_command_index(limit: int = 20, query: str | None = None) -> str: + modules = find_commands(query, limit) if query else list(PORTED_COMMANDS[:limit]) + lines = [f'Command entries: {len(PORTED_COMMANDS)}', ''] + if query: + lines.append(f'Filtered by: {query}') + lines.append('') + lines.extend(f'- {module.name} — {module.source_hint}' for module in modules) + return '\n'.join(lines) diff --git a/src/components/__init__.py b/src/components/__init__.py new file mode 100644 index 0000000..68bd81d --- /dev/null +++ b/src/components/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `components` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'components.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/constants/__init__.py b/src/constants/__init__.py new file mode 100644 index 0000000..4d1f46d --- /dev/null +++ b/src/constants/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `constants` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'constants.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/context.py b/src/context.py new file mode 100644 index 0000000..e208fcd --- /dev/null +++ b/src/context.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +from dataclasses import dataclass +from pathlib import Path + + +@dataclass(frozen=True) +class PortContext: + source_root: Path + tests_root: Path + assets_root: Path + archive_root: Path + python_file_count: int + test_file_count: int + asset_file_count: int + archive_available: bool + + +def build_port_context(base: Path | None = None) -> PortContext: + root = base or Path(__file__).resolve().parent.parent + source_root = root / 'src' + tests_root = root / 'tests' + assets_root = root / 'assets' + archive_root = root / 'archive' / 'claw_code_ts_snapshot' / 'src' + return PortContext( + source_root=source_root, + tests_root=tests_root, + assets_root=assets_root, + archive_root=archive_root, + python_file_count=sum(1 for path in source_root.rglob('*.py') if path.is_file()), + test_file_count=sum(1 for path in tests_root.rglob('*.py') if path.is_file()), + asset_file_count=sum(1 for path in assets_root.rglob('*') if path.is_file()), + archive_available=archive_root.exists(), + ) + + +def render_context(context: PortContext) -> str: + return '\n'.join([ + f'Source root: {context.source_root}', + f'Test root: {context.tests_root}', + f'Assets root: {context.assets_root}', + f'Archive root: {context.archive_root}', + f'Python files: {context.python_file_count}', + f'Test files: {context.test_file_count}', + f'Assets: {context.asset_file_count}', + f'Archive available: {context.archive_available}', + ]) diff --git a/src/coordinator/__init__.py b/src/coordinator/__init__.py new file mode 100644 index 0000000..65a77d3 --- /dev/null +++ b/src/coordinator/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `coordinator` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'coordinator.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/costHook.py b/src/costHook.py new file mode 100644 index 0000000..85c9e02 --- /dev/null +++ b/src/costHook.py @@ -0,0 +1,8 @@ +from __future__ import annotations + +from .cost_tracker import CostTracker + + +def apply_cost_hook(tracker: CostTracker, label: str, units: int) -> CostTracker: + tracker.record(label, units) + return tracker diff --git a/src/cost_tracker.py b/src/cost_tracker.py new file mode 100644 index 0000000..6f95f50 --- /dev/null +++ b/src/cost_tracker.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +from dataclasses import dataclass, field + + +@dataclass +class CostTracker: + total_units: int = 0 + events: list[str] = field(default_factory=list) + + def record(self, label: str, units: int) -> None: + self.total_units += units + self.events.append(f'{label}:{units}') diff --git a/src/deferred_init.py b/src/deferred_init.py new file mode 100644 index 0000000..35eef40 --- /dev/null +++ b/src/deferred_init.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class DeferredInitResult: + trusted: bool + plugin_init: bool + skill_init: bool + mcp_prefetch: bool + session_hooks: bool + + def as_lines(self) -> tuple[str, ...]: + return ( + f'- plugin_init={self.plugin_init}', + f'- skill_init={self.skill_init}', + f'- mcp_prefetch={self.mcp_prefetch}', + f'- session_hooks={self.session_hooks}', + ) + + +def run_deferred_init(trusted: bool) -> DeferredInitResult: + enabled = bool(trusted) + return DeferredInitResult( + trusted=trusted, + plugin_init=enabled, + skill_init=enabled, + mcp_prefetch=enabled, + session_hooks=enabled, + ) diff --git a/src/dialogLaunchers.py b/src/dialogLaunchers.py new file mode 100644 index 0000000..78588c3 --- /dev/null +++ b/src/dialogLaunchers.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class DialogLauncher: + name: str + description: str + + +DEFAULT_DIALOGS = ( + DialogLauncher('summary', 'Launch the Markdown summary view'), + DialogLauncher('parity_audit', 'Launch the parity audit view'), +) diff --git a/src/direct_modes.py b/src/direct_modes.py new file mode 100644 index 0000000..883f94a --- /dev/null +++ b/src/direct_modes.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class DirectModeReport: + mode: str + target: str + active: bool + + def as_text(self) -> str: + return f'mode={self.mode}\ntarget={self.target}\nactive={self.active}' + + +def run_direct_connect(target: str) -> DirectModeReport: + return DirectModeReport(mode='direct-connect', target=target, active=True) + + +def run_deep_link(target: str) -> DirectModeReport: + return DirectModeReport(mode='deep-link', target=target, active=True) diff --git a/src/entrypoints/__init__.py b/src/entrypoints/__init__.py new file mode 100644 index 0000000..3b0a590 --- /dev/null +++ b/src/entrypoints/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `entrypoints` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'entrypoints.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/execution_registry.py b/src/execution_registry.py new file mode 100644 index 0000000..953d46a --- /dev/null +++ b/src/execution_registry.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from .commands import PORTED_COMMANDS, execute_command +from .tools import PORTED_TOOLS, execute_tool + + +@dataclass(frozen=True) +class MirroredCommand: + name: str + source_hint: str + + def execute(self, prompt: str) -> str: + return execute_command(self.name, prompt).message + + +@dataclass(frozen=True) +class MirroredTool: + name: str + source_hint: str + + def execute(self, payload: str) -> str: + return execute_tool(self.name, payload).message + + +@dataclass(frozen=True) +class ExecutionRegistry: + commands: tuple[MirroredCommand, ...] + tools: tuple[MirroredTool, ...] + + def command(self, name: str) -> MirroredCommand | None: + lowered = name.lower() + for command in self.commands: + if command.name.lower() == lowered: + return command + return None + + def tool(self, name: str) -> MirroredTool | None: + lowered = name.lower() + for tool in self.tools: + if tool.name.lower() == lowered: + return tool + return None + + +def build_execution_registry() -> ExecutionRegistry: + return ExecutionRegistry( + commands=tuple(MirroredCommand(module.name, module.source_hint) for module in PORTED_COMMANDS), + tools=tuple(MirroredTool(module.name, module.source_hint) for module in PORTED_TOOLS), + ) diff --git a/src/history.py b/src/history.py new file mode 100644 index 0000000..1d6823c --- /dev/null +++ b/src/history.py @@ -0,0 +1,22 @@ +from __future__ import annotations + +from dataclasses import dataclass, field + + +@dataclass(frozen=True) +class HistoryEvent: + title: str + detail: str + + +@dataclass +class HistoryLog: + events: list[HistoryEvent] = field(default_factory=list) + + def add(self, title: str, detail: str) -> None: + self.events.append(HistoryEvent(title=title, detail=detail)) + + def as_markdown(self) -> str: + lines = ['# Session History', ''] + lines.extend(f'- {event.title}: {event.detail}' for event in self.events) + return '\n'.join(lines) diff --git a/src/hooks/__init__.py b/src/hooks/__init__.py new file mode 100644 index 0000000..4379bbd --- /dev/null +++ b/src/hooks/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `hooks` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'hooks.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/ink.py b/src/ink.py new file mode 100644 index 0000000..6e32aa0 --- /dev/null +++ b/src/ink.py @@ -0,0 +1,6 @@ +from __future__ import annotations + + +def render_markdown_panel(text: str) -> str: + border = '=' * 40 + return f"{border}\n{text}\n{border}" diff --git a/src/interactiveHelpers.py b/src/interactiveHelpers.py new file mode 100644 index 0000000..f4f4d13 --- /dev/null +++ b/src/interactiveHelpers.py @@ -0,0 +1,5 @@ +from __future__ import annotations + + +def bulletize(items: list[str]) -> str: + return '\n'.join(f'- {item}' for item in items) diff --git a/src/keybindings/__init__.py b/src/keybindings/__init__.py new file mode 100644 index 0000000..6d26f3c --- /dev/null +++ b/src/keybindings/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `keybindings` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'keybindings.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..9d74335 --- /dev/null +++ b/src/main.py @@ -0,0 +1,213 @@ +from __future__ import annotations + +import argparse + +from .bootstrap_graph import build_bootstrap_graph +from .command_graph import build_command_graph +from .commands import execute_command, get_command, get_commands, render_command_index +from .direct_modes import run_deep_link, run_direct_connect +from .parity_audit import run_parity_audit +from .permissions import ToolPermissionContext +from .port_manifest import build_port_manifest +from .query_engine import QueryEnginePort +from .remote_runtime import run_remote_mode, run_ssh_mode, run_teleport_mode +from .runtime import PortRuntime +from .session_store import load_session +from .setup import run_setup +from .tool_pool import assemble_tool_pool +from .tools import execute_tool, get_tool, get_tools, render_tool_index + + +def build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser(description='Python porting workspace for the Claw Code rewrite effort') + subparsers = parser.add_subparsers(dest='command', required=True) + subparsers.add_parser('summary', help='render a Markdown summary of the Python porting workspace') + subparsers.add_parser('manifest', help='print the current Python workspace manifest') + subparsers.add_parser('parity-audit', help='compare the Python workspace against the local ignored TypeScript archive when available') + subparsers.add_parser('setup-report', help='render the startup/prefetch setup report') + subparsers.add_parser('command-graph', help='show command graph segmentation') + subparsers.add_parser('tool-pool', help='show assembled tool pool with default settings') + subparsers.add_parser('bootstrap-graph', help='show the mirrored bootstrap/runtime graph stages') + list_parser = subparsers.add_parser('subsystems', help='list the current Python modules in the workspace') + list_parser.add_argument('--limit', type=int, default=32) + + commands_parser = subparsers.add_parser('commands', help='list mirrored command entries from the archived snapshot') + commands_parser.add_argument('--limit', type=int, default=20) + commands_parser.add_argument('--query') + commands_parser.add_argument('--no-plugin-commands', action='store_true') + commands_parser.add_argument('--no-skill-commands', action='store_true') + + tools_parser = subparsers.add_parser('tools', help='list mirrored tool entries from the archived snapshot') + tools_parser.add_argument('--limit', type=int, default=20) + tools_parser.add_argument('--query') + tools_parser.add_argument('--simple-mode', action='store_true') + tools_parser.add_argument('--no-mcp', action='store_true') + tools_parser.add_argument('--deny-tool', action='append', default=[]) + tools_parser.add_argument('--deny-prefix', action='append', default=[]) + + route_parser = subparsers.add_parser('route', help='route a prompt across mirrored command/tool inventories') + route_parser.add_argument('prompt') + route_parser.add_argument('--limit', type=int, default=5) + + bootstrap_parser = subparsers.add_parser('bootstrap', help='build a runtime-style session report from the mirrored inventories') + bootstrap_parser.add_argument('prompt') + bootstrap_parser.add_argument('--limit', type=int, default=5) + + loop_parser = subparsers.add_parser('turn-loop', help='run a small stateful turn loop for the mirrored runtime') + loop_parser.add_argument('prompt') + loop_parser.add_argument('--limit', type=int, default=5) + loop_parser.add_argument('--max-turns', type=int, default=3) + loop_parser.add_argument('--structured-output', action='store_true') + + flush_parser = subparsers.add_parser('flush-transcript', help='persist and flush a temporary session transcript') + flush_parser.add_argument('prompt') + + load_session_parser = subparsers.add_parser('load-session', help='load a previously persisted session') + load_session_parser.add_argument('session_id') + + remote_parser = subparsers.add_parser('remote-mode', help='simulate remote-control runtime branching') + remote_parser.add_argument('target') + ssh_parser = subparsers.add_parser('ssh-mode', help='simulate SSH runtime branching') + ssh_parser.add_argument('target') + teleport_parser = subparsers.add_parser('teleport-mode', help='simulate teleport runtime branching') + teleport_parser.add_argument('target') + direct_parser = subparsers.add_parser('direct-connect-mode', help='simulate direct-connect runtime branching') + direct_parser.add_argument('target') + deep_link_parser = subparsers.add_parser('deep-link-mode', help='simulate deep-link runtime branching') + deep_link_parser.add_argument('target') + + show_command = subparsers.add_parser('show-command', help='show one mirrored command entry by exact name') + show_command.add_argument('name') + show_tool = subparsers.add_parser('show-tool', help='show one mirrored tool entry by exact name') + show_tool.add_argument('name') + + exec_command_parser = subparsers.add_parser('exec-command', help='execute a mirrored command shim by exact name') + exec_command_parser.add_argument('name') + exec_command_parser.add_argument('prompt') + + exec_tool_parser = subparsers.add_parser('exec-tool', help='execute a mirrored tool shim by exact name') + exec_tool_parser.add_argument('name') + exec_tool_parser.add_argument('payload') + return parser + + +def main(argv: list[str] | None = None) -> int: + parser = build_parser() + args = parser.parse_args(argv) + manifest = build_port_manifest() + if args.command == 'summary': + print(QueryEnginePort(manifest).render_summary()) + return 0 + if args.command == 'manifest': + print(manifest.to_markdown()) + return 0 + if args.command == 'parity-audit': + print(run_parity_audit().to_markdown()) + return 0 + if args.command == 'setup-report': + print(run_setup().as_markdown()) + return 0 + if args.command == 'command-graph': + print(build_command_graph().as_markdown()) + return 0 + if args.command == 'tool-pool': + print(assemble_tool_pool().as_markdown()) + return 0 + if args.command == 'bootstrap-graph': + print(build_bootstrap_graph().as_markdown()) + return 0 + if args.command == 'subsystems': + for subsystem in manifest.top_level_modules[: args.limit]: + print(f'{subsystem.name}\t{subsystem.file_count}\t{subsystem.notes}') + return 0 + if args.command == 'commands': + if args.query: + print(render_command_index(limit=args.limit, query=args.query)) + else: + commands = get_commands(include_plugin_commands=not args.no_plugin_commands, include_skill_commands=not args.no_skill_commands) + output_lines = [f'Command entries: {len(commands)}', ''] + output_lines.extend(f'- {module.name} — {module.source_hint}' for module in commands[: args.limit]) + print('\n'.join(output_lines)) + return 0 + if args.command == 'tools': + if args.query: + print(render_tool_index(limit=args.limit, query=args.query)) + else: + permission_context = ToolPermissionContext.from_iterables(args.deny_tool, args.deny_prefix) + tools = get_tools(simple_mode=args.simple_mode, include_mcp=not args.no_mcp, permission_context=permission_context) + output_lines = [f'Tool entries: {len(tools)}', ''] + output_lines.extend(f'- {module.name} — {module.source_hint}' for module in tools[: args.limit]) + print('\n'.join(output_lines)) + return 0 + if args.command == 'route': + matches = PortRuntime().route_prompt(args.prompt, limit=args.limit) + if not matches: + print('No mirrored command/tool matches found.') + return 0 + for match in matches: + print(f'{match.kind}\t{match.name}\t{match.score}\t{match.source_hint}') + return 0 + if args.command == 'bootstrap': + print(PortRuntime().bootstrap_session(args.prompt, limit=args.limit).as_markdown()) + return 0 + if args.command == 'turn-loop': + results = PortRuntime().run_turn_loop(args.prompt, limit=args.limit, max_turns=args.max_turns, structured_output=args.structured_output) + for idx, result in enumerate(results, start=1): + print(f'## Turn {idx}') + print(result.output) + print(f'stop_reason={result.stop_reason}') + return 0 + if args.command == 'flush-transcript': + engine = QueryEnginePort.from_workspace() + engine.submit_message(args.prompt) + path = engine.persist_session() + print(path) + print(f'flushed={engine.transcript_store.flushed}') + return 0 + if args.command == 'load-session': + session = load_session(args.session_id) + print(f'{session.session_id}\n{len(session.messages)} messages\nin={session.input_tokens} out={session.output_tokens}') + return 0 + if args.command == 'remote-mode': + print(run_remote_mode(args.target).as_text()) + return 0 + if args.command == 'ssh-mode': + print(run_ssh_mode(args.target).as_text()) + return 0 + if args.command == 'teleport-mode': + print(run_teleport_mode(args.target).as_text()) + return 0 + if args.command == 'direct-connect-mode': + print(run_direct_connect(args.target).as_text()) + return 0 + if args.command == 'deep-link-mode': + print(run_deep_link(args.target).as_text()) + return 0 + if args.command == 'show-command': + module = get_command(args.name) + if module is None: + print(f'Command not found: {args.name}') + return 1 + print('\n'.join([module.name, module.source_hint, module.responsibility])) + return 0 + if args.command == 'show-tool': + module = get_tool(args.name) + if module is None: + print(f'Tool not found: {args.name}') + return 1 + print('\n'.join([module.name, module.source_hint, module.responsibility])) + return 0 + if args.command == 'exec-command': + result = execute_command(args.name, args.prompt) + print(result.message) + return 0 if result.handled else 1 + if args.command == 'exec-tool': + result = execute_tool(args.name, args.payload) + print(result.message) + return 0 if result.handled else 1 + parser.error(f'unknown command: {args.command}') + return 2 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/src/memdir/__init__.py b/src/memdir/__init__.py new file mode 100644 index 0000000..f8f2e8a --- /dev/null +++ b/src/memdir/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `memdir` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'memdir.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/migrations/__init__.py b/src/migrations/__init__.py new file mode 100644 index 0000000..54f3005 --- /dev/null +++ b/src/migrations/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `migrations` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'migrations.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/models.py b/src/models.py new file mode 100644 index 0000000..d9fc277 --- /dev/null +++ b/src/models.py @@ -0,0 +1,49 @@ +from __future__ import annotations + +from dataclasses import dataclass, field + + +@dataclass(frozen=True) +class Subsystem: + name: str + path: str + file_count: int + notes: str + + +@dataclass(frozen=True) +class PortingModule: + name: str + responsibility: str + source_hint: str + status: str = 'planned' + + +@dataclass(frozen=True) +class PermissionDenial: + tool_name: str + reason: str + + +@dataclass(frozen=True) +class UsageSummary: + input_tokens: int = 0 + output_tokens: int = 0 + + def add_turn(self, prompt: str, output: str) -> 'UsageSummary': + return UsageSummary( + input_tokens=self.input_tokens + len(prompt.split()), + output_tokens=self.output_tokens + len(output.split()), + ) + + +@dataclass +class PortingBacklog: + title: str + modules: list[PortingModule] = field(default_factory=list) + + def summary_lines(self) -> list[str]: + return [ + f'- {module.name} [{module.status}] — {module.responsibility} (from {module.source_hint})' + for module in self.modules + ] diff --git a/src/moreright/__init__.py b/src/moreright/__init__.py new file mode 100644 index 0000000..79f34ad --- /dev/null +++ b/src/moreright/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `moreright` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'moreright.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/native_ts/__init__.py b/src/native_ts/__init__.py new file mode 100644 index 0000000..e3d22f5 --- /dev/null +++ b/src/native_ts/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `native-ts` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'native_ts.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/outputStyles/__init__.py b/src/outputStyles/__init__.py new file mode 100644 index 0000000..563f701 --- /dev/null +++ b/src/outputStyles/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `outputStyles` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'outputStyles.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/parity_audit.py b/src/parity_audit.py new file mode 100644 index 0000000..39230d9 --- /dev/null +++ b/src/parity_audit.py @@ -0,0 +1,138 @@ +from __future__ import annotations + +import json +from dataclasses import dataclass +from pathlib import Path + +ARCHIVE_ROOT = Path(__file__).resolve().parent.parent / 'archive' / 'claw_code_ts_snapshot' / 'src' +CURRENT_ROOT = Path(__file__).resolve().parent +REFERENCE_SURFACE_PATH = CURRENT_ROOT / 'reference_data' / 'archive_surface_snapshot.json' +COMMAND_SNAPSHOT_PATH = CURRENT_ROOT / 'reference_data' / 'commands_snapshot.json' +TOOL_SNAPSHOT_PATH = CURRENT_ROOT / 'reference_data' / 'tools_snapshot.json' + +ARCHIVE_ROOT_FILES = { + 'QueryEngine.ts': 'QueryEngine.py', + 'Task.ts': 'task.py', + 'Tool.ts': 'Tool.py', + 'commands.ts': 'commands.py', + 'context.ts': 'context.py', + 'cost-tracker.ts': 'cost_tracker.py', + 'costHook.ts': 'costHook.py', + 'dialogLaunchers.tsx': 'dialogLaunchers.py', + 'history.ts': 'history.py', + 'ink.ts': 'ink.py', + 'interactiveHelpers.tsx': 'interactiveHelpers.py', + 'main.tsx': 'main.py', + 'projectOnboardingState.ts': 'projectOnboardingState.py', + 'query.ts': 'query.py', + 'replLauncher.tsx': 'replLauncher.py', + 'setup.ts': 'setup.py', + 'tasks.ts': 'tasks.py', + 'tools.ts': 'tools.py', +} + +ARCHIVE_DIR_MAPPINGS = { + 'assistant': 'assistant', + 'bootstrap': 'bootstrap', + 'bridge': 'bridge', + 'buddy': 'buddy', + 'cli': 'cli', + 'commands': 'commands.py', + 'components': 'components', + 'constants': 'constants', + 'context': 'context.py', + 'coordinator': 'coordinator', + 'entrypoints': 'entrypoints', + 'hooks': 'hooks', + 'ink': 'ink.py', + 'keybindings': 'keybindings', + 'memdir': 'memdir', + 'migrations': 'migrations', + 'moreright': 'moreright', + 'native-ts': 'native_ts', + 'outputStyles': 'outputStyles', + 'plugins': 'plugins', + 'query': 'query.py', + 'remote': 'remote', + 'schemas': 'schemas', + 'screens': 'screens', + 'server': 'server', + 'services': 'services', + 'skills': 'skills', + 'state': 'state', + 'tasks': 'tasks.py', + 'tools': 'tools.py', + 'types': 'types', + 'upstreamproxy': 'upstreamproxy', + 'utils': 'utils', + 'vim': 'vim', + 'voice': 'voice', +} + + +@dataclass(frozen=True) +class ParityAuditResult: + archive_present: bool + root_file_coverage: tuple[int, int] + directory_coverage: tuple[int, int] + total_file_ratio: tuple[int, int] + command_entry_ratio: tuple[int, int] + tool_entry_ratio: tuple[int, int] + missing_root_targets: tuple[str, ...] + missing_directory_targets: tuple[str, ...] + + def to_markdown(self) -> str: + lines = ['# Parity Audit'] + if not self.archive_present: + lines.append('Local archive unavailable; parity audit cannot compare against the original snapshot.') + return '\n'.join(lines) + + lines.extend([ + '', + f'Root file coverage: **{self.root_file_coverage[0]}/{self.root_file_coverage[1]}**', + f'Directory coverage: **{self.directory_coverage[0]}/{self.directory_coverage[1]}**', + f'Total Python files vs archived TS-like files: **{self.total_file_ratio[0]}/{self.total_file_ratio[1]}**', + f'Command entry coverage: **{self.command_entry_ratio[0]}/{self.command_entry_ratio[1]}**', + f'Tool entry coverage: **{self.tool_entry_ratio[0]}/{self.tool_entry_ratio[1]}**', + '', + 'Missing root targets:', + ]) + if self.missing_root_targets: + lines.extend(f'- {item}' for item in self.missing_root_targets) + else: + lines.append('- none') + + lines.extend(['', 'Missing directory targets:']) + if self.missing_directory_targets: + lines.extend(f'- {item}' for item in self.missing_directory_targets) + else: + lines.append('- none') + return '\n'.join(lines) + + +def _reference_surface() -> dict[str, object]: + return json.loads(REFERENCE_SURFACE_PATH.read_text()) + + +def _snapshot_count(path: Path) -> int: + return len(json.loads(path.read_text())) + + +def run_parity_audit() -> ParityAuditResult: + current_entries = {path.name for path in CURRENT_ROOT.iterdir()} + root_hits = [target for target in ARCHIVE_ROOT_FILES.values() if target in current_entries] + dir_hits = [target for target in ARCHIVE_DIR_MAPPINGS.values() if target in current_entries] + missing_roots = tuple(target for target in ARCHIVE_ROOT_FILES.values() if target not in current_entries) + missing_dirs = tuple(target for target in ARCHIVE_DIR_MAPPINGS.values() if target not in current_entries) + current_python_files = sum(1 for path in CURRENT_ROOT.rglob('*.py') if path.is_file()) + reference = _reference_surface() + return ParityAuditResult( + archive_present=ARCHIVE_ROOT.exists(), + root_file_coverage=(len(root_hits), len(ARCHIVE_ROOT_FILES)), + directory_coverage=(len(dir_hits), len(ARCHIVE_DIR_MAPPINGS)), + total_file_ratio=(current_python_files, int(reference['total_ts_like_files'])), + command_entry_ratio=(_snapshot_count(COMMAND_SNAPSHOT_PATH), int(reference['command_entry_count'])), + tool_entry_ratio=(_snapshot_count(TOOL_SNAPSHOT_PATH), int(reference['tool_entry_count'])), + missing_root_targets=missing_roots, + missing_directory_targets=missing_dirs, + ) diff --git a/src/permissions.py b/src/permissions.py new file mode 100644 index 0000000..477fd3e --- /dev/null +++ b/src/permissions.py @@ -0,0 +1,20 @@ +from __future__ import annotations + +from dataclasses import dataclass, field + + +@dataclass(frozen=True) +class ToolPermissionContext: + deny_names: frozenset[str] = field(default_factory=frozenset) + deny_prefixes: tuple[str, ...] = () + + @classmethod + def from_iterables(cls, deny_names: list[str] | None = None, deny_prefixes: list[str] | None = None) -> 'ToolPermissionContext': + return cls( + deny_names=frozenset(name.lower() for name in (deny_names or [])), + deny_prefixes=tuple(prefix.lower() for prefix in (deny_prefixes or [])), + ) + + def blocks(self, tool_name: str) -> bool: + lowered = tool_name.lower() + return lowered in self.deny_names or any(lowered.startswith(prefix) for prefix in self.deny_prefixes) diff --git a/src/plugins/__init__.py b/src/plugins/__init__.py new file mode 100644 index 0000000..83b2293 --- /dev/null +++ b/src/plugins/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `plugins` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'plugins.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/port_manifest.py b/src/port_manifest.py new file mode 100644 index 0000000..8c567e9 --- /dev/null +++ b/src/port_manifest.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +from collections import Counter +from dataclasses import dataclass +from pathlib import Path + +from .models import Subsystem + +DEFAULT_SRC_ROOT = Path(__file__).resolve().parent + + +@dataclass(frozen=True) +class PortManifest: + src_root: Path + total_python_files: int + top_level_modules: tuple[Subsystem, ...] + + def to_markdown(self) -> str: + lines = [ + f'Port root: `{self.src_root}`', + f'Total Python files: **{self.total_python_files}**', + '', + 'Top-level Python modules:', + ] + for module in self.top_level_modules: + lines.append(f'- `{module.name}` ({module.file_count} files) — {module.notes}') + return '\n'.join(lines) + + +def build_port_manifest(src_root: Path | None = None) -> PortManifest: + root = src_root or DEFAULT_SRC_ROOT + files = [path for path in root.rglob('*.py') if path.is_file()] + counter = Counter( + path.relative_to(root).parts[0] if len(path.relative_to(root).parts) > 1 else path.name + for path in files + if path.name != '__pycache__' + ) + notes = { + '__init__.py': 'package export surface', + 'main.py': 'CLI entrypoint', + 'port_manifest.py': 'workspace manifest generation', + 'query_engine.py': 'port orchestration summary layer', + 'commands.py': 'command backlog metadata', + 'tools.py': 'tool backlog metadata', + 'models.py': 'shared dataclasses', + 'task.py': 'task-level planning structures', + } + modules = tuple( + Subsystem(name=name, path=f'src/{name}', file_count=count, notes=notes.get(name, 'Python port support module')) + for name, count in counter.most_common() + ) + return PortManifest(src_root=root, total_python_files=len(files), top_level_modules=modules) diff --git a/src/prefetch.py b/src/prefetch.py new file mode 100644 index 0000000..7ba9998 --- /dev/null +++ b/src/prefetch.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from dataclasses import dataclass +from pathlib import Path + + +@dataclass(frozen=True) +class PrefetchResult: + name: str + started: bool + detail: str + + +def start_mdm_raw_read() -> PrefetchResult: + return PrefetchResult('mdm_raw_read', True, 'Simulated MDM raw-read prefetch for workspace bootstrap') + + +def start_keychain_prefetch() -> PrefetchResult: + return PrefetchResult('keychain_prefetch', True, 'Simulated keychain prefetch for trusted startup path') + + +def start_project_scan(root: Path) -> PrefetchResult: + return PrefetchResult('project_scan', True, f'Scanned project root {root}') diff --git a/src/projectOnboardingState.py b/src/projectOnboardingState.py new file mode 100644 index 0000000..842a8eb --- /dev/null +++ b/src/projectOnboardingState.py @@ -0,0 +1,10 @@ +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass +class ProjectOnboardingState: + has_readme: bool + has_tests: bool + python_first: bool = True diff --git a/src/query.py b/src/query.py new file mode 100644 index 0000000..26e8dee --- /dev/null +++ b/src/query.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class QueryRequest: + prompt: str + + +@dataclass(frozen=True) +class QueryResponse: + text: str diff --git a/src/query_engine.py b/src/query_engine.py new file mode 100644 index 0000000..bb14c2e --- /dev/null +++ b/src/query_engine.py @@ -0,0 +1,193 @@ +from __future__ import annotations + +import json +from dataclasses import dataclass, field +from uuid import uuid4 + +from .commands import build_command_backlog +from .models import PermissionDenial, UsageSummary +from .port_manifest import PortManifest, build_port_manifest +from .session_store import StoredSession, load_session, save_session +from .tools import build_tool_backlog +from .transcript import TranscriptStore + + +@dataclass(frozen=True) +class QueryEngineConfig: + max_turns: int = 8 + max_budget_tokens: int = 2000 + compact_after_turns: int = 12 + structured_output: bool = False + structured_retry_limit: int = 2 + + +@dataclass(frozen=True) +class TurnResult: + prompt: str + output: str + matched_commands: tuple[str, ...] + matched_tools: tuple[str, ...] + permission_denials: tuple[PermissionDenial, ...] + usage: UsageSummary + stop_reason: str + + +@dataclass +class QueryEnginePort: + manifest: PortManifest + config: QueryEngineConfig = field(default_factory=QueryEngineConfig) + session_id: str = field(default_factory=lambda: uuid4().hex) + mutable_messages: list[str] = field(default_factory=list) + permission_denials: list[PermissionDenial] = field(default_factory=list) + total_usage: UsageSummary = field(default_factory=UsageSummary) + transcript_store: TranscriptStore = field(default_factory=TranscriptStore) + + @classmethod + def from_workspace(cls) -> 'QueryEnginePort': + return cls(manifest=build_port_manifest()) + + @classmethod + def from_saved_session(cls, session_id: str) -> 'QueryEnginePort': + stored = load_session(session_id) + transcript = TranscriptStore(entries=list(stored.messages), flushed=True) + return cls( + manifest=build_port_manifest(), + session_id=stored.session_id, + mutable_messages=list(stored.messages), + total_usage=UsageSummary(stored.input_tokens, stored.output_tokens), + transcript_store=transcript, + ) + + def submit_message( + self, + prompt: str, + matched_commands: tuple[str, ...] = (), + matched_tools: tuple[str, ...] = (), + denied_tools: tuple[PermissionDenial, ...] = (), + ) -> TurnResult: + if len(self.mutable_messages) >= self.config.max_turns: + output = f'Max turns reached before processing prompt: {prompt}' + return TurnResult( + prompt=prompt, + output=output, + matched_commands=matched_commands, + matched_tools=matched_tools, + permission_denials=denied_tools, + usage=self.total_usage, + stop_reason='max_turns_reached', + ) + + summary_lines = [ + f'Prompt: {prompt}', + f'Matched commands: {", ".join(matched_commands) if matched_commands else "none"}', + f'Matched tools: {", ".join(matched_tools) if matched_tools else "none"}', + f'Permission denials: {len(denied_tools)}', + ] + output = self._format_output(summary_lines) + projected_usage = self.total_usage.add_turn(prompt, output) + stop_reason = 'completed' + if projected_usage.input_tokens + projected_usage.output_tokens > self.config.max_budget_tokens: + stop_reason = 'max_budget_reached' + self.mutable_messages.append(prompt) + self.transcript_store.append(prompt) + self.permission_denials.extend(denied_tools) + self.total_usage = projected_usage + self.compact_messages_if_needed() + return TurnResult( + prompt=prompt, + output=output, + matched_commands=matched_commands, + matched_tools=matched_tools, + permission_denials=denied_tools, + usage=self.total_usage, + stop_reason=stop_reason, + ) + + def stream_submit_message( + self, + prompt: str, + matched_commands: tuple[str, ...] = (), + matched_tools: tuple[str, ...] = (), + denied_tools: tuple[PermissionDenial, ...] = (), + ): + yield {'type': 'message_start', 'session_id': self.session_id, 'prompt': prompt} + if matched_commands: + yield {'type': 'command_match', 'commands': matched_commands} + if matched_tools: + yield {'type': 'tool_match', 'tools': matched_tools} + if denied_tools: + yield {'type': 'permission_denial', 'denials': [denial.tool_name for denial in denied_tools]} + result = self.submit_message(prompt, matched_commands, matched_tools, denied_tools) + yield {'type': 'message_delta', 'text': result.output} + yield { + 'type': 'message_stop', + 'usage': {'input_tokens': result.usage.input_tokens, 'output_tokens': result.usage.output_tokens}, + 'stop_reason': result.stop_reason, + 'transcript_size': len(self.transcript_store.entries), + } + + def compact_messages_if_needed(self) -> None: + if len(self.mutable_messages) > self.config.compact_after_turns: + self.mutable_messages[:] = self.mutable_messages[-self.config.compact_after_turns :] + self.transcript_store.compact(self.config.compact_after_turns) + + def replay_user_messages(self) -> tuple[str, ...]: + return self.transcript_store.replay() + + def flush_transcript(self) -> None: + self.transcript_store.flush() + + def persist_session(self) -> str: + self.flush_transcript() + path = save_session( + StoredSession( + session_id=self.session_id, + messages=tuple(self.mutable_messages), + input_tokens=self.total_usage.input_tokens, + output_tokens=self.total_usage.output_tokens, + ) + ) + return str(path) + + def _format_output(self, summary_lines: list[str]) -> str: + if self.config.structured_output: + payload = { + 'summary': summary_lines, + 'session_id': self.session_id, + } + return self._render_structured_output(payload) + return '\n'.join(summary_lines) + + def _render_structured_output(self, payload: dict[str, object]) -> str: + last_error: Exception | None = None + for _ in range(self.config.structured_retry_limit): + try: + return json.dumps(payload, indent=2) + except (TypeError, ValueError) as exc: # pragma: no cover - defensive branch + last_error = exc + payload = {'summary': ['structured output retry'], 'session_id': self.session_id} + raise RuntimeError('structured output rendering failed') from last_error + + def render_summary(self) -> str: + command_backlog = build_command_backlog() + tool_backlog = build_tool_backlog() + sections = [ + '# Python Porting Workspace Summary', + '', + self.manifest.to_markdown(), + '', + f'Command surface: {len(command_backlog.modules)} mirrored entries', + *command_backlog.summary_lines()[:10], + '', + f'Tool surface: {len(tool_backlog.modules)} mirrored entries', + *tool_backlog.summary_lines()[:10], + '', + f'Session id: {self.session_id}', + f'Conversation turns stored: {len(self.mutable_messages)}', + f'Permission denials tracked: {len(self.permission_denials)}', + f'Usage totals: in={self.total_usage.input_tokens} out={self.total_usage.output_tokens}', + f'Max turns: {self.config.max_turns}', + f'Max budget tokens: {self.config.max_budget_tokens}', + f'Transcript flushed: {self.transcript_store.flushed}', + ] + return '\n'.join(sections) diff --git a/src/reference_data/__init__.py b/src/reference_data/__init__.py new file mode 100644 index 0000000..ef9b78f --- /dev/null +++ b/src/reference_data/__init__.py @@ -0,0 +1 @@ +"""Tracked snapshot metadata extracted from the local TypeScript archive.""" diff --git a/src/reference_data/archive_surface_snapshot.json b/src/reference_data/archive_surface_snapshot.json new file mode 100644 index 0000000..0167acd --- /dev/null +++ b/src/reference_data/archive_surface_snapshot.json @@ -0,0 +1,63 @@ +{ + "archive_root": "archive/claw_code_ts_snapshot/src", + "root_files": [ + "QueryEngine.ts", + "Task.ts", + "Tool.ts", + "commands.ts", + "context.ts", + "cost-tracker.ts", + "costHook.ts", + "dialogLaunchers.tsx", + "history.ts", + "ink.ts", + "interactiveHelpers.tsx", + "main.tsx", + "projectOnboardingState.ts", + "query.ts", + "replLauncher.tsx", + "setup.ts", + "tasks.ts", + "tools.ts" + ], + "root_dirs": [ + "assistant", + "bootstrap", + "bridge", + "buddy", + "cli", + "commands", + "components", + "constants", + "context", + "coordinator", + "entrypoints", + "hooks", + "ink", + "keybindings", + "memdir", + "migrations", + "moreright", + "native-ts", + "outputStyles", + "plugins", + "query", + "remote", + "schemas", + "screens", + "server", + "services", + "skills", + "state", + "tasks", + "tools", + "types", + "upstreamproxy", + "utils", + "vim", + "voice" + ], + "total_ts_like_files": 1902, + "command_entry_count": 207, + "tool_entry_count": 184 +} \ No newline at end of file diff --git a/src/reference_data/commands_snapshot.json b/src/reference_data/commands_snapshot.json new file mode 100644 index 0000000..eb85fd5 --- /dev/null +++ b/src/reference_data/commands_snapshot.json @@ -0,0 +1,1037 @@ +[ + { + "name": "add-dir", + "source_hint": "commands/add-dir/add-dir.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/add-dir/add-dir.tsx" + }, + { + "name": "add-dir", + "source_hint": "commands/add-dir/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/add-dir/index.ts" + }, + { + "name": "validation", + "source_hint": "commands/add-dir/validation.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/add-dir/validation.ts" + }, + { + "name": "advisor", + "source_hint": "commands/advisor.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/advisor.ts" + }, + { + "name": "agents", + "source_hint": "commands/agents/agents.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/agents/agents.tsx" + }, + { + "name": "agents", + "source_hint": "commands/agents/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/agents/index.ts" + }, + { + "name": "ant-trace", + "source_hint": "commands/ant-trace/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/ant-trace/index.js" + }, + { + "name": "autofix-pr", + "source_hint": "commands/autofix-pr/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/autofix-pr/index.js" + }, + { + "name": "backfill-sessions", + "source_hint": "commands/backfill-sessions/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/backfill-sessions/index.js" + }, + { + "name": "branch", + "source_hint": "commands/branch/branch.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/branch/branch.ts" + }, + { + "name": "branch", + "source_hint": "commands/branch/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/branch/index.ts" + }, + { + "name": "break-cache", + "source_hint": "commands/break-cache/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/break-cache/index.js" + }, + { + "name": "bridge", + "source_hint": "commands/bridge/bridge.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/bridge/bridge.tsx" + }, + { + "name": "bridge", + "source_hint": "commands/bridge/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/bridge/index.ts" + }, + { + "name": "bridge-kick", + "source_hint": "commands/bridge-kick.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/bridge-kick.ts" + }, + { + "name": "brief", + "source_hint": "commands/brief.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/brief.ts" + }, + { + "name": "btw", + "source_hint": "commands/btw/btw.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/btw/btw.tsx" + }, + { + "name": "btw", + "source_hint": "commands/btw/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/btw/index.ts" + }, + { + "name": "bughunter", + "source_hint": "commands/bughunter/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/bughunter/index.js" + }, + { + "name": "chrome", + "source_hint": "commands/chrome/chrome.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/chrome/chrome.tsx" + }, + { + "name": "chrome", + "source_hint": "commands/chrome/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/chrome/index.ts" + }, + { + "name": "caches", + "source_hint": "commands/clear/caches.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/clear/caches.ts" + }, + { + "name": "clear", + "source_hint": "commands/clear/clear.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/clear/clear.ts" + }, + { + "name": "conversation", + "source_hint": "commands/clear/conversation.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/clear/conversation.ts" + }, + { + "name": "clear", + "source_hint": "commands/clear/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/clear/index.ts" + }, + { + "name": "color", + "source_hint": "commands/color/color.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/color/color.ts" + }, + { + "name": "color", + "source_hint": "commands/color/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/color/index.ts" + }, + { + "name": "commit-push-pr", + "source_hint": "commands/commit-push-pr.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/commit-push-pr.ts" + }, + { + "name": "commit", + "source_hint": "commands/commit.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/commit.ts" + }, + { + "name": "compact", + "source_hint": "commands/compact/compact.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/compact/compact.ts" + }, + { + "name": "compact", + "source_hint": "commands/compact/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/compact/index.ts" + }, + { + "name": "config", + "source_hint": "commands/config/config.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/config/config.tsx" + }, + { + "name": "config", + "source_hint": "commands/config/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/config/index.ts" + }, + { + "name": "context-noninteractive", + "source_hint": "commands/context/context-noninteractive.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/context/context-noninteractive.ts" + }, + { + "name": "context", + "source_hint": "commands/context/context.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/context/context.tsx" + }, + { + "name": "context", + "source_hint": "commands/context/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/context/index.ts" + }, + { + "name": "copy", + "source_hint": "commands/copy/copy.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/copy/copy.tsx" + }, + { + "name": "copy", + "source_hint": "commands/copy/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/copy/index.ts" + }, + { + "name": "cost", + "source_hint": "commands/cost/cost.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/cost/cost.ts" + }, + { + "name": "cost", + "source_hint": "commands/cost/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/cost/index.ts" + }, + { + "name": "createMovedToPluginCommand", + "source_hint": "commands/createMovedToPluginCommand.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/createMovedToPluginCommand.ts" + }, + { + "name": "ctx_viz", + "source_hint": "commands/ctx_viz/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/ctx_viz/index.js" + }, + { + "name": "debug-tool-call", + "source_hint": "commands/debug-tool-call/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/debug-tool-call/index.js" + }, + { + "name": "desktop", + "source_hint": "commands/desktop/desktop.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/desktop/desktop.tsx" + }, + { + "name": "desktop", + "source_hint": "commands/desktop/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/desktop/index.ts" + }, + { + "name": "diff", + "source_hint": "commands/diff/diff.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/diff/diff.tsx" + }, + { + "name": "diff", + "source_hint": "commands/diff/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/diff/index.ts" + }, + { + "name": "doctor", + "source_hint": "commands/doctor/doctor.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/doctor/doctor.tsx" + }, + { + "name": "doctor", + "source_hint": "commands/doctor/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/doctor/index.ts" + }, + { + "name": "effort", + "source_hint": "commands/effort/effort.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/effort/effort.tsx" + }, + { + "name": "effort", + "source_hint": "commands/effort/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/effort/index.ts" + }, + { + "name": "env", + "source_hint": "commands/env/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/env/index.js" + }, + { + "name": "exit", + "source_hint": "commands/exit/exit.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/exit/exit.tsx" + }, + { + "name": "exit", + "source_hint": "commands/exit/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/exit/index.ts" + }, + { + "name": "export", + "source_hint": "commands/export/export.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/export/export.tsx" + }, + { + "name": "export", + "source_hint": "commands/export/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/export/index.ts" + }, + { + "name": "extra-usage-core", + "source_hint": "commands/extra-usage/extra-usage-core.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/extra-usage/extra-usage-core.ts" + }, + { + "name": "extra-usage-noninteractive", + "source_hint": "commands/extra-usage/extra-usage-noninteractive.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/extra-usage/extra-usage-noninteractive.ts" + }, + { + "name": "extra-usage", + "source_hint": "commands/extra-usage/extra-usage.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/extra-usage/extra-usage.tsx" + }, + { + "name": "extra-usage", + "source_hint": "commands/extra-usage/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/extra-usage/index.ts" + }, + { + "name": "fast", + "source_hint": "commands/fast/fast.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/fast/fast.tsx" + }, + { + "name": "fast", + "source_hint": "commands/fast/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/fast/index.ts" + }, + { + "name": "feedback", + "source_hint": "commands/feedback/feedback.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/feedback/feedback.tsx" + }, + { + "name": "feedback", + "source_hint": "commands/feedback/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/feedback/index.ts" + }, + { + "name": "files", + "source_hint": "commands/files/files.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/files/files.ts" + }, + { + "name": "files", + "source_hint": "commands/files/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/files/index.ts" + }, + { + "name": "good-claw", + "source_hint": "commands/good-claw/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/good-claw/index.js" + }, + { + "name": "heapdump", + "source_hint": "commands/heapdump/heapdump.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/heapdump/heapdump.ts" + }, + { + "name": "heapdump", + "source_hint": "commands/heapdump/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/heapdump/index.ts" + }, + { + "name": "help", + "source_hint": "commands/help/help.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/help/help.tsx" + }, + { + "name": "help", + "source_hint": "commands/help/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/help/index.ts" + }, + { + "name": "hooks", + "source_hint": "commands/hooks/hooks.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/hooks/hooks.tsx" + }, + { + "name": "hooks", + "source_hint": "commands/hooks/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/hooks/index.ts" + }, + { + "name": "ide", + "source_hint": "commands/ide/ide.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/ide/ide.tsx" + }, + { + "name": "ide", + "source_hint": "commands/ide/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/ide/index.ts" + }, + { + "name": "init-verifiers", + "source_hint": "commands/init-verifiers.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/init-verifiers.ts" + }, + { + "name": "init", + "source_hint": "commands/init.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/init.ts" + }, + { + "name": "insights", + "source_hint": "commands/insights.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/insights.ts" + }, + { + "name": "ApiKeyStep", + "source_hint": "commands/install-github-app/ApiKeyStep.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/ApiKeyStep.tsx" + }, + { + "name": "CheckExistingSecretStep", + "source_hint": "commands/install-github-app/CheckExistingSecretStep.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/CheckExistingSecretStep.tsx" + }, + { + "name": "CheckGitHubStep", + "source_hint": "commands/install-github-app/CheckGitHubStep.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/CheckGitHubStep.tsx" + }, + { + "name": "ChooseRepoStep", + "source_hint": "commands/install-github-app/ChooseRepoStep.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/ChooseRepoStep.tsx" + }, + { + "name": "CreatingStep", + "source_hint": "commands/install-github-app/CreatingStep.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/CreatingStep.tsx" + }, + { + "name": "ErrorStep", + "source_hint": "commands/install-github-app/ErrorStep.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/ErrorStep.tsx" + }, + { + "name": "ExistingWorkflowStep", + "source_hint": "commands/install-github-app/ExistingWorkflowStep.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/ExistingWorkflowStep.tsx" + }, + { + "name": "InstallAppStep", + "source_hint": "commands/install-github-app/InstallAppStep.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/InstallAppStep.tsx" + }, + { + "name": "OAuthFlowStep", + "source_hint": "commands/install-github-app/OAuthFlowStep.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/OAuthFlowStep.tsx" + }, + { + "name": "SuccessStep", + "source_hint": "commands/install-github-app/SuccessStep.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/SuccessStep.tsx" + }, + { + "name": "WarningsStep", + "source_hint": "commands/install-github-app/WarningsStep.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/WarningsStep.tsx" + }, + { + "name": "install-github-app", + "source_hint": "commands/install-github-app/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/index.ts" + }, + { + "name": "install-github-app", + "source_hint": "commands/install-github-app/install-github-app.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/install-github-app.tsx" + }, + { + "name": "setupGitHubActions", + "source_hint": "commands/install-github-app/setupGitHubActions.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-github-app/setupGitHubActions.ts" + }, + { + "name": "install-slack-app", + "source_hint": "commands/install-slack-app/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-slack-app/index.ts" + }, + { + "name": "install-slack-app", + "source_hint": "commands/install-slack-app/install-slack-app.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/install-slack-app/install-slack-app.ts" + }, + { + "name": "install", + "source_hint": "commands/install.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/install.tsx" + }, + { + "name": "issue", + "source_hint": "commands/issue/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/issue/index.js" + }, + { + "name": "keybindings", + "source_hint": "commands/keybindings/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/keybindings/index.ts" + }, + { + "name": "keybindings", + "source_hint": "commands/keybindings/keybindings.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/keybindings/keybindings.ts" + }, + { + "name": "login", + "source_hint": "commands/login/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/login/index.ts" + }, + { + "name": "login", + "source_hint": "commands/login/login.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/login/login.tsx" + }, + { + "name": "logout", + "source_hint": "commands/logout/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/logout/index.ts" + }, + { + "name": "logout", + "source_hint": "commands/logout/logout.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/logout/logout.tsx" + }, + { + "name": "addCommand", + "source_hint": "commands/mcp/addCommand.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/mcp/addCommand.ts" + }, + { + "name": "mcp", + "source_hint": "commands/mcp/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/mcp/index.ts" + }, + { + "name": "mcp", + "source_hint": "commands/mcp/mcp.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/mcp/mcp.tsx" + }, + { + "name": "xaaIdpCommand", + "source_hint": "commands/mcp/xaaIdpCommand.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/mcp/xaaIdpCommand.ts" + }, + { + "name": "memory", + "source_hint": "commands/memory/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/memory/index.ts" + }, + { + "name": "memory", + "source_hint": "commands/memory/memory.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/memory/memory.tsx" + }, + { + "name": "mobile", + "source_hint": "commands/mobile/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/mobile/index.ts" + }, + { + "name": "mobile", + "source_hint": "commands/mobile/mobile.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/mobile/mobile.tsx" + }, + { + "name": "mock-limits", + "source_hint": "commands/mock-limits/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/mock-limits/index.js" + }, + { + "name": "model", + "source_hint": "commands/model/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/model/index.ts" + }, + { + "name": "model", + "source_hint": "commands/model/model.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/model/model.tsx" + }, + { + "name": "oauth-refresh", + "source_hint": "commands/oauth-refresh/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/oauth-refresh/index.js" + }, + { + "name": "onboarding", + "source_hint": "commands/onboarding/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/onboarding/index.js" + }, + { + "name": "output-style", + "source_hint": "commands/output-style/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/output-style/index.ts" + }, + { + "name": "output-style", + "source_hint": "commands/output-style/output-style.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/output-style/output-style.tsx" + }, + { + "name": "passes", + "source_hint": "commands/passes/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/passes/index.ts" + }, + { + "name": "passes", + "source_hint": "commands/passes/passes.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/passes/passes.tsx" + }, + { + "name": "perf-issue", + "source_hint": "commands/perf-issue/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/perf-issue/index.js" + }, + { + "name": "permissions", + "source_hint": "commands/permissions/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/permissions/index.ts" + }, + { + "name": "permissions", + "source_hint": "commands/permissions/permissions.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/permissions/permissions.tsx" + }, + { + "name": "plan", + "source_hint": "commands/plan/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/plan/index.ts" + }, + { + "name": "plan", + "source_hint": "commands/plan/plan.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plan/plan.tsx" + }, + { + "name": "AddMarketplace", + "source_hint": "commands/plugin/AddMarketplace.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/AddMarketplace.tsx" + }, + { + "name": "BrowseMarketplace", + "source_hint": "commands/plugin/BrowseMarketplace.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/BrowseMarketplace.tsx" + }, + { + "name": "DiscoverPlugins", + "source_hint": "commands/plugin/DiscoverPlugins.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/DiscoverPlugins.tsx" + }, + { + "name": "ManageMarketplaces", + "source_hint": "commands/plugin/ManageMarketplaces.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/ManageMarketplaces.tsx" + }, + { + "name": "ManagePlugins", + "source_hint": "commands/plugin/ManagePlugins.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/ManagePlugins.tsx" + }, + { + "name": "PluginErrors", + "source_hint": "commands/plugin/PluginErrors.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/PluginErrors.tsx" + }, + { + "name": "PluginOptionsDialog", + "source_hint": "commands/plugin/PluginOptionsDialog.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/PluginOptionsDialog.tsx" + }, + { + "name": "PluginOptionsFlow", + "source_hint": "commands/plugin/PluginOptionsFlow.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/PluginOptionsFlow.tsx" + }, + { + "name": "PluginSettings", + "source_hint": "commands/plugin/PluginSettings.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/PluginSettings.tsx" + }, + { + "name": "PluginTrustWarning", + "source_hint": "commands/plugin/PluginTrustWarning.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/PluginTrustWarning.tsx" + }, + { + "name": "UnifiedInstalledCell", + "source_hint": "commands/plugin/UnifiedInstalledCell.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/UnifiedInstalledCell.tsx" + }, + { + "name": "ValidatePlugin", + "source_hint": "commands/plugin/ValidatePlugin.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/ValidatePlugin.tsx" + }, + { + "name": "plugin", + "source_hint": "commands/plugin/index.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/index.tsx" + }, + { + "name": "parseArgs", + "source_hint": "commands/plugin/parseArgs.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/parseArgs.ts" + }, + { + "name": "plugin", + "source_hint": "commands/plugin/plugin.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/plugin.tsx" + }, + { + "name": "pluginDetailsHelpers", + "source_hint": "commands/plugin/pluginDetailsHelpers.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/pluginDetailsHelpers.tsx" + }, + { + "name": "usePagination", + "source_hint": "commands/plugin/usePagination.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/plugin/usePagination.ts" + }, + { + "name": "pr_comments", + "source_hint": "commands/pr_comments/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/pr_comments/index.ts" + }, + { + "name": "privacy-settings", + "source_hint": "commands/privacy-settings/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/privacy-settings/index.ts" + }, + { + "name": "privacy-settings", + "source_hint": "commands/privacy-settings/privacy-settings.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/privacy-settings/privacy-settings.tsx" + }, + { + "name": "rate-limit-options", + "source_hint": "commands/rate-limit-options/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/rate-limit-options/index.ts" + }, + { + "name": "rate-limit-options", + "source_hint": "commands/rate-limit-options/rate-limit-options.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/rate-limit-options/rate-limit-options.tsx" + }, + { + "name": "release-notes", + "source_hint": "commands/release-notes/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/release-notes/index.ts" + }, + { + "name": "release-notes", + "source_hint": "commands/release-notes/release-notes.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/release-notes/release-notes.ts" + }, + { + "name": "reload-plugins", + "source_hint": "commands/reload-plugins/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/reload-plugins/index.ts" + }, + { + "name": "reload-plugins", + "source_hint": "commands/reload-plugins/reload-plugins.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/reload-plugins/reload-plugins.ts" + }, + { + "name": "remote-env", + "source_hint": "commands/remote-env/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/remote-env/index.ts" + }, + { + "name": "remote-env", + "source_hint": "commands/remote-env/remote-env.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/remote-env/remote-env.tsx" + }, + { + "name": "api", + "source_hint": "commands/remote-setup/api.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/remote-setup/api.ts" + }, + { + "name": "remote-setup", + "source_hint": "commands/remote-setup/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/remote-setup/index.ts" + }, + { + "name": "remote-setup", + "source_hint": "commands/remote-setup/remote-setup.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/remote-setup/remote-setup.tsx" + }, + { + "name": "generateSessionName", + "source_hint": "commands/rename/generateSessionName.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/rename/generateSessionName.ts" + }, + { + "name": "rename", + "source_hint": "commands/rename/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/rename/index.ts" + }, + { + "name": "rename", + "source_hint": "commands/rename/rename.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/rename/rename.ts" + }, + { + "name": "reset-limits", + "source_hint": "commands/reset-limits/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/reset-limits/index.js" + }, + { + "name": "resume", + "source_hint": "commands/resume/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/resume/index.ts" + }, + { + "name": "resume", + "source_hint": "commands/resume/resume.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/resume/resume.tsx" + }, + { + "name": "UltrareviewOverageDialog", + "source_hint": "commands/review/UltrareviewOverageDialog.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/review/UltrareviewOverageDialog.tsx" + }, + { + "name": "reviewRemote", + "source_hint": "commands/review/reviewRemote.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/review/reviewRemote.ts" + }, + { + "name": "ultrareviewCommand", + "source_hint": "commands/review/ultrareviewCommand.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/review/ultrareviewCommand.tsx" + }, + { + "name": "ultrareviewEnabled", + "source_hint": "commands/review/ultrareviewEnabled.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/review/ultrareviewEnabled.ts" + }, + { + "name": "review", + "source_hint": "commands/review.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/review.ts" + }, + { + "name": "rewind", + "source_hint": "commands/rewind/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/rewind/index.ts" + }, + { + "name": "rewind", + "source_hint": "commands/rewind/rewind.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/rewind/rewind.ts" + }, + { + "name": "sandbox-toggle", + "source_hint": "commands/sandbox-toggle/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/sandbox-toggle/index.ts" + }, + { + "name": "sandbox-toggle", + "source_hint": "commands/sandbox-toggle/sandbox-toggle.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/sandbox-toggle/sandbox-toggle.tsx" + }, + { + "name": "security-review", + "source_hint": "commands/security-review.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/security-review.ts" + }, + { + "name": "session", + "source_hint": "commands/session/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/session/index.ts" + }, + { + "name": "session", + "source_hint": "commands/session/session.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/session/session.tsx" + }, + { + "name": "share", + "source_hint": "commands/share/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/share/index.js" + }, + { + "name": "skills", + "source_hint": "commands/skills/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/skills/index.ts" + }, + { + "name": "skills", + "source_hint": "commands/skills/skills.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/skills/skills.tsx" + }, + { + "name": "stats", + "source_hint": "commands/stats/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/stats/index.ts" + }, + { + "name": "stats", + "source_hint": "commands/stats/stats.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/stats/stats.tsx" + }, + { + "name": "status", + "source_hint": "commands/status/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/status/index.ts" + }, + { + "name": "status", + "source_hint": "commands/status/status.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/status/status.tsx" + }, + { + "name": "statusline", + "source_hint": "commands/statusline.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/statusline.tsx" + }, + { + "name": "stickers", + "source_hint": "commands/stickers/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/stickers/index.ts" + }, + { + "name": "stickers", + "source_hint": "commands/stickers/stickers.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/stickers/stickers.ts" + }, + { + "name": "summary", + "source_hint": "commands/summary/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/summary/index.js" + }, + { + "name": "tag", + "source_hint": "commands/tag/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/tag/index.ts" + }, + { + "name": "tag", + "source_hint": "commands/tag/tag.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/tag/tag.tsx" + }, + { + "name": "tasks", + "source_hint": "commands/tasks/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/tasks/index.ts" + }, + { + "name": "tasks", + "source_hint": "commands/tasks/tasks.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/tasks/tasks.tsx" + }, + { + "name": "teleport", + "source_hint": "commands/teleport/index.js", + "responsibility": "Command module mirrored from archived TypeScript path commands/teleport/index.js" + }, + { + "name": "terminalSetup", + "source_hint": "commands/terminalSetup/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/terminalSetup/index.ts" + }, + { + "name": "terminalSetup", + "source_hint": "commands/terminalSetup/terminalSetup.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/terminalSetup/terminalSetup.tsx" + }, + { + "name": "theme", + "source_hint": "commands/theme/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/theme/index.ts" + }, + { + "name": "theme", + "source_hint": "commands/theme/theme.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/theme/theme.tsx" + }, + { + "name": "thinkback", + "source_hint": "commands/thinkback/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/thinkback/index.ts" + }, + { + "name": "thinkback", + "source_hint": "commands/thinkback/thinkback.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/thinkback/thinkback.tsx" + }, + { + "name": "thinkback-play", + "source_hint": "commands/thinkback-play/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/thinkback-play/index.ts" + }, + { + "name": "thinkback-play", + "source_hint": "commands/thinkback-play/thinkback-play.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/thinkback-play/thinkback-play.ts" + }, + { + "name": "ultraplan", + "source_hint": "commands/ultraplan.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/ultraplan.tsx" + }, + { + "name": "upgrade", + "source_hint": "commands/upgrade/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/upgrade/index.ts" + }, + { + "name": "upgrade", + "source_hint": "commands/upgrade/upgrade.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/upgrade/upgrade.tsx" + }, + { + "name": "usage", + "source_hint": "commands/usage/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/usage/index.ts" + }, + { + "name": "usage", + "source_hint": "commands/usage/usage.tsx", + "responsibility": "Command module mirrored from archived TypeScript path commands/usage/usage.tsx" + }, + { + "name": "version", + "source_hint": "commands/version.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/version.ts" + }, + { + "name": "vim", + "source_hint": "commands/vim/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/vim/index.ts" + }, + { + "name": "vim", + "source_hint": "commands/vim/vim.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/vim/vim.ts" + }, + { + "name": "voice", + "source_hint": "commands/voice/index.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/voice/index.ts" + }, + { + "name": "voice", + "source_hint": "commands/voice/voice.ts", + "responsibility": "Command module mirrored from archived TypeScript path commands/voice/voice.ts" + } +] \ No newline at end of file diff --git a/src/reference_data/subsystems/assistant.json b/src/reference_data/subsystems/assistant.json new file mode 100644 index 0000000..3982f61 --- /dev/null +++ b/src/reference_data/subsystems/assistant.json @@ -0,0 +1,8 @@ +{ + "archive_name": "assistant", + "package_name": "assistant", + "module_count": 1, + "sample_files": [ + "assistant/sessionHistory.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/bootstrap.json b/src/reference_data/subsystems/bootstrap.json new file mode 100644 index 0000000..3e730e0 --- /dev/null +++ b/src/reference_data/subsystems/bootstrap.json @@ -0,0 +1,8 @@ +{ + "archive_name": "bootstrap", + "package_name": "bootstrap", + "module_count": 1, + "sample_files": [ + "bootstrap/state.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/bridge.json b/src/reference_data/subsystems/bridge.json new file mode 100644 index 0000000..1abd932 --- /dev/null +++ b/src/reference_data/subsystems/bridge.json @@ -0,0 +1,32 @@ +{ + "archive_name": "bridge", + "package_name": "bridge", + "module_count": 31, + "sample_files": [ + "bridge/bridgeApi.ts", + "bridge/bridgeConfig.ts", + "bridge/bridgeDebug.ts", + "bridge/bridgeEnabled.ts", + "bridge/bridgeMain.ts", + "bridge/bridgeMessaging.ts", + "bridge/bridgePermissionCallbacks.ts", + "bridge/bridgePointer.ts", + "bridge/bridgeStatusUtil.ts", + "bridge/bridgeUI.ts", + "bridge/capacityWake.ts", + "bridge/codeSessionApi.ts", + "bridge/createSession.ts", + "bridge/debugUtils.ts", + "bridge/envLessBridgeConfig.ts", + "bridge/flushGate.ts", + "bridge/inboundAttachments.ts", + "bridge/inboundMessages.ts", + "bridge/initReplBridge.ts", + "bridge/jwtUtils.ts", + "bridge/pollConfig.ts", + "bridge/pollConfigDefaults.ts", + "bridge/remoteBridgeCore.ts", + "bridge/replBridge.ts", + "bridge/replBridgeHandle.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/buddy.json b/src/reference_data/subsystems/buddy.json new file mode 100644 index 0000000..1f5b19e --- /dev/null +++ b/src/reference_data/subsystems/buddy.json @@ -0,0 +1,13 @@ +{ + "archive_name": "buddy", + "package_name": "buddy", + "module_count": 6, + "sample_files": [ + "buddy/CompanionSprite.tsx", + "buddy/companion.ts", + "buddy/prompt.ts", + "buddy/sprites.ts", + "buddy/types.ts", + "buddy/useBuddyNotification.tsx" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/cli.json b/src/reference_data/subsystems/cli.json new file mode 100644 index 0000000..21bd381 --- /dev/null +++ b/src/reference_data/subsystems/cli.json @@ -0,0 +1,26 @@ +{ + "archive_name": "cli", + "package_name": "cli", + "module_count": 19, + "sample_files": [ + "cli/exit.ts", + "cli/handlers/agents.ts", + "cli/handlers/auth.ts", + "cli/handlers/autoMode.ts", + "cli/handlers/mcp.tsx", + "cli/handlers/plugins.ts", + "cli/handlers/util.tsx", + "cli/ndjsonSafeStringify.ts", + "cli/print.ts", + "cli/remoteIO.ts", + "cli/structuredIO.ts", + "cli/transports/HybridTransport.ts", + "cli/transports/SSETransport.ts", + "cli/transports/SerialBatchEventUploader.ts", + "cli/transports/WebSocketTransport.ts", + "cli/transports/WorkerStateUploader.ts", + "cli/transports/ccrClient.ts", + "cli/transports/transportUtils.ts", + "cli/update.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/components.json b/src/reference_data/subsystems/components.json new file mode 100644 index 0000000..510971a --- /dev/null +++ b/src/reference_data/subsystems/components.json @@ -0,0 +1,32 @@ +{ + "archive_name": "components", + "package_name": "components", + "module_count": 389, + "sample_files": [ + "components/AgentProgressLine.tsx", + "components/App.tsx", + "components/ApproveApiKey.tsx", + "components/AutoModeOptInDialog.tsx", + "components/AutoUpdater.tsx", + "components/AutoUpdaterWrapper.tsx", + "components/AwsAuthStatusBox.tsx", + "components/BaseTextInput.tsx", + "components/BashModeProgress.tsx", + "components/BridgeDialog.tsx", + "components/BypassPermissionsModeDialog.tsx", + "components/ChannelDowngradeDialog.tsx", + "components/ClawCodeHint/PluginHintMenu.tsx", + "components/ClawInChromeOnboarding.tsx", + "components/ClawMdExternalIncludesDialog.tsx", + "components/ClickableImageRef.tsx", + "components/CompactSummary.tsx", + "components/ConfigurableShortcutHint.tsx", + "components/ConsoleOAuthFlow.tsx", + "components/ContextSuggestions.tsx", + "components/ContextVisualization.tsx", + "components/CoordinatorAgentStatus.tsx", + "components/CostThresholdDialog.tsx", + "components/CtrlOToExpand.tsx", + "components/CustomSelect/SelectMulti.tsx" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/constants.json b/src/reference_data/subsystems/constants.json new file mode 100644 index 0000000..b208c19 --- /dev/null +++ b/src/reference_data/subsystems/constants.json @@ -0,0 +1,28 @@ +{ + "archive_name": "constants", + "package_name": "constants", + "module_count": 21, + "sample_files": [ + "constants/apiLimits.ts", + "constants/betas.ts", + "constants/common.ts", + "constants/cyberRiskInstruction.ts", + "constants/errorIds.ts", + "constants/figures.ts", + "constants/files.ts", + "constants/github-app.ts", + "constants/keys.ts", + "constants/messages.ts", + "constants/oauth.ts", + "constants/outputStyles.ts", + "constants/product.ts", + "constants/prompts.ts", + "constants/spinnerVerbs.ts", + "constants/system.ts", + "constants/systemPromptSections.ts", + "constants/toolLimits.ts", + "constants/tools.ts", + "constants/turnCompletionVerbs.ts", + "constants/xml.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/coordinator.json b/src/reference_data/subsystems/coordinator.json new file mode 100644 index 0000000..5c1c56f --- /dev/null +++ b/src/reference_data/subsystems/coordinator.json @@ -0,0 +1,8 @@ +{ + "archive_name": "coordinator", + "package_name": "coordinator", + "module_count": 1, + "sample_files": [ + "coordinator/coordinatorMode.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/entrypoints.json b/src/reference_data/subsystems/entrypoints.json new file mode 100644 index 0000000..2142f1e --- /dev/null +++ b/src/reference_data/subsystems/entrypoints.json @@ -0,0 +1,15 @@ +{ + "archive_name": "entrypoints", + "package_name": "entrypoints", + "module_count": 8, + "sample_files": [ + "entrypoints/agentSdkTypes.ts", + "entrypoints/cli.tsx", + "entrypoints/init.ts", + "entrypoints/mcp.ts", + "entrypoints/sandboxTypes.ts", + "entrypoints/sdk/controlSchemas.ts", + "entrypoints/sdk/coreSchemas.ts", + "entrypoints/sdk/coreTypes.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/hooks.json b/src/reference_data/subsystems/hooks.json new file mode 100644 index 0000000..a6685ca --- /dev/null +++ b/src/reference_data/subsystems/hooks.json @@ -0,0 +1,32 @@ +{ + "archive_name": "hooks", + "package_name": "hooks", + "module_count": 104, + "sample_files": [ + "hooks/fileSuggestions.ts", + "hooks/notifs/useAutoModeUnavailableNotification.ts", + "hooks/notifs/useCanSwitchToExistingSubscription.tsx", + "hooks/notifs/useDeprecationWarningNotification.tsx", + "hooks/notifs/useFastModeNotification.tsx", + "hooks/notifs/useIDEStatusIndicator.tsx", + "hooks/notifs/useInstallMessages.tsx", + "hooks/notifs/useLspInitializationNotification.tsx", + "hooks/notifs/useMcpConnectivityStatus.tsx", + "hooks/notifs/useModelMigrationNotifications.tsx", + "hooks/notifs/useNpmDeprecationNotification.tsx", + "hooks/notifs/usePluginAutoupdateNotification.tsx", + "hooks/notifs/usePluginInstallationStatus.tsx", + "hooks/notifs/useRateLimitWarningNotification.tsx", + "hooks/notifs/useSettingsErrors.tsx", + "hooks/notifs/useStartupNotification.ts", + "hooks/notifs/useTeammateShutdownNotification.ts", + "hooks/renderPlaceholder.ts", + "hooks/toolPermission/PermissionContext.ts", + "hooks/toolPermission/handlers/coordinatorHandler.ts", + "hooks/toolPermission/handlers/interactiveHandler.ts", + "hooks/toolPermission/handlers/swarmWorkerHandler.ts", + "hooks/toolPermission/permissionLogging.ts", + "hooks/unifiedSuggestions.ts", + "hooks/useAfterFirstRender.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/keybindings.json b/src/reference_data/subsystems/keybindings.json new file mode 100644 index 0000000..9d94b44 --- /dev/null +++ b/src/reference_data/subsystems/keybindings.json @@ -0,0 +1,21 @@ +{ + "archive_name": "keybindings", + "package_name": "keybindings", + "module_count": 14, + "sample_files": [ + "keybindings/KeybindingContext.tsx", + "keybindings/KeybindingProviderSetup.tsx", + "keybindings/defaultBindings.ts", + "keybindings/loadUserBindings.ts", + "keybindings/match.ts", + "keybindings/parser.ts", + "keybindings/reservedShortcuts.ts", + "keybindings/resolver.ts", + "keybindings/schema.ts", + "keybindings/shortcutFormat.ts", + "keybindings/template.ts", + "keybindings/useKeybinding.ts", + "keybindings/useShortcutDisplay.ts", + "keybindings/validate.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/memdir.json b/src/reference_data/subsystems/memdir.json new file mode 100644 index 0000000..a6bc349 --- /dev/null +++ b/src/reference_data/subsystems/memdir.json @@ -0,0 +1,15 @@ +{ + "archive_name": "memdir", + "package_name": "memdir", + "module_count": 8, + "sample_files": [ + "memdir/findRelevantMemories.ts", + "memdir/memdir.ts", + "memdir/memoryAge.ts", + "memdir/memoryScan.ts", + "memdir/memoryTypes.ts", + "memdir/paths.ts", + "memdir/teamMemPaths.ts", + "memdir/teamMemPrompts.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/migrations.json b/src/reference_data/subsystems/migrations.json new file mode 100644 index 0000000..735df68 --- /dev/null +++ b/src/reference_data/subsystems/migrations.json @@ -0,0 +1,18 @@ +{ + "archive_name": "migrations", + "package_name": "migrations", + "module_count": 11, + "sample_files": [ + "migrations/migrateAutoUpdatesToSettings.ts", + "migrations/migrateBypassPermissionsAcceptedToSettings.ts", + "migrations/migrateEnableAllProjectMcpServersToSettings.ts", + "migrations/migrateFennecToOpus.ts", + "migrations/migrateLegacyOpusToCurrent.ts", + "migrations/migrateOpusToOpus1m.ts", + "migrations/migrateReplBridgeEnabledToRemoteControlAtStartup.ts", + "migrations/migrateSonnet1mToSonnet45.ts", + "migrations/migrateSonnet45ToSonnet46.ts", + "migrations/resetAutoModeOptInForDefaultOffer.ts", + "migrations/resetProToOpusDefault.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/moreright.json b/src/reference_data/subsystems/moreright.json new file mode 100644 index 0000000..430ad9e --- /dev/null +++ b/src/reference_data/subsystems/moreright.json @@ -0,0 +1,8 @@ +{ + "archive_name": "moreright", + "package_name": "moreright", + "module_count": 1, + "sample_files": [ + "moreright/useMoreRight.tsx" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/native_ts.json b/src/reference_data/subsystems/native_ts.json new file mode 100644 index 0000000..23a19d5 --- /dev/null +++ b/src/reference_data/subsystems/native_ts.json @@ -0,0 +1,11 @@ +{ + "archive_name": "native-ts", + "package_name": "native_ts", + "module_count": 4, + "sample_files": [ + "native-ts/color-diff/index.ts", + "native-ts/file-index/index.ts", + "native-ts/yoga-layout/enums.ts", + "native-ts/yoga-layout/index.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/outputStyles.json b/src/reference_data/subsystems/outputStyles.json new file mode 100644 index 0000000..f4f2e47 --- /dev/null +++ b/src/reference_data/subsystems/outputStyles.json @@ -0,0 +1,8 @@ +{ + "archive_name": "outputStyles", + "package_name": "outputStyles", + "module_count": 1, + "sample_files": [ + "outputStyles/loadOutputStylesDir.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/plugins.json b/src/reference_data/subsystems/plugins.json new file mode 100644 index 0000000..8ad4394 --- /dev/null +++ b/src/reference_data/subsystems/plugins.json @@ -0,0 +1,9 @@ +{ + "archive_name": "plugins", + "package_name": "plugins", + "module_count": 2, + "sample_files": [ + "plugins/builtinPlugins.ts", + "plugins/bundled/index.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/remote.json b/src/reference_data/subsystems/remote.json new file mode 100644 index 0000000..71f0561 --- /dev/null +++ b/src/reference_data/subsystems/remote.json @@ -0,0 +1,11 @@ +{ + "archive_name": "remote", + "package_name": "remote", + "module_count": 4, + "sample_files": [ + "remote/RemoteSessionManager.ts", + "remote/SessionsWebSocket.ts", + "remote/remotePermissionBridge.ts", + "remote/sdkMessageAdapter.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/schemas.json b/src/reference_data/subsystems/schemas.json new file mode 100644 index 0000000..8cce4a9 --- /dev/null +++ b/src/reference_data/subsystems/schemas.json @@ -0,0 +1,8 @@ +{ + "archive_name": "schemas", + "package_name": "schemas", + "module_count": 1, + "sample_files": [ + "schemas/hooks.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/screens.json b/src/reference_data/subsystems/screens.json new file mode 100644 index 0000000..821cf93 --- /dev/null +++ b/src/reference_data/subsystems/screens.json @@ -0,0 +1,10 @@ +{ + "archive_name": "screens", + "package_name": "screens", + "module_count": 3, + "sample_files": [ + "screens/Doctor.tsx", + "screens/REPL.tsx", + "screens/ResumeConversation.tsx" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/server.json b/src/reference_data/subsystems/server.json new file mode 100644 index 0000000..81e7d72 --- /dev/null +++ b/src/reference_data/subsystems/server.json @@ -0,0 +1,10 @@ +{ + "archive_name": "server", + "package_name": "server", + "module_count": 3, + "sample_files": [ + "server/createDirectConnectSession.ts", + "server/directConnectManager.ts", + "server/types.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/services.json b/src/reference_data/subsystems/services.json new file mode 100644 index 0000000..9f506ee --- /dev/null +++ b/src/reference_data/subsystems/services.json @@ -0,0 +1,32 @@ +{ + "archive_name": "services", + "package_name": "services", + "module_count": 130, + "sample_files": [ + "services/AgentSummary/agentSummary.ts", + "services/MagicDocs/magicDocs.ts", + "services/MagicDocs/prompts.ts", + "services/PromptSuggestion/promptSuggestion.ts", + "services/PromptSuggestion/speculation.ts", + "services/SessionMemory/prompts.ts", + "services/SessionMemory/sessionMemory.ts", + "services/SessionMemory/sessionMemoryUtils.ts", + "services/analytics/config.ts", + "services/analytics/datadog.ts", + "services/analytics/firstPartyEventLogger.ts", + "services/analytics/firstPartyEventLoggingExporter.ts", + "services/analytics/growthbook.ts", + "services/analytics/index.ts", + "services/analytics/metadata.ts", + "services/analytics/sink.ts", + "services/analytics/sinkKillswitch.ts", + "services/api/adminRequests.ts", + "services/api/bootstrap.ts", + "services/api/claw.ts", + "services/api/client.ts", + "services/api/dumpPrompts.ts", + "services/api/emptyUsage.ts", + "services/api/errorUtils.ts", + "services/api/errors.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/skills.json b/src/reference_data/subsystems/skills.json new file mode 100644 index 0000000..5b323b1 --- /dev/null +++ b/src/reference_data/subsystems/skills.json @@ -0,0 +1,27 @@ +{ + "archive_name": "skills", + "package_name": "skills", + "module_count": 20, + "sample_files": [ + "skills/bundled/batch.ts", + "skills/bundled/clawApi.ts", + "skills/bundled/clawApiContent.ts", + "skills/bundled/clawInChrome.ts", + "skills/bundled/debug.ts", + "skills/bundled/index.ts", + "skills/bundled/keybindings.ts", + "skills/bundled/loop.ts", + "skills/bundled/loremIpsum.ts", + "skills/bundled/remember.ts", + "skills/bundled/scheduleRemoteAgents.ts", + "skills/bundled/simplify.ts", + "skills/bundled/skillify.ts", + "skills/bundled/stuck.ts", + "skills/bundled/updateConfig.ts", + "skills/bundled/verify.ts", + "skills/bundled/verifyContent.ts", + "skills/bundledSkills.ts", + "skills/loadSkillsDir.ts", + "skills/mcpSkillBuilders.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/state.json b/src/reference_data/subsystems/state.json new file mode 100644 index 0000000..ef2b05d --- /dev/null +++ b/src/reference_data/subsystems/state.json @@ -0,0 +1,13 @@ +{ + "archive_name": "state", + "package_name": "state", + "module_count": 6, + "sample_files": [ + "state/AppState.tsx", + "state/AppStateStore.ts", + "state/onChangeAppState.ts", + "state/selectors.ts", + "state/store.ts", + "state/teammateViewHelpers.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/types.json b/src/reference_data/subsystems/types.json new file mode 100644 index 0000000..31d2e40 --- /dev/null +++ b/src/reference_data/subsystems/types.json @@ -0,0 +1,18 @@ +{ + "archive_name": "types", + "package_name": "types", + "module_count": 11, + "sample_files": [ + "types/command.ts", + "types/generated/events_mono/claw_code/v1/claw_code_internal_event.ts", + "types/generated/events_mono/common/v1/auth.ts", + "types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts", + "types/generated/google/protobuf/timestamp.ts", + "types/hooks.ts", + "types/ids.ts", + "types/logs.ts", + "types/permissions.ts", + "types/plugin.ts", + "types/textInputTypes.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/upstreamproxy.json b/src/reference_data/subsystems/upstreamproxy.json new file mode 100644 index 0000000..7bb92d4 --- /dev/null +++ b/src/reference_data/subsystems/upstreamproxy.json @@ -0,0 +1,9 @@ +{ + "archive_name": "upstreamproxy", + "package_name": "upstreamproxy", + "module_count": 2, + "sample_files": [ + "upstreamproxy/relay.ts", + "upstreamproxy/upstreamproxy.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/utils.json b/src/reference_data/subsystems/utils.json new file mode 100644 index 0000000..b7ddcb1 --- /dev/null +++ b/src/reference_data/subsystems/utils.json @@ -0,0 +1,32 @@ +{ + "archive_name": "utils", + "package_name": "utils", + "module_count": 564, + "sample_files": [ + "utils/CircularBuffer.ts", + "utils/Cursor.ts", + "utils/QueryGuard.ts", + "utils/Shell.ts", + "utils/ShellCommand.ts", + "utils/abortController.ts", + "utils/activityManager.ts", + "utils/advisor.ts", + "utils/agentContext.ts", + "utils/agentId.ts", + "utils/agentSwarmsEnabled.ts", + "utils/agenticSessionSearch.ts", + "utils/analyzeContext.ts", + "utils/ansiToPng.ts", + "utils/ansiToSvg.ts", + "utils/api.ts", + "utils/apiPreconnect.ts", + "utils/appleTerminalBackup.ts", + "utils/argumentSubstitution.ts", + "utils/array.ts", + "utils/asciicast.ts", + "utils/attachments.ts", + "utils/attribution.ts", + "utils/auth.ts", + "utils/authFileDescriptor.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/vim.json b/src/reference_data/subsystems/vim.json new file mode 100644 index 0000000..e58f401 --- /dev/null +++ b/src/reference_data/subsystems/vim.json @@ -0,0 +1,12 @@ +{ + "archive_name": "vim", + "package_name": "vim", + "module_count": 5, + "sample_files": [ + "vim/motions.ts", + "vim/operators.ts", + "vim/textObjects.ts", + "vim/transitions.ts", + "vim/types.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/subsystems/voice.json b/src/reference_data/subsystems/voice.json new file mode 100644 index 0000000..bba3b59 --- /dev/null +++ b/src/reference_data/subsystems/voice.json @@ -0,0 +1,8 @@ +{ + "archive_name": "voice", + "package_name": "voice", + "module_count": 1, + "sample_files": [ + "voice/voiceModeEnabled.ts" + ] +} \ No newline at end of file diff --git a/src/reference_data/tools_snapshot.json b/src/reference_data/tools_snapshot.json new file mode 100644 index 0000000..3d4ac5f --- /dev/null +++ b/src/reference_data/tools_snapshot.json @@ -0,0 +1,922 @@ +[ + { + "name": "AgentTool", + "source_hint": "tools/AgentTool/AgentTool.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/AgentTool.tsx" + }, + { + "name": "UI", + "source_hint": "tools/AgentTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/UI.tsx" + }, + { + "name": "agentColorManager", + "source_hint": "tools/AgentTool/agentColorManager.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/agentColorManager.ts" + }, + { + "name": "agentDisplay", + "source_hint": "tools/AgentTool/agentDisplay.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/agentDisplay.ts" + }, + { + "name": "agentMemory", + "source_hint": "tools/AgentTool/agentMemory.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/agentMemory.ts" + }, + { + "name": "agentMemorySnapshot", + "source_hint": "tools/AgentTool/agentMemorySnapshot.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/agentMemorySnapshot.ts" + }, + { + "name": "agentToolUtils", + "source_hint": "tools/AgentTool/agentToolUtils.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/agentToolUtils.ts" + }, + { + "name": "clawCodeGuideAgent", + "source_hint": "tools/AgentTool/built-in/clawCodeGuideAgent.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/built-in/clawCodeGuideAgent.ts" + }, + { + "name": "exploreAgent", + "source_hint": "tools/AgentTool/built-in/exploreAgent.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/built-in/exploreAgent.ts" + }, + { + "name": "generalPurposeAgent", + "source_hint": "tools/AgentTool/built-in/generalPurposeAgent.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/built-in/generalPurposeAgent.ts" + }, + { + "name": "planAgent", + "source_hint": "tools/AgentTool/built-in/planAgent.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/built-in/planAgent.ts" + }, + { + "name": "statuslineSetup", + "source_hint": "tools/AgentTool/built-in/statuslineSetup.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/built-in/statuslineSetup.ts" + }, + { + "name": "verificationAgent", + "source_hint": "tools/AgentTool/built-in/verificationAgent.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/built-in/verificationAgent.ts" + }, + { + "name": "builtInAgents", + "source_hint": "tools/AgentTool/builtInAgents.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/builtInAgents.ts" + }, + { + "name": "constants", + "source_hint": "tools/AgentTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/constants.ts" + }, + { + "name": "forkSubagent", + "source_hint": "tools/AgentTool/forkSubagent.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/forkSubagent.ts" + }, + { + "name": "loadAgentsDir", + "source_hint": "tools/AgentTool/loadAgentsDir.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/loadAgentsDir.ts" + }, + { + "name": "prompt", + "source_hint": "tools/AgentTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/prompt.ts" + }, + { + "name": "resumeAgent", + "source_hint": "tools/AgentTool/resumeAgent.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/resumeAgent.ts" + }, + { + "name": "runAgent", + "source_hint": "tools/AgentTool/runAgent.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AgentTool/runAgent.ts" + }, + { + "name": "AskUserQuestionTool", + "source_hint": "tools/AskUserQuestionTool/AskUserQuestionTool.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AskUserQuestionTool/AskUserQuestionTool.tsx" + }, + { + "name": "prompt", + "source_hint": "tools/AskUserQuestionTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/AskUserQuestionTool/prompt.ts" + }, + { + "name": "BashTool", + "source_hint": "tools/BashTool/BashTool.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/BashTool.tsx" + }, + { + "name": "BashToolResultMessage", + "source_hint": "tools/BashTool/BashToolResultMessage.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/BashToolResultMessage.tsx" + }, + { + "name": "UI", + "source_hint": "tools/BashTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/UI.tsx" + }, + { + "name": "bashCommandHelpers", + "source_hint": "tools/BashTool/bashCommandHelpers.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/bashCommandHelpers.ts" + }, + { + "name": "bashPermissions", + "source_hint": "tools/BashTool/bashPermissions.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/bashPermissions.ts" + }, + { + "name": "bashSecurity", + "source_hint": "tools/BashTool/bashSecurity.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/bashSecurity.ts" + }, + { + "name": "commandSemantics", + "source_hint": "tools/BashTool/commandSemantics.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/commandSemantics.ts" + }, + { + "name": "commentLabel", + "source_hint": "tools/BashTool/commentLabel.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/commentLabel.ts" + }, + { + "name": "destructiveCommandWarning", + "source_hint": "tools/BashTool/destructiveCommandWarning.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/destructiveCommandWarning.ts" + }, + { + "name": "modeValidation", + "source_hint": "tools/BashTool/modeValidation.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/modeValidation.ts" + }, + { + "name": "pathValidation", + "source_hint": "tools/BashTool/pathValidation.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/pathValidation.ts" + }, + { + "name": "prompt", + "source_hint": "tools/BashTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/prompt.ts" + }, + { + "name": "readOnlyValidation", + "source_hint": "tools/BashTool/readOnlyValidation.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/readOnlyValidation.ts" + }, + { + "name": "sedEditParser", + "source_hint": "tools/BashTool/sedEditParser.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/sedEditParser.ts" + }, + { + "name": "sedValidation", + "source_hint": "tools/BashTool/sedValidation.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/sedValidation.ts" + }, + { + "name": "shouldUseSandbox", + "source_hint": "tools/BashTool/shouldUseSandbox.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/shouldUseSandbox.ts" + }, + { + "name": "toolName", + "source_hint": "tools/BashTool/toolName.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/toolName.ts" + }, + { + "name": "utils", + "source_hint": "tools/BashTool/utils.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BashTool/utils.ts" + }, + { + "name": "BriefTool", + "source_hint": "tools/BriefTool/BriefTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BriefTool/BriefTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/BriefTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BriefTool/UI.tsx" + }, + { + "name": "attachments", + "source_hint": "tools/BriefTool/attachments.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BriefTool/attachments.ts" + }, + { + "name": "prompt", + "source_hint": "tools/BriefTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BriefTool/prompt.ts" + }, + { + "name": "upload", + "source_hint": "tools/BriefTool/upload.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/BriefTool/upload.ts" + }, + { + "name": "ConfigTool", + "source_hint": "tools/ConfigTool/ConfigTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ConfigTool/ConfigTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/ConfigTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ConfigTool/UI.tsx" + }, + { + "name": "constants", + "source_hint": "tools/ConfigTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ConfigTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/ConfigTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ConfigTool/prompt.ts" + }, + { + "name": "supportedSettings", + "source_hint": "tools/ConfigTool/supportedSettings.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ConfigTool/supportedSettings.ts" + }, + { + "name": "EnterPlanModeTool", + "source_hint": "tools/EnterPlanModeTool/EnterPlanModeTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/EnterPlanModeTool/EnterPlanModeTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/EnterPlanModeTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/EnterPlanModeTool/UI.tsx" + }, + { + "name": "constants", + "source_hint": "tools/EnterPlanModeTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/EnterPlanModeTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/EnterPlanModeTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/EnterPlanModeTool/prompt.ts" + }, + { + "name": "EnterWorktreeTool", + "source_hint": "tools/EnterWorktreeTool/EnterWorktreeTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/EnterWorktreeTool/EnterWorktreeTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/EnterWorktreeTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/EnterWorktreeTool/UI.tsx" + }, + { + "name": "constants", + "source_hint": "tools/EnterWorktreeTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/EnterWorktreeTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/EnterWorktreeTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/EnterWorktreeTool/prompt.ts" + }, + { + "name": "ExitPlanModeV2Tool", + "source_hint": "tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts" + }, + { + "name": "UI", + "source_hint": "tools/ExitPlanModeTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ExitPlanModeTool/UI.tsx" + }, + { + "name": "constants", + "source_hint": "tools/ExitPlanModeTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ExitPlanModeTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/ExitPlanModeTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ExitPlanModeTool/prompt.ts" + }, + { + "name": "ExitWorktreeTool", + "source_hint": "tools/ExitWorktreeTool/ExitWorktreeTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ExitWorktreeTool/ExitWorktreeTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/ExitWorktreeTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ExitWorktreeTool/UI.tsx" + }, + { + "name": "constants", + "source_hint": "tools/ExitWorktreeTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ExitWorktreeTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/ExitWorktreeTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ExitWorktreeTool/prompt.ts" + }, + { + "name": "FileEditTool", + "source_hint": "tools/FileEditTool/FileEditTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileEditTool/FileEditTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/FileEditTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileEditTool/UI.tsx" + }, + { + "name": "constants", + "source_hint": "tools/FileEditTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileEditTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/FileEditTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileEditTool/prompt.ts" + }, + { + "name": "types", + "source_hint": "tools/FileEditTool/types.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileEditTool/types.ts" + }, + { + "name": "utils", + "source_hint": "tools/FileEditTool/utils.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileEditTool/utils.ts" + }, + { + "name": "FileReadTool", + "source_hint": "tools/FileReadTool/FileReadTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileReadTool/FileReadTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/FileReadTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileReadTool/UI.tsx" + }, + { + "name": "imageProcessor", + "source_hint": "tools/FileReadTool/imageProcessor.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileReadTool/imageProcessor.ts" + }, + { + "name": "limits", + "source_hint": "tools/FileReadTool/limits.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileReadTool/limits.ts" + }, + { + "name": "prompt", + "source_hint": "tools/FileReadTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileReadTool/prompt.ts" + }, + { + "name": "FileWriteTool", + "source_hint": "tools/FileWriteTool/FileWriteTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileWriteTool/FileWriteTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/FileWriteTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileWriteTool/UI.tsx" + }, + { + "name": "prompt", + "source_hint": "tools/FileWriteTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/FileWriteTool/prompt.ts" + }, + { + "name": "GlobTool", + "source_hint": "tools/GlobTool/GlobTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/GlobTool/GlobTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/GlobTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/GlobTool/UI.tsx" + }, + { + "name": "prompt", + "source_hint": "tools/GlobTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/GlobTool/prompt.ts" + }, + { + "name": "GrepTool", + "source_hint": "tools/GrepTool/GrepTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/GrepTool/GrepTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/GrepTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/GrepTool/UI.tsx" + }, + { + "name": "prompt", + "source_hint": "tools/GrepTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/GrepTool/prompt.ts" + }, + { + "name": "LSPTool", + "source_hint": "tools/LSPTool/LSPTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/LSPTool/LSPTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/LSPTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/LSPTool/UI.tsx" + }, + { + "name": "formatters", + "source_hint": "tools/LSPTool/formatters.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/LSPTool/formatters.ts" + }, + { + "name": "prompt", + "source_hint": "tools/LSPTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/LSPTool/prompt.ts" + }, + { + "name": "schemas", + "source_hint": "tools/LSPTool/schemas.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/LSPTool/schemas.ts" + }, + { + "name": "symbolContext", + "source_hint": "tools/LSPTool/symbolContext.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/LSPTool/symbolContext.ts" + }, + { + "name": "ListMcpResourcesTool", + "source_hint": "tools/ListMcpResourcesTool/ListMcpResourcesTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ListMcpResourcesTool/ListMcpResourcesTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/ListMcpResourcesTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ListMcpResourcesTool/UI.tsx" + }, + { + "name": "prompt", + "source_hint": "tools/ListMcpResourcesTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ListMcpResourcesTool/prompt.ts" + }, + { + "name": "MCPTool", + "source_hint": "tools/MCPTool/MCPTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/MCPTool/MCPTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/MCPTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/MCPTool/UI.tsx" + }, + { + "name": "classifyForCollapse", + "source_hint": "tools/MCPTool/classifyForCollapse.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/MCPTool/classifyForCollapse.ts" + }, + { + "name": "prompt", + "source_hint": "tools/MCPTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/MCPTool/prompt.ts" + }, + { + "name": "McpAuthTool", + "source_hint": "tools/McpAuthTool/McpAuthTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/McpAuthTool/McpAuthTool.ts" + }, + { + "name": "NotebookEditTool", + "source_hint": "tools/NotebookEditTool/NotebookEditTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/NotebookEditTool/NotebookEditTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/NotebookEditTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/NotebookEditTool/UI.tsx" + }, + { + "name": "constants", + "source_hint": "tools/NotebookEditTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/NotebookEditTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/NotebookEditTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/NotebookEditTool/prompt.ts" + }, + { + "name": "PowerShellTool", + "source_hint": "tools/PowerShellTool/PowerShellTool.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/PowerShellTool.tsx" + }, + { + "name": "UI", + "source_hint": "tools/PowerShellTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/UI.tsx" + }, + { + "name": "clmTypes", + "source_hint": "tools/PowerShellTool/clmTypes.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/clmTypes.ts" + }, + { + "name": "commandSemantics", + "source_hint": "tools/PowerShellTool/commandSemantics.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/commandSemantics.ts" + }, + { + "name": "commonParameters", + "source_hint": "tools/PowerShellTool/commonParameters.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/commonParameters.ts" + }, + { + "name": "destructiveCommandWarning", + "source_hint": "tools/PowerShellTool/destructiveCommandWarning.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/destructiveCommandWarning.ts" + }, + { + "name": "gitSafety", + "source_hint": "tools/PowerShellTool/gitSafety.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/gitSafety.ts" + }, + { + "name": "modeValidation", + "source_hint": "tools/PowerShellTool/modeValidation.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/modeValidation.ts" + }, + { + "name": "pathValidation", + "source_hint": "tools/PowerShellTool/pathValidation.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/pathValidation.ts" + }, + { + "name": "powershellPermissions", + "source_hint": "tools/PowerShellTool/powershellPermissions.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/powershellPermissions.ts" + }, + { + "name": "powershellSecurity", + "source_hint": "tools/PowerShellTool/powershellSecurity.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/powershellSecurity.ts" + }, + { + "name": "prompt", + "source_hint": "tools/PowerShellTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/prompt.ts" + }, + { + "name": "readOnlyValidation", + "source_hint": "tools/PowerShellTool/readOnlyValidation.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/readOnlyValidation.ts" + }, + { + "name": "toolName", + "source_hint": "tools/PowerShellTool/toolName.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/PowerShellTool/toolName.ts" + }, + { + "name": "constants", + "source_hint": "tools/REPLTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/REPLTool/constants.ts" + }, + { + "name": "primitiveTools", + "source_hint": "tools/REPLTool/primitiveTools.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/REPLTool/primitiveTools.ts" + }, + { + "name": "ReadMcpResourceTool", + "source_hint": "tools/ReadMcpResourceTool/ReadMcpResourceTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ReadMcpResourceTool/ReadMcpResourceTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/ReadMcpResourceTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ReadMcpResourceTool/UI.tsx" + }, + { + "name": "prompt", + "source_hint": "tools/ReadMcpResourceTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ReadMcpResourceTool/prompt.ts" + }, + { + "name": "RemoteTriggerTool", + "source_hint": "tools/RemoteTriggerTool/RemoteTriggerTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/RemoteTriggerTool/RemoteTriggerTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/RemoteTriggerTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/RemoteTriggerTool/UI.tsx" + }, + { + "name": "prompt", + "source_hint": "tools/RemoteTriggerTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/RemoteTriggerTool/prompt.ts" + }, + { + "name": "CronCreateTool", + "source_hint": "tools/ScheduleCronTool/CronCreateTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ScheduleCronTool/CronCreateTool.ts" + }, + { + "name": "CronDeleteTool", + "source_hint": "tools/ScheduleCronTool/CronDeleteTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ScheduleCronTool/CronDeleteTool.ts" + }, + { + "name": "CronListTool", + "source_hint": "tools/ScheduleCronTool/CronListTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ScheduleCronTool/CronListTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/ScheduleCronTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ScheduleCronTool/UI.tsx" + }, + { + "name": "prompt", + "source_hint": "tools/ScheduleCronTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ScheduleCronTool/prompt.ts" + }, + { + "name": "SendMessageTool", + "source_hint": "tools/SendMessageTool/SendMessageTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/SendMessageTool/SendMessageTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/SendMessageTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/SendMessageTool/UI.tsx" + }, + { + "name": "constants", + "source_hint": "tools/SendMessageTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/SendMessageTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/SendMessageTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/SendMessageTool/prompt.ts" + }, + { + "name": "SkillTool", + "source_hint": "tools/SkillTool/SkillTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/SkillTool/SkillTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/SkillTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/SkillTool/UI.tsx" + }, + { + "name": "constants", + "source_hint": "tools/SkillTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/SkillTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/SkillTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/SkillTool/prompt.ts" + }, + { + "name": "prompt", + "source_hint": "tools/SleepTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/SleepTool/prompt.ts" + }, + { + "name": "SyntheticOutputTool", + "source_hint": "tools/SyntheticOutputTool/SyntheticOutputTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/SyntheticOutputTool/SyntheticOutputTool.ts" + }, + { + "name": "TaskCreateTool", + "source_hint": "tools/TaskCreateTool/TaskCreateTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskCreateTool/TaskCreateTool.ts" + }, + { + "name": "constants", + "source_hint": "tools/TaskCreateTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskCreateTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/TaskCreateTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskCreateTool/prompt.ts" + }, + { + "name": "TaskGetTool", + "source_hint": "tools/TaskGetTool/TaskGetTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskGetTool/TaskGetTool.ts" + }, + { + "name": "constants", + "source_hint": "tools/TaskGetTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskGetTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/TaskGetTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskGetTool/prompt.ts" + }, + { + "name": "TaskListTool", + "source_hint": "tools/TaskListTool/TaskListTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskListTool/TaskListTool.ts" + }, + { + "name": "constants", + "source_hint": "tools/TaskListTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskListTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/TaskListTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskListTool/prompt.ts" + }, + { + "name": "TaskOutputTool", + "source_hint": "tools/TaskOutputTool/TaskOutputTool.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskOutputTool/TaskOutputTool.tsx" + }, + { + "name": "constants", + "source_hint": "tools/TaskOutputTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskOutputTool/constants.ts" + }, + { + "name": "TaskStopTool", + "source_hint": "tools/TaskStopTool/TaskStopTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskStopTool/TaskStopTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/TaskStopTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskStopTool/UI.tsx" + }, + { + "name": "prompt", + "source_hint": "tools/TaskStopTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskStopTool/prompt.ts" + }, + { + "name": "TaskUpdateTool", + "source_hint": "tools/TaskUpdateTool/TaskUpdateTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskUpdateTool/TaskUpdateTool.ts" + }, + { + "name": "constants", + "source_hint": "tools/TaskUpdateTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskUpdateTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/TaskUpdateTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TaskUpdateTool/prompt.ts" + }, + { + "name": "TeamCreateTool", + "source_hint": "tools/TeamCreateTool/TeamCreateTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TeamCreateTool/TeamCreateTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/TeamCreateTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TeamCreateTool/UI.tsx" + }, + { + "name": "constants", + "source_hint": "tools/TeamCreateTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TeamCreateTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/TeamCreateTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TeamCreateTool/prompt.ts" + }, + { + "name": "TeamDeleteTool", + "source_hint": "tools/TeamDeleteTool/TeamDeleteTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TeamDeleteTool/TeamDeleteTool.ts" + }, + { + "name": "UI", + "source_hint": "tools/TeamDeleteTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TeamDeleteTool/UI.tsx" + }, + { + "name": "constants", + "source_hint": "tools/TeamDeleteTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TeamDeleteTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/TeamDeleteTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TeamDeleteTool/prompt.ts" + }, + { + "name": "TodoWriteTool", + "source_hint": "tools/TodoWriteTool/TodoWriteTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TodoWriteTool/TodoWriteTool.ts" + }, + { + "name": "constants", + "source_hint": "tools/TodoWriteTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TodoWriteTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/TodoWriteTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/TodoWriteTool/prompt.ts" + }, + { + "name": "ToolSearchTool", + "source_hint": "tools/ToolSearchTool/ToolSearchTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ToolSearchTool/ToolSearchTool.ts" + }, + { + "name": "constants", + "source_hint": "tools/ToolSearchTool/constants.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ToolSearchTool/constants.ts" + }, + { + "name": "prompt", + "source_hint": "tools/ToolSearchTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/ToolSearchTool/prompt.ts" + }, + { + "name": "UI", + "source_hint": "tools/WebFetchTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/WebFetchTool/UI.tsx" + }, + { + "name": "WebFetchTool", + "source_hint": "tools/WebFetchTool/WebFetchTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/WebFetchTool/WebFetchTool.ts" + }, + { + "name": "preapproved", + "source_hint": "tools/WebFetchTool/preapproved.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/WebFetchTool/preapproved.ts" + }, + { + "name": "prompt", + "source_hint": "tools/WebFetchTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/WebFetchTool/prompt.ts" + }, + { + "name": "utils", + "source_hint": "tools/WebFetchTool/utils.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/WebFetchTool/utils.ts" + }, + { + "name": "UI", + "source_hint": "tools/WebSearchTool/UI.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/WebSearchTool/UI.tsx" + }, + { + "name": "WebSearchTool", + "source_hint": "tools/WebSearchTool/WebSearchTool.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/WebSearchTool/WebSearchTool.ts" + }, + { + "name": "prompt", + "source_hint": "tools/WebSearchTool/prompt.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/WebSearchTool/prompt.ts" + }, + { + "name": "gitOperationTracking", + "source_hint": "tools/shared/gitOperationTracking.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/shared/gitOperationTracking.ts" + }, + { + "name": "spawnMultiAgent", + "source_hint": "tools/shared/spawnMultiAgent.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/shared/spawnMultiAgent.ts" + }, + { + "name": "TestingPermissionTool", + "source_hint": "tools/testing/TestingPermissionTool.tsx", + "responsibility": "Tool module mirrored from archived TypeScript path tools/testing/TestingPermissionTool.tsx" + }, + { + "name": "utils", + "source_hint": "tools/utils.ts", + "responsibility": "Tool module mirrored from archived TypeScript path tools/utils.ts" + } +] \ No newline at end of file diff --git a/src/remote/__init__.py b/src/remote/__init__.py new file mode 100644 index 0000000..ae9ac1e --- /dev/null +++ b/src/remote/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `remote` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'remote.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/remote_runtime.py b/src/remote_runtime.py new file mode 100644 index 0000000..9dab999 --- /dev/null +++ b/src/remote_runtime.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class RuntimeModeReport: + mode: str + connected: bool + detail: str + + def as_text(self) -> str: + return f'mode={self.mode}\nconnected={self.connected}\ndetail={self.detail}' + + +def run_remote_mode(target: str) -> RuntimeModeReport: + return RuntimeModeReport('remote', True, f'Remote control placeholder prepared for {target}') + + +def run_ssh_mode(target: str) -> RuntimeModeReport: + return RuntimeModeReport('ssh', True, f'SSH proxy placeholder prepared for {target}') + + +def run_teleport_mode(target: str) -> RuntimeModeReport: + return RuntimeModeReport('teleport', True, f'Teleport resume/create placeholder prepared for {target}') diff --git a/src/replLauncher.py b/src/replLauncher.py new file mode 100644 index 0000000..c75a94d --- /dev/null +++ b/src/replLauncher.py @@ -0,0 +1,5 @@ +from __future__ import annotations + + +def build_repl_banner() -> str: + return 'Python porting REPL is not interactive yet; use `python3 -m src.main summary` instead.' diff --git a/src/runtime.py b/src/runtime.py new file mode 100644 index 0000000..c4116b7 --- /dev/null +++ b/src/runtime.py @@ -0,0 +1,192 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from .commands import PORTED_COMMANDS +from .context import PortContext, build_port_context, render_context +from .history import HistoryLog +from .models import PermissionDenial, PortingModule +from .query_engine import QueryEngineConfig, QueryEnginePort, TurnResult +from .setup import SetupReport, WorkspaceSetup, run_setup +from .system_init import build_system_init_message +from .tools import PORTED_TOOLS +from .execution_registry import build_execution_registry + + +@dataclass(frozen=True) +class RoutedMatch: + kind: str + name: str + source_hint: str + score: int + + +@dataclass +class RuntimeSession: + prompt: str + context: PortContext + setup: WorkspaceSetup + setup_report: SetupReport + system_init_message: str + history: HistoryLog + routed_matches: list[RoutedMatch] + turn_result: TurnResult + command_execution_messages: tuple[str, ...] + tool_execution_messages: tuple[str, ...] + stream_events: tuple[dict[str, object], ...] + persisted_session_path: str + + def as_markdown(self) -> str: + lines = [ + '# Runtime Session', + '', + f'Prompt: {self.prompt}', + '', + '## Context', + render_context(self.context), + '', + '## Setup', + f'- Python: {self.setup.python_version} ({self.setup.implementation})', + f'- Platform: {self.setup.platform_name}', + f'- Test command: {self.setup.test_command}', + '', + '## Startup Steps', + *(f'- {step}' for step in self.setup.startup_steps()), + '', + '## System Init', + self.system_init_message, + '', + '## Routed Matches', + ] + if self.routed_matches: + lines.extend( + f'- [{match.kind}] {match.name} ({match.score}) — {match.source_hint}' + for match in self.routed_matches + ) + else: + lines.append('- none') + lines.extend([ + '', + '## Command Execution', + *(self.command_execution_messages or ('none',)), + '', + '## Tool Execution', + *(self.tool_execution_messages or ('none',)), + '', + '## Stream Events', + *(f"- {event['type']}: {event}" for event in self.stream_events), + '', + '## Turn Result', + self.turn_result.output, + '', + f'Persisted session path: {self.persisted_session_path}', + '', + self.history.as_markdown(), + ]) + return '\n'.join(lines) + + +class PortRuntime: + def route_prompt(self, prompt: str, limit: int = 5) -> list[RoutedMatch]: + tokens = {token.lower() for token in prompt.replace('/', ' ').replace('-', ' ').split() if token} + by_kind = { + 'command': self._collect_matches(tokens, PORTED_COMMANDS, 'command'), + 'tool': self._collect_matches(tokens, PORTED_TOOLS, 'tool'), + } + + selected: list[RoutedMatch] = [] + for kind in ('command', 'tool'): + if by_kind[kind]: + selected.append(by_kind[kind].pop(0)) + + leftovers = sorted( + [match for matches in by_kind.values() for match in matches], + key=lambda item: (-item.score, item.kind, item.name), + ) + selected.extend(leftovers[: max(0, limit - len(selected))]) + return selected[:limit] + + def bootstrap_session(self, prompt: str, limit: int = 5) -> RuntimeSession: + context = build_port_context() + setup_report = run_setup(trusted=True) + setup = setup_report.setup + history = HistoryLog() + engine = QueryEnginePort.from_workspace() + history.add('context', f'python_files={context.python_file_count}, archive_available={context.archive_available}') + history.add('registry', f'commands={len(PORTED_COMMANDS)}, tools={len(PORTED_TOOLS)}') + matches = self.route_prompt(prompt, limit=limit) + registry = build_execution_registry() + command_execs = tuple(registry.command(match.name).execute(prompt) for match in matches if match.kind == 'command' and registry.command(match.name)) + tool_execs = tuple(registry.tool(match.name).execute(prompt) for match in matches if match.kind == 'tool' and registry.tool(match.name)) + denials = tuple(self._infer_permission_denials(matches)) + stream_events = tuple(engine.stream_submit_message( + prompt, + matched_commands=tuple(match.name for match in matches if match.kind == 'command'), + matched_tools=tuple(match.name for match in matches if match.kind == 'tool'), + denied_tools=denials, + )) + turn_result = engine.submit_message( + prompt, + matched_commands=tuple(match.name for match in matches if match.kind == 'command'), + matched_tools=tuple(match.name for match in matches if match.kind == 'tool'), + denied_tools=denials, + ) + persisted_session_path = engine.persist_session() + history.add('routing', f'matches={len(matches)} for prompt={prompt!r}') + history.add('execution', f'command_execs={len(command_execs)} tool_execs={len(tool_execs)}') + history.add('turn', f'commands={len(turn_result.matched_commands)} tools={len(turn_result.matched_tools)} denials={len(turn_result.permission_denials)} stop={turn_result.stop_reason}') + history.add('session_store', persisted_session_path) + return RuntimeSession( + prompt=prompt, + context=context, + setup=setup, + setup_report=setup_report, + system_init_message=build_system_init_message(trusted=True), + history=history, + routed_matches=matches, + turn_result=turn_result, + command_execution_messages=command_execs, + tool_execution_messages=tool_execs, + stream_events=stream_events, + persisted_session_path=persisted_session_path, + ) + + def run_turn_loop(self, prompt: str, limit: int = 5, max_turns: int = 3, structured_output: bool = False) -> list[TurnResult]: + engine = QueryEnginePort.from_workspace() + engine.config = QueryEngineConfig(max_turns=max_turns, structured_output=structured_output) + matches = self.route_prompt(prompt, limit=limit) + command_names = tuple(match.name for match in matches if match.kind == 'command') + tool_names = tuple(match.name for match in matches if match.kind == 'tool') + results: list[TurnResult] = [] + for turn in range(max_turns): + turn_prompt = prompt if turn == 0 else f'{prompt} [turn {turn + 1}]' + result = engine.submit_message(turn_prompt, command_names, tool_names, ()) + results.append(result) + if result.stop_reason != 'completed': + break + return results + + def _infer_permission_denials(self, matches: list[RoutedMatch]) -> list[PermissionDenial]: + denials: list[PermissionDenial] = [] + for match in matches: + if match.kind == 'tool' and 'bash' in match.name.lower(): + denials.append(PermissionDenial(tool_name=match.name, reason='destructive shell execution remains gated in the Python port')) + return denials + + def _collect_matches(self, tokens: set[str], modules: tuple[PortingModule, ...], kind: str) -> list[RoutedMatch]: + matches: list[RoutedMatch] = [] + for module in modules: + score = self._score(tokens, module) + if score > 0: + matches.append(RoutedMatch(kind=kind, name=module.name, source_hint=module.source_hint, score=score)) + matches.sort(key=lambda item: (-item.score, item.name)) + return matches + + @staticmethod + def _score(tokens: set[str], module: PortingModule) -> int: + haystacks = [module.name.lower(), module.source_hint.lower(), module.responsibility.lower()] + score = 0 + for token in tokens: + if any(token in haystack for haystack in haystacks): + score += 1 + return score diff --git a/src/schemas/__init__.py b/src/schemas/__init__.py new file mode 100644 index 0000000..16b84b0 --- /dev/null +++ b/src/schemas/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `schemas` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'schemas.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/screens/__init__.py b/src/screens/__init__.py new file mode 100644 index 0000000..2b1ef0d --- /dev/null +++ b/src/screens/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `screens` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'screens.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/server/__init__.py b/src/server/__init__.py new file mode 100644 index 0000000..b391d1d --- /dev/null +++ b/src/server/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `server` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'server.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/services/__init__.py b/src/services/__init__.py new file mode 100644 index 0000000..a7efae1 --- /dev/null +++ b/src/services/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `services` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'services.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/session_store.py b/src/session_store.py new file mode 100644 index 0000000..5f7502a --- /dev/null +++ b/src/session_store.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +import json +from dataclasses import asdict, dataclass +from pathlib import Path + + +@dataclass(frozen=True) +class StoredSession: + session_id: str + messages: tuple[str, ...] + input_tokens: int + output_tokens: int + + +DEFAULT_SESSION_DIR = Path('.port_sessions') + + +def save_session(session: StoredSession, directory: Path | None = None) -> Path: + target_dir = directory or DEFAULT_SESSION_DIR + target_dir.mkdir(parents=True, exist_ok=True) + path = target_dir / f'{session.session_id}.json' + path.write_text(json.dumps(asdict(session), indent=2)) + return path + + +def load_session(session_id: str, directory: Path | None = None) -> StoredSession: + target_dir = directory or DEFAULT_SESSION_DIR + data = json.loads((target_dir / f'{session_id}.json').read_text()) + return StoredSession( + session_id=data['session_id'], + messages=tuple(data['messages']), + input_tokens=data['input_tokens'], + output_tokens=data['output_tokens'], + ) diff --git a/src/setup.py b/src/setup.py new file mode 100644 index 0000000..b8e5a4d --- /dev/null +++ b/src/setup.py @@ -0,0 +1,77 @@ +from __future__ import annotations + +import platform +import sys +from dataclasses import dataclass +from pathlib import Path + +from .deferred_init import DeferredInitResult, run_deferred_init +from .prefetch import PrefetchResult, start_keychain_prefetch, start_mdm_raw_read, start_project_scan + + +@dataclass(frozen=True) +class WorkspaceSetup: + python_version: str + implementation: str + platform_name: str + test_command: str = 'python3 -m unittest discover -s tests -v' + + def startup_steps(self) -> tuple[str, ...]: + return ( + 'start top-level prefetch side effects', + 'build workspace context', + 'load mirrored command snapshot', + 'load mirrored tool snapshot', + 'prepare parity audit hooks', + 'apply trust-gated deferred init', + ) + + +@dataclass(frozen=True) +class SetupReport: + setup: WorkspaceSetup + prefetches: tuple[PrefetchResult, ...] + deferred_init: DeferredInitResult + trusted: bool + cwd: Path + + def as_markdown(self) -> str: + lines = [ + '# Setup Report', + '', + f'- Python: {self.setup.python_version} ({self.setup.implementation})', + f'- Platform: {self.setup.platform_name}', + f'- Trusted mode: {self.trusted}', + f'- CWD: {self.cwd}', + '', + 'Prefetches:', + *(f'- {prefetch.name}: {prefetch.detail}' for prefetch in self.prefetches), + '', + 'Deferred init:', + *self.deferred_init.as_lines(), + ] + return '\n'.join(lines) + + +def build_workspace_setup() -> WorkspaceSetup: + return WorkspaceSetup( + python_version='.'.join(str(part) for part in sys.version_info[:3]), + implementation=platform.python_implementation(), + platform_name=platform.platform(), + ) + + +def run_setup(cwd: Path | None = None, trusted: bool = True) -> SetupReport: + root = cwd or Path(__file__).resolve().parent.parent + prefetches = [ + start_mdm_raw_read(), + start_keychain_prefetch(), + start_project_scan(root), + ] + return SetupReport( + setup=build_workspace_setup(), + prefetches=tuple(prefetches), + deferred_init=run_deferred_init(trusted=trusted), + trusted=trusted, + cwd=root, + ) diff --git a/src/skills/__init__.py b/src/skills/__init__.py new file mode 100644 index 0000000..1dc4c96 --- /dev/null +++ b/src/skills/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `skills` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'skills.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/state/__init__.py b/src/state/__init__.py new file mode 100644 index 0000000..d1bde5a --- /dev/null +++ b/src/state/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `state` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'state.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/system_init.py b/src/system_init.py new file mode 100644 index 0000000..9f802bf --- /dev/null +++ b/src/system_init.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from .commands import built_in_command_names, get_commands +from .setup import run_setup +from .tools import get_tools + + +def build_system_init_message(trusted: bool = True) -> str: + setup = run_setup(trusted=trusted) + commands = get_commands() + tools = get_tools() + lines = [ + '# System Init', + '', + f'Trusted: {setup.trusted}', + f'Built-in command names: {len(built_in_command_names())}', + f'Loaded command entries: {len(commands)}', + f'Loaded tool entries: {len(tools)}', + '', + 'Startup steps:', + *(f'- {step}' for step in setup.setup.startup_steps()), + ] + return '\n'.join(lines) diff --git a/src/task.py b/src/task.py new file mode 100644 index 0000000..1676d62 --- /dev/null +++ b/src/task.py @@ -0,0 +1,5 @@ +from __future__ import annotations + +from .task import PortingTask + +__all__ = ['PortingTask'] diff --git a/src/tasks.py b/src/tasks.py new file mode 100644 index 0000000..432e459 --- /dev/null +++ b/src/tasks.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +from .task import PortingTask + + +def default_tasks() -> list[PortingTask]: + return [ + PortingTask('root-module-parity', 'Mirror the root module surface of the archived snapshot'), + PortingTask('directory-parity', 'Mirror top-level subsystem names as Python packages'), + PortingTask('parity-audit', 'Continuously measure parity against the local archive'), + ] diff --git a/src/tool_pool.py b/src/tool_pool.py new file mode 100644 index 0000000..428a35e --- /dev/null +++ b/src/tool_pool.py @@ -0,0 +1,37 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from .models import PortingModule +from .permissions import ToolPermissionContext +from .tools import get_tools + + +@dataclass(frozen=True) +class ToolPool: + tools: tuple[PortingModule, ...] + simple_mode: bool + include_mcp: bool + + def as_markdown(self) -> str: + lines = [ + '# Tool Pool', + '', + f'Simple mode: {self.simple_mode}', + f'Include MCP: {self.include_mcp}', + f'Tool count: {len(self.tools)}', + ] + lines.extend(f'- {tool.name} — {tool.source_hint}' for tool in self.tools[:15]) + return '\n'.join(lines) + + +def assemble_tool_pool( + simple_mode: bool = False, + include_mcp: bool = True, + permission_context: ToolPermissionContext | None = None, +) -> ToolPool: + return ToolPool( + tools=get_tools(simple_mode=simple_mode, include_mcp=include_mcp, permission_context=permission_context), + simple_mode=simple_mode, + include_mcp=include_mcp, + ) diff --git a/src/tools.py b/src/tools.py new file mode 100644 index 0000000..580a078 --- /dev/null +++ b/src/tools.py @@ -0,0 +1,96 @@ +from __future__ import annotations + +import json +from dataclasses import dataclass +from functools import lru_cache +from pathlib import Path + +from .models import PortingBacklog, PortingModule +from .permissions import ToolPermissionContext + +SNAPSHOT_PATH = Path(__file__).resolve().parent / 'reference_data' / 'tools_snapshot.json' + + +@dataclass(frozen=True) +class ToolExecution: + name: str + source_hint: str + payload: str + handled: bool + message: str + + +@lru_cache(maxsize=1) +def load_tool_snapshot() -> tuple[PortingModule, ...]: + raw_entries = json.loads(SNAPSHOT_PATH.read_text()) + return tuple( + PortingModule( + name=entry['name'], + responsibility=entry['responsibility'], + source_hint=entry['source_hint'], + status='mirrored', + ) + for entry in raw_entries + ) + + +PORTED_TOOLS = load_tool_snapshot() + + +def build_tool_backlog() -> PortingBacklog: + return PortingBacklog(title='Tool surface', modules=list(PORTED_TOOLS)) + + +def tool_names() -> list[str]: + return [module.name for module in PORTED_TOOLS] + + +def get_tool(name: str) -> PortingModule | None: + needle = name.lower() + for module in PORTED_TOOLS: + if module.name.lower() == needle: + return module + return None + + +def filter_tools_by_permission_context(tools: tuple[PortingModule, ...], permission_context: ToolPermissionContext | None = None) -> tuple[PortingModule, ...]: + if permission_context is None: + return tools + return tuple(module for module in tools if not permission_context.blocks(module.name)) + + +def get_tools( + simple_mode: bool = False, + include_mcp: bool = True, + permission_context: ToolPermissionContext | None = None, +) -> tuple[PortingModule, ...]: + tools = list(PORTED_TOOLS) + if simple_mode: + tools = [module for module in tools if module.name in {'BashTool', 'FileReadTool', 'FileEditTool'}] + if not include_mcp: + tools = [module for module in tools if 'mcp' not in module.name.lower() and 'mcp' not in module.source_hint.lower()] + return filter_tools_by_permission_context(tuple(tools), permission_context) + + +def find_tools(query: str, limit: int = 20) -> list[PortingModule]: + needle = query.lower() + matches = [module for module in PORTED_TOOLS if needle in module.name.lower() or needle in module.source_hint.lower()] + return matches[:limit] + + +def execute_tool(name: str, payload: str = '') -> ToolExecution: + module = get_tool(name) + if module is None: + return ToolExecution(name=name, source_hint='', payload=payload, handled=False, message=f'Unknown mirrored tool: {name}') + action = f"Mirrored tool '{module.name}' from {module.source_hint} would handle payload {payload!r}." + return ToolExecution(name=module.name, source_hint=module.source_hint, payload=payload, handled=True, message=action) + + +def render_tool_index(limit: int = 20, query: str | None = None) -> str: + modules = find_tools(query, limit) if query else list(PORTED_TOOLS[:limit]) + lines = [f'Tool entries: {len(PORTED_TOOLS)}', ''] + if query: + lines.append(f'Filtered by: {query}') + lines.append('') + lines.extend(f'- {module.name} — {module.source_hint}' for module in modules) + return '\n'.join(lines) diff --git a/src/transcript.py b/src/transcript.py new file mode 100644 index 0000000..0221ca2 --- /dev/null +++ b/src/transcript.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from dataclasses import dataclass, field + + +@dataclass +class TranscriptStore: + entries: list[str] = field(default_factory=list) + flushed: bool = False + + def append(self, entry: str) -> None: + self.entries.append(entry) + self.flushed = False + + def compact(self, keep_last: int = 10) -> None: + if len(self.entries) > keep_last: + self.entries[:] = self.entries[-keep_last:] + + def replay(self) -> tuple[str, ...]: + return tuple(self.entries) + + def flush(self) -> None: + self.flushed = True diff --git a/src/types/__init__.py b/src/types/__init__.py new file mode 100644 index 0000000..55375d2 --- /dev/null +++ b/src/types/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `types` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'types.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/upstreamproxy/__init__.py b/src/upstreamproxy/__init__.py new file mode 100644 index 0000000..d4c3675 --- /dev/null +++ b/src/upstreamproxy/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `upstreamproxy` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'upstreamproxy.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/utils/__init__.py b/src/utils/__init__.py new file mode 100644 index 0000000..5774ef5 --- /dev/null +++ b/src/utils/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `utils` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'utils.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/vim/__init__.py b/src/vim/__init__.py new file mode 100644 index 0000000..fed972f --- /dev/null +++ b/src/vim/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `vim` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'vim.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/src/voice/__init__.py b/src/voice/__init__.py new file mode 100644 index 0000000..ef3c929 --- /dev/null +++ b/src/voice/__init__.py @@ -0,0 +1,16 @@ +"""Python package placeholder for the archived `voice` subsystem.""" + +from __future__ import annotations + +import json +from pathlib import Path + +SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'voice.json' +_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text()) + +ARCHIVE_NAME = _SNAPSHOT['archive_name'] +MODULE_COUNT = _SNAPSHOT['module_count'] +SAMPLE_FILES = tuple(_SNAPSHOT['sample_files']) +PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references." + +__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES'] diff --git a/tests/test_porting_workspace.py b/tests/test_porting_workspace.py new file mode 100644 index 0000000..b332467 --- /dev/null +++ b/tests/test_porting_workspace.py @@ -0,0 +1,248 @@ +from __future__ import annotations + +import subprocess +import sys +import unittest +from pathlib import Path + +from src.commands import PORTED_COMMANDS +from src.parity_audit import run_parity_audit +from src.port_manifest import build_port_manifest +from src.query_engine import QueryEnginePort +from src.tools import PORTED_TOOLS + + +class PortingWorkspaceTests(unittest.TestCase): + def test_manifest_counts_python_files(self) -> None: + manifest = build_port_manifest() + self.assertGreaterEqual(manifest.total_python_files, 20) + self.assertTrue(manifest.top_level_modules) + + def test_query_engine_summary_mentions_workspace(self) -> None: + summary = QueryEnginePort.from_workspace().render_summary() + self.assertIn('Python Porting Workspace Summary', summary) + self.assertIn('Command surface:', summary) + self.assertIn('Tool surface:', summary) + + def test_cli_summary_runs(self) -> None: + result = subprocess.run( + [sys.executable, '-m', 'src.main', 'summary'], + check=True, + capture_output=True, + text=True, + ) + self.assertIn('Python Porting Workspace Summary', result.stdout) + + def test_parity_audit_runs(self) -> None: + result = subprocess.run( + [sys.executable, '-m', 'src.main', 'parity-audit'], + check=True, + capture_output=True, + text=True, + ) + self.assertIn('Parity Audit', result.stdout) + + def test_root_file_coverage_is_complete_when_local_archive_exists(self) -> None: + audit = run_parity_audit() + if audit.archive_present: + self.assertEqual(audit.root_file_coverage[0], audit.root_file_coverage[1]) + self.assertGreaterEqual(audit.directory_coverage[0], 28) + self.assertGreaterEqual(audit.command_entry_ratio[0], 150) + self.assertGreaterEqual(audit.tool_entry_ratio[0], 100) + + def test_command_and_tool_snapshots_are_nontrivial(self) -> None: + self.assertGreaterEqual(len(PORTED_COMMANDS), 150) + self.assertGreaterEqual(len(PORTED_TOOLS), 100) + + def test_commands_and_tools_cli_run(self) -> None: + commands_result = subprocess.run( + [sys.executable, '-m', 'src.main', 'commands', '--limit', '5', '--query', 'review'], + check=True, + capture_output=True, + text=True, + ) + tools_result = subprocess.run( + [sys.executable, '-m', 'src.main', 'tools', '--limit', '5', '--query', 'MCP'], + check=True, + capture_output=True, + text=True, + ) + self.assertIn('Command entries:', commands_result.stdout) + self.assertIn('Tool entries:', tools_result.stdout) + + def test_subsystem_packages_expose_archive_metadata(self) -> None: + from src import assistant, bridge, utils + + self.assertGreater(assistant.MODULE_COUNT, 0) + self.assertGreater(bridge.MODULE_COUNT, 0) + self.assertGreater(utils.MODULE_COUNT, 100) + self.assertTrue(utils.SAMPLE_FILES) + + def test_route_and_show_entry_cli_run(self) -> None: + route_result = subprocess.run( + [sys.executable, '-m', 'src.main', 'route', 'review MCP tool', '--limit', '5'], + check=True, + capture_output=True, + text=True, + ) + show_command = subprocess.run( + [sys.executable, '-m', 'src.main', 'show-command', 'review'], + check=True, + capture_output=True, + text=True, + ) + show_tool = subprocess.run( + [sys.executable, '-m', 'src.main', 'show-tool', 'MCPTool'], + check=True, + capture_output=True, + text=True, + ) + self.assertIn('review', route_result.stdout.lower()) + self.assertIn('review', show_command.stdout.lower()) + self.assertIn('mcptool', show_tool.stdout.lower()) + + def test_bootstrap_cli_runs(self) -> None: + result = subprocess.run( + [sys.executable, '-m', 'src.main', 'bootstrap', 'review MCP tool', '--limit', '5'], + check=True, + capture_output=True, + text=True, + ) + self.assertIn('Runtime Session', result.stdout) + self.assertIn('Startup Steps', result.stdout) + self.assertIn('Routed Matches', result.stdout) + + def test_bootstrap_session_tracks_turn_state(self) -> None: + from src.runtime import PortRuntime + + session = PortRuntime().bootstrap_session('review MCP tool', limit=5) + self.assertGreaterEqual(len(session.turn_result.matched_tools), 1) + self.assertIn('Prompt:', session.turn_result.output) + self.assertGreaterEqual(session.turn_result.usage.input_tokens, 1) + + def test_exec_command_and_tool_cli_run(self) -> None: + command_result = subprocess.run( + [sys.executable, '-m', 'src.main', 'exec-command', 'review', 'inspect security review'], + check=True, + capture_output=True, + text=True, + ) + tool_result = subprocess.run( + [sys.executable, '-m', 'src.main', 'exec-tool', 'MCPTool', 'fetch resource list'], + check=True, + capture_output=True, + text=True, + ) + self.assertIn("Mirrored command 'review'", command_result.stdout) + self.assertIn("Mirrored tool 'MCPTool'", tool_result.stdout) + + def test_setup_report_and_registry_filters_run(self) -> None: + setup_result = subprocess.run( + [sys.executable, '-m', 'src.main', 'setup-report'], + check=True, + capture_output=True, + text=True, + ) + command_result = subprocess.run( + [sys.executable, '-m', 'src.main', 'commands', '--limit', '5', '--no-plugin-commands'], + check=True, + capture_output=True, + text=True, + ) + tool_result = subprocess.run( + [sys.executable, '-m', 'src.main', 'tools', '--limit', '5', '--simple-mode', '--no-mcp'], + check=True, + capture_output=True, + text=True, + ) + self.assertIn('Setup Report', setup_result.stdout) + self.assertIn('Command entries:', command_result.stdout) + self.assertIn('Tool entries:', tool_result.stdout) + + def test_load_session_cli_runs(self) -> None: + from src.runtime import PortRuntime + + session = PortRuntime().bootstrap_session('review MCP tool', limit=5) + session_id = Path(session.persisted_session_path).stem + result = subprocess.run( + [sys.executable, '-m', 'src.main', 'load-session', session_id], + check=True, + capture_output=True, + text=True, + ) + self.assertIn(session_id, result.stdout) + self.assertIn('messages', result.stdout) + + def test_tool_permission_filtering_cli_runs(self) -> None: + result = subprocess.run( + [sys.executable, '-m', 'src.main', 'tools', '--limit', '10', '--deny-prefix', 'mcp'], + check=True, + capture_output=True, + text=True, + ) + self.assertIn('Tool entries:', result.stdout) + self.assertNotIn('MCPTool', result.stdout) + + def test_turn_loop_cli_runs(self) -> None: + result = subprocess.run( + [sys.executable, '-m', 'src.main', 'turn-loop', 'review MCP tool', '--max-turns', '2', '--structured-output'], + check=True, + capture_output=True, + text=True, + ) + self.assertIn('## Turn 1', result.stdout) + self.assertIn('stop_reason=', result.stdout) + + def test_remote_mode_clis_run(self) -> None: + remote_result = subprocess.run([sys.executable, '-m', 'src.main', 'remote-mode', 'workspace'], check=True, capture_output=True, text=True) + ssh_result = subprocess.run([sys.executable, '-m', 'src.main', 'ssh-mode', 'workspace'], check=True, capture_output=True, text=True) + teleport_result = subprocess.run([sys.executable, '-m', 'src.main', 'teleport-mode', 'workspace'], check=True, capture_output=True, text=True) + self.assertIn('mode=remote', remote_result.stdout) + self.assertIn('mode=ssh', ssh_result.stdout) + self.assertIn('mode=teleport', teleport_result.stdout) + + def test_flush_transcript_cli_runs(self) -> None: + result = subprocess.run( + [sys.executable, '-m', 'src.main', 'flush-transcript', 'review MCP tool'], + check=True, + capture_output=True, + text=True, + ) + self.assertIn('flushed=True', result.stdout) + + def test_command_graph_and_tool_pool_cli_run(self) -> None: + command_graph = subprocess.run([sys.executable, '-m', 'src.main', 'command-graph'], check=True, capture_output=True, text=True) + tool_pool = subprocess.run([sys.executable, '-m', 'src.main', 'tool-pool'], check=True, capture_output=True, text=True) + self.assertIn('Command Graph', command_graph.stdout) + self.assertIn('Tool Pool', tool_pool.stdout) + + def test_setup_report_mentions_deferred_init(self) -> None: + result = subprocess.run( + [sys.executable, '-m', 'src.main', 'setup-report'], + check=True, + capture_output=True, + text=True, + ) + self.assertIn('Deferred init:', result.stdout) + self.assertIn('plugin_init=True', result.stdout) + + def test_execution_registry_runs(self) -> None: + from src.execution_registry import build_execution_registry + + registry = build_execution_registry() + self.assertGreaterEqual(len(registry.commands), 150) + self.assertGreaterEqual(len(registry.tools), 100) + self.assertIn('Mirrored command', registry.command('review').execute('review security')) + self.assertIn('Mirrored tool', registry.tool('MCPTool').execute('fetch mcp resources')) + + def test_bootstrap_graph_and_direct_modes_run(self) -> None: + graph_result = subprocess.run([sys.executable, '-m', 'src.main', 'bootstrap-graph'], check=True, capture_output=True, text=True) + direct_result = subprocess.run([sys.executable, '-m', 'src.main', 'direct-connect-mode', 'workspace'], check=True, capture_output=True, text=True) + deep_link_result = subprocess.run([sys.executable, '-m', 'src.main', 'deep-link-mode', 'workspace'], check=True, capture_output=True, text=True) + self.assertIn('Bootstrap Graph', graph_result.stdout) + self.assertIn('mode=direct-connect', direct_result.stdout) + self.assertIn('mode=deep-link', deep_link_result.stdout) + + +if __name__ == '__main__': + unittest.main()