@zergai/ztc 0.4.0-beta.1 → 0.5.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (718) hide show
  1. package/README.md +398 -45
  2. package/RUST_THIRD_PARTY_LICENSES.txt +1080 -822
  3. package/THIRD_PARTY_NOTICES.md +273 -12
  4. package/bin/zmux-darwin-arm64 +0 -0
  5. package/bin/ztc-audio-darwin-arm64 +0 -0
  6. package/bin/ztc-capture-darwin-arm64 +0 -0
  7. package/bin/ztc-computer-darwin-arm64 +0 -0
  8. package/bin/ztc-llm-darwin-arm64 +0 -0
  9. package/bin/ztc-tts-darwin-arm64 +0 -0
  10. package/bin/ztc-tui-darwin-arm64 +0 -0
  11. package/bin/ztc-zlicky-overlay-darwin-arm64 +0 -0
  12. package/bin/zterm-darwin-arm64 +0 -0
  13. package/dist/App.js +1206 -209
  14. package/dist/agent/agent.d.ts +74 -8
  15. package/dist/agent/agent.js +1073 -184
  16. package/dist/agent/backends/account_rotation.d.ts +4 -0
  17. package/dist/agent/backends/account_rotation.js +8 -2
  18. package/dist/agent/backends/anthropic.d.ts +13 -0
  19. package/dist/agent/backends/anthropic.js +169 -28
  20. package/dist/agent/backends/claude_cli.js +18 -8
  21. package/dist/agent/backends/codex_app_server.d.ts +1 -0
  22. package/dist/agent/backends/codex_app_server.js +55 -3
  23. package/dist/agent/backends/codex_auth.d.ts +1 -0
  24. package/dist/agent/backends/codex_auth.js +67 -13
  25. package/dist/agent/backends/codex_buffered_recovery.d.ts +27 -0
  26. package/dist/agent/backends/codex_buffered_recovery.js +293 -0
  27. package/dist/agent/backends/gemini.js +3 -1
  28. package/dist/agent/backends/http_error.d.ts +26 -0
  29. package/dist/agent/backends/http_error.js +221 -0
  30. package/dist/agent/backends/index.d.ts +9 -2
  31. package/dist/agent/backends/index.js +22 -2
  32. package/dist/agent/backends/openai.d.ts +0 -6
  33. package/dist/agent/backends/openai.js +5 -2
  34. package/dist/agent/backends/openai_compatible.d.ts +5 -4
  35. package/dist/agent/backends/openai_compatible.js +26 -19
  36. package/dist/agent/backends/openai_responses.d.ts +8 -3
  37. package/dist/agent/backends/openai_responses.js +77 -33
  38. package/dist/agent/backends/provider_ids.d.ts +1 -0
  39. package/dist/agent/backends/provider_ids.js +4 -0
  40. package/dist/agent/backends/request_metrics.js +12 -2
  41. package/dist/agent/backends/types.d.ts +109 -6
  42. package/dist/agent/backends/types.js +5 -1
  43. package/dist/agent/backends/zrouter_stream.d.ts +6 -1
  44. package/dist/agent/backends/zrouter_stream.js +160 -42
  45. package/dist/agent/background_registry.d.ts +2 -0
  46. package/dist/agent/background_registry.js +1 -0
  47. package/dist/agent/claim_observation.d.ts +6 -0
  48. package/dist/agent/claim_observation.js +54 -0
  49. package/dist/agent/commands/accounts.js +46 -177
  50. package/dist/agent/commands/attention.d.ts +2 -0
  51. package/dist/agent/commands/attention.js +67 -0
  52. package/dist/agent/commands/auth.js +18 -2
  53. package/dist/agent/commands/board.d.ts +2 -0
  54. package/dist/agent/commands/board.js +169 -0
  55. package/dist/agent/commands/clipboard.js +50 -1
  56. package/dist/agent/commands/compact.js +21 -13
  57. package/dist/agent/commands/config.js +4 -1
  58. package/dist/agent/commands/context.js +6 -1
  59. package/dist/agent/commands/desktop.d.ts +2 -0
  60. package/dist/agent/commands/desktop.js +29 -0
  61. package/dist/agent/commands/effort.js +14 -6
  62. package/dist/agent/commands/environment.d.ts +3 -0
  63. package/dist/agent/commands/environment.js +109 -0
  64. package/dist/agent/commands/evidence.d.ts +2 -0
  65. package/dist/agent/commands/evidence.js +9 -0
  66. package/dist/agent/commands/fork.js +4 -3
  67. package/dist/agent/commands/goal.d.ts +33 -1
  68. package/dist/agent/commands/goal.js +174 -14
  69. package/dist/agent/commands/goal_exit.d.ts +36 -0
  70. package/dist/agent/commands/goal_exit.js +120 -0
  71. package/dist/agent/commands/help.js +3 -1
  72. package/dist/agent/commands/history.js +3 -1
  73. package/dist/agent/commands/inbox.d.ts +2 -0
  74. package/dist/agent/commands/inbox.js +148 -0
  75. package/dist/agent/commands/index.js +16 -1
  76. package/dist/agent/commands/input_mode.js +8 -6
  77. package/dist/agent/commands/job.d.ts +2 -0
  78. package/dist/agent/commands/job.js +93 -0
  79. package/dist/agent/commands/keybindings.js +4 -1
  80. package/dist/agent/commands/label.d.ts +2 -0
  81. package/dist/agent/commands/label.js +77 -0
  82. package/dist/agent/commands/layout.d.ts +2 -0
  83. package/dist/agent/commands/layout.js +20 -0
  84. package/dist/agent/commands/mirror.js +16 -1
  85. package/dist/agent/commands/model.js +12 -2
  86. package/dist/agent/commands/permissions.d.ts +3 -1
  87. package/dist/agent/commands/permissions.js +79 -89
  88. package/dist/agent/commands/plan.js +5 -15
  89. package/dist/agent/commands/profile.js +21 -2
  90. package/dist/agent/commands/provider_selection.js +20 -1
  91. package/dist/agent/commands/rename.js +1 -1
  92. package/dist/agent/commands/resources.d.ts +2 -0
  93. package/dist/agent/commands/resources.js +67 -0
  94. package/dist/agent/commands/rewind.d.ts +3 -0
  95. package/dist/agent/commands/rewind.js +16 -0
  96. package/dist/agent/commands/runbooks.d.ts +2 -0
  97. package/dist/agent/commands/runbooks.js +73 -0
  98. package/dist/agent/commands/runbooks_lazy.d.ts +2 -0
  99. package/dist/agent/commands/runbooks_lazy.js +8 -0
  100. package/dist/agent/commands/sessions.d.ts +1 -1
  101. package/dist/agent/commands/sessions.js +33 -5
  102. package/dist/agent/commands/settings.js +185 -39
  103. package/dist/agent/commands/setup.d.ts +2 -0
  104. package/dist/agent/commands/setup.js +78 -0
  105. package/dist/agent/commands/share.d.ts +2 -0
  106. package/dist/agent/commands/share.js +64 -0
  107. package/dist/agent/commands/status.js +14 -2
  108. package/dist/agent/commands/types.d.ts +99 -6
  109. package/dist/agent/commands/update.js +8 -0
  110. package/dist/agent/commands/usage.d.ts +2 -0
  111. package/dist/agent/commands/usage.js +8 -0
  112. package/dist/agent/factory.d.ts +11 -0
  113. package/dist/agent/factory.js +113 -88
  114. package/dist/agent/loop_policy.d.ts +6 -3
  115. package/dist/agent/loop_policy.js +12 -3
  116. package/dist/agent/measurement_guidance.d.ts +2 -0
  117. package/dist/agent/measurement_guidance.js +5 -0
  118. package/dist/agent/request_encoder.d.ts +8 -1
  119. package/dist/agent/request_encoder.js +95 -23
  120. package/dist/agent/runtime/benchmark_comparison.d.ts +30 -0
  121. package/dist/agent/runtime/benchmark_comparison.js +94 -0
  122. package/dist/agent/runtime/benchmark_contract.d.ts +48 -0
  123. package/dist/agent/runtime/benchmark_contract.js +90 -0
  124. package/dist/agent/runtime/checked_commands.d.ts +32 -0
  125. package/dist/agent/runtime/checked_commands.js +119 -0
  126. package/dist/agent/runtime/command_execution_policy.d.ts +26 -0
  127. package/dist/agent/runtime/command_execution_policy.js +91 -0
  128. package/dist/agent/runtime/command_jobs.d.ts +36 -18
  129. package/dist/agent/runtime/command_jobs.js +151 -13
  130. package/dist/agent/runtime/command_panes.d.ts +59 -0
  131. package/dist/agent/runtime/command_panes.js +398 -0
  132. package/dist/agent/runtime/command_wait.d.ts +19 -0
  133. package/dist/agent/runtime/command_wait.js +167 -0
  134. package/dist/agent/runtime/cpu_benchmark.d.ts +30 -0
  135. package/dist/agent/runtime/cpu_benchmark.js +126 -0
  136. package/dist/agent/runtime/delegated_evidence.d.ts +26 -0
  137. package/dist/agent/runtime/delegated_evidence.js +80 -0
  138. package/dist/agent/runtime/evidence.d.ts +127 -0
  139. package/dist/agent/runtime/evidence.js +468 -0
  140. package/dist/agent/runtime/execution_context.d.ts +7 -0
  141. package/dist/agent/runtime/execution_context.js +39 -3
  142. package/dist/agent/runtime/json_verifier_recipe.d.ts +8 -0
  143. package/dist/agent/runtime/json_verifier_recipe.js +66 -0
  144. package/dist/agent/runtime/measurements.d.ts +110 -0
  145. package/dist/agent/runtime/measurements.js +317 -0
  146. package/dist/agent/runtime/policy.d.ts +4 -0
  147. package/dist/agent/runtime/policy.js +31 -20
  148. package/dist/agent/runtime/provider_native_evidence.d.ts +20 -0
  149. package/dist/agent/runtime/provider_native_evidence.js +86 -0
  150. package/dist/agent/runtime/recovery.d.ts +2 -0
  151. package/dist/agent/runtime/recovery.js +45 -2
  152. package/dist/agent/runtime/remote_broker_transport.d.ts +10 -0
  153. package/dist/agent/runtime/remote_broker_transport.js +84 -0
  154. package/dist/agent/runtime/remote_deletion_receipts.d.ts +3 -0
  155. package/dist/agent/runtime/remote_deletion_receipts.js +43 -0
  156. package/dist/agent/runtime/remote_journal_replay.d.ts +13 -0
  157. package/dist/agent/runtime/remote_journal_replay.js +233 -0
  158. package/dist/agent/runtime/remote_mutation_journal.d.ts +25 -0
  159. package/dist/agent/runtime/remote_mutation_journal.js +208 -0
  160. package/dist/agent/runtime/remote_resource_endpoint.d.ts +7 -0
  161. package/dist/agent/runtime/remote_resource_endpoint.js +6 -0
  162. package/dist/agent/runtime/remote_resource_errors.d.ts +5 -0
  163. package/dist/agent/runtime/remote_resource_errors.js +9 -0
  164. package/dist/agent/runtime/remote_resource_script.d.ts +2 -0
  165. package/dist/agent/runtime/remote_resource_script.js +1009 -0
  166. package/dist/agent/runtime/remote_resources.d.ts +29 -0
  167. package/dist/agent/runtime/remote_resources.js +160 -0
  168. package/dist/agent/runtime/source_verification.d.ts +12 -0
  169. package/dist/agent/runtime/source_verification.js +210 -0
  170. package/dist/agent/runtime/source_verification_contract.d.ts +75 -0
  171. package/dist/agent/runtime/source_verification_contract.js +203 -0
  172. package/dist/agent/runtime/tool_checkpoints.d.ts +11 -0
  173. package/dist/agent/runtime/tool_checkpoints.js +26 -0
  174. package/dist/agent/runtime/tool_effects.d.ts +5 -0
  175. package/dist/agent/runtime/tool_progress.d.ts +12 -0
  176. package/dist/agent/runtime/tool_progress.js +76 -0
  177. package/dist/agent/runtime/tool_runtime.d.ts +16 -1
  178. package/dist/agent/runtime/tool_runtime.js +204 -10
  179. package/dist/agent/runtime/tracing.d.ts +1 -1
  180. package/dist/agent/runtime/verifier_capture.d.ts +9 -0
  181. package/dist/agent/runtime/verifier_capture.js +100 -0
  182. package/dist/agent/runtime/verifier_contract.d.ts +24 -0
  183. package/dist/agent/runtime/verifier_contract.js +41 -0
  184. package/dist/agent/subagent.d.ts +20 -10
  185. package/dist/agent/subagent.js +266 -29
  186. package/dist/agent/tool_response_directory.d.ts +24 -0
  187. package/dist/agent/tool_response_directory.js +61 -0
  188. package/dist/agent/tool_response_source.d.ts +8 -0
  189. package/dist/agent/tool_response_source.js +49 -0
  190. package/dist/agent/tool_response_store.d.ts +75 -4
  191. package/dist/agent/tool_response_store.js +583 -64
  192. package/dist/agent/tools/ask_user.d.ts +3 -1
  193. package/dist/agent/tools/ask_user.js +30 -11
  194. package/dist/agent/tools/background.js +1 -0
  195. package/dist/agent/tools/benchmark_cpu.d.ts +2 -0
  196. package/dist/agent/tools/benchmark_cpu.js +102 -0
  197. package/dist/agent/tools/compare_benchmarks.d.ts +2 -0
  198. package/dist/agent/tools/compare_benchmarks.js +53 -0
  199. package/dist/agent/tools/deferred.js +1 -0
  200. package/dist/agent/tools/delegate.js +18 -2
  201. package/dist/agent/tools/helper_requirements.d.ts +7 -0
  202. package/dist/agent/tools/helper_requirements.js +19 -0
  203. package/dist/agent/tools/index.d.ts +1 -0
  204. package/dist/agent/tools/index.js +3 -0
  205. package/dist/agent/tools/measurement_report.d.ts +22 -0
  206. package/dist/agent/tools/measurement_report.js +190 -0
  207. package/dist/agent/tools/pane.d.ts +0 -7
  208. package/dist/agent/tools/pane.js +5 -4
  209. package/dist/agent/tools/project_context.d.ts +3 -0
  210. package/dist/agent/tools/project_context.js +45 -0
  211. package/dist/agent/tools/recall_tool_response.d.ts +3 -5
  212. package/dist/agent/tools/recall_tool_response.js +19 -29
  213. package/dist/agent/tools/registry.d.ts +1 -0
  214. package/dist/agent/tools/registry.js +23 -0
  215. package/dist/agent/tools/related_sessions.d.ts +2 -0
  216. package/dist/agent/tools/related_sessions.js +156 -0
  217. package/dist/agent/tools/routine.js +13 -3
  218. package/dist/agent/tools/session_evidence.d.ts +3 -0
  219. package/dist/agent/tools/session_evidence.js +72 -0
  220. package/dist/agent/tools/shell.d.ts +4 -3
  221. package/dist/agent/tools/shell.js +174 -47
  222. package/dist/agent/tools/tool_search.js +3 -2
  223. package/dist/agent/tools/types.d.ts +28 -0
  224. package/dist/agent/tools/verify_artifact.d.ts +2 -0
  225. package/dist/agent/tools/verify_artifact.js +60 -0
  226. package/dist/agent/tools/workflow.js +1 -0
  227. package/dist/app/activity.d.ts +6 -1
  228. package/dist/app/activity.js +81 -12
  229. package/dist/app/agent_runner.d.ts +6 -1
  230. package/dist/app/agent_runner.js +34 -19
  231. package/dist/app/command_context.js +106 -10
  232. package/dist/app/controller.d.ts +15 -4
  233. package/dist/app/controller.js +29 -3
  234. package/dist/app/escape_stop.d.ts +11 -0
  235. package/dist/app/escape_stop.js +15 -0
  236. package/dist/app/liveness.d.ts +6 -4
  237. package/dist/app/liveness.js +13 -3
  238. package/dist/app/model_catalog_cache.d.ts +5 -0
  239. package/dist/app/model_catalog_cache.js +138 -0
  240. package/dist/app/ordered_transcript.js +43 -4
  241. package/dist/app/prompt_turn.d.ts +14 -0
  242. package/dist/app/prompt_turn.js +53 -0
  243. package/dist/app/recap.d.ts +3 -0
  244. package/dist/app/recap.js +9 -3
  245. package/dist/app/restart.d.ts +3 -2
  246. package/dist/app/restart.js +22 -7
  247. package/dist/app/rewind.d.ts +3 -3
  248. package/dist/app/rewind.js +3 -3
  249. package/dist/app/selection_completion.d.ts +17 -2
  250. package/dist/app/selection_completion.js +84 -9
  251. package/dist/app/session_manager.d.ts +38 -6
  252. package/dist/app/session_manager.js +263 -60
  253. package/dist/app/session_messages.d.ts +3 -0
  254. package/dist/app/session_messages.js +60 -0
  255. package/dist/app/task_scope_router.d.ts +20 -0
  256. package/dist/app/task_scope_router.js +173 -0
  257. package/dist/app/transcript_window.d.ts +2 -0
  258. package/dist/app/transcript_window.js +4 -0
  259. package/dist/app/workspace_admission_details.d.ts +3 -0
  260. package/dist/app/workspace_admission_details.js +26 -0
  261. package/dist/app/workspace_layout_controller.d.ts +11 -0
  262. package/dist/app/workspace_layout_controller.js +88 -0
  263. package/dist/app/workspace_monitor.d.ts +1 -0
  264. package/dist/app/workspace_monitor.js +216 -0
  265. package/dist/app/workspace_presets.d.ts +29 -0
  266. package/dist/app/workspace_presets.js +192 -0
  267. package/dist/attention/queue.d.ts +37 -0
  268. package/dist/attention/queue.js +183 -0
  269. package/dist/bench/rf_shared.d.ts +2 -0
  270. package/dist/board/binding.d.ts +42 -0
  271. package/dist/board/binding.js +38 -0
  272. package/dist/board/client.d.ts +42 -0
  273. package/dist/board/client.js +60 -0
  274. package/dist/cli.js +1 -1
  275. package/dist/cli_args.js +19 -17
  276. package/dist/cli_main.js +110 -13
  277. package/dist/cli_ratatui.d.ts +183 -16
  278. package/dist/cli_ratatui.js +3989 -1255
  279. package/dist/components/ActivityLine.d.ts +3 -2
  280. package/dist/components/ActivityLine.js +2 -2
  281. package/dist/components/InputArea.d.ts +19 -1
  282. package/dist/components/InputArea.js +264 -190
  283. package/dist/components/MessageList.d.ts +2 -0
  284. package/dist/components/MessageList.js +3 -1
  285. package/dist/components/SingleMessage.d.ts +2 -0
  286. package/dist/components/SingleMessage.js +4 -2
  287. package/dist/components/StatusBar.d.ts +4 -2
  288. package/dist/components/StatusBar.js +3 -1
  289. package/dist/conductor_branch.js +3 -0
  290. package/dist/config/api_retry.d.ts +6 -1
  291. package/dist/config/api_retry.js +19 -1
  292. package/dist/config/defaults.d.ts +2 -1
  293. package/dist/config/defaults.js +9 -2
  294. package/dist/config/message_display.d.ts +1 -0
  295. package/dist/config/message_display.js +17 -2
  296. package/dist/config/permissions.d.ts +21 -0
  297. package/dist/config/permissions.js +89 -0
  298. package/dist/config/resolved.d.ts +2 -2
  299. package/dist/config/types.d.ts +32 -5
  300. package/dist/config.d.ts +38 -4
  301. package/dist/config.js +290 -42
  302. package/dist/context/project_intelligence.d.ts +44 -0
  303. package/dist/context/project_intelligence.js +246 -0
  304. package/dist/desktop/cli_launch.d.ts +8 -0
  305. package/dist/desktop/cli_launch.js +6 -0
  306. package/dist/desktop/cli_shim.d.ts +8 -0
  307. package/dist/desktop/cli_shim.js +120 -0
  308. package/dist/desktop/runtime.d.ts +16 -0
  309. package/dist/desktop/runtime.js +161 -0
  310. package/dist/desktop/worker_launch.d.ts +7 -0
  311. package/dist/desktop/worker_launch.js +7 -0
  312. package/dist/diagnostics/cargo_mutants_selection.d.ts +27 -0
  313. package/dist/diagnostics/cargo_mutants_selection.js +48 -0
  314. package/dist/diagnostics/native_terminal_benchmark.d.ts +58 -0
  315. package/dist/diagnostics/native_terminal_benchmark.js +1247 -0
  316. package/dist/diagnostics/session_evidence_package.d.ts +40 -0
  317. package/dist/diagnostics/session_evidence_package.js +234 -0
  318. package/dist/diagnostics/session_export.d.ts +93 -0
  319. package/dist/diagnostics/session_export.js +634 -0
  320. package/dist/emulation/tool_adapters.js +48 -18
  321. package/dist/emulation/ztc_addendum.d.ts +1 -0
  322. package/dist/emulation/ztc_addendum.js +13 -12
  323. package/dist/environment/service_runner.d.ts +1 -0
  324. package/dist/environment/service_runner.js +68 -0
  325. package/dist/environment/store.d.ts +120 -0
  326. package/dist/environment/store.js +387 -0
  327. package/dist/events.d.ts +40 -1
  328. package/dist/events.js +10 -17
  329. package/dist/goal_contract.d.ts +25 -0
  330. package/dist/goal_contract.js +44 -0
  331. package/dist/headless.d.ts +31 -0
  332. package/dist/headless.js +578 -70
  333. package/dist/headless_cli.js +8 -0
  334. package/dist/headless_cli_args.d.ts +1 -0
  335. package/dist/headless_cli_args.js +1 -0
  336. package/dist/intake/cli.d.ts +1 -0
  337. package/dist/intake/cli.js +33 -0
  338. package/dist/intake/format.d.ts +2 -0
  339. package/dist/intake/format.js +14 -0
  340. package/dist/intake/notifications.d.ts +16 -0
  341. package/dist/intake/notifications.js +132 -0
  342. package/dist/intake/store.d.ts +56 -0
  343. package/dist/intake/store.js +238 -0
  344. package/dist/library.d.ts +8 -0
  345. package/dist/library.js +19 -10
  346. package/dist/mcp/client.d.ts +1 -0
  347. package/dist/mcp/client.js +20 -0
  348. package/dist/modes/builtin/plan.yaml +2 -2
  349. package/dist/modes/handlers.js +1 -1
  350. package/dist/onboarding/first_run.d.ts +3 -0
  351. package/dist/onboarding/first_run.js +33 -25
  352. package/dist/onboarding/setup.d.ts +32 -0
  353. package/dist/onboarding/setup.js +133 -0
  354. package/dist/onboarding/setup_agent_health.d.ts +17 -0
  355. package/dist/onboarding/setup_agent_health.js +79 -0
  356. package/dist/onboarding/setup_environment.d.ts +66 -0
  357. package/dist/onboarding/setup_environment.js +219 -0
  358. package/dist/onboarding/setup_workspace.d.ts +17 -0
  359. package/dist/onboarding/setup_workspace.js +129 -0
  360. package/dist/optimize/adapters/index.d.ts +4 -1
  361. package/dist/optimize/adapters/index.js +7 -0
  362. package/dist/optimize/adapters/kernelbench.js +14 -5
  363. package/dist/optimize/adapters/popcorn.js +3 -2
  364. package/dist/optimize/adapters/profile_benchmark.js +13 -7
  365. package/dist/optimize/adapters/rfbench.js +25 -14
  366. package/dist/optimize/adapters/types.d.ts +3 -0
  367. package/dist/optimize/adapters/zergpod.js +5 -2
  368. package/dist/optimize/baseline.js +10 -21
  369. package/dist/optimize/branch.js +9 -12
  370. package/dist/optimize/combine.js +2 -3
  371. package/dist/optimize/executor.js +34 -48
  372. package/dist/optimize/measurements.d.ts +55 -0
  373. package/dist/optimize/measurements.js +173 -0
  374. package/dist/optimize/results.d.ts +1 -0
  375. package/dist/optimize/results.js +11 -33
  376. package/dist/optimize/tge.js +2 -1
  377. package/dist/panes/initial_input.d.ts +19 -0
  378. package/dist/panes/initial_input.js +206 -0
  379. package/dist/panes/labels.d.ts +16 -0
  380. package/dist/panes/labels.js +42 -0
  381. package/dist/panes/model_catalog.d.ts +3 -3
  382. package/dist/panes/model_catalog.js +28 -4
  383. package/dist/panes/pane_registry.js +6 -2
  384. package/dist/panes/types.d.ts +3 -0
  385. package/dist/panes/ztc_launch.js +19 -0
  386. package/dist/plugin/optimization.d.ts +2 -0
  387. package/dist/plugin/optimization.js +1 -0
  388. package/dist/plugin/runtime.d.ts +2 -0
  389. package/dist/plugin/simulation.d.ts +6 -1
  390. package/dist/plugin/simulation_contract.d.ts +836 -1
  391. package/dist/plugin/simulation_documents.d.ts +22 -0
  392. package/dist/plugin/simulation_documents.js +1 -0
  393. package/dist/plugin/simulation_interventions.d.ts +103 -0
  394. package/dist/plugin/simulation_interventions.js +1 -0
  395. package/dist/plugin/simulation_living.d.ts +1 -0
  396. package/dist/plugin/simulation_living.js +3 -0
  397. package/dist/plugin/simulation_meetings.d.ts +121 -0
  398. package/dist/plugin/simulation_meetings.js +1 -0
  399. package/dist/plugin/simulation_story_review.d.ts +111 -0
  400. package/dist/plugin/simulation_story_review.js +1 -0
  401. package/dist/plugin/simulation_storyteller.d.ts +91 -0
  402. package/dist/plugin/simulation_storyteller.js +1 -0
  403. package/dist/plugin/simulation_structured.d.ts +2 -0
  404. package/dist/plugin/simulation_structured.js +2 -0
  405. package/dist/plugin/simulation_toolkit.d.ts +21 -0
  406. package/dist/plugin/simulation_toolkit.js +24 -0
  407. package/dist/prompts/tool_delegate_task.j2 +1 -1
  408. package/dist/remote-broker/Dockerfile +10 -0
  409. package/dist/remote-broker/archive.py +1227 -0
  410. package/dist/remote-broker/cutover.py +761 -0
  411. package/dist/remote-broker/requirements.txt +5 -0
  412. package/dist/remote-broker/resources.json +6 -0
  413. package/dist/remote-broker/resources.write-staging.example.json +18 -0
  414. package/dist/remote-broker/retained.py +686 -0
  415. package/dist/remote-broker/retained_cleanup.py +550 -0
  416. package/dist/remote-broker/server.py +648 -0
  417. package/dist/remote-broker/worker.py +1007 -0
  418. package/dist/router_auth.d.ts +31 -0
  419. package/dist/router_auth.js +155 -9
  420. package/dist/runbooks/catalog.d.ts +3 -0
  421. package/dist/runbooks/catalog.js +26 -0
  422. package/dist/runbooks/library.d.ts +11 -0
  423. package/dist/runbooks/library.js +95 -0
  424. package/dist/runbooks/package.d.ts +43 -0
  425. package/dist/runbooks/package.js +102 -0
  426. package/dist/session.d.ts +65 -13
  427. package/dist/session.js +548 -43
  428. package/dist/session_handoff.d.ts +25 -0
  429. package/dist/session_handoff.js +322 -0
  430. package/dist/session_handoff_contract.d.ts +89 -0
  431. package/dist/session_handoff_contract.js +179 -0
  432. package/dist/session_media.d.ts +41 -0
  433. package/dist/session_media.js +357 -0
  434. package/dist/session_ownership.d.ts +16 -0
  435. package/dist/session_ownership.js +221 -0
  436. package/dist/session_public.d.ts +10 -2
  437. package/dist/session_public.js +6 -1
  438. package/dist/simulation/dynamic_history.d.ts +42 -0
  439. package/dist/simulation/dynamic_history.js +173 -0
  440. package/dist/simulation/engines/swarm/pane_manager.js +7 -6
  441. package/dist/simulation/inference.d.ts +3 -1
  442. package/dist/simulation/inference.js +19 -1
  443. package/dist/simulation/intervention_generation.d.ts +27 -0
  444. package/dist/simulation/intervention_generation.js +246 -0
  445. package/dist/simulation/intervention_material.d.ts +4 -0
  446. package/dist/simulation/intervention_material.js +81 -0
  447. package/dist/simulation/living/context.d.ts +3130 -0
  448. package/dist/simulation/living/context.js +944 -0
  449. package/dist/simulation/living/definer.d.ts +12 -0
  450. package/dist/simulation/living/definer.js +223 -0
  451. package/dist/simulation/living/definition.d.ts +257 -0
  452. package/dist/simulation/living/definition.js +341 -0
  453. package/dist/simulation/living/frame.d.ts +259 -0
  454. package/dist/simulation/living/frame.js +223 -0
  455. package/dist/simulation/living/identifiers.d.ts +2 -0
  456. package/dist/simulation/living/identifiers.js +12 -0
  457. package/dist/simulation/living/index.d.ts +15 -0
  458. package/dist/simulation/living/index.js +15 -0
  459. package/dist/simulation/living/inference.d.ts +219 -0
  460. package/dist/simulation/living/inference.js +576 -0
  461. package/dist/simulation/living/mechanics.d.ts +54 -0
  462. package/dist/simulation/living/mechanics.js +588 -0
  463. package/dist/simulation/living/model-input.d.ts +25 -0
  464. package/dist/simulation/living/model-input.js +215 -0
  465. package/dist/simulation/living/open-world.d.ts +257 -0
  466. package/dist/simulation/living/open-world.js +102 -0
  467. package/dist/simulation/living/projection.d.ts +7 -0
  468. package/dist/simulation/living/projection.js +31 -0
  469. package/dist/simulation/living/recall.d.ts +17 -0
  470. package/dist/simulation/living/recall.js +25 -0
  471. package/dist/simulation/living/reduce.d.ts +15 -0
  472. package/dist/simulation/living/reduce.js +1853 -0
  473. package/dist/simulation/living/replay.d.ts +6 -0
  474. package/dist/simulation/living/replay.js +22 -0
  475. package/dist/simulation/living/runtime.d.ts +140 -0
  476. package/dist/simulation/living/runtime.js +3020 -0
  477. package/dist/simulation/living/shared-kinds.d.ts +24 -0
  478. package/dist/simulation/living/shared-kinds.js +96 -0
  479. package/dist/simulation/living/types.d.ts +2785 -0
  480. package/dist/simulation/living/types.js +669 -0
  481. package/dist/simulation/llm.d.ts +3 -1
  482. package/dist/simulation/llm.js +90 -30
  483. package/dist/simulation/memory/embedding.d.ts +1 -1
  484. package/dist/simulation/memory/embedding.js +9 -3
  485. package/dist/simulation/memory/filesystem.d.ts +2 -0
  486. package/dist/simulation/memory/filesystem.js +5 -1
  487. package/dist/simulation/memory/filesystem_file_tree.d.ts +4 -1
  488. package/dist/simulation/memory/filesystem_file_tree.js +41 -10
  489. package/dist/simulation/memory/filesystem_invariants.js +1 -2
  490. package/dist/simulation/memory/filesystem_types.d.ts +1 -0
  491. package/dist/simulation/memory/memory.d.ts +2 -0
  492. package/dist/simulation/memory/memory.js +5 -1
  493. package/dist/simulation/orchestration/intent.js +0 -2
  494. package/dist/simulation/orchestration/lifecycle.js +0 -2
  495. package/dist/simulation/plugin_host.d.ts +25 -1
  496. package/dist/simulation/plugin_host.js +334 -17
  497. package/dist/simulation/session_documents.d.ts +20 -0
  498. package/dist/simulation/session_documents.js +62 -0
  499. package/dist/simulation/session_input_validation.d.ts +43 -0
  500. package/dist/simulation/session_input_validation.js +364 -0
  501. package/dist/simulation/session_inputs.d.ts +32 -0
  502. package/dist/simulation/session_inputs.js +154 -0
  503. package/dist/simulation/telemetry.d.ts +11 -14
  504. package/dist/simulation/telemetry.js +177 -54
  505. package/dist/simulation/toolkit/bounded_turns.d.ts +13 -0
  506. package/dist/simulation/toolkit/bounded_turns.js +80 -0
  507. package/dist/simulation/toolkit/dynamic_agents.d.ts +25 -0
  508. package/dist/simulation/toolkit/dynamic_agents.js +218 -0
  509. package/dist/simulation/toolkit/dynamic_digest.d.ts +1 -0
  510. package/dist/simulation/toolkit/dynamic_digest.js +8 -0
  511. package/dist/simulation/toolkit/dynamic_documents.d.ts +7 -0
  512. package/dist/simulation/toolkit/dynamic_documents.js +71 -0
  513. package/dist/simulation/toolkit/dynamic_driver.d.ts +8 -0
  514. package/dist/simulation/toolkit/dynamic_driver.js +269 -0
  515. package/dist/simulation/toolkit/dynamic_game.d.ts +53 -0
  516. package/dist/simulation/toolkit/dynamic_game.js +805 -0
  517. package/dist/simulation/toolkit/dynamic_knowledge.d.ts +15 -0
  518. package/dist/simulation/toolkit/dynamic_knowledge.js +91 -0
  519. package/dist/simulation/toolkit/dynamic_mechanics.d.ts +22 -0
  520. package/dist/simulation/toolkit/dynamic_mechanics.js +910 -0
  521. package/dist/simulation/toolkit/dynamic_meetings.d.ts +239 -0
  522. package/dist/simulation/toolkit/dynamic_meetings.js +350 -0
  523. package/dist/simulation/toolkit/dynamic_progress.d.ts +131 -0
  524. package/dist/simulation/toolkit/dynamic_progress.js +214 -0
  525. package/dist/simulation/toolkit/dynamic_projection.d.ts +9 -0
  526. package/dist/simulation/toolkit/dynamic_projection.js +219 -0
  527. package/dist/simulation/toolkit/dynamic_runtime.d.ts +412 -0
  528. package/dist/simulation/toolkit/dynamic_runtime.js +6536 -0
  529. package/dist/simulation/toolkit/dynamic_state.d.ts +111 -0
  530. package/dist/simulation/toolkit/dynamic_state.js +1967 -0
  531. package/dist/simulation/toolkit/dynamic_story_review.d.ts +508 -0
  532. package/dist/simulation/toolkit/dynamic_story_review.js +333 -0
  533. package/dist/simulation/toolkit/dynamic_storyteller.d.ts +77 -0
  534. package/dist/simulation/toolkit/dynamic_storyteller.js +114 -0
  535. package/dist/simulation/toolkit/dynamic_storyteller_runtime.d.ts +26 -0
  536. package/dist/simulation/toolkit/dynamic_storyteller_runtime.js +126 -0
  537. package/dist/simulation/toolkit/dynamic_world.d.ts +22 -0
  538. package/dist/simulation/toolkit/dynamic_world.js +377 -0
  539. package/dist/simulation/toolkit/structured_output.d.ts +5 -0
  540. package/dist/simulation/toolkit/structured_output.js +321 -0
  541. package/dist/simulation/types/world.d.ts +2 -0
  542. package/dist/simulation/world/artifact_store.js +1 -1
  543. package/dist/simulation/world/memory_manager.d.ts +5 -0
  544. package/dist/simulation/world/memory_manager.js +17 -2
  545. package/dist/simulation/world/state.d.ts +3 -2
  546. package/dist/simulation/world/state.js +15 -5
  547. package/dist/skills/bundled/measurement-validation/SKILL.md +144 -0
  548. package/dist/terminal_attach.d.ts +1 -0
  549. package/dist/terminal_attach.js +113 -0
  550. package/dist/tool_progress.d.ts +3 -0
  551. package/dist/tool_progress.js +27 -0
  552. package/dist/types.d.ts +145 -10
  553. package/dist/types.js +3 -0
  554. package/dist/ui/core/input.d.ts +3 -0
  555. package/dist/ui/core/input_segments.d.ts +18 -1
  556. package/dist/ui/core/input_segments.js +131 -47
  557. package/dist/ui/core/input_state.d.ts +12 -0
  558. package/dist/ui/core/layout_yoga.d.ts +1 -1
  559. package/dist/ui/core/turn_metadata.d.ts +5 -0
  560. package/dist/ui/core/turn_metadata.js +22 -0
  561. package/dist/ui/ink/render.d.ts +2 -1
  562. package/dist/ui/ink/render.js +6 -5
  563. package/dist/ui/ratatui/headless_pane_manager.d.ts +14 -1
  564. package/dist/ui/ratatui/headless_pane_manager.js +293 -104
  565. package/dist/ui/ratatui/index.d.ts +1 -0
  566. package/dist/ui/ratatui/input.d.ts +4 -0
  567. package/dist/ui/ratatui/input.js +15 -0
  568. package/dist/ui/ratatui/ipc_path.d.ts +2 -0
  569. package/dist/ui/ratatui/ipc_path.js +29 -1
  570. package/dist/ui/ratatui/mux_persistence.d.ts +3 -1
  571. package/dist/ui/ratatui/mux_persistence.js +139 -1
  572. package/dist/ui/ratatui/pane_relay.d.ts +1 -1
  573. package/dist/ui/ratatui/pane_relay.js +55 -27
  574. package/dist/ui/ratatui/process.d.ts +17 -1
  575. package/dist/ui/ratatui/process.js +80 -7
  576. package/dist/ui/ratatui/protocol.d.ts +236 -1
  577. package/dist/ui/ratatui/protocol.js +90 -0
  578. package/dist/ui/scrollback.d.ts +2 -1
  579. package/dist/ui/scrollback.js +9 -4
  580. package/dist/ui/stream_typewriter.d.ts +8 -3
  581. package/dist/ui/stream_typewriter.js +30 -1
  582. package/dist/ui/streaming_scrollback.d.ts +1 -0
  583. package/dist/ui/streaming_scrollback.js +1 -1
  584. package/dist/ui/transcript_render_cache.js +10 -0
  585. package/dist/ui/views/activity_line.d.ts +5 -3
  586. package/dist/ui/views/activity_line.js +65 -7
  587. package/dist/ui/views/app.d.ts +6 -3
  588. package/dist/ui/views/app.js +17 -6
  589. package/dist/ui/views/completion_menu.js +10 -5
  590. package/dist/ui/views/input_area.d.ts +7 -3
  591. package/dist/ui/views/input_area.js +15 -9
  592. package/dist/ui/views/message_list.d.ts +4 -1
  593. package/dist/ui/views/message_list.js +89 -19
  594. package/dist/ui/views/queue_panel.d.ts +3 -1
  595. package/dist/ui/views/queue_panel.js +9 -2
  596. package/dist/ui/views/status_bar.d.ts +4 -2
  597. package/dist/ui/views/status_bar.js +28 -13
  598. package/dist/ui/views/theme.d.ts +2 -0
  599. package/dist/ui/views/theme.js +2 -0
  600. package/dist/ui/widgets/color_panel.js +18 -0
  601. package/dist/ui/widgets/form.js +8 -0
  602. package/dist/ui/widgets/log_view.js +7 -0
  603. package/dist/ui/widgets/navigator_panel.js +8 -0
  604. package/dist/ui/widgets/prompt_viewer.js +2 -0
  605. package/dist/ui/widgets/questionnaire.d.ts +2 -0
  606. package/dist/ui/widgets/questionnaire.js +79 -16
  607. package/dist/ui/widgets/resume_panel.d.ts +2 -0
  608. package/dist/ui/widgets/resume_panel.js +26 -15
  609. package/dist/ui/widgets/rewind_panel.d.ts +2 -2
  610. package/dist/ui/widgets/rewind_panel.js +4 -2
  611. package/dist/ui/widgets/select.js +16 -27
  612. package/dist/ui/widgets/settings_panel.js +16 -0
  613. package/dist/ui/widgets/status_line_panel.d.ts +1 -0
  614. package/dist/ui/widgets/status_line_panel.js +30 -4
  615. package/dist/ui/widgets/text_input.d.ts +2 -0
  616. package/dist/ui/widgets/text_input.js +15 -1
  617. package/dist/ui/widgets/types.d.ts +2 -0
  618. package/dist/usage_projection.d.ts +24 -0
  619. package/dist/usage_projection.js +130 -0
  620. package/dist/usage_snapshot.d.ts +36 -0
  621. package/dist/usage_snapshot.js +131 -0
  622. package/dist/utils/assistant_message.d.ts +2 -0
  623. package/dist/utils/assistant_message.js +5 -0
  624. package/dist/utils/atomic_write.d.ts +6 -2
  625. package/dist/utils/atomic_write.js +29 -4
  626. package/dist/utils/checked_shell.d.ts +25 -0
  627. package/dist/utils/checked_shell.js +107 -0
  628. package/dist/utils/compaction.d.ts +4 -1
  629. package/dist/utils/compaction.js +31 -7
  630. package/dist/utils/context.d.ts +4 -4
  631. package/dist/utils/context.js +14 -12
  632. package/dist/utils/deepseek.d.ts +2 -2
  633. package/dist/utils/deepseek.js +13 -5
  634. package/dist/utils/ephemeral.js +4 -0
  635. package/dist/utils/ephemeral_tools.d.ts +18 -0
  636. package/dist/utils/ephemeral_tools.js +97 -0
  637. package/dist/utils/jev_client.d.ts +4 -0
  638. package/dist/utils/jev_client.js +15 -0
  639. package/dist/utils/model_cache.d.ts +15 -0
  640. package/dist/utils/model_cache.js +143 -0
  641. package/dist/utils/models.d.ts +4 -2
  642. package/dist/utils/models.js +12 -16
  643. package/dist/utils/reasoning.d.ts +8 -1
  644. package/dist/utils/reasoning.js +31 -11
  645. package/dist/utils/router_catalog.d.ts +49 -0
  646. package/dist/utils/router_catalog.js +271 -0
  647. package/dist/utils/sandbox.d.ts +9 -0
  648. package/dist/utils/sandbox.js +118 -15
  649. package/dist/utils/shell.d.ts +7 -0
  650. package/dist/utils/shell.js +98 -34
  651. package/dist/utils/subprocess_env.d.ts +3 -0
  652. package/dist/utils/subprocess_env.js +27 -1
  653. package/dist/web/accounts_mirror.d.ts +3 -1
  654. package/dist/web/accounts_mirror.js +13 -9
  655. package/dist/web/child_publication.d.ts +17 -0
  656. package/dist/web/child_publication.js +45 -0
  657. package/dist/web/mirror_authenticator.d.ts +31 -11
  658. package/dist/web/mirror_authenticator.js +67 -17
  659. package/dist/web/mirror_client.d.ts +31 -4
  660. package/dist/web/mirror_client.js +189 -23
  661. package/dist/web/mirror_stream.d.ts +84 -22
  662. package/dist/web/mirror_stream.js +676 -95
  663. package/dist/web/observer_query_redaction.d.ts +6 -0
  664. package/dist/web/observer_query_redaction.js +58 -0
  665. package/dist/web/pane_registry.d.ts +2 -0
  666. package/dist/web/pane_registry.js +86 -22
  667. package/dist/web/tool_image.d.ts +6 -0
  668. package/dist/web/tool_image.js +17 -0
  669. package/dist/web/view_plugin.d.ts +14 -0
  670. package/dist/web/view_plugin.js +23 -1
  671. package/dist/worker/executor.js +31 -12
  672. package/dist/worker/index.d.ts +1 -0
  673. package/dist/worker/toolsets.js +3 -1
  674. package/dist/worker/types.d.ts +12 -1
  675. package/dist/workflows/registry.js +1 -0
  676. package/dist/workflows/registry_handle.d.ts +2 -0
  677. package/dist/workflows/runtime.d.ts +2 -0
  678. package/dist/workflows/runtime.js +1 -0
  679. package/dist/workspace_agent.d.ts +7 -0
  680. package/dist/workspace_agent.js +36 -0
  681. package/dist/workspace_collision.d.ts +76 -0
  682. package/dist/workspace_collision.js +688 -0
  683. package/dist/workspace_layout.d.ts +18 -0
  684. package/dist/workspace_layout.js +121 -0
  685. package/dist/workspace_runtime.d.ts +44 -0
  686. package/dist/workspace_runtime.js +82 -0
  687. package/dist/workspace_session_context.d.ts +62 -0
  688. package/dist/workspace_session_context.js +160 -0
  689. package/dist/zlm-embed.mjs +32518 -9615
  690. package/dist/zlm.js +1 -0
  691. package/node_modules/@zerg/model-contracts/LICENSE.md +375 -0
  692. package/node_modules/@zerg/model-contracts/README.md +90 -0
  693. package/node_modules/@zerg/model-contracts/index.d.ts +20 -0
  694. package/node_modules/@zerg/model-contracts/index.js +223 -0
  695. package/node_modules/@zerg/model-contracts/package.json +8 -0
  696. package/node_modules/glob/node_modules/brace-expansion/index.js +78 -22
  697. package/node_modules/glob/node_modules/brace-expansion/package.json +1 -1
  698. package/node_modules/readdir-glob/node_modules/brace-expansion/index.js +78 -22
  699. package/node_modules/readdir-glob/node_modules/brace-expansion/package.json +1 -1
  700. package/package.json +45 -24
  701. package/packages/model-contracts/LICENSE.md +375 -0
  702. package/packages/model-contracts/README.md +90 -0
  703. package/packages/model-contracts/index.d.ts +20 -0
  704. package/packages/model-contracts/index.js +223 -0
  705. package/packages/model-contracts/package.json +8 -0
  706. package/remote-broker/Dockerfile +10 -0
  707. package/remote-broker/README.md +308 -0
  708. package/remote-broker/archive.py +1227 -0
  709. package/remote-broker/cutover.py +761 -0
  710. package/remote-broker/requirements.txt +5 -0
  711. package/remote-broker/resources.example.json +6 -0
  712. package/remote-broker/resources.write-staging.example.json +18 -0
  713. package/remote-broker/retained.py +686 -0
  714. package/remote-broker/retained_cleanup.py +550 -0
  715. package/remote-broker/server.py +648 -0
  716. package/scripts/build-remote-broker.mjs +13 -0
  717. package/scripts/ensure-local-packages.mjs +6 -0
  718. package/scripts/node-pty-helpers.mjs +103 -0
