@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
@@ -2,6 +2,9 @@ import type { ZTCAuthMode } from './config/types.js';
2
2
  export declare const DEFAULT_ROUTER_ORIGIN = "https://zergrouter.com";
3
3
  /** Local, actionable routing failures whose messages contain no remote payload. */
4
4
  export declare class RouterConfigurationError extends Error {
5
+ readonly kind: 'configuration' | 'expired' | 'authentication_required';
6
+ constructor(message: string, kind?: 'configuration' | 'expired' | 'authentication_required');
7
+ get needsSignIn(): boolean;
5
8
  }
6
9
  type RouterAuthOutput = (message: string, stream: 'stdout' | 'stderr') => void;
7
10
  export interface RouterCredentials {
@@ -16,6 +19,34 @@ export interface RouterCredentials {
16
19
  };
17
20
  }
18
21
  export declare function loadRouterCredentials(): Promise<RouterCredentials | null>;
22
+ export interface RouterAccountReadiness {
23
+ version: 1;
24
+ scope: {
25
+ kind: 'personal';
26
+ accountId: string;
27
+ };
28
+ funding: {
29
+ state: 'ready' | 'needs_payment' | 'payment_pending' | 'payment_failed' | 'cap_reached' | 'unavailable';
30
+ mode: 'live' | 'test' | 'unknown';
31
+ source: 'paid' | 'trial' | null;
32
+ remainingUsd: string | null;
33
+ capUsd: string | null;
34
+ trialTokensRemaining: number | null;
35
+ };
36
+ model: {
37
+ provider: 'modal';
38
+ id: 'deepseek-v4.1-flash';
39
+ available: boolean;
40
+ };
41
+ ready: boolean;
42
+ nextAction: 'start' | 'billing' | 'wait_for_payment' | 'retry' | 'select_model';
43
+ links: {
44
+ billing: string;
45
+ signIn: string;
46
+ };
47
+ }
48
+ export declare function readRouterAccountReadiness(credentials: RouterCredentials): Promise<RouterAccountReadiness>;
49
+ export declare function formatRouterAccountReadiness(account: RouterAccountReadiness): string;
19
50
  /** Shared Router authentication for the shell and in-session slash commands. */
20
51
  export declare function runRouterAuthCommand(args: readonly string[], output?: RouterAuthOutput): Promise<void>;
21
52
  export {};
@@ -1,14 +1,22 @@
1
1
  import { createHash, randomBytes, randomUUID } from 'node:crypto';
2
2
  import { chmod, mkdir, readFile, rename, unlink, writeFile } from 'node:fs/promises';
3
3
  import { hostname } from 'node:os';
4
- import { join } from 'node:path';
4
+ import { dirname, join } from 'node:path';
5
5
  import { spawn } from 'node:child_process';
6
6
  import { setTimeout as delay } from 'node:timers/promises';
7
7
  import { getVersion } from './utils/version.js';
8
- import { profileConfigDir } from './config/profiles.js';
8
+ import { activeProfile, profileConfigDir } from './config/profiles.js';
9
9
  export const DEFAULT_ROUTER_ORIGIN = 'https://zergrouter.com';
10
10
  /** Local, actionable routing failures whose messages contain no remote payload. */
11
11
  export class RouterConfigurationError extends Error {
12
+ kind;
13
+ constructor(message, kind = 'configuration') {
14
+ super(message);
15
+ this.kind = kind;
16
+ }
17
+ get needsSignIn() {
18
+ return this.kind === 'expired' || this.kind === 'authentication_required';
19
+ }
12
20
  }
13
21
  const terminalOutput = (message, stream) => { process[stream].write(message); };
14
22
  function credentialDirectory() {
@@ -81,12 +89,13 @@ export async function loadRouterCredentials() {
81
89
  }
82
90
  }
