@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,3 +1,4 @@
1
+ import { displayPaneTitle, replacePaneLabels } from '../../panes/labels.js';
1
2
  import { stripPasteMarkers } from './pane_input.js';
2
3
  import { CAPABILITY_PANE_DELIVERY_ACK } from './protocol.js';
3
4
  /**
@@ -14,11 +15,12 @@ import { CAPABILITY_PANE_DELIVERY_ACK } from './protocol.js';
14
15
  * native build), terminal panes fall back to the old piped-stdio behavior.
15
16
  */
16
17
  import { spawn } from 'child_process';
17
- import { accessSync, chmodSync, existsSync } from 'fs';
18
- import { dirname, join } from 'path';
18
+ import { accessSync, chmodSync, constants, existsSync, statSync } from 'fs';
19
+ import { delimiter, dirname, isAbsolute, join, resolve } from 'path';
19
20
  import { createRequire } from 'module';
20
- import { isMuxPaneRestorable, resolveMuxPersistenceOptions, sanitizeMuxSessionState, shouldPersistMuxPaneType } from './mux_persistence.js';
21
- import { buildUserSubprocessEnv } from '../../utils/subprocess_env.js';
21
+ import { isMuxPaneRestorable, resolveMuxPersistenceOptions, sanitizeMuxSessionState, validateWorkspaceState } from './mux_persistence.js';
22
+ import { buildUserSubprocessEnv, removeUserSubprocessCredentials } from '../../utils/subprocess_env.js';
23
+ import { handleWorkspaceLayout } from '../../workspace_layout.js';
22
24
  let _ptyMod;
23
25
  function loadPty() {
24
26
  if (_ptyMod !== undefined)
@@ -56,6 +58,32 @@ function isTerminalPaneType(paneType) {
56
58
  return paneType === 'process' || paneType === 'command';
57
59
  }
58
60
  const MAX_BUFFER_LINES = 200;
61
+ function restoredPaneStatus(pane) {
62
+ if (pane.cwd !== undefined) {
63
+ try {
64
+ if (!statSync(pane.cwd).isDirectory())
65
+ return 'missing_directory';
66
+ }
67
+ catch {
68
+ return 'missing_directory';
69
+ }
70
+ }
71
+ if (!pane.command)
72
+ return 'missing_command';
73
+ const candidates = isAbsolute(pane.command) || /[/\\]/.test(pane.command)
74
+ ? [isAbsolute(pane.command) ? pane.command : resolve(pane.cwd ?? process.cwd(), pane.command)]
75
+ : (process.env.PATH ?? '').split(delimiter).filter(Boolean).map(directory => join(directory, pane.command));
76
+ for (const candidate of candidates) {
77
+ try {
78
+ if (!statSync(candidate).isFile())
79
+ continue;
80
+ accessSync(candidate, process.platform === 'win32' ? constants.F_OK : constants.X_OK);
81
+ return 'not_started';
82
+ }
83
+ catch { /* A missing executable is retained as inactive intent. */ }
84
+ }
85
+ return 'missing_command';
86
+ }
59
87
  // ZTC child panes (--pane / colony) run as headless paneChild processes that
60
88
  // read ONE JSON object per stdin line and recover the full (possibly
61
89
  // multi-line) prompt via JSON.parse (headless.ts paneChild / --json branches).
@@ -77,16 +105,18 @@ export function encodeZtcPaneInput(input) {
77
105
  * buildUserSubprocessEnv so nested user processes don't inherit the parent's
78
106
  * control plane. Callers that DO need specific infra vars in a child (e.g.
79
107
  * sim agent panes attaching to the message bus) must pass them explicitly via
80
- * `commandEnv` — those are merged last and survive the stripping.
108
+ * `commandEnv` — those are merged last. Host RPC credentials are still removed
109
+ * from user process panes after the merge.
81
110
  */
82
111
  export function computePaneSpawnEnv(paneType, paneId, options = {}, source = process.env) {
83
- return {
112
+ const env = {
84
113
  ...(paneType === 'colony_ztc' ? source : buildUserSubprocessEnv(source)),
85
114
  ...(paneType === 'colony_ztc' ? {} : { ZTC_HEADLESS_MUX: '1' }),
86
115
  ZTC_PANE_ID: String(paneId),
87
116
  ...(options.persona ? { ZTC_SIM_PERSONA: options.persona } : {}),
88
117
  ...(options.commandEnv ?? {}),
89
118
  };
119
+ return paneType === 'colony_ztc' ? env : removeUserSubprocessCredentials(env);
90
120
  }
91
121
  /**
92
122
  * Inverse of encodeZtcPaneInput: recover the original input from a stdin line a
@@ -157,25 +187,40 @@ export class HeadlessPaneManager {
157
187
  closedPanes = new Map();
158
188
  nextPaneId;
159
189
  handlers = new Set();
160
- hostTitle = 'ZTC';
190
+ hostTitle = 'Main';
161
191
  hostActivity = {};
162
192
  layout = { type: 'leaf', pane_id: 0 };
163
- constructor(options) {
164
- this.nextPaneId = options?.startPaneId ?? 1;
165
- // Safety net: force-kill all children when this process exits.
166
- // Runs synchronously — works for normal exit, SIGTERM, uncaught exceptions.
167
- // SIGKILL cannot be caught, but the OS will clean up child processes if
168
- // they're in the same process group (default for spawn with shell: true).
169
- process.on('exit', () => {
170
- for (const pane of this.panes.values()) {
171
- if (pane.isAlive && (pane.process || pane.pty)) {
172
- try {
173
- this.killPaneProc(pane, 'SIGTERM');
174
- }
175
- catch { /* ignore */ }
193
+ workspaceMetadata = {
194
+ schema_version: 1,
195
+ focused_pane_id: 0,
196
+ geometry: { cols: 120, rows: 40 },
197
+ };
198
+ hostLabels = {};
199
+ exitSubscribed = false;
200
+ exitHandler = () => {
201
+ for (const pane of this.panes.values()) {
202
+ if (pane.isAlive && (pane.process || pane.pty)) {
203
+ try {
204
+ this.killPaneProc(pane, 'SIGTERM');
176
205
  }
206
+ catch { /* ignore */ }
177
207
  }
178
- });
208
+ }
209
+ };
210
+ constructor(options) {
211
+ this.nextPaneId = options?.startPaneId ?? 1;
212
+ // Synchronous safety net for normal process exit; stopped owners release it.
213
+ this.subscribeToExit();
214
+ }
215
+ subscribeToExit() {
216
+ if (this.exitSubscribed)
217
+ return;
218
+ process.on('exit', this.exitHandler);
219
+ this.exitSubscribed = true;
220
+ }
221
+ unsubscribeFromExit() {
222
+ process.off('exit', this.exitHandler);
223
+ this.exitSubscribed = false;
179
224
  }
