claw-code 源码详细分析:Remote / SSH / Teleport / Deep Link——运行时分支爆炸怎样用「模拟模式」先收束状态机?
涉及源码:
src/remote_runtime.py、src/direct_modes.py、src/main.py、src/bootstrap_graph.py,tests/test_porting_workspace.py。
1. 分支爆炸在说什么
真实 Agent/IDE Harness 里,「当前跑在哪」往往不是二元的,而是多维组合:
- 控制面:本机进程 / 远程控制会话 / SSH 到另一台机器 /「Teleport」类工作区跳转;
- 链路面:直连后端 / 经上游代理 / 深链唤起带 query;
- 数据面:
cwd、凭证、环境变量、信任门是否打开、是否允许执行 shell。
若一开始就把这些全部写进bootstrap_session或QueryEnginePort,会出现:
- 条件组合指数级增长,单测难以覆盖;
- 网络/flaky与业务逻辑缠在一起,排障困难;
- CLI 与 UI难以对齐「同一种模式」的命名。
模拟模式策略是:先把「有哪些模式」和「每种模式对外暴露什么最小状态」钉死,实现体暂时是占位返回值,从而收束状态机的对外边界,再接真实 I/O。
2. 本仓库里的两块实现:remote_runtimevsdirect_modes
2.1 远程族:RuntimeModeReport(remote / ssh / teleport)
# 6:25:src/remote_runtime.py@dataclass(frozen=True)classRuntimeModeReport:mode:strconnected:booldetail:strdefas_text(self)->str:returnf'mode={self.mode}\nconnected={self.connected}\ndetail={self.detail}'defrun_remote_mode(target:str)->RuntimeModeReport:returnRuntimeModeReport('remote',True,f'Remote control placeholder prepared for{target}')defrun_ssh_mode(target:str)->RuntimeModeReport:returnRuntimeModeReport('ssh',True,f'SSH proxy placeholder prepared for{target}')defrun_teleport_mode(target:str)->RuntimeModeReport:returnRuntimeModeReport('teleport',True,f'Teleport resume/create placeholder prepared for{target}')收束点:
- 一模式一函数:
run_remote_mode/run_ssh_mode/run_teleport_mode,入口清晰,未来可在函数内换实现而不扩散调用点。 - 报告结构固定:
mode+connected+detail,CLI 与人类 diff 都稳定。 - 无网络、无子进程:移植期确定性输出,CI 只断言
mode=...子串即可。
2.2 直连族:DirectModeReport(direct-connect / deep-link)
# 6:21:src/direct_modes.py@dataclass(frozen=True)classDirectModeReport:mode:strtarget:stractive:booldefas_text(self)->str:returnf'mode={self.mode}\ntarget={self.target}\nactive={self.active}'defrun_direct_connect(target:str)->DirectModeReport:returnDirectModeReport(mode='direct-connect',target=target,active=True)defrun_deep_link(target:str)->DirectModeReport:returnDirectModeReport(mode='deep-link',target=target,active=True)收束点:显式保留target(深链 URI、工作区 id 等未来可解析),与远程族用detail字符串承载上下文略有不同——属于演进期可统一的报告形状(例如将来抽共用ModeReport基类)。
3. CLI:一子命令一模态,help 写明 simulate
# 68:77:src/main.pyremote_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')# 171:185:src/main.pyifargs.command=='remote-mode':print(run_remote_mode(args.target).as_text())return0ifargs.command=='ssh-mode':print(run_ssh_mode(args.target).as_text())return0ifargs.command=='teleport-mode':print(run_teleport_mode(args.target).as_text())return0ifargs.command=='direct-connect-mode':print(run_direct_connect(args.target).as_text())return0ifargs.command=='deep-link-mode':print(run_deep_link(args.target).as_text())return0收束状态机的方式:
- 用户意图 → 子命令即离散状态,不靠「再猜一个 flag 组合」。
target是唯一自由变量,先统一成字符串,后续再在各自run_*内做解析/校验。- 与
bootstrap/turn-loop解耦:当前PortRuntime.bootstrap_session不读取这些模式——避免「单条命令里藏六种 runtime」,先把模式探针做成独立 CLI,符合分阶段集成。
4. 测试如何把「模式」钉成契约
# 196:202:tests/test_porting_workspace.pydeftest_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)# 238:244:tests/test_porting_workspace.pydeftest_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)学习点:断言稳定键(mode=...),不断言占位文案全文——占位升级时少碎测试。
5. 与「启动叙事」对齐:bootstrap_graph
# 16:26:src/bootstrap_graph.pydefbuild_bootstrap_graph()->BootstrapGraph:returnBootstrapGraph(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',))作用:在文档/评审层把模式路由标成独立阶段,与query engine submit loop前后分明——提醒实现者:先定 mode,再进会话循环,而不是在循环里隐式猜环境。
6. 与src/remote/占位包的关系
src/remote/等目录通过reference_data/subsystems/remote.json挂归档体量元数据(见result/12.md),代表未来真实远程子系统的代码位置;
当前可执行的「模式探针」在remote_runtime.py/direct_modes.py+main,二者分层:先 CLI 契约与小报告对象,再填包内实现。
7. 后续接真实现时的建议(仍防爆炸)
- 统一
RuntimeContext或SessionTransport:内含mode: Enum、target: str、可选credentials_handle,由单一工厂根据 CLI/配置构造,避免在十处if ssh。 - 真实连接失败→ 仍返回结构化报告(
connected=False,detail=错误原因),与现在形状兼容,便于 UI 与日志。 - 再把 mode 注入
bootstrap_session:例如PortRuntime.bootstrap_session(..., transport=...),单测里注入 fake transport,保持无网可跑。 - 组合爆炸用表驱动测试:
(mode, target_validity) -> expected_report,而非复制五个集成测试。
8. 小结
- Remote / SSH / Teleport / Direct-connect / Deep-link在本仓库中通过独立子命令 + 小型不可变报告 dataclass + 纯函数入口实现模拟模式。
- 状态机被收束在:离散 CLI 分支、固定文本键
mode=、与核心bootstrap_session暂时分离三层。 - bootstrap_graph把「mode routing」写成显式阶段,与submit loop解耦叙事。
- 这是典型Harness 移植节奏:先可测、无 I/O 的模态面,再填远程包与真实链路。
