@iowarp/clio-coder 0.3.0 → 0.3.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 (988) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +50 -53
  3. package/dist/acp-FPR54DGL.js +138 -0
  4. package/dist/{agents-Q4MYPMUW.js → agents-OGPIHPJH.js} +33 -25
  5. package/dist/assets/codewiki.json +1 -0
  6. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/LICENSE +21 -0
  7. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/cgmanifest.json +16 -0
  8. package/dist/assets/grammars/notices/tree-sitter-wasms/LICENSE +24 -0
  9. package/dist/assets/grammars/tree-sitter-c-sharp.wasm +0 -0
  10. package/dist/assets/grammars/tree-sitter-c.wasm +0 -0
  11. package/dist/assets/grammars/tree-sitter-cpp.wasm +0 -0
  12. package/dist/assets/grammars/tree-sitter-go.wasm +0 -0
  13. package/dist/assets/grammars/tree-sitter-java.wasm +0 -0
  14. package/dist/assets/grammars/tree-sitter-javascript.wasm +0 -0
  15. package/dist/assets/grammars/tree-sitter-python.wasm +0 -0
  16. package/dist/assets/grammars/tree-sitter-ruby.wasm +0 -0
  17. package/dist/assets/grammars/tree-sitter-rust.wasm +0 -0
  18. package/dist/assets/grammars/tree-sitter-tsx.wasm +0 -0
  19. package/dist/assets/grammars/tree-sitter-typescript.wasm +0 -0
  20. package/dist/assets/grammars/tree-sitter.wasm +0 -0
  21. package/dist/{auth-O6HYIJ6J.js → auth-IC3K6NIZ.js} +22 -15
  22. package/dist/{chunk-KKKPTZLM.js → chunk-2STGEDFV.js} +8 -1
  23. package/dist/chunk-3I7MS7N2.js +40 -0
  24. package/dist/chunk-3R73A4XB.js +69 -0
  25. package/dist/{chunk-26BZQOAD.js → chunk-474KN5II.js} +86 -115
  26. package/dist/{chunk-NI4DEJMC.js → chunk-4QKXUHSR.js} +26 -3
  27. package/dist/{chunk-X3BR7HWV.js → chunk-5WIGXA4T.js} +7 -1
  28. package/dist/{chunk-TFSSEXL6.js → chunk-673JJUWJ.js} +14 -4
  29. package/dist/{chunk-GNGDQYDU.js → chunk-7SS2CTV2.js} +27922 -1249
  30. package/dist/{chunk-7RBKDI66.js → chunk-ASND7OZK.js} +104 -12
  31. package/dist/{chunk-X3NE4WVW.js → chunk-BNAZZHFG.js} +7 -1
  32. package/dist/{chunk-RQDWMVRB.js → chunk-BSU2YIWB.js} +9 -3
  33. package/dist/{chunk-CLJ5HLUD.js → chunk-C4PTHK7P.js} +24 -5
  34. package/dist/{chunk-QV47YRF4.js → chunk-CGKSTWHD.js} +7 -1
  35. package/dist/{chunk-BYEU76JP.js → chunk-DKGKUHFA.js} +34 -9
  36. package/dist/chunk-EYOKLTMF.js +170 -0
  37. package/dist/{chunk-PS4PFJQP.js → chunk-FCIH3BIZ.js} +15258 -14130
  38. package/dist/{chunk-2J63S4SF.js → chunk-FST4FYJB.js} +82 -14
  39. package/dist/{chunk-3DANZDGR.js → chunk-G34LV2PF.js} +34 -9
  40. package/dist/{chunk-BBUH4VAA.js → chunk-GAEBEQVI.js} +34 -21
  41. package/dist/chunk-GB6QRBXN.js +8543 -0
  42. package/dist/chunk-GEP36Y4X.js +12796 -0
  43. package/dist/{chunk-TKHQ4DGZ.js → chunk-H6F6BYOH.js} +496 -121
  44. package/dist/{chunk-UGYAX5YI.js → chunk-HQQID6OA.js} +10 -5
  45. package/dist/chunk-IHXBNWMM.js +137 -0
  46. package/dist/{chunk-ME6DNWIU.js → chunk-IS3ONKU3.js} +7 -1
  47. package/dist/{chunk-DXQNI4PC.js → chunk-IWHMRKLL.js} +8 -1
  48. package/dist/chunk-K2ITRMHZ.js +642 -0
  49. package/dist/{chunk-KBR4MZZR.js → chunk-K5XEMXTI.js} +7 -1
  50. package/dist/{chunk-AMFR5YA3.js → chunk-KKNLWXI6.js} +24 -10
  51. package/dist/{chunk-JWHCJDCI.js → chunk-KY56HMHH.js} +145 -61
  52. package/dist/{chunk-E3NYWENM.js → chunk-LU4TK2PR.js} +52 -7
  53. package/dist/{chunk-UWIJNAOB.js → chunk-M5T5VO65.js} +109 -42
  54. package/dist/{chunk-JPOWPFCU.js → chunk-MAR7Y6HW.js} +38 -16
  55. package/dist/chunk-N6F52NLF.js +6951 -0
  56. package/dist/{chunk-UHTSULZS.js → chunk-NMOX6HFD.js} +20 -7
  57. package/dist/{chunk-WD6AJM35.js → chunk-OLBBMFRD.js} +30 -13
  58. package/dist/{chunk-VOO7NYPP.js → chunk-PFEFKVGL.js} +22 -6
  59. package/dist/{chunk-6CWDTGUC.js → chunk-PIUMUEMV.js} +7 -1
  60. package/dist/chunk-PV4JUBVJ.js +462 -0
  61. package/dist/{chunk-527KG6XR.js → chunk-Q3RUPKEJ.js} +22 -4
  62. package/dist/{chunk-D5YD55AR.js → chunk-Q5WJOSJ7.js} +11 -1
  63. package/dist/{chunk-5N2FG33Q.js → chunk-R346GLFC.js} +7 -1
  64. package/dist/{chunk-4UQA7NCT.js → chunk-R5KLMSBV.js} +7 -2
  65. package/dist/{chunk-PIDUD6M2.js → chunk-RDLVBZEO.js} +11 -6
  66. package/dist/{chunk-O4EJEDHO.js → chunk-RPTR2H26.js} +40 -31
  67. package/dist/{chunk-HBU5MTAM.js → chunk-SVNXH4L2.js} +7 -1
  68. package/dist/{chunk-XNISANGE.js → chunk-TEKV33Q5.js} +122 -57
  69. package/dist/chunk-TXOTCRLG.js +15 -0
  70. package/dist/{chunk-VPAWTYLY.js → chunk-WEPFGWHJ.js} +7 -1
  71. package/dist/{chunk-HMYNFFY4.js → chunk-XPLRXC72.js} +7 -2
  72. package/dist/{chunk-UU3R62TT.js → chunk-XYWBQRDM.js} +13 -4
  73. package/dist/{chunk-7BHLZB3A.js → chunk-ZPY3JZ5E.js} +32 -10
  74. package/dist/cli/index.js +39 -33
  75. package/dist/clio-BZVGEUFJ.js +58 -0
  76. package/dist/{components-JVHMUBEB.js → components-DMAOEKFB.js} +26 -9
  77. package/dist/{config-ZFCDBMDC.js → config-IRUQ7SE4.js} +42 -31
  78. package/dist/configure-S7S6F6CL.js +32 -0
  79. package/dist/{context-CDXTP2MP.js → context-3KWFLHJG.js} +17 -11
  80. package/dist/{context-E3KIFVXI.js → context-5RADCKTR.js} +33 -28
  81. package/dist/{context-clear-3F4PLXOS.js → context-clear-7TSNPAAI.js} +36 -28
  82. package/dist/{context-index-Q7YSYTR3.js → context-index-W4RLWOQH.js} +10 -4
  83. package/dist/{docs-YIETIWZI.js → docs-5AWSPS37.js} +16 -10
  84. package/dist/doctor-UC5NAJYQ.js +77 -0
  85. package/dist/{eval-B3KZZESM.js → eval-U6TJHRLX.js} +77 -24
  86. package/dist/{evidence-V67CHM35.js → evidence-YEGUW4L3.js} +34 -26
  87. package/dist/{evolve-YDZSUQYA.js → evolve-TXARCTPG.js} +39 -26
  88. package/dist/{extensions-SRG7XCAH.js → extensions-OZFJ3A3G.js} +13 -7
  89. package/dist/{fleet-CA2CRTVG.js → fleet-6G3DHNYE.js} +45 -37
  90. package/dist/fleet-preflight-DSNT37JK.js +23 -0
  91. package/dist/{init-2OZDJE2D.js → init-KZ5QTF6M.js} +42 -34
  92. package/dist/{memory-3PIQQAKX.js → memory-73ESV5YC.js} +35 -27
  93. package/dist/{models-DY35XI7Y.js → models-A4PVNWJK.js} +34 -23
  94. package/dist/{paths-5OMXW7Z4.js → paths-C4H6IV77.js} +12 -6
  95. package/dist/preload-6WVMHX3A.js +13 -0
  96. package/dist/{reset-PIFYNOS3.js → reset-BGW6OGMV.js} +17 -11
  97. package/dist/{run-3VSPP24F.js → run-YTPEYQOH.js} +60 -48
  98. package/dist/{share-D36RQCXM.js → share-YIFFV4NQ.js} +16 -10
  99. package/dist/{skills-F2MRLELY.js → skills-2V6RA3OQ.js} +18 -11
  100. package/dist/{skills-eval-E2ZTW4PL.js → skills-eval-S2TVJO4F.js} +45 -36
  101. package/dist/{targets-DZMEZAH4.js → targets-TYXLPB23.js} +61 -59
  102. package/dist/{trace-7NYCUI2J.js → trace-GGOJ6Q6Z.js} +9 -3
  103. package/dist/{uninstall-AD3JWHBB.js → uninstall-LLLT4F4W.js} +14 -8
  104. package/dist/{upgrade-WYYBKGDY.js → upgrade-33G2LMM5.js} +45 -23
  105. package/dist/{usage-ULIDAGFF.js → usage-ZAFSXKKG.js} +35 -27
  106. package/dist/version-KGEG7EPO.js +21 -0
  107. package/dist/{wiki-generate-PKFIX6OB.js → wiki-generate-NUQCVOQ3.js} +55 -45
  108. package/dist/worker/entry.js +101 -43
  109. package/docs/README.md +12 -9
  110. package/docs/acp.md +28 -5
  111. package/docs/alcf-provider.md +1 -1
  112. package/docs/architecture.md +23 -2
  113. package/docs/artifact-placement.md +101 -0
  114. package/docs/artifact-versions.md +1 -1
  115. package/docs/built-in-agents.md +4 -2
  116. package/docs/capacity-and-scheduling.md +1 -1
  117. package/docs/commands-and-modes.md +125 -41
  118. package/docs/configuration-and-targets.md +88 -18
  119. package/docs/context-engine.md +6 -2
  120. package/docs/development-pipeline.md +77 -0
  121. package/docs/documentation-coverage.md +4 -4
  122. package/docs/documentation-guide.md +3 -3
  123. package/docs/environment-variables.md +2 -1
  124. package/docs/eval-runner.md +3 -3
  125. package/docs/evals-internal.md +2 -2
  126. package/docs/evidence-and-memory.md +6 -2
  127. package/docs/evolution.md +1 -1
  128. package/docs/exit-codes-and-output.md +1 -1
  129. package/docs/extensions-and-sharing.md +18 -11
  130. package/docs/fleet-demo-runbook.md +22 -23
  131. package/docs/fleet-dispatch.md +111 -12
  132. package/docs/glossary.md +107 -15
  133. package/docs/html/agents_blueprint.html +3 -3
  134. package/docs/html/alcf_blueprint.html +3 -3
  135. package/docs/html/architecture_blueprint.html +3 -3
  136. package/docs/html/commands_blueprint.html +187 -42
  137. package/docs/html/configuration_blueprint.html +7 -7
  138. package/docs/html/context_blueprint.html +3 -3
  139. package/docs/html/documentation_blueprint.html +1 -1
  140. package/docs/html/environment_blueprint.html +3 -3
  141. package/docs/html/eval_blueprint.html +4 -4
  142. package/docs/html/evals_internal_blueprint.html +3 -3
  143. package/docs/html/evolution_blueprint.html +3 -3
  144. package/docs/html/extensions_blueprint.html +3 -3
  145. package/docs/html/fleet_dispatch_blueprint.html +8 -8
  146. package/docs/html/index.html +5 -5
  147. package/docs/html/lifecycle_blueprint.html +4 -4
  148. package/docs/html/memory_blueprint.html +3 -3
  149. package/docs/html/middleware_blueprint.html +3 -3
  150. package/docs/html/models_blueprint.html +2 -2
  151. package/docs/html/observability_blueprint.html +2 -2
  152. package/docs/html/provider_adapter_blueprint.html +3 -3
  153. package/docs/html/safety_blueprint.html +3 -3
  154. package/docs/html/skills_blueprint.html +2 -2
  155. package/docs/html/soak_blueprint.html +3 -3
  156. package/docs/html/tool_usage_blueprint.html +4 -4
  157. package/docs/html/tools_blueprint.html +2 -2
  158. package/docs/html/trace_blueprint.html +3 -3
  159. package/docs/html/tui_design_blueprint.html +100 -40
  160. package/docs/html/validation_blueprint.html +1 -1
  161. package/docs/html/worker_dispatch_blueprint.html +3 -3
  162. package/docs/installation-and-lifecycle.md +62 -11
  163. package/docs/middleware-and-components.md +1 -1
  164. package/docs/model-catalog.md +2 -2
  165. package/docs/observability.md +3 -3
  166. package/docs/proactive-memory.md +12 -12
  167. package/docs/prompt-envelope-and-tools.md +2 -2
  168. package/docs/provider-adapter-cookbook.md +1 -1
  169. package/docs/release-cut-checklist.md +4 -0
  170. package/docs/safety-model.md +21 -5
  171. package/docs/scientific-validation.md +3 -3
  172. package/docs/session-lifecycle.md +2 -2
  173. package/docs/skills-marketplace.md +1 -1
  174. package/docs/time-conventions.md +101 -0
  175. package/docs/tool-usage.md +5 -4
  176. package/docs/trace-store.md +1 -1
  177. package/docs/troubleshooting.md +1 -1
  178. package/docs/tui-design.md +83 -27
  179. package/docs/worker-dispatch-mechanics.md +3 -3
  180. package/package.json +16 -16
  181. package/skills/README.md +5 -6
  182. package/skills/git/file-ticket/SKILL.md +107 -0
  183. package/skills/git/file-ticket/evals.md +54 -0
  184. package/skills/git/fix-issue/SKILL.md +106 -0
  185. package/skills/git/fix-issue/evals.md +71 -0
  186. package/skills/git/ship/SKILL.md +92 -0
  187. package/skills/git/ship/evals.md +72 -0
  188. package/skills/skill-marketplace.json +12 -20
  189. package/src/cli/acp.ts +88 -0
  190. package/src/cli/agents.ts +60 -0
  191. package/src/cli/args.ts +280 -0
  192. package/src/cli/argv.ts +170 -0
  193. package/src/cli/ask.ts +34 -0
  194. package/src/cli/auth.ts +468 -0
  195. package/src/cli/bootstrap-generate.ts +498 -0
  196. package/src/cli/clio.ts +34 -0
  197. package/src/cli/components.ts +195 -0
  198. package/src/cli/config-inspect.ts +330 -0
  199. package/src/cli/config.ts +72 -0
  200. package/src/cli/configure-interop.ts +67 -0
  201. package/src/cli/configure-layout.ts +172 -0
  202. package/src/cli/configure.ts +1487 -0
  203. package/src/cli/context-clear.ts +76 -0
  204. package/src/cli/context-index.ts +102 -0
  205. package/src/cli/context.ts +316 -0
  206. package/src/cli/default-target.ts +63 -0
  207. package/src/cli/docs.ts +340 -0
  208. package/src/cli/doctor.ts +54 -0
  209. package/src/cli/eval.ts +315 -0
  210. package/src/cli/evidence.ts +222 -0
  211. package/src/cli/evolve.ts +219 -0
  212. package/src/cli/extensions.ts +205 -0
  213. package/src/cli/fleet.ts +827 -0
  214. package/src/cli/index.ts +309 -0
  215. package/src/cli/init.ts +219 -0
  216. package/src/cli/initial-message.ts +47 -0
  217. package/src/cli/internal-dispatch.ts +55 -0
  218. package/src/cli/memory.ts +180 -0
  219. package/src/cli/models.ts +257 -0
  220. package/src/cli/modes/json-stream.ts +85 -0
  221. package/src/cli/modes/jsonl.ts +9 -0
  222. package/src/cli/modes/print.ts +589 -0
  223. package/src/cli/oauth-manual-input.ts +72 -0
  224. package/src/cli/oauth-select.ts +36 -0
  225. package/src/cli/output-guard.ts +48 -0
  226. package/src/cli/paths.ts +44 -0
  227. package/src/cli/provider-target.ts +113 -0
  228. package/src/cli/removal.ts +72 -0
  229. package/src/cli/reset.ts +253 -0
  230. package/src/cli/run.ts +497 -0
  231. package/src/cli/share.ts +243 -0
  232. package/src/cli/shared.ts +60 -0
  233. package/src/cli/skills-eval.ts +1225 -0
  234. package/src/cli/skills.ts +470 -0
  235. package/src/cli/steer-channel.ts +86 -0
  236. package/src/cli/targets.ts +1150 -0
  237. package/src/cli/text-layout.ts +102 -0
  238. package/src/cli/trace.ts +274 -0
  239. package/src/cli/uninstall.ts +405 -0
  240. package/src/cli/upgrade.ts +270 -0
  241. package/src/cli/usage.ts +869 -0
  242. package/src/cli/validate-model.ts +28 -0
  243. package/src/cli/version.ts +7 -0
  244. package/src/cli/wiki-generate.ts +509 -0
  245. package/src/core/artifact-paths.ts +43 -0
  246. package/src/core/bash-exec.ts +242 -0
  247. package/src/core/boot-trace.ts +37 -0
  248. package/src/core/bus-events.ts +728 -0
  249. package/src/core/bus-trace.ts +53 -0
  250. package/src/core/c-header-language.ts +265 -0
  251. package/src/core/clio-repo.ts +78 -0
  252. package/src/core/config.ts +1593 -0
  253. package/src/core/context-floor.ts +33 -0
  254. package/src/core/defaults.ts +625 -0
  255. package/src/core/domain-loader.ts +170 -0
  256. package/src/core/event-bus.ts +94 -0
  257. package/src/core/file-references.ts +282 -0
  258. package/src/core/guardrails.ts +185 -0
  259. package/src/core/headless-permission.ts +21 -0
  260. package/src/core/init.ts +223 -0
  261. package/src/core/json-payload.ts +58 -0
  262. package/src/core/package-root.ts +54 -0
  263. package/src/core/path-canonical.ts +37 -0
  264. package/src/core/process-identity.ts +41 -0
  265. package/src/core/recent-models.ts +91 -0
  266. package/src/core/release.ts +2 -0
  267. package/src/core/residency-protection.ts +56 -0
  268. package/src/core/resolve-config-value.ts +88 -0
  269. package/src/core/response-schema.ts +279 -0
  270. package/src/core/run-overrides.ts +77 -0
  271. package/src/core/safe-exec.ts +193 -0
  272. package/src/core/safe-id.ts +37 -0
  273. package/src/core/safe-resource-write.ts +162 -0
  274. package/src/core/session-routing.ts +339 -0
  275. package/src/core/settings-layers.ts +220 -0
  276. package/src/core/shared-bus.ts +8 -0
  277. package/src/core/shell-quote.ts +26 -0
  278. package/src/core/skill-activation.ts +190 -0
  279. package/src/core/startup-timer.ts +37 -0
  280. package/src/core/state-file-lock.ts +207 -0
  281. package/src/core/termination.ts +202 -0
  282. package/src/core/timers.ts +38 -0
  283. package/src/core/tool-names.ts +65 -0
  284. package/src/core/verification-scripts.ts +13 -0
  285. package/src/core/workspace-files.ts +492 -0
  286. package/src/core/xdg.ts +177 -0
  287. package/src/domains/agents/builtins/architect.md +4 -4
  288. package/src/domains/agents/builtins/coder.md +3 -2
  289. package/src/domains/agents/builtins/debugger.md +1 -1
  290. package/src/domains/agents/builtins/documenter.md +1 -1
  291. package/src/domains/agents/builtins/git-master.md +3 -3
  292. package/src/domains/agents/builtins/provenance.md +1 -1
  293. package/src/domains/agents/builtins/researcher.md +1 -1
  294. package/src/domains/agents/builtins/scout.md +1 -1
  295. package/src/domains/agents/builtins/tester.md +1 -1
  296. package/src/domains/agents/builtins/verifier.md +1 -1
  297. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  298. package/src/domains/agents/catalog.ts +172 -0
  299. package/src/domains/agents/contract.ts +16 -0
  300. package/src/domains/agents/extension.ts +110 -0
  301. package/src/domains/agents/fleet-commands.ts +154 -0
  302. package/src/domains/agents/fleet-contract.ts +797 -0
  303. package/src/domains/agents/frontmatter.ts +40 -0
  304. package/src/domains/agents/index.ts +102 -0
  305. package/src/domains/agents/manifest.ts +6 -0
  306. package/src/domains/agents/recipe-schema.ts +202 -0
  307. package/src/domains/agents/recipe.ts +125 -0
  308. package/src/domains/agents/registry.ts +111 -0
  309. package/src/domains/agents/result-contract.ts +1265 -0
  310. package/src/domains/agents/spec.ts +371 -0
  311. package/src/domains/agents/write-boundary.ts +109 -0
  312. package/src/domains/components/diff.ts +99 -0
  313. package/src/domains/components/hash.ts +21 -0
  314. package/src/domains/components/index.ts +3 -0
  315. package/src/domains/components/scan.ts +304 -0
  316. package/src/domains/components/snapshot.ts +108 -0
  317. package/src/domains/components/types.ts +82 -0
  318. package/src/domains/config/agent-namespace.ts +13 -0
  319. package/src/domains/config/classify.ts +94 -0
  320. package/src/domains/config/contract.ts +22 -0
  321. package/src/domains/config/extension.ts +136 -0
  322. package/src/domains/config/index.ts +13 -0
  323. package/src/domains/config/keybindings.ts +164 -0
  324. package/src/domains/config/manifest.ts +6 -0
  325. package/src/domains/config/watcher.ts +41 -0
  326. package/src/domains/context/adoption.ts +880 -0
  327. package/src/domains/context/bootstrap-prompt.ts +273 -0
  328. package/src/domains/context/bootstrap.ts +1409 -0
  329. package/src/domains/context/clear.ts +86 -0
  330. package/src/domains/context/clio-md.ts +327 -0
  331. package/src/domains/context/codewiki/cmake.ts +356 -0
  332. package/src/domains/context/codewiki/cooperative.ts +46 -0
  333. package/src/domains/context/codewiki/digest.ts +135 -0
  334. package/src/domains/context/codewiki/grammar-assets.ts +33 -0
  335. package/src/domains/context/codewiki/indexer.ts +1614 -0
  336. package/src/domains/context/codewiki/tree-sitter.ts +771 -0
  337. package/src/domains/context/contract.ts +62 -0
  338. package/src/domains/context/excluded-dirs.ts +1 -0
  339. package/src/domains/context/extension.ts +407 -0
  340. package/src/domains/context/fingerprint.ts +196 -0
  341. package/src/domains/context/index.ts +164 -0
  342. package/src/domains/context/init-options.ts +69 -0
  343. package/src/domains/context/manifest.ts +6 -0
  344. package/src/domains/context/operator-profile.ts +157 -0
  345. package/src/domains/context/project-metadata.ts +510 -0
  346. package/src/domains/context/project-rules.ts +227 -0
  347. package/src/domains/context/prompt-context.ts +62 -0
  348. package/src/domains/context/refresh.ts +170 -0
  349. package/src/domains/context/sibling-files.ts +10 -0
  350. package/src/domains/context/state.ts +237 -0
  351. package/src/domains/context/wiki/assemble.ts +303 -0
  352. package/src/domains/context/wiki/frontmatter.ts +210 -0
  353. package/src/domains/context/wiki/generate.ts +590 -0
  354. package/src/domains/context/wiki/layout.ts +111 -0
  355. package/src/domains/context/wiki/meta.ts +221 -0
  356. package/src/domains/context/wiki/plan-store.ts +217 -0
  357. package/src/domains/context/wiki/plan.ts +250 -0
  358. package/src/domains/context/wiki/prompts.ts +270 -0
  359. package/src/domains/context/wiki/staleness.ts +198 -0
  360. package/src/domains/dispatch/active-route-planner.ts +168 -0
  361. package/src/domains/dispatch/admission-queue.ts +150 -0
  362. package/src/domains/dispatch/admission.ts +334 -0
  363. package/src/domains/dispatch/agent-candidates.ts +307 -0
  364. package/src/domains/dispatch/agent-ledger-hub.ts +71 -0
  365. package/src/domains/dispatch/agent-ledger-store.ts +257 -0
  366. package/src/domains/dispatch/agent-ledger.ts +212 -0
  367. package/src/domains/dispatch/agent-plan-adapter.ts +85 -0
  368. package/src/domains/dispatch/assignment-events.ts +132 -0
  369. package/src/domains/dispatch/assignment-reconcile.ts +76 -0
  370. package/src/domains/dispatch/assignment-store.ts +162 -0
  371. package/src/domains/dispatch/assignment.ts +278 -0
  372. package/src/domains/dispatch/backoff.ts +59 -0
  373. package/src/domains/dispatch/batch-store.ts +134 -0
  374. package/src/domains/dispatch/batch-tracker.ts +66 -0
  375. package/src/domains/dispatch/capability-match.ts +155 -0
  376. package/src/domains/dispatch/capacity-lease.ts +413 -0
  377. package/src/domains/dispatch/code-step-store.ts +52 -0
  378. package/src/domains/dispatch/code-step.ts +368 -0
  379. package/src/domains/dispatch/contract.ts +278 -0
  380. package/src/domains/dispatch/dedup.ts +133 -0
  381. package/src/domains/dispatch/event-pump.ts +251 -0
  382. package/src/domains/dispatch/execution-handoff.ts +29 -0
  383. package/src/domains/dispatch/execution-plan.ts +328 -0
  384. package/src/domains/dispatch/execution-role.ts +277 -0
  385. package/src/domains/dispatch/execution-scheduler.ts +583 -0
  386. package/src/domains/dispatch/extension.ts +5869 -0
  387. package/src/domains/dispatch/failure-classification.ts +141 -0
  388. package/src/domains/dispatch/fleet-plan.ts +225 -0
  389. package/src/domains/dispatch/fleet-preflight.ts +394 -0
  390. package/src/domains/dispatch/gate-decisions.ts +1040 -0
  391. package/src/domains/dispatch/gate-role-prompts.ts +58 -0
  392. package/src/domains/dispatch/heartbeat.ts +27 -0
  393. package/src/domains/dispatch/index.ts +137 -0
  394. package/src/domains/dispatch/joint-route-adapter.ts +114 -0
  395. package/src/domains/dispatch/joint-route-resolver.ts +283 -0
  396. package/src/domains/dispatch/manifest.ts +6 -0
  397. package/src/domains/dispatch/orphan-recovery.ts +224 -0
  398. package/src/domains/dispatch/outcome.ts +109 -0
  399. package/src/domains/dispatch/phase-timing.ts +47 -0
  400. package/src/domains/dispatch/placement.ts +202 -0
  401. package/src/domains/dispatch/receipt-findings.ts +255 -0
  402. package/src/domains/dispatch/receipt-integrity.ts +378 -0
  403. package/src/domains/dispatch/recovery-candidates.ts +74 -0
  404. package/src/domains/dispatch/reproducibility.ts +48 -0
  405. package/src/domains/dispatch/reservation-store.ts +501 -0
  406. package/src/domains/dispatch/route-approval.ts +177 -0
  407. package/src/domains/dispatch/route-candidates.ts +57 -0
  408. package/src/domains/dispatch/route-decision.ts +1079 -0
  409. package/src/domains/dispatch/route-facts.ts +187 -0
  410. package/src/domains/dispatch/route-history.ts +238 -0
  411. package/src/domains/dispatch/route-observer.ts +488 -0
  412. package/src/domains/dispatch/route-policy.ts +327 -0
  413. package/src/domains/dispatch/route-quality.ts +256 -0
  414. package/src/domains/dispatch/route-readiness.ts +120 -0
  415. package/src/domains/dispatch/routing-intent.ts +287 -0
  416. package/src/domains/dispatch/run-identity.ts +56 -0
  417. package/src/domains/dispatch/scout-transition.ts +130 -0
  418. package/src/domains/dispatch/state.ts +277 -0
  419. package/src/domains/dispatch/tool-stats.ts +132 -0
  420. package/src/domains/dispatch/transport.ts +209 -0
  421. package/src/domains/dispatch/types.ts +785 -0
  422. package/src/domains/dispatch/validation-grounding.ts +154 -0
  423. package/src/domains/dispatch/validation.ts +721 -0
  424. package/src/domains/dispatch/worker-protocol.ts +275 -0
  425. package/src/domains/dispatch/worker-spawn.ts +566 -0
  426. package/src/domains/dispatch/write-boundary-enforcer.ts +97 -0
  427. package/src/domains/dispatch/write-boundary.ts +426 -0
  428. package/src/domains/eval/artifacts/redact.ts +42 -0
  429. package/src/domains/eval/artifacts/store.ts +173 -0
  430. package/src/domains/eval/compare/compare.ts +33 -0
  431. package/src/domains/eval/compare/gates.ts +66 -0
  432. package/src/domains/eval/compare/thresholds.ts +92 -0
  433. package/src/domains/eval/harness-metrics.ts +62 -0
  434. package/src/domains/eval/index.ts +66 -0
  435. package/src/domains/eval/metrics/chaos-stream.ts +93 -0
  436. package/src/domains/eval/metrics/context.ts +34 -0
  437. package/src/domains/eval/metrics/coverage.ts +21 -0
  438. package/src/domains/eval/metrics/evidence.ts +182 -0
  439. package/src/domains/eval/metrics/fleet-loop-stream.ts +196 -0
  440. package/src/domains/eval/metrics/invariants.ts +736 -0
  441. package/src/domains/eval/metrics/latency.ts +4 -0
  442. package/src/domains/eval/metrics/token-stream.ts +139 -0
  443. package/src/domains/eval/metrics/tokens.ts +51 -0
  444. package/src/domains/eval/metrics/tool-calls.ts +7 -0
  445. package/src/domains/eval/proactive-memory.ts +279 -0
  446. package/src/domains/eval/provenance.ts +35 -0
  447. package/src/domains/eval/report.ts +234 -0
  448. package/src/domains/eval/reports/json.ts +5 -0
  449. package/src/domains/eval/reports/junit.ts +23 -0
  450. package/src/domains/eval/reports/markdown.ts +20 -0
  451. package/src/domains/eval/reports/swe-jsonl.ts +16 -0
  452. package/src/domains/eval/reports/text.ts +25 -0
  453. package/src/domains/eval/run-compare.ts +274 -0
  454. package/src/domains/eval/runner.ts +244 -0
  455. package/src/domains/eval/runners/clio-run.ts +148 -0
  456. package/src/domains/eval/runners/context-index.ts +56 -0
  457. package/src/domains/eval/runners/context-init.ts +203 -0
  458. package/src/domains/eval/runners/external-command.ts +350 -0
  459. package/src/domains/eval/runtime-paths.ts +171 -0
  460. package/src/domains/eval/schema/artifact.ts +75 -0
  461. package/src/domains/eval/schema/suite.ts +235 -0
  462. package/src/domains/eval/schema/validate.ts +339 -0
  463. package/src/domains/eval/store.ts +392 -0
  464. package/src/domains/eval/suites/load.ts +74 -0
  465. package/src/domains/eval/suites/matrix.ts +19 -0
  466. package/src/domains/eval/suites/resolve.ts +44 -0
  467. package/src/domains/eval/suites/run.ts +325 -0
  468. package/src/domains/eval/task-file.ts +186 -0
  469. package/src/domains/eval/types.ts +141 -0
  470. package/src/domains/eval/verifiers/command.ts +27 -0
  471. package/src/domains/eval/verifiers/file-exists.ts +6 -0
  472. package/src/domains/eval/verifiers/patch.ts +22 -0
  473. package/src/domains/eval/workspaces/git.ts +41 -0
  474. package/src/domains/eval/workspaces/local.ts +17 -0
  475. package/src/domains/eval/workspaces/temp-copy.ts +29 -0
  476. package/src/domains/evidence/build.ts +1714 -0
  477. package/src/domains/evidence/eval.ts +605 -0
  478. package/src/domains/evidence/failure-attribution.ts +54 -0
  479. package/src/domains/evidence/finish-contract-map.ts +42 -0
  480. package/src/domains/evidence/index.ts +55 -0
  481. package/src/domains/evidence/provenance.ts +200 -0
  482. package/src/domains/evidence/redact.ts +81 -0
  483. package/src/domains/evidence/store.ts +291 -0
  484. package/src/domains/evidence/types.ts +325 -0
  485. package/src/domains/evolution/SELF_EDIT_GATE.md +91 -0
  486. package/src/domains/evolution/index.ts +26 -0
  487. package/src/domains/evolution/manifest.ts +154 -0
  488. package/src/domains/evolution/validate.ts +304 -0
  489. package/src/domains/extensions/contract.ts +22 -0
  490. package/src/domains/extensions/discovery.ts +193 -0
  491. package/src/domains/extensions/extension.ts +46 -0
  492. package/src/domains/extensions/index.ts +34 -0
  493. package/src/domains/extensions/manager.ts +30 -0
  494. package/src/domains/extensions/manifest.ts +6 -0
  495. package/src/domains/extensions/resources.ts +38 -0
  496. package/src/domains/extensions/state.ts +224 -0
  497. package/src/domains/extensions/types.ts +83 -0
  498. package/src/domains/interop/consent.ts +185 -0
  499. package/src/domains/interop/contract.ts +29 -0
  500. package/src/domains/interop/detect.ts +173 -0
  501. package/src/domains/interop/extension.ts +59 -0
  502. package/src/domains/interop/index.ts +34 -0
  503. package/src/domains/interop/manifest.ts +6 -0
  504. package/src/domains/interop/registry.ts +139 -0
  505. package/src/domains/interop/state.ts +92 -0
  506. package/src/domains/interop/types.ts +109 -0
  507. package/src/domains/lifecycle/contract.ts +11 -0
  508. package/src/domains/lifecycle/doctor.ts +536 -0
  509. package/src/domains/lifecycle/extension.ts +23 -0
  510. package/src/domains/lifecycle/index.ts +21 -0
  511. package/src/domains/lifecycle/install-method.ts +51 -0
  512. package/src/domains/lifecycle/manifest.ts +6 -0
  513. package/src/domains/lifecycle/migrations/index.ts +94 -0
  514. package/src/domains/lifecycle/state.ts +93 -0
  515. package/src/domains/lifecycle/upgrade-notice.ts +35 -0
  516. package/src/domains/lifecycle/version.ts +35 -0
  517. package/src/domains/memory/index.ts +128 -0
  518. package/src/domains/memory/operations.ts +143 -0
  519. package/src/domains/memory/prompt-section.ts +86 -0
  520. package/src/domains/memory/proposal.ts +180 -0
  521. package/src/domains/memory/store.ts +163 -0
  522. package/src/domains/memory/task-bank.ts +229 -0
  523. package/src/domains/memory/task-memory-handoff.ts +222 -0
  524. package/src/domains/memory/task-memory-policy.ts +602 -0
  525. package/src/domains/memory/task-memory-status.ts +58 -0
  526. package/src/domains/memory/task-memory-telemetry.ts +346 -0
  527. package/src/domains/memory/task-memory-trace.ts +89 -0
  528. package/src/domains/memory/types.ts +74 -0
  529. package/src/domains/memory/validate.ts +297 -0
  530. package/src/domains/middleware/budget.ts +216 -0
  531. package/src/domains/middleware/contract.ts +35 -0
  532. package/src/domains/middleware/dispatch-nudge.ts +469 -0
  533. package/src/domains/middleware/extension.ts +129 -0
  534. package/src/domains/middleware/hook-receipts.ts +70 -0
  535. package/src/domains/middleware/hooks-io.ts +174 -0
  536. package/src/domains/middleware/hooks.ts +432 -0
  537. package/src/domains/middleware/index.ts +154 -0
  538. package/src/domains/middleware/manifest.ts +6 -0
  539. package/src/domains/middleware/memory-intervention.ts +701 -0
  540. package/src/domains/middleware/rules.ts +42 -0
  541. package/src/domains/middleware/runtime.ts +333 -0
  542. package/src/domains/middleware/skills-reminder.ts +187 -0
  543. package/src/domains/middleware/snapshot.ts +71 -0
  544. package/src/domains/middleware/stalled-turn.ts +71 -0
  545. package/src/domains/middleware/task-board-reminder.ts +87 -0
  546. package/src/domains/middleware/task-nudge.ts +77 -0
  547. package/src/domains/middleware/tool-choice-control.ts +42 -0
  548. package/src/domains/middleware/types.ts +131 -0
  549. package/src/domains/middleware/validate.ts +329 -0
  550. package/src/domains/observability/accountability.ts +67 -0
  551. package/src/domains/observability/contract.ts +168 -0
  552. package/src/domains/observability/cost.ts +206 -0
  553. package/src/domains/observability/evidence-index.ts +123 -0
  554. package/src/domains/observability/extension.ts +281 -0
  555. package/src/domains/observability/index.ts +78 -0
  556. package/src/domains/observability/manifest.ts +10 -0
  557. package/src/domains/observability/metrics.ts +37 -0
  558. package/src/domains/observability/projection.ts +477 -0
  559. package/src/domains/observability/telemetry.ts +89 -0
  560. package/src/domains/observability/trace-store.ts +1454 -0
  561. package/src/domains/prompts/compiler.ts +556 -0
  562. package/src/domains/prompts/contract.ts +30 -0
  563. package/src/domains/prompts/extension.ts +304 -0
  564. package/src/domains/prompts/fragment-loader.ts +139 -0
  565. package/src/domains/prompts/fragments/identity/clio.md +3 -2
  566. package/src/domains/prompts/fragments/identity/self-awareness.md +63 -0
  567. package/src/domains/prompts/fragments/operating/contract.md +10 -1
  568. package/src/domains/prompts/hash.ts +73 -0
  569. package/src/domains/prompts/index.ts +32 -0
  570. package/src/domains/prompts/manifest.ts +8 -0
  571. package/src/domains/prompts/memory-intervention.ts +57 -0
  572. package/src/domains/prompts/preload.ts +82 -0
  573. package/src/domains/providers/auth/api-key.ts +47 -0
  574. package/src/domains/providers/auth/backend-file.ts +69 -0
  575. package/src/domains/providers/auth/backend-memory.ts +17 -0
  576. package/src/domains/providers/auth/index.ts +37 -0
  577. package/src/domains/providers/auth/oauth.ts +36 -0
  578. package/src/domains/providers/auth/storage.ts +667 -0
  579. package/src/domains/providers/capabilities.ts +50 -0
  580. package/src/domains/providers/catalog.ts +162 -0
  581. package/src/domains/providers/contract.ts +151 -0
  582. package/src/domains/providers/credentials.ts +20 -0
  583. package/src/domains/providers/eligibility.ts +24 -0
  584. package/src/domains/providers/errors.ts +64 -0
  585. package/src/domains/providers/extension.ts +536 -0
  586. package/src/domains/providers/index.ts +142 -0
  587. package/src/domains/providers/knowledge-base-path.ts +102 -0
  588. package/src/domains/providers/manifest.ts +6 -0
  589. package/src/domains/providers/model-capabilities.ts +136 -0
  590. package/src/domains/providers/model-discovery.ts +144 -0
  591. package/src/domains/providers/model-family.ts +32 -0
  592. package/src/domains/providers/model-runtime-capabilities.ts +712 -0
  593. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +2 -2
  594. package/src/domains/providers/plugins.ts +59 -0
  595. package/src/domains/providers/probe/fingerprint.ts +44 -0
  596. package/src/domains/providers/probe/http.ts +114 -0
  597. package/src/domains/providers/probe/reasoning.ts +111 -0
  598. package/src/domains/providers/registry.ts +166 -0
  599. package/src/domains/providers/resolver.ts +156 -0
  600. package/src/domains/providers/runtime-resolution.ts +720 -0
  601. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +90 -0
  602. package/src/domains/providers/runtimes/builtins.ts +78 -0
  603. package/src/domains/providers/runtimes/claude/claude-code.ts +38 -0
  604. package/src/domains/providers/runtimes/claude/claude-sdk.ts +38 -0
  605. package/src/domains/providers/runtimes/claude/common.ts +55 -0
  606. package/src/domains/providers/runtimes/cloud/alcf.ts +171 -0
  607. package/src/domains/providers/runtimes/cloud/anthropic-max.ts +71 -0
  608. package/src/domains/providers/runtimes/cloud/anthropic.ts +43 -0
  609. package/src/domains/providers/runtimes/cloud/bedrock.ts +35 -0
  610. package/src/domains/providers/runtimes/cloud/deepseek.ts +50 -0
  611. package/src/domains/providers/runtimes/cloud/google.ts +41 -0
  612. package/src/domains/providers/runtimes/cloud/groq.ts +46 -0
  613. package/src/domains/providers/runtimes/cloud/mistral.ts +46 -0
  614. package/src/domains/providers/runtimes/cloud/openai-codex.ts +49 -0
  615. package/src/domains/providers/runtimes/cloud/openai.ts +46 -0
  616. package/src/domains/providers/runtimes/cloud/openrouter.ts +111 -0
  617. package/src/domains/providers/runtimes/common/lmstudio-logger.ts +32 -0
  618. package/src/domains/providers/runtimes/common/local-synth.ts +165 -0
  619. package/src/domains/providers/runtimes/common/probe-helpers.ts +474 -0
  620. package/src/domains/providers/runtimes/local-native/lemonade-anthropic.ts +27 -0
  621. package/src/domains/providers/runtimes/local-native/lemonade-openai.ts +26 -0
  622. package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +88 -0
  623. package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +207 -0
  624. package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +180 -0
  625. package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +126 -0
  626. package/src/domains/providers/runtimes/local-native/llamacpp.ts +98 -0
  627. package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +491 -0
  628. package/src/domains/providers/runtimes/local-native/ollama-native.ts +117 -0
  629. package/src/domains/providers/runtimes/local-native/sglang.ts +26 -0
  630. package/src/domains/providers/runtimes/local-native/vllm.ts +27 -0
  631. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +104 -0
  632. package/src/domains/providers/runtimes/protocol/anthropic-messages.ts +28 -0
  633. package/src/domains/providers/runtimes/protocol/bedrock.ts +26 -0
  634. package/src/domains/providers/runtimes/protocol/google.ts +27 -0
  635. package/src/domains/providers/runtimes/protocol/openai-compat.ts +145 -0
  636. package/src/domains/providers/support.ts +238 -0
  637. package/src/domains/providers/thinking-control-policy.ts +85 -0
  638. package/src/domains/providers/types/capability-flags.ts +114 -0
  639. package/src/domains/providers/types/cost-provenance.ts +7 -0
  640. package/src/domains/providers/types/inference.ts +41 -0
  641. package/src/domains/providers/types/knowledge-base.ts +156 -0
  642. package/src/domains/providers/types/local-model-quirks.ts +218 -0
  643. package/src/domains/providers/types/runtime-descriptor.ts +170 -0
  644. package/src/domains/providers/types/target-descriptor.ts +38 -0
  645. package/src/domains/resources/collision.ts +92 -0
  646. package/src/domains/resources/common-loader.ts +140 -0
  647. package/src/domains/resources/contract.ts +25 -0
  648. package/src/domains/resources/extension.ts +61 -0
  649. package/src/domains/resources/index.ts +74 -0
  650. package/src/domains/resources/loader.ts +86 -0
  651. package/src/domains/resources/manifest.ts +6 -0
  652. package/src/domains/resources/prompts/loader.ts +232 -0
  653. package/src/domains/resources/prompts/substitute.ts +65 -0
  654. package/src/domains/resources/skills/content-hash.ts +105 -0
  655. package/src/domains/resources/skills/evals.ts +175 -0
  656. package/src/domains/resources/skills/install.ts +410 -0
  657. package/src/domains/resources/skills/loader.ts +978 -0
  658. package/src/domains/resources/skills/marketplace.ts +255 -0
  659. package/src/domains/resources/skills/provenance-pin.ts +115 -0
  660. package/src/domains/safety/action-classifier.ts +268 -0
  661. package/src/domains/safety/approval-axis.ts +23 -0
  662. package/src/domains/safety/audit.ts +487 -0
  663. package/src/domains/safety/autonomy.ts +174 -0
  664. package/src/domains/safety/call-target.ts +59 -0
  665. package/src/domains/safety/contract.ts +65 -0
  666. package/src/domains/safety/damage-control.ts +44 -0
  667. package/src/domains/safety/default-path-policy.ts +117 -0
  668. package/src/domains/safety/extension.ts +383 -0
  669. package/src/domains/safety/finish-contract-registration.ts +128 -0
  670. package/src/domains/safety/finish-contract.ts +554 -0
  671. package/src/domains/safety/index.ts +44 -0
  672. package/src/domains/safety/loop-detector.ts +143 -0
  673. package/src/domains/safety/manifest.ts +6 -0
  674. package/src/domains/safety/path-policy.ts +164 -0
  675. package/src/domains/safety/policy-engine.ts +994 -0
  676. package/src/domains/safety/project-policy.ts +391 -0
  677. package/src/domains/safety/protected-artifacts-registration.ts +189 -0
  678. package/src/domains/safety/protected-artifacts.ts +993 -0
  679. package/src/domains/safety/rejection-feedback.ts +102 -0
  680. package/src/domains/safety/rigor.ts +72 -0
  681. package/src/domains/safety/rule-compiler.ts +48 -0
  682. package/src/domains/safety/rule-pack-loader.ts +92 -0
  683. package/src/domains/safety/run-effects.ts +197 -0
  684. package/src/domains/safety/scope.ts +61 -0
  685. package/src/domains/scheduling/budget.ts +35 -0
  686. package/src/domains/scheduling/cluster.ts +175 -0
  687. package/src/domains/scheduling/contract.ts +30 -0
  688. package/src/domains/scheduling/extension.ts +91 -0
  689. package/src/domains/scheduling/index.ts +12 -0
  690. package/src/domains/scheduling/manifest.ts +6 -0
  691. package/src/domains/session/archive-readers.ts +208 -0
  692. package/src/domains/session/checkpoint.ts +38 -0
  693. package/src/domains/session/compaction/auto.ts +89 -0
  694. package/src/domains/session/compaction/branch-summary.ts +186 -0
  695. package/src/domains/session/compaction/compact.ts +493 -0
  696. package/src/domains/session/compaction/cut-point.ts +171 -0
  697. package/src/domains/session/compaction/defaults.ts +34 -0
  698. package/src/domains/session/compaction/mask-observations.ts +265 -0
  699. package/src/domains/session/compaction/session-entries.ts +18 -0
  700. package/src/domains/session/compaction/tokens.ts +147 -0
  701. package/src/domains/session/context-accounting.ts +583 -0
  702. package/src/domains/session/context-ledger.ts +348 -0
  703. package/src/domains/session/contract.ts +144 -0
  704. package/src/domains/session/cwd-fallback.ts +65 -0
  705. package/src/domains/session/entries.ts +509 -0
  706. package/src/domains/session/extension.ts +322 -0
  707. package/src/domains/session/history.ts +172 -0
  708. package/src/domains/session/index.ts +84 -0
  709. package/src/domains/session/manager.ts +128 -0
  710. package/src/domains/session/manifest.ts +6 -0
  711. package/src/domains/session/migrations/index.ts +27 -0
  712. package/src/domains/session/prompt-manifest.ts +173 -0
  713. package/src/domains/session/protected-artifact-journal.ts +241 -0
  714. package/src/domains/session/protected-artifacts.ts +90 -0
  715. package/src/domains/session/retry.ts +238 -0
  716. package/src/domains/session/task-board.ts +375 -0
  717. package/src/domains/session/tree/active-path.ts +98 -0
  718. package/src/domains/session/tree/fork.ts +160 -0
  719. package/src/domains/session/tree/manager.ts +128 -0
  720. package/src/domains/session/tree/navigator.ts +177 -0
  721. package/src/domains/session/tree/preview.ts +259 -0
  722. package/src/domains/session/usage.ts +148 -0
  723. package/src/domains/session/workspace/git-probe.ts +161 -0
  724. package/src/domains/session/workspace/index.ts +4 -0
  725. package/src/domains/session/workspace/project-type.ts +217 -0
  726. package/src/domains/session/workspace/snapshot.ts +74 -0
  727. package/src/domains/share/archive.ts +684 -0
  728. package/src/domains/share/contract.ts +9 -0
  729. package/src/domains/share/extension.ts +26 -0
  730. package/src/domains/share/index.ts +28 -0
  731. package/src/domains/share/manifest.ts +6 -0
  732. package/src/engine/acp/adapter.ts +397 -0
  733. package/src/engine/acp/errors.ts +32 -0
  734. package/src/engine/acp/event-mapper.ts +154 -0
  735. package/src/engine/acp/server.ts +656 -0
  736. package/src/engine/acp/tool-mediator.ts +686 -0
  737. package/src/engine/acp/transport.ts +654 -0
  738. package/src/engine/acp/types.ts +170 -0
  739. package/src/engine/agent.ts +29 -0
  740. package/src/engine/ai.ts +202 -0
  741. package/src/engine/alcf-oauth.ts +198 -0
  742. package/src/engine/antigravity/subprocess-runtime.ts +205 -0
  743. package/src/engine/apis/degraded-inference.ts +95 -0
  744. package/src/engine/apis/index.ts +20 -0
  745. package/src/engine/apis/llamacpp-residency.ts +252 -0
  746. package/src/engine/apis/lmstudio-native.ts +1438 -0
  747. package/src/engine/apis/lmstudio-residency.ts +92 -0
  748. package/src/engine/apis/ollama-native.ts +507 -0
  749. package/src/engine/apis/openai-completions.ts +716 -0
  750. package/src/engine/apis/output-budget.ts +99 -0
  751. package/src/engine/apis/residency-lock.ts +29 -0
  752. package/src/engine/apis/residency.ts +640 -0
  753. package/src/engine/apis/resident-models.ts +42 -0
  754. package/src/engine/apis/sampling-overrides.ts +38 -0
  755. package/src/engine/apis/thinking-replay.ts +11 -0
  756. package/src/engine/claude/sdk-runtime.ts +685 -0
  757. package/src/engine/claude/session-id.ts +5 -0
  758. package/src/engine/claude/subprocess-runtime.ts +316 -0
  759. package/src/engine/claude/tool-safety.ts +400 -0
  760. package/src/engine/external-subprocess.ts +23 -0
  761. package/src/engine/harmony-response.ts +165 -0
  762. package/src/engine/loop-guard.ts +1127 -0
  763. package/src/engine/oauth.ts +192 -0
  764. package/src/engine/pi-mono-names.ts +13 -0
  765. package/src/engine/provider-payload.ts +315 -0
  766. package/src/engine/select-list.ts +53 -0
  767. package/src/engine/session.ts +834 -0
  768. package/src/engine/strip-tokenizer-sentinels.ts +125 -0
  769. package/src/engine/tui.ts +103 -0
  770. package/src/engine/types.ts +66 -0
  771. package/src/engine/worker-events.ts +100 -0
  772. package/src/engine/worker-runtime.ts +1022 -0
  773. package/src/engine/worker-tools.ts +203 -0
  774. package/src/entry/orchestrator.ts +1873 -0
  775. package/src/interactive/application-controller.ts +346 -0
  776. package/src/interactive/bus-notices.ts +265 -0
  777. package/src/interactive/chat-loop-messages.ts +626 -0
  778. package/src/interactive/chat-loop-policy.ts +18 -0
  779. package/src/interactive/chat-loop.ts +865 -0
  780. package/src/interactive/chat-panel.ts +1694 -0
  781. package/src/interactive/chat-renderer.ts +1038 -0
  782. package/src/interactive/clio-editor.ts +166 -0
  783. package/src/interactive/command-fallbacks.ts +23 -0
  784. package/src/interactive/command-output.ts +85 -0
  785. package/src/interactive/context-activity.ts +203 -0
  786. package/src/interactive/context-meter.ts +223 -0
  787. package/src/interactive/context-overlay.ts +220 -0
  788. package/src/interactive/cost-overlay.ts +279 -0
  789. package/src/interactive/dispatch-board.ts +1319 -0
  790. package/src/interactive/dispatch-steering.ts +86 -0
  791. package/src/interactive/editor-bash.ts +46 -0
  792. package/src/interactive/editor-steer.ts +51 -0
  793. package/src/interactive/editor-submit.ts +303 -0
  794. package/src/interactive/external-editor.ts +67 -0
  795. package/src/interactive/follow-up-queue-panel.ts +75 -0
  796. package/src/interactive/footer/dashboard.ts +534 -0
  797. package/src/interactive/footer/notifications.ts +275 -0
  798. package/src/interactive/footer/widgets.ts +1246 -0
  799. package/src/interactive/footer-panel.ts +187 -0
  800. package/src/interactive/format-time.ts +85 -0
  801. package/src/interactive/index.ts +11 -0
  802. package/src/interactive/interactive-application.ts +755 -0
  803. package/src/interactive/interactive-event-projection.ts +380 -0
  804. package/src/interactive/interactive-input-runtime.ts +261 -0
  805. package/src/interactive/interactive-presentation.ts +452 -0
  806. package/src/interactive/interactive-shell.ts +134 -0
  807. package/src/interactive/interactive-slash-runtime.ts +492 -0
  808. package/src/interactive/interactive-subscriptions.ts +111 -0
  809. package/src/interactive/interactive-tickers.ts +152 -0
  810. package/src/interactive/keybinding-manager.ts +496 -0
  811. package/src/interactive/layout.ts +20 -0
  812. package/src/interactive/leader-key.ts +143 -0
  813. package/src/interactive/loop-guard-interrupt.ts +101 -0
  814. package/src/interactive/memory-overlay.ts +280 -0
  815. package/src/interactive/overlay-ask-user-lifecycle.ts +110 -0
  816. package/src/interactive/overlay-auth-lifecycle.ts +308 -0
  817. package/src/interactive/overlay-frame.ts +502 -0
  818. package/src/interactive/overlay-general-openers.ts +217 -0
  819. package/src/interactive/overlay-key-routing.ts +213 -0
  820. package/src/interactive/overlay-lifecycle.ts +413 -0
  821. package/src/interactive/overlay-model-selectors.ts +127 -0
  822. package/src/interactive/overlay-permission-lifecycle.ts +344 -0
  823. package/src/interactive/overlay-resource-openers.ts +112 -0
  824. package/src/interactive/overlay-session-lifecycle.ts +270 -0
  825. package/src/interactive/overlay-transitions.ts +57 -0
  826. package/src/interactive/overlays/agents.ts +69 -0
  827. package/src/interactive/overlays/ask-user.ts +921 -0
  828. package/src/interactive/overlays/auth-dialog.ts +221 -0
  829. package/src/interactive/overlays/context-reset.ts +108 -0
  830. package/src/interactive/overlays/cwd-fallback.ts +141 -0
  831. package/src/interactive/overlays/extensions.ts +54 -0
  832. package/src/interactive/overlays/help-reference.ts +140 -0
  833. package/src/interactive/overlays/interop.ts +139 -0
  834. package/src/interactive/overlays/keybinding-detail.ts +90 -0
  835. package/src/interactive/overlays/list-overlay.ts +606 -0
  836. package/src/interactive/overlays/message-picker.ts +155 -0
  837. package/src/interactive/overlays/model-selector.ts +1091 -0
  838. package/src/interactive/overlays/prompts.ts +72 -0
  839. package/src/interactive/overlays/session-selector-search.ts +31 -0
  840. package/src/interactive/overlays/session-selector.ts +266 -0
  841. package/src/interactive/overlays/settings.ts +3363 -0
  842. package/src/interactive/overlays/skills-hub.ts +237 -0
  843. package/src/interactive/overlays/tree-selector.ts +387 -0
  844. package/src/interactive/permission-overlay.ts +170 -0
  845. package/src/interactive/render-trace.ts +125 -0
  846. package/src/interactive/renderers/branch-summary.ts +86 -0
  847. package/src/interactive/renderers/code-ink.ts +420 -0
  848. package/src/interactive/renderers/compaction-summary.ts +112 -0
  849. package/src/interactive/renderers/diff.ts +126 -0
  850. package/src/interactive/renderers/notice.ts +28 -0
  851. package/src/interactive/renderers/retry-status.ts +31 -0
  852. package/src/interactive/renderers/structured.ts +89 -0
  853. package/src/interactive/renderers/tool-execution.ts +1104 -0
  854. package/src/interactive/renderers/worker-entry.ts +264 -0
  855. package/src/interactive/session-last-turn.ts +186 -0
  856. package/src/interactive/session-transcript.ts +105 -0
  857. package/src/interactive/session-usage-reseed.ts +74 -0
  858. package/src/interactive/slash-autocomplete.ts +364 -0
  859. package/src/interactive/slash-commands.ts +1319 -0
  860. package/src/interactive/slash-spec.ts +453 -0
  861. package/src/interactive/status/controller.ts +256 -0
  862. package/src/interactive/status/index.ts +23 -0
  863. package/src/interactive/status/state-machine.ts +530 -0
  864. package/src/interactive/status/summary.ts +170 -0
  865. package/src/interactive/status/types.ts +121 -0
  866. package/src/interactive/status/verbs.ts +163 -0
  867. package/src/interactive/status/watchdog.ts +24 -0
  868. package/src/interactive/tasks-overlay.ts +186 -0
  869. package/src/interactive/theme/components.ts +55 -0
  870. package/src/interactive/theme/glyphs.ts +70 -0
  871. package/src/interactive/theme/index.ts +15 -0
  872. package/src/interactive/theme/labels.ts +88 -0
  873. package/src/interactive/theme/rules.ts +138 -0
  874. package/src/interactive/theme/segments.ts +88 -0
  875. package/src/interactive/theme/tokens.ts +121 -0
  876. package/src/interactive/thinking-level-policy.ts +6 -0
  877. package/src/interactive/tool-prose-loop.ts +122 -0
  878. package/src/interactive/tool-prose-registration.ts +48 -0
  879. package/src/interactive/turn-context.ts +854 -0
  880. package/src/interactive/turn-middleware.ts +283 -0
  881. package/src/interactive/turn-persistence.ts +441 -0
  882. package/src/interactive/turn-queues.ts +169 -0
  883. package/src/interactive/turn-recovery.ts +306 -0
  884. package/src/interactive/turn-runtime.ts +802 -0
  885. package/src/interactive/turn-state.ts +123 -0
  886. package/src/interactive/view/artifacts.ts +1342 -0
  887. package/src/interactive/view/view-overlay.ts +732 -0
  888. package/src/interactive/welcome-dashboard.ts +536 -0
  889. package/src/interactive/worker-receipts.ts +94 -0
  890. package/src/interactive/worker-replay.ts +111 -0
  891. package/src/interactive/worker-share.ts +100 -0
  892. package/src/interactive/worker-stream.ts +442 -0
  893. package/src/interactive/workspace-facts.ts +141 -0
  894. package/src/tools/agent-tools.ts +382 -0
  895. package/src/tools/artifact.ts +103 -0
  896. package/src/tools/ask-user.ts +656 -0
  897. package/src/tools/bash.ts +176 -0
  898. package/src/tools/bootstrap.ts +474 -0
  899. package/src/tools/codewiki/code-nav.ts +563 -0
  900. package/src/tools/codewiki/shared.ts +115 -0
  901. package/src/tools/compete-worktrees.ts +898 -0
  902. package/src/tools/context/docs-engine.ts +619 -0
  903. package/src/tools/context/index.ts +435 -0
  904. package/src/tools/credential-present.ts +151 -0
  905. package/src/tools/dispatch-arguments.ts +228 -0
  906. package/src/tools/dispatch-plan.ts +741 -0
  907. package/src/tools/dispatch-scout.ts +461 -0
  908. package/src/tools/dispatch.ts +3338 -0
  909. package/src/tools/edit-diff.ts +534 -0
  910. package/src/tools/edit.ts +128 -0
  911. package/src/tools/executables.ts +22 -0
  912. package/src/tools/file-mutation-queue.ts +35 -0
  913. package/src/tools/find.ts +292 -0
  914. package/src/tools/grep.ts +495 -0
  915. package/src/tools/ignore-policy.ts +169 -0
  916. package/src/tools/ledger.ts +206 -0
  917. package/src/tools/ls.ts +110 -0
  918. package/src/tools/monitor.ts +797 -0
  919. package/src/tools/network-policy.ts +29 -0
  920. package/src/tools/observation.ts +421 -0
  921. package/src/tools/observers.ts +99 -0
  922. package/src/tools/path-utils.ts +79 -0
  923. package/src/tools/policy.ts +154 -0
  924. package/src/tools/profiles.ts +108 -0
  925. package/src/tools/read.ts +173 -0
  926. package/src/tools/registry.ts +1157 -0
  927. package/src/tools/result-shaping.ts +204 -0
  928. package/src/tools/safe-exec.ts +128 -0
  929. package/src/tools/spawn-hygiene.ts +182 -0
  930. package/src/tools/steer.ts +88 -0
  931. package/src/tools/string-enum.ts +15 -0
  932. package/src/tools/tasks.ts +168 -0
  933. package/src/tools/truncate-utf8.ts +17 -0
  934. package/src/tools/truncate.ts +202 -0
  935. package/src/tools/verify/frontend.ts +685 -0
  936. package/src/tools/verify/index.ts +66 -0
  937. package/src/tools/verify/scripts.ts +108 -0
  938. package/src/tools/web-fetch.ts +777 -0
  939. package/src/tools/worker-evidence.ts +215 -0
  940. package/src/tools/write.ts +52 -0
  941. package/src/utils/exif-orientation.ts +192 -0
  942. package/src/utils/git.ts +24 -0
  943. package/src/utils/image-resize.ts +148 -0
  944. package/src/utils/photon.ts +103 -0
  945. package/src/worker/control-lane.ts +22 -0
  946. package/src/worker/entry.ts +257 -0
  947. package/src/worker/event-projection.ts +56 -0
  948. package/src/worker/heartbeat.ts +24 -0
  949. package/src/worker/ledger-mirror.ts +95 -0
  950. package/src/worker/ndjson.ts +40 -0
  951. package/src/worker/protocol.ts +529 -0
  952. package/src/worker/resource-facts.ts +79 -0
  953. package/src/worker/runtime-registry.ts +12 -0
  954. package/src/worker/spec-contract.ts +654 -0
  955. package/src/worker/stdin-demux.ts +316 -0
  956. package/dist/acp-UMLFVA3F.js +0 -92
  957. package/dist/chunk-262G75JS.js +0 -35
  958. package/dist/chunk-5LDRNKX2.js +0 -1063
  959. package/dist/chunk-67MTHP2E.js +0 -135
  960. package/dist/chunk-GOTUR54M.js +0 -9
  961. package/dist/chunk-TPOCL34A.js +0 -2876
  962. package/dist/chunk-XV4ZJ6ZM.js +0 -3177
  963. package/dist/clio-KIQ5SNDS.js +0 -53
  964. package/dist/configure-G4E3A2PG.js +0 -27
  965. package/dist/doctor-M5HJJZOL.js +0 -61
  966. package/dist/domains/agents/builtins/architect.md +0 -33
  967. package/dist/domains/agents/builtins/coder.md +0 -31
  968. package/dist/domains/agents/builtins/context-bootstrap.md +0 -38
  969. package/dist/domains/agents/builtins/debugger.md +0 -30
  970. package/dist/domains/agents/builtins/documenter.md +0 -31
  971. package/dist/domains/agents/builtins/git-master.md +0 -30
  972. package/dist/domains/agents/builtins/provenance.md +0 -30
  973. package/dist/domains/agents/builtins/researcher.md +0 -71
  974. package/dist/domains/agents/builtins/scout.md +0 -42
  975. package/dist/domains/agents/builtins/tester.md +0 -31
  976. package/dist/domains/agents/builtins/verifier.md +0 -30
  977. package/dist/domains/agents/builtins/wiki-writer.md +0 -41
  978. package/dist/fleet-preflight-CLIAX7YR.js +0 -21
  979. package/dist/preload-KZVHET2B.js +0 -11
  980. package/dist/version-ROZ6CZKH.js +0 -16
  981. package/skills/git/commit-crafting/SKILL.md +0 -79
  982. package/skills/git/commit-crafting/evals.md +0 -92
  983. package/skills/git/create-pr/SKILL.md +0 -116
  984. package/skills/git/create-pr/evals.md +0 -114
  985. package/skills/git/investigate-issue/SKILL.md +0 -139
  986. package/skills/git/investigate-issue/evals.md +0 -94
  987. package/skills/git/review-changes/SKILL.md +0 -103
  988. package/skills/git/review-changes/evals.md +0 -85
