@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,398 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { mkdir, readFile, open, lstat, rm, rename, chmod, realpath } from 'node:fs/promises';
3
+ import { homedir } from 'node:os';
4
+ import { dirname, join } from 'node:path';
5
+ import { getSessionPathForCwd } from '../../session.js';
6
+ import { writeFileAtomic } from '../../utils/atomic_write.js';
7
+ import { withPathLock } from '../../utils/path_lock.js';
8
+ import { buildUserSubprocessEnv } from '../../utils/subprocess_env.js';
9
+ import { startCommandJob, readCommandJob, stopCommandJob } from './command_jobs.js';
10
+ const namePattern = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
11
+ const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
12
+ const states = new Set(['suspended', 'running', 'completed', 'failed', 'unknown']);
13
+ function alive(pid) {
14
+ if (!Number.isSafeInteger(pid) || pid <= 0)
15
+ return false;
16
+ try {
17
+ process.kill(pid, 0);
18
+ return true;
19
+ }
20
+ catch (error) {
21
+ return error.code !== 'ESRCH';
22
+ }
23
+ }
24
+ function validateEnvironment(env) {
25
+ if (!env || Array.isArray(env) || typeof env !== 'object' || Object.keys(env).length > 64
26
+ || Buffer.byteLength(JSON.stringify(env)) > 65536
27
+ || Object.entries(env).some(([key, value]) => !/^[A-Za-z_][A-Za-z0-9_]{0,127}$/.test(key)
28
+ || /^(ZTC_|ZERG_)/.test(key) || typeof value !== 'string' || value.includes('\0')))
29
+ throw new Error('Environment must contain at most 64 valid application variables (64 KiB total), without ZTC_/ZERG_ control variables.');
30
+ }
31
+ function stateOf(receipt) {
32
+ if (receipt.status === 'running')
33
+ return 'running';
34
+ if (receipt.status === 'completed' && receipt.exit_code === 0)
35
+ return 'completed';
36
+ if (receipt.status === 'interrupted')
37
+ return 'unknown';
38
+ return 'failed';
39
+ }
40
+ /** Durable definitions and command receipts are authoritative; panes are projections. */
41
+ export class CommandPaneManager {
42
+ sessionId;
43
+ shellOptions;
44
+ file;
45
+ sessionDirectory;
46
+ listeners = new Set();
47
+ localJobs = new Set();
48
+ admittedJobs = new Map();
49
+ timer;
50
+ refreshTask;
51
+ closed = false;
52
+ lastPublished;
53
+ constructor(sessionId, sessionCwd, shellOptions) {
54
+ this.sessionId = sessionId;
55
+ this.shellOptions = shellOptions;
56
+ this.file = join(process.env.ZTC_CONFIG_DIR || join(homedir(), '.ztc'), 'command-panes', createHash('sha256').update(sessionId).digest('hex') + '.json');
57
+ this.sessionDirectory = dirname(getSessionPathForCwd(sessionCwd, sessionId));
58
+ }
59
+ async read() {
60
+ let raw;
61
+ try {
62
+ const info = await lstat(this.file);
63
+ if (!info.isFile() || info.isSymbolicLink() || info.size > 1024 * 1024)
64
+ throw new Error('Invalid command-pane manifest file.');
65
+ raw = await readFile(this.file, 'utf8');
66
+ }
67
+ catch (error) {
68
+ if (error.code === 'ENOENT')
69
+ return { version: 1, sessionId: this.sessionId, commands: [] };
70
+ throw error;
71
+ }
72
+ const data = JSON.parse(raw);
73
+ if (data.version !== 1 || data.sessionId !== this.sessionId || !Array.isArray(data.commands) || data.commands.length > 32)
74
+ throw new Error('Invalid command-pane manifest.');
75
+ const names = new Set();
76
+ const ids = new Set();
77
+ for (const c of data.commands) {
78
+ if (!namePattern.test(c.name) || !uuidPattern.test(c.id) || names.has(c.name) || ids.has(c.id)
79
+ || typeof c.command !== 'string' || !c.command.trim() || c.command.length > 16384 || c.command.includes('\0')
80
+ || typeof c.cwd !== 'string' || !states.has(c.state)
81
+ || (c.state === 'running' && !c.receipt)
82
+ || (c.receipt && !uuidPattern.test(c.receipt.job_id))
83
+ || (c.admission && (!uuidPattern.test(c.admission.id) || !Number.isSafeInteger(c.admission.ownerPid) || c.admission.ownerPid <= 0)))
84
+ throw new Error('Invalid pinned command.');
85
+ validateEnvironment(c.env);
86
+ names.add(c.name);
87
+ ids.add(c.id);
88
+ }
89
+ return data;
90
+ }
91
+ async mutate(operation) {
92
+ if (this.closed)
93
+ throw new Error('Command-pane manager has stopped.');
94
+ return withPathLock(this.file, async () => {
95
+ await mkdir(dirname(this.file), { recursive: true, mode: 0o700 });
96
+ const lockPath = this.file + '.lock';
97
+ const lock = await open(lockPath, 'wx', 0o600).catch(error => {
98
+ if (error.code === 'EEXIST')
99
+ throw new Error('A command-pane operation owns this session. Inspect its lock before recovery.');
100
+ throw error;
101
+ });
102
+ const identity = await lock.stat();
103
+ try {
104
+ await lock.writeFile(JSON.stringify({ pid: process.pid, sessionId: this.sessionId }));
105
+ const data = await this.read();
106
+ const before = JSON.stringify(data);
107
+ const result = await operation(data);
108
+ const after = JSON.stringify(data);
109
+ if (after !== before) {
110
+ await writeFileAtomic(this.file, after);
111
+ await chmod(this.file, 0o600);
112
+ }
113
+ return result;
114
+ }
115
+ finally {
116
+ await lock.close();
117
+ const current = await lstat(lockPath).catch(error => { if (error.code !== 'ENOENT')
118
+ throw error; return null; });
119
+ if (current?.ino === identity.ino && current.dev === identity.dev)
120
+ await rm(lockPath);
121
+ }
122
+ });
123
+ }
124
+ find(data, name) {
125
+ const command = data.commands.find(c => c.name === name);
126
+ if (!command)
127
+ throw new Error('Pinned command not found in this session.');
128
+ return command;
129
+ }
130
+ async pin(options) {
131
+ if (!namePattern.test(options.name))
132
+ throw new Error('Command name must use 1–64 letters, numbers, underscores or hyphens.');
133
+ const command = options.command.trim();
134
+ if (!command || command.length > 16384 || command.includes('\0'))
135
+ throw new Error('Command must contain 1–16384 characters without NUL.');
136
+ const env = options.env ?? {};
137
+ validateEnvironment(env);
138
+ const cwd = await realpath(options.cwd);
139
+ if (!(await lstat(cwd)).isDirectory())
140
+ throw new Error('Command cwd must be a directory.');
141
+ await this.mutate(async (data) => {
142
+ if (data.commands.some(c => c.name === options.name))
143
+ throw new Error('That command name is already pinned.');
144
+ if (data.commands.length >= 32)
145
+ throw new Error('Pinned command limit (32) reached. Unpin an inactive command first.');
146
+ data.commands.push({ id: randomUUID(), name: options.name, command, cwd, env: { ...env }, state: 'suspended' });
147
+ });
148
+ if (!options.suspended)
149
+ await this.run(options.name, 'none');
150
+ this.watch();
151
+ await this.publish();
152
+ return (await this.list()).find(c => c.name === options.name);
153
+ }
154
+ /** expectedAttempt binds an action to the snapshot it was offered on. */
155
+ async run(name, expectedAttempt) {
156
+ await this.mutate(async (data) => {
157
+ const c = this.find(data, name);
158
+ if ((c.admission?.id ?? c.receipt?.job_id ?? 'none') !== expectedAttempt)
159
+ throw new Error('Command attempt changed. Refresh before rerunning.');
160
+ if (c.admission && !c.admission.error && alive(c.admission.ownerPid))
161
+ throw new Error('Command admission is unresolved in a live owner. Inspect it before rerunning.');
162
+ if (c.state === 'running' && (this.localJobs.has(c.receipt.job_id) || alive(c.receipt?.owner_pid)))
163
+ throw new Error('Command is still running. Stop it before rerunning.');
164
+ // Rebind cwd before launch; a missing directory never falls back to another workspace.
165
+ if (await realpath(c.cwd) !== c.cwd || !(await lstat(c.cwd)).isDirectory())
166
+ throw new Error('Command directory changed. Inspect it before running.');
167
+ const shell = this.shellOptions();
168
+ // Persist the action identity before any process can run. Lost completion
169
+ // acknowledgement must not restore the old action's admission authority.
170
+ c.admission = { id: randomUUID(), ownerPid: process.pid };
171
+ c.state = 'unknown';
172
+ delete c.receipt;
173
+ delete c.evidence;
174
+ await writeFileAtomic(this.file, JSON.stringify(data));
175
+ await chmod(this.file, 0o600);
176
+ let receipt;
177
+ try {
178
+ receipt = await startCommandJob({ sessionId: this.sessionId, command: c.command, cwd: c.cwd, maxJobs: 8,
179
+ shell: { ...shell, env: { ...buildUserSubprocessEnv(shell.env), ...c.env } } });
180
+ }
181
+ catch (error) {
182
+ c.admission.error = error instanceof Error ? error.message : String(error);
183
+ c.state = 'failed';
184
+ await writeFileAtomic(this.file, JSON.stringify(data));
185
+ await chmod(this.file, 0o600);
186
+ throw error;
187
+ }
188
+ this.admittedJobs.set(c.admission.id, receipt.job_id);
189
+ c.receipt = receipt;
190
+ c.state = stateOf(receipt);
191
+ delete c.admission;
192
+ if (receipt.status === 'running')
193
+ this.localJobs.add(receipt.job_id);
194
+ });
195
+ this.watch();
196
+ await this.refresh();
197
+ return (await this.list()).find(c => c.name === name);
198
+ }
199
+ async stop(name, expectedAttempt) {
200
+ await this.mutate(async (data) => {
201
+ const c = this.find(data, name);
202
+ if (c.receipt?.job_id !== expectedAttempt)
203
+ throw new Error('Command attempt changed. Refresh before stopping.');
204
+ if (!this.localJobs.has(expectedAttempt))
205
+ throw new Error('This process does not own that command.');
206
+ c.receipt = await stopCommandJob(this.sessionId, expectedAttempt);
207
+ c.state = stateOf(c.receipt);
208
+ this.localJobs.delete(expectedAttempt);
209
+ });
210
+ await this.publish();
211
+ }
212
+ async unpin(name) {
213
+ await this.mutate(async (data) => {
214
+ const c = this.find(data, name);
215
+ if (c.state === 'running' && (this.localJobs.has(c.receipt.job_id) || alive(c.receipt?.owner_pid)))
216
+ throw new Error('Stop the running command before unpinning.');
217
+ if (c.receipt)
218
+ this.localJobs.delete(c.receipt.job_id);
219
+ data.commands = data.commands.filter(entry => entry.id !== c.id);
220
+ });
221
+ await this.publish();
222
+ }
223
+ async output(c) {
224
+ if (!c.receipt || !this.localJobs.has(c.receipt.job_id) && c.state === 'running')
225
+ return '';
226
+ try {
227
+ const receipt = await readCommandJob(this.sessionId, c.receipt.job_id);
228
+ const file = await open(receipt.log_path, 'r');
229
+ try {
230
+ const size = (await file.stat()).size;
231
+ const length = Math.min(size, 32768);
232
+ const buffer = Buffer.alloc(length);
233
+ const { bytesRead } = await file.read(buffer, 0, length, size - length);
234
+ let start = 0;
235
+ while (start < bytesRead && (buffer[start] & 0xc0) === 0x80)
236
+ start++;
237
+ return (size > length ? '[earlier output omitted from pane; attach evidence for retained log]\n' : '') + buffer.subarray(start, bytesRead).toString('utf8');
238
+ }
239
+ finally {
240
+ await file.close();
241
+ }
242
+ }
243
+ catch (error) {
244
+ return `[Output unavailable: ${error instanceof Error ? error.message : String(error)}]`;
245
+ }
246
+ }
247
+ async list() {
248
+ const data = await this.read();
249
+ return Promise.all(data.commands.map(async (c) => ({ id: c.id, name: c.name, command: c.command, cwd: c.cwd,
250
+ environmentKeys: Object.keys(c.env), state: c.state === 'running' && !this.localJobs.has(c.receipt.job_id) ? 'unknown' : c.state,
251
+ attempt: c.admission?.id ?? c.receipt?.job_id ?? 'none', exitCode: c.receipt?.exit_code,
252
+ error: c.admission ? c.admission.error ?? 'Command admission has no durable process receipt. Inspect the owner before retrying.' : c.receipt?.error,
253
+ output: await this.output(c), evidence: c.evidence })));
254
+ }
255
+ async attachEvidence(name, expectedAttempt) {
256
+ const evidence = await this.mutate(async (data) => {
257
+ const c = this.find(data, name);
258
+ if (!c.receipt || c.receipt.job_id !== expectedAttempt)
259
+ throw new Error('Command attempt changed or has not started. Refresh before attaching evidence.');
260
+ if (c.state === 'running')
261
+ throw new Error('Wait for a terminal command result before attaching evidence.');
262
+ if (c.evidence)
263
+ return c.evidence;
264
+ const receipt = await readCommandJob(this.sessionId, expectedAttempt);
265
+ const log = await readFile(receipt.log_path);
266
+ if (log.length > 16 * 1024 * 1024)
267
+ throw new Error('Retained command log exceeds its evidence limit.');
268
+ const root = join(this.sessionDirectory, 'command-evidence');
269
+ await mkdir(root, { recursive: true, mode: 0o700 });
270
+ const target = join(root, expectedAttempt);
271
+ const staging = target + '.tmp-' + randomUUID();
272
+ await mkdir(staging, { mode: 0o700 });
273
+ try {
274
+ const outputSha256 = createHash('sha256').update(log).digest('hex');
275
+ const payload = JSON.stringify({ schemaVersion: 1, sessionId: this.sessionId, commandPaneId: c.id, name: c.name,
276
+ command: c.command, cwd: c.cwd, environmentKeys: Object.keys(c.env), receipt, outputSha256, outputBytes: log.length }, null, 2);
277
+ const file = await open(join(staging, 'receipt.json'), 'wx', 0o600);
278
+ try {
279
+ await file.writeFile(payload);
280
+ }
281
+ finally {
282
+ await file.close();
283
+ }
284
+ const out = await open(join(staging, 'output.log'), 'wx', 0o600);
285
+ try {
286
+ await out.writeFile(log);
287
+ }
288
+ finally {
289
+ await out.close();
290
+ }
291
+ await rename(staging, target);
292
+ c.evidence = { path: join(target, 'receipt.json'), sha256: createHash('sha256').update(payload).digest('hex') };
293
+ return c.evidence;
294
+ }
295
+ finally {
296
+ await rm(staging, { recursive: true, force: true });
297
+ }
298
+ });
299
+ await this.publish();
300
+ return evidence;
301
+ }
302
+ subscribe(listener) {
303
+ this.listeners.add(listener);
304
+ this.watch();
305
+ void this.list().then(views => { if (this.listeners.has(listener))
306
+ listener(views); }).catch(() => { });
307
+ return () => { this.listeners.delete(listener); };
308
+ }
309
+ watch() {
310
+ if (this.closed || this.timer)
311
+ return;
312
+ this.timer = setInterval(() => { if (!this.refreshTask)
313
+ void this.refresh().catch(() => { }); }, 1000);
314
+ this.timer.unref();
315
+ }
316
+ refresh() {
317
+ if (this.closed)
318
+ return Promise.resolve();
319
+ if (this.refreshTask)
320
+ return this.refreshTask;
321
+ this.refreshTask = (async () => {
322
+ const current = await this.read();
323
+ if (current.commands.some(c => c.state === 'running' || c.admission && this.admittedJobs.has(c.admission.id)))
324
+ await this.mutate(async (data) => {
325
+ for (const c of data.commands) {
326
+ if (c.admission) {
327
+ const job = this.admittedJobs.get(c.admission.id);
328
+ if (job) {
329
+ c.receipt = await readCommandJob(this.sessionId, job);
330
+ delete c.admission;
331
+ c.state = stateOf(c.receipt);
332
+ }
333
+ }
334
+ if (c.state !== 'running' || !c.receipt) {
335
+ if (c.receipt)
336
+ this.localJobs.delete(c.receipt.job_id);
337
+ continue;
338
+ }
339
+ if (!this.localJobs.has(c.receipt.job_id) && alive(c.receipt.owner_pid))
340
+ continue;
341
+ c.receipt = await readCommandJob(this.sessionId, c.receipt.job_id);
342
+ c.state = stateOf(c.receipt);
343
+ if (c.state !== 'running')
344
+ this.localJobs.delete(c.receipt.job_id);
345
+ }
346
+ });
347
+ const reserved = new Set((await this.read()).commands.flatMap(c => c.admission ? [c.admission.id] : []));
348
+ for (const id of this.admittedJobs.keys())
349
+ if (!reserved.has(id))
350
+ this.admittedJobs.delete(id);
351
+ const remaining = await this.read();
352
+ if (!remaining.commands.some(c => c.state === 'running' || c.admission && this.admittedJobs.has(c.admission.id)) && this.timer) {
353
+ clearInterval(this.timer);
354
+ this.timer = undefined;
355
+ }
356
+ await this.publish();
357
+ })().finally(() => { this.refreshTask = undefined; });
358
+ return this.refreshTask;
359
+ }
360
+ async publish() {
361
+ if (this.closed)
362
+ return;
363
+ const views = await this.list();
364
+ const signature = JSON.stringify(views);
365
+ if (signature === this.lastPublished)
366
+ return;
367
+ this.lastPublished = signature;
368
+ for (const listener of this.listeners) {
369
+ try {
370
+ listener(views);
371
+ }
372
+ catch { /* Views cannot change execution outcomes. */ }
373
+ }
374
+ }
375
+ async dispose() {
376
+ if (this.closed)
377
+ return;
378
+ if (this.timer)
379
+ clearInterval(this.timer);
380
+ this.timer = undefined;
381
+ await this.refresh();
382
+ for (const job of this.localJobs)
383
+ await stopCommandJob(this.sessionId, job);
384
+ await this.refresh();
385
+ this.closed = true;
386
+ this.listeners.clear();
387
+ }
388
+ }
389
+ export function commandPaneText(command) {
390
+ return `${command.name} · ${command.state}${command.exitCode === undefined ? '' : ' · exit ' + command.exitCode}\n`
391
+ + `Directory: ${command.cwd}\nCommand: ${command.command}\nEnvironment: ${command.environmentKeys.join(', ') || 'inherited application environment'}\n`
392
+ + `Attempt: ${command.attempt}\n`
393
+ + (command.state === 'running' ? `/job stop ${command.name} --after ${command.attempt}\n`
394
+ : `/job ${command.attempt === 'none' ? 'start' : 'rerun'} ${command.name} --after ${command.attempt}\n`)
395
+ + (command.attempt !== 'none' && command.state !== 'running' ? `/job evidence ${command.name} --after ${command.attempt}\n` : '')
396
+ + (command.evidence ? `Evidence: ${command.evidence.path}\nSHA-256: ${command.evidence.sha256}\n` : '')
397
+ + (command.error ? `Error: ${command.error}\n` : '') + '\n' + command.output;
398
+ }
@@ -0,0 +1,19 @@
1
+ import type { AgentEvent, Message } from '../../types.js';
2
+ import { type ManagedCommandObservation } from './command_jobs.js';
3
+ export type ManagedCommandWaitObservation = ManagedCommandObservation & {
4
+ toolCallId: string;
5
+ readCursor?: number;
6
+ };
7
+ export interface ManagedCommandWaitOptions {
8
+ signal?: AbortSignal;
9
+ takeSteering?: () => Message[];
10
+ emit?: (event: AgentEvent) => void;
11
+ deadlineAt?: number;
12
+ }
13
+ export interface ManagedCommandWaitResult {
14
+ observations: ManagedCommandWaitObservation[];
15
+ steering: Message[];
16
+ waited: boolean;
17
+ }
18
+ export declare function awaitManagedCommandProgress(observations: readonly ManagedCommandWaitObservation[], options?: ManagedCommandWaitOptions): Promise<ManagedCommandWaitResult>;
19
+ export declare function formatManagedCommandObservations(observations: readonly ManagedCommandWaitObservation[]): string;
@@ -0,0 +1,167 @@
1
+ import { readCommandJob, waitForCommandProgress } from './command_jobs.js';
2
+ export async function awaitManagedCommandProgress(observations, options = {}) {
3
+ if (options.deadlineAt !== undefined && (!Number.isFinite(options.deadlineAt) || options.deadlineAt < 0)) {
4
+ throw new Error('deadlineAt must be a finite non-negative timestamp');
5
+ }
6
+ let current = observations.map(item => ({ ...item }));
7
+ // A launch or zero-wait inspection is not a request to suspend independent work.
8
+ if (!current.length || current.length > 256 || current.some(item => item.kind !== 'read'
9
+ || !Number.isSafeInteger(item.requestedWaitMs) || item.requestedWaitMs <= 0 || item.requestedWaitMs > 60000
10
+ || item.result.status !== 'running' || item.result.output !== '' || item.result.has_more
11
+ || !Number.isSafeInteger(item.result.cursor) || item.result.cursor < 0
12
+ || !item.toolCallId || item.toolCallId.length > 256)) {
13
+ return { observations: current, steering: [], waited: false };
14
+ }
15
+ // The scheduler may admit up to 256 calls, but one owned job/cursor needs
16
+ // only one waiter. The managed broker admits at most 32 active jobs.
17
+ const unique = new Map();
18
+ for (const item of current) {
19
+ const key = JSON.stringify([item.sessionId, item.result.job_id, item.result.cursor]);
20
+ if (!unique.has(key))
21
+ unique.set(key, item);
22
+ }
23
+ if (unique.size > 32)
24
+ return { observations: current, steering: [], waited: false };
25
+ current = [...unique.values()];
26
+ const refresh = async () => {
27
+ for (const item of current) {
28
+ item.readCursor = item.result.cursor;
29
+ item.result = await readCommandJob(item.sessionId, item.result.job_id, item.readCursor);
30
+ }
31
+ };
32
+ const startedAt = Date.now();
33
+ let reason = 'error';
34
+ for (const item of current)
35
+ options.emit?.({ type: 'command_wait', waiting: {
36
+ kind: 'managed_command', toolCallId: item.toolCallId, jobId: item.result.job_id,
37
+ cursor: item.result.cursor, startedAt, ...(options.deadlineAt === undefined ? {} : { deadlineAt: options.deadlineAt }),
38
+ } });
39
+ try {
40
+ while (true) {
41
+ if (options.signal?.aborted)
42
+ throw new Error('Command waiting cancelled; the owned job may still be running.');
43
+ const steering = options.takeSteering?.() ?? [];
44
+ if (steering.length) {
45
+ reason = 'steering';
46
+ await refresh();
47
+ return { observations: current, steering, waited: true };
48
+ }
49
+ const remaining = options.deadlineAt === undefined ? 60000 : Math.max(0, options.deadlineAt - Date.now());
50
+ if (remaining === 0) {
51
+ await refresh();
52
+ reason = 'deadline';
53
+ return { observations: current, steering: [], waited: true };
54
+ }
55
+ // Job notifications wake immediately; the bounded clock wake also admits Enter steering.
56
+ const maxWaitMs = Math.min(Math.ceil(remaining), options.takeSteering ? 1000 : 60000);
57
+ const reads = new AbortController();
58
+ const signal = options.signal ? AbortSignal.any([options.signal, reads.signal]) : reads.signal;
59
+ const pending = current.map(item => waitForCommandProgress(item.sessionId, item.result.job_id, { cursor: item.result.cursor, maxWaitMs, signal }));
60
+ let change;
61
+ try {
62
+ change = await Promise.race(pending);
63
+ }
64
+ finally {
65
+ reads.abort();
66
+ await Promise.allSettled(pending);
67
+ }
68
+ if (change.reason !== 'deadline') {
69
+ // Dispose the other read waiters, then preserve each job's exact current observation.
70
+ // Aborting a read never aborts its independently owned process.
71
+ await refresh();
72
+ reason = current.some(item => item.result.status !== 'running') ? 'terminal' : 'output';
73
+ return { observations: current, steering: [], waited: true };
74
+ }
75
+ }
76
+ }
77
+ catch (error) {
78
+ reason = options.signal?.aborted ? 'cancelled' : 'error';
79
+ throw error;
80
+ }
81
+ finally {
82
+ for (const item of current)
83
+ options.emit?.({ type: 'command_wait_end', toolCallId: item.toolCallId, reason });
84
+ }
85
+ }
86
+ export function formatManagedCommandObservations(observations) {
87
+ const prefix = '[Host command observation] ';
88
+ const budget = 64 * 1024;
89
+ if (observations.length > 32)
90
+ throw new Error('at most 32 managed command observations can be formatted');
91
+ const rows = observations.map(item => ({
92
+ toolCallId: item.toolCallId, job_id: item.result.job_id, status: item.result.status,
93
+ cursor: item.result.cursor, has_more: item.result.has_more, output: item.result.output,
94
+ ...(item.result.ended_at === undefined ? {} : { ended_at: item.result.ended_at }),
95
+ ...(item.result.exit_code === undefined ? {} : { exit_code: item.result.exit_code }),
96
+ ...(item.result.error === undefined ? {} : { error: item.result.error }),
97
+ ...(item.result.output_truncated === undefined ? {} : { output_truncated: item.result.output_truncated }),
98
+ ...(item.result.dropped_bytes === undefined ? {} : { dropped_bytes: item.result.dropped_bytes }),
99
+ }));
100
+ const serialize = () => prefix + JSON.stringify(rows);
101
+ const full = serialize();
102
+ if (Buffer.byteLength(full) <= budget)
103
+ return full;
104
+ const fields = [];
105
+ for (const [index, item] of observations.entries()) {
106
+ const row = rows[index];
107
+ for (const field of ['output', 'error']) {
108
+ const value = item.result[field];
109
+ if (!value)
110
+ continue;
111
+ fields.push({ index, field, value });
112
+ row[field] = '';
113
+ row[field === 'output' ? 'output_omitted_bytes' : 'error_omitted_bytes'] = Buffer.byteLength(value);
114
+ }
115
+ if ((row.output_omitted_bytes ?? 0) > 0 || (row.error_omitted_bytes ?? 0) > 0) {
116
+ row.retrieval = { tool: 'read_command', arguments: {
117
+ job_id: item.result.job_id,
118
+ cursor: item.readCursor ?? Math.max(0, item.result.cursor - Buffer.byteLength(item.result.output)),
119
+ wait_ms: 0,
120
+ } };
121
+ }
122
+ }
123
+ const metadataBytes = Buffer.byteLength(serialize());
124
+ if (metadataBytes > budget)
125
+ throw new Error('managed command observation metadata exceeds the context budget');
126
+ const allowance = Math.floor((budget - metadataBytes) / Math.max(1, fields.length));
127
+ for (const { index, field, value } of fields) {
128
+ const row = rows[index];
129
+ const initialBytes = Buffer.byteLength(JSON.stringify(row));
130
+ const characters = Array.from(value);
131
+ const sourceBytes = Buffer.byteLength(value);
132
+ const project = (count) => {
133
+ const visible = characters.slice(0, count).join('');
134
+ const candidate = { ...row, [field]: visible };
135
+ const omittedField = field === 'output' ? 'output_omitted_bytes' : 'error_omitted_bytes';
136
+ const omitted = sourceBytes - Buffer.byteLength(visible);
137
+ if (omitted > 0)
138
+ candidate[omittedField] = omitted;
139
+ else
140
+ delete candidate[omittedField];
141
+ if (!(candidate.output_omitted_bytes ?? 0) && !(candidate.error_omitted_bytes ?? 0))
142
+ delete candidate.retrieval;
143
+ return candidate;
144
+ };
145
+ const fits = (candidate) => Buffer.byteLength(JSON.stringify(candidate)) - initialBytes <= allowance;
146
+ const complete = project(characters.length);
147
+ if (fits(complete)) {
148
+ rows[index] = complete;
149
+ continue;
150
+ }
151
+ // Search code-point boundaries using encoded JSON bytes, including escaping.
152
+ let low = 0;
153
+ let high = characters.length - 1;
154
+ while (low < high) {
155
+ const middle = Math.ceil((low + high) / 2);
156
+ if (fits(project(middle)))
157
+ low = middle;
158
+ else
159
+ high = middle - 1;
160
+ }
161
+ rows[index] = project(low);
162
+ }
163
+ const bounded = serialize();
164
+ if (Buffer.byteLength(bounded) > budget)
165
+ throw new Error('managed command observation metadata exceeds the context budget');
166
+ return bounded;
167
+ }
@@ -0,0 +1,30 @@
1
+ import type { ToolContext } from '../tools/types.js';
2
+ export type CPUVariant = 'for_loop' | 'array_reduce';
3
+ export interface CPUWorkload {
4
+ values: number[];
5
+ config: {
6
+ schema_version: 1;
7
+ variant: CPUVariant;
8
+ iterations: number;
9
+ warmup: number;
10
+ samples: number;
11
+ };
12
+ }
13
+ export declare const CPU_HOST_INSTANCE_ID: string;
14
+ export declare const cpuHash: (text: string) => string;
15
+ /** Independent exact arithmetic, outside the measured process and timing interval. */
16
+ export declare function integerSumOracle(values: readonly number[]): number;
17
+ export declare const CPU_PROGRAM_SHA256: Readonly<{
18
+ for_loop: string;
19
+ array_reduce: string;
20
+ }>;
21
+ export declare const CPU_CHECKER_SHA256: string;
22
+ export declare const CPU_RECIPE_SHA256: string;
23
+ export declare function parseCPUWorkload(input: string, config: string): CPUWorkload | null;
24
+ export interface CPURun {
25
+ outcome: 'passed' | 'failed' | 'timed_out' | 'cancelled' | 'unknown';
26
+ output: string;
27
+ executionPolicyId: string | null;
28
+ }
29
+ /** Launch only the fixed host script; project bytes enter through stdin as data, never code. */
30
+ export declare function runCPUWorkload(workload: CPUWorkload, context: Pick<ToolContext, 'cwd' | 'signal' | 'commandPolicy'>): Promise<CPURun>;