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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (718) hide show
  1. package/README.md +398 -45
  2. package/RUST_THIRD_PARTY_LICENSES.txt +1080 -822
  3. package/THIRD_PARTY_NOTICES.md +273 -12
  4. package/bin/zmux-darwin-arm64 +0 -0
  5. package/bin/ztc-audio-darwin-arm64 +0 -0
  6. package/bin/ztc-capture-darwin-arm64 +0 -0
  7. package/bin/ztc-computer-darwin-arm64 +0 -0
  8. package/bin/ztc-llm-darwin-arm64 +0 -0
  9. package/bin/ztc-tts-darwin-arm64 +0 -0
  10. package/bin/ztc-tui-darwin-arm64 +0 -0
  11. package/bin/ztc-zlicky-overlay-darwin-arm64 +0 -0
  12. package/bin/zterm-darwin-arm64 +0 -0
  13. package/dist/App.js +1206 -209
  14. package/dist/agent/agent.d.ts +74 -8
  15. package/dist/agent/agent.js +1073 -184
  16. package/dist/agent/backends/account_rotation.d.ts +4 -0
  17. package/dist/agent/backends/account_rotation.js +8 -2
  18. package/dist/agent/backends/anthropic.d.ts +13 -0
  19. package/dist/agent/backends/anthropic.js +169 -28
  20. package/dist/agent/backends/claude_cli.js +18 -8
  21. package/dist/agent/backends/codex_app_server.d.ts +1 -0
  22. package/dist/agent/backends/codex_app_server.js +55 -3
  23. package/dist/agent/backends/codex_auth.d.ts +1 -0
  24. package/dist/agent/backends/codex_auth.js +67 -13
  25. package/dist/agent/backends/codex_buffered_recovery.d.ts +27 -0
  26. package/dist/agent/backends/codex_buffered_recovery.js +293 -0
  27. package/dist/agent/backends/gemini.js +3 -1
  28. package/dist/agent/backends/http_error.d.ts +26 -0
  29. package/dist/agent/backends/http_error.js +221 -0
  30. package/dist/agent/backends/index.d.ts +9 -2
  31. package/dist/agent/backends/index.js +22 -2
  32. package/dist/agent/backends/openai.d.ts +0 -6
  33. package/dist/agent/backends/openai.js +5 -2
  34. package/dist/agent/backends/openai_compatible.d.ts +5 -4
  35. package/dist/agent/backends/openai_compatible.js +26 -19
  36. package/dist/agent/backends/openai_responses.d.ts +8 -3
  37. package/dist/agent/backends/openai_responses.js +77 -33
  38. package/dist/agent/backends/provider_ids.d.ts +1 -0
  39. package/dist/agent/backends/provider_ids.js +4 -0
  40. package/dist/agent/backends/request_metrics.js +12 -2
  41. package/dist/agent/backends/types.d.ts +109 -6
  42. package/dist/agent/backends/types.js +5 -1
  43. package/dist/agent/backends/zrouter_stream.d.ts +6 -1
  44. package/dist/agent/backends/zrouter_stream.js +160 -42
  45. package/dist/agent/background_registry.d.ts +2 -0
  46. package/dist/agent/background_registry.js +1 -0
  47. package/dist/agent/claim_observation.d.ts +6 -0
  48. package/dist/agent/claim_observation.js +54 -0
  49. package/dist/agent/commands/accounts.js +46 -177
  50. package/dist/agent/commands/attention.d.ts +2 -0
  51. package/dist/agent/commands/attention.js +67 -0
  52. package/dist/agent/commands/auth.js +18 -2
  53. package/dist/agent/commands/board.d.ts +2 -0
  54. package/dist/agent/commands/board.js +169 -0
  55. package/dist/agent/commands/clipboard.js +50 -1
  56. package/dist/agent/commands/compact.js +21 -13
  57. package/dist/agent/commands/config.js +4 -1
  58. package/dist/agent/commands/context.js +6 -1
  59. package/dist/agent/commands/desktop.d.ts +2 -0
  60. package/dist/agent/commands/desktop.js +29 -0
  61. package/dist/agent/commands/effort.js +14 -6
  62. package/dist/agent/commands/environment.d.ts +3 -0
  63. package/dist/agent/commands/environment.js +109 -0
  64. package/dist/agent/commands/evidence.d.ts +2 -0
  65. package/dist/agent/commands/evidence.js +9 -0
  66. package/dist/agent/commands/fork.js +4 -3
  67. package/dist/agent/commands/goal.d.ts +33 -1
  68. package/dist/agent/commands/goal.js +174 -14
  69. package/dist/agent/commands/goal_exit.d.ts +36 -0
  70. package/dist/agent/commands/goal_exit.js +120 -0
  71. package/dist/agent/commands/help.js +3 -1
  72. package/dist/agent/commands/history.js +3 -1
  73. package/dist/agent/commands/inbox.d.ts +2 -0
  74. package/dist/agent/commands/inbox.js +148 -0
  75. package/dist/agent/commands/index.js +16 -1
  76. package/dist/agent/commands/input_mode.js +8 -6
  77. package/dist/agent/commands/job.d.ts +2 -0
  78. package/dist/agent/commands/job.js +93 -0
  79. package/dist/agent/commands/keybindings.js +4 -1
  80. package/dist/agent/commands/label.d.ts +2 -0
  81. package/dist/agent/commands/label.js +77 -0
  82. package/dist/agent/commands/layout.d.ts +2 -0
  83. package/dist/agent/commands/layout.js +20 -0
  84. package/dist/agent/commands/mirror.js +16 -1
  85. package/dist/agent/commands/model.js +12 -2
  86. package/dist/agent/commands/permissions.d.ts +3 -1
  87. package/dist/agent/commands/permissions.js +79 -89
  88. package/dist/agent/commands/plan.js +5 -15
  89. package/dist/agent/commands/profile.js +21 -2
  90. package/dist/agent/commands/provider_selection.js +20 -1
  91. package/dist/agent/commands/rename.js +1 -1
  92. package/dist/agent/commands/resources.d.ts +2 -0
  93. package/dist/agent/commands/resources.js +67 -0
  94. package/dist/agent/commands/rewind.d.ts +3 -0
  95. package/dist/agent/commands/rewind.js +16 -0
  96. package/dist/agent/commands/runbooks.d.ts +2 -0
  97. package/dist/agent/commands/runbooks.js +73 -0
  98. package/dist/agent/commands/runbooks_lazy.d.ts +2 -0
  99. package/dist/agent/commands/runbooks_lazy.js +8 -0
  100. package/dist/agent/commands/sessions.d.ts +1 -1
  101. package/dist/agent/commands/sessions.js +33 -5
  102. package/dist/agent/commands/settings.js +185 -39
  103. package/dist/agent/commands/setup.d.ts +2 -0
  104. package/dist/agent/commands/setup.js +78 -0
  105. package/dist/agent/commands/share.d.ts +2 -0
  106. package/dist/agent/commands/share.js +64 -0
  107. package/dist/agent/commands/status.js +14 -2
  108. package/dist/agent/commands/types.d.ts +99 -6
  109. package/dist/agent/commands/update.js +8 -0
  110. package/dist/agent/commands/usage.d.ts +2 -0
  111. package/dist/agent/commands/usage.js +8 -0
  112. package/dist/agent/factory.d.ts +11 -0
  113. package/dist/agent/factory.js +113 -88
  114. package/dist/agent/loop_policy.d.ts +6 -3
  115. package/dist/agent/loop_policy.js +12 -3
  116. package/dist/agent/measurement_guidance.d.ts +2 -0
  117. package/dist/agent/measurement_guidance.js +5 -0
  118. package/dist/agent/request_encoder.d.ts +8 -1
  119. package/dist/agent/request_encoder.js +95 -23
  120. package/dist/agent/runtime/benchmark_comparison.d.ts +30 -0
  121. package/dist/agent/runtime/benchmark_comparison.js +94 -0
  122. package/dist/agent/runtime/benchmark_contract.d.ts +48 -0
  123. package/dist/agent/runtime/benchmark_contract.js +90 -0
  124. package/dist/agent/runtime/checked_commands.d.ts +32 -0
  125. package/dist/agent/runtime/checked_commands.js +119 -0
  126. package/dist/agent/runtime/command_execution_policy.d.ts +26 -0
  127. package/dist/agent/runtime/command_execution_policy.js +91 -0
  128. package/dist/agent/runtime/command_jobs.d.ts +36 -18
  129. package/dist/agent/runtime/command_jobs.js +151 -13
  130. package/dist/agent/runtime/command_panes.d.ts +59 -0
  131. package/dist/agent/runtime/command_panes.js +398 -0
  132. package/dist/agent/runtime/command_wait.d.ts +19 -0
  133. package/dist/agent/runtime/command_wait.js +167 -0
  134. package/dist/agent/runtime/cpu_benchmark.d.ts +30 -0
  135. package/dist/agent/runtime/cpu_benchmark.js +126 -0
  136. package/dist/agent/runtime/delegated_evidence.d.ts +26 -0
  137. package/dist/agent/runtime/delegated_evidence.js +80 -0
  138. package/dist/agent/runtime/evidence.d.ts +127 -0
  139. package/dist/agent/runtime/evidence.js +468 -0
  140. package/dist/agent/runtime/execution_context.d.ts +7 -0
  141. package/dist/agent/runtime/execution_context.js +39 -3
  142. package/dist/agent/runtime/json_verifier_recipe.d.ts +8 -0
  143. package/dist/agent/runtime/json_verifier_recipe.js +66 -0
  144. package/dist/agent/runtime/measurements.d.ts +110 -0
  145. package/dist/agent/runtime/measurements.js +317 -0
  146. package/dist/agent/runtime/policy.d.ts +4 -0
  147. package/dist/agent/runtime/policy.js +31 -20
  148. package/dist/agent/runtime/provider_native_evidence.d.ts +20 -0
  149. package/dist/agent/runtime/provider_native_evidence.js +86 -0
  150. package/dist/agent/runtime/recovery.d.ts +2 -0
  151. package/dist/agent/runtime/recovery.js +45 -2
  152. package/dist/agent/runtime/remote_broker_transport.d.ts +10 -0
  153. package/dist/agent/runtime/remote_broker_transport.js +84 -0
  154. package/dist/agent/runtime/remote_deletion_receipts.d.ts +3 -0
  155. package/dist/agent/runtime/remote_deletion_receipts.js +43 -0
  156. package/dist/agent/runtime/remote_journal_replay.d.ts +13 -0
  157. package/dist/agent/runtime/remote_journal_replay.js +233 -0
  158. package/dist/agent/runtime/remote_mutation_journal.d.ts +25 -0
  159. package/dist/agent/runtime/remote_mutation_journal.js +208 -0
  160. package/dist/agent/runtime/remote_resource_endpoint.d.ts +7 -0
  161. package/dist/agent/runtime/remote_resource_endpoint.js +6 -0
  162. package/dist/agent/runtime/remote_resource_errors.d.ts +5 -0
  163. package/dist/agent/runtime/remote_resource_errors.js +9 -0
  164. package/dist/agent/runtime/remote_resource_script.d.ts +2 -0
  165. package/dist/agent/runtime/remote_resource_script.js +1009 -0
  166. package/dist/agent/runtime/remote_resources.d.ts +29 -0
  167. package/dist/agent/runtime/remote_resources.js +160 -0
  168. package/dist/agent/runtime/source_verification.d.ts +12 -0
  169. package/dist/agent/runtime/source_verification.js +210 -0
  170. package/dist/agent/runtime/source_verification_contract.d.ts +75 -0
  171. package/dist/agent/runtime/source_verification_contract.js +203 -0
  172. package/dist/agent/runtime/tool_checkpoints.d.ts +11 -0
  173. package/dist/agent/runtime/tool_checkpoints.js +26 -0
  174. package/dist/agent/runtime/tool_effects.d.ts +5 -0
  175. package/dist/agent/runtime/tool_progress.d.ts +12 -0
  176. package/dist/agent/runtime/tool_progress.js +76 -0
  177. package/dist/agent/runtime/tool_runtime.d.ts +16 -1
  178. package/dist/agent/runtime/tool_runtime.js +204 -10
  179. package/dist/agent/runtime/tracing.d.ts +1 -1
  180. package/dist/agent/runtime/verifier_capture.d.ts +9 -0
  181. package/dist/agent/runtime/verifier_capture.js +100 -0
  182. package/dist/agent/runtime/verifier_contract.d.ts +24 -0
  183. package/dist/agent/runtime/verifier_contract.js +41 -0
  184. package/dist/agent/subagent.d.ts +20 -10
  185. package/dist/agent/subagent.js +266 -29
  186. package/dist/agent/tool_response_directory.d.ts +24 -0
  187. package/dist/agent/tool_response_directory.js +61 -0
  188. package/dist/agent/tool_response_source.d.ts +8 -0
  189. package/dist/agent/tool_response_source.js +49 -0
  190. package/dist/agent/tool_response_store.d.ts +75 -4
  191. package/dist/agent/tool_response_store.js +583 -64
  192. package/dist/agent/tools/ask_user.d.ts +3 -1
  193. package/dist/agent/tools/ask_user.js +30 -11
  194. package/dist/agent/tools/background.js +1 -0
  195. package/dist/agent/tools/benchmark_cpu.d.ts +2 -0
  196. package/dist/agent/tools/benchmark_cpu.js +102 -0
  197. package/dist/agent/tools/compare_benchmarks.d.ts +2 -0
  198. package/dist/agent/tools/compare_benchmarks.js +53 -0
  199. package/dist/agent/tools/deferred.js +1 -0
  200. package/dist/agent/tools/delegate.js +18 -2
  201. package/dist/agent/tools/helper_requirements.d.ts +7 -0
  202. package/dist/agent/tools/helper_requirements.js +19 -0
  203. package/dist/agent/tools/index.d.ts +1 -0
  204. package/dist/agent/tools/index.js +3 -0
  205. package/dist/agent/tools/measurement_report.d.ts +22 -0
  206. package/dist/agent/tools/measurement_report.js +190 -0
  207. package/dist/agent/tools/pane.d.ts +0 -7
  208. package/dist/agent/tools/pane.js +5 -4
  209. package/dist/agent/tools/project_context.d.ts +3 -0
  210. package/dist/agent/tools/project_context.js +45 -0
  211. package/dist/agent/tools/recall_tool_response.d.ts +3 -5
  212. package/dist/agent/tools/recall_tool_response.js +19 -29
  213. package/dist/agent/tools/registry.d.ts +1 -0
  214. package/dist/agent/tools/registry.js +23 -0
  215. package/dist/agent/tools/related_sessions.d.ts +2 -0
  216. package/dist/agent/tools/related_sessions.js +156 -0
  217. package/dist/agent/tools/routine.js +13 -3
  218. package/dist/agent/tools/session_evidence.d.ts +3 -0
  219. package/dist/agent/tools/session_evidence.js +72 -0
  220. package/dist/agent/tools/shell.d.ts +4 -3
  221. package/dist/agent/tools/shell.js +174 -47
  222. package/dist/agent/tools/tool_search.js +3 -2
  223. package/dist/agent/tools/types.d.ts +28 -0
  224. package/dist/agent/tools/verify_artifact.d.ts +2 -0
  225. package/dist/agent/tools/verify_artifact.js +60 -0
  226. package/dist/agent/tools/workflow.js +1 -0
  227. package/dist/app/activity.d.ts +6 -1
  228. package/dist/app/activity.js +81 -12
  229. package/dist/app/agent_runner.d.ts +6 -1
  230. package/dist/app/agent_runner.js +34 -19
  231. package/dist/app/command_context.js +106 -10
  232. package/dist/app/controller.d.ts +15 -4
  233. package/dist/app/controller.js +29 -3
  234. package/dist/app/escape_stop.d.ts +11 -0
  235. package/dist/app/escape_stop.js +15 -0
  236. package/dist/app/liveness.d.ts +6 -4
  237. package/dist/app/liveness.js +13 -3
  238. package/dist/app/model_catalog_cache.d.ts +5 -0
  239. package/dist/app/model_catalog_cache.js +138 -0
  240. package/dist/app/ordered_transcript.js +43 -4
  241. package/dist/app/prompt_turn.d.ts +14 -0
  242. package/dist/app/prompt_turn.js +53 -0
  243. package/dist/app/recap.d.ts +3 -0
  244. package/dist/app/recap.js +9 -3
  245. package/dist/app/restart.d.ts +3 -2
  246. package/dist/app/restart.js +22 -7
  247. package/dist/app/rewind.d.ts +3 -3
  248. package/dist/app/rewind.js +3 -3
  249. package/dist/app/selection_completion.d.ts +17 -2
  250. package/dist/app/selection_completion.js +84 -9
  251. package/dist/app/session_manager.d.ts +38 -6
  252. package/dist/app/session_manager.js +263 -60
  253. package/dist/app/session_messages.d.ts +3 -0
  254. package/dist/app/session_messages.js +60 -0
  255. package/dist/app/task_scope_router.d.ts +20 -0
  256. package/dist/app/task_scope_router.js +173 -0
  257. package/dist/app/transcript_window.d.ts +2 -0
  258. package/dist/app/transcript_window.js +4 -0
  259. package/dist/app/workspace_admission_details.d.ts +3 -0
  260. package/dist/app/workspace_admission_details.js +26 -0
  261. package/dist/app/workspace_layout_controller.d.ts +11 -0
  262. package/dist/app/workspace_layout_controller.js +88 -0
  263. package/dist/app/workspace_monitor.d.ts +1 -0
  264. package/dist/app/workspace_monitor.js +216 -0
  265. package/dist/app/workspace_presets.d.ts +29 -0
  266. package/dist/app/workspace_presets.js +192 -0
  267. package/dist/attention/queue.d.ts +37 -0
  268. package/dist/attention/queue.js +183 -0
  269. package/dist/bench/rf_shared.d.ts +2 -0
  270. package/dist/board/binding.d.ts +42 -0
  271. package/dist/board/binding.js +38 -0
  272. package/dist/board/client.d.ts +42 -0
  273. package/dist/board/client.js +60 -0
  274. package/dist/cli.js +1 -1
  275. package/dist/cli_args.js +19 -17
  276. package/dist/cli_main.js +110 -13
  277. package/dist/cli_ratatui.d.ts +183 -16
  278. package/dist/cli_ratatui.js +3989 -1255
  279. package/dist/components/ActivityLine.d.ts +3 -2
  280. package/dist/components/ActivityLine.js +2 -2
  281. package/dist/components/InputArea.d.ts +19 -1
  282. package/dist/components/InputArea.js +264 -190
  283. package/dist/components/MessageList.d.ts +2 -0
  284. package/dist/components/MessageList.js +3 -1
  285. package/dist/components/SingleMessage.d.ts +2 -0
  286. package/dist/components/SingleMessage.js +4 -2
  287. package/dist/components/StatusBar.d.ts +4 -2
  288. package/dist/components/StatusBar.js +3 -1
  289. package/dist/conductor_branch.js +3 -0
  290. package/dist/config/api_retry.d.ts +6 -1
  291. package/dist/config/api_retry.js +19 -1
  292. package/dist/config/defaults.d.ts +2 -1
  293. package/dist/config/defaults.js +9 -2
  294. package/dist/config/message_display.d.ts +1 -0
  295. package/dist/config/message_display.js +17 -2
  296. package/dist/config/permissions.d.ts +21 -0
  297. package/dist/config/permissions.js +89 -0
  298. package/dist/config/resolved.d.ts +2 -2
  299. package/dist/config/types.d.ts +32 -5
  300. package/dist/config.d.ts +38 -4
  301. package/dist/config.js +290 -42
  302. package/dist/context/project_intelligence.d.ts +44 -0
  303. package/dist/context/project_intelligence.js +246 -0
  304. package/dist/desktop/cli_launch.d.ts +8 -0
  305. package/dist/desktop/cli_launch.js +6 -0
  306. package/dist/desktop/cli_shim.d.ts +8 -0
  307. package/dist/desktop/cli_shim.js +120 -0
  308. package/dist/desktop/runtime.d.ts +16 -0
  309. package/dist/desktop/runtime.js +161 -0
  310. package/dist/desktop/worker_launch.d.ts +7 -0
  311. package/dist/desktop/worker_launch.js +7 -0
  312. package/dist/diagnostics/cargo_mutants_selection.d.ts +27 -0
  313. package/dist/diagnostics/cargo_mutants_selection.js +48 -0
  314. package/dist/diagnostics/native_terminal_benchmark.d.ts +58 -0
  315. package/dist/diagnostics/native_terminal_benchmark.js +1247 -0
  316. package/dist/diagnostics/session_evidence_package.d.ts +40 -0
  317. package/dist/diagnostics/session_evidence_package.js +234 -0
  318. package/dist/diagnostics/session_export.d.ts +93 -0
  319. package/dist/diagnostics/session_export.js +634 -0
  320. package/dist/emulation/tool_adapters.js +48 -18
  321. package/dist/emulation/ztc_addendum.d.ts +1 -0
  322. package/dist/emulation/ztc_addendum.js +13 -12
  323. package/dist/environment/service_runner.d.ts +1 -0
  324. package/dist/environment/service_runner.js +68 -0
  325. package/dist/environment/store.d.ts +120 -0
  326. package/dist/environment/store.js +387 -0
  327. package/dist/events.d.ts +40 -1
  328. package/dist/events.js +10 -17
  329. package/dist/goal_contract.d.ts +25 -0
  330. package/dist/goal_contract.js +44 -0
  331. package/dist/headless.d.ts +31 -0
  332. package/dist/headless.js +578 -70
  333. package/dist/headless_cli.js +8 -0
  334. package/dist/headless_cli_args.d.ts +1 -0
  335. package/dist/headless_cli_args.js +1 -0
  336. package/dist/intake/cli.d.ts +1 -0
  337. package/dist/intake/cli.js +33 -0
  338. package/dist/intake/format.d.ts +2 -0
  339. package/dist/intake/format.js +14 -0
  340. package/dist/intake/notifications.d.ts +16 -0
  341. package/dist/intake/notifications.js +132 -0
  342. package/dist/intake/store.d.ts +56 -0
  343. package/dist/intake/store.js +238 -0
  344. package/dist/library.d.ts +8 -0
  345. package/dist/library.js +19 -10
  346. package/dist/mcp/client.d.ts +1 -0
  347. package/dist/mcp/client.js +20 -0
  348. package/dist/modes/builtin/plan.yaml +2 -2
  349. package/dist/modes/handlers.js +1 -1
  350. package/dist/onboarding/first_run.d.ts +3 -0
  351. package/dist/onboarding/first_run.js +33 -25
  352. package/dist/onboarding/setup.d.ts +32 -0
  353. package/dist/onboarding/setup.js +133 -0
  354. package/dist/onboarding/setup_agent_health.d.ts +17 -0
  355. package/dist/onboarding/setup_agent_health.js +79 -0
  356. package/dist/onboarding/setup_environment.d.ts +66 -0
  357. package/dist/onboarding/setup_environment.js +219 -0
  358. package/dist/onboarding/setup_workspace.d.ts +17 -0
  359. package/dist/onboarding/setup_workspace.js +129 -0
  360. package/dist/optimize/adapters/index.d.ts +4 -1
  361. package/dist/optimize/adapters/index.js +7 -0
  362. package/dist/optimize/adapters/kernelbench.js +14 -5
  363. package/dist/optimize/adapters/popcorn.js +3 -2
  364. package/dist/optimize/adapters/profile_benchmark.js +13 -7
  365. package/dist/optimize/adapters/rfbench.js +25 -14
  366. package/dist/optimize/adapters/types.d.ts +3 -0
  367. package/dist/optimize/adapters/zergpod.js +5 -2
  368. package/dist/optimize/baseline.js +10 -21
  369. package/dist/optimize/branch.js +9 -12
  370. package/dist/optimize/combine.js +2 -3
  371. package/dist/optimize/executor.js +34 -48
  372. package/dist/optimize/measurements.d.ts +55 -0
  373. package/dist/optimize/measurements.js +173 -0
  374. package/dist/optimize/results.d.ts +1 -0
  375. package/dist/optimize/results.js +11 -33
  376. package/dist/optimize/tge.js +2 -1
  377. package/dist/panes/initial_input.d.ts +19 -0
  378. package/dist/panes/initial_input.js +206 -0
  379. package/dist/panes/labels.d.ts +16 -0
  380. package/dist/panes/labels.js +42 -0
  381. package/dist/panes/model_catalog.d.ts +3 -3
  382. package/dist/panes/model_catalog.js +28 -4
  383. package/dist/panes/pane_registry.js +6 -2
  384. package/dist/panes/types.d.ts +3 -0
  385. package/dist/panes/ztc_launch.js +19 -0
  386. package/dist/plugin/optimization.d.ts +2 -0
  387. package/dist/plugin/optimization.js +1 -0
  388. package/dist/plugin/runtime.d.ts +2 -0
  389. package/dist/plugin/simulation.d.ts +6 -1
  390. package/dist/plugin/simulation_contract.d.ts +836 -1
  391. package/dist/plugin/simulation_documents.d.ts +22 -0
  392. package/dist/plugin/simulation_documents.js +1 -0
  393. package/dist/plugin/simulation_interventions.d.ts +103 -0
  394. package/dist/plugin/simulation_interventions.js +1 -0
  395. package/dist/plugin/simulation_living.d.ts +1 -0
  396. package/dist/plugin/simulation_living.js +3 -0
  397. package/dist/plugin/simulation_meetings.d.ts +121 -0
  398. package/dist/plugin/simulation_meetings.js +1 -0
  399. package/dist/plugin/simulation_story_review.d.ts +111 -0
  400. package/dist/plugin/simulation_story_review.js +1 -0
  401. package/dist/plugin/simulation_storyteller.d.ts +91 -0
  402. package/dist/plugin/simulation_storyteller.js +1 -0
  403. package/dist/plugin/simulation_structured.d.ts +2 -0
  404. package/dist/plugin/simulation_structured.js +2 -0
  405. package/dist/plugin/simulation_toolkit.d.ts +21 -0
  406. package/dist/plugin/simulation_toolkit.js +24 -0
  407. package/dist/prompts/tool_delegate_task.j2 +1 -1
  408. package/dist/remote-broker/Dockerfile +10 -0
  409. package/dist/remote-broker/archive.py +1227 -0
  410. package/dist/remote-broker/cutover.py +761 -0
  411. package/dist/remote-broker/requirements.txt +5 -0
  412. package/dist/remote-broker/resources.json +6 -0
  413. package/dist/remote-broker/resources.write-staging.example.json +18 -0
  414. package/dist/remote-broker/retained.py +686 -0
  415. package/dist/remote-broker/retained_cleanup.py +550 -0
  416. package/dist/remote-broker/server.py +648 -0
  417. package/dist/remote-broker/worker.py +1007 -0
  418. package/dist/router_auth.d.ts +31 -0
  419. package/dist/router_auth.js +155 -9
  420. package/dist/runbooks/catalog.d.ts +3 -0
  421. package/dist/runbooks/catalog.js +26 -0
  422. package/dist/runbooks/library.d.ts +11 -0
  423. package/dist/runbooks/library.js +95 -0
  424. package/dist/runbooks/package.d.ts +43 -0
  425. package/dist/runbooks/package.js +102 -0
  426. package/dist/session.d.ts +65 -13
  427. package/dist/session.js +548 -43
  428. package/dist/session_handoff.d.ts +25 -0
  429. package/dist/session_handoff.js +322 -0
  430. package/dist/session_handoff_contract.d.ts +89 -0
  431. package/dist/session_handoff_contract.js +179 -0
  432. package/dist/session_media.d.ts +41 -0
  433. package/dist/session_media.js +357 -0
  434. package/dist/session_ownership.d.ts +16 -0
  435. package/dist/session_ownership.js +221 -0
  436. package/dist/session_public.d.ts +10 -2
  437. package/dist/session_public.js +6 -1
  438. package/dist/simulation/dynamic_history.d.ts +42 -0
  439. package/dist/simulation/dynamic_history.js +173 -0
  440. package/dist/simulation/engines/swarm/pane_manager.js +7 -6
  441. package/dist/simulation/inference.d.ts +3 -1
  442. package/dist/simulation/inference.js +19 -1
  443. package/dist/simulation/intervention_generation.d.ts +27 -0
  444. package/dist/simulation/intervention_generation.js +246 -0
  445. package/dist/simulation/intervention_material.d.ts +4 -0
  446. package/dist/simulation/intervention_material.js +81 -0
  447. package/dist/simulation/living/context.d.ts +3130 -0
  448. package/dist/simulation/living/context.js +944 -0
  449. package/dist/simulation/living/definer.d.ts +12 -0
  450. package/dist/simulation/living/definer.js +223 -0
  451. package/dist/simulation/living/definition.d.ts +257 -0
  452. package/dist/simulation/living/definition.js +341 -0
  453. package/dist/simulation/living/frame.d.ts +259 -0
  454. package/dist/simulation/living/frame.js +223 -0
  455. package/dist/simulation/living/identifiers.d.ts +2 -0
  456. package/dist/simulation/living/identifiers.js +12 -0
  457. package/dist/simulation/living/index.d.ts +15 -0
  458. package/dist/simulation/living/index.js +15 -0
  459. package/dist/simulation/living/inference.d.ts +219 -0
  460. package/dist/simulation/living/inference.js +576 -0
  461. package/dist/simulation/living/mechanics.d.ts +54 -0
  462. package/dist/simulation/living/mechanics.js +588 -0
  463. package/dist/simulation/living/model-input.d.ts +25 -0
  464. package/dist/simulation/living/model-input.js +215 -0
  465. package/dist/simulation/living/open-world.d.ts +257 -0
  466. package/dist/simulation/living/open-world.js +102 -0
  467. package/dist/simulation/living/projection.d.ts +7 -0
  468. package/dist/simulation/living/projection.js +31 -0
  469. package/dist/simulation/living/recall.d.ts +17 -0
  470. package/dist/simulation/living/recall.js +25 -0
  471. package/dist/simulation/living/reduce.d.ts +15 -0
  472. package/dist/simulation/living/reduce.js +1853 -0
  473. package/dist/simulation/living/replay.d.ts +6 -0
  474. package/dist/simulation/living/replay.js +22 -0
  475. package/dist/simulation/living/runtime.d.ts +140 -0
  476. package/dist/simulation/living/runtime.js +3020 -0
  477. package/dist/simulation/living/shared-kinds.d.ts +24 -0
  478. package/dist/simulation/living/shared-kinds.js +96 -0
  479. package/dist/simulation/living/types.d.ts +2785 -0
  480. package/dist/simulation/living/types.js +669 -0
  481. package/dist/simulation/llm.d.ts +3 -1
  482. package/dist/simulation/llm.js +90 -30
  483. package/dist/simulation/memory/embedding.d.ts +1 -1
  484. package/dist/simulation/memory/embedding.js +9 -3
  485. package/dist/simulation/memory/filesystem.d.ts +2 -0
  486. package/dist/simulation/memory/filesystem.js +5 -1
  487. package/dist/simulation/memory/filesystem_file_tree.d.ts +4 -1
  488. package/dist/simulation/memory/filesystem_file_tree.js +41 -10
  489. package/dist/simulation/memory/filesystem_invariants.js +1 -2
  490. package/dist/simulation/memory/filesystem_types.d.ts +1 -0
  491. package/dist/simulation/memory/memory.d.ts +2 -0
  492. package/dist/simulation/memory/memory.js +5 -1
  493. package/dist/simulation/orchestration/intent.js +0 -2
  494. package/dist/simulation/orchestration/lifecycle.js +0 -2
  495. package/dist/simulation/plugin_host.d.ts +25 -1
  496. package/dist/simulation/plugin_host.js +334 -17
  497. package/dist/simulation/session_documents.d.ts +20 -0
  498. package/dist/simulation/session_documents.js +62 -0
  499. package/dist/simulation/session_input_validation.d.ts +43 -0
  500. package/dist/simulation/session_input_validation.js +364 -0
  501. package/dist/simulation/session_inputs.d.ts +32 -0
  502. package/dist/simulation/session_inputs.js +154 -0
  503. package/dist/simulation/telemetry.d.ts +11 -14
  504. package/dist/simulation/telemetry.js +177 -54
  505. package/dist/simulation/toolkit/bounded_turns.d.ts +13 -0
  506. package/dist/simulation/toolkit/bounded_turns.js +80 -0
  507. package/dist/simulation/toolkit/dynamic_agents.d.ts +25 -0
  508. package/dist/simulation/toolkit/dynamic_agents.js +218 -0
  509. package/dist/simulation/toolkit/dynamic_digest.d.ts +1 -0
  510. package/dist/simulation/toolkit/dynamic_digest.js +8 -0
  511. package/dist/simulation/toolkit/dynamic_documents.d.ts +7 -0
  512. package/dist/simulation/toolkit/dynamic_documents.js +71 -0
  513. package/dist/simulation/toolkit/dynamic_driver.d.ts +8 -0
  514. package/dist/simulation/toolkit/dynamic_driver.js +269 -0
  515. package/dist/simulation/toolkit/dynamic_game.d.ts +53 -0
  516. package/dist/simulation/toolkit/dynamic_game.js +805 -0
  517. package/dist/simulation/toolkit/dynamic_knowledge.d.ts +15 -0
  518. package/dist/simulation/toolkit/dynamic_knowledge.js +91 -0
  519. package/dist/simulation/toolkit/dynamic_mechanics.d.ts +22 -0
  520. package/dist/simulation/toolkit/dynamic_mechanics.js +910 -0
  521. package/dist/simulation/toolkit/dynamic_meetings.d.ts +239 -0
  522. package/dist/simulation/toolkit/dynamic_meetings.js +350 -0
  523. package/dist/simulation/toolkit/dynamic_progress.d.ts +131 -0
  524. package/dist/simulation/toolkit/dynamic_progress.js +214 -0
  525. package/dist/simulation/toolkit/dynamic_projection.d.ts +9 -0
  526. package/dist/simulation/toolkit/dynamic_projection.js +219 -0
  527. package/dist/simulation/toolkit/dynamic_runtime.d.ts +412 -0
  528. package/dist/simulation/toolkit/dynamic_runtime.js +6536 -0
  529. package/dist/simulation/toolkit/dynamic_state.d.ts +111 -0
  530. package/dist/simulation/toolkit/dynamic_state.js +1967 -0
  531. package/dist/simulation/toolkit/dynamic_story_review.d.ts +508 -0
  532. package/dist/simulation/toolkit/dynamic_story_review.js +333 -0
  533. package/dist/simulation/toolkit/dynamic_storyteller.d.ts +77 -0
  534. package/dist/simulation/toolkit/dynamic_storyteller.js +114 -0
  535. package/dist/simulation/toolkit/dynamic_storyteller_runtime.d.ts +26 -0
  536. package/dist/simulation/toolkit/dynamic_storyteller_runtime.js +126 -0
  537. package/dist/simulation/toolkit/dynamic_world.d.ts +22 -0
  538. package/dist/simulation/toolkit/dynamic_world.js +377 -0
  539. package/dist/simulation/toolkit/structured_output.d.ts +5 -0
  540. package/dist/simulation/toolkit/structured_output.js +321 -0
  541. package/dist/simulation/types/world.d.ts +2 -0
  542. package/dist/simulation/world/artifact_store.js +1 -1
  543. package/dist/simulation/world/memory_manager.d.ts +5 -0
  544. package/dist/simulation/world/memory_manager.js +17 -2
  545. package/dist/simulation/world/state.d.ts +3 -2
  546. package/dist/simulation/world/state.js +15 -5
  547. package/dist/skills/bundled/measurement-validation/SKILL.md +144 -0
  548. package/dist/terminal_attach.d.ts +1 -0
  549. package/dist/terminal_attach.js +113 -0
  550. package/dist/tool_progress.d.ts +3 -0
  551. package/dist/tool_progress.js +27 -0
  552. package/dist/types.d.ts +145 -10
  553. package/dist/types.js +3 -0
  554. package/dist/ui/core/input.d.ts +3 -0
  555. package/dist/ui/core/input_segments.d.ts +18 -1
  556. package/dist/ui/core/input_segments.js +131 -47
  557. package/dist/ui/core/input_state.d.ts +12 -0
  558. package/dist/ui/core/layout_yoga.d.ts +1 -1
  559. package/dist/ui/core/turn_metadata.d.ts +5 -0
  560. package/dist/ui/core/turn_metadata.js +22 -0
  561. package/dist/ui/ink/render.d.ts +2 -1
  562. package/dist/ui/ink/render.js +6 -5
  563. package/dist/ui/ratatui/headless_pane_manager.d.ts +14 -1
  564. package/dist/ui/ratatui/headless_pane_manager.js +293 -104
  565. package/dist/ui/ratatui/index.d.ts +1 -0
  566. package/dist/ui/ratatui/input.d.ts +4 -0
  567. package/dist/ui/ratatui/input.js +15 -0
  568. package/dist/ui/ratatui/ipc_path.d.ts +2 -0
  569. package/dist/ui/ratatui/ipc_path.js +29 -1
  570. package/dist/ui/ratatui/mux_persistence.d.ts +3 -1
  571. package/dist/ui/ratatui/mux_persistence.js +139 -1
  572. package/dist/ui/ratatui/pane_relay.d.ts +1 -1
  573. package/dist/ui/ratatui/pane_relay.js +55 -27
  574. package/dist/ui/ratatui/process.d.ts +17 -1
  575. package/dist/ui/ratatui/process.js +80 -7
  576. package/dist/ui/ratatui/protocol.d.ts +236 -1
  577. package/dist/ui/ratatui/protocol.js +90 -0
  578. package/dist/ui/scrollback.d.ts +2 -1
  579. package/dist/ui/scrollback.js +9 -4
  580. package/dist/ui/stream_typewriter.d.ts +8 -3
  581. package/dist/ui/stream_typewriter.js +30 -1
  582. package/dist/ui/streaming_scrollback.d.ts +1 -0
  583. package/dist/ui/streaming_scrollback.js +1 -1
  584. package/dist/ui/transcript_render_cache.js +10 -0
  585. package/dist/ui/views/activity_line.d.ts +5 -3
  586. package/dist/ui/views/activity_line.js +65 -7
  587. package/dist/ui/views/app.d.ts +6 -3
  588. package/dist/ui/views/app.js +17 -6
  589. package/dist/ui/views/completion_menu.js +10 -5
  590. package/dist/ui/views/input_area.d.ts +7 -3
  591. package/dist/ui/views/input_area.js +15 -9
  592. package/dist/ui/views/message_list.d.ts +4 -1
  593. package/dist/ui/views/message_list.js +89 -19
  594. package/dist/ui/views/queue_panel.d.ts +3 -1
  595. package/dist/ui/views/queue_panel.js +9 -2
  596. package/dist/ui/views/status_bar.d.ts +4 -2
  597. package/dist/ui/views/status_bar.js +28 -13
  598. package/dist/ui/views/theme.d.ts +2 -0
  599. package/dist/ui/views/theme.js +2 -0
  600. package/dist/ui/widgets/color_panel.js +18 -0
  601. package/dist/ui/widgets/form.js +8 -0
  602. package/dist/ui/widgets/log_view.js +7 -0
  603. package/dist/ui/widgets/navigator_panel.js +8 -0
  604. package/dist/ui/widgets/prompt_viewer.js +2 -0
  605. package/dist/ui/widgets/questionnaire.d.ts +2 -0
  606. package/dist/ui/widgets/questionnaire.js +79 -16
  607. package/dist/ui/widgets/resume_panel.d.ts +2 -0
  608. package/dist/ui/widgets/resume_panel.js +26 -15
  609. package/dist/ui/widgets/rewind_panel.d.ts +2 -2
  610. package/dist/ui/widgets/rewind_panel.js +4 -2
  611. package/dist/ui/widgets/select.js +16 -27
  612. package/dist/ui/widgets/settings_panel.js +16 -0
  613. package/dist/ui/widgets/status_line_panel.d.ts +1 -0
  614. package/dist/ui/widgets/status_line_panel.js +30 -4
  615. package/dist/ui/widgets/text_input.d.ts +2 -0
  616. package/dist/ui/widgets/text_input.js +15 -1
  617. package/dist/ui/widgets/types.d.ts +2 -0
  618. package/dist/usage_projection.d.ts +24 -0
  619. package/dist/usage_projection.js +130 -0
  620. package/dist/usage_snapshot.d.ts +36 -0
  621. package/dist/usage_snapshot.js +131 -0
  622. package/dist/utils/assistant_message.d.ts +2 -0
  623. package/dist/utils/assistant_message.js +5 -0
  624. package/dist/utils/atomic_write.d.ts +6 -2
  625. package/dist/utils/atomic_write.js +29 -4
  626. package/dist/utils/checked_shell.d.ts +25 -0
  627. package/dist/utils/checked_shell.js +107 -0
  628. package/dist/utils/compaction.d.ts +4 -1
  629. package/dist/utils/compaction.js +31 -7
  630. package/dist/utils/context.d.ts +4 -4
  631. package/dist/utils/context.js +14 -12
  632. package/dist/utils/deepseek.d.ts +2 -2
  633. package/dist/utils/deepseek.js +13 -5
  634. package/dist/utils/ephemeral.js +4 -0
  635. package/dist/utils/ephemeral_tools.d.ts +18 -0
  636. package/dist/utils/ephemeral_tools.js +97 -0
  637. package/dist/utils/jev_client.d.ts +4 -0
  638. package/dist/utils/jev_client.js +15 -0
  639. package/dist/utils/model_cache.d.ts +15 -0
  640. package/dist/utils/model_cache.js +143 -0
  641. package/dist/utils/models.d.ts +4 -2
  642. package/dist/utils/models.js +12 -16
  643. package/dist/utils/reasoning.d.ts +8 -1
  644. package/dist/utils/reasoning.js +31 -11
  645. package/dist/utils/router_catalog.d.ts +49 -0
  646. package/dist/utils/router_catalog.js +271 -0
  647. package/dist/utils/sandbox.d.ts +9 -0
  648. package/dist/utils/sandbox.js +118 -15
  649. package/dist/utils/shell.d.ts +7 -0
  650. package/dist/utils/shell.js +98 -34
  651. package/dist/utils/subprocess_env.d.ts +3 -0
  652. package/dist/utils/subprocess_env.js +27 -1
  653. package/dist/web/accounts_mirror.d.ts +3 -1
  654. package/dist/web/accounts_mirror.js +13 -9
  655. package/dist/web/child_publication.d.ts +17 -0
  656. package/dist/web/child_publication.js +45 -0
  657. package/dist/web/mirror_authenticator.d.ts +31 -11
  658. package/dist/web/mirror_authenticator.js +67 -17
  659. package/dist/web/mirror_client.d.ts +31 -4
  660. package/dist/web/mirror_client.js +189 -23
  661. package/dist/web/mirror_stream.d.ts +84 -22
  662. package/dist/web/mirror_stream.js +676 -95
  663. package/dist/web/observer_query_redaction.d.ts +6 -0
  664. package/dist/web/observer_query_redaction.js +58 -0
  665. package/dist/web/pane_registry.d.ts +2 -0
  666. package/dist/web/pane_registry.js +86 -22
  667. package/dist/web/tool_image.d.ts +6 -0
  668. package/dist/web/tool_image.js +17 -0
  669. package/dist/web/view_plugin.d.ts +14 -0
  670. package/dist/web/view_plugin.js +23 -1
  671. package/dist/worker/executor.js +31 -12
  672. package/dist/worker/index.d.ts +1 -0
  673. package/dist/worker/toolsets.js +3 -1
  674. package/dist/worker/types.d.ts +12 -1
  675. package/dist/workflows/registry.js +1 -0
  676. package/dist/workflows/registry_handle.d.ts +2 -0
  677. package/dist/workflows/runtime.d.ts +2 -0
  678. package/dist/workflows/runtime.js +1 -0
  679. package/dist/workspace_agent.d.ts +7 -0
  680. package/dist/workspace_agent.js +36 -0
  681. package/dist/workspace_collision.d.ts +76 -0
  682. package/dist/workspace_collision.js +688 -0
  683. package/dist/workspace_layout.d.ts +18 -0
  684. package/dist/workspace_layout.js +121 -0
  685. package/dist/workspace_runtime.d.ts +44 -0
  686. package/dist/workspace_runtime.js +82 -0
  687. package/dist/workspace_session_context.d.ts +62 -0
  688. package/dist/workspace_session_context.js +160 -0
  689. package/dist/zlm-embed.mjs +32518 -9615
  690. package/dist/zlm.js +1 -0
  691. package/node_modules/@zerg/model-contracts/LICENSE.md +375 -0
  692. package/node_modules/@zerg/model-contracts/README.md +90 -0
  693. package/node_modules/@zerg/model-contracts/index.d.ts +20 -0
  694. package/node_modules/@zerg/model-contracts/index.js +223 -0
  695. package/node_modules/@zerg/model-contracts/package.json +8 -0
  696. package/node_modules/glob/node_modules/brace-expansion/index.js +78 -22
  697. package/node_modules/glob/node_modules/brace-expansion/package.json +1 -1
  698. package/node_modules/readdir-glob/node_modules/brace-expansion/index.js +78 -22
  699. package/node_modules/readdir-glob/node_modules/brace-expansion/package.json +1 -1
  700. package/package.json +45 -24
  701. package/packages/model-contracts/LICENSE.md +375 -0
  702. package/packages/model-contracts/README.md +90 -0
  703. package/packages/model-contracts/index.d.ts +20 -0
  704. package/packages/model-contracts/index.js +223 -0
  705. package/packages/model-contracts/package.json +8 -0
  706. package/remote-broker/Dockerfile +10 -0
  707. package/remote-broker/README.md +308 -0
  708. package/remote-broker/archive.py +1227 -0
  709. package/remote-broker/cutover.py +761 -0
  710. package/remote-broker/requirements.txt +5 -0
  711. package/remote-broker/resources.example.json +6 -0
  712. package/remote-broker/resources.write-staging.example.json +18 -0
  713. package/remote-broker/retained.py +686 -0
  714. package/remote-broker/retained_cleanup.py +550 -0
  715. package/remote-broker/server.py +648 -0
  716. package/scripts/build-remote-broker.mjs +13 -0
  717. package/scripts/ensure-local-packages.mjs +6 -0
  718. package/scripts/node-pty-helpers.mjs +103 -0