@@ -0,0 +1,1022 @@
1
+ /**
2
+ * Worker-subprocess engine boundary.
3
+ *
4
+ * Owns the pi-agent-core Agent instance for a worker run and forwards every
5
+ * AgentEvent to an emit callback (the worker entry serializes events to NDJSON
6
+ * stdout). Post-W5 the surface takes a resolved TargetDescriptor +
7
+ * RuntimeDescriptor + wire model id, not a provider/model pair. HTTP/native
8
+ * runtimes stay pi-agent-backed; sanctioned external runtimes branch to their
9
+ * own worker runners before pi-agent model synthesis.
10
+ */
11
+
12
+ import { existsSync, readFileSync } from "node:fs";
13
+ import path from "node:path";
14
+ import { validateSettingsFile } from "../core/config.js";
15
+ import {
16
+ configureGuardrails,
17
+ isWorkerToolCallCapExceededReason,
18
+ isWorkerToolCallCapSynthesisReason,
19
+ } from "../core/guardrails.js";
20
+ import { runtimeSpeaksResponseSchemaDialect } from "../core/response-schema.js";
21
+ import { agentSkillToolPolicy } from "../core/skill-activation.js";
22
+ import { type ToolName, ToolNames } from "../core/tool-names.js";
23
+ import {
24
+ type ObservedReadRanges,
25
+ type ObservedRunEffects,
26
+ parseResultContract,
27
+ RESULT_CONTRACT_REPAIR_LIMIT,
28
+ type ResultContract,
29
+ resultContractRepairMessages,
30
+ validateResultContract,
31
+ } from "../domains/agents/result-contract.js";
32
+ import type { AgentProduct } from "../domains/agents/spec.js";
33
+ import type { MiddlewareSnapshot } from "../domains/middleware/index.js";
34
+ import { createMiddlewareToolChoiceControl } from "../domains/middleware/index.js";
35
+ import { shouldRequestStalledTurnContinuation } from "../domains/middleware/stalled-turn.js";
36
+ import type {
37
+ CapabilityFlags,
38
+ RuntimeDescriptor,
39
+ RuntimeTargetSnapshot,
40
+ TargetDescriptor,
41
+ ThinkingLevel,
42
+ } from "../domains/providers/index.js";
43
+ import { applyModelCapabilityPatch, resolveModelRuntimeCapabilitiesForModel } from "../domains/providers/index.js";
44
+ import { resolveProviderKnowledgeBaseRoots } from "../domains/providers/knowledge-base-path.js";
45
+ import {
46
+ FileKnowledgeBase,
47
+ type KnowledgeBase,
48
+ type KnowledgeBaseHit,
49
+ } from "../domains/providers/types/knowledge-base.js";
50
+ import type { ActionClass } from "../domains/safety/action-classifier.js";
51
+ import type { AutonomyLevel } from "../domains/safety/autonomy.js";
52
+ import { describeCallTarget } from "../domains/safety/call-target.js";
53
+ import { createProtectedArtifactsRegistration } from "../domains/safety/protected-artifacts-registration.js";
54
+ import { createRunEffectsRecorder } from "../domains/safety/run-effects.js";
55
+ import { resolveAgentTools, type ToolTelemetry } from "../tools/agent-tools.js";
56
+ import type { ToolProfileName } from "../tools/profiles.js";
57
+ import { type AgentLedgerPort, canonicalJson } from "../worker/protocol.js";
58
+ import {
59
+ DEFAULT_ESCALATION_FALLBACK,
60
+ DEFAULT_ESCALATION_TIMEOUT_MS,
61
+ WORKER_EXIT_PERMISSION_REQUIRED,
62
+ type WorkerBudget,
63
+ type WorkerEscalationConfig,
64
+ type WorkerPromptMessage,
65
+ type WorkerProtectedArtifactState,
66
+ } from "../worker/spec-contract.js";
67
+ import { createEngineAgent, type EngineAgentOptions } from "./agent.js";
68
+ import { registerFauxFromEnv } from "./ai.js";
69
+ import { startAntigravityWorkerRun } from "./antigravity/subprocess-runtime.js";
70
+ import { registerClioApiProviders, setGlobalDefaultMaxOutputTokens } from "./apis/index.js";
71
+ import { startClaudeSdkWorkerRun } from "./claude/sdk-runtime.js";
72
+ import { startClaudeCodeWorkerRun } from "./claude/subprocess-runtime.js";
73
+ import {
74
+ createLoopGuardRegistration,
75
+ isLoopGuardSynthesisBackstopReason,
76
+ lockedSynthesisFallbackText,
77
+ resolveDeliveryTools,
78
+ sanitizeLockedSynthesisMessage,
79
+ workerLoopBlockBudget,
80
+ } from "./loop-guard.js";
81
+ import { patchWorkerRequestPayload } from "./provider-payload.js";
82
+ import type { AgentEvent, AgentMessage, EngineModel } from "./types.js";
83
+ import type { ClioWorkerEvent } from "./worker-events.js";
84
+ import { createWorkerSafety, createWorkerToolRegistry } from "./worker-tools.js";
85
+
86
+ export interface WorkerRunInput {
87
+ sessionId?: string;
88
+ systemPrompt: string;
89
+ dynamicPromptMessages?: ReadonlyArray<WorkerPromptMessage>;
90
+ agentId: string;
91
+ task: string;
92
+ target: TargetDescriptor;
93
+ runtime: RuntimeDescriptor;
94
+ wireModelId: string;
95
+ modelCapabilities?: Partial<CapabilityFlags>;
96
+ apiKey?: string;
97
+ thinkingLevel?: ThinkingLevel;
98
+ /** JSON Schema enforced by the native llama.cpp request payload. */
99
+ responseSchema?: Record<string, unknown>;
100
+ /** Orchestrator-resolved runtime decision carried on the WorkerSpec. */
101
+ runtimeResolution?: RuntimeTargetSnapshot;
102
+ /**
103
+ * Terminal contract this run's recipe declares. The worker validates its own
104
+ * final result against it and spends bounded repair rounds before exiting,
105
+ * so a model that gathered the right evidence is not failed by the
106
+ * orchestrator for a recoverable shape mistake it was never told about.
107
+ */
108
+ resultContract?: ResultContract;
109
+ /** What this run delivers; decides which delivery tools the reserve keeps live. */
110
+ product?: AgentProduct;
111
+ /**
112
+ * The run's agent-ledger port, present only when this run was dispatched
113
+ * alongside concurrent peers. The ledger tool is registered either way.
114
+ */
115
+ agentLedger?: AgentLedgerPort;
116
+ /** Workspace root the result contract resolves relative paths against. */
117
+ cwd?: string;
118
+ /** Tool ids the worker is allowed to expose for this run. */
119
+ allowedTools: ReadonlyArray<ToolName>;
120
+ /** Dispatch-resolved agent phase policy and independent hard attempt cap. */
121
+ budget: WorkerBudget;
122
+ /**
123
+ * Dispatch-time tool profile that narrowed `allowedTools`. Carried so
124
+ * black-box external CLI runtimes (claude-code, antigravity) that cannot
125
+ * mediate per-tool calls can refuse a narrowing profile instead of silently
126
+ * running their full builtin surface. Undefined or "full-agent" imposes no
127
+ * narrowing.
128
+ */
129
+ toolProfile?: ToolProfileName;
130
+ /** Worker-safe declarative middleware metadata captured by the orchestrator. */
131
+ middlewareSnapshot?: MiddlewareSnapshot;
132
+ /** Frozen parent-session protection state, enforced before every mediated call. */
133
+ protectedArtifactState?: WorkerProtectedArtifactState;
134
+ signal?: AbortSignal;
135
+ noSkills?: boolean;
136
+ skillPaths?: ReadonlyArray<string>;
137
+ /** Recipe-bound skill names; context(scope=skills) admits exactly these for the run. */
138
+ agentSkills?: ReadonlyArray<string>;
139
+ trustProjectCompatRoots?: boolean;
140
+ /** Non-stall posture for permission-requiring tool calls; default "deny". */
141
+ onPermission?: "deny" | "fail" | "escalate";
142
+ /** Escalation bounds, honored only when onPermission="escalate". */
143
+ escalation?: WorkerEscalationConfig;
144
+ /**
145
+ * Session autonomy level captured at dispatch admission (sd-01 §2.5).
146
+ * Workers inherit the orchestrator's level; absent means the default.
147
+ */
148
+ autonomy?: AutonomyLevel;
149
+ /**
150
+ * Absolute directories write-class tool calls are confined to for this run.
151
+ * Enforced at the shared worker safety seam (createWorkerSafety) so both the
152
+ * native registry and the Claude SDK hook path block out-of-root writes.
153
+ */
154
+ writeRoots?: ReadonlyArray<string>;
155
+ }
156
+
157
+ export interface WorkerRunResult {
158
+ messages: AgentMessage[];
159
+ exitCode: number;
160
+ }
161
+
162
+ export interface WorkerRunHandle {
163
+ promise: Promise<WorkerRunResult>;
164
+ abort(): void;
165
+ /**
166
+ * Queue operator guidance on a runtime that exposes a live input API. Absent
167
+ * for single-shot subprocess runtimes. Returns true only after the runtime
168
+ * accepts the input; a steer that races run completion may return false.
169
+ */
170
+ steer?(text: string): boolean | Promise<boolean>;
171
+ /**
172
+ * Apply an operator decision to a parked escalation. Present only on native
173
+ * pi-agent workers (the runtimes with a registry park loop); external
174
+ * runners omit it. Returns false when the requestId is unknown or already
175
+ * resolved (duplicate), so callers can drop the line without crashing.
176
+ */
177
+ resolvePermission?(requestId: string, decision: "approve" | "deny"): boolean;
178
+ }
179
+
180
+ export type WorkerEventEmit = (event: AgentEvent | ClioWorkerEvent) => void;
181
+
182
+ function isAssistantMessage(
183
+ message: AgentMessage | undefined,
184
+ ): message is AgentMessage & { role: "assistant"; stopReason?: string; errorMessage?: string } {
185
+ if (typeof message !== "object" || message === null) return false;
186
+ return "role" in message && message.role === "assistant";
187
+ }
188
+
189
+ function getTerminalAgentError(messages: AgentMessage[]): string | null {
190
+ for (let i = messages.length - 1; i >= 0; i--) {
191
+ const message = messages[i];
192
+ if (!isAssistantMessage(message)) continue;
193
+ if (message.stopReason !== "error") return null;
194
+ return typeof message.errorMessage === "string" ? message.errorMessage : "";
195
+ }
196
+ return null;
197
+ }
198
+
199
+ function assistantMessageText(message: AgentMessage | undefined): string | null {
200
+ if (!isAssistantMessage(message) || !Array.isArray(message.content)) return null;
201
+ return message.content
202
+ .filter((block): block is { type: "text"; text: string } => block.type === "text" && typeof block.text === "string")
203
+ .map((block) => block.text)
204
+ .join("")
205
+ .trim();
206
+ }
207
+
208
+ /**
209
+ * Whether this assistant message ends the run. A message that carries tool
210
+ * calls is mid-run and states no result yet; an errored message already fails
211
+ * the run through its own path.
212
+ */
213
+ function isTerminalAssistantMessage(message: AgentMessage | undefined): boolean {
214
+ if (!isAssistantMessage(message)) return false;
215
+ return message.stopReason !== "toolUse" && message.stopReason !== "error";
216
+ }
217
+
218
+ /**
219
+ * Why this run's terminal message misses its contract, or null when it holds.
220
+ * A message that announces further work fails even when it parses, because the
221
+ * synthesis lock means no further work will happen.
222
+ */
223
+ function terminalContractViolation(
224
+ contract: ResultContract,
225
+ message: AgentMessage | undefined,
226
+ cwd: string,
227
+ observedReadRanges: ObservedReadRanges,
228
+ observedRunEffects: ObservedRunEffects,
229
+ ): string | null {
230
+ if (!isAssistantMessage(message)) return null;
231
+ const text = assistantMessageText(message);
232
+ if (text === null || text.length === 0) return "missing final result";
233
+ // The loop guard already replaced this reply with its own notice, so there is
234
+ // no model result here to judge against a shape. Reporting the contract's
235
+ // shape anyway sent the repair directive, the receipt, and the operator after
236
+ // a JSON formatting problem that never existed: a bootstrap run that spiraled
237
+ // through 45 tool calls and lost its answer to the lockout was reported as
238
+ // "result must be valid JSON".
239
+ if (text.trim() === lockedSynthesisFallbackText()) {
240
+ return "the reply after the tool-call lockout held only tool-call markup and was removed; tools are off, so state the final result as plain text";
241
+ }
242
+ const stopReason = message.stopReason;
243
+ if (
244
+ shouldRequestStalledTurnContinuation({
245
+ hook: "turn_end",
246
+ text,
247
+ metadata: { turnToolCalls: 0, ...(typeof stopReason === "string" ? { stopReason } : {}) },
248
+ })
249
+ ) {
250
+ return "the response announced further work instead of stating the final result";
251
+ }
252
+ const validation = validateResultContract({
253
+ contract,
254
+ output: text,
255
+ cwd,
256
+ observedReadRanges,
257
+ observedRunEffects,
258
+ // Repair rounds judge shape and grounding only. Network posture belongs to
259
+ // the orchestrator's sealed validation, which runs again on the receipt.
260
+ networkAllowed: true,
261
+ filesystem: {
262
+ readFile(filePath) {
263
+ try {
264
+ return readFileSync(filePath, "utf8");
265
+ } catch {
266
+ return null;
267
+ }
268
+ },
269
+ pathExists(filePath) {
270
+ return existsSync(filePath);
271
+ },
272
+ },
273
+ });
274
+ return validation.conformance === "pass" ? null : (validation.reason ?? "invalid result");
275
+ }
276
+
277
+ class NullKnowledgeBase implements KnowledgeBase {
278
+ lookup(_modelId: string): KnowledgeBaseHit | null {
279
+ return null;
280
+ }
281
+ entries() {
282
+ return [];
283
+ }
284
+ }
285
+
286
+ let kbSingleton: KnowledgeBase | null = null;
287
+
288
+ function getKnowledgeBase(): KnowledgeBase {
289
+ if (kbSingleton) return kbSingleton;
290
+ try {
291
+ const roots = resolveProviderKnowledgeBaseRoots(import.meta.url);
292
+ kbSingleton = roots.length > 0 ? new FileKnowledgeBase(roots) : new NullKnowledgeBase();
293
+ } catch {
294
+ kbSingleton = new NullKnowledgeBase();
295
+ }
296
+ return kbSingleton;
297
+ }
298
+
299
+ function clampThinkingLevelForModel(model: EngineModel, requested: ThinkingLevel | undefined): ThinkingLevel {
300
+ const level = requested ?? "off";
301
+ return resolveModelRuntimeCapabilitiesForModel(model, level).thinking.effectiveLevel;
302
+ }
303
+
304
+ function promptMessage(fragment: WorkerPromptMessage): AgentMessage {
305
+ return {
306
+ role: "user",
307
+ content: [{ type: "text", text: fragment.body }],
308
+ timestamp: Date.now(),
309
+ } as AgentMessage;
310
+ }
311
+
312
+ function taskMessage(task: string): AgentMessage {
313
+ return {
314
+ role: "user",
315
+ content: [{ type: "text", text: task }],
316
+ timestamp: Date.now(),
317
+ } as AgentMessage;
318
+ }
319
+
320
+ function promptMessagesForWorker(input: WorkerRunInput): AgentMessage[] {
321
+ const messages = (input.dynamicPromptMessages ?? []).map(promptMessage);
322
+ messages.push(taskMessage(input.task));
323
+ return messages;
324
+ }
325
+
326
+ /**
327
+ * Whether the resolved runtime mediates tool calls at all. Exported so the
328
+ * worker entry attests the same tool surface this run will actually build.
329
+ */
330
+ export function workerProviderSupportsTools(input: WorkerRunInput): boolean {
331
+ const runtimeDecision = input.runtimeResolution?.capabilities.tools;
332
+ if (runtimeDecision !== undefined) return runtimeDecision === true;
333
+ if (typeof input.modelCapabilities?.tools === "boolean") return input.modelCapabilities.tools;
334
+ return input.runtime.defaultCapabilities.tools === true;
335
+ }
336
+
337
+ function assertResponseSchemaRuntime(input: WorkerRunInput): void {
338
+ if (input.responseSchema === undefined) return;
339
+ if (
340
+ runtimeSpeaksResponseSchemaDialect(input.runtime) &&
341
+ input.modelCapabilities?.structuredOutputs === "json-schema"
342
+ ) {
343
+ return;
344
+ }
345
+ throw new Error(
346
+ `responseSchema requires a native llamacpp runtime with resolved JSON-schema support; received '${input.runtime.id}'`,
347
+ );
348
+ }
349
+
350
+ /** Return the admitted worker specification budget unchanged. */
351
+ function resolveWorkerRuntimeBudget(input: Pick<WorkerRunInput, "budget">): WorkerBudget {
352
+ return input.budget;
353
+ }
354
+
355
+ /**
356
+ * Spin up a pi-agent-core Agent for the worker subprocess. Subscribes an event
357
+ * sink that forwards every AgentEvent to `emit`. Starts one run via
358
+ * `agent.prompt(task)`. Returns a handle with the final promise and an abort
359
+ * function; the promise resolves when `agent.waitForIdle()` returns.
360
+ */
361
+ export function startWorkerRun(input: WorkerRunInput, emit: WorkerEventEmit): WorkerRunHandle {
362
+ assertResponseSchemaRuntime(input);
363
+ // The wire carries the contract as data; the one strict parser owns its
364
+ // shape. The worker subprocess may not import it (it stays slim), so the
365
+ // check lands here, before any model call.
366
+ if (input.resultContract !== undefined) parseResultContract(input.resultContract, "WorkerSpec.resultContract");
367
+ if (input.runtime.id === "claude-sdk") {
368
+ return startClaudeSdkWorkerRun(input, emit);
369
+ }
370
+ if (input.runtime.id === "claude-code") {
371
+ return startClaudeCodeWorkerRun(input, emit);
372
+ }
373
+ if (input.runtime.id === "antigravity-code") {
374
+ return startAntigravityWorkerRun(input, emit);
375
+ }
376
+
377
+ // pi-ai is process-local. The orchestrator registers Clio API providers in
378
+ // providers/extension.ts, but the worker subprocess starts a fresh process,
379
+ // so it must register them here before any agent.prompt() touches a local
380
+ // runtime (lmstudio-native, ollama-native).
381
+ registerClioApiProviders();
382
+ // The worker is a fresh process; mirror the orchestrator's global output
383
+ // budget so dispatched runs honor settings.defaults.maxTokens too. Use the
384
+ // non-throwing read: a worker must not abort over a settings issue the parent
385
+ // already surfaced.
386
+ const workerSettings = validateSettingsFile().settings;
387
+ setGlobalDefaultMaxOutputTokens(workerSettings.defaults.maxTokens);
388
+ // Same mirroring for guardrail policy: the worker's loop-guard cap and tool
389
+ // byte caps resolve settings-first, so the fresh process needs the section
390
+ // installed before any registry or tool construction reads it.
391
+ configureGuardrails(workerSettings.guardrails);
392
+ const fauxModel = registerFauxFromEnv();
393
+ // Workers are bounded runs against an admission-verified recipe surface.
394
+ // They have no operator to widen a missing tool, so the active surface is
395
+ // exactly the admitted set.
396
+ const agentSkillPolicy =
397
+ input.allowedTools.includes(ToolNames.Context) && input.noSkills !== true
398
+ ? agentSkillToolPolicy(input.agentSkills ?? [])
399
+ : undefined;
400
+ const activeWorkerTools = workerProviderSupportsTools(input) ? input.allowedTools : [];
401
+
402
+ const kb = getKnowledgeBase();
403
+ const kbHit = kb.lookup(input.wireModelId);
404
+ const synthesized = input.runtime.synthesizeModel(input.target, input.wireModelId, kbHit);
405
+ const model = applyModelCapabilityPatch(
406
+ input.target.runtime === "faux" && fauxModel ? fauxModel : synthesized,
407
+ input.modelCapabilities,
408
+ );
409
+
410
+ // Per-run safety contract: one loop-detector state per worker subprocess.
411
+ // The loop guard rides on the registry's middleware contract as a
412
+ // before_tool registration (engine/loop-guard.ts), so admission and
413
+ // repetition detection share one seam; there is no agent-loop hook anymore.
414
+ const safety = createWorkerSafety({
415
+ cwd: process.cwd(),
416
+ ...(input.writeRoots !== undefined ? { writeRoots: input.writeRoots } : {}),
417
+ ...(input.protectedArtifactState !== undefined
418
+ ? { protectedArtifactState: { artifacts: [...input.protectedArtifactState.artifacts] } }
419
+ : {}),
420
+ });
421
+ // Flipped by the loop guard's lockout callback; read by onPayload below to
422
+ // force the remaining model rounds text-only via tool_choice none.
423
+ let synthesisToolLock = false;
424
+ let workerBoundFailure: string | null = null;
425
+ let workerBoundAborted = false;
426
+ let abortWorkerForBound: (() => void) | null = null;
427
+ // For synthesis:false, the loop guard records the final admitted call while
428
+ // rejecting later siblings immediately. The runtime stops only after pi has
429
+ // emitted that call's tool-result message, so a slow tool is never aborted
430
+ // merely because its before_tool admission reached the agent boundary.
431
+ // Unset (null) never matches. A call admitted without a provider id arms
432
+ // the explicit wildcard, which cannot collide with any real result id.
433
+ const STOP_AFTER_ANY_TOOL_RESULT = Symbol("stop-after-any-tool-result");
434
+ let stopAfterToolResultCallId: string | typeof STOP_AFTER_ANY_TOOL_RESULT | null = null;
435
+ const workerBudget = resolveWorkerRuntimeBudget(input);
436
+ const readReserve = input.allowedTools.includes(ToolNames.Read) ? workerBudget.readReserve : 0;
437
+ // The reserve ends discovery, not the run's own product. An agent that was
438
+ // granted mutation tools delivers by writing, so those stay admitted in the
439
+ // reserve window; a read-only agent has none and the window stays read-only.
440
+ const deliveryTools = resolveDeliveryTools(input.allowedTools, input.product);
441
+ const middlewareToolChoice = createMiddlewareToolChoiceControl();
442
+ // Tool calls emitted by one provider response share this correlation. The
443
+ // loop guard counts synthesis-lock noncompliance by model round, preventing
444
+ // one wide parallel batch from consuming the entire denial backstop.
445
+ let workerModelRound = 0;
446
+ const registry = createWorkerToolRegistry(
447
+ input.middlewareSnapshot,
448
+ safety,
449
+ {
450
+ ...(input.noSkills !== undefined ? { noSkills: input.noSkills } : {}),
451
+ ...(input.skillPaths !== undefined ? { skillPaths: [...input.skillPaths] } : {}),
452
+ ...(input.trustProjectCompatRoots !== undefined ? { trustProjectCompatRoots: input.trustProjectCompatRoots } : {}),
453
+ },
454
+ // Workers run unattended, so the loop guard carries the hard tool-call
455
+ // cap in addition to repetition blocking, plus the synthesis lockout:
456
+ // after the loop-block budget the worker is told to report from what it
457
+ // gathered instead of burning the lifetime cap on a retry spiral, and
458
+ // the bounded backstop reason is watched in telemetry.onFinish below to
459
+ // abort a worker that keeps calling tools anyway.
460
+ // The protected-artifacts guard starts from the parent-session snapshot
461
+ // and has no persistence sink. It can still absorb worker-local
462
+ // protect_path effects from snapshot rules for the rest of this run.
463
+ [
464
+ createLoopGuardRegistration({
465
+ safety,
466
+ toolCallCap: workerBudget.hardCap,
467
+ toolCallSoftLimit: workerBudget.toolCalls,
468
+ // A worker's blocks all land in one run-long bucket, so the bound on
469
+ // them is a statement about this run's length, not about a turn.
470
+ turnBlockBudget: workerLoopBlockBudget(workerBudget.toolCalls),
471
+ toolCallSoftReadReserve: readReserve,
472
+ ...(deliveryTools.length > 0 ? { deliveryTools } : {}),
473
+ turnSynthesisLockout: workerBudget.synthesis,
474
+ // Once locked, the next model round is forced text-only at the
475
+ // request level (the tool surface is removed in onPayload below):
476
+ // the lockout directive alone relies on model compliance, and
477
+ // measured local models kept calling tools until the backstop
478
+ // aborted the run, or answered the forced round with tool-call
479
+ // markup that the loop guard then removed.
480
+ onSynthesisLockout: () => {
481
+ if (workerBudget.synthesis) {
482
+ synthesisToolLock = true;
483
+ }
484
+ },
485
+ ...(!workerBudget.synthesis
486
+ ? {
487
+ onSoftLimitFinalCallAdmitted: (toolCallId: string | undefined) => {
488
+ if (workerBoundFailure === null) {
489
+ workerBoundFailure = `worker agent budget reached (${workerBudget.toolCalls}); synthesis is disabled`;
490
+ }
491
+ // Native agent tool calls carry a stable provider id. The wildcard
492
+ // keeps even an invariant violation on the post-result path
493
+ // instead of reintroducing a before_tool abort.
494
+ stopAfterToolResultCallId = toolCallId ?? STOP_AFTER_ANY_TOOL_RESULT;
495
+ },
496
+ }
497
+ : {}),
498
+ // Forcing the next round to `read` is only correct when reading is
499
+ // the whole reserve. An agent with delivery tools must be able to
500
+ // write in its own reserve window, so it gets the steering directive
501
+ // without the request-level lock.
502
+ ...(readReserve > 0 && deliveryTools.length === 0
503
+ ? {
504
+ onSoftReadReserve: () => {
505
+ middlewareToolChoice.apply([{ kind: "require_tool", toolName: ToolNames.Read }]);
506
+ },
507
+ }
508
+ : {}),
509
+ }),
510
+ createProtectedArtifactsRegistration({
511
+ ...(input.protectedArtifactState !== undefined
512
+ ? { initialState: { artifacts: [...input.protectedArtifactState.artifacts] } }
513
+ : {}),
514
+ }),
515
+ ],
516
+ input.autonomy,
517
+ (effects) => middlewareToolChoice.apply(effects),
518
+ input.agentLedger,
519
+ );
520
+ const contractCwd = input.cwd ?? process.cwd();
521
+ let resultContractRepairsQueued = 0;
522
+ /** Read tool call id -> what was asked for, pending that call's result. */
523
+ const pendingReadCitations = new Map<string, { path: string; offset: number | null; tail: boolean }>();
524
+ const observedReadRanges = new Map<string, Array<readonly [number, number]>>();
525
+ // The write-side equivalent: what this run changed and what it validated,
526
+ // so a mutation report is judged against the run instead of believed.
527
+ const runEffects = createRunEffectsRecorder(contractCwd);
528
+
529
+ /**
530
+ * Fold one successful read into the observed spans. The request says where
531
+ * the model aimed; the result says how many lines it actually received.
532
+ * Only their combination is an honest span, because a byte-capped or
533
+ * end-of-file read returns less than the window that was asked for.
534
+ */
535
+ const recordObservedRead = (
536
+ request: { path: string; offset: number | null; tail: boolean },
537
+ result: unknown,
538
+ ): void => {
539
+ const observation = (result as { details?: { observation?: Record<string, unknown> } } | null)?.details?.observation;
540
+ if (!observation) return;
541
+ const shown = observation.shownCount;
542
+ const total = observation.totalCount;
543
+ if (typeof shown !== "number" || !Number.isFinite(shown) || shown <= 0) return;
544
+ // A tail read lands at the end of the file, so it can only be placed once
545
+ // the total line count is known; without it the span is dropped rather
546
+ // than guessed, which costs a citation but never invents grounding.
547
+ let start: number;
548
+ if (request.tail) {
549
+ if (typeof total !== "number" || !Number.isFinite(total)) return;
550
+ start = Math.max(1, Math.floor(total) - shown + 1);
551
+ } else {
552
+ start = request.offset ?? 1;
553
+ }
554
+ const key = path.resolve(contractCwd, request.path);
555
+ const spans = observedReadRanges.get(key) ?? [];
556
+ spans.push([start, start + shown - 1] as const);
557
+ observedReadRanges.set(key, spans);
558
+ };
559
+
560
+ /** Spans quoted back to the model, as `path:start-end`. */
561
+ const observedReadAnchors = (): string[] =>
562
+ [...observedReadRanges.entries()].flatMap(([key, spans]) =>
563
+ spans.map(([start, end]) => `${path.relative(contractCwd, key) || key}:${start}-${end}`),
564
+ );
565
+ const telemetry: ToolTelemetry = {
566
+ onStart(event) {
567
+ emit({ type: "clio_tool_start", payload: event });
568
+ },
569
+ onFinish(event) {
570
+ emit({ type: "clio_tool_finish", payload: event });
571
+ if (event.outcome !== "blocked" || typeof event.reason !== "string") return;
572
+ // Lifetime-cap lockout: record the bound (the run must not seal as an
573
+ // ordinary success) but do not abort. The loop guard has flipped the
574
+ // synthesis tool lock, so the next model round runs text-only and the
575
+ // synthesized answer still reaches message_end and the receipt.
576
+ if (isWorkerToolCallCapSynthesisReason(event.reason)) {
577
+ emit({ type: "clio_run_outcome", payload: { outcomeCode: "worker_tool_call_cap_exhausted" } });
578
+ if (workerBoundFailure === null) {
579
+ workerBoundFailure = event.reason;
580
+ process.stderr.write(`[worker] ${event.reason}\n`);
581
+ }
582
+ return;
583
+ }
584
+ // Hard bounds: the legacy immediate cap abort (lockout not wired) and
585
+ // the synthesis backstop for a model that keeps emitting tool calls
586
+ // after the lock. Both end the run; the first recorded bound wins the
587
+ // receipt diagnostic.
588
+ if (isWorkerToolCallCapExceededReason(event.reason) || isLoopGuardSynthesisBackstopReason(event.reason)) {
589
+ emit({
590
+ type: "clio_run_outcome",
591
+ payload: {
592
+ outcomeCode: isLoopGuardSynthesisBackstopReason(event.reason)
593
+ ? "loop_guard_tools_disabled_exhausted"
594
+ : "worker_tool_call_cap_exhausted",
595
+ },
596
+ });
597
+ if (workerBoundAborted) return;
598
+ workerBoundAborted = true;
599
+ if (workerBoundFailure === null) workerBoundFailure = event.reason;
600
+ process.stderr.write(`[worker] ${event.reason}\n`);
601
+ abortWorkerForBound?.();
602
+ }
603
+ },
604
+ };
605
+ const tools = resolveAgentTools({
606
+ registry,
607
+ telemetry,
608
+ allowedTools: activeWorkerTools,
609
+ agentId: input.agentId,
610
+ task: input.task,
611
+ includeInteractiveTools: false,
612
+ invokeOptions: () => ({
613
+ correlationId: `worker-model-round-${workerModelRound}`,
614
+ ...(agentSkillPolicy ? { pendingSkillPolicy: agentSkillPolicy } : {}),
615
+ }),
616
+ });
617
+ if (tools.length === 0 && activeWorkerTools.length > 0) {
618
+ process.stderr.write(`[worker] warning: no tools resolved for allowed=[${activeWorkerTools.join(",")}]\n`);
619
+ }
620
+ const effectiveThinkingLevel = clampThinkingLevelForModel(
621
+ model,
622
+ input.runtimeResolution?.effectiveThinkingLevel ?? input.thinkingLevel,
623
+ );
624
+
625
+ const options: EngineAgentOptions = {
626
+ initialState: {
627
+ systemPrompt: input.systemPrompt,
628
+ model,
629
+ thinkingLevel: effectiveThinkingLevel,
630
+ tools,
631
+ messages: [],
632
+ },
633
+ onPayload: async (payload, currentModel) => {
634
+ const middlewareChoice = middlewareToolChoice.current();
635
+ return patchWorkerRequestPayload(payload, currentModel, {
636
+ runtimeId: input.runtime.id,
637
+ thinkingLevel: effectiveThinkingLevel,
638
+ ...(input.responseSchema !== undefined ? { responseSchema: input.responseSchema } : {}),
639
+ toolSurfaceLocked: synthesisToolLock,
640
+ toolChoiceNone: middlewareChoice.kind === "none",
641
+ ...(middlewareChoice.kind === "required" ? { toolChoiceName: middlewareChoice.toolName } : {}),
642
+ });
643
+ },
644
+ getApiKey: async () => input.apiKey,
645
+ };
646
+ if (input.sessionId) options.sessionId = input.sessionId;
647
+
648
+ const { agent } = createEngineAgent(options);
649
+ // The result-contract repair queues a call/result pair that must land in
650
+ // one drain, or the provider sees a lone assistant tool call.
651
+ agent.followUpMode = "all";
652
+ abortWorkerForBound = () => agent.abort();
653
+ const unsubscribe = agent.subscribe(async (event) => {
654
+ if (event.type === "turn_start") workerModelRound += 1;
655
+ if (event.type === "tool_execution_start") middlewareToolChoice.toolStarted(event.toolName);
656
+ // Read spans this run actually observed. They ground the terminal result
657
+ // (a cited line has to fall inside one) and they are handed back verbatim
658
+ // in a repair round, so re-emitting findings never invites invention.
659
+ if (event.type === "tool_execution_start") {
660
+ runEffects.start(event.toolCallId, event.toolName, event.args as Record<string, unknown>);
661
+ }
662
+ if (event.type === "tool_execution_end") {
663
+ runEffects.finish(event.toolCallId, event.isError === true);
664
+ }
665
+ if (event.type === "tool_execution_start" && event.toolName === ToolNames.Read) {
666
+ const args = event.args as Record<string, unknown>;
667
+ const readPath = typeof args.path === "string" ? args.path.trim() : "";
668
+ const offset =
669
+ typeof args.offset === "number" && Number.isFinite(args.offset) && args.offset > 0 ? Math.floor(args.offset) : null;
670
+ if (readPath.length > 0) {
671
+ pendingReadCitations.set(event.toolCallId, { path: readPath, offset, tail: args.tail !== undefined });
672
+ }
673
+ }
674
+ if (event.type === "tool_execution_end" && event.toolName === ToolNames.Read) {
675
+ const request = pendingReadCitations.get(event.toolCallId);
676
+ pendingReadCitations.delete(event.toolCallId);
677
+ if (request !== undefined && event.isError !== true) recordObservedRead(request, event.result);
678
+ }
679
+ // Synthesis-locked run: a model that ignores tool_choice none emits its
680
+ // chat template's tool-call syntax as plain text. Sanitize the finished
681
+ // message in place before it hits stdout; pi stores this same object in
682
+ // agent state, so the NDJSON event, the dispatch consumer's answer
683
+ // reconstruction, and any later provider round all see the same text.
684
+ if (synthesisToolLock && event.type === "message_end") {
685
+ sanitizeLockedSynthesisMessage(event.message);
686
+ }
687
+ // Bounded terminal-contract repair, on whichever message ends the run.
688
+ // A worker that finishes inside its budget never trips the synthesis
689
+ // lock, so gating this on the lock would skip repair on exactly the
690
+ // well-behaved runs it exists to save. The orchestrator validates the
691
+ // same contract against the sealed receipt; this is the only point at
692
+ // which the model can still act on the validator's reason.
693
+ const contract = input.resultContract;
694
+ if (contract && event.type === "message_end" && isTerminalAssistantMessage(event.message)) {
695
+ const violation = terminalContractViolation(
696
+ contract,
697
+ event.message,
698
+ contractCwd,
699
+ observedReadRanges,
700
+ runEffects.snapshot(),
701
+ );
702
+ if (violation !== null) {
703
+ if (resultContractRepairsQueued < RESULT_CONTRACT_REPAIR_LIMIT) {
704
+ resultContractRepairsQueued += 1;
705
+ // A repair round is terminal by construction, so enforce the
706
+ // directive's own claim that tool use is over at the request
707
+ // level instead of trusting the model to honor it.
708
+ synthesisToolLock = true;
709
+ // Delivered as a paired tool exchange, never a user turn. Templates
710
+ // that key history rendering off the last `user` message re-render
711
+ // every earlier assistant turn when one is appended mid-run, which
712
+ // invalidates the whole prompt cache: Nemotron reprocessed 11,352
713
+ // tokens for this directive as `user` against 407 for the same
714
+ // bytes as a tool result (#55). The synthetic assistant call gives
715
+ // the result a real tool_call_id for strict endpoints (#62).
716
+ const repair = resultContractRepairMessages(
717
+ { contract, reason: violation, attempt: resultContractRepairsQueued, anchors: observedReadAnchors() },
718
+ { provider: model.provider, api: model.api, model: model.id },
719
+ );
720
+ for (const message of repair) agent.followUp(message as unknown as AgentMessage);
721
+ } else if (workerBoundFailure === null) {
722
+ workerBoundFailure = `result contract failed after ${RESULT_CONTRACT_REPAIR_LIMIT} bounded repair rounds: ${violation}`;
723
+ emit({ type: "clio_run_outcome", payload: { outcomeCode: "result_contract_exhausted" } });
724
+ process.stderr.write(`[worker] ${workerBoundFailure}\n`);
725
+ }
726
+ }
727
+ }
728
+ emit(event);
729
+ if (
730
+ stopAfterToolResultCallId !== null &&
731
+ event.type === "message_end" &&
732
+ event.message.role === "toolResult" &&
733
+ (stopAfterToolResultCallId === STOP_AFTER_ANY_TOOL_RESULT || event.message.toolCallId === stopAfterToolResultCallId)
734
+ ) {
735
+ stopAfterToolResultCallId = null;
736
+ workerBoundAborted = true;
737
+ abortWorkerForBound?.();
738
+ }
739
+ });
740
+
741
+ // Non-stall guarantee (Symphony §10.5): a dispatched worker has no
742
+ // operator by default, so a permission-requiring tool call must never park
743
+ // forever. "deny" resolves the parked call as a structured denial and the
744
+ // run continues; "fail" denies it and aborts the run, which then exits with
745
+ // the dedicated permission-required code so the orchestrator can resolve
746
+ // the outcome as failed/permission_required without racing the event
747
+ // stream; "escalate" parks the call, hands the decision up to the operator
748
+ // over the event/stdin channels, and applies the configured deny/fail
749
+ // fallback on timeout so the run still cannot hang forever.
750
+ const onPermission = input.onPermission ?? "deny";
751
+ const escalationConfig: WorkerEscalationConfig | null =
752
+ onPermission === "escalate"
753
+ ? {
754
+ timeoutMs: input.escalation?.timeoutMs ?? DEFAULT_ESCALATION_TIMEOUT_MS,
755
+ fallback: input.escalation?.fallback ?? DEFAULT_ESCALATION_FALLBACK,
756
+ }
757
+ : null;
758
+ let permissionFailure = false;
759
+
760
+ // Exact, byte-stable denial reasons for the deny/fail postures. Escalate
761
+ // timeouts and operator denials use their own wording below.
762
+ const denyReason = (tool: string, actionClass: string): string =>
763
+ `permission denied by policy: dispatched workers run non-interactively (workers.onPermission=deny); ${tool} requires ${actionClass} confirmation`;
764
+ const failReason = (tool: string, actionClass: string): string =>
765
+ `permission required for ${tool} (${actionClass}); workers.onPermission=fail ends this run`;
766
+
767
+ interface ActiveEscalation {
768
+ requestId: string;
769
+ tool: string;
770
+ actionClass: ActionClass;
771
+ /** Identity of the parked call (tool plus canonical args) for the answered-escalation memory. */
772
+ callKey: string;
773
+ timer: ReturnType<typeof setTimeout>;
774
+ }
775
+ let activeEscalation: ActiveEscalation | null = null;
776
+ // Answered escalations, keyed by the exact call. A worker that re-issues
777
+ // the identical call after the operator already decided it gets the same
778
+ // answer without a new card: a live coder re-asked one bash approval eight
779
+ // times after its edits were done, and each approval only bought the next
780
+ // identical card (#79). The memory is per run and per exact (tool, args)
781
+ // tuple; a different command is a new decision.
782
+ const answeredEscalations = new Map<string, { decision: "approve" | "deny"; requestId: string }>();
783
+ const escalationCallKey = (tool: string, args: Record<string, unknown> | undefined): string =>
784
+ `${tool}\u0000${canonicalJson(args ?? {})}`;
785
+ const clearActiveEscalation = (): void => {
786
+ if (activeEscalation) {
787
+ clearTimeout(activeEscalation.timer);
788
+ activeEscalation = null;
789
+ }
790
+ };
791
+
792
+ // One escalation is outstanding at a time. A call that parks while a prior
793
+ // escalation awaits a decision is re-notified after the active one resolves
794
+ // (registry.resumeParkedCalls re-fires onPermissionRequired for the next
795
+ // parked call), so it never gets lost and the requestId->parked-call
796
+ // mapping stays unambiguous.
797
+ const resolveEscalation = (
798
+ requestId: string,
799
+ decision: "approve" | "deny",
800
+ source: "operator" | "timeout",
801
+ ): boolean => {
802
+ const active = activeEscalation;
803
+ if (!active || active.requestId !== requestId) return false;
804
+ clearActiveEscalation();
805
+ answeredEscalations.set(active.callKey, { decision, requestId });
806
+ if (decision === "approve") {
807
+ emit({
808
+ type: "clio_permission_resolved",
809
+ payload: {
810
+ tool: active.tool,
811
+ actionClass: active.actionClass,
812
+ mode: "escalate",
813
+ source,
814
+ requestId,
815
+ decision: "approved",
816
+ reason: `operator approved permission escalation for ${active.tool} (${active.actionClass})`,
817
+ },
818
+ } as ClioWorkerEvent);
819
+ void registry.resumeParkedCalls({
820
+ actionClass: active.actionClass,
821
+ requestId,
822
+ requestedBy: `escalation:${source}`,
823
+ });
824
+ return true;
825
+ }
826
+ // A denial resolves to the effective posture: a timeout with fallback
827
+ // "fail" ends the run like posture fail; every other denial mirrors
828
+ // posture deny, so the structured tool denial the model sees (including
829
+ // the "permission denied" reason) is identical to the deny posture.
830
+ const effectiveFail = source === "timeout" && escalationConfig?.fallback === "fail";
831
+ const mode: "deny" | "fail" = effectiveFail ? "fail" : "deny";
832
+ const denialContext = source === "timeout" ? "escalation timed out with no operator decision" : "operator denied";
833
+ const reason = effectiveFail
834
+ ? `permission required for ${active.tool} (${active.actionClass}); ${denialContext} and workers fallback=fail ends this run`
835
+ : `permission denied by ${source === "timeout" ? "escalation timeout fallback" : "operator"}: ${active.tool} requires ${active.actionClass} confirmation`;
836
+ emit({
837
+ type: "clio_permission_resolved",
838
+ payload: {
839
+ tool: active.tool,
840
+ actionClass: active.actionClass,
841
+ mode,
842
+ source,
843
+ requestId,
844
+ decision: "denied",
845
+ reason,
846
+ },
847
+ } as ClioWorkerEvent);
848
+ if (effectiveFail) {
849
+ permissionFailure = true;
850
+ registry.cancelParkedCalls(reason);
851
+ agent.abort();
852
+ return true;
853
+ }
854
+ if (source === "operator") registry.cancelParkedCall(requestId, reason);
855
+ else registry.cancelParkedCalls(reason);
856
+ return true;
857
+ };
858
+
859
+ const denyActiveEscalationOnAbort = (reason: string): void => {
860
+ const active = activeEscalation;
861
+ if (!active) return;
862
+ emit({
863
+ type: "clio_permission_resolved",
864
+ payload: {
865
+ tool: active.tool,
866
+ actionClass: active.actionClass,
867
+ mode: "escalate",
868
+ source: "operator",
869
+ requestId: active.requestId,
870
+ decision: "denied",
871
+ reason,
872
+ },
873
+ } as ClioWorkerEvent);
874
+ clearActiveEscalation();
875
+ };
876
+
877
+ const unsubscribePermission = registry.onPermissionRequired((call, decision, meta) => {
878
+ const actionClass = decision.classification.actionClass;
879
+ if (escalationConfig) {
880
+ const callKey = escalationCallKey(call.tool, call.args);
881
+ const remembered = answeredEscalations.get(callKey);
882
+ if (remembered !== undefined) {
883
+ const approved = remembered.decision === "approve";
884
+ const reason = approved
885
+ ? `operator approved an identical ${call.tool} call earlier in this run (request ${remembered.requestId}); the answer stands without a new prompt`
886
+ : `permission denied by operator: an identical ${call.tool} call was already denied earlier in this run (request ${remembered.requestId}); the answer stands, so do not repeat this call`;
887
+ emit({
888
+ type: "clio_permission_resolved",
889
+ payload: {
890
+ tool: call.tool,
891
+ actionClass,
892
+ mode: "escalate",
893
+ source: "remembered",
894
+ requestId: meta.requestId,
895
+ decision: approved ? "approved" : "denied",
896
+ reason,
897
+ },
898
+ } as ClioWorkerEvent);
899
+ if (approved) {
900
+ void registry.resumeParkedCalls({
901
+ actionClass,
902
+ requestId: meta.requestId,
903
+ requestedBy: "escalation:remembered",
904
+ });
905
+ } else {
906
+ registry.cancelParkedCall(meta.requestId, reason);
907
+ }
908
+ return;
909
+ }
910
+ if (activeEscalation !== null) return;
911
+ const requestId = meta.requestId;
912
+ // The timer must hold the event loop: its firing is what denies an
913
+ // escalation the orchestrator never resolves. clearActiveEscalation
914
+ // clears it on every resolution path.
915
+ const timer = setTimeout(() => resolveEscalation(requestId, "deny", "timeout"), escalationConfig.timeoutMs);
916
+ activeEscalation = { requestId, tool: call.tool, actionClass, callKey, timer };
917
+ // The operator decides on this exact call, so the escalation carries a
918
+ // sanitized preview of its object; the args stay inside the worker. The
919
+ // cap bounds the NDJSON line, and the overlay truncates further.
920
+ const target = describeCallTarget(call.args).slice(0, 200);
921
+ emit({
922
+ type: "clio_permission_escalated",
923
+ payload: {
924
+ requestId,
925
+ tool: call.tool,
926
+ summary: `${call.tool} requires ${actionClass} confirmation`,
927
+ ...(target.length > 0 ? { target } : {}),
928
+ axis: meta.axis,
929
+ decision: {
930
+ actionClass,
931
+ reasons: decision.classification.reasons,
932
+ ...(decision.policy?.reasonCode ? { reasonCode: decision.policy.reasonCode } : {}),
933
+ ...(decision.policy?.ruleId ? { ruleId: decision.policy.ruleId } : {}),
934
+ ...(decision.policy?.policySource ? { policySource: decision.policy.policySource } : {}),
935
+ },
936
+ timeoutMs: escalationConfig.timeoutMs,
937
+ },
938
+ } as ClioWorkerEvent);
939
+ return;
940
+ }
941
+ const reason = onPermission === "fail" ? failReason(call.tool, actionClass) : denyReason(call.tool, actionClass);
942
+ emit({
943
+ type: "clio_permission_resolved",
944
+ payload: {
945
+ tool: call.tool,
946
+ actionClass,
947
+ mode: onPermission,
948
+ source: "policy",
949
+ requestId: meta.requestId,
950
+ reason,
951
+ },
952
+ } as ClioWorkerEvent);
953
+ if (onPermission === "fail") {
954
+ permissionFailure = true;
955
+ registry.cancelParkedCalls(reason);
956
+ agent.abort();
957
+ return;
958
+ }
959
+ registry.cancelParkedCalls(reason);
960
+ });
961
+
962
+ const promise = (async (): Promise<WorkerRunResult> => {
963
+ try {
964
+ await agent.prompt(promptMessagesForWorker(input));
965
+ await agent.waitForIdle();
966
+ unsubscribe();
967
+ if (workerBoundFailure !== null) {
968
+ return { messages: agent.state.messages, exitCode: 1 };
969
+ }
970
+ if (permissionFailure) {
971
+ return { messages: agent.state.messages, exitCode: WORKER_EXIT_PERMISSION_REQUIRED };
972
+ }
973
+ const messages = agent.state.messages;
974
+ const errorMessage = getTerminalAgentError(messages);
975
+ if (errorMessage !== null) {
976
+ if (errorMessage.length > 0) {
977
+ process.stderr.write(`[worker] agent ended with stopReason=error: ${errorMessage}\n`);
978
+ }
979
+ return { messages, exitCode: 1 };
980
+ }
981
+ return { messages, exitCode: 0 };
982
+ } catch (err) {
983
+ unsubscribe();
984
+ if (workerBoundFailure !== null) {
985
+ return { messages: agent.state.messages, exitCode: 1 };
986
+ }
987
+ if (permissionFailure) {
988
+ return { messages: agent.state.messages, exitCode: WORKER_EXIT_PERMISSION_REQUIRED };
989
+ }
990
+ const msg = err instanceof Error ? err.message : String(err);
991
+ emit({ type: "agent_end", messages: agent.state.messages });
992
+ process.stderr.write(`[worker] agent error: ${msg}\n`);
993
+ return { messages: agent.state.messages, exitCode: 1 };
994
+ } finally {
995
+ clearActiveEscalation();
996
+ unsubscribePermission();
997
+ }
998
+ })();
999
+
1000
+ return {
1001
+ promise,
1002
+ abort: () => {
1003
+ // Under escalate a parked call would otherwise keep waitForIdle from
1004
+ // returning, so cancel it before aborting. cancelParkedCalls is a
1005
+ // no-op when nothing is parked, so deny/fail abort stays unchanged.
1006
+ if (escalationConfig) {
1007
+ const reason = "run aborted while a permission escalation was pending";
1008
+ denyActiveEscalationOnAbort(reason);
1009
+ registry.cancelParkedCalls(reason);
1010
+ }
1011
+ agent.abort();
1012
+ },
1013
+ steer: (text: string) => {
1014
+ const trimmed = text.trim();
1015
+ if (trimmed.length === 0) return false;
1016
+ agent.steer(taskMessage(trimmed));
1017
+ return true;
1018
+ },
1019
+ resolvePermission: (requestId: string, decision: "approve" | "deny") =>
1020
+ resolveEscalation(requestId, decision, "operator"),
1021
+ };
1022
+ }