@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
@@ -0,0 +1,17 @@
1
+ export type ChildPublicationAdmission = {
2
+ accepted: true;
3
+ duplicate: boolean;
4
+ } | {
5
+ accepted: false;
6
+ status: 400 | 409;
7
+ error: string;
8
+ };
9
+ /** Bounded parent-issued stream receipts. Retain tombstones so pane reuse cannot revive an old stream. */
10
+ export declare class ChildPublicationLedger {
11
+ private readonly capacity;
12
+ private readonly streams;
13
+ constructor(capacity?: number);
14
+ open(paneId: number, scope?: string): string | null;
15
+ admit(paneId: number, id: unknown, sequence: unknown, scope?: string): ChildPublicationAdmission;
16
+ invalidate(paneId: number): void;
17
+ }
@@ -0,0 +1,45 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ /** Bounded parent-issued stream receipts. Retain tombstones so pane reuse cannot revive an old stream. */
3
+ export class ChildPublicationLedger {
4
+ capacity;
5
+ streams = new Map();
6
+ constructor(capacity = 1024) {
7
+ this.capacity = capacity;
8
+ if (!Number.isSafeInteger(capacity) || capacity < 1)
9
+ throw new RangeError('Publication capacity must be a positive safe integer');
10
+ }
11
+ open(paneId, scope = '') {
12
+ const key = JSON.stringify([scope, paneId]);
13
+ if (!this.streams.has(key) && this.streams.size >= this.capacity)
14
+ return null;
15
+ const id = randomUUID();
16
+ this.streams.set(key, { paneId, id, sequence: 0 });
17
+ return id;
18
+ }
19
+ admit(paneId, id, sequence, scope = '') {
20
+ const stream = this.streams.get(JSON.stringify([scope, paneId]));
21
+ // Legacy children remain compatible only until this pane opts into ordered publication.
22
+ if (id === undefined && sequence === undefined) {
23
+ return stream ? { accepted: false, status: 409, error: 'publication_identity_required' }
24
+ : { accepted: true, duplicate: false };
25
+ }
26
+ if (typeof id !== 'string' || !Number.isSafeInteger(sequence) || sequence < 1) {
27
+ return { accepted: false, status: 400, error: 'invalid_publication_sequence' };
28
+ }
29
+ if (!stream || stream.id !== id)
30
+ return { accepted: false, status: 409, error: 'publication_superseded' };
31
+ const next = sequence;
32
+ if (next <= stream.sequence)
33
+ return { accepted: true, duplicate: true };
34
+ if (next !== stream.sequence + 1)
35
+ return { accepted: false, status: 409, error: 'publication_sequence_gap' };
36
+ stream.sequence = next;
37
+ return { accepted: true, duplicate: false };
38
+ }
39
+ invalidate(paneId) {
40
+ for (const stream of this.streams.values()) {
41
+ if (stream.paneId === paneId)
42
+ stream.id = null;
43
+ }
44
+ }
45
+ }
@@ -21,11 +21,29 @@
21
21
  export interface MirrorSession {
22
22
  expiresAtMs: number;
23
23
  canInspectPrompts: boolean;
24
+ /** Absent only in callers predating capability-scoped sessions. */
25
+ canControl?: boolean;
26
+ shareId?: string;
24
27
  }
25
28
  export interface MirrorTokenValidationResult {
26
29
  ok: boolean;
27
30
  expiresAtMs: number;
28
31
  canInspectPrompts: boolean;
32
+ canControl?: boolean;
33
+ shareId?: string;
34
+ }
35
+ export interface MirrorShare {
36
+ id: string;
37
+ label: string;
38
+ expiresAtMs: number;
39
+ createdAtMs: number;
40
+ revoked: boolean;
41
+ }
42
+ export interface MirrorTokenOptions {
43
+ ttlMs?: number;
44
+ canInspectPrompts?: boolean;
45
+ readOnly?: boolean;
46
+ label?: string;
29
47
  }