180
225
  /** Set the display title for pane 0 (the host ZTC process). */
181
226
  setHostTitle(title) {
@@ -217,6 +262,8 @@ export class HeadlessPaneManager {
217
262
  return this.handleCreateDocPane(cmd);
218
263
  case 'replace_pane':
219
264
  return this.handleReplacePane(cmd);
265
+ case 'restart_pane':
266
+ return this.handleRestartPane(cmd);
220
267
  case 'read_pane':
221
268
  return this.handleReadPane(cmd);
222
269
  case 'write_pane':
@@ -229,6 +276,16 @@ export class HeadlessPaneManager {
229
276
  return this.handleSetPaneContent(cmd);
230
277
  case 'close_pane':
231
278
  return this.handleClosePane(cmd);
279
+ case 'set_pane_labels':
280
+ if (cmd.pane_id === 0)
281
+ this.hostLabels = replacePaneLabels(this.hostLabels, cmd.labels, cmd.if_newer);
282
+ else {
283
+ const pane = this.panes.get(cmd.pane_id);
284
+ if (pane)
285
+ pane.labels = replacePaneLabels(pane.labels ?? {}, cmd.labels, cmd.if_newer);
286
+ }
287
+ this.publishPaneLabels();
288
+ return true;
232
289
  case 'set_pane_title':
233
290
  return this.handleSetPaneTitle(cmd);
234
291
  case 'set_pane_activity':
@@ -237,8 +294,14 @@ export class HeadlessPaneManager {
237
294
  return this.handleListPanes();
238
295
  case 'get_session_state':
239
296
  return this.handleGetSessionState();
297
+ case 'get_terminal_metrics':
298
+ this.emit({ type: 'error', message: 'terminal frame metrics require the native desktop renderer' });
299
+ return true;
240
300
  case 'restore_session_state':
241
- return this.handleRestoreSessionState(cmd);
301
+ this.handleRestoreSessionState(cmd);
302
+ return true;
303
+ case 'workspace_layout':
304
+ return this.handleNamedWorkspaceLayout(cmd);
242
305
  case 'resize_fence':
243
306
  this.emit({ type: 'resize_ack', seq: cmd.seq });
244
307
  return true;
@@ -249,7 +312,7 @@ export class HeadlessPaneManager {
249
312
  }
250
313
  /** Headless implements correlated pane reads and delivery receipts itself. */
251
314
  hasCapability(name) {
252
- return name === CAPABILITY_PANE_DELIVERY_ACK;
315
+ return name === CAPABILITY_PANE_DELIVERY_ACK || name === 'inactive_workspace_restore' || name === 'pane_labels_v1';
253
316
  }
254
317
  /**
255
318
  * Headless mode has no native renderer to read the clipboard, so image
@@ -258,10 +321,14 @@ export class HeadlessPaneManager {
258
321
  readClipboardImage() {
259
322
  return Promise.resolve(null);
260
323
  }
324
+ readClipboardText() {
325
+ return Promise.resolve(null);
326
+ }
261
327
  isReady() {
262
328
  return true;
263
329
  }
264
330
  async start(_options) {
331
+ this.subscribeToExit();
265
332
  return { cols: 120, rows: 40 };
266
333
  }
267
334
  async stop() {
@@ -289,6 +356,7 @@ export class HeadlessPaneManager {
289
356
  }
290
357
  this.panes.clear();
291
358
  this.closedPanes.clear();
359
+ this.unsubscribeFromExit();
292
360
  }
293
361
  kill() {
294
362
  for (const pane of this.panes.values()) {
@@ -303,6 +371,7 @@ export class HeadlessPaneManager {
303
371
  }
304
372
  this.panes.clear();
305
373
  this.closedPanes.clear();
374
+ this.unsubscribeFromExit();
306
375
  }
307
376
  // --------------------------------------------------------------------------
308
377
  // Command handlers
@@ -312,11 +381,25 @@ export class HeadlessPaneManager {
312
381
  const dir = direction || 'horizontal';
313
382
  const r = ratio ?? 0.5;
314
383
  this.layout = splitLayoutNode(this.layout, targetId, paneId, dir, r);
384
+ const window = this.workspaceMetadata.windows?.find(window => window.id === this.workspaceMetadata.active_window_id);
385
+ if (window)
386
+ window.layout = this.layout;
315
387
  }
316
388
  removePaneFromLayout(paneId) {
317
389
  const updated = removeLayoutNode(this.layout, paneId);
318
- if (updated)
319
- this.layout = updated;
390
+ this.layout = updated ?? { type: 'leaf', pane_id: 0 };
391
+ for (const window of this.workspaceMetadata.windows ?? []) {
392
+ window.layout = removeLayoutNode(window.layout, paneId) ?? { type: 'leaf', pane_id: 0 };
393
+ if (window.focused_pane_id === paneId)
394
+ window.focused_pane_id = findFirstLeafId(window.layout);
395
+ if (window.zoomed_pane_id === paneId)
396
+ delete window.zoomed_pane_id;
397
+ }
398
+ if (this.workspaceMetadata.focused_pane_id === paneId) {
399
+ this.workspaceMetadata.focused_pane_id = findFirstLeafId(this.layout);
400
+ }
401
+ if (this.workspaceMetadata.zoomed_pane_id === paneId)
402
+ delete this.workspaceMetadata.zoomed_pane_id;
320
403
  }
321
404
  reservePaneId(paneId) {
322
405
  const id = paneId ?? this.nextPaneId;
@@ -329,12 +412,14 @@ export class HeadlessPaneManager {
329
412
  return id;
330
413
  }
331
414
  handleCreatePane(cmd, options) {
415
+ // Direct transport callers may create panes without an explicit start().
416
+ this.subscribeToExit();
332
417
  const id = this.reservePaneId(options?.paneId);
333
418
  const title = cmd.title || cmd.command;
334
419
  const args = cmd.args || [];
335
420
  const cwd = cmd.cwd || process.cwd();
336
421
  // Detect whether this is a ZTC child or a generic process
337
- const isZtc = args.some(a => /cli_(main|ratatui)\.(js|ts)$/.test(a)) && args.includes('--pane');
422
+ const isZtc = (args[0] === '--ztc-cli' || args.some(a => /cli_(main|ratatui)\.(js|ts)$/.test(a))) && args.includes('--pane');
338
423
  const paneType = cmd.pane_type || (isZtc ? 'ztc' : 'process');
339
424
  const groupId = cmd.env?.ZTC_MIRROR_GROUP || '';
340
425
  // Reuse the shared env builder (dev's computePaneSpawnEnv) — behaviourally
@@ -350,6 +435,7 @@ export class HeadlessPaneManager {
350
435
  paneType,
351
436
  outputBuffer: [],
352
437
  isAlive: true,
438
+ windowId: this.workspaceMetadata.active_window_id,
353
439
  launch: { command: cmd.command, args, cwd, requestId: cmd.request_id },
354
440
  };
355
441
  const appendOutput = (text) => {
@@ -440,7 +526,7 @@ export class HeadlessPaneManager {
440
526
  cwd,
441
527
  stdio: ['pipe', 'pipe', 'pipe'],
442
528
  env: childEnv,
443
- shell: paneType !== 'colony_ztc',
529
+ shell: !isZtcPaneType(paneType),
444
530
  });
445
531
  }
446
532
  catch {
@@ -481,6 +567,7 @@ export class HeadlessPaneManager {
481
567
  paneType: 'feed',
482
568
  outputBuffer: [...(cmd.lines || [])],
483
569
  isAlive: true,
570
+ windowId: this.workspaceMetadata.active_window_id,
484
571
  launch: { content: (cmd.lines || []).join('\n') },
485
572
  };
486
573
  this.panes.set(id, pane);
@@ -504,6 +591,7 @@ export class HeadlessPaneManager {
504
591
  paneType: 'doc',
505
592
  outputBuffer: splitDocContent(cmd.content || ''),
506
593
  isAlive: true,
594
+ windowId: this.workspaceMetadata.active_window_id,
507
595
  launch: { content: cmd.content || '' },
508
596
  };
509
597
  this.panes.set(id, pane);
@@ -548,7 +636,7 @@ export class HeadlessPaneManager {
548
636
  cwd,
549
637
  stdio: ['pipe', 'pipe', 'pipe'],
550
638
  env: computePaneSpawnEnv(paneType, cmd.pane_id),
551
- shell: paneType !== 'colony_ztc',
639
+ shell: !isZtcPaneType(paneType),
552
640
  });
553
641
  const nextPane = {
554
642
  id: cmd.pane_id,
@@ -602,6 +690,40 @@ export class HeadlessPaneManager {
602
690
  }
603
691
  return true;
604
692
  }
693
+ handleRestartPane(cmd) {
694
+ const pane = this.panes.get(cmd.pane_id);
695
+ if (!pane) {
696
+ this.emit({ type: 'error', message: `Pane ${cmd.pane_id} not found; no saved intent was started.` });
697
+ return true;
698
+ }
699
+ if (isZtcPaneType(pane.paneType) || pane.agentSession) {
700
+ this.emit({ type: 'error', message: `Pane ${cmd.pane_id} is an agent session. Resume its exact saved session through the owning ZTC session controls.` });
701
+ return true;
702
+ }
703
+ if (pane.isAlive || !isTerminalPaneType(pane.paneType)) {
704
+ this.emit({ type: 'error', message: `Pane ${cmd.pane_id} is not an inactive process; close its current task before relaunching.` });
705
+ return true;
706
+ }
707
+ const launch = pane.launch;
708
+ if (!launch?.cwd) {
709
+ this.emit({ type: 'error', message: `Pane ${cmd.pane_id} has no saved working directory; choose an explicit working directory before relaunching.` });
710
+ return true;
711
+ }
712
+ const status = restoredPaneStatus({ id: pane.id, title: pane.title, pane_type: pane.paneType,
713
+ command: launch.command, args: launch.args, cwd: launch.cwd });
714
+ if (status !== 'not_started' || !launch.command) {
715
+ const reason = status === 'missing_directory' ? 'Saved working directory is missing or unavailable'
716
+ : 'Saved command is missing or unavailable';
717
+ this.emit({ type: 'error', message: `Pane ${cmd.pane_id}: ${reason}; saved intent was preserved.` });
718
+ return true;
719
+ }
720
+ const created = this.handleCreatePane({ type: 'create_pane', command: launch.command,
721
+ args: launch.args, cwd: launch.cwd, title: pane.title, pane_type: pane.paneType }, { paneId: pane.id });
722
+ const nextPane = this.panes.get(pane.id);
723
+ if (nextPane)
724
+ nextPane.windowId = pane.windowId;
725
+ return created;
726
+ }
605
727
  handleReadPane(cmd) {
606
728
  const pane = this.panes.get(cmd.pane_id) ?? this.closedPanes.get(cmd.pane_id);
607
729
  if (!pane) {
@@ -711,6 +833,10 @@ export class HeadlessPaneManager {
711
833
  });
712
834
  return true;
713
835
  }
836
+ if (pane.agentSession && !pane.isAlive) {
837
+ this.emit({ type: 'error', message: `Pane ${cmd.pane_id}: explicit Resume is required before changing saved agent content` });
838
+ return true;
839
+ }
714
840
  pane.outputBuffer.push(...cmd.lines);
715
841
  const trim = cmd.trim ?? MAX_BUFFER_LINES;
716
842
  if (pane.outputBuffer.length > trim) {
@@ -727,13 +853,23 @@ export class HeadlessPaneManager {
727
853
  });
728
854
  return true;
729
855
  }
856
+ if (pane.agentSession && !pane.isAlive) {
857
+ this.emit({ type: 'error', message: `Pane ${cmd.pane_id}: explicit Resume is required before changing saved agent content` });
858
+ return true;
859
+ }
730
860
  pane.outputBuffer = splitDocContent(cmd.content);
861
+ if (pane.launch)
862
+ pane.launch.content = cmd.content;
731
863
  // Publish content update to mirror so the web view stays in sync
732
864
  this.emit({ type: 'pane_output', pane_id: cmd.pane_id, content: cmd.content });
733
865
  return true;
734
866
  }
735
867
  handleClosePane(cmd) {
736
868
  const pane = this.panes.get(cmd.pane_id);
869
+ if (pane?.labels?.pinned) {
870
+ this.emit({ type: 'error', message: `Pane ${cmd.pane_id} is pinned. Unpin it with /label pane ${cmd.pane_id} unpin before closing.` });
871
+ return true;
872
+ }
737
873
  if (!pane) {
738
874
  this.emit({
739
875
  type: 'error',
@@ -775,13 +911,21 @@ export class HeadlessPaneManager {
775
911
  }
776
912
  handleSetPaneTitle(cmd) {
777
913
  if (cmd.pane_id === 0) {
778
- this.hostTitle = cmd.title;
914
+ if (cmd.source === 'inferred')
915
+ this.hostTitle = cmd.title;
916
+ else
917
+ this.hostLabels = replacePaneLabels(this.hostLabels, { ...this.hostLabels, manual_title: cmd.title });
918
+ this.publishPaneLabels();
779
919
  return true;
780
920
  }
781
921
  const pane = this.panes.get(cmd.pane_id);
782
922
  if (pane) {
783
- pane.title = cmd.title;
923
+ if (cmd.source === 'inferred')
924
+ pane.title = cmd.title;
925
+ else
926
+ pane.labels = replacePaneLabels(pane.labels ?? {}, { ...pane.labels, manual_title: cmd.title });
784
927
  }
928
+ this.publishPaneLabels();
785
929
  return true;
786
930
  }
787
931
  handleSetPaneActivity(cmd) {
@@ -802,48 +946,97 @@ export class HeadlessPaneManager {
802
946
  }
803
947
  return true;
804
948
  }
805
- handleGetSessionState() {
949
+ buildSessionState() {
806
950
  const persistenceOptions = resolveMuxPersistenceOptions();
807
951
  const panes = [];
808
952
  for (const pane of this.panes.values()) {
809
- if (!shouldPersistMuxPaneType(pane.paneType, persistenceOptions))
953
+ if (!isMuxPaneRestorable({ id: pane.id, pane_type: pane.paneType,
954
+ agent_session: pane.agentSession }, persistenceOptions))
810
955
  continue;
811
956
  panes.push({
812
957
  id: pane.id,
813
- title: pane.title,
958
+ title: displayPaneTitle(pane.title, pane.labels),
959
+ inferred_title: pane.title,
960
+ labels: { ...pane.labels },
814
961
  pane_type: pane.paneType,
815
962
  command: pane.launch?.command,
816
963
  args: pane.launch?.args,
817
964
  cwd: pane.launch?.cwd,
818
- content: pane.paneType === 'doc'
965
+ ...(pane.agentSession ? { agent_session: structuredClone(pane.agentSession) } : {}),
966
+ ...(pane.restorationStatus ? { restoration_status: pane.restorationStatus } : {}),
967
+ ...(pane.windowId === undefined ? {} : { window_id: pane.windowId }),
968
+ content: pane.restorationStatus || pane.paneType === 'doc'
819
969
  ? pane.launch?.content
820
970
  : pane.outputBuffer.length > 0
821
971
  ? pane.outputBuffer.join('\n')
822
972
  : undefined,
823
973
  });
824
974
  }
825
- const state = sanitizeMuxSessionState({
826
- focused_pane_id: 0,
827
- layout: this.layout,
975
+ return sanitizeMuxSessionState({
976
+ ...structuredClone(this.workspaceMetadata),
977
+ layout: structuredClone(this.layout),
828
978
  panes,
829
979
  }, persistenceOptions);
980
+ }
981
+ handleGetSessionState() {
830
982
  this.emit({
831
983
  type: 'session_state',
832
- state,
984
+ state: this.buildSessionState(),
833
985
  });
834
986
  return true;
835
987
  }
988
+ handleNamedWorkspaceLayout(cmd) {
989
+ let result;
990
+ try {
991
+ result = handleWorkspaceLayout(cmd, cmd.action === 'save' && cmd.state === undefined
992
+ ? this.buildSessionState() : undefined);
993
+ if (result.ok && cmd.action === 'restore' && result.state
994
+ && !this.handleRestoreSessionState({ type: 'restore_session_state', state: result.state })) {
995
+ result.ok = false;
996
+ result.message = 'Workspace restore was not admitted; close live child tasks before restoring.';
997
+ delete result.state;
998
+ }
999
+ }
1000
+ catch (error) {
1001
+ result = { type: 'workspace_layout_result', request_id: cmd.request_id, action: cmd.action,
1002
+ ok: false, names: [], message: error instanceof Error ? error.message : String(error) };
1003
+ }
1004
+ this.emit(result);
1005
+ return true;
1006
+ }
836
1007
  handleRestoreSessionState(cmd) {
837
1008
  const persistenceOptions = resolveMuxPersistenceOptions();
838
- const state = sanitizeMuxSessionState(cmd.state, persistenceOptions);
1009
+ let state;
1010
+ try {
1011
+ validateWorkspaceState(cmd.state);
1012
+ state = sanitizeMuxSessionState(structuredClone(cmd.state), persistenceOptions);
1013
+ }
1014
+ catch {
1015
+ this.emit({ type: 'error', message: 'Workspace restore state is invalid; current panes were preserved.' });
1016
+ this.emit({ type: 'session_restored', restored_panes: 0, skipped_panes: 0 });
1017
+ return false;
1018
+ }
839
1019
  let restored = 0;
840
1020
  let skipped = 0;
841
- const restoredProcessPaneIds = [];
842
1021
  // Guard against malformed state — emit empty restore and bail
843
1022
  if (!state || !Array.isArray(state.panes)) {
844
1023
  this.emit({ type: 'session_restored', restored_panes: 0, skipped_panes: 0 });
845
- return true;
1024
+ return false;
846
1025
  }
1026
+ if ([...this.panes.values()].some(pane => pane.isAlive && (pane.process || pane.pty))) {
1027
+ this.emit({ type: 'error', message: 'Workspace restore refused while a child process is live; close its current task first.' });
1028
+ this.emit({ type: 'session_restored', restored_panes: 0, skipped_panes: state.panes.length });
1029
+ return false;
1030
+ }
1031
+ // Only inactive intent and content panes remain here. Preserve the host
1032
+ // process (pane zero) and replace the old saved workspace as one operation.
1033
+ for (const pane of this.panes.values()) {
1034
+ this.emit({ type: 'pane_closed', pane_id: pane.id, exit_code: pane.exitCode });
1035
+ }
1036
+ this.panes.clear();
1037
+ const { panes: _panes, layout: _layout, ...metadata } = state;
1038
+ this.workspaceMetadata = { ...metadata, schema_version: metadata.schema_version ?? 1,
1039
+ geometry: metadata.geometry ?? { cols: 120, rows: 40 } };
847
1040
  // Restore the saved layout tree so pane arrangement is preserved.
848
1041
  // Individual create calls below use paneId option which skips layout insertion.
849
1042
  if (state.layout) {
@@ -855,81 +1048,68 @@ export class HeadlessPaneManager {
855
1048
  skipped++;
856
1049
  continue;
857
1050
  }
858
- if (paneState.pane_type === 'doc' && paneState.content !== undefined) {
1051
+ if (paneState.pane_type === 'doc' && !paneState.agent_session) {
859
1052
  this.handleCreateDocPane({
860
1053
  type: 'create_doc_pane',
861
- title: paneState.title,
862
- content: paneState.content,
1054
+ title: paneState.inferred_title ?? paneState.title,
1055
+ content: paneState.content ?? '',
863
1056
  }, { paneId: paneState.id });
864
1057
  restored++;
865
1058
  }
866
- else if (paneState.pane_type === 'feed') {
1059
+ else if (paneState.pane_type === 'feed' && !paneState.agent_session) {
867
1060
  const lines = paneState.content ? paneState.content.split('\n') : [];
868
1061
  this.handleCreateFeedPane({
869
1062
  type: 'create_feed_pane',
870
- title: paneState.title,
1063
+ title: paneState.inferred_title ?? paneState.title,
871
1064
  lines,
872
1065
  }, { paneId: paneState.id });
873
1066
  restored++;
874
1067
  }
875
- else if (paneState.command) {
876
- // Validate cwd exists before spawning — stale worktree paths cause immediate failure
877
- let cwd = paneState.cwd;
878
- if (cwd) {
879
- try {
880
- accessSync(cwd);
881
- }
882
- catch {
883
- cwd = process.cwd();
884
- }
885
- }
886
- const restoredOk = this.handleCreatePane({
887
- type: 'create_pane',
888
- command: paneState.command,
889
- args: paneState.args,
890
- cwd,
1068
+ else {
1069
+ // A saved launch descriptor describes prior work. Restore its slot and
1070
+ // scrollback without assuming that the old process or job still exists.
1071
+ const restorationStatus = paneState.restoration_status?.startsWith('session_')
1072
+ ? paneState.restoration_status : paneState.agent_session ? 'not_started' : restoredPaneStatus(paneState);
1073
+ const explanation = restorationStatus === 'missing_directory'
1074
+ ? 'Saved working directory is missing or unavailable.'
1075
+ : restorationStatus === 'missing_command'
1076
+ ? 'Saved command is missing or unavailable.'
1077
+ : restorationStatus.startsWith('session_')
1078
+ ? `Saved agent session is unavailable (${restorationStatus}).`
1079
+ : 'Saved command is not started.';
1080
+ const content = [paneState.content, `[${explanation} Previous job state is unknown; explicitly relaunch to run it.]`]
1081
+ .filter(Boolean).join('\n');
1082
+ const pane = {
1083
+ id: this.reservePaneId(paneState.id),
891
1084
  title: paneState.title,
892
- pane_type: paneState.pane_type,
893
- }, { paneId: paneState.id });
894
- if (restoredOk) {
895
- restoredProcessPaneIds.push(paneState.id);
896
- const restoredPane = this.panes.get(paneState.id);
897
- if (restoredPane && paneState.content) {
898
- // Pre-fill output buffer with saved scrollback so read_pane returns previous output
899
- restoredPane.outputBuffer = paneState.content.split('\n').slice(-MAX_BUFFER_LINES);
900
- // Emit content to mirror so the web UI sees the restored scrollback
901
- this.emit({ type: 'pane_output', pane_id: paneState.id, content: paneState.content });
902
- }
903
- else if (paneState.pane_type !== 'ztc') {
904
- // No saved content — emit a synthetic placeholder so the panel isn't blank
905
- this.emit({ type: 'pane_output', pane_id: paneState.id, content: `[restored: ${paneState.title || paneState.command}]\n$ ` });
906
- }
907
- }
1085
+ paneType: paneState.pane_type,
1086
+ isAlive: false,
1087
+ restorationStatus,
1088
+ agentSession: paneState.agent_session,
1089
+ windowId: paneState.window_id,
1090
+ activityStatus: restorationStatus,
1091
+ activityLabel: 'Prior job state unknown',
1092
+ outputBuffer: content.split('\n').slice(-MAX_BUFFER_LINES),
1093
+ launch: { command: paneState.command, args: paneState.args === undefined ? undefined : [...paneState.args],
1094
+ cwd: paneState.cwd, content: paneState.content },
1095
+ };
1096
+ this.panes.set(pane.id, pane);
1097
+ this.emit({ type: 'pane_created', pane_id: pane.id, title: pane.title, pane_type: pane.paneType });
1098
+ this.emit({ type: 'pane_output', pane_id: pane.id, content });
908
1099
  restored++;
909
1100
  }
910
- else {
911
- skipped++;
912
- }
1101
+ const restoredPane = this.panes.get(paneState.id);
1102
+ if (restoredPane)
1103
+ restoredPane.labels = { ...paneState.labels };
1104
+ const pane = this.panes.get(paneState.id);
1105
+ if (pane)
1106
+ pane.windowId = paneState.window_id;
913
1107
  }
914
1108
  catch {
915
1109
  // Bad pane data — skip it rather than breaking the whole restore
916
1110
  skipped++;
917
1111
  }
918
1112
  }
919
- // Post-restore liveness check: prune process panes that died immediately
920
- // after spawning (e.g., bad command, missing binary). Deferred to allow
921
- // the process 'close' / 'error' events to fire first.
922
- if (restoredProcessPaneIds.length > 0) {
923
- setTimeout(() => {
924
- for (const id of restoredProcessPaneIds) {
925
- const pane = this.panes.get(id);
926
- if (pane && !pane.isAlive) {
927
- this.panes.delete(id);
928
- this.emit({ type: 'pane_closed', pane_id: id });
929
- }
930
- }
931
- }, 1500);
932
- }
933
1113
  this.emit({
934
1114
  type: 'session_restored',
935
1115
  restored_panes: restored,
@@ -937,16 +1117,18 @@ export class HeadlessPaneManager {
937
1117
  });
938
1118
  return true;
939
1119
  }
940
- handleListPanes() {
1120
+ paneInfo() {
941
1121
  const panes = [
942
1122
  // Pane 0 = the host ZTC process (overseer). Not in this.panes because
943
1123
  // it IS the host, not a child — but callers (especially sub-panes via
944
1124
  // relay) need to see it so they can send messages / interact with it.
945
1125
  {
946
1126
  id: 0,
947
- title: this.hostTitle,
1127
+ title: displayPaneTitle(this.hostTitle, this.hostLabels),
1128
+ inferred_title: this.hostTitle,
1129
+ labels: { ...this.hostLabels },
948
1130
  pane_type: 'ztc',
949
- is_focused: true,
1131
+ is_focused: this.workspaceMetadata.focused_pane_id === 0,
950
1132
  is_alive: true,
951
1133
  x: undefined,
952
1134
  y: undefined,
@@ -964,9 +1146,11 @@ export class HeadlessPaneManager {
964
1146
  for (const pane of this.panes.values()) {
965
1147
  panes.push({
966
1148
  id: pane.id,
967
- title: pane.title,
1149
+ title: displayPaneTitle(pane.title, pane.labels),
1150
+ inferred_title: pane.title,
1151
+ labels: { ...pane.labels },
968
1152
  pane_type: pane.paneType,
969
- is_focused: false,
1153
+ is_focused: this.workspaceMetadata.focused_pane_id === pane.id,
970
1154
  is_alive: pane.isAlive,
971
1155
  x: undefined,
972
1156
  y: undefined,
@@ -979,14 +1163,18 @@ export class HeadlessPaneManager {
979
1163
  activity_status: pane.activityStatus,
980
1164
  activity_spinner: pane.activitySpinner,
981
1165
  activity_label: pane.activityLabel,
1166
+ window_id: pane.windowId,
982
1167
  });
983
1168
  }
984
- this.emit({
985
- type: 'pane_list',
986
- panes,
987
- });
1169
+ return panes;
1170
+ }
1171
+ handleListPanes() {
1172
+ this.emit({ type: 'pane_list', panes: this.paneInfo() });
988
1173
  return true;
989
1174
  }
1175
+ publishPaneLabels() {
1176
+ this.emit({ type: 'pane_state', cols: 120, rows: 40, panes: this.paneInfo() });
1177
+ }
990
1178
  finalizePaneClose(pane, exitCode) {
991
1179
  if (pane.replaced)
992
1180
  return;
@@ -994,6 +1182,7 @@ export class HeadlessPaneManager {
994
1182
  pane.exitCode = exitCode;
995
1183
  if (this.panes.get(pane.id) === pane) {
996
1184
  this.panes.delete(pane.id);
1185
+ this.removePaneFromLayout(pane.id);
997
1186
  }
998
1187
  this.closedPanes.set(pane.id, pane);
999
1188
  // Cap memory: keep only the most recent closed-pane tails.