@@ -1,4 +1,6 @@
1
1
  /** Private adapter from the public simulation plugin contract to the ZTC kernel. */
2
+ import { createRequire } from 'node:module';
3
+ import { CODEX_REASONING_EFFORTS } from '../config/types.js';
2
4
  import { SIMULATION_PLUGIN_API_VERSION } from '../plugin/simulation_contract.js';
3
5
  import { llmComplete, SimulationAbortedError } from './llm.js';
4
6
  import { getOrchestrator, registerOrchestrator, } from './orchestration/registry.js';
@@ -6,17 +8,28 @@ import { registerSimulationRuntimeBinding } from './runtime_bindings.js';
6
8
  import { DEFAULT_SIM_CONFIG } from './types.js';
7
9
  import { SIMULATION_CHECKPOINT_VERSION, } from './world/checkpoint.js';
8
10
  import { SimState, getSimState, setSimState } from './world/state.js';
11
+ import { validateDocumentWrite, validateSessionDocuments } from './session_documents.js';
9
12
  import { getVersion } from '../utils/version.js';
13
+ const require = createRequire(import.meta.url);
14
+ const dynamicStateToolkit = () => require('./toolkit/dynamic_state.js');
15
+ const inputValidation = () => require('./session_input_validation.js');
10
16
  const HOST_VERSION = getVersion();