30
48
  export interface MirrorAuthDecision {
31
49
  ok: boolean;
@@ -56,10 +74,10 @@ export interface MirrorAuthenticator {
56
74
  readonly zergId: string;
57
75
  readonly cookieName: string;
58
76
  readonly queryTokenName: string;
59
- issueToken(opts?: {
60
- ttlMs?: number;
61
- canInspectPrompts?: boolean;
62
- }): string;
77
+ issueToken(opts?: MirrorTokenOptions): string;
78
+ listShares(): MirrorShare[];
79
+ revokeShare(id: string): boolean;
80
+ onShareRevoked(callback: (id: string) => void): () => void;
63
81
  isValidToken(token: string): MirrorTokenValidationResult;
64
82
  authenticate(ctx: MirrorAuthContext): MirrorAuthDecision;
65
83
  authenticateUpgrade(ctx: MirrorAuthContext): boolean;
@@ -69,19 +87,22 @@ export interface MirrorAuthenticator {
69
87
  }
70
88
  /** Production HMAC + session authenticator. Denies requests without valid credentials. */
71
89
  export declare class HmacMirrorAuthenticator implements MirrorAuthenticator {
72
- readonly enabled: boolean;
90
+ protected requiresCredentials: boolean;
91
+ get enabled(): boolean;
73
92
  readonly zergId: string;
74
93
  readonly cookieName: string;
75
94
  readonly queryTokenName: string;
76
95
  protected readonly sharedSecret: string;
77
96
  protected readonly internalToken: string;
78
97
  protected readonly sessions: Map<string, MirrorSession>;
98
+ private readonly shares;
99
+ private readonly revocationListeners;
79
100
  constructor(config: MirrorAuthenticatorConfig);
80
- issueToken(opts?: {
81
- ttlMs?: number;
82
- canInspectPrompts?: boolean;
83
- }): string;
101
+ issueToken(opts?: MirrorTokenOptions): string;
84
102
  isValidToken(token: string): MirrorTokenValidationResult;
103
+ listShares(): MirrorShare[];
104
+ revokeShare(id: string): boolean;
105
+ onShareRevoked(callback: (id: string) => void): () => void;
85
106
  authenticate(ctx: MirrorAuthContext): MirrorAuthDecision;
86
107
  authenticateUpgrade(ctx: MirrorAuthContext): boolean;
87
108
  persistSession(session: MirrorSession): string;
@@ -98,9 +119,8 @@ export declare class HmacMirrorAuthenticator implements MirrorAuthenticator {
98
119
  * legacy `!mirrorAuthEnabled` fallback that ran AFTER the token path.
99
120
  */
100
121
  export declare class OpenMirrorAuthenticator extends HmacMirrorAuthenticator {
101
- readonly enabled: boolean;
122
+ constructor(config: MirrorAuthenticatorConfig);
102
123
  authenticate(ctx: MirrorAuthContext): MirrorAuthDecision;
103
- authenticateUpgrade(_ctx: MirrorAuthContext): boolean;
104
124
  }
105
125
  /**
106
126
  * Build the authenticator from environment policy, mirroring the legacy
@@ -24,13 +24,16 @@ const DEFAULT_QUERY_TOKEN_NAME = 'ztc_mirror_token';
24
24
  const DEFAULT_TTL_MS = 12 * 60 * 60 * 1000;
25
25
  /** Production HMAC + session authenticator. Denies requests without valid credentials. */
26
26
  export class HmacMirrorAuthenticator {
27
- enabled = true;
27
+ requiresCredentials = true;
28
+ get enabled() { return this.requiresCredentials; }
28
29
  zergId;
29
30
  cookieName;
30
31
  queryTokenName;
31
32
  sharedSecret;
32
33
  internalToken;
33
34
  sessions = new Map();
35
+ shares = new Map();
36
+ revocationListeners = new Set();
34
37
  constructor(config) {
35
38
  this.sharedSecret = config.sharedSecret;
36
39
  this.zergId = config.zergId;
@@ -40,6 +43,26 @@ export class HmacMirrorAuthenticator {
40
43
  }
41
44
  issueToken(opts = {}) {
42
45
  const ttlMs = opts.ttlMs ?? DEFAULT_TTL_MS;
46
+ if (opts.readOnly) {
47
+ if (!Number.isSafeInteger(ttlMs) || ttlMs < 1000 || ttlMs > DEFAULT_TTL_MS)
48
+ throw new Error('Observation TTL must be between 1 second and 12 hours, in whole milliseconds.');
49
+ const label = (opts.label ?? 'Observer').trim();
50
+ if (!label || label.length > 64 || /[\x00-\x1f\x7f]/.test(label))
51
+ throw new Error('Share label must contain 1–64 printable characters.');
52
+ for (const [id, share] of this.shares) {
53
+ if (share.revoked || share.expiresAtMs <= Date.now())
54
+ this.shares.delete(id);
55
+ }
56
+ if (this.shares.size >= 100)
57
+ throw new Error('Share limit reached. Revoke an active observation share first.');
58
+ const id = randomUUID();
59
+ const expiresAtMs = Date.now() + ttlMs;
60
+ const signature = createHmac('sha256', this.sharedSecret).update(`${this.zergId}:${expiresAtMs}:observe:${id}`).digest('hex');
61
+ this.shares.set(id, { id, label, expiresAtMs, createdAtMs: Date.now(), revoked: false });
62
+ // Latch this on: revoking the last share must never restore open control.
63
+ this.requiresCredentials = true;
64
+ return `${expiresAtMs}.observe.${id}.${signature}`;
65
+ }
43
66
  const canInspectPrompts = opts.canInspectPrompts ?? false;
44
67
  const expiresAtSeconds = Math.floor((Date.now() + ttlMs) / 1000);
45
68
  const promptScope = canInspectPrompts ? '1' : '0';
@@ -49,6 +72,20 @@ export class HmacMirrorAuthenticator {
49
72
  }
50
73
  isValidToken(token) {
51
74
  const parts = token.split('.');
75
+ if (parts[1] === 'observe') {
76
+ const denied = { ok: false, expiresAtMs: 0, canInspectPrompts: false, canControl: false };
77
+ if (parts.length !== 4 || !/^\d+$/.test(parts[0]) || !/^[a-f0-9]{64}$/.test(parts[3]))
78
+ return denied;
79
+ const share = this.shares.get(parts[2]);
80
+ const expiresAtMs = Number(parts[0]);
81
+ if (!share || share.revoked || share.expiresAtMs !== expiresAtMs || Date.now() >= expiresAtMs || !this.sharedSecret)
82
+ return denied;
83
+ const expected = createHmac('sha256', this.sharedSecret).update(`${this.zergId}:${parts[0]}:observe:${share.id}`).digest();
84
+ const provided = Buffer.from(parts[3], 'hex');
85
+ if (!timingSafeEqual(expected, provided))
86
+ return denied;
87
+ return { ok: true, expiresAtMs, canInspectPrompts: false, canControl: false, shareId: share.id };
88
+ }
52
89
  if ((parts.length !== 2 && parts.length !== 3) || !this.sharedSecret) {
53
90
  return { ok: false, expiresAtMs: 0, canInspectPrompts: false };
54
91
  }
@@ -77,7 +114,21 @@ export class HmacMirrorAuthenticator {
77
114
  if (!timingSafeEqual(expected, provided)) {
78
115
  return { ok: false, expiresAtMs: 0, canInspectPrompts: false };
79
116
  }
80
- return { ok: true, expiresAtMs, canInspectPrompts: promptScope === '1' };
117
+ return { ok: true, expiresAtMs, canInspectPrompts: promptScope === '1', canControl: true };
118
+ }
119
+ listShares() { return [...this.shares.values()].map(share => ({ ...share })); }
120
+ revokeShare(id) {
121
+ const share = this.shares.get(id);
122
+ if (!share || share.revoked)
123
+ return false;
124
+ share.revoked = true;
125
+ for (const listener of this.revocationListeners)
126
+ listener(id);
127
+ return true;
128
+ }
129
+ onShareRevoked(callback) {
130
+ this.revocationListeners.add(callback);
131
+ return () => { this.revocationListeners.delete(callback); };
81
132
  }
82
133
  authenticate(ctx) {
83
134
  // 1. Internal-token header (process-internal callers).
@@ -95,9 +146,13 @@ export class HmacMirrorAuthenticator {
95
146
  const session = {
96
147
  expiresAtMs: result.expiresAtMs,
97
148
  canInspectPrompts: result.canInspectPrompts,
149
+ canControl: result.canControl !== false,
150
+ ...(result.shareId ? { shareId: result.shareId } : {}),
98
151
  };
99
152
  return { ok: true, session, issueCookie: session, source: 'browser' };
100
153
  }
154
+ if (tokenCandidate.split('.')[1] === 'observe')
155
+ return { ok: false, session: null, issueCookie: null, source: null };
101
156
  }
102
157
  // 3. Existing session cookie — no re-issuance.
103
158
  const session = this.sessionFromCookies(ctx.cookies);
@@ -108,26 +163,21 @@ export class HmacMirrorAuthenticator {
108
163
  return { ok: false, session: null, issueCookie: null, source: null };
109
164
  }
110
165
  authenticateUpgrade(ctx) {
111
- if (this.matchesInternalToken(ctx.headers))
112
- return true;
113
- const bearer = this.extractBearerToken(ctx.headers);
114
- if (bearer && this.isValidToken(bearer).ok)
115
- return true;
116
- const queryToken = ctx.url.searchParams.get(this.queryTokenName) || '';
117
- if (queryToken && this.isValidToken(queryToken).ok)
118
- return true;
119
- return this.sessionFromCookies(ctx.cookies) !== null;
166
+ const decision = this.authenticate(ctx);
167
+ return decision.ok && decision.session?.canControl !== false;
120
168
  }
121
169
  persistSession(session) {
122
170
  const sessionId = randomUUID();
123
- this.sessions.set(sessionId, session);
171
+ const observer = session.canControl === false || session.shareId !== undefined;
172
+ this.sessions.set(sessionId, { ...session, canControl: !observer, canInspectPrompts: observer ? false : session.canInspectPrompts });
124
173
  return sessionId;
125
174
  }
126
175
  getSession(sessionId) {
127
176
  const session = this.sessions.get(sessionId);
128
177
  if (!session)
129
178
  return null;
130
- if (Date.now() > session.expiresAtMs) {
179
+ const share = session.shareId ? this.shares.get(session.shareId) : undefined;
180
+ if (Date.now() >= session.expiresAtMs || (session.shareId && (!share || share.revoked || Date.now() >= share.expiresAtMs))) {
131
181
  this.sessions.delete(sessionId);
132
182
  return null;
133
183
  }
@@ -165,16 +215,16 @@ export class HmacMirrorAuthenticator {
165
215
  * legacy `!mirrorAuthEnabled` fallback that ran AFTER the token path.
166
216
  */
167
217
  export class OpenMirrorAuthenticator extends HmacMirrorAuthenticator {
168
- enabled = false;
218
+ constructor(config) { super(config); this.requiresCredentials = false; }
169
219
  authenticate(ctx) {
170
220
  const decision = super.authenticate(ctx);
171
221
  if (decision.ok)
172
222
  return decision;
223
+ const candidate = this.extractBearerToken(ctx.headers) || ctx.url.searchParams.get(this.queryTokenName) || '';
224
+ if (this.enabled || candidate.split('.')[1] === 'observe')
225
+ return decision;
173
226
  return { ok: true, session: null, issueCookie: null, source: 'open' };
174
227
  }
175
- authenticateUpgrade(_ctx) {
176
- return true;
177
- }
178
228
  }
179
229
  /**
180
230
  * Build the authenticator from environment policy, mirroring the legacy
@@ -8,18 +8,34 @@
8
8
  *
9
9
  * Also provides bus connectivity for inter-ZTC messaging via SSE.
10
10
  */
11
+ import { type EvidenceSnapshot } from '../agent/runtime/evidence.js';
12
+ import type { TaskHandoffProjection } from '../session_handoff_contract.js';
11
13
  import type { SlashCommandUsage } from '../agent/commands/index.js';
12
14
  import type { MirrorPublisher, BusMessage, BusMember, ZlickyWebCursor, ZlickyWebHighlight, ZlickyWebStatus, HookApprovalPublishPayload } from './mirror_stream.js';
15
+ export interface MirrorClientOptions {
16
+ /** Absolute deadline for each local HTTP exchange, including its response body. */
17
+ publicationTimeoutMs?: number;
18
+ }
13
19
  export declare class MirrorClient implements MirrorPublisher {
14
20
  private port;
15
21
  private paneId;
22
+ private readonly sessionId;
16
23
  private busConnection;
17
24
  private busReconnectTimer;
18
25
  private paneName;
19
26
  private lastTokenUsage;
20
27
  private internalToken;
21
28
  private groupId;
22
- constructor(port: number, paneId: number);
29
+ private readonly publicationTimeoutMs;
30
+ private publicationId;
31
+ private publicationSequence;
32
+ private publicationQueue;
33
+ private publicationBytes;
34
+ private publicationRequest;
35
+ private publicationDraining;
36
+ private publicationFailure;
37
+ private publicationDrain;
38
+ constructor(port: number, paneId: number, options?: MirrorClientOptions | string);
23
39
  getPaneId(): number;
24
40
  getPaneName(): string;
25
41
  getBusMember(): BusMember;
@@ -27,7 +43,12 @@ export declare class MirrorClient implements MirrorPublisher {
27
43
  type: string;
28
44
  data: Record<string, unknown>;
29
45
  }): void;
46
+ /** Resolve after acknowledged publications, or reject with the bounded transport failure. */
47
+ flushPublications(): Promise<void>;
48
+ private failPublication;
30
49
  private postEvent;
50
+ private drainPublications;
51
+ private postPublication;
31
52
  storeEvent(event: {
32
53
  type: string;
33
54
  data: Record<string, unknown>;
@@ -54,6 +75,8 @@ export declare class MirrorClient implements MirrorPublisher {
54
75
  publishSettingsPage(data?: Record<string, unknown>): void;
55
76
  publishStreamEnd(finalMessage?: string, metadata?: Record<string, unknown>): void;
56
77
  publishToolCall(tool: string, args: Record<string, unknown>, toolCallId: string): void;
78
+ publishEvidenceSnapshot(snapshot: EvidenceSnapshot, sessionId: string): void;
79
+ publishTaskHandoff(projection: TaskHandoffProjection | null, sessionId: string): void;
57
80
  publishToolResult(tool: string, result: string, success: boolean, toolCallId: string): void;
58
81
  publishTodoList(todos: Array<{
59
82
  content: string;
@@ -67,13 +90,17 @@ export declare class MirrorClient implements MirrorPublisher {
67
90
  description: string;
68
91
  recommended?: boolean;
69
92
  }>;
70
- }>, paneId?: number, allowOther?: boolean): void;
93
+ }>, paneId?: number, allowOther?: boolean): string;
71
94
  publishHookApprovalRequest(request: HookApprovalPublishPayload): void;
95
+ publishHookApprovalResolved(id: string): void;
96
+ publishQuestionDismiss(questionId: string): void;
72
97
  publishWidgetPrompt(widgetId: string, options: {
73
98
  title?: string;
74
99
  question: string;
75
100
  placeholder?: string;
76
101
  defaultValue?: string;
102
+ isPassword?: boolean;
103
+ allowEmptySubmit?: boolean;
77
104
  }): void;
78
105
  publishWidgetSelect(widgetId: string, options: {
79
106
  title?: string;
@@ -104,7 +131,7 @@ export declare class MirrorClient implements MirrorPublisher {
104
131
  }): void;
105
132
  publishWidgetDismiss(widgetId: string): void;
106
133
  publishWidgetSettings(widgetId: string, data: Record<string, unknown>): void;
107
- publishStatus(status: string, verb?: string): void;
134
+ publishStatus(status: string, verb?: string, waiting?: import('../types.js').CommandWaitingState, toolProgress?: import('../types.js').AgentState['toolProgress']): void;
108
135
  publishQueueState(total: number, entries: string[]): void;
109
136
  publishTokenUsage(input: number, output: number, total: number, percentage: number, options?: {
110
137
  reset?: boolean;
@@ -168,4 +195,4 @@ export declare class MirrorClient implements MirrorPublisher {
168
195
  * Create a MirrorClient if the environment indicates we're a child pane
169
196
  * with a parent mirror server. Returns null otherwise.
170
197
  */
171
- export declare function initMirrorClient(): MirrorClient | null;
198
+ export declare function initMirrorClient(sessionId?: string): MirrorClient | null;
@@ -9,18 +9,43 @@
9
9
  * Also provides bus connectivity for inter-ZTC messaging via SSE.
10
10
  */
11
11
  import { request } from 'http';
12
+ import { parseEvidenceSnapshot } from '../agent/runtime/evidence.js';
13
+ import { parseToolProgress } from '../tool_progress.js';
14
+ import { parseTaskHandoffView } from './view_plugin.js';
15
+ import { randomUUID } from 'node:crypto';
16
+ import { MAX_TOOL_IMAGE_BODY_BYTES, mirrorToolImage } from './tool_image.js';
17
+ const MAX_PENDING_PUBLICATIONS = 256;
18
+ const MAX_PENDING_PUBLICATION_BYTES = 2 * 1024 * 1024;
19
+ const MAX_CHILD_EVENT_BYTES = 512 * 1024 - 512;
20
+ const MAX_PUBLICATION_RESPONSE_BYTES = 16 * 1024;
12
21
  export class MirrorClient {
13
22
  port;
14
23
  paneId;
24
+ sessionId;
15
25
  busConnection = null;
16
26
  busReconnectTimer = null;
17
27
  paneName;
18
28
  lastTokenUsage = null;
19
29
  internalToken;
20
30
  groupId;
21
- constructor(port, paneId) {
31
+ publicationTimeoutMs;
32
+ publicationId = null;
33
+ publicationSequence = 0;
34
+ publicationQueue = [];
35
+ publicationBytes = 0;
36
+ publicationRequest = null;
37
+ publicationDraining = false;
38
+ publicationFailure = null;
39
+ publicationDrain = Promise.resolve();
40
+ constructor(port, paneId, options = {}) {
22
41
  this.port = port;
23
42
  this.paneId = paneId;
43
+ this.sessionId = typeof options === 'string' ? options : null;
44
+ const timeout = (typeof options === 'string' ? {} : options).publicationTimeoutMs ?? 5000;
45
+ if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 60_000) {
46
+ throw new RangeError('publicationTimeoutMs must be an integer between 1 and 60000');
47
+ }
48
+ this.publicationTimeoutMs = timeout;
24
49
  this.paneName = paneId > 0 ? `ZTC ${paneId}` : 'ZTC';
25
50
  this.internalToken = process.env.ZTC_MIRROR_INTERNAL_TOKEN || '';
26
51
  this.groupId = process.env.ZTC_MIRROR_GROUP || '';
@@ -37,22 +62,141 @@ export class MirrorClient {
37
62
  publish(event) {
38
63
  this.postEvent(event);
39
64
  }
40
- postEvent(event, storeOnly = false) {
41
- const payload = JSON.stringify({ pane_id: this.paneId, event, ...(storeOnly ? { store_only: true } : {}) });
42
- const req = request({
43
- hostname: 'localhost',
44
- port: this.port,
45
- path: this.groupId ? `/pane-events/${this.groupId}` : '/pane-events',
46
- method: 'POST',
47
- headers: {
48
- 'Content-Type': 'application/json',
49
- 'Content-Length': Buffer.byteLength(payload),
50
- ...(this.internalToken ? { 'x-ztc-internal-token': this.internalToken } : {}),
51
- },
65
+ /** Resolve after acknowledged publications, or reject with the bounded transport failure. */
66
+ async flushPublications() {
67
+ await this.publicationDrain;
68
+ if (this.publicationFailure)
69
+ throw this.publicationFailure;
70
+ }
71
+ failPublication(error) {
72
+ if (this.publicationFailure)
73
+ return;
74
+ this.publicationFailure = error;
75
+ const dropped = this.publicationQueue.length;
76
+ this.publicationQueue = [];
77
+ this.publicationBytes = 0;
78
+ this.publicationId = null;
79
+ this.publicationSequence = 0;
80
+ this.publicationRequest?.destroy();
81
+ process.stderr.write(`[Mirror pane=${this.paneId}] Child publication failed: ${error.message}. ${dropped} queued update(s) discarded; later updates open a fresh stream without replay.\n`);
82
+ }
83
+ postEvent(event, storeOnly = false, toolImage = false) {
84
+ if (this.sessionId !== null)
85
+ event = { ...event, data: { ...event.data, origin_session_id: this.sessionId } };
86
+ // A failure already tearing down its request cannot accept another update yet.
87
+ if (this.publicationDraining && this.publicationFailure)
88
+ return;
89
+ if (!this.publicationDraining)
90
+ this.publicationFailure = null;
91
+ let eventJson;
92
+ try {
93
+ eventJson = JSON.stringify(event);
94
+ }
95
+ catch {
96
+ this.failPublication(new Error('Child event is not JSON serializable'));
97
+ return;
98
+ }
99
+ const bytes = Buffer.byteLength(eventJson) + 512;
100
+ if (bytes > (toolImage ? MAX_TOOL_IMAGE_BODY_BYTES : MAX_CHILD_EVENT_BYTES)) {
101
+ this.failPublication(new Error('Child event exceeds the 512 KiB publication limit'));
102
+ return;
103
+ }
104
+ if (this.publicationQueue.length >= MAX_PENDING_PUBLICATIONS || this.publicationBytes + bytes > (toolImage ? MAX_TOOL_IMAGE_BODY_BYTES + MAX_PENDING_PUBLICATION_BYTES : MAX_PENDING_PUBLICATION_BYTES)) {
105
+ this.failPublication(new Error('Child publication queue exceeds 256 updates or 2 MiB'));
106
+ return;
107
+ }
108
+ this.publicationQueue.push({ eventJson, bytes, storeOnly, toolImage });
109
+ this.publicationBytes += bytes;
110
+ if (!this.publicationDraining)
111
+ this.publicationDrain = this.drainPublications();
112
+ }
113
+ async drainPublications() {
114
+ this.publicationDraining = true;
115
+ try {
116
+ if (!this.publicationId) {
117
+ const opened = await this.postPublication('/pane-publication', JSON.stringify({ pane_id: this.paneId }));
118
+ if (this.publicationFailure)
119
+ throw this.publicationFailure;
120
+ if (typeof opened.publication_id !== 'string' || !opened.publication_id || opened.publication_id.length > 256) {
121
+ throw new Error('Parent mirror did not issue a publication identity; update parent and child to matching versions');
122
+ }
123
+ this.publicationId = opened.publication_id;
124
+ }
125
+ while (this.publicationQueue.length) {
126
+ const item = this.publicationQueue[0];
127
+ const sequence = this.publicationSequence + 1;
128
+ const payload = `{"pane_id":${this.paneId},"publication_id":${JSON.stringify(this.publicationId)},"sequence":${sequence},"event":${item.eventJson}${item.storeOnly ? ',"store_only":true' : ''}}`;
129
+ await this.postPublication('/pane-events', payload, item.toolImage);
130
+ if (this.publicationFailure)
131
+ throw this.publicationFailure;
132
+ this.publicationSequence = sequence;
133
+ this.publicationQueue.shift();
134
+ this.publicationBytes -= item.bytes;
135
+ }
136
+ }
137
+ catch (error) {
138
+ this.failPublication(error instanceof Error ? error : new Error(String(error)));
139
+ }
140
+ finally {
141
+ this.publicationDraining = false;
142
+ }
143
+ }
144
+ postPublication(path, payload, toolImage = false) {
145
+ return new Promise((resolve, reject) => {
146
+ const req = request({
147
+ hostname: 'localhost', port: this.port,
148
+ path: this.groupId ? `${path}/${this.groupId}` : path,
149
+ method: 'POST', headers: {
150
+ 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload),
151
+ ...(this.internalToken ? { 'x-ztc-internal-token': this.internalToken } : {}),
152
+ ...(toolImage ? { 'x-ztc-tool-image': '1' } : {}),
153
+ },
154
+ }, res => {
155
+ let output = '';
156
+ let bytes = 0;
157
+ res.on('data', (chunk) => {
158
+ bytes += chunk.length;
159
+ if (bytes > MAX_PUBLICATION_RESPONSE_BYTES) {
160
+ reject(new Error('Parent publication response exceeds 16 KiB'));
161
+ req.destroy();
162
+ res.destroy();
163
+ }
164
+ else
165
+ output += chunk.toString();
166
+ });
167
+ res.on('aborted', () => reject(new Error('Parent publication response was interrupted')));
168
+ res.on('error', reject);
169
+ res.on('end', () => {
170
+ if (res.statusCode !== 200) {
171
+ reject(new Error(`Parent publication HTTP ${res.statusCode ?? 0}`));
172
+ return;
173
+ }
174
+ try {
175
+ const body = JSON.parse(output);
176
+ if (!body || typeof body !== 'object' || Array.isArray(body) || body.ok !== true) {
177
+ reject(new Error('Parent publication receipt is malformed'));
178
+ return;
179
+ }
180
+ resolve(body);
181
+ }
182
+ catch {
183
+ reject(new Error('Parent publication receipt is not valid JSON'));
184
+ }
185
+ });
186
+ });
187
+ this.publicationRequest = req;
188
+ const timer = setTimeout(() => {
189
+ reject(new Error(`Child publication timed out after ${this.publicationTimeoutMs} ms`));
190
+ req.destroy();
191
+ }, this.publicationTimeoutMs);
192
+ req.on('error', reject);
193
+ req.on('close', () => {
194
+ clearTimeout(timer);
195
+ if (this.publicationRequest === req)
196
+ this.publicationRequest = null;
197
+ });
198
+ req.end(payload);
52
199
  });
53
- req.on('error', () => { }); // fire-and-forget
54
- req.write(payload);
55
- req.end();
56
200
  }
57
201
  storeEvent(event) {
58
202
  this.postEvent(event, true);
@@ -194,23 +338,37 @@ export class MirrorClient {
194
338
  publishToolCall(tool, args, toolCallId) {
195
339
  this.postEvent({ type: 'tool_call', data: { tool, args, toolCallId } });
196
340
  }
341
+ publishEvidenceSnapshot(snapshot, sessionId) {
342
+ const validated = parseEvidenceSnapshot(snapshot);
343
+ if (!validated || !sessionId || Buffer.byteLength(sessionId) > 1024)
344
+ return;
345
+ this.postEvent({ type: 'evidence', data: { snapshot: validated, session_id: sessionId } });
346
+ }
347
+ publishTaskHandoff(projection, sessionId) {
348
+ const validated = parseTaskHandoffView({ sessionId, projection });
349
+ if (validated)
350
+ this.postEvent({ type: 'task_handoff', data: { ...validated } });
351
+ }
197
352
  publishToolResult(tool, result, success, toolCallId) {
353
+ const image = mirrorToolImage(result);
198
354
  this.postEvent({
199
355
  type: 'tool_result',
200
- data: { tool, result: result.slice(0, 2000), success, toolCallId },
201
- });
356
+ data: { tool, result: image ? result : result.slice(0, 2000), success, toolCallId },
357
+ }, false, Boolean(image));
202
358
  }
203
359
  publishTodoList(todos) {
204
360
  this.postEvent({ type: 'todo_list', data: { todos } });
205
361
  }
206
362
  publishAskUser(questions, paneId, allowOther) {
207
- const baseData = { pane_id: paneId, allow_other: allowOther ?? true };
363
+ const questionId = randomUUID();
364
+ const baseData = { pane_id: paneId, question_id: questionId, allow_other: allowOther ?? true };
208
365
  if (questions.length === 1) {
209
366
  this.postEvent({ type: 'ask_user', data: { ...baseData, question: questions[0].question, options: questions[0].options } });
210
367
  }
211
368
  else {
212
369
  this.postEvent({ type: 'ask_user', data: { ...baseData, questions } });
213
370
  }
371
+ return questionId;
214
372
  }
215
373
  publishHookApprovalRequest(request) {
216
374
  this.postEvent({
@@ -226,6 +384,12 @@ export class MirrorClient {
226
384
  },
227
385
  });
228
386
  }
387
+ publishHookApprovalResolved(id) {
388
+ this.postEvent({ type: 'hook_approval_resolved', data: { id } });
389
+ }
390
+ publishQuestionDismiss(questionId) {
391
+ this.postEvent({ type: 'question_dismiss', data: { question_id: questionId } });
392
+ }
229
393
  publishWidgetPrompt(widgetId, options) {
230
394
  this.postEvent({ type: 'widget_prompt', data: { widget_id: widgetId, ...options } });
231
395
  }
@@ -241,8 +405,10 @@ export class MirrorClient {
241
405
  publishWidgetSettings(widgetId, data) {
242
406
  this.postEvent({ type: 'widget_settings', data: { widget_id: widgetId, ...data } });
243
407
  }
244
- publishStatus(status, verb) {
245
- this.postEvent({ type: 'status', data: { status, verb } });
408
+ publishStatus(status, verb, waiting, toolProgress) {
409
+ const observed = status === 'tool_executing' ? parseToolProgress(toolProgress) : null;
410
+ this.postEvent({ type: 'status', data: { status, verb, ...(waiting ? { waiting } : {}),
411
+ ...(observed ? { toolProgress: observed } : {}) } });
246
412
  }
247
413
  publishQueueState(total, entries) {
248
414
  this.postEvent({ type: 'queue_state', data: { total, entries } });
@@ -327,10 +493,10 @@ export class MirrorClient {
327
493
  * Create a MirrorClient if the environment indicates we're a child pane
328
494
  * with a parent mirror server. Returns null otherwise.
329
495
  */
330
- export function initMirrorClient() {
496
+ export function initMirrorClient(sessionId) {
331
497
  const port = process.env.ZTC_MIRROR_PORT;
332
498
  const paneId = process.env.ZTC_PANE_ID;
333
499
  if (!port)
334
500
  return null;
335
- return new MirrorClient(parseInt(port, 10), paneId ? parseInt(paneId, 10) : -1);
501
+ return new MirrorClient(parseInt(port, 10), paneId ? parseInt(paneId, 10) : -1, sessionId);
336
502
  }