83
91
  async function saveCredentials(credentials) {
84
- await mkdir(credentialDirectory(), { recursive: true, mode: 0o700 });
85
- const temporary = `${credentialPath()}.${randomUUID()}.tmp`;
92
+ const path = credentialPath();
93
+ await mkdir(dirname(path), { recursive: true, mode: 0o700 });
94
+ const temporary = `${path}.${randomUUID()}.tmp`;
86
95
  try {
87
96
  await writeFile(temporary, JSON.stringify(credentials) + '\n', { mode: 0o600, flag: 'wx' });
88
97
  await chmod(temporary, 0o600);
89
- await rename(temporary, credentialPath());
98
+ await rename(temporary, path);
90
99
  }
91
100
  finally {
92
101
  await unlink(temporary).catch(error => {
@@ -119,7 +128,34 @@ async function request(origin, path, body, token, method) {
119
128
  signal: AbortSignal.timeout(15_000),
120
129
  redirect: 'error',
121
130
  });
122
- const value = await response.json().catch(() => null);
131
+ let value = null;
132
+ const reader = response.body?.getReader();
133
+ if (reader) {
134
+ const chunks = [];
135
+ let size = 0;
136
+ try {
137
+ for (;;) {
138
+ const { done, value: chunk } = await reader.read();
139
+ if (done)
140
+ break;
141
+ size += chunk.byteLength;
142
+ if (size > 32_768) {
143
+ await reader.cancel();
144
+ throw new Error('Router returned an invalid oversized response.');
145
+ }
146
+ chunks.push(chunk);
147
+ }
148
+ try {
149
+ value = JSON.parse(Buffer.concat(chunks).toString('utf8'));
150
+ }
151
+ catch {
152
+ value = null;
153
+ }
154
+ }
155
+ finally {
156
+ reader.releaseLock();
157
+ }
158
+ }
123
159
  if (!response.ok) {
124
160
  const failure = value && typeof value === 'object' ? value : {};
125
161
  const nested = failure.data && typeof failure.data === 'object' ? failure.data : {};
@@ -129,6 +165,67 @@ async function request(origin, path, body, token, method) {
129
165
  }
130
166
  return record(value);
131
167
  }
168
+ function validateReadiness(value, credentials) {
169
+ const invalid = () => new Error('Router returned invalid account readiness. Retry ztc auth readiness.');
170
+ const scope = record(value.scope);
171
+ const funding = record(value.funding);
172
+ const model = record(value.model);
173
+ const links = record(value.links);
174
+ const states = ['ready', 'needs_payment', 'payment_pending', 'payment_failed', 'cap_reached', 'unavailable'];
175
+ const actions = ['start', 'billing', 'wait_for_payment', 'retry', 'select_model'];
176
+ const money = (amount) => amount === null || typeof amount === 'string' && /^\d{1,15}(?:\.\d{1,12})?$/.test(amount);
177
+ if (value.version !== 1 || scope.kind !== 'personal' || scope.accountId !== credentials.workspaceId
178
+ || typeof funding.state !== 'string' || !states.includes(funding.state)
179
+ || typeof funding.mode !== 'string' || !['live', 'test', 'unknown'].includes(funding.mode)
180
+ || !['paid', 'trial', null].includes(funding.source) || !money(funding.remainingUsd) || !money(funding.capUsd)
181
+ || !(funding.trialTokensRemaining === null || Number.isSafeInteger(funding.trialTokensRemaining) && Number(funding.trialTokensRemaining) >= 0)
182
+ || model.provider !== 'modal' || model.id !== 'deepseek-v4.1-flash' || typeof model.available !== 'boolean'
183
+ || typeof value.ready !== 'boolean' || typeof value.nextAction !== 'string' || !actions.includes(value.nextAction))
184
+ throw invalid();
185
+ const expectedBilling = `${credentials.origin}/dashboard/billing`;
186
+ const expectedSignIn = `${credentials.origin}/api/auth/zerg/start?next=%2Fdashboard%2Fbilling`;
187
+ if (links.billing !== expectedBilling || links.signIn !== expectedSignIn
188
+ || value.ready !== (funding.state === 'ready' && model.available) || (value.ready && value.nextAction !== 'start'))
189
+ throw invalid();
190
+ return { version: 1, scope: { kind: 'personal', accountId: credentials.workspaceId },
191
+ funding: { state: funding.state, mode: funding.mode, source: funding.source, remainingUsd: funding.remainingUsd, capUsd: funding.capUsd, trialTokensRemaining: funding.trialTokensRemaining },
192
+ model: { provider: 'modal', id: 'deepseek-v4.1-flash', available: model.available }, ready: value.ready,
193
+ nextAction: value.nextAction, links: { billing: expectedBilling, signIn: expectedSignIn } };
194
+ }
195
+ export async function readRouterAccountReadiness(credentials) {
196
+ if (Date.parse(credentials.expiresAt) <= Date.now())
197
+ throw new RouterConfigurationError('Router session expired. Run ztc auth login again; verify your email in the browser before approving the device.', 'expired');
198
+ try {
199
+ return validateReadiness(await request(credentials.origin, '/api/cli/account/readiness', undefined, credentials.token), credentials);
200
+ }
201
+ catch (error) {
202
+ if (error instanceof RouterAuthError && [401, 403].includes(error.status))
203
+ throw new RouterConfigurationError('Router authorization needs renewal. Run ztc auth login, finish email verification in the browser, then retry ztc auth readiness.', 'authentication_required');
204
+ throw error;
205
+ }
206
+ }
207
+ export function formatRouterAccountReadiness(account) {
208
+ const funding = account.funding;
209
+ const lines = [`Personal Router account (${funding.mode} billing).`];
210
+ if (funding.state === 'ready')
211
+ lines.push(`${funding.source === 'trial' ? 'Trial' : 'Pay-as-you-go'} allowance remaining: $${funding.remainingUsd}.`);
212
+ else if (funding.state === 'payment_pending')
213
+ lines.push('Payment confirmation is pending. Wait for the browser billing page to confirm, then run ztc auth readiness again.');
214
+ else if (funding.state === 'payment_failed')
215
+ lines.push('Billing reports an outstanding or rejected payment. Run ztc auth billing to review it.');
216
+ else if (funding.state === 'cap_reached')
217
+ lines.push('Your account or API-key spending cap is reached. Review account billing and key caps in the browser before retrying.');
218
+ else if (funding.state === 'needs_payment')
219
+ lines.push('Set up personal pay-as-you-go funding: ztc auth billing. Confirm pricing and your spending cap in the browser; sign-in alone does not enable billing.');
220
+ else
221
+ lines.push('Funding readiness is temporarily unavailable. Review ztc auth billing, then retry ztc auth readiness.');
222
+ if (account.ready)
223
+ lines.push('Default model available: DeepSeek Flash. Start ZTC and enter your first task; /plan "Map this project." is a useful start. Your current model and provider settings are preserved.');
224
+ else if (funding.state === 'ready' && !account.model.available)
225
+ lines.push('DeepSeek Flash is temporarily unavailable. Run /models to choose an available model, or retry ztc auth readiness.');
226
+ lines.push('This check makes no model request. Optional bounded health check: /setup --check-agent (confirm before it uses quota).');
227
+ return lines.join('\n') + '\n';
228
+ }
132
229
  function openBrowser(url, output) {
133
230
  const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'rundll32' : 'xdg-open';
134
231
  const args = process.platform === 'win32' ? ['url.dll,FileProtocolHandler', url] : [url];
@@ -137,6 +234,12 @@ function openBrowser(url, output) {
137
234
  child.unref();
138
235
  }
139
236
  async function login(origin, noBrowser, output) {
237
+ const profile = activeProfile();
238
+ const directory = profileConfigDir();
239
+ const assertOwner = () => {
240
+ if (activeProfile() !== profile || profileConfigDir() !== directory)
241
+ throw new Error('Router login cancelled: profile changed during browser approval. Run /auth login in the selected profile.');
242
+ };
140
243
  // A failed/denied attempt leaves an existing session intact.
141
244
  const existing = await loadRouterCredentials().catch(() => null);
142
245
  const deviceFingerprint = existing?.origin === origin ? existing.deviceFingerprint : randomUUID();
@@ -168,11 +271,14 @@ async function login(origin, noBrowser, output) {
168
271
  await delay(Math.min(interval * 1_000, deadline - Date.now()));
169
272
  if (Date.now() >= deadline)
170
273
  break;
274
+ assertOwner();
171
275
  try {
172
276
  const issued = await request(origin, '/api/cli/device/exchange', { grant_id: grantId, code_verifier: verifier });
277
+ assertOwner();
173
278
  const { ConfigStore } = await import('./config.js');
174
279
  const config = new ConfigStore();
175
280
  await config.load();
281
+ assertOwner();
176
282
  const current = config.get();
177
283
  // A repeated login must retain the settings from before the first login.
178
284
  const previousConfig = existing?.previousConfig && current.zergProxyUrl === existing.origin
@@ -190,6 +296,7 @@ async function login(origin, noBrowser, output) {
190
296
  if (Date.parse(credentials.expiresAt) <= Date.now())
191
297
  throw new Error('Router returned an expired session.');
192
298
  await saveCredentials(credentials);
299
+ assertOwner();
193
300
  config.setGlobal('zergProxyUrl', origin);
194
301
  config.setGlobal('authMode', authMode);
195
302
  await config.save();
@@ -197,6 +304,16 @@ async function login(origin, noBrowser, output) {
197
304
  output(authMode === 'auto'
198
305
  ? 'Routing: auto (Router while available, otherwise direct-provider authentication). Logout restores your previous settings.\n'
199
306
  : 'Routing: zrouter (Router authentication required). Logout restores your previous settings.\n', 'stderr');
307
+ try {
308
+ const readiness = await readRouterAccountReadiness(credentials);
309
+ assertOwner();
310
+ output(formatRouterAccountReadiness(readiness), 'stderr');
311
+ }
312
+ catch {
313
+ // Account metadata availability cannot undo a completed device login.
314
+ if (activeProfile() === profile && profileConfigDir() === directory)
315
+ output('Signed in. Check personal funding with ztc auth readiness; open ztc auth billing to review pay-as-you-go pricing and caps. No model request was made.\n', 'stderr');
316
+ }
200
317
  return;
201
318
  }
202
319
  catch (error) {
@@ -209,13 +326,13 @@ async function login(origin, noBrowser, output) {
209
326
  throw error;
210
327
  }
211
328
  }
212
- throw new Error('Router login expired. Run ztc auth login again.');
329
+ throw new Error('Router login expired. Finish signup and email verification in your browser, then run ztc auth login again.');
213
330
  }
214
331
  /** Shared Router authentication for the shell and in-session slash commands. */
215
332
  export async function runRouterAuthCommand(args, output = terminalOutput) {
216
333
  const [action, ...options] = args;
217
334
  if (action === 'login') {
218
- let origin = DEFAULT_ROUTER_ORIGIN;
335
+ let origin;
219
336
  let noBrowser = false;
220
337
  for (let i = 0; i < options.length; i++) {
221
338
  if (options[i] === '--no-browser')
@@ -225,11 +342,40 @@ export async function runRouterAuthCommand(args, output = terminalOutput) {
225
342
  else
226
343
  throw new Error('Usage: ztc auth login [--url <router-origin>] [--no-browser]');
227
344
  }
345
+ if (!origin) {
346
+ // Shell and slash-command login share the active profile and URL overrides.
347
+ const { ConfigStore } = await import('./config.js');
348
+ const config = new ConfigStore();
349
+ await config.load();
350
+ origin = routerOrigin(config.get().zergProxyUrl ?? DEFAULT_ROUTER_ORIGIN);
351
+ }
228
352
  await login(origin, noBrowser, output);
229
353
  return;
230
354
  }
355
+ if (action === 'readiness' || action === 'billing') {
356
+ if (options.some(option => option !== (action === 'readiness' ? '--json' : '--no-browser')))
357
+ throw new Error(`Usage: ztc auth ${action} ${action === 'readiness' ? '[--json]' : '[--no-browser]'}`);
358
+ const profile = activeProfile();
359
+ const directory = profileConfigDir();
360
+ const credentials = await loadRouterCredentials();
361
+ if (action === 'billing') {
362
+ const url = `${credentials?.origin ?? DEFAULT_ROUTER_ORIGIN}/dashboard/billing`;
363
+ output(`Review personal pay-as-you-go pricing, payment status and your spending cap in the browser:\n${url}\nThen run ztc auth readiness.\n`, 'stdout');
364
+ if (!options.includes('--no-browser'))
365
+ openBrowser(url, output);
366
+ }
367
+ else {
368
+ if (!credentials)
369
+ throw new RouterConfigurationError('Sign in first: ztc auth login. Complete signup and email verification in the browser, then approve this device.', 'authentication_required');
370
+ const readiness = await readRouterAccountReadiness(credentials);
371
+ if (activeProfile() !== profile || profileConfigDir() !== directory)
372
+ throw new Error('Profile changed while checking readiness. Retry in the selected profile.');
373
+ output(options.includes('--json') ? JSON.stringify(readiness) + '\n' : formatRouterAccountReadiness(readiness), 'stdout');
374
+ }
375
+ return;
376
+ }
231
377
  if (action !== 'status' && action !== 'logout')
232
- throw new Error('Usage: ztc auth <login|status|logout>');
378
+ throw new Error('Usage: ztc auth <login|status|readiness|billing|logout>');
233
379
  if (options.some(option => option !== (action === 'status' ? '--json' : '--local-only'))) {
234
380
  throw new Error(`Usage: ztc auth ${action} ${action === 'status' ? '[--json]' : '[--local-only]'}`);
235
381
  }
@@ -0,0 +1,3 @@
1
+ import type { RunbookPackage } from './package.js';
2
+ /** Bundled data is compiled with core; scripts use only the existing workflow language. */
3
+ export declare const bundledRunbooks: readonly RunbookPackage[];
@@ -0,0 +1,26 @@
1
+ const readers = ['read_file', 'Read'];
2
+ const commands = ['run_command', 'Bash', 'exec_command', 'shell_command'];
3
+ const jobs = [
4
+ ['repo-orientation', 'Repo orientation', 'Map entrypoints, architecture and targeted checks from repository evidence. Read project instructions first. Return source-linked findings and unknowns; do not edit the repository.', ['Architecture map with source paths', 'Documented development and test commands']],
5
+ ['pr-review', 'PR review', 'Review the requested diff against surrounding code and project instructions. Identify concrete defects with source references, reproduce narrow failures where possible, and distinguish observations from hypotheses. Return recommendations for specialized review skills to the parent session when needed.', ['Reviewed source revision and diff scope', 'Prioritized findings with reproduction evidence']],
6
+ ['qa-gate', 'QA gate', 'Identify the project-specific verification gate. Run only the relevant existing checks through managed command tools, retain command outcomes and source revisions, and report failed, skipped or unavailable checks explicitly. Do not repair unrelated failures in this run.', ['Source-bound command outcomes', 'Pass/fail/skip verdict with limitations']],
7
+ ['deploy', 'Deploy', 'Prepare the deployment for the requested target. Inspect its runbook, credentials prerequisites and rollback plan without exposing credentials. Verify build and test evidence. Return missing inputs and consequential deployment approval requirements to the parent session before execution; the runbook installation itself grants no execution authority.', ['Deployment target and proposed steps', 'Verification, approval and rollback evidence']],
8
+ ['incident-triage', 'Incident triage', 'Inspect the specified incident scope and available logs using the current session tools. Establish a timeline, impacted surface and evidence-backed hypotheses. Propose a bounded next step and return missing authorization to the parent session before recovery actions. Do not reset or alter unrelated services.', ['Incident timeline and source-linked observations', 'Proposed recovery with uncertainty and ownership']],
9
+ ['onboarding', 'Onboarding', 'Read the repository instructions and setup documentation. Explain the minimum setup and first useful verification task. Return missing requirements to the parent session. Report unavailable tools or credentials as prerequisites; do not claim unexecuted setup succeeded.', ['Setup prerequisites and source references', 'First verification task and observed blockers']],
10
+ ['release-prep', 'Release prep', 'Inspect the current release rules, version metadata and applicable verification evidence. Produce a release checklist and candidate notes tied to the source revision. Treat missing build, package, signing or publication proof as incomplete. Do not tag or publish merely because this runbook was installed.', ['Revision-bound release checklist', 'Release notes and unresolved gate evidence']],
11
+ ];
12
+ /** Bundled data is compiled with core; scripts use only the existing workflow language. */
13
+ export const bundledRunbooks = jobs.map(([id, name, instructions, expectedEvidence]) => ({
14
+ schemaVersion: 1, id, name, description: instructions.split('.')[0] + '.', instructions,
15
+ minimumNodeMajor: 20,
16
+ inputs: [{ name: 'goal', description: 'Requested scope, target, incident or review context.', required: id === 'deploy' || id === 'incident-triage' }],
17
+ requiredTools: [readers, ...(id === 'repo-orientation' || id === 'onboarding' ? [] : [commands])],
18
+ expectedEvidence: [...expectedEvidence], entrypoint: 'main.js', scripts: {
19
+ 'main.js': `export const meta = ${JSON.stringify({ name: id, description: name, phases: ['inspect', 'report'] })};
20
+ phase("inspect");
21
+ const result = await agent(args.runbookInstructions + "\\n\\nUser scope: " + (args.goal ?? "Current repository"), { label: ${JSON.stringify(id)}, toolset: "research", failFast: true });
22
+ phase("report");
23
+ return { summary: result, expectedEvidence: args.runbookExpectedEvidence };
24
+ `,
25
+ },
26
+ }));
@@ -0,0 +1,11 @@
1
+ import { type ResolvedRunbook } from './package.js';
2
+ export declare function findRunbook(source: string, cwd: string): Promise<ResolvedRunbook>;
3
+ export declare function listRunbooks(cwd: string): Promise<{
4
+ runbooks: ResolvedRunbook[];
5
+ errors: string[];
6
+ }>;
7
+ /** Stage package data in the current project. Never executes scripts or changes permissions. */
8
+ export declare function installRunbook(source: string, cwd: string): Promise<{
9
+ path: string;
10
+ book: ResolvedRunbook;
11
+ }>;
@@ -0,0 +1,95 @@
1
+ import { lstat, mkdir, readdir, realpath, rmdir } from 'node:fs/promises';
2
+ import { join, resolve, relative } from 'node:path';
3
+ import { writeFileAtomic } from '../utils/atomic_write.js';
4
+ import { bundledRunbooks } from './catalog.js';
5
+ import { RUNBOOK_MAX_BYTES, readRunbookPackage, resolveRunbookPackage } from './package.js';
6
+ const safeId = /^[a-z][a-z0-9-]{0,63}$/u;
7
+ const code = (error) => error.code;
8
+ export async function findRunbook(source, cwd) {
9
+ if (safeId.test(source)) {
10
+ const installed = join(resolve(cwd), '.ztc', 'runbooks', source, 'runbook.json');
11
+ try {
12
+ const book = await readRunbookPackage(installed);
13
+ if (book.package.id !== source)
14
+ throw new Error('Package id does not match its installation directory');
15
+ return book;
16
+ }
17
+ catch (error) {
18
+ if (code(error) !== 'ENOENT')
19
+ throw error;
20
+ }
21
+ const bundled = bundledRunbooks.find(book => book.id === source);
22
+ if (bundled)
23
+ return resolveRunbookPackage(bundled, `bundled:${source}`);
24
+ throw new Error(`Runbook not found: ${source}. Use /runbooks list or provide a local runbook JSON path.`);
25
+ }
26
+ return readRunbookPackage(resolve(cwd, source));
27
+ }
28
+ export async function listRunbooks(cwd) {
29
+ const runbooks = new Map(bundledRunbooks.map(book => [book.id, resolveRunbookPackage(book, `bundled:${book.id}`)]));
30
+ const errors = [];
31
+ const root = join(resolve(cwd), '.ztc', 'runbooks');
32
+ let directories;
33
+ try {
34
+ directories = await readdir(root, { withFileTypes: true });
35
+ }
36
+ catch (error) {
37
+ if (code(error) !== 'ENOENT')
38
+ errors.push(`Cannot read runbook library ${root}: ${String(error).slice(0, 500)}`);
39
+ return { runbooks: [...runbooks.values()], errors };
40
+ }
41
+ const candidates = directories.filter(entry => entry.isDirectory() && safeId.test(entry.name)).sort((a, b) => a.name.localeCompare(b.name));
42
+ if (candidates.length > 128)
43
+ errors.push('Runbook library exceeds 128 packages; only the first 128 are displayed.');
44
+ for (const entry of candidates.slice(0, 128)) {
45
+ try {
46
+ const book = await readRunbookPackage(join(root, entry.name, 'runbook.json'));
47
+ if (book.package.id !== entry.name)
48
+ throw new Error('Package id does not match its installation directory');
49
+ runbooks.set(book.package.id, book);
50
+ }
51
+ catch (error) {
52
+ errors.push(`${entry.name}: ${String(error).slice(0, 500)}`);
53
+ }
54
+ }
55
+ return { runbooks: [...runbooks.values()].sort((a, b) => a.package.id.localeCompare(b.package.id)), errors };
56
+ }
57
+ /** Stage package data in the current project. Never executes scripts or changes permissions. */
58
+ export async function installRunbook(source, cwd) {
59
+ const book = await findRunbook(source, cwd);
60
+ const manifest = JSON.stringify({ ...book.package, installedFrom: { source: book.source, digest: book.digest } }, null, 2) + '\n';
61
+ if (Buffer.byteLength(manifest) > RUNBOOK_MAX_BYTES)
62
+ throw new Error('Runbook installed package with retained origin exceeds 256 KiB; reduce its content before installation.');
63
+ const project = await realpath(cwd);
64
+ let root = project;
65
+ for (const component of ['.ztc', 'runbooks']) {
66
+ root = join(root, component);
67
+ await mkdir(root, { recursive: true });
68
+ const stat = await lstat(root);
69
+ if (stat.isSymbolicLink() || !stat.isDirectory() || relative(project, await realpath(root)).startsWith('..')) {
70
+ throw new Error(`Runbook installation requires a project-owned directory: ${root}`);
71
+ }
72
+ }
73
+ const destination = join(root, book.package.id);
74
+ try {
75
+ await mkdir(destination);
76
+ }
77
+ catch (error) {
78
+ if (code(error) === 'EEXIST')
79
+ throw new Error(`Runbook ${book.package.id} is already installed at ${destination}. Inspect the existing package; installation never overwrites it.`);
80
+ throw error;
81
+ }
82
+ const path = join(destination, 'runbook.json');
83
+ try {
84
+ await writeFileAtomic(path, manifest);
85
+ }
86
+ catch (error) {
87
+ // Remove only our empty reservation; never delete an existing package or another writer's files.
88
+ try {
89
+ await rmdir(destination);
90
+ }
91
+ catch { /* Incomplete files remain available for manual inspection. */ }
92
+ throw new Error(`Runbook installation incomplete at ${destination}: ${String(error).slice(0, 500)}`);
93
+ }
94
+ return { path, book };
95
+ }
@@ -0,0 +1,43 @@
1
+ import { z } from 'zod';
2
+ export declare const RUNBOOK_MAX_BYTES: number;
3
+ declare const packageSchema: z.ZodObject<{
4
+ schemaVersion: z.ZodLiteral<1>;
5
+ id: z.ZodString;
6
+ name: z.ZodString;
7
+ description: z.ZodString;
8
+ instructions: z.ZodString;
9
+ minimumNodeMajor: z.ZodNumber;
10
+ inputs: z.ZodArray<z.ZodObject<{
11
+ name: z.ZodString;
12
+ description: z.ZodString;
13
+ required: z.ZodBoolean;
14
+ }, z.core.$strict>>;
15
+ requiredTools: z.ZodArray<z.ZodArray<z.ZodString>>;
16
+ expectedEvidence: z.ZodArray<z.ZodString>;
17
+ entrypoint: z.ZodString;
18
+ scripts: z.ZodRecord<z.ZodString, z.ZodString>;
19
+ installedFrom: z.ZodOptional<z.ZodObject<{
20
+ source: z.ZodString;
21
+ digest: z.ZodString;
22
+ }, z.core.$strict>>;
23
+ }, z.core.$strict>;
24
+ export type RunbookPackage = z.infer<typeof packageSchema>;
25
+ export interface ResolvedRunbook {
26
+ package: RunbookPackage;
27
+ source: string;
28
+ digest: string;
29
+ installedFrom?: {
30
+ source: string;
31
+ digest: string;
32
+ };
33
+ }
34
+ /** Validate package data and the existing workflow language without executing scripts. */
35
+ export declare function parseRunbookPackage(value: unknown): RunbookPackage;
36
+ export declare function resolveRunbookPackage(value: unknown, source: string): ResolvedRunbook;
37
+ export declare function readRunbookPackage(path: string): Promise<ResolvedRunbook>;
38
+ /** Current host capabilities are prerequisites, not permission grants or evidence of execution. */
39
+ export declare function prepareRunbookRun(book: ResolvedRunbook, inputs: unknown, tools: readonly string[], nodeVersion?: string): {
40
+ script: string;
41
+ args: Record<string, unknown>;
42
+ };
43
+ export {};
@@ -0,0 +1,102 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { open } from 'node:fs/promises';
3
+ import { z } from 'zod';
4
+ import { parseWorkflowScript } from '../workflows/parser.js';
5
+ export const RUNBOOK_MAX_BYTES = 256 * 1024;
6
+ const id = z.string().regex(/^[a-z][a-z0-9-]{0,63}$/u);
7
+ const scriptName = z.string().regex(/^[a-z][a-z0-9_-]{0,63}\.js$/u);
8
+ const inputName = z.string().regex(/^[a-z][a-z0-9_]{0,63}$/u)
9
+ .refine(name => !name.startsWith('runbook') && !['constructor', 'prototype'].includes(name), 'Reserved input name');
10
+ const text = z.string().min(1).max(4000);
11
+ const packageSchema = z.object({
12
+ schemaVersion: z.literal(1),
13
+ id,
14
+ name: text,
15
+ description: text,
16
+ instructions: z.string().min(1).max(32 * 1024),
17
+ minimumNodeMajor: z.number().int().min(20).max(99),
18
+ inputs: z.array(z.object({ name: inputName, description: text, required: z.boolean() }).strict()).max(16),
19
+ requiredTools: z.array(z.array(z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,99}$/u)).min(1).max(8)).max(16),
20
+ expectedEvidence: z.array(text).min(1).max(16),
21
+ entrypoint: scriptName,
22
+ scripts: z.record(scriptName, z.string().min(1).max(128 * 1024))
23
+ .refine(scripts => Object.keys(scripts).length >= 1 && Object.keys(scripts).length <= 16, 'Use 1–16 workflow scripts'),
24
+ installedFrom: z.object({ source: text, digest: z.string().regex(/^[a-f0-9]{64}$/u) }).strict().optional(),
25
+ }).strict();
26
+ /** Validate package data and the existing workflow language without executing scripts. */
27
+ export function parseRunbookPackage(value) {
28
+ const result = packageSchema.safeParse(value);
29
+ if (!result.success)
30
+ throw new Error(`Invalid runbook package (supported schemaVersion: 1): ${result.error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`).join('; ').slice(0, 1500)}`);
31
+ const book = result.data;
32
+ if (new Set(book.inputs.map(input => input.name)).size !== book.inputs.length)
33
+ throw new Error('Runbook input names must be unique');
34
+ if (!Object.hasOwn(book.scripts, book.entrypoint))
35
+ throw new Error(`Missing runbook entrypoint: ${book.entrypoint}`);
36
+ if (Buffer.byteLength(JSON.stringify(book)) > RUNBOOK_MAX_BYTES)
37
+ throw new Error('Runbook package exceeds 256 KiB');
38
+ for (const [name, script] of Object.entries(book.scripts)) {
39
+ try {
40
+ parseWorkflowScript(script);
41
+ }
42
+ catch (error) {
43
+ throw new Error(`Invalid runbook workflow ${name}: ${error instanceof Error ? error.message : String(error)}`);
44
+ }
45
+ }
46
+ return book;
47
+ }
48
+ export function resolveRunbookPackage(value, source) {
49
+ const book = parseRunbookPackage(value);
50
+ const { installedFrom, ...content } = book;
51
+ return { package: book, source, digest: createHash('sha256').update(JSON.stringify(content)).digest('hex'),
52
+ ...(installedFrom ? { installedFrom } : {}) };
53
+ }
54
+ export async function readRunbookPackage(path) {
55
+ const file = await open(path, 'r');
56
+ try {
57
+ if (!(await file.stat()).isFile())
58
+ throw new Error('Runbook package must be a regular JSON file');
59
+ const buffer = Buffer.alloc(RUNBOOK_MAX_BYTES + 1);
60
+ let size = 0;
61
+ while (size < buffer.length) {
62
+ const read = await file.read(buffer, size, buffer.length - size, size);
63
+ if (!read.bytesRead)
64
+ break;
65
+ size += read.bytesRead;
66
+ }
67
+ if (size > RUNBOOK_MAX_BYTES)
68
+ throw new Error('Runbook package exceeds 256 KiB');
69
+ let value;
70
+ try {
71
+ value = JSON.parse(buffer.subarray(0, size).toString('utf8'));
72
+ }
73
+ catch {
74
+ throw new Error(`Runbook is not valid JSON: ${path}`);
75
+ }
76
+ return resolveRunbookPackage(value, path);
77
+ }
78
+ finally {
79
+ await file.close();
80
+ }
81
+ }
82
+ /** Current host capabilities are prerequisites, not permission grants or evidence of execution. */
83
+ export function prepareRunbookRun(book, inputs, tools, nodeVersion = process.versions.node) {
84
+ const major = nodeVersion.match(/^(\d+)\.\d+\.\d+(?:[-+].*)?$/u)?.[1];
85
+ if (!major || Number(major) < book.package.minimumNodeMajor)
86
+ throw new Error(`Runbook ${book.package.id} requires Node ${book.package.minimumNodeMajor}+; current runtime is ${nodeVersion}. Update the ZTC runtime.`);
87
+ const missing = book.package.requiredTools.filter(alternatives => !alternatives.some(tool => tools.includes(tool)));
88
+ if (missing.length)
89
+ throw new Error(`Runbook ${book.package.id} needs registered tools: ${missing.map(names => names.join(' or ')).join(', ')}. Change to a compatible session/provider/mode; permission decisions still apply.`);
90
+ const fields = Object.fromEntries(book.package.inputs.map(input => {
91
+ const field = z.string().min(1).max(10_000);
92
+ return [input.name, input.required ? field : field.optional()];
93
+ }));
94
+ const result = z.object(fields).strict().safeParse(inputs);
95
+ if (!result.success)
96
+ throw new Error(`Invalid runbook inputs: ${result.error.issues.map(issue => `${issue.path.join('.') || 'inputs'}: ${issue.message}`).join('; ').slice(0, 1500)}. Use /runbooks show ${book.package.id} for input requirements.`);
97
+ return { script: book.package.scripts[book.package.entrypoint], args: {
98
+ ...result.data,
99
+ runbookInstructions: book.package.instructions, runbookSource: book.source,
100
+ runbookDigest: book.digest, runbookExpectedEvidence: book.package.expectedEvidence,
101
+ } };
102
+ }