11
17
  const HOST_CHECKPOINT_NAMESPACE = 'ztc.host';
12
18
  const HOST_CAPABILITIES = Object.freeze([
13
19
  'atomic-transitions',
14
20
  'checkpoint-extensions',
21
+ 'dynamic-state',
15
22
  'notifications',
23
+ 'per-request-inference-routing',
24
+ 'player-commands',
16
25
  'provider-inference',
26
+ 'simulation-catalog',
17
27
  ]);
18
28
  const MAX_RETAINED_SESSIONS = 32;
29
+ const MAX_PLAYER_COMMAND_BYTES = 16_384;
30
+ const MAX_PLAYER_COMMAND_IDS = 256;
19
31
  const registrations = new Map();
32
+ const definitions = new Map();
20
33
  const sessions = new Map();
21
34
  const activeDrivers = new Map();
22
35
  const startSignals = new Map();
@@ -89,6 +102,83 @@ function assertCreateRequest(request) {
89
102
  throw new Error('Simulation startTime must be an ISO date');
90
103
  }
91
104
  }
105
+ function assertNonEmptyBoundedString(name, value, maximum) {
106
+ const length = value.trim().length;
107
+ if (length === 0 || length > maximum) {
108
+ throw new RangeError(`${name} must contain from 1 to ${maximum} characters`);
109
+ }
110
+ }
111
+ function assertDefinition(definition, kind, maximumTurns = 100) {
112
+ if (definition.kind !== kind) {
113
+ throw new Error(`Simulation definition kind ${definition.kind} must match driver ${kind}`);
114
+ }
115
+ assertNonEmptyBoundedString('Simulation definition title', definition.title, 80);
116
+ assertNonEmptyBoundedString('Simulation definition summary', definition.summary, 400);
117
+ assertNonEmptyBoundedString('Simulation definition objective', definition.objective, 400);
118
+ if (!Number.isSafeInteger(definition.maxTurns) || definition.maxTurns < 1 || definition.maxTurns > maximumTurns) {
119
+ throw new RangeError(`Simulation definition maxTurns must be an integer from 1 to ${maximumTurns}`);
120
+ }
121
+ if (!Number.isSafeInteger(definition.estimatedMinutes)
122
+ || definition.estimatedMinutes < 1
123
+ || definition.estimatedMinutes > 1_440) {
124
+ throw new RangeError('Simulation definition estimatedMinutes must be an integer from 1 to 1440');
125
+ }
126
+ for (const [name, values, maximum] of [
127
+ ['playerRoles', definition.playerRoles, 16],
128
+ ['mechanics', definition.mechanics, 64],
129
+ ]) {
130
+ if (values.length === 0 || values.length > maximum) {
131
+ throw new RangeError(`Simulation definition ${name} must contain from 1 to ${maximum} values`);
132
+ }
133
+ for (const value of values) {
134
+ assertNonEmptyBoundedString(`Simulation definition ${name} value`, value, 80);
135
+ }
136
+ if (new Set(values).size !== values.length) {
137
+ throw new Error(`Simulation definition ${name} must not contain duplicates`);
138
+ }
139
+ }
140
+ }
141
+ function cloneDefinition(definition) {
142
+ return {
143
+ ...definition,
144
+ playerRoles: [...definition.playerRoles],
145
+ mechanics: [...definition.mechanics],
146
+ };
147
+ }
148
+ function parsePlayerCommand(value) {
149
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
150
+ throw new TypeError('Simulation player command must be an object');
151
+ }
152
+ const candidate = value;
153
+ if (typeof candidate.commandId !== 'string') {
154
+ throw new TypeError('Simulation player command commandId must be a string');
155
+ }
156
+ if (typeof candidate.kind !== 'string') {
157
+ throw new TypeError('Simulation player command kind must be a string');
158
+ }
159
+ assertNonEmptyBoundedString('Simulation player command commandId', candidate.commandId, 200);
160
+ assertNonEmptyBoundedString('Simulation player command kind', candidate.kind, 120);
161
+ if (candidate.actorId !== undefined
162
+ && (typeof candidate.actorId !== 'string' || candidate.actorId.trim().length === 0)) {
163
+ throw new TypeError('Simulation player command actorId must be a non-empty string');
164
+ }
165
+ if (candidate.payload === null
166
+ || typeof candidate.payload !== 'object'
167
+ || Array.isArray(candidate.payload)) {
168
+ throw new TypeError('Simulation player command payload must be an object');
169
+ }
170
+ const serialized = JSON.stringify(candidate);
171
+ if (serialized === undefined || Buffer.byteLength(serialized, 'utf8') > MAX_PLAYER_COMMAND_BYTES) {
172
+ throw new RangeError(`Simulation player command must be at most ${MAX_PLAYER_COMMAND_BYTES} bytes`);
173
+ }
174
+ const parsed = JSON.parse(serialized);
175
+ return {
176
+ commandId: parsed.commandId,
177
+ kind: parsed.kind,
178
+ ...(parsed.actorId === undefined ? {} : { actorId: parsed.actorId }),
179
+ payload: parsed.payload,
180
+ };
181
+ }
92
182
  function driverKindForState(state) {
93
183
  return state.config.runtimeBinding?.kind ?? state.config.orchestration ?? 'gamemaster';
94
184
  }