@@ -1,33 +1,84 @@
1
1
  import { AGENT_STATUS_LABELS } from '../types.js';
2
2
  import { getToolVerb } from '../utils/tool_verbs.js';
3
+ import { parseEvidenceSnapshot } from '../agent/runtime/evidence.js';
4
+ import { parseTaskHandoffProjection } from '../session_handoff_contract.js';
5
+ import { parseToolProgress } from '../tool_progress.js';
3
6
  export function applyAgentEventToState(previous, event) {
4
7
  // Preserve startedAt across mid-run re-entries (e.g. after a tool round-trip)
5
8
  // so the activity-line elapsed timer has a stable origin.
6
9
  const startedAt = previous.startedAt ?? new Date();
7
10
  switch (event.type) {
11
+ case 'task_handoff': {
12
+ if (!event.sessionId)
13
+ return previous;
14
+ const projection = event.projection === null ? null : parseTaskHandoffProjection(event.projection);
15
+ if (event.projection !== null && !projection)
16
+ return previous;
17
+ const retained = previous.taskHandoff;
18
+ if (projection && retained?.sessionId === event.sessionId
19
+ && retained.projection?.snapshot.source.sessionId === projection.snapshot.source.sessionId
20
+ && retained.projection.snapshot.revision >= projection.snapshot.revision)
21
+ return previous;
22
+ return { ...previous, taskHandoff: { sessionId: event.sessionId, projection } };
23
+ }
24
+ case 'evidence': {
25
+ const snapshot = parseEvidenceSnapshot(event.snapshot);
26
+ if (!snapshot || !event.sessionId || (previous.evidence?.sessionId === event.sessionId
27
+ && previous.evidence.snapshot.revision >= snapshot.revision))
28
+ return previous;
29
+ return { ...previous, evidence: { sessionId: event.sessionId, snapshot } };
30
+ }
31
+ case 'command_wait':
32
+ return { ...previous, status: 'tool_use', startedAt, waiting: event.waiting, requestRetry: undefined, error: undefined };
33
+ case 'command_wait_end':
34
+ return previous.waiting?.toolCallId === event.toolCallId ? { ...previous, waiting: undefined } : previous;
8
35
  case 'thinking_start':
9
- return { ...previous, status: 'thinking', currentTool: undefined, startedAt, error: undefined };
10
- case 'tool_start':
11
- return { ...previous, status: 'tool_use', currentTool: event.tool, startedAt, error: undefined };
36
+ return { ...previous, status: 'thinking', currentTool: undefined, startedAt, error: undefined, requestRetry: undefined, waiting: undefined, toolProgress: undefined };
37
+ case 'api_retry':
38
+ return { ...previous, status: 'thinking', currentTool: undefined, startedAt, error: undefined,
39
+ waiting: undefined, toolProgress: undefined, requestRetry: { phase: event.phase ?? 'retry', attempt: event.attempt, delay: event.delay, ...(event.rateLimited ? { rateLimited: true } : {}) } };
40
+ case 'tool_start': {
41
+ const toolProgress = parseToolProgress({ toolCallId: event.toolCallId, tool: event.tool,
42
+ progress: { startedAt: Date.now(), outputBytes: 0, outputLines: 0, latestLine: '' } });
43
+ return { ...previous, status: 'tool_use', currentTool: event.tool, startedAt, error: undefined, requestRetry: undefined, waiting: undefined,
44
+ toolProgress: toolProgress ?? undefined };
45
+ }
46
+ case 'tool_progress': {
47
+ const observed = parseToolProgress({ toolCallId: event.toolCallId, tool: event.tool, progress: event.progress });
48
+ const owned = previous.toolProgress;
49
+ if (!observed || previous.status !== 'tool_use' || !owned
50
+ || owned.toolCallId !== observed.toolCallId || owned.tool !== observed.tool
51
+ || observed.progress.outputBytes < owned.progress.outputBytes
52
+ || observed.progress.outputLines < owned.progress.outputLines
53
+ || (owned.progress.lastOutputAt !== undefined
54
+ && (observed.progress.lastOutputAt === undefined || observed.progress.lastOutputAt < owned.progress.lastOutputAt)))
55
+ return previous;
56
+ return { ...previous, toolProgress: observed };
57
+ }
58
+ case 'tool_end':
59
+ return previous.toolProgress?.toolCallId === event.toolCallId
60
+ ? { ...previous, toolProgress: undefined } : previous;
12
61
  case 'stream_start':
13
62
  case 'stream_end':
14
- return { ...previous, status: 'streaming', startedAt, error: undefined };
63
+ return { ...previous, status: 'streaming', startedAt, error: undefined, requestRetry: undefined, waiting: undefined, toolProgress: undefined };
15
64
  case 'reasoning_delta':
16
- if (previous.status === 'thinking' && previous.startedAt && previous.error === undefined) {
65
+ if (previous.status === 'thinking' && previous.startedAt && previous.error === undefined && !previous.requestRetry && !previous.waiting && !previous.toolProgress) {
17
66
  return previous;
18
67
  }
19
- return { ...previous, status: 'thinking', startedAt, error: undefined };
68
+ return { ...previous, status: 'thinking', startedAt, error: undefined, requestRetry: undefined, waiting: undefined, toolProgress: undefined };
20
69
  case 'stream_delta':
21
70
  // Hot path: one event per token. Skip the allocation when the status is
22
71
  // already streaming so subscribers don't fire per-token no-op updates.
23
- if (previous.status === 'streaming' && previous.startedAt && previous.error === undefined) {
72
+ if (previous.status === 'streaming' && previous.startedAt && previous.error === undefined && !previous.waiting && !previous.toolProgress) {
24
73
  return previous;
25
74
  }
26
- return { ...previous, status: 'streaming', startedAt, error: undefined };
75
+ return { ...previous, status: 'streaming', startedAt, error: undefined, requestRetry: undefined, waiting: undefined, toolProgress: undefined };
27
76
  case 'tool_error':
28
- return { ...previous, status: 'error', currentTool: event.tool, error: event.error };
77
+ if (previous.toolProgress && previous.toolProgress.toolCallId !== event.toolCallId)
78
+ return previous;
79
+ return { ...previous, status: 'error', currentTool: event.tool, error: event.error, requestRetry: undefined, waiting: undefined, toolProgress: undefined };
29
80
  case 'error':
30
- return { ...previous, status: 'error', error: event.error };
81
+ return { ...previous, status: 'error', error: event.error, requestRetry: undefined, waiting: undefined, toolProgress: undefined };
31
82
  default:
32
83
  return previous;
33
84
  }
@@ -37,14 +88,19 @@ export function buildActivityDisplayState(state, thinkingLabel) {
37
88
  case 'thinking':
38
89
  return {
39
90
  wireStatus: 'thinking',
40
- label: thinkingLabel,
91
+ label: state.requestRetry ? retryActivityLabel(state.requestRetry) : thinkingLabel,
92
+ ...(state.requestRetry?.rateLimited ? { verb: retryActivityLabel(state.requestRetry) } : {}),
41
93
  };
42
94
  case 'tool_use': {
95
+ if (state.waiting)
96
+ return { wireStatus: 'tool_executing', verb: 'Waiting for command', label: 'Waiting for command', waiting: state.waiting,
97
+ ...(state.toolProgress ? { toolProgress: state.toolProgress } : {}) };
43
98
  const verb = state.currentTool ? getToolVerb(state.currentTool) : 'Running tool';
44
99
  return {
45
100
  wireStatus: 'tool_executing',
46
101
  verb,
47
102
  label: verb,
103
+ ...(state.toolProgress ? { toolProgress: state.toolProgress } : {}),
48
104
  };
49
105
  }
50
106
  case 'streaming':
@@ -74,8 +130,10 @@ export function buildActivityDisplayState(state, thinkingLabel) {
74
130
  export function getAgentActionLabel(state) {
75
131
  switch (state.status) {
76
132
  case 'thinking':
77
- return AGENT_STATUS_LABELS.thinking;
133
+ return state.requestRetry ? retryActivityLabel(state.requestRetry) : AGENT_STATUS_LABELS.thinking;
78
134
  case 'tool_use':
135
+ if (state.waiting)
136
+ return 'Waiting for command';
79
137
  return getToolVerb(state.currentTool || 'tool');
80
138
  case 'streaming':
81
139
  return `${AGENT_STATUS_LABELS.streaming} response`;
@@ -83,6 +141,17 @@ export function getAgentActionLabel(state) {
83
141
  return null;
84
142
  }
85
143
  }
144
+ function retryActivityLabel(retry) {
145
+ if (retry.rateLimited)
146
+ return `Rate-limited, waiting ${Math.ceil(retry.delay / 1000)}s`;
147
+ return retry.phase === 'recovery' ? 'Waiting for LLM endpoint' : 'Retrying LLM request';
148
+ }
149
+ export function formatApiRetryNotice(event) {
150
+ const attempts = event.phase === 'recovery'
151
+ ? `recovery attempt ${event.attempt - event.maxAttempts + 1}; current task retained`
152
+ : `attempt ${event.attempt}/${event.maxAttempts}`;
153
+ return `⚠️ ${event.reason}. Retrying in ${event.delay / 1000}s... (${attempts})`;
154
+ }
86
155
  /**
87
156
  * Placeholder text for the composer while the agent is active.
88
157
  * Shared by every renderer so Ink and Ratatui show the same prompt.
@@ -8,9 +8,14 @@
8
8
  */
9
9
  import { Agent } from '../agent/index.js';
10
10
  import type { AgentEvent } from '../types.js';
11
+ import type { ModelUsageObserver } from '../types.js';
11
12
  import { type AgentFactoryOptions } from '../agent/factory.js';
12
13
  import type { Message } from '../types.js';
14
+ import type { ToolCheckpointHandler } from '../agent/runtime/tool_checkpoints.js';
15
+ import type { SteeringAdmissionCheckpointHandler } from '../agent/agent.js';
13
16
  interface AgentRunnerOptions extends Partial<AgentFactoryOptions> {
17
+ /** Profile selection may wait for sign-in while retaining its session. */
18
+ allowUnavailableRouterAuth?: boolean;
14
19
  cwdProvider?: () => string;
15
20
  }
16
21
  /**
@@ -52,7 +57,7 @@ export declare class AgentRunLifecycle {
52
57
  * The callback should contain the renderer-specific event switch.
53
58
  * @returns The agent response and whether it was cancelled
54
59
  */
55
- run(agent: Agent, messages: Message[], onEvent: (event: AgentEvent) => void, takeSteering?: () => Message[]): Promise<AgentRunResult>;
60
+ run(agent: Agent, messages: Message[], onEvent: (event: AgentEvent) => void, takeSteering?: () => Message[], toolCheckpoint?: ToolCheckpointHandler, steeringAdmission?: SteeringAdmissionCheckpointHandler, onUsage?: ModelUsageObserver): Promise<AgentRunResult>;
56
61
  /**
57
62
  * Cancel the currently active run (if any).
58
63
  * Aborts the in-flight API call and stops event delivery.
@@ -9,12 +9,14 @@
9
9
  import { AgentError } from '../agent/index.js';
10
10
  import { createAgentFromConfig, resolveAgentBackendFromConfig } from '../agent/factory.js';
11
11
  import { configStore } from '../config.js';
12
+ import { RouterConfigurationError } from '../router_auth.js';
12
13
  import { setBackgroundRegistry, getBackgroundRegistry, clearBackgroundRegistry } from '../agent/tools/index.js';
13
14
  import { BackgroundTaskRegistry } from '../agent/background_registry.js';
14
15
  import { InProcessWorkerExecutor, setWorkerExecutor, clearWorkerExecutor } from '../worker/index.js';
15
16
  import { configureWorkflowRegistry, shutdownAndClearWorkflowRegistry } from '../workflows/registry_handle.js';
16
17
  import { workflowsEnabled } from '../workflows/config.js';
17
- import { isCodexAppServerProvider } from '../agent/backends/provider_ids.js';
18
+ import { isCodexAppServerProvider, normalizeProviderId } from '../agent/backends/provider_ids.js';
19
+ import { admitPermissionProvider, projectPermissionPolicy, resolvePermissionProfile } from '../config/permissions.js';
18
20
  /**
19
21
  * Ensure the BackgroundTaskRegistry tracks the current shared executor.
20
22
  * Reuses the existing registry if one is already set — background tasks
@@ -40,11 +42,6 @@ function configureWorkflowRegistryContext(executor, cwdProvider, execution) {
40
42
  };
41
43
  configureWorkflowRegistry(registryOptions);
42
44
  }
43
- function resolveWorkerPermissionProfile() {
44
- const config = configStore.get();
45
- const id = config.permissionProfile;
46
- return id ? config.permissionProfiles?.[id] : undefined;
47
- }
48
45
  function providerSupportsWorkflowWorkers(provider) {
49
46
  return !isCodexAppServerProvider(provider);
50
47
  }
@@ -58,23 +55,38 @@ function providerSupportsWorkflowWorkers(provider) {
58
55
  * @returns Agent instance or null if no usable credentials are configured
59
56
  */
60
57
  export function createAgentWithConfig(overrides = {}) {
61
- const { cwdProvider = () => process.cwd(), ...agentOverrides } = overrides;
58
+ const { cwdProvider = () => process.cwd(), allowUnavailableRouterAuth = false, ...agentOverrides } = overrides;
62
59
  const config = configStore.get();
60
+ const permissionProfile = resolvePermissionProfile(config);
61
+ admitPermissionProvider(permissionProfile, projectPermissionPolicy(config), normalizeProviderId(agentOverrides.provider ?? config.provider ?? configStore.getProvider()));
63
62
  // provider/model are intentionally NOT passed here: the config snapshot
64
63
  // already carries the resolved values (get() folds in CLI/session
65
64
  // overrides), and passing them as renderer intent would make the
66
65
  // repo-scoped override (<cwd>/.ztc/config.json) unreachable. Renderer
67
66
  // overrides still flow via agentOverrides and win.
68
- const resolvedBackend = resolveAgentBackendFromConfig({
69
- config,
70
- apiKey: overrides.apiKey,
71
- openaiCompatibleBaseUrl: configStore.getOpenAICompatibleBaseUrl(),
72
- emulationId: configStore.getEmulationId(),
73
- cwd: cwdProvider(),
74
- ...agentOverrides,
75
- });
67
+ let resolvedBackend;
68
+ let deferredRouterAuth = false;
69
+ try {
70
+ resolvedBackend = resolveAgentBackendFromConfig({
71
+ config,
72
+ apiKey: overrides.apiKey,
73
+ // Backend resolution validates the endpoint only when that provider is
74
+ // selected; unrelated saved settings must not block another provider.
75
+ openaiCompatibleBaseUrl: configStore.getOpenAICompatibleSettings().baseUrl,
76
+ emulationId: configStore.getEmulationId(),
77
+ cwd: cwdProvider(),
78
+ ...agentOverrides,
79
+ });
80
+ }
81
+ catch (error) {
82
+ if (!allowUnavailableRouterAuth || !(error instanceof RouterConfigurationError) || !error.needsSignIn)
83
+ throw error;
84
+ resolvedBackend = null;
85
+ deferredRouterAuth = true;
86
+ }
76
87
  // Set up shared WorkerExecutor so delegate/background/batch can access the API
77
88
  if (resolvedBackend) {
89
+ admitPermissionProvider(permissionProfile, projectPermissionPolicy(config), resolvedBackend.provider);
78
90
  const executor = new InProcessWorkerExecutor({
79
91
  provider: resolvedBackend.provider,
80
92
  apiKey: resolvedBackend.apiKey,
@@ -86,7 +98,8 @@ export function createAgentWithConfig(overrides = {}) {
86
98
  approvalRequester: overrides.hookApprovalRequester,
87
99
  backend: resolvedBackend.backend,
88
100
  toolPermissions: config.toolPermissions,
89
- permissionProfile: resolveWorkerPermissionProfile(),
101
+ permissionProfile,
102
+ commandPolicy: { profileId: config.permissionProfile ?? 'trusted', profile: permissionProfile, sandbox: config.sandbox },
90
103
  });
91
104
  setWorkerExecutor(executor);
92
105
  ensureBackgroundRegistry(executor);
@@ -108,10 +121,12 @@ export function createAgentWithConfig(overrides = {}) {
108
121
  clearBackgroundRegistry();
109
122
  void shutdownAndClearWorkflowRegistry(5000);
110
123
  }
124
+ if (deferredRouterAuth)
125
+ return null;
111
126
  return createAgentFromConfig({
112
127
  config,
113
128
  apiKey: overrides.apiKey,
114
- openaiCompatibleBaseUrl: configStore.getOpenAICompatibleBaseUrl(),
129
+ openaiCompatibleBaseUrl: configStore.getOpenAICompatibleSettings().baseUrl,
115
130
  emulationId: configStore.getEmulationId(),
116
131
  cwd: cwdProvider(),
117
132
  ...agentOverrides,
@@ -140,7 +155,7 @@ export class AgentRunLifecycle {
140
155
  * The callback should contain the renderer-specific event switch.
141
156
  * @returns The agent response and whether it was cancelled
142
157
  */
143
- async run(agent, messages, onEvent, takeSteering) {
158
+ async run(agent, messages, onEvent, takeSteering, toolCheckpoint, steeringAdmission, onUsage) {
144
159
  // Abort previous run if still in flight to avoid concurrent API calls
145
160
  if (this.abortController) {
146
161
  this.abortController.abort();
@@ -160,7 +175,7 @@ export class AgentRunLifecycle {
160
175
  // iterates. Renderers own their controller state and persist the visible
161
176
  // final turn themselves, so keep those API-only mutations off the live
162
177
  // transcript array.
163
- const response = await agent.run(messages.slice(), controller.signal, takeSteering);
178
+ const response = await agent.run(messages.slice(), controller.signal, takeSteering, toolCheckpoint, steeringAdmission, onUsage);
164
179
  const cancelled = !isActive();
165
180
  return { response: cancelled ? null : response, cancelled };
166
181
  }
@@ -1,10 +1,5 @@
1
- /**
2
- * CommandContext Factory
3
- *
4
- * Shared helpers for building CommandContext objects used by command handlers.
5
- * Eliminates duplication between TUI (cli_ratatui.ts) and headless (headless.ts) renderers.
6
- */
7
- import { listModels } from '../utils/models.js';
1
+ import { discoverRouterCatalog, readRouterCatalog, routerModelIds, routerCatalogScope } from '../utils/router_catalog.js';
2
+ import { loadModelCatalog } from './model_catalog_cache.js';
8
3
  import { getSkills } from '../skills/registry.js';
9
4
  import { runShellCommand } from '../utils/shell.js';
10
5
  import { configStore } from '../config.js';
@@ -33,6 +28,58 @@ export function routeUserInput(text) {
33
28
  const parts = text.slice(1).trimEnd().split(/\s+/);
34
29
  const cmd = parts[0];
35
30
  if (!cmd.includes('/')) {
31
+ if (cmd === 'job' && parts[1] === 'pin') {
32
+ // Only parse pin options. The command after -- belongs to the shell and
33
+ // must retain its exact quotes, argument spaces and metacharacters.
34
+ const tokens = [];
35
+ let token = '';
36
+ let quote = '';
37
+ let braces = 0;
38
+ let escaped = false;
39
+ const source = text.slice(1).trimEnd();
40
+ for (let i = 0; i < source.length; i++) {
41
+ const char = source[i];
42
+ if (!quote && !braces && /\s/.test(char)) {
43
+ if (token) {
44
+ tokens.push(token);
45
+ if (token === '--') {
46
+ tokens.push(source.slice(i + 1));
47
+ return { type: 'command', cmd, args: tokens.slice(1) };
48
+ }
49
+ token = '';
50
+ }
51
+ continue;
52
+ }
53
+ token += char;
54
+ if (escaped) {
55
+ escaped = false;
56
+ continue;
57
+ }
58
+ if (quote && char === '\\') {
59
+ escaped = true;
60
+ continue;
61
+ }
62
+ if (quote) {
63
+ if (char === quote)
64
+ quote = '';
65
+ }
66
+ else if (char === '"' || char === "'")
67
+ quote = char;
68
+ else if (char === '{')
69
+ braces++;
70
+ else if (char === '}')
71
+ braces = Math.max(0, braces - 1);
72
+ }
73
+ if (token)
74
+ tokens.push(token);
75
+ return { type: 'command', cmd, args: tokens.slice(1) };
76
+ }
77
+ if (cmd.toLowerCase() === 'fork' || cmd.toLowerCase() === 'side') {
78
+ // A fork's body is authored task data, not tokenized command options.
79
+ // Remove exactly the command separator and retain the remaining bytes.
80
+ const task = text.slice(cmd.length + 2);
81
+ return { type: 'command', cmd, args: task.length ? [task] : [] };
82
+ }
36
83
  return { type: 'command', cmd, args: parts.slice(1) };
37
84
  }
38
85
  }
@@ -43,19 +90,66 @@ export function routeUserInput(text) {
43
90
  * The models.list implementation is identical across all renderers.
44
91
  */
45
92
  export function buildModelsController(config) {
93
+ const listRouter = async (provider, options) => {
94
+ options?.signal?.throwIfAborted();
95
+ const connection = config.getRouterCatalogConnection?.();
96
+ const preview = connection && readRouterCatalog(connection);
97
+ const age = preview ? Date.now() - preview.fetchedAt : Infinity;
98
+ if (!options?.refresh && preview && !preview.authRequired && age >= 0 && age < 24 * 60 * 60 * 1000) {
99
+ // Scoped disk rows preview choices; a shared background refresh owns
100
+ // qualification and adoption. Editing never waits on a stale catalog.
101
+ if (age >= 30_000)
102
+ void buildModelsController(config).catalog(options?.signal, { refresh: true }).catch(() => { });
103
+ return routerModelIds(preview, provider);
104
+ }
105
+ return routerModelIds(await buildModelsController(config).catalog(options?.signal, options), provider);
106
+ };
46
107
  return {
108
+ catalog: async (signal, options) => {
109
+ try {
110
+ const connection = config.getRouterCatalogConnection?.();
111
+ if (!connection)
112
+ throw new Error('Router discovery requires a Router login. Run ztc auth login.');
113
+ const scope = routerCatalogScope(connection);
114
+ signal?.throwIfAborted();
115
+ const previous = readRouterCatalog(connection);
116
+ const age = previous === undefined ? Infinity : Date.now() - previous.fetchedAt;
117
+ // Startup may reuse this process's live discovery, but always refreshes
118
+ // disk previews. An explicit refresh still forces a new HTTP request.
119
+ const reuse = !options?.refresh || options.refresh === 'startup' && !!readRouterCatalog(connection, { liveOnly: true });
120
+ const catalog = reuse && previous && !previous.authRequired && age >= 0 && age < 30_000
121
+ ? previous : await discoverRouterCatalog(connection, signal);
122
+ signal?.throwIfAborted();
123
+ const active = config.getRouterCatalogConnection?.();
124
+ if (!active || routerCatalogScope(active) !== scope)
125
+ throw new Error('Router discovery context changed. Retry model discovery.');
126
+ await config.adoptRouterCatalog?.(catalog);
127
+ return catalog;
128
+ }
129
+ catch (error) {
130
+ const cached = config.getRouterCatalog?.();
131
+ if (!signal?.aborted && cached)
132
+ return { ...cached, ...(error instanceof Error && /authentication|expired|login|origin/i.test(error.message) ? { authRequired: true } : {}) };
133
+ throw error;
134
+ }
135
+ },
47
136
  list: async (provider, options) => {
137
+ if ((options?.authMode ?? config.getAuthMode?.()) === 'zrouter') {
138
+ return listRouter(provider ?? config.getProvider(), options);
139
+ }
48
140
  const llm = config.resolveLLMBackendConfig({ provider,
49
141
  config: options?.authMode ? { ...config.get(), authMode: options.authMode } : undefined });
50
- // Preserve discovery failures so callers can distinguish an unavailable
51
- // catalog from a successful provider response with zero supported models.
52
- return listModels({
142
+ if (llm.useProxy) {
143
+ return listRouter(llm.provider, options);
144
+ }
145
+ return loadModelCatalog({
53
146
  signal: options?.signal,
54
147
  provider: llm.provider,
55
148
  apiKey: llm.apiKey,
56
149
  baseUrl: llm.provider === 'openai_compatible' ? llm.compatBaseUrl : undefined,
57
150
  proxyUrl: llm.useProxy ? llm.proxyUrl : undefined,
58
151
  authToken: llm.useProxy ? llm.authToken : undefined,
152
+ workspaceId: llm.useProxy ? config.getRouterCatalogConnection?.()?.workspaceId : undefined,
59
153
  codexAppServerCommand: llm.codexAppServerCommand,
60
154
  codexAppServerArgs: llm.codexAppServerArgs,
61
155
  codexHome: llm.codexHome,
@@ -178,6 +272,7 @@ export function buildAutoSelectWidgets() {
178
272
  /** Session controls do not execute the plan or change project files. */
179
273
  const PLAN_MODE_SESSION_COMMANDS = new Set([
180
274
  'accounts',
275
+ 'attention',
181
276
  'auth',
182
277
  'config',
183
278
  'context',
@@ -192,6 +287,7 @@ const PLAN_MODE_SESSION_COMMANDS = new Set([
192
287
  'models',
193
288
  'permissions',
194
289
  'profile',
290
+ 'rewind',
195
291
  'settings',
196
292
  'shortcuts',
197
293
  'skills',
@@ -7,11 +7,12 @@
7
7
  * The state is a single immutable object that gets updated via dispatch().
8
8
  * Subscribers are notified whenever the state changes.
9
9
  */
10
- import type { Message, AgentState, InputMode, MessageInput, QueueEntry, DeliveryIntent, TodoStatus } from '../types.js';
10
+ import { type Message, type AgentState, type InputMode, type CanonicalInputMode, type MessageInput, type QueueEntry, type DeliveryIntent, type TodoStatus } from '../types.js';
11
11
  import type { InputState } from '../ui/core/input_state.js';
12
12
  import type { ContextStatus } from '../utils/context.js';
13
13
  import type { Skill } from '../skills/types.js';
14
14
  import type { AgentMode } from './modes.js';
15
+ import type { WorkspaceCollisionSnapshot } from '../workspace_collision.js';
15
16
  export type { TodoStatus } from '../types.js';
16
17
  export interface TodoItem {
17
18
  /** Unique identifier for the todo */
@@ -33,6 +34,7 @@ export declare const MAX_QUEUE = 10;
33
34
  */
34
35
  export declare const DEFAULT_TOAST_MS = 5000;
35
36
  export interface AppState {
37
+ workspaceCollision: WorkspaceCollisionSnapshot | null;
36
38
  /** Chat messages */
37
39
  messages: Message[];
38
40
  /** Current agent state (thinking, streaming, etc.) */
@@ -41,8 +43,8 @@ export interface AppState {
41
43
  sessionId: string;
42
44
  /** Current input state (segments, cursor, history) */
43
45
  inputState: InputState;
44
- /** Input mode (queue or normal) */
45
- inputMode: InputMode;
46
+ /** Busy Enter mode; legacy values are normalized at dispatch. */
47
+ inputMode: CanonicalInputMode;
46
48
  /** Toast notification message */
47
49
  toast: string | null;
48
50
  /** Spinner label when agent is working */
@@ -89,10 +91,13 @@ export interface AppState {
89
91
  mode: AgentMode;
90
92
  /** Path to current plan file (when in plan mode) */
91
93
  planFile: string | null;
92
- /** Outbound message queue. Single-writer: ENQUEUE / DEQUEUE / REMOVE / CLEAR actions only. */
94
+ /** Outbound message queue, updated only through canonical queue actions. */
93
95
  queue: QueueEntry[];
94
96
  }
95
97
  export type AppAction = {
98
+ type: 'SET_WORKSPACE_COLLISION';
99
+ snapshot: WorkspaceCollisionSnapshot | null;
100
+ } | {
96
101
  type: 'ADD_MESSAGE';
97
102
  message: Omit<Message, 'id' | 'timestamp'>;
98
103
  } | {
@@ -194,6 +199,9 @@ export type AppAction = {
194
199
  type: 'UPDATE_QUEUE_ENTRY';
195
200
  id: string;
196
201
  text: string;
202
+ } | {
203
+ type: 'REORDER_QUEUE';
204
+ ids: string[];
197
205
  } | {
198
206
  type: 'CLEAR_QUEUE';
199
207
  };
@@ -228,6 +236,7 @@ export declare class AppController {
228
236
  setMessages(messages: Message[]): void;
229
237
  clearMessages(): void;
230
238
  setAgentState(agentState: AgentState): void;
239
+ setWorkspaceCollision(snapshot: WorkspaceCollisionSnapshot | null): void;
231
240
  setInputState(inputState: InputState): void;
232
241
  setInputStateSilent(inputState: InputState): void;
233
242
  /**
@@ -287,6 +296,8 @@ export declare class AppController {
287
296
  removeQueueEntry(id: string): void;
288
297
  /** Rewrite a queued entry's text in place. Returns false when the id is no longer queued. */
289
298
  updateQueueEntry(id: string, text: string): boolean;
299
+ /** Apply only an exact permutation of the currently accepted queue IDs. */
300
+ reorderQueue(ids: readonly string[]): boolean;
290
301
  clearQueue(): void;
291
302
  getQueue(): QueueEntry[];
292
303
  }
@@ -7,6 +7,7 @@
7
7
  * The state is a single immutable object that gets updated via dispatch().
8
8
  * Subscribers are notified whenever the state changes.
9
9
  */
10
+ import { normalizeInputMode } from '../types.js';
10
11
  import { buildTodoIdentity } from './todo_state.js';
11
12
  function getActiveTodoKey(todos) {
12
13
  const activeIndex = todos.findIndex(todo => todo.status === 'in_progress');
@@ -41,6 +42,7 @@ export const DEFAULT_TOAST_MS = 5000;
41
42
  const generateId = () => Math.random().toString(36).slice(2, 11);
42
43
  function createInitialState() {
43
44
  return {
45
+ workspaceCollision: null,
44
46
  messages: [],
45
47
  agentState: { status: 'idle' },
46
48
  sessionId: generateId(),
@@ -50,7 +52,7 @@ function createInitialState() {
50
52
  history: [],
51
53
  historyIdx: -1,
52
54
  },
53
- inputMode: 'queue',
55
+ inputMode: 'steer',
54
56
  toast: null,
55
57
  spinnerLabel: null,
56
58
  spinnerFrame: null,
@@ -88,6 +90,8 @@ function isDuplicateAssistantAppend(previous, next) {
88
90
  }
89
91
  function reducer(state, action) {
90
92
  switch (action.type) {
93
+ case 'SET_WORKSPACE_COLLISION':
94
+ return { ...state, workspaceCollision: action.snapshot };
91
95
  case 'ADD_MESSAGE': {
92
96
  const lastMessage = state.messages[state.messages.length - 1];
93
97
  if (isDuplicateAssistantAppend(lastMessage, action.message)) {
@@ -142,11 +146,13 @@ function reducer(state, action) {
142
146
  messages: state.messages.filter((msg) => msg.id !== action.id),
143
147
  };
144
148
  case 'SET_AGENT_STATE':
145
- return { ...state, agentState: action.state };
149
+ return { ...state, agentState: { ...action.state,
150
+ taskHandoff: action.state.taskHandoff ?? state.agentState.taskHandoff,
151
+ evidence: action.state.evidence ?? state.agentState.evidence } };
146
152
  case 'SET_INPUT_STATE':
147
153
  return { ...state, inputState: action.state };
148
154
  case 'SET_INPUT_MODE':
149
- return { ...state, inputMode: action.mode };
155
+ return { ...state, inputMode: normalizeInputMode(action.mode) };
150
156
  case 'SET_TOAST':
151
157
  return { ...state, toast: action.message };
152
158
  case 'SET_SPINNER':
@@ -234,6 +240,17 @@ function reducer(state, action) {
234
240
  queue[index] = { ...current, text: action.text };
235
241
  return { ...state, queue };
236
242
  }
243
+ case 'REORDER_QUEUE': {
244
+ if (action.ids.length !== state.queue.length || new Set(action.ids).size !== action.ids.length)
245
+ return state;
246
+ const byId = new Map(state.queue.map(entry => [entry.id, entry]));
247
+ if (action.ids.some(id => !byId.has(id)))
248
+ return state;
249
+ const queue = action.ids.map(id => byId.get(id));
250
+ if (queue.every((entry, index) => entry === state.queue[index]))
251
+ return state;
252
+ return { ...state, queue };
253
+ }
237
254
  case 'CLEAR_QUEUE':
238
255
  return { ...state, queue: [] };
239
256
  default:
@@ -309,6 +326,9 @@ export class AppController {
309
326
  setAgentState(agentState) {
310
327
  this.dispatch({ type: 'SET_AGENT_STATE', state: agentState });
311
328
  }
329
+ setWorkspaceCollision(snapshot) {
330
+ this.dispatch({ type: 'SET_WORKSPACE_COLLISION', snapshot });
331
+ }
312
332
  setInputState(inputState) {
313
333
  this.dispatch({ type: 'SET_INPUT_STATE', state: inputState });
314
334
  }
@@ -474,6 +494,12 @@ export class AppController {
474
494
  this.dispatch({ type: 'UPDATE_QUEUE_ENTRY', id, text });
475
495
  return true;
476
496
  }
497
+ /** Apply only an exact permutation of the currently accepted queue IDs. */
498
+ reorderQueue(ids) {
499
+ this.dispatch({ type: 'REORDER_QUEUE', ids: [...ids] });
500
+ return ids.length === this.state.queue.length
501
+ && this.state.queue.every((entry, index) => entry.id === ids[index]);
502
+ }
477
503
  clearQueue() {
478
504
  this.dispatch({ type: 'CLEAR_QUEUE' });
479
505
  }
@@ -0,0 +1,11 @@
1
+ /** Global Escape confirms only the same running owner within this window. */
2
+ export declare const ESCAPE_STOP_WINDOW_MS = 2000;
3
+ export interface EscapeStopArm<Owner> {
4
+ owner: Owner;
5
+ armedAtMs: number;
6
+ }
7
+ export declare function isEscapeStopArmed<Owner>(arm: EscapeStopArm<Owner> | null, owner: Owner | null, nowMs: number): boolean;
8
+ export declare function advanceEscapeStop<Owner>(arm: EscapeStopArm<Owner> | null, owner: Owner | null, nowMs: number): {
9
+ confirmed: boolean;
10
+ arm: EscapeStopArm<Owner> | null;
11
+ };
@@ -0,0 +1,15 @@
1
+ /** Global Escape confirms only the same running owner within this window. */
2
+ export const ESCAPE_STOP_WINDOW_MS = 2000;
3
+ export function isEscapeStopArmed(arm, owner, nowMs) {
4
+ if (arm === null || owner === null || arm.owner !== owner)
5
+ return false;
6
+ const elapsed = nowMs - arm.armedAtMs;
7
+ return elapsed >= 0 && elapsed <= ESCAPE_STOP_WINDOW_MS;
8
+ }
9
+ export function advanceEscapeStop(arm, owner, nowMs) {
10
+ if (owner === null)
11
+ return { confirmed: false, arm: null };
12
+ if (isEscapeStopArmed(arm, owner, nowMs))
13
+ return { confirmed: true, arm: null };
14
+ return { confirmed: false, arm: { owner, armedAtMs: nowMs } };
15
+ }