@@ -98,9 +188,28 @@ function makeSessionRecord(state, requestedDriverKind) {
98
188
  const restoredPluginData = hostExtension?.data.pluginData;
99
189
  const restoredRevision = hostExtension?.data.revision;
100
190
  const restoredActorMetadata = hostExtension?.data.actorMetadata;
101
- return {
191
+ const restoredPlayerCommandIds = hostExtension?.data.submittedPlayerCommandIds;
192
+ const restoredPendingPlayerCommand = hostExtension?.data.pendingPlayerCommand;
193
+ const restoredDynamicState = hostExtension?.data.dynamicState;
194
+ const driverKind = requestedDriverKind ?? driverKindForState(state);
195
+ const revision = typeof restoredRevision === 'number'
196
+ && Number.isSafeInteger(restoredRevision)
197
+ && restoredRevision >= 0
198
+ ? restoredRevision
199
+ : 0;
200
+ const dynamicState = restoredDynamicState === undefined || restoredDynamicState === null
201
+ ? null
202
+ : dynamicStateToolkit().parseDynamicSimulationState(restoredDynamicState);
203
+ if (dynamicState !== null
204
+ && (dynamicState.gameKind !== driverKind || dynamicState.revision !== revision)) {
205
+ throw new Error('Checkpoint dynamic state does not match its host revision or driver');
206
+ }
207
+ validateRegisteredDynamicState(dynamicState, driverKind);
208
+ const record = {
102
209
  state,
103
- driverKind: requestedDriverKind ?? driverKindForState(state),
210
+ inputJournal: hostExtension?.data.inputJournal === undefined ? undefined : inputValidation().parseInputJournal(hostExtension.data.inputJournal),
211
+ lastTransition: null,
212
+ driverKind,
104
213
  appliedTransitions: new Set(Array.isArray(restoredIds)
105
214
  ? restoredIds.filter((value) => typeof value === 'string')
106
215
  : []),
@@ -110,18 +219,30 @@ function makeSessionRecord(state, requestedDriverKind) {
110
219
  ? Object.entries(restoredActorMetadata)
111
220
  .filter((entry) => (entry[1] !== null && typeof entry[1] === 'object' && !Array.isArray(entry[1])))
112
221
  : []),
222
+ submittedPlayerCommandIds: new Set(Array.isArray(restoredPlayerCommandIds)
223
+ ? restoredPlayerCommandIds
224
+ .filter((value) => typeof value === 'string')
225
+ .slice(-MAX_PLAYER_COMMAND_IDS)
226
+ : []),
227
+ pendingPlayerCommand: restoredPendingPlayerCommand === undefined
228
+ || restoredPendingPlayerCommand === null
229
+ ? null
230
+ : parsePlayerCommand(restoredPendingPlayerCommand),
231
+ dynamicState,
113
232
  pluginData: restoredPluginData !== null
114
233
  && typeof restoredPluginData === 'object'
115
234
  && !Array.isArray(restoredPluginData)
116
235
  ? structuredClone(restoredPluginData)
117
236
  : {},
118
237
  status: 'ready',
119
- revision: typeof restoredRevision === 'number'
120
- && Number.isSafeInteger(restoredRevision)
121
- && restoredRevision >= 0
122
- ? restoredRevision
123
- : 0,
238
+ revision,
124
239
  };
240
+ if (record.inputJournal)
241
+ inputValidation().validateSessionInputSnapshot(toSnapshot(record));
242
+ else
243
+ validateSessionDocuments(toSnapshot(record));
244
+ validateRegisteredDocuments(record);
245
+ return record;
125
246
  }
126
247
  function ensureSessionRecord(state, requestedDriverKind) {
127
248
  const existing = sessions.get(state.id);
@@ -149,6 +270,8 @@ function requireSessionRecord(ref) {
149
270
  }
150
271
  function toDocumentSnapshot(document) {
151
272
  return {
273
+ ...(document.provenance === undefined ? {} : { provenance: structuredClone(document.provenance) }),
274
+ ...(document.ownerActorId === undefined ? {} : { ownerActorId: document.ownerActorId }),
152
275
  documentId: document.id,
153
276
  label: document.label,
154
277
  type: document.type,
@@ -185,6 +308,7 @@ function toSnapshot(record) {
185
308
  })
186
309
  : null;
187
310
  return {
311
+ ...(record.inputJournal === undefined ? {} : { inputJournal: structuredClone(record.inputJournal) }),
188
312
  ref: sessionRef(record),
189
313
  status: record.status,
190
314
  revision: record.revision,
@@ -203,6 +327,9 @@ function toSnapshot(record) {
203
327
  })),
204
328
  documents: state.getDocumentTrail().map(toDocumentSnapshot),
205
329
  world,
330
+ dynamicState: record.dynamicState === null
331
+ ? null
332
+ : structuredClone(record.dynamicState),
206
333
  pluginData: asJsonObject(record.pluginData),
207
334
  };
208
335
  }
@@ -279,7 +406,11 @@ function applyOperation(record, operation) {
279
406
  });
280
407
  return;
281
408
  case 'document.write':
409
+ if (operation.ownerActorId !== undefined)
410
+ validateDocumentWrite(toSnapshot(record), operation);
282
411
  record.state.addDocument({
412
+ ...(operation.provenance === undefined ? {} : { provenance: structuredClone(operation.provenance) }),
413
+ ...(operation.ownerActorId === undefined ? {} : { ownerActorId: operation.ownerActorId }),
283
414
  type: operation.documentType,
284
415
  label: operation.label,
285
416
  content: operation.content,
@@ -289,6 +420,11 @@ function applyOperation(record, operation) {
289
420
  revisionOf: operation.revisionOf,
290
421
  });
291
422
  return;
423
+ case 'session-inputs.resolve':
424
+ if (!record.inputJournal)
425
+ throw new Error('Session inputs are unavailable');
426
+ record.inputJournal.resolutions.push(...structuredClone(operation.resolutions));
427
+ return;
292
428
  case 'document.comment': {
293
429
  const result = record.state.addDocumentComment(operation.label, operation.author, operation.text, operation.authorActorId, operation.parentId, operation.sectionRef);
294
430
  if (!result.ok) {
@@ -298,10 +434,51 @@ function applyOperation(record, operation) {
298
434
  }
299
435
  case 'plugin-data.set':
300
436
  record.pluginData[operation.namespace] = asJsonObject(operation.value);
437
+ return;
438
+ case 'dynamic-state.commit': {
439
+ const next = dynamicStateToolkit().validateDynamicStateTransition({
440
+ previous: record.dynamicState,
441
+ next: operation.state,
442
+ driverKind: record.driverKind,
443
+ hostRevision: record.revision,
444
+ });
445
+ validateRegisteredDynamicState(next, record.driverKind);
446
+ if (next.history.at(-1)?.objectGraphBefore === undefined) {
447
+ throw new Error('A new dynamic state commit requires action-time context');
448
+ }
449
+ record.dynamicState = next;
450
+ return;
451
+ }
301
452
  }
302
453
  }
303
- function restoreTransitionMetadata(record, pluginData, revision, appliedTransitions) {
454
+ const detachedValidators = new Map();
455
+ /** Register canonical checkpoint validators without loading a driver or claiming its inference boundary. */
456
+ export function registerSimulationCheckpointValidators(kind, validators) {
457
+ if (!kind.trim() || !validators.validateDynamicState || !validators.validateDocuments)
458
+ throw new Error('Checkpoint validators require a kind and both canonical validators');
459
+ detachedValidators.set(kind, validators);
460
+ }
461
+ function validateRegisteredDynamicState(state, driverKind) {
462
+ if (state === null)
463
+ return;
464
+ const validate = registrations.get(driverKind)?.validateDynamicState ?? detachedValidators.get(driverKind)?.validateDynamicState;
465
+ if (validate === undefined && state.initialization === null)
466
+ return;
467
+ if (validate === undefined)
468
+ throw new Error('Dynamic policy validator is unavailable');
469
+ validate(state);
470
+ }
471
+ function validateRegisteredDocuments(record) {
472
+ const validate = registrations.get(record.driverKind)?.validateDocuments ?? detachedValidators.get(record.driverKind)?.validateDocuments;
473
+ const initialization = record.dynamicState?.initialization;
474
+ if (initialization?.version === 2 && initialization.documents && !validate) {
475
+ throw new Error('Document policy validator is unavailable');
476
+ }
477
+ validate?.(toSnapshot(record));
478
+ }
479
+ function restoreTransitionMetadata(record, pluginData, dynamicState, revision, appliedTransitions) {
304
480
  record.pluginData = pluginData;
481
+ record.dynamicState = dynamicState;
305
482
  record.revision = revision;
306
483
  record.appliedTransitions.clear();
307
484
  for (const key of appliedTransitions)
@@ -314,26 +491,48 @@ async function applyTransition(record, batch) {
314
491
  if (batch.expectedRevision !== record.revision) {
315
492
  throw new Error(`Simulation transition expected revision ${batch.expectedRevision}; current revision is ${record.revision}`);
316
493
  }
494
+ if (record.inputJournal || batch.operations.some(operation => operation.operation === 'session-inputs.resolve')) {
495
+ inputValidation().validateInputTransition(toSnapshot(record), batch);
496
+ }
497
+ const advanceTimeSteps = batch.advanceTimeSteps ?? 1;
498
+ if (!Number.isSafeInteger(advanceTimeSteps) || advanceTimeSteps < 1 || advanceTimeSteps > 12) {
499
+ throw new RangeError('Simulation advanceTimeSteps must be an integer from 1 to 12');
500
+ }
501
+ const dynamicCommits = batch.operations.filter(operation => (operation.operation === 'dynamic-state.commit')).length;
502
+ if ((record.dynamicState !== null || dynamicCommits > 0) && dynamicCommits !== 1) {
503
+ throw new Error('A dynamic transition must contain exactly one dynamic state commit');
504
+ }
317
505
  const joinedPeriod = record.state.getActiveWorldTransitionPeriodNumber();
318
506
  if (joinedPeriod !== null) {
319
507
  if (batch.periodNumber !== undefined && batch.periodNumber !== joinedPeriod) {
320
508
  throw new Error(`Simulation transition period ${batch.periodNumber} does not match active world period ${joinedPeriod}`);
321
509
  }
510
+ const inputsBefore = structuredClone(record.inputJournal);
511
+ const lastTransitionBefore = record.lastTransition;
322
512
  const pluginDataBefore = structuredClone(record.pluginData);
513
+ const dynamicStateBefore = record.dynamicState === null
514
+ ? null
515
+ : structuredClone(record.dynamicState);
323
516
  const revisionBefore = record.revision;
324
517
  const appliedTransitionsBefore = new Set(record.appliedTransitions);
325
518
  try {
326
519
  for (const operation of batch.operations)
327
520
  applyOperation(record, operation);
521
+ validateRegisteredDocuments(record);
328
522
  record.revision += 1;
329
523
  record.appliedTransitions.add(batch.idempotencyKey);
524
+ record.lastTransition = structuredClone(batch);
330
525
  record.state.registerWorldTransitionRollback(() => {
331
- restoreTransitionMetadata(record, pluginDataBefore, revisionBefore, appliedTransitionsBefore);
526
+ record.inputJournal = inputsBefore;
527
+ record.lastTransition = lastTransitionBefore;
528
+ restoreTransitionMetadata(record, pluginDataBefore, dynamicStateBefore, revisionBefore, appliedTransitionsBefore);
332
529
  });
333
530
  return { applied: true, revision: record.revision };
334
531
  }
335
532
  catch (error) {
336
- restoreTransitionMetadata(record, pluginDataBefore, revisionBefore, appliedTransitionsBefore);
533
+ record.inputJournal = inputsBefore;
534
+ record.lastTransition = lastTransitionBefore;
535
+ restoreTransitionMetadata(record, pluginDataBefore, dynamicStateBefore, revisionBefore, appliedTransitionsBefore);
337
536
  throw error;
338
537
  }
339
538
  }
@@ -345,21 +544,31 @@ async function applyTransition(record, batch) {
345
544
  }
346
545
  }
347
546
  const pluginDataBefore = structuredClone(record.pluginData);
547
+ const inputJournalBefore = structuredClone(record.inputJournal);
548
+ const dynamicStateBefore = record.dynamicState === null
549
+ ? null
550
+ : structuredClone(record.dynamicState);
348
551
  const proposal = record.state.beginWorldTransition(batch.kind, batch.periodNumber);
349
552
  try {
350
553
  if (batch.periodNumber !== undefined) {
351
554
  record.state.setRuntimePeriodNumber(batch.periodNumber);
352
- record.state.advanceTime();
555
+ for (let step = 0; step < advanceTimeSteps; step += 1) {
556
+ record.state.advanceTime();
557
+ }
353
558
  }
354
559
  for (const operation of batch.operations)
355
560
  applyOperation(record, operation);
561
+ validateRegisteredDocuments(record);
356
562
  record.state.commitWorldTransition(proposal.id);
357
563
  record.revision += 1;
358
564
  record.appliedTransitions.add(batch.idempotencyKey);
565
+ record.lastTransition = structuredClone(batch);
359
566
  return { applied: true, revision: record.revision };
360
567
  }
361
568
  catch (error) {
569
+ record.inputJournal = inputJournalBefore;
362
570
  record.pluginData = pluginDataBefore;
571
+ record.dynamicState = dynamicStateBefore;
363
572
  record.state.rollbackWorldTransition(proposal.id, error);
364
573
  if (previousPeriod === null)
365
574
  record.state.clearRuntimePeriodNumber();
@@ -386,9 +595,33 @@ function hostCheckpointExtension(record) {
386
595
  appliedTransitionIds: [...record.appliedTransitions].sort(),
387
596
  pluginData: record.pluginData,
388
597
  actorMetadata: Object.fromEntries(record.actorMetadata),
598
+ submittedPlayerCommandIds: [...record.submittedPlayerCommandIds].sort(),
599
+ pendingPlayerCommand: record.pendingPlayerCommand === null
600
+ ? null
601
+ : asJsonObject(record.pendingPlayerCommand),
602
+ dynamicState: record.dynamicState === null
603
+ ? null
604
+ : asJsonObject(record.dynamicState),
605
+ ...(record.inputJournal === undefined ? {} : { inputJournal: asJsonObject(record.inputJournal) }),
389
606
  },
390
607
  };
391
608
  }
609
+ export async function detachedSessionRecord(checkpoint) {
610
+ return makeSessionRecord(await SimState.fromCheckpoint(structuredClone(checkpoint), undefined, true));
611
+ }
612
+ export function detachedSessionSnapshot(record) {
613
+ return toSnapshot(record);
614
+ }
615
+ export function detachedSessionCheckpoint(record, source) {
616
+ const extensions = source.extensions;
617
+ return asJsonObject(record.state.createCheckpoint({ ...extensions, [HOST_CHECKPOINT_NAMESPACE]: hostCheckpointExtension(record) }));
618
+ }
619
+ export async function applyDetachedSessionTransition(record, batch) {
620
+ await applyTransition(record, batch);
621
+ }
622
+ export function getOriginalSessionTransition(ref) {
623
+ return structuredClone(requireSessionRecord(ref).lastTransition);
624
+ }
392
625
  export function saveSimulationSessionCheckpoint(state, outputPath) {
393
626
  const record = ensureSessionRecord(state);
394
627
  return state.saveCheckpoint(outputPath, {
@@ -432,7 +665,7 @@ async function loadRegisteredDriver(kind) {
432
665
  }
433
666
  return driver;
434
667
  }
435
- function createDriverContext(record, controller, notify) {
668
+ function createDriverContext(record, controller, notify, playerCommand = null) {
436
669
  const requireActiveAuthority = () => {
437
670
  const active = activeDrivers.get(record.state.id);
438
671
  if (record.status !== 'running'
@@ -449,6 +682,7 @@ function createDriverContext(record, controller, notify) {
449
682
  return applyTransition(record, batch);
450
683
  },
451
684
  },
685
+ playerCommand: playerCommand === null ? null : parsePlayerCommand(playerCommand),
452
686
  signal: controller.signal,
453
687
  notify,
454
688
  completeInference: (request) => {
@@ -458,6 +692,14 @@ function createDriverContext(record, controller, notify) {
458
692
  };
459
693
  }
460
694
  async function completeInference(request, signal) {
695
+ const routing = request.routing;
696
+ if (routing !== undefined && (routing === null || typeof routing !== 'object'
697
+ || !['character', 'game-master'].includes(routing.role)
698
+ || typeof routing.provider !== 'string' || !routing.provider.trim()
699
+ || typeof routing.model !== 'string' || !routing.model.trim()
700
+ || !CODEX_REASONING_EFFORTS.includes(routing.reasoningEffort)
701
+ || (routing.serviceTier !== undefined && routing.serviceTier !== 'priority')))
702
+ throw new Error('Invalid simulation inference route');
461
703
  const text = await llmComplete(request.system, request.user, request.maxTokens, request.timeoutMs, {
462
704
  stage: request.context.stage,
463
705
  periodNumber: request.context.periodNumber,
@@ -466,7 +708,14 @@ async function completeInference(request, signal) {
466
708
  requestId: request.context.requestId,
467
709
  component: request.context.component,
468
710
  attempt: request.context.attempt,
469
- }, signal);
711
+ }, signal, routing === undefined
712
+ ? undefined
713
+ : {
714
+ provider: routing.provider,
715
+ model: routing.model,
716
+ codexEffort: routing.reasoningEffort,
717
+ codexFastMode: routing.serviceTier === 'priority',
718
+ }, undefined, request.outputSchema, request.outputSchemaStrict, request.bufferedRecovery === undefined ? undefined : { ...request.bufferedRecovery, onAttempt: request.onTransportAttempt });
470
719
  return { text };
471
720
  }
472
721
  function pruneSessionRecords() {
@@ -501,7 +750,8 @@ async function makePrivateOrchestrator(kind) {
501
750
  if (notification.type === 'progress')
502
751
  onProgress(notification.message);
503
752
  };
504
- const context = createDriverContext(record, controller, notify);
753
+ const playerCommand = record.pendingPlayerCommand;
754
+ const context = createDriverContext(record, controller, notify, playerCommand);
505
755
  if (controller.signal.aborted) {
506
756
  throw new SimulationAbortedError('Simulation stopped');
507
757
  }
@@ -517,6 +767,10 @@ async function makePrivateOrchestrator(kind) {
517
767
  if (controller.signal.aborted) {
518
768
  throw new SimulationAbortedError('Simulation stopped');
519
769
  }
770
+ if (playerCommand !== null
771
+ && record.pendingPlayerCommand?.commandId === playerCommand.commandId) {
772
+ record.pendingPlayerCommand = null;
773
+ }
520
774
  record.status = 'completed';
521
775
  onComplete('Simulation completed');
522
776
  }
@@ -548,6 +802,9 @@ export function validateSimulationDriverRegistration(registration) {
548
802
  assertCompatibility(registration.compatibility);
549
803
  if (!registration.kind.trim())
550
804
  throw new Error('Simulation driver kind must not be empty');
805
+ if (registration.definition !== undefined) {
806
+ assertDefinition(registration.definition, registration.kind, registration.validateDynamicState === undefined ? 100 : Number.MAX_SAFE_INTEGER);
807
+ }
551
808
  if (registrations.has(registration.kind) || getOrchestrator(registration.kind)) {
552
809
  throw new Error(`Simulation driver ${registration.kind} is already registered`);
553
810
  }
@@ -555,6 +812,9 @@ export function validateSimulationDriverRegistration(registration) {
555
812
  export function registerSimulationDriver(registration) {
556
813
  validateSimulationDriverRegistration(registration);
557
814
  registrations.set(registration.kind, registration);
815
+ if (registration.definition !== undefined) {
816
+ definitions.set(registration.kind, cloneDefinition(registration.definition));
817
+ }
558
818
  registerOrchestrator(registration.kind, () => makePrivateOrchestrator(registration.kind));
559
819
  registerSimulationRuntimeBinding(registration.kind, {
560
820
  rehydrate: async (state, context) => {
@@ -575,8 +835,21 @@ const simulationHost = {
575
835
  checkpointSchemaVersions: [SIMULATION_CHECKPOINT_VERSION],
576
836
  capabilities: HOST_CAPABILITIES,
577
837
  },
838
+ listSimulationDefinitions() {
839
+ return [...definitions.values()]
840
+ .sort((left, right) => left.title.localeCompare(right.title))
841
+ .map(cloneDefinition);
842
+ },
578
843
  async createSession(request) {
579
844
  assertCreateRequest(request);
845
+ const requestedDynamicState = request.dynamicState === undefined
846
+ ? null
847
+ : dynamicStateToolkit().parseDynamicSimulationState(request.dynamicState);
848
+ if (requestedDynamicState !== null
849
+ && (requestedDynamicState.gameKind !== request.driverKind || requestedDynamicState.revision !== 0)) {
850
+ throw new Error('Initial dynamic state must match its driver at revision zero');
851
+ }
852
+ validateRegisteredDynamicState(requestedDynamicState, request.driverKind);
580
853
  pruneSessionRecords();
581
854
  if (!registrations.has(request.driverKind) && request.driverKind !== 'gamemaster') {
582
855
  throw new Error(`Simulation driver ${request.driverKind} is not registered`);
@@ -613,18 +886,37 @@ const simulationHost = {
613
886
  if (actor.metadata)
614
887
  actorMetadata.set(created.id, structuredClone(actor.metadata));
615
888
  }
616
- setSimState(state);
617
- const record = ensureSessionRecord(state, request.driverKind);
889
+ const record = makeSessionRecord(state, request.driverKind);
618
890
  for (const [actorId, metadata] of actorMetadata) {
619
891
  record.actorMetadata.set(actorId, metadata);
620
892
  }
893
+ if (request.dynamicState !== undefined) {
894
+ record.dynamicState = requestedDynamicState;
895
+ }
621
896
  if (request.pluginData)
622
897
  record.pluginData.root = asJsonObject(request.pluginData);
898
+ try {
899
+ if (requestedDynamicState !== null) {
900
+ const documents = registrations.get(request.driverKind)?.initializeDocuments?.(requestedDynamicState) ?? [];
901
+ for (const document of documents)
902
+ applyOperation(record, document);
903
+ }
904
+ validateRegisteredDocuments(record);
905
+ }
906
+ catch (error) {
907
+ state.close();
908
+ throw error;
909
+ }
910
+ sessions.set(state.id, record);
911
+ setSimState(state);
623
912
  return makeSession(record);
624
913
  },
625
914
  async loadSession(request) {
626
915
  pruneSessionRecords();
627
- const state = await SimState.loadCheckpoint(request.checkpointPath);
916
+ if (request.outputDirectory !== undefined && request.outputDirectory.trim() === '') {
917
+ throw new Error('Simulation output directory cannot be empty');
918
+ }
919
+ const state = await SimState.loadCheckpoint(request.checkpointPath, request.outputDirectory);
628
920
  try {
629
921
  const checkpointDriverKind = driverKindForState(state);
630
922
  if (request.driverKind !== undefined && request.driverKind !== checkpointDriverKind) {
@@ -656,6 +948,31 @@ const simulationHost = {
656
948
  const record = sessions.get(ref.sessionId);
657
949
  return record && record.driverKind === ref.driverKind ? makeSession(record) : null;
658
950
  },
951
+ async submitPlayerCommand(ref, command) {
952
+ const record = requireSessionRecord(ref);
953
+ if (sessionRuns.has(record.state.id) || ['running', 'stopping'].includes(record.status)) {
954
+ throw new Error(`Simulation session ${record.state.id} cannot accept a command while running`);
955
+ }
956
+ const parsed = parsePlayerCommand(command);
957
+ if (record.submittedPlayerCommandIds.has(parsed.commandId)) {
958
+ return { accepted: false };
959
+ }
960
+ if (record.pendingPlayerCommand !== null) {
961
+ throw new Error(`Simulation session ${record.state.id} already has a pending player command`);
962
+ }
963
+ if (record.submittedPlayerCommandIds.size >= MAX_PLAYER_COMMAND_IDS) {
964
+ throw new Error(`Simulation session ${record.state.id} reached its ${MAX_PLAYER_COMMAND_IDS}-command bound`);
965
+ }
966
+ if (parsed.actorId !== undefined) {
967
+ const actor = record.state.getAllAgents().find(candidate => candidate.id === parsed.actorId);
968
+ if (actor?.humanControlled !== true) {
969
+ throw new Error(`Simulation player command actorId must name a human-controlled actor in session ${record.state.id}`);
970
+ }
971
+ }
972
+ record.pendingPlayerCommand = parsed;
973
+ record.submittedPlayerCommandIds.add(parsed.commandId);
974
+ return { accepted: true };
975
+ },
659
976
  async startSession(request) {
660
977
  const record = requireSessionRecord(request.ref);
661
978
  if (sessionRuns.has(record.state.id) || ['running', 'stopping'].includes(record.status)) {
@@ -0,0 +1,20 @@
1
+ import type { SimulationDocumentWriteV1, SimulationSessionSnapshotV1 } from '../plugin/simulation_contract.js';
2
+ import type { SimulationAuthorizedDocumentV1 } from '../plugin/simulation_interventions.js';
3
+ export declare class SimulationInputError extends Error {
4
+ readonly code: string;
5
+ constructor(code: string, message: string);
6
+ }
7
+ export declare const fail: (code: string, message: string) => never;
8
+ export declare function inputActorId(actor: SimulationSessionSnapshotV1['actors'][number]): string;
9
+ export declare function actors(snapshot: SimulationSessionSnapshotV1): {
10
+ actorId: string;
11
+ name: string;
12
+ role: string;
13
+ organization?: string;
14
+ humanControlled: boolean;
15
+ currentAction?: string;
16
+ metadata?: import("../plugin/simulation_contract.js").SimulationJsonObjectV1;
17
+ }[];
18
+ export declare function validateDocumentWrite(snapshot: SimulationSessionSnapshotV1, write: SimulationDocumentWriteV1): void;
19
+ export declare function sessionDocuments(snapshot: SimulationSessionSnapshotV1): SimulationAuthorizedDocumentV1[];
20
+ export declare function validateSessionDocuments(snapshot: SimulationSessionSnapshotV1): void;
@@ -0,0 +1,62 @@
1
+ import { isDeepStrictEqual } from 'node:util';
2
+ export class SimulationInputError extends Error {
3
+ code;
4
+ constructor(code, message) {
5
+ super(message);
6
+ this.code = code;
7
+ this.name = 'SimulationInputError';
8
+ }
9
+ }
10
+ export const fail = (code, message) => { throw new SimulationInputError(code, message); };
11
+ export function inputActorId(actor) {
12
+ return typeof actor.metadata?.dynamicActorId === 'string' ? actor.metadata.dynamicActorId : actor.actorId;
13
+ }
14
+ export function actors(snapshot) { return snapshot.actors.map(actor => ({ ...actor, actorId: inputActorId(actor) })); }
15
+ export function validateDocumentWrite(snapshot, write) {
16
+ const roster = actors(snapshot);
17
+ if (!write.ownerActorId || !roster.some(actor => actor.actorId === write.ownerActorId)
18
+ || !write.recipientActorIds.includes(write.ownerActorId) || new Set(write.recipientActorIds).size !== write.recipientActorIds.length
19
+ || write.recipientActorIds.some(id => !roster.some(actor => actor.actorId === id)))
20
+ fail('recipient_invalid', 'Document owner and recipients must name the exact cast');
21
+ if (Buffer.byteLength(write.content, 'utf8') > 8192)
22
+ fail('body_too_large', 'Document exceeds its byte limit');
23
+ if (write.revisionOf) {
24
+ const prior = snapshot.documents.find(doc => doc.documentId === write.revisionOf);
25
+ if (!prior || snapshot.documents.some(doc => doc.revisionOf === prior.documentId)
26
+ || prior.ownerActorId !== write.ownerActorId || !isDeepStrictEqual(prior.recipientActorIds, write.recipientActorIds))
27
+ fail('document_version_conflict', 'Document version or recipients changed');
28
+ }
29
+ }
30
+ export function sessionDocuments(snapshot) {
31
+ const byId = new Map(snapshot.documents.map(doc => [doc.documentId, doc]));
32
+ return snapshot.documents.filter(doc => doc.ownerActorId !== undefined).map(doc => {
33
+ let root = doc;
34
+ let version = 1;
35
+ const seen = new Set([doc.documentId]);
36
+ while (root.revisionOf) {
37
+ const parent = byId.get(root.revisionOf);
38
+ if (!parent || seen.has(parent.documentId))
39
+ return fail('input_state_invalid', 'Document version chain is invalid');
40
+ seen.add(parent.documentId);
41
+ root = parent;
42
+ version += 1;
43
+ }
44
+ return { ...(doc.provenance === undefined ? {} : { provenance: structuredClone(doc.provenance) }), documentId: root.documentId, versionId: doc.documentId, version, ownerActorId: doc.ownerActorId, recipientActorIds: doc.recipientActorIds, body: doc.content, label: doc.label };
45
+ });
46
+ }
47
+ export function validateSessionDocuments(snapshot) {
48
+ sessionDocuments(snapshot);
49
+ for (const [index, doc] of snapshot.documents.entries()) {
50
+ if (doc.ownerActorId === undefined)
51
+ continue;
52
+ try {
53
+ validateDocumentWrite({ ...snapshot, documents: snapshot.documents.slice(0, index) }, {
54
+ operation: 'document.write', ownerActorId: doc.ownerActorId, recipientActorIds: doc.recipientActorIds,
55
+ label: doc.label, documentType: doc.type, content: doc.content, createdBy: doc.createdBy, revisionOf: doc.revisionOf,
56
+ });
57
+ }
58
+ catch {
59
+ fail('input_state_invalid', 'Session input references are invalid');
60
+ }
61
+ }
62
+ }