@iowarp/clio-coder 0.3.0 → 0.3.2

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 (1187) hide show
  1. package/CHANGELOG.md +123 -2
  2. package/CONTRIBUTING.md +23 -23
  3. package/README.md +295 -627
  4. package/dist/acp-BIYHVZIM.js +128 -0
  5. package/dist/{agents-Q4MYPMUW.js → agents-YT6SSRIT.js} +52 -27
  6. package/dist/assets/codewiki.json +1 -0
  7. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/LICENSE +21 -0
  8. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/cgmanifest.json +16 -0
  9. package/dist/assets/grammars/notices/tree-sitter-wasms/LICENSE +24 -0
  10. package/dist/assets/grammars/tree-sitter-c-sharp.wasm +0 -0
  11. package/dist/assets/grammars/tree-sitter-c.wasm +0 -0
  12. package/dist/assets/grammars/tree-sitter-cpp.wasm +0 -0
  13. package/dist/assets/grammars/tree-sitter-go.wasm +0 -0
  14. package/dist/assets/grammars/tree-sitter-java.wasm +0 -0
  15. package/dist/assets/grammars/tree-sitter-javascript.wasm +0 -0
  16. package/dist/assets/grammars/tree-sitter-python.wasm +0 -0
  17. package/dist/assets/grammars/tree-sitter-ruby.wasm +0 -0
  18. package/dist/assets/grammars/tree-sitter-rust.wasm +0 -0
  19. package/dist/assets/grammars/tree-sitter-tsx.wasm +0 -0
  20. package/dist/assets/grammars/tree-sitter-typescript.wasm +0 -0
  21. package/dist/assets/grammars/tree-sitter.wasm +0 -0
  22. package/dist/{auth-O6HYIJ6J.js → auth-5TWEIYDN.js} +30 -15
  23. package/dist/chunk-2EHAIA3X.js +481 -0
  24. package/dist/{chunk-ME6DNWIU.js → chunk-2IR2NMPA.js} +12 -4
  25. package/dist/chunk-2SFS6XQE.js +122 -0
  26. package/dist/{chunk-KKKPTZLM.js → chunk-2STGEDFV.js} +8 -1
  27. package/dist/chunk-2VTFPG5O.js +48 -0
  28. package/dist/chunk-3I7MS7N2.js +40 -0
  29. package/dist/chunk-3R73A4XB.js +69 -0
  30. package/dist/{chunk-JPOWPFCU.js → chunk-3ZXDFGR5.js} +52 -23
  31. package/dist/chunk-4BJ5BYCE.js +61 -0
  32. package/dist/{chunk-26BZQOAD.js → chunk-4BPJXDWC.js} +161 -260
  33. package/dist/chunk-4KLWL3UC.js +18 -0
  34. package/dist/{chunk-5LDRNKX2.js → chunk-4VP4KH3K.js} +161 -262
  35. package/dist/chunk-4ZG3XFUR.js +77 -0
  36. package/dist/chunk-5B2AEOW5.js +5407 -0
  37. package/dist/chunk-5TSRNF4G.js +510 -0
  38. package/dist/{chunk-WD6AJM35.js → chunk-5UUP6MWO.js} +48 -69
  39. package/dist/{chunk-X3BR7HWV.js → chunk-5WIGXA4T.js} +7 -1
  40. package/dist/chunk-65DEGPJ6.js +52 -0
  41. package/dist/chunk-6EJMN2Y3.js +17 -0
  42. package/dist/chunk-6EJV5X2W.js +16405 -0
  43. package/dist/chunk-6N5PTWMY.js +136 -0
  44. package/dist/chunk-6XLNIQDB.js +27 -0
  45. package/dist/{chunk-XNISANGE.js → chunk-77VKQEHF.js} +171 -74
  46. package/dist/chunk-7CR24IG7.js +242 -0
  47. package/dist/{chunk-UWIJNAOB.js → chunk-7EYHLWU7.js} +907 -638
  48. package/dist/chunk-7MNJORFF.js +22 -0
  49. package/dist/{chunk-JWHCJDCI.js → chunk-A3CYT5EX.js} +257 -79
  50. package/dist/chunk-AGYYIBLL.js +1069 -0
  51. package/dist/chunk-AO4RKG4M.js +277 -0
  52. package/dist/chunk-APJ265NV.js +7410 -0
  53. package/dist/chunk-ARBGF5F7.js +174 -0
  54. package/dist/{chunk-TFSSEXL6.js → chunk-BMEMKKIT.js} +14 -4
  55. package/dist/{chunk-X3NE4WVW.js → chunk-BNAZZHFG.js} +7 -1
  56. package/dist/chunk-CBCAPZAA.js +229 -0
  57. package/dist/{chunk-QV47YRF4.js → chunk-CGKSTWHD.js} +7 -1
  58. package/dist/chunk-CMZWFGD2.js +352 -0
  59. package/dist/chunk-ECH6PKUQ.js +39 -0
  60. package/dist/{chunk-67MTHP2E.js → chunk-ED4KHGC3.js} +13 -5
  61. package/dist/chunk-EKMEHE4H.js +340 -0
  62. package/dist/{chunk-O4EJEDHO.js → chunk-EPVUXGXG.js} +50 -35
  63. package/dist/chunk-FCSXB6T2.js +338 -0
  64. package/dist/chunk-FJ3H4MN5.js +48 -0
  65. package/dist/chunk-FQ4SKYE4.js +29 -0
  66. package/dist/chunk-G2DE3C7R.js +644 -0
  67. package/dist/chunk-G4BMMOKF.js +182 -0
  68. package/dist/{chunk-7BHLZB3A.js → chunk-GGXXDWE4.js} +190 -1218
  69. package/dist/chunk-HC4CLZ2Y.js +68 -0
  70. package/dist/{chunk-E3NYWENM.js → chunk-HFSBBKSQ.js} +55 -61
  71. package/dist/chunk-HKIYEGME.js +30 -0
  72. package/dist/chunk-I4HZDVNP.js +73 -0
  73. package/dist/chunk-IGLFWIYI.js +161 -0
  74. package/dist/chunk-IHXBNWMM.js +137 -0
  75. package/dist/chunk-IKCO5N3L.js +162 -0
  76. package/dist/chunk-IR4CFBFN.js +56 -0
  77. package/dist/{chunk-DXQNI4PC.js → chunk-IWHMRKLL.js} +8 -1
  78. package/dist/{chunk-VOO7NYPP.js → chunk-J5HN4RYU.js} +27 -9
  79. package/dist/{chunk-4UQA7NCT.js → chunk-J5Q24KAG.js} +7 -2
  80. package/dist/{chunk-KBR4MZZR.js → chunk-JVCV3ICN.js} +7 -1
  81. package/dist/chunk-KJ5LWLOE.js +1077 -0
  82. package/dist/chunk-LBMZMYH2.js +285 -0
  83. package/dist/{chunk-3DANZDGR.js → chunk-LBNRH5WM.js} +100 -161
  84. package/dist/{chunk-TKHQ4DGZ.js → chunk-LZSJBIVT.js} +7358 -7414
  85. package/dist/{chunk-UGYAX5YI.js → chunk-M6SHUN7Q.js} +13 -8
  86. package/dist/chunk-MAW544W2.js +1882 -0
  87. package/dist/chunk-MBS4V7ZP.js +217 -0
  88. package/dist/{chunk-2J63S4SF.js → chunk-MFFY33HR.js} +167 -140
  89. package/dist/chunk-MNA4JGU4.js +255 -0
  90. package/dist/chunk-MQSRRFWA.js +3428 -0
  91. package/dist/{chunk-RQDWMVRB.js → chunk-MVVUPGPW.js} +138 -137
  92. package/dist/chunk-OAO4GE4M.js +619 -0
  93. package/dist/chunk-OHHN2SO4.js +5135 -0
  94. package/dist/chunk-OKGUZO2U.js +34 -0
  95. package/dist/{chunk-BBUH4VAA.js → chunk-OOJYHWRB.js} +60 -361
  96. package/dist/{chunk-D5YD55AR.js → chunk-OQ33BKR3.js} +12 -1
  97. package/dist/chunk-OQE5J4C6.js +73 -0
  98. package/dist/{chunk-AMFR5YA3.js → chunk-ORBHGJC5.js} +26 -12
  99. package/dist/chunk-POHLU5DW.js +1186 -0
  100. package/dist/chunk-QKMUKYO7.js +4961 -0
  101. package/dist/{chunk-7RBKDI66.js → chunk-QTYWRVRA.js} +104 -12
  102. package/dist/{chunk-5N2FG33Q.js → chunk-R346GLFC.js} +7 -1
  103. package/dist/chunk-SRF2PJNW.js +184 -0
  104. package/dist/chunk-SST6Z5JA.js +80 -0
  105. package/dist/{chunk-XV4ZJ6ZM.js → chunk-STBPMHSX.js} +473 -1194
  106. package/dist/{chunk-HBU5MTAM.js → chunk-SVNXH4L2.js} +7 -1
  107. package/dist/chunk-T6YILFSB.js +80 -0
  108. package/dist/chunk-TXOTCRLG.js +15 -0
  109. package/dist/chunk-TZTZS7QK.js +227 -0
  110. package/dist/chunk-UOV2BYIW.js +107 -0
  111. package/dist/{chunk-527KG6XR.js → chunk-V4RXGQ5Q.js} +72 -185
  112. package/dist/chunk-VAKQQHWR.js +434 -0
  113. package/dist/chunk-VG7TBQIY.js +128 -0
  114. package/dist/chunk-VJWL6YS5.js +244 -0
  115. package/dist/chunk-WEH5XRJQ.js +32 -0
  116. package/dist/{chunk-VPAWTYLY.js → chunk-WEPFGWHJ.js} +7 -1
  117. package/dist/chunk-WMSVI4G2.js +2095 -0
  118. package/dist/chunk-WVO7V2QY.js +797 -0
  119. package/dist/chunk-X4RCMKVQ.js +641 -0
  120. package/dist/chunk-X75S7HFS.js +374 -0
  121. package/dist/chunk-XN3L4EYL.js +46 -0
  122. package/dist/{chunk-HMYNFFY4.js → chunk-XPLRXC72.js} +7 -2
  123. package/dist/{chunk-PIDUD6M2.js → chunk-YCWGATWI.js} +12 -5
  124. package/dist/chunk-YHZX5GEU.js +193 -0
  125. package/dist/chunk-YXLYO42X.js +91 -0
  126. package/dist/{chunk-UHTSULZS.js → chunk-ZDOOVTXZ.js} +38 -73
  127. package/dist/chunk-ZI647VB5.js +37 -0
  128. package/dist/{chunk-CLJ5HLUD.js → chunk-ZWLZP4ZT.js} +25 -6
  129. package/dist/cli/index.js +70 -56
  130. package/dist/clio-4LY5K2AC.js +25 -0
  131. package/dist/code-nav-7AX6FYE6.js +600 -0
  132. package/dist/codewiki/build-worker.js +66 -0
  133. package/dist/compile-cache-CVJMMODC.js +18 -0
  134. package/dist/{components-JVHMUBEB.js → components-KELWS457.js} +31 -9
  135. package/dist/{config-ZFCDBMDC.js → config-GTLUW2PR.js} +104 -56
  136. package/dist/configure-R6A64DHX.js +42 -0
  137. package/dist/context-5VKGUVJJ.js +866 -0
  138. package/dist/{context-CDXTP2MP.js → context-JFZEJ7W5.js} +21 -13
  139. package/dist/{context-E3KIFVXI.js → context-RW5HC47S.js} +77 -36
  140. package/dist/{context-clear-3F4PLXOS.js → context-clear-6ZHBAZZT.js} +64 -30
  141. package/dist/{context-index-Q7YSYTR3.js → context-index-BZ4UYMTC.js} +36 -24
  142. package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
  143. package/dist/{docs-YIETIWZI.js → docs-2C2LTVT2.js} +32 -13
  144. package/dist/doctor-KI767GSN.js +87 -0
  145. package/dist/{eval-B3KZZESM.js → eval-XSSNATB4.js} +93 -27
  146. package/dist/{evidence-V67CHM35.js → evidence-UA6AWDQQ.js} +55 -27
  147. package/dist/{evolve-YDZSUQYA.js → evolve-QNTFGV6Z.js} +59 -26
  148. package/dist/{extensions-SRG7XCAH.js → extensions-QVDOHDGJ.js} +23 -8
  149. package/dist/{fleet-CA2CRTVG.js → fleet-Q7UOMUSG.js} +173 -56
  150. package/dist/fleet-preflight-DDN536IT.js +26 -0
  151. package/dist/{init-2OZDJE2D.js → init-WBB65ZHQ.js} +79 -34
  152. package/dist/{memory-3PIQQAKX.js → memory-MD3O64RI.js} +57 -28
  153. package/dist/{models-DY35XI7Y.js → models-BZU34YWD.js} +49 -24
  154. package/dist/monitor-MEQA5C3I.js +661 -0
  155. package/dist/{chunk-PS4PFJQP.js → orchestrator-CGFKEP27.js} +22837 -18564
  156. package/dist/{paths-5OMXW7Z4.js → paths-UXLN5YYZ.js} +17 -6
  157. package/dist/preload-P6DGH2PZ.js +13 -0
  158. package/dist/{reset-PIFYNOS3.js → reset-L2FQEE3E.js} +25 -13
  159. package/dist/{run-3VSPP24F.js → run-IV4Q6RLN.js} +115 -63
  160. package/dist/{share-D36RQCXM.js → share-S5BZQC5I.js} +23 -10
  161. package/dist/{skills-F2MRLELY.js → skills-LQEKRDTN.js} +42 -15
  162. package/dist/{skills-eval-E2ZTW4PL.js → skills-eval-3DC4HEWS.js} +90 -45
  163. package/dist/steer-GGWFUJUD.js +77 -0
  164. package/dist/{targets-DZMEZAH4.js → targets-C4SSGQOB.js} +78 -60
  165. package/dist/terminal-lease-IT5JW2NR.js +395 -0
  166. package/dist/{trace-7NYCUI2J.js → trace-PNCASAXC.js} +48 -17
  167. package/dist/tree-sitter-HGKH6LG4.js +4673 -0
  168. package/dist/{uninstall-AD3JWHBB.js → uninstall-FZCQCDKC.js} +19 -8
  169. package/dist/{upgrade-WYYBKGDY.js → upgrade-7TT7SQ3G.js} +66 -24
  170. package/dist/{usage-ULIDAGFF.js → usage-GV4PKT3M.js} +71 -32
  171. package/dist/verify-G6V4D2G7.js +716 -0
  172. package/dist/version-KGEG7EPO.js +21 -0
  173. package/dist/web-fetch-2YHJ3KTG.js +638 -0
  174. package/dist/{wiki-generate-PKFIX6OB.js → wiki-generate-DQF6Z66B.js} +98 -48
  175. package/dist/worker/entry.js +297 -54
  176. package/dist/workspace-G4ZWUIPR.js +22 -0
  177. package/docs/README.md +29 -21
  178. package/docs/acp.md +191 -16
  179. package/docs/alcf-provider.md +1 -1
  180. package/docs/architecture.md +157 -7
  181. package/docs/artifact-placement.md +101 -0
  182. package/docs/artifact-versions.md +1 -1
  183. package/docs/built-in-agents.md +4 -2
  184. package/docs/capacity-and-scheduling.md +1 -1
  185. package/docs/commands-and-modes.md +224 -97
  186. package/docs/config-knobs-audit.md +1 -3
  187. package/docs/configuration-and-targets.md +236 -38
  188. package/docs/context-engine.md +34 -7
  189. package/docs/development-pipeline.md +102 -0
  190. package/docs/dispatch-architecture-rationale.md +1 -1
  191. package/docs/documentation-coverage.md +4 -4
  192. package/docs/documentation-guide.md +3 -3
  193. package/docs/environment-variables.md +15 -6
  194. package/docs/eval-runner.md +3 -3
  195. package/docs/evals-internal.md +2 -2
  196. package/docs/evidence-and-memory.md +10 -2
  197. package/docs/evolution.md +2 -2
  198. package/docs/exit-codes-and-output.md +15 -9
  199. package/docs/extensions-and-sharing.md +25 -18
  200. package/docs/fleet-demo-runbook.md +22 -23
  201. package/docs/fleet-dispatch.md +117 -16
  202. package/docs/git-commit-provenance.md +120 -0
  203. package/docs/glossary.md +107 -15
  204. package/docs/installation-and-lifecycle.md +75 -17
  205. package/docs/middleware-and-components.md +1 -1
  206. package/docs/model-catalog.md +46 -15
  207. package/docs/observability.md +8 -5
  208. package/docs/performance-methodology.md +491 -0
  209. package/docs/pi-boundary.md +72 -0
  210. package/docs/proactive-memory.md +14 -14
  211. package/docs/prompt-envelope-and-tools.md +25 -4
  212. package/docs/provider-adapter-cookbook.md +57 -4
  213. package/docs/release-cut-checklist.md +129 -111
  214. package/docs/safety-model.md +28 -8
  215. package/docs/scientific-validation.md +3 -3
  216. package/docs/session-lifecycle.md +55 -12
  217. package/docs/skills-marketplace.md +12 -8
  218. package/docs/time-conventions.md +101 -0
  219. package/docs/tool-usage.md +6 -5
  220. package/docs/trace-store.md +1 -1
  221. package/docs/troubleshooting.md +10 -7
  222. package/docs/tui-design.md +121 -28
  223. package/docs/worker-dispatch-mechanics.md +3 -3
  224. package/package.json +33 -36
  225. package/skills/README.md +5 -6
  226. package/skills/coding/ast-grep/SKILL.md +136 -0
  227. package/skills/coding/ast-grep/evals.md +56 -0
  228. package/skills/coding/ast-grep/references/rule_reference.md +297 -0
  229. package/skills/coding/coding-standards/SKILL.md +113 -0
  230. package/skills/coding/coding-standards/evals.md +34 -0
  231. package/skills/coding/prototype/SKILL.md +86 -0
  232. package/skills/coding/prototype/evals.md +42 -0
  233. package/skills/coding/prototype/references/LOGIC.md +67 -0
  234. package/skills/coding/prototype/references/UI.md +112 -0
  235. package/skills/coding/tdd/SKILL.md +101 -0
  236. package/skills/coding/tdd/evals.md +41 -0
  237. package/skills/coding/tdd/references/mocking.md +59 -0
  238. package/skills/coding/tdd/references/tests.md +77 -0
  239. package/skills/context/context-handoff/SKILL.md +126 -0
  240. package/skills/context/context-handoff/evals.md +57 -0
  241. package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
  242. package/skills/context/context-prime/SKILL.md +95 -0
  243. package/skills/context/context-prime/evals.md +54 -0
  244. package/skills/git/file-ticket/SKILL.md +107 -0
  245. package/skills/git/file-ticket/evals.md +54 -0
  246. package/skills/git/fix-issue/SKILL.md +106 -0
  247. package/skills/git/fix-issue/evals.md +71 -0
  248. package/skills/git/ship/SKILL.md +92 -0
  249. package/skills/git/ship/evals.md +72 -0
  250. package/skills/meta/clio-dev/SKILL.md +91 -0
  251. package/skills/meta/clio-dev/evals.md +45 -0
  252. package/skills/meta/clio-test/SKILL.md +130 -0
  253. package/skills/meta/clio-test/evals.md +43 -0
  254. package/skills/meta/clio-test/references/harness.md +97 -0
  255. package/skills/meta/clio-test/references/test-map.md +59 -0
  256. package/skills/meta/credentials/SKILL.md +125 -0
  257. package/skills/meta/credentials/evals.md +104 -0
  258. package/skills/meta/find-skills/SKILL.md +72 -0
  259. package/skills/meta/find-skills/evals.md +47 -0
  260. package/skills/meta/herdr/SKILL.md +127 -0
  261. package/skills/meta/herdr/evals.md +38 -0
  262. package/skills/meta/skill-craft/SKILL.md +102 -0
  263. package/skills/meta/skill-craft/evals.md +41 -0
  264. package/skills/planning/architecture/SKILL.md +129 -0
  265. package/skills/planning/architecture/evals.md +36 -0
  266. package/skills/planning/backlog/SKILL.md +90 -0
  267. package/skills/planning/backlog/evals.md +43 -0
  268. package/skills/planning/prd/SKILL.md +82 -0
  269. package/skills/planning/prd/evals.md +49 -0
  270. package/skills/planning/product-intent/SKILL.md +112 -0
  271. package/skills/planning/product-intent/evals.md +36 -0
  272. package/skills/planning/tech-spec/SKILL.md +115 -0
  273. package/skills/planning/tech-spec/evals.md +47 -0
  274. package/skills/registry.yaml +136 -0
  275. package/skills/research/arxiv-literature/SKILL.md +104 -0
  276. package/skills/research/arxiv-literature/evals.md +58 -0
  277. package/skills/research/experiment-protocol/SKILL.md +122 -0
  278. package/skills/research/experiment-protocol/evals.md +91 -0
  279. package/skills/research/scientific-debugging/SKILL.md +119 -0
  280. package/skills/research/scientific-debugging/evals.md +138 -0
  281. package/skills/research/scientific-modernization/SKILL.md +138 -0
  282. package/skills/research/scientific-modernization/evals.md +84 -0
  283. package/skills/skill-marketplace.json +12 -20
  284. package/skills/workflow/design-council/SKILL.md +139 -0
  285. package/skills/workflow/design-council/evals.md +97 -0
  286. package/skills/workflow/grill-me/SKILL.md +186 -0
  287. package/skills/workflow/grill-me/evals.md +78 -0
  288. package/skills/workflow/workflow-distiller/SKILL.md +136 -0
  289. package/skills/workflow/workflow-distiller/evals.md +107 -0
  290. package/src/cli/acp.ts +115 -0
  291. package/src/cli/agents.ts +60 -0
  292. package/src/cli/args.ts +280 -0
  293. package/src/cli/argv.ts +170 -0
  294. package/src/cli/ask.ts +34 -0
  295. package/src/cli/auth.ts +468 -0
  296. package/src/cli/bootstrap-generate.ts +498 -0
  297. package/src/cli/clio.ts +96 -0
  298. package/src/cli/components.ts +195 -0
  299. package/src/cli/config-inspect.ts +336 -0
  300. package/src/cli/config.ts +72 -0
  301. package/src/cli/configure-interop.ts +67 -0
  302. package/src/cli/configure-layout.ts +172 -0
  303. package/src/cli/configure.ts +1525 -0
  304. package/src/cli/context-clear.ts +76 -0
  305. package/src/cli/context-index.ts +100 -0
  306. package/src/cli/context.ts +321 -0
  307. package/src/cli/default-target.ts +55 -0
  308. package/src/cli/docs.ts +346 -0
  309. package/src/cli/doctor.ts +54 -0
  310. package/src/cli/eval.ts +315 -0
  311. package/src/cli/evidence.ts +225 -0
  312. package/src/cli/evolve.ts +219 -0
  313. package/src/cli/extensions.ts +214 -0
  314. package/src/cli/fleet.ts +868 -0
  315. package/src/cli/index.ts +338 -0
  316. package/src/cli/init.ts +219 -0
  317. package/src/cli/initial-message.ts +47 -0
  318. package/src/cli/internal-dispatch.ts +55 -0
  319. package/src/cli/memory.ts +182 -0
  320. package/src/cli/models.ts +257 -0
  321. package/src/cli/modes/json-stream.ts +121 -0
  322. package/src/cli/modes/jsonl.ts +9 -0
  323. package/src/cli/modes/print.ts +604 -0
  324. package/src/cli/oauth-manual-input.ts +72 -0
  325. package/src/cli/oauth-select.ts +36 -0
  326. package/src/cli/output-guard.ts +48 -0
  327. package/src/cli/paths.ts +44 -0
  328. package/src/cli/provider-target.ts +113 -0
  329. package/src/cli/removal.ts +72 -0
  330. package/src/cli/reset.ts +253 -0
  331. package/src/cli/run.ts +497 -0
  332. package/src/cli/share.ts +243 -0
  333. package/src/cli/shared.ts +60 -0
  334. package/src/cli/skills-eval.ts +1240 -0
  335. package/src/cli/skills.ts +485 -0
  336. package/src/cli/steer-channel.ts +86 -0
  337. package/src/cli/targets.ts +1154 -0
  338. package/src/cli/text-layout.ts +112 -0
  339. package/src/cli/trace.ts +322 -0
  340. package/src/cli/uninstall.ts +405 -0
  341. package/src/cli/upgrade.ts +286 -0
  342. package/src/cli/usage.ts +876 -0
  343. package/src/cli/validate-model.ts +28 -0
  344. package/src/cli/version.ts +7 -0
  345. package/src/cli/wiki-generate.ts +510 -0
  346. package/src/core/agent-environment.ts +7 -0
  347. package/src/core/artifact-paths.ts +43 -0
  348. package/src/core/bash-exec.ts +313 -0
  349. package/src/core/boot-trace.ts +42 -0
  350. package/src/core/bus-events.ts +744 -0
  351. package/src/core/bus-trace.ts +53 -0
  352. package/src/core/c-header-language.ts +265 -0
  353. package/src/core/clio-repo.ts +78 -0
  354. package/src/core/commit-attribution.ts +157 -0
  355. package/src/core/compile-cache.ts +159 -0
  356. package/src/core/config.ts +1722 -0
  357. package/src/core/context-floor.ts +33 -0
  358. package/src/core/defaults.ts +659 -0
  359. package/src/core/domain-loader.ts +177 -0
  360. package/src/core/event-bus.ts +94 -0
  361. package/src/core/file-references.ts +282 -0
  362. package/src/core/git-commit-attribution.ts +362 -0
  363. package/src/core/guardrails.ts +185 -0
  364. package/src/core/headless-permission.ts +21 -0
  365. package/src/core/incomplete-installation.ts +45 -0
  366. package/src/core/init.ts +223 -0
  367. package/src/core/json-payload.ts +58 -0
  368. package/src/core/package-root.ts +54 -0
  369. package/src/core/path-canonical.ts +37 -0
  370. package/src/core/process-identity.ts +41 -0
  371. package/src/core/recent-models.ts +91 -0
  372. package/src/core/residency-protection.ts +56 -0
  373. package/src/core/resolve-config-value.ts +88 -0
  374. package/src/core/response-schema.ts +279 -0
  375. package/src/core/run-overrides.ts +77 -0
  376. package/src/core/safe-exec.ts +205 -0
  377. package/src/core/safe-id.ts +37 -0
  378. package/src/core/safe-resource-write.ts +162 -0
  379. package/src/core/session-routing.ts +339 -0
  380. package/src/core/settings-layers.ts +354 -0
  381. package/src/core/shared-bus.ts +8 -0
  382. package/src/core/shell-quote.ts +26 -0
  383. package/src/core/skill-activation.ts +190 -0
  384. package/src/core/startup-timer.ts +37 -0
  385. package/src/core/state-file-lock.ts +219 -0
  386. package/src/core/termination.ts +275 -0
  387. package/src/core/timers.ts +38 -0
  388. package/src/core/tool-names.ts +65 -0
  389. package/src/core/verification-scripts.ts +13 -0
  390. package/src/core/workspace-files.ts +492 -0
  391. package/src/core/xdg.ts +177 -0
  392. package/src/domains/agents/builtins/architect.md +4 -4
  393. package/src/domains/agents/builtins/coder.md +3 -2
  394. package/src/domains/agents/builtins/debugger.md +1 -1
  395. package/src/domains/agents/builtins/documenter.md +1 -1
  396. package/src/domains/agents/builtins/git-master.md +3 -3
  397. package/src/domains/agents/builtins/provenance.md +1 -1
  398. package/src/domains/agents/builtins/researcher.md +1 -1
  399. package/src/domains/agents/builtins/scout.md +1 -1
  400. package/src/domains/agents/builtins/tester.md +1 -1
  401. package/src/domains/agents/builtins/verifier.md +1 -1
  402. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  403. package/src/domains/agents/catalog.ts +172 -0
  404. package/src/domains/agents/contract.ts +16 -0
  405. package/src/domains/agents/extension.ts +110 -0
  406. package/src/domains/agents/fleet-commands.ts +154 -0
  407. package/src/domains/agents/fleet-contract.ts +797 -0
  408. package/src/domains/agents/frontmatter.ts +40 -0
  409. package/src/domains/agents/index.ts +102 -0
  410. package/src/domains/agents/manifest.ts +6 -0
  411. package/src/domains/agents/recipe-schema.ts +202 -0
  412. package/src/domains/agents/recipe.ts +125 -0
  413. package/src/domains/agents/registry.ts +111 -0
  414. package/src/domains/agents/result-contract.ts +1265 -0
  415. package/src/domains/agents/spec.ts +371 -0
  416. package/src/domains/agents/write-boundary.ts +109 -0
  417. package/src/domains/components/diff.ts +99 -0
  418. package/src/domains/components/hash.ts +21 -0
  419. package/src/domains/components/index.ts +3 -0
  420. package/src/domains/components/scan.ts +304 -0
  421. package/src/domains/components/snapshot.ts +108 -0
  422. package/src/domains/components/types.ts +82 -0
  423. package/src/domains/config/agent-namespace.ts +13 -0
  424. package/src/domains/config/classify.ts +106 -0
  425. package/src/domains/config/contract.ts +22 -0
  426. package/src/domains/config/extension.ts +142 -0
  427. package/src/domains/config/index.ts +23 -0
  428. package/src/domains/config/keybindings.ts +200 -0
  429. package/src/domains/config/manifest.ts +6 -0
  430. package/src/domains/config/watcher.ts +41 -0
  431. package/src/domains/context/adoption.ts +880 -0
  432. package/src/domains/context/bootstrap-prompt.ts +273 -0
  433. package/src/domains/context/bootstrap.ts +1502 -0
  434. package/src/domains/context/clear.ts +91 -0
  435. package/src/domains/context/clio-md.ts +429 -0
  436. package/src/domains/context/codewiki/artifact.ts +400 -0
  437. package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
  438. package/src/domains/context/codewiki/build-worker.ts +54 -0
  439. package/src/domains/context/codewiki/cmake.ts +356 -0
  440. package/src/domains/context/codewiki/cooperative.ts +46 -0
  441. package/src/domains/context/codewiki/coordinator.ts +182 -0
  442. package/src/domains/context/codewiki/digest.ts +135 -0
  443. package/src/domains/context/codewiki/grammar-assets.ts +33 -0
  444. package/src/domains/context/codewiki/indexer.ts +1529 -0
  445. package/src/domains/context/codewiki/paths.ts +67 -0
  446. package/src/domains/context/codewiki/schema.ts +80 -0
  447. package/src/domains/context/codewiki/tree-sitter.ts +771 -0
  448. package/src/domains/context/contract.ts +68 -0
  449. package/src/domains/context/excluded-dirs.ts +1 -0
  450. package/src/domains/context/extension.ts +358 -0
  451. package/src/domains/context/fingerprint.ts +198 -0
  452. package/src/domains/context/index.ts +154 -0
  453. package/src/domains/context/init-options.ts +69 -0
  454. package/src/domains/context/manifest.ts +6 -0
  455. package/src/domains/context/operator-profile.ts +157 -0
  456. package/src/domains/context/project-metadata.ts +529 -0
  457. package/src/domains/context/project-rules.ts +227 -0
  458. package/src/domains/context/prompt-context.ts +61 -0
  459. package/src/domains/context/refresh.ts +178 -0
  460. package/src/domains/context/runtime.ts +17 -0
  461. package/src/domains/context/sibling-files.ts +10 -0
  462. package/src/domains/context/state.ts +237 -0
  463. package/src/domains/context/wiki/assemble.ts +303 -0
  464. package/src/domains/context/wiki/frontmatter.ts +210 -0
  465. package/src/domains/context/wiki/generate.ts +595 -0
  466. package/src/domains/context/wiki/layout.ts +111 -0
  467. package/src/domains/context/wiki/meta.ts +221 -0
  468. package/src/domains/context/wiki/plan-store.ts +217 -0
  469. package/src/domains/context/wiki/plan.ts +250 -0
  470. package/src/domains/context/wiki/prompts.ts +283 -0
  471. package/src/domains/context/wiki/staleness.ts +198 -0
  472. package/src/domains/dispatch/active-route-planner.ts +168 -0
  473. package/src/domains/dispatch/admission-queue.ts +150 -0
  474. package/src/domains/dispatch/admission.ts +334 -0
  475. package/src/domains/dispatch/agent-candidates.ts +307 -0
  476. package/src/domains/dispatch/agent-ledger-hub.ts +71 -0
  477. package/src/domains/dispatch/agent-ledger-store.ts +257 -0
  478. package/src/domains/dispatch/agent-ledger.ts +212 -0
  479. package/src/domains/dispatch/agent-plan-adapter.ts +85 -0
  480. package/src/domains/dispatch/assignment-events.ts +132 -0
  481. package/src/domains/dispatch/assignment-reconcile.ts +76 -0
  482. package/src/domains/dispatch/assignment-store.ts +162 -0
  483. package/src/domains/dispatch/assignment.ts +278 -0
  484. package/src/domains/dispatch/backoff.ts +59 -0
  485. package/src/domains/dispatch/batch-store.ts +134 -0
  486. package/src/domains/dispatch/batch-tracker.ts +66 -0
  487. package/src/domains/dispatch/capability-match.ts +155 -0
  488. package/src/domains/dispatch/capacity-lease.ts +413 -0
  489. package/src/domains/dispatch/code-step-store.ts +52 -0
  490. package/src/domains/dispatch/code-step.ts +387 -0
  491. package/src/domains/dispatch/contract.ts +278 -0
  492. package/src/domains/dispatch/dedup.ts +133 -0
  493. package/src/domains/dispatch/event-pump.ts +251 -0
  494. package/src/domains/dispatch/execution-handoff.ts +29 -0
  495. package/src/domains/dispatch/execution-plan.ts +328 -0
  496. package/src/domains/dispatch/execution-role.ts +277 -0
  497. package/src/domains/dispatch/execution-scheduler.ts +583 -0
  498. package/src/domains/dispatch/extension.ts +6006 -0
  499. package/src/domains/dispatch/failure-classification.ts +147 -0
  500. package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
  501. package/src/domains/dispatch/fleet-plan.ts +225 -0
  502. package/src/domains/dispatch/fleet-preflight.ts +394 -0
  503. package/src/domains/dispatch/gate-decisions.ts +1040 -0
  504. package/src/domains/dispatch/gate-role-prompts.ts +58 -0
  505. package/src/domains/dispatch/heartbeat.ts +27 -0
  506. package/src/domains/dispatch/index.ts +137 -0
  507. package/src/domains/dispatch/joint-route-adapter.ts +114 -0
  508. package/src/domains/dispatch/joint-route-resolver.ts +283 -0
  509. package/src/domains/dispatch/manifest.ts +6 -0
  510. package/src/domains/dispatch/orphan-recovery.ts +266 -0
  511. package/src/domains/dispatch/outcome.ts +109 -0
  512. package/src/domains/dispatch/phase-timing.ts +47 -0
  513. package/src/domains/dispatch/placement.ts +202 -0
  514. package/src/domains/dispatch/receipt-findings.ts +255 -0
  515. package/src/domains/dispatch/receipt-integrity.ts +383 -0
  516. package/src/domains/dispatch/recovery-candidates.ts +74 -0
  517. package/src/domains/dispatch/reproducibility.ts +48 -0
  518. package/src/domains/dispatch/reservation-store.ts +501 -0
  519. package/src/domains/dispatch/route-approval.ts +177 -0
  520. package/src/domains/dispatch/route-candidates.ts +57 -0
  521. package/src/domains/dispatch/route-decision.ts +1079 -0
  522. package/src/domains/dispatch/route-facts.ts +187 -0
  523. package/src/domains/dispatch/route-history.ts +238 -0
  524. package/src/domains/dispatch/route-observer.ts +488 -0
  525. package/src/domains/dispatch/route-policy.ts +327 -0
  526. package/src/domains/dispatch/route-quality.ts +256 -0
  527. package/src/domains/dispatch/route-readiness.ts +120 -0
  528. package/src/domains/dispatch/routing-intent.ts +287 -0
  529. package/src/domains/dispatch/run-identity.ts +56 -0
  530. package/src/domains/dispatch/scout-transition.ts +130 -0
  531. package/src/domains/dispatch/state.ts +302 -0
  532. package/src/domains/dispatch/tool-stats.ts +132 -0
  533. package/src/domains/dispatch/transport.ts +210 -0
  534. package/src/domains/dispatch/types.ts +799 -0
  535. package/src/domains/dispatch/validation-grounding.ts +154 -0
  536. package/src/domains/dispatch/validation.ts +721 -0
  537. package/src/domains/dispatch/worker-protocol.ts +275 -0
  538. package/src/domains/dispatch/worker-spawn.ts +585 -0
  539. package/src/domains/dispatch/write-boundary-enforcer.ts +97 -0
  540. package/src/domains/dispatch/write-boundary.ts +426 -0
  541. package/src/domains/eval/artifacts/redact.ts +42 -0
  542. package/src/domains/eval/artifacts/store.ts +173 -0
  543. package/src/domains/eval/compare/compare.ts +33 -0
  544. package/src/domains/eval/compare/gates.ts +66 -0
  545. package/src/domains/eval/compare/thresholds.ts +92 -0
  546. package/src/domains/eval/harness-metrics.ts +62 -0
  547. package/src/domains/eval/index.ts +66 -0
  548. package/src/domains/eval/metrics/chaos-stream.ts +93 -0
  549. package/src/domains/eval/metrics/context.ts +34 -0
  550. package/src/domains/eval/metrics/coverage.ts +21 -0
  551. package/src/domains/eval/metrics/evidence.ts +182 -0
  552. package/src/domains/eval/metrics/fleet-loop-stream.ts +196 -0
  553. package/src/domains/eval/metrics/invariants.ts +736 -0
  554. package/src/domains/eval/metrics/latency.ts +4 -0
  555. package/src/domains/eval/metrics/token-stream.ts +139 -0
  556. package/src/domains/eval/metrics/tokens.ts +51 -0
  557. package/src/domains/eval/metrics/tool-calls.ts +7 -0
  558. package/src/domains/eval/proactive-memory.ts +279 -0
  559. package/src/domains/eval/provenance.ts +35 -0
  560. package/src/domains/eval/report.ts +234 -0
  561. package/src/domains/eval/reports/json.ts +5 -0
  562. package/src/domains/eval/reports/junit.ts +23 -0
  563. package/src/domains/eval/reports/markdown.ts +20 -0
  564. package/src/domains/eval/reports/swe-jsonl.ts +16 -0
  565. package/src/domains/eval/reports/text.ts +25 -0
  566. package/src/domains/eval/run-compare.ts +274 -0
  567. package/src/domains/eval/runner.ts +244 -0
  568. package/src/domains/eval/runners/clio-run.ts +148 -0
  569. package/src/domains/eval/runners/context-index.ts +56 -0
  570. package/src/domains/eval/runners/context-init.ts +203 -0
  571. package/src/domains/eval/runners/external-command.ts +350 -0
  572. package/src/domains/eval/runtime-paths.ts +171 -0
  573. package/src/domains/eval/schema/artifact.ts +75 -0
  574. package/src/domains/eval/schema/suite.ts +235 -0
  575. package/src/domains/eval/schema/validate.ts +339 -0
  576. package/src/domains/eval/store.ts +392 -0
  577. package/src/domains/eval/suites/load.ts +74 -0
  578. package/src/domains/eval/suites/matrix.ts +19 -0
  579. package/src/domains/eval/suites/resolve.ts +44 -0
  580. package/src/domains/eval/suites/run.ts +325 -0
  581. package/src/domains/eval/task-file.ts +186 -0
  582. package/src/domains/eval/types.ts +140 -0
  583. package/src/domains/eval/verifiers/command.ts +27 -0
  584. package/src/domains/eval/verifiers/file-exists.ts +6 -0
  585. package/src/domains/eval/verifiers/patch.ts +22 -0
  586. package/src/domains/eval/workspaces/git.ts +41 -0
  587. package/src/domains/eval/workspaces/local.ts +17 -0
  588. package/src/domains/eval/workspaces/temp-copy.ts +29 -0
  589. package/src/domains/evidence/build.ts +1754 -0
  590. package/src/domains/evidence/eval.ts +605 -0
  591. package/src/domains/evidence/failure-attribution.ts +54 -0
  592. package/src/domains/evidence/finish-contract-map.ts +42 -0
  593. package/src/domains/evidence/index.ts +55 -0
  594. package/src/domains/evidence/provenance.ts +200 -0
  595. package/src/domains/evidence/redact.ts +81 -0
  596. package/src/domains/evidence/store.ts +291 -0
  597. package/src/domains/evidence/types.ts +325 -0
  598. package/src/domains/evolution/SELF_EDIT_GATE.md +91 -0
  599. package/src/domains/evolution/index.ts +26 -0
  600. package/src/domains/evolution/manifest.ts +154 -0
  601. package/src/domains/evolution/validate.ts +304 -0
  602. package/src/domains/extensions/contract.ts +22 -0
  603. package/src/domains/extensions/discovery.ts +193 -0
  604. package/src/domains/extensions/extension.ts +46 -0
  605. package/src/domains/extensions/index.ts +34 -0
  606. package/src/domains/extensions/manager.ts +30 -0
  607. package/src/domains/extensions/manifest.ts +6 -0
  608. package/src/domains/extensions/resources.ts +38 -0
  609. package/src/domains/extensions/state.ts +224 -0
  610. package/src/domains/extensions/types.ts +83 -0
  611. package/src/domains/interop/consent.ts +185 -0
  612. package/src/domains/interop/contract.ts +29 -0
  613. package/src/domains/interop/detect.ts +173 -0
  614. package/src/domains/interop/extension.ts +59 -0
  615. package/src/domains/interop/index.ts +34 -0
  616. package/src/domains/interop/manifest.ts +6 -0
  617. package/src/domains/interop/registry.ts +139 -0
  618. package/src/domains/interop/state.ts +92 -0
  619. package/src/domains/interop/types.ts +109 -0
  620. package/src/domains/lifecycle/contract.ts +11 -0
  621. package/src/domains/lifecycle/doctor.ts +536 -0
  622. package/src/domains/lifecycle/extension.ts +23 -0
  623. package/src/domains/lifecycle/index.ts +21 -0
  624. package/src/domains/lifecycle/install-method.ts +51 -0
  625. package/src/domains/lifecycle/manifest.ts +6 -0
  626. package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
  627. package/src/domains/lifecycle/migrations/index.ts +114 -0
  628. package/src/domains/lifecycle/state.ts +93 -0
  629. package/src/domains/lifecycle/upgrade-notice.ts +35 -0
  630. package/src/domains/lifecycle/version.ts +35 -0
  631. package/src/domains/memory/index.ts +128 -0
  632. package/src/domains/memory/operations.ts +143 -0
  633. package/src/domains/memory/prompt-section.ts +86 -0
  634. package/src/domains/memory/proposal.ts +180 -0
  635. package/src/domains/memory/store.ts +163 -0
  636. package/src/domains/memory/task-bank.ts +229 -0
  637. package/src/domains/memory/task-memory-handoff.ts +222 -0
  638. package/src/domains/memory/task-memory-policy.ts +602 -0
  639. package/src/domains/memory/task-memory-status.ts +58 -0
  640. package/src/domains/memory/task-memory-telemetry.ts +346 -0
  641. package/src/domains/memory/task-memory-trace.ts +89 -0
  642. package/src/domains/memory/types.ts +74 -0
  643. package/src/domains/memory/validate.ts +297 -0
  644. package/src/domains/middleware/budget.ts +216 -0
  645. package/src/domains/middleware/contract.ts +35 -0
  646. package/src/domains/middleware/dispatch-nudge.ts +469 -0
  647. package/src/domains/middleware/extension.ts +129 -0
  648. package/src/domains/middleware/hook-receipts.ts +70 -0
  649. package/src/domains/middleware/hooks-io.ts +186 -0
  650. package/src/domains/middleware/hooks.ts +432 -0
  651. package/src/domains/middleware/index.ts +154 -0
  652. package/src/domains/middleware/manifest.ts +6 -0
  653. package/src/domains/middleware/memory-intervention.ts +701 -0
  654. package/src/domains/middleware/rules.ts +42 -0
  655. package/src/domains/middleware/runtime.ts +333 -0
  656. package/src/domains/middleware/skills-reminder.ts +202 -0
  657. package/src/domains/middleware/snapshot.ts +71 -0
  658. package/src/domains/middleware/stalled-turn.ts +71 -0
  659. package/src/domains/middleware/task-board-reminder.ts +87 -0
  660. package/src/domains/middleware/task-nudge.ts +77 -0
  661. package/src/domains/middleware/tool-choice-control.ts +42 -0
  662. package/src/domains/middleware/types.ts +131 -0
  663. package/src/domains/middleware/validate.ts +329 -0
  664. package/src/domains/observability/accountability.ts +67 -0
  665. package/src/domains/observability/contract.ts +168 -0
  666. package/src/domains/observability/cost.ts +206 -0
  667. package/src/domains/observability/evidence-index.ts +123 -0
  668. package/src/domains/observability/extension.ts +281 -0
  669. package/src/domains/observability/index.ts +78 -0
  670. package/src/domains/observability/manifest.ts +10 -0
  671. package/src/domains/observability/metrics.ts +37 -0
  672. package/src/domains/observability/projection.ts +477 -0
  673. package/src/domains/observability/telemetry.ts +89 -0
  674. package/src/domains/observability/trace-store.ts +1454 -0
  675. package/src/domains/prompts/compiler.ts +614 -0
  676. package/src/domains/prompts/contract.ts +46 -0
  677. package/src/domains/prompts/extension.ts +336 -0
  678. package/src/domains/prompts/fragment-loader.ts +138 -0
  679. package/src/domains/prompts/fragments/identity/clio.md +5 -6
  680. package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
  681. package/src/domains/prompts/fragments/identity/self-awareness.md +19 -0
  682. package/src/domains/prompts/fragments/operating/contract.md +4 -41
  683. package/src/domains/prompts/fragments/operating/delegation.md +42 -0
  684. package/src/domains/prompts/fragments/operating/skills.md +26 -0
  685. package/src/domains/prompts/fragments/operating/worker.md +16 -0
  686. package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
  687. package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
  688. package/src/domains/prompts/fragments/safety/read-only.md +4 -4
  689. package/src/domains/prompts/fragments/safety/suggest.md +2 -2
  690. package/src/domains/prompts/fragments/wiki/page.md +10 -0
  691. package/src/domains/prompts/fragments/wiki/plan.md +10 -0
  692. package/src/domains/prompts/hash.ts +73 -0
  693. package/src/domains/prompts/index.ts +32 -0
  694. package/src/domains/prompts/manifest.ts +8 -0
  695. package/src/domains/prompts/memory-intervention.ts +57 -0
  696. package/src/domains/prompts/preload.ts +82 -0
  697. package/src/domains/providers/auth/api-key.ts +47 -0
  698. package/src/domains/providers/auth/backend-file.ts +79 -0
  699. package/src/domains/providers/auth/backend-memory.ts +72 -0
  700. package/src/domains/providers/auth/boot-status.ts +65 -0
  701. package/src/domains/providers/auth/index.ts +37 -0
  702. package/src/domains/providers/auth/oauth.ts +37 -0
  703. package/src/domains/providers/auth/storage.ts +726 -0
  704. package/src/domains/providers/capabilities.ts +58 -0
  705. package/src/domains/providers/catalog.ts +162 -0
  706. package/src/domains/providers/contract.ts +162 -0
  707. package/src/domains/providers/credentials.ts +20 -0
  708. package/src/domains/providers/eligibility.ts +24 -0
  709. package/src/domains/providers/errors.ts +64 -0
  710. package/src/domains/providers/extension.ts +548 -0
  711. package/src/domains/providers/index.ts +142 -0
  712. package/src/domains/providers/knowledge-base-path.ts +102 -0
  713. package/src/domains/providers/manifest.ts +6 -0
  714. package/src/domains/providers/model-capabilities.ts +136 -0
  715. package/src/domains/providers/model-discovery.ts +144 -0
  716. package/src/domains/providers/model-family.ts +32 -0
  717. package/src/domains/providers/model-runtime-capabilities.ts +723 -0
  718. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +120 -37
  719. package/src/domains/providers/plugins.ts +61 -0
  720. package/src/domains/providers/probe/fingerprint.ts +64 -0
  721. package/src/domains/providers/probe/http.ts +114 -0
  722. package/src/domains/providers/probe/reasoning.ts +111 -0
  723. package/src/domains/providers/registry.ts +187 -0
  724. package/src/domains/providers/resolver.ts +156 -0
  725. package/src/domains/providers/runtime-resolution.ts +720 -0
  726. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +90 -0
  727. package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
  728. package/src/domains/providers/runtimes/builtins.ts +78 -0
  729. package/src/domains/providers/runtimes/claude/claude-code.ts +38 -0
  730. package/src/domains/providers/runtimes/claude/claude-sdk.ts +38 -0
  731. package/src/domains/providers/runtimes/claude/common.ts +55 -0
  732. package/src/domains/providers/runtimes/cloud/alcf.ts +171 -0
  733. package/src/domains/providers/runtimes/cloud/anthropic-max.ts +71 -0
  734. package/src/domains/providers/runtimes/cloud/anthropic.ts +43 -0
  735. package/src/domains/providers/runtimes/cloud/bedrock.ts +35 -0
  736. package/src/domains/providers/runtimes/cloud/deepseek.ts +50 -0
  737. package/src/domains/providers/runtimes/cloud/google.ts +41 -0
  738. package/src/domains/providers/runtimes/cloud/groq.ts +46 -0
  739. package/src/domains/providers/runtimes/cloud/mistral.ts +46 -0
  740. package/src/domains/providers/runtimes/cloud/openai-codex.ts +49 -0
  741. package/src/domains/providers/runtimes/cloud/openai.ts +46 -0
  742. package/src/domains/providers/runtimes/cloud/openrouter.ts +111 -0
  743. package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
  744. package/src/domains/providers/runtimes/common/local-synth.ts +164 -0
  745. package/src/domains/providers/runtimes/common/probe-helpers.ts +474 -0
  746. package/src/domains/providers/runtimes/local-native/lemonade-anthropic.ts +27 -0
  747. package/src/domains/providers/runtimes/local-native/lemonade-openai.ts +26 -0
  748. package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +88 -0
  749. package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +207 -0
  750. package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +180 -0
  751. package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +126 -0
  752. package/src/domains/providers/runtimes/local-native/llamacpp.ts +98 -0
  753. package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
  754. package/src/domains/providers/runtimes/local-native/ollama-native.ts +117 -0
  755. package/src/domains/providers/runtimes/local-native/sglang.ts +26 -0
  756. package/src/domains/providers/runtimes/local-native/vllm.ts +27 -0
  757. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +104 -0
  758. package/src/domains/providers/runtimes/protocol/anthropic-messages.ts +28 -0
  759. package/src/domains/providers/runtimes/protocol/bedrock.ts +26 -0
  760. package/src/domains/providers/runtimes/protocol/google.ts +27 -0
  761. package/src/domains/providers/runtimes/protocol/openai-compat.ts +145 -0
  762. package/src/domains/providers/support.ts +241 -0
  763. package/src/domains/providers/thinking-control-policy.ts +85 -0
  764. package/src/domains/providers/types/capability-flags.ts +114 -0
  765. package/src/domains/providers/types/cost-provenance.ts +7 -0
  766. package/src/domains/providers/types/inference.ts +41 -0
  767. package/src/domains/providers/types/knowledge-base.ts +156 -0
  768. package/src/domains/providers/types/local-model-quirks.ts +216 -0
  769. package/src/domains/providers/types/runtime-descriptor.ts +181 -0
  770. package/src/domains/providers/types/target-descriptor.ts +60 -0
  771. package/src/domains/resources/collision.ts +92 -0
  772. package/src/domains/resources/common-loader.ts +140 -0
  773. package/src/domains/resources/contract.ts +24 -0
  774. package/src/domains/resources/extension.ts +59 -0
  775. package/src/domains/resources/index.ts +74 -0
  776. package/src/domains/resources/loader.ts +85 -0
  777. package/src/domains/resources/manifest.ts +6 -0
  778. package/src/domains/resources/prompts/loader.ts +246 -0
  779. package/src/domains/resources/prompts/substitute.ts +1 -0
  780. package/src/domains/resources/skills/content-hash.ts +107 -0
  781. package/src/domains/resources/skills/evals.ts +175 -0
  782. package/src/domains/resources/skills/install.ts +427 -0
  783. package/src/domains/resources/skills/loader.ts +985 -0
  784. package/src/domains/resources/skills/marketplace.ts +301 -0
  785. package/src/domains/resources/skills/provenance-pin.ts +115 -0
  786. package/src/domains/safety/action-classifier.ts +270 -0
  787. package/src/domains/safety/approval-axis.ts +23 -0
  788. package/src/domains/safety/audit.ts +493 -0
  789. package/src/domains/safety/autonomy.ts +174 -0
  790. package/src/domains/safety/call-target.ts +59 -0
  791. package/src/domains/safety/contract.ts +65 -0
  792. package/src/domains/safety/damage-control.ts +44 -0
  793. package/src/domains/safety/default-path-policy.ts +117 -0
  794. package/src/domains/safety/extension.ts +383 -0
  795. package/src/domains/safety/finish-contract-registration.ts +128 -0
  796. package/src/domains/safety/finish-contract.ts +554 -0
  797. package/src/domains/safety/index.ts +44 -0
  798. package/src/domains/safety/loop-detector.ts +143 -0
  799. package/src/domains/safety/manifest.ts +6 -0
  800. package/src/domains/safety/path-policy.ts +164 -0
  801. package/src/domains/safety/policy-engine.ts +994 -0
  802. package/src/domains/safety/project-policy.ts +391 -0
  803. package/src/domains/safety/protected-artifacts-registration.ts +189 -0
  804. package/src/domains/safety/protected-artifacts.ts +993 -0
  805. package/src/domains/safety/rejection-feedback.ts +102 -0
  806. package/src/domains/safety/rigor.ts +72 -0
  807. package/src/domains/safety/rule-compiler.ts +48 -0
  808. package/src/domains/safety/rule-pack-loader.ts +92 -0
  809. package/src/domains/safety/run-effects.ts +197 -0
  810. package/src/domains/safety/scope.ts +61 -0
  811. package/src/domains/scheduling/budget.ts +35 -0
  812. package/src/domains/scheduling/cluster.ts +175 -0
  813. package/src/domains/scheduling/contract.ts +30 -0
  814. package/src/domains/scheduling/extension.ts +91 -0
  815. package/src/domains/scheduling/index.ts +12 -0
  816. package/src/domains/scheduling/manifest.ts +6 -0
  817. package/src/domains/session/archive-readers.ts +208 -0
  818. package/src/domains/session/checkpoint.ts +38 -0
  819. package/src/domains/session/compaction/auto.ts +89 -0
  820. package/src/domains/session/compaction/branch-summary.ts +187 -0
  821. package/src/domains/session/compaction/compact.ts +493 -0
  822. package/src/domains/session/compaction/cut-point.ts +172 -0
  823. package/src/domains/session/compaction/defaults.ts +34 -0
  824. package/src/domains/session/compaction/mask-observations.ts +265 -0
  825. package/src/domains/session/compaction/session-entries.ts +18 -0
  826. package/src/domains/session/compaction/tokens.ts +148 -0
  827. package/src/domains/session/context-accounting.ts +583 -0
  828. package/src/domains/session/context-ledger.ts +362 -0
  829. package/src/domains/session/contract.ts +159 -0
  830. package/src/domains/session/cwd-fallback.ts +65 -0
  831. package/src/domains/session/decision-board.ts +190 -0
  832. package/src/domains/session/entries.ts +572 -0
  833. package/src/domains/session/extension.ts +403 -0
  834. package/src/domains/session/history.ts +172 -0
  835. package/src/domains/session/index.ts +84 -0
  836. package/src/domains/session/manager.ts +128 -0
  837. package/src/domains/session/manifest.ts +6 -0
  838. package/src/domains/session/migrations/index.ts +27 -0
  839. package/src/domains/session/prompt-manifest.ts +173 -0
  840. package/src/domains/session/protected-artifact-journal.ts +241 -0
  841. package/src/domains/session/protected-artifacts.ts +90 -0
  842. package/src/domains/session/retry.ts +230 -0
  843. package/src/domains/session/session-artifacts.ts +107 -0
  844. package/src/domains/session/task-board.ts +569 -0
  845. package/src/domains/session/tree/active-path.ts +137 -0
  846. package/src/domains/session/tree/fork.ts +159 -0
  847. package/src/domains/session/tree/manager.ts +128 -0
  848. package/src/domains/session/tree/navigator.ts +177 -0
  849. package/src/domains/session/tree/preview.ts +259 -0
  850. package/src/domains/session/usage.ts +148 -0
  851. package/src/domains/session/workspace/git-probe.ts +167 -0
  852. package/src/domains/session/workspace/index.ts +4 -0
  853. package/src/domains/session/workspace/project-type.ts +217 -0
  854. package/src/domains/session/workspace/snapshot.ts +74 -0
  855. package/src/domains/share/archive.ts +684 -0
  856. package/src/domains/share/contract.ts +9 -0
  857. package/src/domains/share/extension.ts +26 -0
  858. package/src/domains/share/index.ts +28 -0
  859. package/src/domains/share/manifest.ts +6 -0
  860. package/src/domains/user-tasks/store.ts +297 -0
  861. package/src/engine/acp/adapter.ts +397 -0
  862. package/src/engine/acp/errors.ts +128 -0
  863. package/src/engine/acp/event-mapper.ts +154 -0
  864. package/src/engine/acp/server.ts +2238 -0
  865. package/src/engine/acp/tool-mediator.ts +686 -0
  866. package/src/engine/acp/transport.ts +775 -0
  867. package/src/engine/acp/types.ts +196 -0
  868. package/src/engine/agent.ts +29 -0
  869. package/src/engine/ai.ts +207 -0
  870. package/src/engine/alcf-oauth.ts +205 -0
  871. package/src/engine/antigravity/subprocess-runtime.ts +205 -0
  872. package/src/engine/api-registry.ts +223 -0
  873. package/src/engine/apis/degraded-inference.ts +95 -0
  874. package/src/engine/apis/index.ts +16 -0
  875. package/src/engine/apis/llamacpp-residency.ts +292 -0
  876. package/src/engine/apis/lmstudio-residency.ts +76 -0
  877. package/src/engine/apis/lmstudio.ts +243 -0
  878. package/src/engine/apis/ollama-native.ts +528 -0
  879. package/src/engine/apis/openai-completions.ts +795 -0
  880. package/src/engine/apis/output-budget.ts +99 -0
  881. package/src/engine/apis/residency-lock.ts +29 -0
  882. package/src/engine/apis/residency.ts +776 -0
  883. package/src/engine/apis/resident-models.ts +42 -0
  884. package/src/engine/apis/sampling-overrides.ts +38 -0
  885. package/src/engine/apis/types.ts +16 -0
  886. package/src/engine/claude/sdk-runtime.ts +685 -0
  887. package/src/engine/claude/session-id.ts +5 -0
  888. package/src/engine/claude/subprocess-runtime.ts +316 -0
  889. package/src/engine/claude/tool-safety.ts +400 -0
  890. package/src/engine/env-api-keys.ts +98 -0
  891. package/src/engine/external-subprocess.ts +23 -0
  892. package/src/engine/gemma-channel-filter.ts +223 -0
  893. package/src/engine/harmony-response.ts +165 -0
  894. package/src/engine/instrumented-tui.ts +192 -0
  895. package/src/engine/loop-guard.ts +1127 -0
  896. package/src/engine/messages.ts +14 -0
  897. package/src/engine/models.ts +42 -0
  898. package/src/engine/oauth.ts +196 -0
  899. package/src/engine/pi-mono-names.ts +13 -0
  900. package/src/engine/prompt-templates.ts +1 -0
  901. package/src/engine/provider-payload.ts +272 -0
  902. package/src/engine/select-list.ts +53 -0
  903. package/src/engine/session.ts +834 -0
  904. package/src/engine/strip-tokenizer-sentinels.ts +125 -0
  905. package/src/engine/truncate.ts +9 -0
  906. package/src/engine/tui.ts +111 -0
  907. package/src/engine/types.ts +63 -0
  908. package/src/engine/worker-events.ts +100 -0
  909. package/src/engine/worker-runtime-capabilities.ts +5 -0
  910. package/src/engine/worker-runtime.ts +1022 -0
  911. package/src/engine/worker-tools.ts +208 -0
  912. package/src/entry/boot-options.ts +50 -0
  913. package/src/entry/orchestrator.ts +2011 -0
  914. package/src/interactive/application-controller.ts +433 -0
  915. package/src/interactive/bus-notices.ts +265 -0
  916. package/src/interactive/chat-loop-messages.ts +626 -0
  917. package/src/interactive/chat-loop-policy.ts +18 -0
  918. package/src/interactive/chat-loop.ts +1090 -0
  919. package/src/interactive/chat-panel.ts +1820 -0
  920. package/src/interactive/chat-renderer.ts +1228 -0
  921. package/src/interactive/clio-editor.ts +161 -0
  922. package/src/interactive/command-fallbacks.ts +23 -0
  923. package/src/interactive/command-output.ts +85 -0
  924. package/src/interactive/context-activity.ts +203 -0
  925. package/src/interactive/context-meter.ts +223 -0
  926. package/src/interactive/context-overlay.ts +246 -0
  927. package/src/interactive/cost-overlay.ts +279 -0
  928. package/src/interactive/dispatch-board.ts +1319 -0
  929. package/src/interactive/dispatch-steering.ts +86 -0
  930. package/src/interactive/editor-bash.ts +46 -0
  931. package/src/interactive/editor-steer.ts +51 -0
  932. package/src/interactive/editor-submit.ts +507 -0
  933. package/src/interactive/export-html/ansi-to-html.ts +161 -0
  934. package/src/interactive/export-html/index.ts +51 -0
  935. package/src/interactive/export-html/template.ts +45 -0
  936. package/src/interactive/export-html/tool-renderer.ts +54 -0
  937. package/src/interactive/external-editor.ts +67 -0
  938. package/src/interactive/follow-up-queue-panel.ts +75 -0
  939. package/src/interactive/footer/dashboard.ts +538 -0
  940. package/src/interactive/footer/notifications.ts +275 -0
  941. package/src/interactive/footer/widgets.ts +1264 -0
  942. package/src/interactive/footer-panel.ts +187 -0
  943. package/src/interactive/format-time.ts +97 -0
  944. package/src/interactive/index.ts +11 -0
  945. package/src/interactive/interactive-application.ts +939 -0
  946. package/src/interactive/interactive-event-projection.ts +385 -0
  947. package/src/interactive/interactive-input-runtime.ts +307 -0
  948. package/src/interactive/interactive-presentation.ts +584 -0
  949. package/src/interactive/interactive-shell.ts +388 -0
  950. package/src/interactive/interactive-slash-runtime.ts +554 -0
  951. package/src/interactive/interactive-subscriptions.ts +111 -0
  952. package/src/interactive/interactive-tickers.ts +183 -0
  953. package/src/interactive/keybinding-manager.ts +496 -0
  954. package/src/interactive/layout.ts +57 -0
  955. package/src/interactive/leader-key.ts +143 -0
  956. package/src/interactive/loop-guard-interrupt.ts +101 -0
  957. package/src/interactive/memory-overlay.ts +280 -0
  958. package/src/interactive/overlay-ask-user-lifecycle.ts +110 -0
  959. package/src/interactive/overlay-auth-lifecycle.ts +308 -0
  960. package/src/interactive/overlay-frame.ts +502 -0
  961. package/src/interactive/overlay-general-openers.ts +274 -0
  962. package/src/interactive/overlay-key-routing.ts +216 -0
  963. package/src/interactive/overlay-lifecycle.ts +426 -0
  964. package/src/interactive/overlay-model-selectors.ts +127 -0
  965. package/src/interactive/overlay-permission-lifecycle.ts +345 -0
  966. package/src/interactive/overlay-resource-openers.ts +112 -0
  967. package/src/interactive/overlay-session-lifecycle.ts +327 -0
  968. package/src/interactive/overlay-transitions.ts +57 -0
  969. package/src/interactive/overlays/agents.ts +69 -0
  970. package/src/interactive/overlays/ask-user.ts +921 -0
  971. package/src/interactive/overlays/auth-dialog.ts +221 -0
  972. package/src/interactive/overlays/context-reset.ts +108 -0
  973. package/src/interactive/overlays/cwd-fallback.ts +141 -0
  974. package/src/interactive/overlays/decisions.ts +300 -0
  975. package/src/interactive/overlays/extensions.ts +54 -0
  976. package/src/interactive/overlays/help-reference.ts +145 -0
  977. package/src/interactive/overlays/interop.ts +139 -0
  978. package/src/interactive/overlays/keybinding-detail.ts +90 -0
  979. package/src/interactive/overlays/list-overlay.ts +606 -0
  980. package/src/interactive/overlays/message-picker.ts +155 -0
  981. package/src/interactive/overlays/model-selector.ts +1109 -0
  982. package/src/interactive/overlays/prompts.ts +72 -0
  983. package/src/interactive/overlays/session-selector-search.ts +31 -0
  984. package/src/interactive/overlays/session-selector.ts +284 -0
  985. package/src/interactive/overlays/settings.ts +3451 -0
  986. package/src/interactive/overlays/skills-hub.ts +237 -0
  987. package/src/interactive/overlays/tree-selector.ts +422 -0
  988. package/src/interactive/permission-overlay.ts +170 -0
  989. package/src/interactive/render-trace.ts +534 -0
  990. package/src/interactive/renderers/branch-summary.ts +86 -0
  991. package/src/interactive/renderers/code-ink.ts +420 -0
  992. package/src/interactive/renderers/compaction-summary.ts +112 -0
  993. package/src/interactive/renderers/diff.ts +137 -0
  994. package/src/interactive/renderers/mermaid.ts +53 -0
  995. package/src/interactive/renderers/notice.ts +28 -0
  996. package/src/interactive/renderers/retry-status.ts +31 -0
  997. package/src/interactive/renderers/structured.ts +89 -0
  998. package/src/interactive/renderers/tool-execution.ts +1357 -0
  999. package/src/interactive/renderers/worker-entry.ts +280 -0
  1000. package/src/interactive/session-last-turn.ts +186 -0
  1001. package/src/interactive/session-switch-settlement.ts +10 -0
  1002. package/src/interactive/session-transcript.ts +105 -0
  1003. package/src/interactive/session-usage-reseed.ts +74 -0
  1004. package/src/interactive/slash-autocomplete.ts +256 -0
  1005. package/src/interactive/slash-commands.ts +1407 -0
  1006. package/src/interactive/slash-spec.ts +424 -0
  1007. package/src/interactive/status/controller.ts +260 -0
  1008. package/src/interactive/status/index.ts +23 -0
  1009. package/src/interactive/status/state-machine.ts +530 -0
  1010. package/src/interactive/status/summary.ts +170 -0
  1011. package/src/interactive/status/types.ts +121 -0
  1012. package/src/interactive/status/verbs.ts +163 -0
  1013. package/src/interactive/status/watchdog.ts +24 -0
  1014. package/src/interactive/stdout-backpressure.ts +99 -0
  1015. package/src/interactive/stream-pacer.ts +530 -0
  1016. package/src/interactive/stream-pacing-policy.ts +66 -0
  1017. package/src/interactive/tasks-overlay.ts +540 -0
  1018. package/src/interactive/terminal-lease.ts +485 -0
  1019. package/src/interactive/theme/components.ts +55 -0
  1020. package/src/interactive/theme/glyphs.ts +70 -0
  1021. package/src/interactive/theme/index.ts +15 -0
  1022. package/src/interactive/theme/labels.ts +88 -0
  1023. package/src/interactive/theme/rules.ts +138 -0
  1024. package/src/interactive/theme/segments.ts +88 -0
  1025. package/src/interactive/theme/tokens.ts +121 -0
  1026. package/src/interactive/thinking-level-policy.ts +6 -0
  1027. package/src/interactive/tool-prose-loop.ts +122 -0
  1028. package/src/interactive/tool-prose-registration.ts +48 -0
  1029. package/src/interactive/turn-context.ts +855 -0
  1030. package/src/interactive/turn-middleware.ts +283 -0
  1031. package/src/interactive/turn-persistence.ts +458 -0
  1032. package/src/interactive/turn-queues.ts +181 -0
  1033. package/src/interactive/turn-recovery.ts +323 -0
  1034. package/src/interactive/turn-runtime.ts +869 -0
  1035. package/src/interactive/turn-state.ts +133 -0
  1036. package/src/interactive/view/artifacts.ts +1452 -0
  1037. package/src/interactive/view/view-overlay.ts +735 -0
  1038. package/src/interactive/welcome-dashboard.ts +537 -0
  1039. package/src/interactive/worker-receipts.ts +143 -0
  1040. package/src/interactive/worker-replay.ts +111 -0
  1041. package/src/interactive/worker-share.ts +100 -0
  1042. package/src/interactive/worker-stream.ts +446 -0
  1043. package/src/interactive/workspace-facts.ts +141 -0
  1044. package/src/tools/agent-tools.ts +402 -0
  1045. package/src/tools/artifact.ts +103 -0
  1046. package/src/tools/ask-user.ts +666 -0
  1047. package/src/tools/bash.ts +204 -0
  1048. package/src/tools/bootstrap.ts +77 -0
  1049. package/src/tools/builtin-tool-catalog.ts +265 -0
  1050. package/src/tools/codewiki/code-nav-surface.ts +29 -0
  1051. package/src/tools/codewiki/code-nav.ts +549 -0
  1052. package/src/tools/codewiki/shared.ts +118 -0
  1053. package/src/tools/compete-worktrees.ts +898 -0
  1054. package/src/tools/context/docs-engine.ts +630 -0
  1055. package/src/tools/context/index.ts +514 -0
  1056. package/src/tools/context/surface.ts +19 -0
  1057. package/src/tools/core-bootstrap.ts +168 -0
  1058. package/src/tools/credential-present.ts +151 -0
  1059. package/src/tools/dispatch-admission.ts +533 -0
  1060. package/src/tools/dispatch-arguments.ts +228 -0
  1061. package/src/tools/dispatch-background.ts +54 -0
  1062. package/src/tools/dispatch-event-text.ts +6 -0
  1063. package/src/tools/dispatch-plan.ts +746 -0
  1064. package/src/tools/dispatch-run-events.ts +238 -0
  1065. package/src/tools/dispatch-runner.ts +2370 -0
  1066. package/src/tools/dispatch-scout-admission.ts +295 -0
  1067. package/src/tools/dispatch-scout.ts +461 -0
  1068. package/src/tools/dispatch-types.ts +77 -0
  1069. package/src/tools/dispatch.ts +244 -0
  1070. package/src/tools/edit-diff.ts +534 -0
  1071. package/src/tools/edit.ts +128 -0
  1072. package/src/tools/executables.ts +22 -0
  1073. package/src/tools/file-mutation-queue.ts +35 -0
  1074. package/src/tools/find.ts +294 -0
  1075. package/src/tools/grep.ts +495 -0
  1076. package/src/tools/ignore-policy.ts +169 -0
  1077. package/src/tools/lazy-tool.ts +60 -0
  1078. package/src/tools/ledger.ts +206 -0
  1079. package/src/tools/ls.ts +110 -0
  1080. package/src/tools/monitor-surface.ts +36 -0
  1081. package/src/tools/monitor.ts +767 -0
  1082. package/src/tools/network-policy.ts +29 -0
  1083. package/src/tools/observation.ts +421 -0
  1084. package/src/tools/observers.ts +99 -0
  1085. package/src/tools/path-utils.ts +79 -0
  1086. package/src/tools/policy.ts +154 -0
  1087. package/src/tools/profiles.ts +108 -0
  1088. package/src/tools/read.ts +173 -0
  1089. package/src/tools/registry.ts +1169 -0
  1090. package/src/tools/result-shaping.ts +204 -0
  1091. package/src/tools/safe-exec.ts +128 -0
  1092. package/src/tools/spawn-hygiene.ts +182 -0
  1093. package/src/tools/steer-surface.ts +17 -0
  1094. package/src/tools/steer.ts +77 -0
  1095. package/src/tools/tasks.ts +265 -0
  1096. package/src/tools/truncate-utf8.ts +17 -0
  1097. package/src/tools/truncate.ts +43 -0
  1098. package/src/tools/verify/frontend.ts +687 -0
  1099. package/src/tools/verify/index.ts +31 -0
  1100. package/src/tools/verify/scripts.ts +108 -0
  1101. package/src/tools/verify/surface.ts +46 -0
  1102. package/src/tools/web-fetch-surface.ts +23 -0
  1103. package/src/tools/web-fetch.ts +759 -0
  1104. package/src/tools/worker-evidence.ts +215 -0
  1105. package/src/tools/write.ts +57 -0
  1106. package/src/utils/exif-orientation.ts +192 -0
  1107. package/src/utils/git.ts +24 -0
  1108. package/src/utils/image-resize.ts +148 -0
  1109. package/src/utils/photon.ts +103 -0
  1110. package/src/worker/control-lane.ts +22 -0
  1111. package/src/worker/entry.ts +294 -0
  1112. package/src/worker/event-projection.ts +56 -0
  1113. package/src/worker/heartbeat.ts +24 -0
  1114. package/src/worker/ledger-mirror.ts +95 -0
  1115. package/src/worker/ndjson.ts +40 -0
  1116. package/src/worker/protocol.ts +529 -0
  1117. package/src/worker/resource-facts.ts +79 -0
  1118. package/src/worker/runtime-registry.ts +12 -0
  1119. package/src/worker/spec-contract.ts +675 -0
  1120. package/src/worker/stdin-demux.ts +316 -0
  1121. package/dist/acp-UMLFVA3F.js +0 -92
  1122. package/dist/chunk-262G75JS.js +0 -35
  1123. package/dist/chunk-6CWDTGUC.js +0 -20
  1124. package/dist/chunk-BYEU76JP.js +0 -899
  1125. package/dist/chunk-GNGDQYDU.js +0 -34688
  1126. package/dist/chunk-GOTUR54M.js +0 -9
  1127. package/dist/chunk-NI4DEJMC.js +0 -88
  1128. package/dist/chunk-TPOCL34A.js +0 -2876
  1129. package/dist/chunk-UU3R62TT.js +0 -128
  1130. package/dist/clio-KIQ5SNDS.js +0 -53
  1131. package/dist/configure-G4E3A2PG.js +0 -27
  1132. package/dist/doctor-M5HJJZOL.js +0 -61
  1133. package/dist/domains/agents/builtins/architect.md +0 -33
  1134. package/dist/domains/agents/builtins/coder.md +0 -31
  1135. package/dist/domains/agents/builtins/context-bootstrap.md +0 -38
  1136. package/dist/domains/agents/builtins/debugger.md +0 -30
  1137. package/dist/domains/agents/builtins/documenter.md +0 -31
  1138. package/dist/domains/agents/builtins/git-master.md +0 -30
  1139. package/dist/domains/agents/builtins/provenance.md +0 -30
  1140. package/dist/domains/agents/builtins/researcher.md +0 -71
  1141. package/dist/domains/agents/builtins/scout.md +0 -42
  1142. package/dist/domains/agents/builtins/tester.md +0 -31
  1143. package/dist/domains/agents/builtins/verifier.md +0 -30
  1144. package/dist/domains/agents/builtins/wiki-writer.md +0 -41
  1145. package/dist/fleet-preflight-CLIAX7YR.js +0 -21
  1146. package/dist/preload-KZVHET2B.js +0 -11
  1147. package/dist/version-ROZ6CZKH.js +0 -16
  1148. package/docs/html/agents_blueprint.html +0 -936
  1149. package/docs/html/alcf_blueprint.html +0 -324
  1150. package/docs/html/architecture_blueprint.html +0 -850
  1151. package/docs/html/commands_blueprint.html +0 -794
  1152. package/docs/html/config_knobs_audit_blueprint.html +0 -178
  1153. package/docs/html/configuration_blueprint.html +0 -1080
  1154. package/docs/html/context_blueprint.html +0 -603
  1155. package/docs/html/documentation_blueprint.html +0 -832
  1156. package/docs/html/environment_blueprint.html +0 -404
  1157. package/docs/html/eval_blueprint.html +0 -743
  1158. package/docs/html/evals_internal_blueprint.html +0 -190
  1159. package/docs/html/evolution_blueprint.html +0 -674
  1160. package/docs/html/extensions_blueprint.html +0 -2065
  1161. package/docs/html/fleet_dispatch_blueprint.html +0 -286
  1162. package/docs/html/index.html +0 -919
  1163. package/docs/html/lifecycle_blueprint.html +0 -723
  1164. package/docs/html/memory_blueprint.html +0 -699
  1165. package/docs/html/middleware_blueprint.html +0 -664
  1166. package/docs/html/models_blueprint.html +0 -2366
  1167. package/docs/html/observability_blueprint.html +0 -683
  1168. package/docs/html/provider_adapter_blueprint.html +0 -245
  1169. package/docs/html/safety_blueprint.html +0 -1386
  1170. package/docs/html/shared.css +0 -571
  1171. package/docs/html/shared.js +0 -143
  1172. package/docs/html/skills_blueprint.html +0 -671
  1173. package/docs/html/soak_blueprint.html +0 -182
  1174. package/docs/html/tool_usage_blueprint.html +0 -350
  1175. package/docs/html/tools_blueprint.html +0 -2249
  1176. package/docs/html/trace_blueprint.html +0 -235
  1177. package/docs/html/tui_design_blueprint.html +0 -314
  1178. package/docs/html/validation_blueprint.html +0 -961
  1179. package/docs/html/worker_dispatch_blueprint.html +0 -231
  1180. package/skills/git/commit-crafting/SKILL.md +0 -79
  1181. package/skills/git/commit-crafting/evals.md +0 -92
  1182. package/skills/git/create-pr/SKILL.md +0 -116
  1183. package/skills/git/create-pr/evals.md +0 -114
  1184. package/skills/git/investigate-issue/SKILL.md +0 -139
  1185. package/skills/git/investigate-issue/evals.md +0 -94
  1186. package/skills/git/review-changes/SKILL.md +0 -103
  1187. package/skills/git/review-changes/evals.md +0 -85
@@ -0,0 +1,1090 @@
1
+ /**
2
+ * The chat loop: one turn's state machine.
3
+ *
4
+ * Composition of single-owner turn modules:
5
+ * - turn-runtime.ts target resolution, hot-swap, agent + event pipeline
6
+ * - turn-context.ts prompt compile cache, snapshots, compaction
7
+ * - turn-persistence.ts session-ledger appends
8
+ * - turn-queues.ts steer/follow-up mirror, stranded-steer resubmit
9
+ * - turn-recovery.ts overflow compact-and-retry, transient retry chain
10
+ * - turn-middleware.ts turn hooks and the reminder buffer
11
+ *
12
+ * This file owns the ChatLoop public surface, the submit/cancel state
13
+ * machine, and the shared ChatTurnState the modules coordinate through.
14
+ */
15
+
16
+ import { BusChannels, type RunAbortSource } from "../core/bus-events.js";
17
+ import type { ClioSettings } from "../core/config.js";
18
+ import type { SafeEventBus } from "../core/event-bus.js";
19
+ import type { PendingSkillRequest } from "../core/skill-activation.js";
20
+ import {
21
+ createMiddlewareToolChoiceControl,
22
+ type MiddlewareContract,
23
+ type MiddlewareToolChoiceControl,
24
+ } from "../domains/middleware/index.js";
25
+ import type { ObservabilityContract } from "../domains/observability/contract.js";
26
+ import type { PromptsContract } from "../domains/prompts/contract.js";
27
+ import { toContextOverflowError } from "../domains/providers/errors.js";
28
+ import type { ProvidersContract } from "../domains/providers/index.js";
29
+ import { runtimeTargetSnapshot } from "../domains/providers/index.js";
30
+ import type { ProtectedArtifactState } from "../domains/safety/protected-artifacts.js";
31
+ import type { CompactResult } from "../domains/session/compaction/compact.js";
32
+ import type { ContextSnapshot, ContextUsageSnapshot } from "../domains/session/context-accounting.js";
33
+ import { ceilChars, snapshotInputTokens } from "../domains/session/context-accounting.js";
34
+ import type { ContextLedger } from "../domains/session/context-ledger.js";
35
+ import type { SessionContract } from "../domains/session/contract.js";
36
+ import type { CompactionTrigger, SessionEntry } from "../domains/session/entries.js";
37
+ import { protectedArtifactStateFromSessionEntries } from "../domains/session/protected-artifacts.js";
38
+ import { isRetryableErrorMessage, type RetrySettings } from "../domains/session/retry.js";
39
+ import { createEngineAgent } from "../engine/agent.js";
40
+ import { resolveReservedOutputTokens } from "../engine/apis/output-budget.js";
41
+ import type { AgentEvent, AgentMessage, ImageContent } from "../engine/types.js";
42
+ import { resolveSessionTools } from "../tools/agent-tools.js";
43
+ import { finalizeAskUserInterviewForHost } from "../tools/ask-user.js";
44
+ import type { AskUserToolPolicy, ToolInvokeOptions, ToolRegistry } from "../tools/registry.js";
45
+ import {
46
+ createAskUserToolPolicy,
47
+ createPendingSkillToolPolicy,
48
+ detectOverflowFromState,
49
+ detectTerminalFailureFromState,
50
+ notConfiguredNotice,
51
+ noticeMessage,
52
+ pendingSkillRequestPreamble,
53
+ toolSignatureFromState,
54
+ } from "./chat-loop-messages.js";
55
+ import { normalizeRetrySettings } from "./chat-loop-policy.js";
56
+ import type { ApprovalRequestView } from "./permission-overlay.js";
57
+ import type { AgentStatusEvent } from "./status/types.js";
58
+ import { createTurnContext } from "./turn-context.js";
59
+ import { createTurnMiddleware } from "./turn-middleware.js";
60
+ import { createTurnPersistence } from "./turn-persistence.js";
61
+ import {
62
+ createTurnQueues,
63
+ DEFAULT_STEERING_MODE,
64
+ type QueuedChatMessage,
65
+ type QueuedMessagesSnapshot,
66
+ type SteeringMode,
67
+ } from "./turn-queues.js";
68
+ import {
69
+ createTurnRecovery,
70
+ type RetryStatusEvent,
71
+ reclassifyStallAbort,
72
+ rewriteStallAbortMessage,
73
+ } from "./turn-recovery.js";
74
+ import { type AssistantDeltaEvent, createTurnRuntime, TurnAdmissionError } from "./turn-runtime.js";
75
+ import { type AgentRuntime, type ChatLoopRunSnapshot, createTurnState } from "./turn-state.js";
76
+ import { isWorkerShareNote } from "./worker-share.js";
77
+
78
+ export type { QueuedChatMessage, QueuedMessageKind, QueuedMessagesSnapshot, SteeringMode } from "./turn-queues.js";
79
+ export type { RetryStatusEvent, RetryStatusPayload, RetryStatusPhase } from "./turn-recovery.js";
80
+ export type { AssistantDeltaEvent } from "./turn-runtime.js";
81
+ export type { ChatLoopRunSnapshot } from "./turn-state.js";
82
+
83
+ export interface QueueUpdateEvent {
84
+ type: "queue_update";
85
+ messages: QueuedChatMessage[];
86
+ }
87
+
88
+ /**
89
+ * A queued steer or follow-up the engine just injected into the run. Emitted
90
+ * at injection time (never at enqueue time) so the transcript shows the user
91
+ * turn exactly when the model sees it, mirroring the pi-coding-agent flow
92
+ * where a pending message leaves the queue panel and enters the chat in the
93
+ * same beat. Enqueue time shows the text only in the steering-queue panel.
94
+ */
95
+ export interface QueuedUserTurnEvent {
96
+ type: "queued_user_turn";
97
+ text: string;
98
+ /** `interrupt` marks a message that cancelled the run and was submitted as a fresh prompt. */
99
+ kind: QueuedChatMessage["kind"] | "interrupt";
100
+ }
101
+
102
+ /**
103
+ * First-class advisory event. `surface` says where the notice belongs:
104
+ * "transcript" notices are turn-adjacent chat lines (cancellations,
105
+ * compaction summaries, configuration errors) and "footer" notices are
106
+ * ambient status (nudge chips). Notices are never assistant messages: they
107
+ * carry no `message_end`, cannot become a headless turn's answer, and never
108
+ * end a run.
109
+ */
110
+ export interface ChatNoticeEvent {
111
+ type: "notice";
112
+ level: "info" | "success" | "warning" | "error";
113
+ surface: "footer" | "transcript";
114
+ text: string;
115
+ key?: string;
116
+ /**
117
+ * Present only on a notice that reports a turn Clio refused to start. The
118
+ * `reason` is a closed-set code, not prose: protocol surfaces (the ACP
119
+ * server) fail the turn with it instead of returning an empty success, and
120
+ * every other surface renders the notice exactly as before.
121
+ */
122
+ admission?: { reason: string };
123
+ }
124
+
125
+ /**
126
+ * Approval-lifecycle signal for a tool call that pi already started
127
+ * (`tool_execution_start` fires before admission parks the body). The
128
+ * interactive composition root emits it from the registry's
129
+ * permission-required signal ("awaiting-approval") and from the operator's
130
+ * one-shot grant ("resumed") so the chat panel can restyle the exact parked
131
+ * segment instead of leaving a counting running line. Deny/cancel needs no
132
+ * state here: the parked promise resolves blocked and the segment settles
133
+ * through its ordinary `tool_execution_end`.
134
+ */
135
+ export type ToolApprovalStateEvent =
136
+ | {
137
+ type: "tool_approval_state";
138
+ toolCallId: string;
139
+ state: "awaiting-approval";
140
+ /**
141
+ * Already-redacted facts shown by the permission overlay. This payload
142
+ * exists only on the live event and is never written to the session
143
+ * ledger; the transcript renderer must not reconstruct safety facts
144
+ * from raw tool arguments.
145
+ */
146
+ view: ApprovalRequestView;
147
+ }
148
+ | {
149
+ type: "tool_approval_state";
150
+ toolCallId: string;
151
+ state: "resumed";
152
+ };
153
+
154
+ export type ChatLoopEvent =
155
+ | AgentEvent
156
+ | AssistantDeltaEvent
157
+ | RetryStatusEvent
158
+ | QueueUpdateEvent
159
+ | QueuedUserTurnEvent
160
+ | ChatNoticeEvent
161
+ | AgentStatusEvent
162
+ | ToolApprovalStateEvent;
163
+
164
+ export interface ChatSubmitOptions {
165
+ images?: ReadonlyArray<ImageContent>;
166
+ /** Files already expanded into this session's working context. */
167
+ workingContextPaths?: ReadonlyArray<string>;
168
+ /** Skill requests parsed by the harness for this turn. Not recorded as loaded until the skill body loads. */
169
+ pendingSkillRequests?: ReadonlyArray<PendingSkillRequest>;
170
+ /** Internal middleware resubmit; does not reset the per-user-prompt stalled-turn nudge cap. */
171
+ requestContinuation?: boolean;
172
+ /**
173
+ * Delivery mode when a run is active; ignored when idle. Defaults to
174
+ * `next-slot`. `interrupt` cancels the run, waits for it to settle, and
175
+ * submits the text as a fresh prompt; see {@link ChatLoop.interruptRefusal}
176
+ * for the two states in which it degrades to `next-slot` instead.
177
+ */
178
+ steering?: SteeringMode;
179
+ /**
180
+ * Fires once this submit owns the live turn (`isStreaming()` is true) and
181
+ * the next queued submit may use streaming queue routing. Stage 0 replay
182
+ * awaits it; the loop's own admission gate releases on it.
183
+ */
184
+ onAdmitted?: () => void;
185
+ }
186
+
187
+ /** Closing notice an operator interrupt leaves in the transcript and the ledger. */
188
+ const INTERRUPT_CANCEL_REASON = "[Clio Coder] run interrupted by operator; delivering the new message now.";
189
+ const ENGINE_ACTIVE_PROMPT_ERROR =
190
+ "Agent is already processing a prompt. Use steer() or followUp() to queue messages, or wait for completion.";
191
+ const ACTIVE_PROMPT_NOTICE =
192
+ "[Clio Coder] another response was already active, so this response could not start. Wait for it to finish, then submit again.";
193
+
194
+ function operatorFacingEngineError(message: string): string {
195
+ return message.includes(ENGINE_ACTIVE_PROMPT_ERROR) ? ACTIVE_PROMPT_NOTICE : message;
196
+ }
197
+
198
+ /**
199
+ * Options for {@link ChatLoop.cancel}. A bare cancel is an operator Esc/Ctrl+C
200
+ * that ends the in-flight turn as an empty aborted message. Passing a `reason`
201
+ * marks the cancel as an explained interrupt (the loop guard, or an operator
202
+ * interrupt-with-message): the chat loop persists a durable, visible assistant
203
+ * turn carrying that reason in place of the empty aborted turn, and tags the
204
+ * audit trail with `source`.
205
+ */
206
+ export interface ChatCancelOptions {
207
+ /** Operator-facing explanation for a system-initiated stop. */
208
+ reason?: string;
209
+ /** Audit source for the emitted RunAborted event. Defaults to "stream_cancel". */
210
+ source?: RunAbortSource;
211
+ /** Short audit reason string. Defaults to a source-appropriate phrase. */
212
+ auditReason?: string;
213
+ }
214
+
215
+ export interface ChatLoop {
216
+ submit(text: string, options?: ChatSubmitOptions): Promise<void>;
217
+ steer(text: string): boolean;
218
+ queueFollowUp(text: string): boolean;
219
+ /**
220
+ * Why an interrupt would be refused right now, or null when it would
221
+ * cancel the run. An attached dispatch is refused because the parent's abort
222
+ * kills the worker's run and discards its work with no receipt; a parked
223
+ * permission ask is refused because it is already waiting on the operator.
224
+ * In both cases `submit(text, { steering: "interrupt" })` says so and
225
+ * queues the text for the next slot instead.
226
+ */
227
+ interruptRefusal(): string | null;
228
+ clearQueuedFollowUps(): string[];
229
+ queuedMessages(): QueuedMessagesSnapshot;
230
+ cancel(options?: ChatCancelOptions): void;
231
+ onEvent(handler: (event: ChatLoopEvent) => void): () => void;
232
+ getSessionId(): string | null;
233
+ lastRunSnapshot?(): ChatLoopRunSnapshot | null;
234
+ isStreaming(): boolean;
235
+ contextUsage(): ContextUsageSnapshot;
236
+ /**
237
+ * Categorized context-window ledger for the `/context` overlay: where every
238
+ * occupied token lives (system prompt, tools, agents, skills, memory,
239
+ * messages), the autocompact reserve, and free space. Composes the live
240
+ * estimate with the current turn's prompt segment manifest.
241
+ */
242
+ contextLedger(): ContextLedger;
243
+ /**
244
+ * Force-run the compaction flow for the current session, swap the agent's
245
+ * in-memory `state.messages` for a single bridge message carrying the
246
+ * summary, and emit the standard summary notice. Used by `/context compact`
247
+ * slash command so the next user turn ships only the bridge plus the new
248
+ * text to the provider (slice 12.5b bug 4). Silent no-op when no session
249
+ * or no compaction deps are wired; in both cases emits a user-visible
250
+ * notice so the `/context compact` handler does not have to mirror the logic.
251
+ */
252
+ compact(instructions?: string): Promise<void>;
253
+ /**
254
+ * Drop or replace the chat-loop's in-memory state after a session switch
255
+ * (/resume, /fork, /new). `leafTurnId` is the id the next user turn
256
+ * should parent under. `replayMessages` is the provider context rebuilt
257
+ * from the selected session entries; omit it for a fresh session.
258
+ */
259
+ resetForSession(leafTurnId: string | null, replayMessages?: ReadonlyArray<AgentMessage>): void;
260
+ /** Abort the live agent and release pi-ai session-scoped resources before shutdown. */
261
+ dispose(): void;
262
+ /**
263
+ * Resolves once the in-flight submit (if any) has fully settled, including
264
+ * the aborted run's tool results and their ledger appends. Shutdown awaits
265
+ * this after dispose() so domains (the session writer among them) never
266
+ * stop while the turn is still persisting: `session.append` after session
267
+ * stop is impossible by ordering.
268
+ */
269
+ whenSettled(): Promise<void>;
270
+ }
271
+
272
+ export interface CreateChatLoopDeps {
273
+ getSettings: () => Readonly<ClioSettings>;
274
+ providers: ProvidersContract;
275
+ /**
276
+ * Whitelist of target ids that the chat-loop is allowed to drive. The
277
+ * orchestrator composes this from `providers.list()` so an unknown
278
+ * `settings.orchestrator.target` surfaces a configuration error before
279
+ * the agent is constructed.
280
+ */
281
+ knownTargets: () => ReadonlySet<string>;
282
+ session?: SessionContract;
283
+ /**
284
+ * Prompt compiler. When wired, the session system prompt is compiled once
285
+ * per session and written into `state.systemPrompt`; recompiles happen
286
+ * only on explicit events (model/target change, safety-level change,
287
+ * config hot-reload, session switch).
288
+ *
289
+ * Optional so unit tests can inject stubs and a degraded boot (prompts
290
+ * failed to load) still runs with the built-in identity fallback below.
291
+ * In production this is always wired by `entry/orchestrator.ts`.
292
+ */
293
+ prompts?: PromptsContract;
294
+ createAgent?: typeof createEngineAgent;
295
+ /**
296
+ * Return the current session's entries for token estimation. The chat-loop
297
+ * calls this on every submit so the auto-compaction threshold sees the
298
+ * latest transcript. Returns an empty array when there is no current
299
+ * session or when the session contract is absent.
300
+ */
301
+ readSessionEntries?: () => ReadonlyArray<SessionEntry>;
302
+ /**
303
+ * Run the compaction flow end-to-end (read entries, resolve model,
304
+ * summarize, persist a compactionSummary entry) and return the result,
305
+ * or null when the flow is a legitimate no-op (no entries or no cut
306
+ * crossed). Configuration, provider, read, and persistence failures reject
307
+ * so the activity path can report them as failures. Chat-loop invokes this from two sites:
308
+ * 1. Before every agent.prompt when the threshold is crossed or
309
+ * CLIO_CODER_FORCE_COMPACT=1 is set.
310
+ * 2. After catching a ContextOverflowError, as the first half of the
311
+ * one-shot compact-and-retry recovery path.
312
+ * Both sites share an AutoCompactionTrigger so two fires in the same tick
313
+ * coalesce onto one summarization call.
314
+ */
315
+ autoCompact?: (instructions?: string, trigger?: CompactionTrigger) => Promise<CompactResult | null>;
316
+ /** Optional observability sink for orchestrator chat token usage. */
317
+ observability?: ObservabilityContract;
318
+ /**
319
+ * Production tool admission path. When wired, every agent-facing tool runs
320
+ * through `ToolRegistry.invoke(...)` so safety classification and
321
+ * confirmation admission happen on the actual execution path.
322
+ */
323
+ toolRegistry?: ToolRegistry;
324
+ /**
325
+ * Middleware hook surface. When wired, the chat-loop fires `turn_start`
326
+ * when a prompt is accepted (flushing accumulated `inject_reminder`
327
+ * effects into the request as a system-reminder block) and `turn_end`
328
+ * when the final assistant message of a run lands (finish contract,
329
+ * tool-prose loop). Optional so unit tests that exercise neither stay
330
+ * minimal.
331
+ */
332
+ middleware?: MiddlewareContract;
333
+ /**
334
+ * Shared next-round provider routing. The registry applies effects emitted
335
+ * by before_tool/after_tool; the chat loop applies turn hooks and consumes
336
+ * the resulting choice in onPayload.
337
+ */
338
+ middlewareToolChoice?: MiddlewareToolChoiceControl;
339
+ /**
340
+ * Protected-artifact state handle, backed by the protected-artifacts hook
341
+ * registration at the composition root. The chat-loop replaces the state
342
+ * wholesale on session switch so protections follow the active session.
343
+ */
344
+ protectedArtifacts?: {
345
+ replace(state: ProtectedArtifactState): void;
346
+ markDegraded(reason: string): void;
347
+ };
348
+ /**
349
+ * Shared event bus. When wired, `cancel()` fans a `BusChannels.RunAborted`
350
+ * payload with `source: "stream_cancel"` so the safety audit subscriber
351
+ * persists a kind: "abort" row for every Esc-on-stream / Ctrl+C cancel.
352
+ * Optional so unit tests that drive chat-loop in isolation do not need
353
+ * to construct a bus.
354
+ */
355
+ bus?: SafeEventBus;
356
+ /**
357
+ * Build the approved-memory prompt section for the current turn. Returns
358
+ * the empty string when no approved, evidence-linked, in-scope memory
359
+ * applies; otherwise returns a compact markdown section that the prompt
360
+ * compiler injects via the memory dynamic fragment. Optional so unit
361
+ * tests omit it when memory is irrelevant.
362
+ */
363
+ getMemorySection?: () => string;
364
+ /** Structured, redacted task-bank export supplied only to an explicit context-handoff skill request. */
365
+ getTaskMemoryHandoffSource?: () => string;
366
+ /**
367
+ * Hand the composition root a delivery path for reminders that background
368
+ * observers produce after their turn boundary closed. Called once during
369
+ * composition; the loop owns the buffer the reminder lands in.
370
+ */
371
+ registerDeferredReminderSink?: (sink: (message: string) => void) => void;
372
+ /**
373
+ * Host-finalizer seam for branch-anchored interview snapshots. Called once,
374
+ * after the ask-user host finalizer has settled the policy and its transcript.
375
+ */
376
+ onAskUserFinalized?: (policy: AskUserToolPolicy) => void;
377
+ /**
378
+ * True while an attached `dispatch` call is running. An interrupt is refused
379
+ * in that state; the composition root wires this from the dispatch
380
+ * background registry, which holds exactly the attached calls.
381
+ */
382
+ hasAttachedDispatch?: () => boolean;
383
+ }
384
+
385
+ export function reloadProtectedArtifactsForSession(
386
+ protectedArtifacts: NonNullable<CreateChatLoopDeps["protectedArtifacts"]>,
387
+ readSessionEntries: (() => ReadonlyArray<SessionEntry>) | undefined,
388
+ ): void {
389
+ try {
390
+ const entries = readSessionEntries ? readSessionEntries() : [];
391
+ protectedArtifacts.replace(protectedArtifactStateFromSessionEntries(entries));
392
+ } catch (error) {
393
+ protectedArtifacts.markDegraded(
394
+ `session protection history could not be read: ${error instanceof Error ? error.message : String(error)}`,
395
+ );
396
+ }
397
+ }
398
+
399
+ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
400
+ const listeners = new Set<(event: ChatLoopEvent) => void>();
401
+ const createAgent = deps.createAgent ?? createEngineAgent;
402
+ const middlewareToolChoice = deps.middlewareToolChoice ?? createMiddlewareToolChoiceControl();
403
+ const state = createTurnState(deps.getSettings().orchestrator.thinkingLevel ?? "off");
404
+ const toolStartTimes = new Map<string, number>();
405
+
406
+ const emit = (event: ChatLoopEvent): void => {
407
+ for (const listener of listeners) {
408
+ listener(event);
409
+ }
410
+ };
411
+
412
+ const emitFooterNotice = (level: ChatNoticeEvent["level"], text: string, key: string): void => {
413
+ emit({ type: "notice", level, surface: "footer", text, key });
414
+ };
415
+
416
+ /**
417
+ * Transcript notices are first-class `notice` events, never fake
418
+ * `message_end` assistant messages: a notice can never become a headless
419
+ * turn's answer, never carries usage, and never ends a run. Run closure is
420
+ * the engine's job (handleRunFailure delivers agent_end on abort and
421
+ * provider-failure paths) and RunAborted carries abort provenance to the
422
+ * status reducer.
423
+ */
424
+ const emitNotice = (text: string, level: ChatNoticeEvent["level"] = "info", key?: string): void => {
425
+ emit({ type: "notice", level, surface: "transcript", text, ...(key === undefined ? {} : { key }) });
426
+ };
427
+
428
+ /**
429
+ * The same transcript notice every admission exit already emitted, carrying
430
+ * the reason the turn never started. Text, level, and surface are unchanged,
431
+ * so the TUI and headless paths render exactly what they rendered before.
432
+ */
433
+ const emitAdmissionNotice = (text: string, reason: string): void => {
434
+ emit({ type: "notice", level: "info", surface: "transcript", text, admission: { reason } });
435
+ };
436
+
437
+ /**
438
+ * Which of the two settings is actually missing when the runtime resolves to
439
+ * null. Both halves produce the same operator-facing notice, but a machine
440
+ * consumer of the reason (the ACP server reports it as `data.reason`) needs
441
+ * to tell "no orchestrator at all" from "a target that names no model", and
442
+ * collapsing them sent a client with a configured target to the wrong fix.
443
+ */
444
+ const nullRuntimeAdmissionReason = (): string => {
445
+ const orchestrator = deps.getSettings().orchestrator;
446
+ const target = orchestrator.target?.trim() ?? "";
447
+ const model = orchestrator.model?.trim() ?? "";
448
+ return target.length > 0 && model.length === 0 ? "model-not-configured" : "orchestrator-not-configured";
449
+ };
450
+
451
+ const retrySettings = (): RetrySettings => normalizeRetrySettings(deps.getSettings().retry);
452
+
453
+ const currentToolInvokeOptions = (): Partial<ToolInvokeOptions> => {
454
+ const options: Partial<ToolInvokeOptions> = {};
455
+ const sessionId = deps.session?.current()?.id ?? null;
456
+ if (sessionId) options.sessionId = sessionId;
457
+ const turnId = state.activeUserTurnId ?? state.lastTurnId;
458
+ if (turnId) options.turnId = turnId;
459
+ if (state.currentPendingSkillPolicy) options.pendingSkillPolicy = state.currentPendingSkillPolicy;
460
+ if (state.currentAskUserPolicy) options.askUserPolicy = state.currentAskUserPolicy;
461
+ return options;
462
+ };
463
+
464
+ // --- module composition -------------------------------------------------
465
+
466
+ const queues = createTurnQueues({
467
+ state,
468
+ emitQueueUpdateEvent: (messages) => emit({ type: "queue_update", messages }),
469
+ emitQueuedUserTurn: (entry) => emit({ type: "queued_user_turn", text: entry.text, kind: entry.kind }),
470
+ emitNotice,
471
+ // The loop's own resubmits (stranded steers, continuation requests) run
472
+ // from submit's finally and bypass the admission gate: an interrupt that
473
+ // holds the gate while awaiting that same run would otherwise deadlock.
474
+ submit: (text, options) => submitTracked(text, options),
475
+ });
476
+
477
+ const middleware = createTurnMiddleware({
478
+ state,
479
+ middleware: deps.middleware,
480
+ session: deps.session,
481
+ middlewareToolChoice,
482
+ emitNotice,
483
+ emitFooterNotice,
484
+ });
485
+
486
+ try {
487
+ deps.registerDeferredReminderSink?.((message) => middleware.injectDeferredReminder(message));
488
+ } catch {
489
+ // A background observer losing its delivery path must not stop the loop
490
+ // from starting; it simply stays silent.
491
+ }
492
+
493
+ const context = createTurnContext({
494
+ state,
495
+ getSettings: deps.getSettings,
496
+ providers: deps.providers,
497
+ session: deps.session,
498
+ prompts: deps.prompts,
499
+ toolRegistry: deps.toolRegistry,
500
+ observability: deps.observability,
501
+ bus: deps.bus,
502
+ readSessionEntries: deps.readSessionEntries,
503
+ autoCompact: deps.autoCompact,
504
+ getMemorySection: deps.getMemorySection,
505
+ middleware,
506
+ emitNotice,
507
+ });
508
+
509
+ const persistence = createTurnPersistence({
510
+ state,
511
+ session: deps.session,
512
+ getSettings: deps.getSettings,
513
+ middlewareToolChoice,
514
+ consumePersistedEcho: (text) => queues.consumePersistedEcho(text),
515
+ removeQueuedMirrorEntry: (text) => queues.removeQueuedMirrorEntry(text),
516
+ promptCachePayloadForAssistant: (usage) => context.promptCachePayloadForAssistant(usage),
517
+ promptSideTokens: () => context.promptSideTokens(),
518
+ observability: deps.observability,
519
+ });
520
+
521
+ const recovery = createTurnRecovery({
522
+ state,
523
+ persistence,
524
+ context,
525
+ retrySettings,
526
+ markPersistedUserEcho: (text, prompt) => queues.markPersistedUserEcho(text, prompt),
527
+ emitRetryStatus: (status) => emit({ type: "retry_status", status }),
528
+ emitFailureMessage: (message) => emit({ type: "message_end", message }),
529
+ emitNotice,
530
+ });
531
+ const emitRuntimeEvent = (event: AgentEvent | AssistantDeltaEvent): void => {
532
+ if (event.type === "message_end") rewriteStallAbortMessage(state, event.message);
533
+ emit(event as ChatLoopEvent);
534
+ };
535
+
536
+ const turnRuntime = createTurnRuntime({
537
+ state,
538
+ getSettings: deps.getSettings,
539
+ providers: deps.providers,
540
+ knownTargets: deps.knownTargets,
541
+ observability: deps.observability,
542
+ createAgent,
543
+ middlewareToolChoice,
544
+ persistence,
545
+ context,
546
+ middleware,
547
+ retrySettings,
548
+ emit: emitRuntimeEvent,
549
+ emitNotice,
550
+ toolStartTimes,
551
+ });
552
+
553
+ // --- bus subscriptions --------------------------------------------------
554
+
555
+ // A config hot-reload may change prompt fragments or settings that feed
556
+ // the session prompt; invalidate so the next submit recompiles. If the
557
+ // recompiled text is byte-identical, nothing changes and no ledger entry
558
+ // is written.
559
+ const unsubscribeConfigReload =
560
+ deps.bus?.on(BusChannels.ConfigHotReload, () => {
561
+ context.invalidateSessionPromptCache();
562
+ }) ?? null;
563
+
564
+ const unsubscribeSynthesisLock =
565
+ deps.bus?.on(BusChannels.LoopBlocked, (payload) => {
566
+ const disposition = (payload as { disposition?: unknown } | null)?.disposition;
567
+ if (disposition === "lockout") state.synthesisToolLock = true;
568
+ }) ?? null;
569
+
570
+ // --- the state machine --------------------------------------------------
571
+
572
+ // Settlement tracking for whenSettled(): the latest submit's promise,
573
+ // coerced to never reject so shutdown ordering cannot throw. `priorSubmit`
574
+ // is the promise `activeSubmit` held before the latest submit replaced it,
575
+ // which is the run an interrupt has to wait out.
576
+ let activeSubmit: Promise<void> = Promise.resolve();
577
+ let priorSubmit: Promise<void> = Promise.resolve();
578
+
579
+ const interruptRefusalReason = (): string | null => {
580
+ if (deps.hasAttachedDispatch?.() === true) {
581
+ return "an attached dispatch is running and the interrupt would kill the worker's run with no receipt; use @<agent> to steer it or Esc to cancel it";
582
+ }
583
+ if (deps.toolRegistry?.hasParkedCalls() === true) {
584
+ return "a permission ask is parked and already waiting on you; answer it or press Esc";
585
+ }
586
+ return null;
587
+ };
588
+
589
+ const api: ChatLoop = {
590
+ steer: (text) => queues.steer(text),
591
+ queueFollowUp: (text) => queues.queueFollowUp(text),
592
+ interruptRefusal: () => (state.streaming ? interruptRefusalReason() : null),
593
+ clearQueuedFollowUps: () => queues.clearQueuedMirror().map((entry) => entry.text),
594
+ queuedMessages: () => queues.queuedMessages(),
595
+
596
+ async submit(text: string, options: ChatSubmitOptions = {}): Promise<void> {
597
+ let interrupted = false;
598
+ if (state.streaming) {
599
+ let mode: SteeringMode = options.steering ?? DEFAULT_STEERING_MODE;
600
+ const trimmed = text.trim();
601
+ if (mode === "interrupt" && trimmed.length > 0) {
602
+ const refusal = interruptRefusalReason();
603
+ if (refusal !== null) {
604
+ emitNotice(`[Clio Coder] interrupt refused: ${refusal}. Queued for the next slot instead.`, "warning");
605
+ mode = "next-slot";
606
+ } else {
607
+ // Cancel, then wait for the cancelled run to settle (its in-flight
608
+ // tool results and closing ledger turn), then fall through to the
609
+ // fresh-prompt path below. `priorSubmit` is the run being cancelled;
610
+ // `activeSubmit` already points at this call.
611
+ const prior = priorSubmit;
612
+ api.cancel({
613
+ reason: INTERRUPT_CANCEL_REASON,
614
+ auditReason: "operator interrupted the run with a message",
615
+ });
616
+ await prior;
617
+ if (!state.streaming) {
618
+ interrupted = true;
619
+ } else {
620
+ // Something restarted a run while the cancel settled (a
621
+ // continuation resubmit); do not fight it, deliver at the next slot.
622
+ emitNotice(
623
+ "[Clio Coder] a run restarted before the interrupt landed. Queued for the next slot instead.",
624
+ "warning",
625
+ );
626
+ mode = "next-slot";
627
+ }
628
+ }
629
+ }
630
+ if (!interrupted) {
631
+ const hasImages = options.images !== undefined && options.images.length > 0;
632
+ if (!hasImages && trimmed.length > 0 && state.runtime) {
633
+ // Enter while streaming means "correct it now": the engine
634
+ // steering queue drains after every tool batch, so the text
635
+ // lands as a user message before the next model turn.
636
+ // alt+enter (queueFollowUp) keeps the after-this-run intent.
637
+ if (isWorkerShareNote(trimmed)) state.turnSharedWorkerNote = true;
638
+ if (mode === "end-of-turn") queues.queueFollowUp(trimmed);
639
+ else queues.steer(trimmed);
640
+ return;
641
+ }
642
+ emitNotice("[Clio Coder] response already in progress. Press Esc to cancel the active run.");
643
+ return;
644
+ }
645
+ }
646
+
647
+ state.lastRunSnapshot = null;
648
+ let agentRuntime: AgentRuntime | null;
649
+ try {
650
+ await turnRuntime.ensureLiveCapabilitiesForSelectedModel();
651
+ agentRuntime = turnRuntime.ensureRuntime();
652
+ } catch (err) {
653
+ emitAdmissionNotice(
654
+ err instanceof Error ? err.message : String(err),
655
+ err instanceof TurnAdmissionError ? err.reason : "admission-failed",
656
+ );
657
+ return;
658
+ }
659
+ if (!agentRuntime) {
660
+ emitAdmissionNotice(notConfiguredNotice(), nullRuntimeAdmissionReason());
661
+ return;
662
+ }
663
+
664
+ // 1. Accept the prompt: reset per-turn accounting, freeze the tool
665
+ // surface, fire turn_start, and assemble the submitted text.
666
+ state.turnToolCalls = 0;
667
+ state.turnSharedWorkerNote = isWorkerShareNote(text);
668
+ middlewareToolChoice.reset();
669
+ if (options.requestContinuation !== true) state.stalledTurnNudgeSpent = false;
670
+ const images = options.images && options.images.length > 0 ? [...options.images] : undefined;
671
+ const pendingSkillRequests = options.pendingSkillRequests ?? [];
672
+ context.addWorkingContextPaths(options.workingContextPaths ?? []);
673
+ const pendingSkillPolicy = createPendingSkillToolPolicy(pendingSkillRequests);
674
+ // Resolve the frozen session tool surface before turn_start so intent
675
+ // middleware sees the exact tools this request can actually call.
676
+ agentRuntime.agent.state.tools = resolveSessionTools(
677
+ agentRuntime,
678
+ deps.toolRegistry,
679
+ currentToolInvokeOptions,
680
+ turnRuntime.toolTelemetry,
681
+ );
682
+ const askUserPolicy = createAskUserToolPolicy(agentRuntime.agent.state.tools);
683
+ // turn_start: the prompt is accepted; registrations may inject
684
+ // context for this request. Accumulated reminders (turn_end
685
+ // advisories from the previous turn plus anything turn_start just
686
+ // emitted) flush into the request as one system-reminder block.
687
+ // Like the skill preamble below, the block is plain visible text in
688
+ // the user message: persisted in the ledger, no hidden prompt
689
+ // machinery.
690
+ middleware.fireTurnStart(agentRuntime, text, pendingSkillRequests.length, options.requestContinuation === true);
691
+ const reminderBlock = middleware.flushPendingReminders();
692
+ // Pending skill requests are plain visible text in the user message
693
+ // itself: persisted in the ledger, no hidden prompt machinery.
694
+ const skillPreamble = pendingSkillRequestPreamble(pendingSkillRequests);
695
+ let taskMemoryHandoffSource = "";
696
+ if (pendingSkillRequests.some((request) => request.name.trim() === "context-handoff")) {
697
+ try {
698
+ taskMemoryHandoffSource = deps.getTaskMemoryHandoffSource?.() ?? "";
699
+ } catch {
700
+ // Handoff export is supplemental; a snapshot failure must not block
701
+ // the explicitly requested skill turn.
702
+ }
703
+ }
704
+ const submittedText = [reminderBlock, skillPreamble, taskMemoryHandoffSource, text]
705
+ .filter((part) => part.length > 0)
706
+ .join("\n\n");
707
+
708
+ // 2. Pre-submit auto-compaction trigger
709
+ const forceNow = process.env.CLIO_CODER_FORCE_COMPACT === "1";
710
+ try {
711
+ await context.runAutoCompact(agentRuntime, forceNow, undefined, undefined, submittedText);
712
+ } catch (err) {
713
+ emitNotice(`[Clio Coder] auto-compaction failed: ${err instanceof Error ? err.message : String(err)}`);
714
+ }
715
+
716
+ // 3. Ensure the session prompt (compiles only on explicit events)
717
+ const compiledPrompt = await context.ensureSessionPrompt(agentRuntime);
718
+
719
+ // 4. Preflight overflow check, before the user turn is committed.
720
+ // A blocked request must not leave a dangling user entry that the
721
+ // next replay would treat as an unanswered turn.
722
+ const compactionThreshold = deps.getSettings().compaction?.threshold ?? null;
723
+ const captureTurnSnapshot = (turnId: string): ContextSnapshot =>
724
+ context.captureRuntimeContextSnapshot(agentRuntime, turnId, compactionThreshold, {
725
+ promptSegments: compiledPrompt
726
+ ? compiledPrompt.sections.map((s) => ({ id: s.id, tokenEstimate: s.tokenEstimate }))
727
+ : undefined,
728
+ pendingUserInput: submittedText,
729
+ images,
730
+ promptHash: compiledPrompt?.systemPromptHash,
731
+ toolSignature: toolSignatureFromState(agentRuntime.agent.state.tools),
732
+ });
733
+
734
+ const reservedOutput = resolveReservedOutputTokens(agentRuntime.runtimeResolution.capabilityDecisions.maxTokens);
735
+ const effectiveWindow = agentRuntime.runtimeResolution.contextWindowDetails.effectiveContextWindow;
736
+ const pendingInputTokens = ceilChars(submittedText.length);
737
+ let turnSnapshot = captureTurnSnapshot("pending");
738
+ const totalEstimate = snapshotInputTokens(turnSnapshot) + pendingInputTokens + reservedOutput;
739
+
740
+ if (effectiveWindow > 0 && totalEstimate > effectiveWindow) {
741
+ emitNotice(
742
+ `[Clio Coder] Estimated request size ${totalEstimate} tokens (input ${snapshotInputTokens(turnSnapshot) + pendingInputTokens} + output budget ${reservedOutput}) exceeds the effective context window of ${effectiveWindow} tokens. Running compaction before sending...`,
743
+ );
744
+ const compacted = await context.runAutoCompact(agentRuntime, true, undefined, undefined, submittedText);
745
+ if (!compacted) {
746
+ emitNotice(
747
+ "[Clio Coder] Compaction could not reclaim enough space. Request blocked; trim the prompt, reduce active tools, or start a fresh session.",
748
+ );
749
+ return;
750
+ }
751
+ context.refreshAgentMessagesFromSession(agentRuntime);
752
+ turnSnapshot = captureTurnSnapshot("pending");
753
+ const postTotalEstimate = snapshotInputTokens(turnSnapshot) + pendingInputTokens + reservedOutput;
754
+ if (postTotalEstimate > effectiveWindow) {
755
+ emitNotice(
756
+ `[Clio Coder] Request still exceeds the effective window after compaction (${postTotalEstimate} > ${effectiveWindow}). Request blocked.`,
757
+ );
758
+ return;
759
+ }
760
+ emitNotice(
761
+ `[Clio Coder] Context budget check passed post-compaction (${postTotalEstimate} <= ${effectiveWindow}). Proceeding.`,
762
+ );
763
+ }
764
+
765
+ // 5. Append the user turn, then stamp and persist the snapshot.
766
+ // PendingSkillRequest is intent only; SkillActivation ledger entries
767
+ // are recorded on skill-load success.
768
+ const userTurnId = persistence.appendSubmittedUserTurn(
769
+ agentRuntime,
770
+ submittedText,
771
+ images,
772
+ options.requestContinuation === true,
773
+ text,
774
+ );
775
+ // An interrupt was submitted while a run was active, so no caller drew
776
+ // it in the transcript; render it here, after the cancel notice and the
777
+ // cancelled run's leftovers, which is the order the ledger has.
778
+ if (interrupted) emit({ type: "queued_user_turn", text, kind: "interrupt" });
779
+ context.logPromptCompileIfPending();
780
+ turnSnapshot = { ...turnSnapshot, turnId: userTurnId ?? "unknown" };
781
+ context.setCurrentSnapshot(turnSnapshot);
782
+ context.persistContextSnapshot(turnSnapshot);
783
+ const promptHash = compiledPrompt?.systemPromptHash ?? null;
784
+ state.lastRunSnapshot = {
785
+ targetId: agentRuntime.targetId,
786
+ targetUrl: agentRuntime.runtimeResolution.target.url ?? null,
787
+ runtimeId: agentRuntime.runtimeId,
788
+ runtimeKind: agentRuntime.runtimeResolution.runtimeKind,
789
+ wireModelId: agentRuntime.wireModelId,
790
+ autonomy: deps.getSettings().autonomy,
791
+ compiledPromptHash: promptHash,
792
+ staticCompositionHash: promptHash,
793
+ promptSignature: promptHash,
794
+ toolSignature: toolSignatureFromState(agentRuntime.agent.state.tools),
795
+ runtimeResolution: runtimeTargetSnapshot(agentRuntime.runtimeResolution),
796
+ sessionId: deps.session?.current()?.id ?? null,
797
+ cwd: process.cwd(),
798
+ };
799
+
800
+ agentRuntime.agent.maxRetryDelayMs = retrySettings().maxDelayMs;
801
+ state.currentThinkingLevel = agentRuntime.agent.state.thinkingLevel;
802
+ state.toolProseAbortReason = null;
803
+ state.toolProseAssessedChars = 0;
804
+ state.activeInterruptReason = null;
805
+ state.interruptedUsage = null;
806
+
807
+ // 6. Cache-disturbance honesty (T3.3)
808
+ context.consumeExpectedColdReasons(agentRuntime.runtimeId);
809
+
810
+ // 7. Run the prompt, then route the settled state through recovery.
811
+ state.streaming = true;
812
+ try {
813
+ options.onAdmitted?.();
814
+ } catch {
815
+ // Admission observers are bookkeeping only and cannot affect the turn.
816
+ }
817
+ const runtimePromptText = submittedText;
818
+ const priorPendingSkillPolicy = state.currentPendingSkillPolicy;
819
+ const priorAskUserPolicy = state.currentAskUserPolicy;
820
+ state.currentPendingSkillPolicy = pendingSkillPolicy;
821
+ state.currentAskUserPolicy = askUserPolicy;
822
+ try {
823
+ await queues.markPersistedUserEcho(runtimePromptText, () => agentRuntime.agent.prompt(runtimePromptText, images));
824
+ // pi-agent-core does NOT throw on provider failures:
825
+ // it pushes an assistant message with stopReason="error" and
826
+ // errorMessage="<provider text>" onto state.messages, sets
827
+ // state.errorMessage, emits agent_end, and resolves normally.
828
+ // The overflow-recovery heuristic must inspect the state after
829
+ // a resolve, not only the catch arm.
830
+ const overflowPostResolve = detectOverflowFromState(agentRuntime.agent);
831
+ if (overflowPostResolve) {
832
+ await recovery.runCompactAndRetry(agentRuntime, runtimePromptText, overflowPostResolve, images);
833
+ } else {
834
+ const settled = detectTerminalFailureFromState(agentRuntime.agent);
835
+ if (settled) {
836
+ if (state.toolProseAbortReason && settled.message) {
837
+ (settled.message as { errorMessage?: string }).errorMessage = state.toolProseAbortReason;
838
+ }
839
+ // A stalled stream settles here, not in the catch arm: the engine's
840
+ // runWithLifecycle swallows the abort and resolves with an aborted
841
+ // assistant message. Reclassify before the ladder's gate so the
842
+ // watchdog's abort retries and an operator cancel still does not.
843
+ const failure = reclassifyStallAbort(state, settled);
844
+ recovery.ensureFailureVisibleAndPersisted(failure);
845
+ await recovery.runTransientRetryChain(agentRuntime, runtimePromptText, failure);
846
+ }
847
+ }
848
+ } catch (err) {
849
+ // Genuine throws (network, abort, pre-stream bugs) still land
850
+ // here. The heuristic is the same so a thrown overflow from
851
+ // an older pi-agent-core still routes through compact-retry.
852
+ const overflow = toContextOverflowError(err);
853
+ if (!overflow) {
854
+ const message = state.toolProseAbortReason ?? (err instanceof Error ? err.message : String(err));
855
+ if (isRetryableErrorMessage(message)) {
856
+ const failureMessage = {
857
+ role: "assistant",
858
+ content: [{ type: "text", text: "" }],
859
+ stopReason: "error",
860
+ errorMessage: message,
861
+ timestamp: Date.now(),
862
+ } as AgentMessage;
863
+ await recovery.runTransientRetryChain(agentRuntime, runtimePromptText, {
864
+ stopReason: "error",
865
+ errorMessage: message,
866
+ message: failureMessage,
867
+ });
868
+ return;
869
+ }
870
+ emitNotice(operatorFacingEngineError(message));
871
+ return;
872
+ }
873
+ await recovery.runCompactAndRetry(agentRuntime, runtimePromptText, overflow, images);
874
+ } finally {
875
+ if (askUserPolicy) {
876
+ try {
877
+ await finalizeAskUserInterviewForHost(
878
+ askUserPolicy,
879
+ "turn_finished",
880
+ currentToolInvokeOptions(),
881
+ deps.onAskUserFinalized,
882
+ );
883
+ } catch (error) {
884
+ emitNotice(
885
+ `[Clio Coder] interview decisions could not be persisted: ${error instanceof Error ? error.message : String(error)}`,
886
+ "warning",
887
+ `decision-ledger:${askUserPolicy.id}`,
888
+ );
889
+ }
890
+ }
891
+ state.streaming = false;
892
+ if (state.activeInterruptReason !== null) {
893
+ // The loop-guard cancel showed its closing message live; persist
894
+ // the durable closing turn only now, after the aborted run's
895
+ // in-flight tool results have all landed, so the ledger replays
896
+ // as tool_calls → tool_results → closing text.
897
+ // A thinking-only abort never reaches the ledger, so its estimated
898
+ // spend rides on the closing turn; persistence computes nothing
899
+ // further for a message that already reports positive usage.
900
+ const closing = noticeMessage(state.activeInterruptReason);
901
+ if (state.interruptedUsage !== null) {
902
+ (closing as { usage?: unknown }).usage = state.interruptedUsage;
903
+ }
904
+ persistence.appendAssistantTurn(closing);
905
+ state.activeInterruptReason = null;
906
+ state.interruptedUsage = null;
907
+ }
908
+ state.currentPendingSkillPolicy = priorPendingSkillPolicy;
909
+ state.currentAskUserPolicy = priorAskUserPolicy;
910
+ state.activeUserTurnId = null;
911
+ // Safety net for thrown paths where agent_end never delivered;
912
+ // no-op when the agent_end flush already ran.
913
+ context.flushReconciledSnapshot();
914
+ // Runs on every exit path (normal settle, catch-arm returns) so
915
+ // a steer the engine never drained still reaches the model.
916
+ if (!(await queues.resubmitStrandedSteers())) await queues.resubmitRequestContinuation();
917
+ }
918
+ },
919
+
920
+ cancel(options?: ChatCancelOptions): void {
921
+ const wasStreaming = state.streaming;
922
+ recovery.cancelRetryCountdown();
923
+ // Clear both queues before the abort settles the in-flight prompt:
924
+ // a cancelled run must not deliver queued steers or follow-ups, and
925
+ // the stranded-steer fallback must find an empty mirror.
926
+ queues.clearQueuedMirror();
927
+ const requestedReason = options?.reason?.trim();
928
+ if (wasStreaming) {
929
+ // Show the stop reason immediately, but persist the durable closing
930
+ // turn only when the run settles (submit's finally). The abort below
931
+ // still lets the in-flight tool results land; persisting here would
932
+ // interleave an assistant turn between a tool-call message and its
933
+ // results, which strict chat templates reject on replay.
934
+ // `activeInterruptReason` meanwhile suppresses the empty aborted
935
+ // messages the abort leaves behind, in both the ledger and the live
936
+ // transcript. Operator cancels take the same path with the default
937
+ // text, so they no longer render a redundant "[aborted] Request was
938
+ // aborted" turn on top of the cancellation notice.
939
+ state.activeInterruptReason =
940
+ requestedReason && requestedReason.length > 0 ? requestedReason : "[Clio Coder] active response cancelled.";
941
+ emitNotice(state.activeInterruptReason, "warning", "turn.interrupted");
942
+ }
943
+ state.runtime?.agent.abort();
944
+ if (wasStreaming && deps.bus) {
945
+ deps.bus.emit(BusChannels.RunAborted, {
946
+ source: options?.source ?? "stream_cancel",
947
+ runId: null,
948
+ startedAt: null,
949
+ elapsedMs: null,
950
+ at: Date.now(),
951
+ reason: options?.auditReason ?? (requestedReason ? "loop guard stopped a runaway turn" : "user cancelled stream"),
952
+ });
953
+ }
954
+ },
955
+
956
+ onEvent(handler: (event: ChatLoopEvent) => void): () => void {
957
+ listeners.add(handler);
958
+ return () => {
959
+ listeners.delete(handler);
960
+ };
961
+ },
962
+
963
+ getSessionId(): string | null {
964
+ return deps.session?.current()?.id ?? null;
965
+ },
966
+
967
+ lastRunSnapshot(): ChatLoopRunSnapshot | null {
968
+ return state.lastRunSnapshot ? structuredClone(state.lastRunSnapshot) : null;
969
+ },
970
+
971
+ isStreaming(): boolean {
972
+ return state.streaming;
973
+ },
974
+
975
+ contextUsage: () => context.contextUsage(),
976
+ contextLedger: () => context.contextLedger(),
977
+ whenSettled: () => activeSubmit,
978
+
979
+ resetForSession(leafTurnId: string | null, replayMessages?: ReadonlyArray<AgentMessage>): void {
980
+ if (state.runtime) {
981
+ state.runtime.agent.abort();
982
+ (state.runtime.agent as { clearAllQueues?: () => void } | undefined)?.clearAllQueues?.();
983
+ turnRuntime.cleanupSessionResources(state.runtime.agent.sessionId);
984
+ }
985
+ recovery.cancelRetryCountdown();
986
+ queues.reset();
987
+ middleware.clearPendingReminders();
988
+ middlewareToolChoice.reset();
989
+ state.lastTurnId = leafTurnId;
990
+ context.resetForSession();
991
+ state.replayedContextMessages = replayMessages ? [...replayMessages] : [];
992
+ if (state.runtime) {
993
+ state.runtime.agent.state.messages = [...state.replayedContextMessages];
994
+ }
995
+ if (deps.protectedArtifacts) {
996
+ reloadProtectedArtifactsForSession(deps.protectedArtifacts, deps.readSessionEntries);
997
+ }
998
+ },
999
+
1000
+ dispose(): void {
1001
+ unsubscribeConfigReload?.();
1002
+ unsubscribeSynthesisLock?.();
1003
+ context.dispose();
1004
+ if (state.runtime) {
1005
+ state.runtime.agent.abort();
1006
+ (state.runtime.agent as { clearAllQueues?: () => void } | undefined)?.clearAllQueues?.();
1007
+ turnRuntime.cleanupSessionResources(state.runtime.agent.sessionId);
1008
+ }
1009
+ recovery.cancelRetryCountdown();
1010
+ queues.reset();
1011
+ middlewareToolChoice.reset();
1012
+ },
1013
+
1014
+ async compact(instructions?: string): Promise<void> {
1015
+ // Session check runs BEFORE orchestrator-configuration so a fresh
1016
+ // TUI with nothing configured still reports the actionable "no
1017
+ // current session" message rather than the "not configured"
1018
+ // banner.
1019
+ if (!deps.session?.current()) {
1020
+ emitNotice("[/context compact] no current session to compact; start one with /new or /resume first");
1021
+ return;
1022
+ }
1023
+ let agentRuntime: AgentRuntime | null;
1024
+ try {
1025
+ await turnRuntime.ensureLiveCapabilitiesForSelectedModel();
1026
+ agentRuntime = turnRuntime.ensureRuntime();
1027
+ } catch (err) {
1028
+ emitNotice(`[/context compact] ${err instanceof Error ? err.message : String(err)}`);
1029
+ return;
1030
+ }
1031
+ if (!agentRuntime) {
1032
+ emitNotice(`[/context compact] ${notConfiguredNotice()}`);
1033
+ return;
1034
+ }
1035
+ let compacted = false;
1036
+ try {
1037
+ compacted = await context.runAutoCompact(agentRuntime, true, instructions, "force");
1038
+ } catch (err) {
1039
+ emitNotice(`[/context compact] ${err instanceof Error ? err.message : String(err)}`);
1040
+ return;
1041
+ }
1042
+ if (!compacted) {
1043
+ emitNotice("[/context compact] nothing to compact; session is empty or no cut crossed");
1044
+ }
1045
+ },
1046
+ };
1047
+
1048
+ const submitInner = api.submit.bind(api);
1049
+ const submitTracked: ChatLoop["submit"] = (text, options) => {
1050
+ priorSubmit = activeSubmit;
1051
+ const run = submitInner(text, options);
1052
+ activeSubmit = run.catch(() => {});
1053
+ return run;
1054
+ };
1055
+
1056
+ // FIFO admission gate. Between entry and `state.streaming = true` a fresh
1057
+ // submit awaits the target probe, auto-compaction, and the session prompt
1058
+ // compile; a second submit arriving in that window used to run the same
1059
+ // pipeline concurrently, skip the probe the first one was still awaiting,
1060
+ // append its user turn first, and leave the first to fail on the engine's
1061
+ // active-prompt invariant after its turn was already in the ledger. Each
1062
+ // submit now waits for the previous one to either own the stream or return,
1063
+ // then re-evaluates `state.streaming`, so a prompt typed during boot lands
1064
+ // as the next steer or follow-up in the order it was typed. The gate is
1065
+ // released at admission, not settlement, so steering stays immediate.
1066
+ let admissionTail: Promise<void> | null = null;
1067
+ api.submit = (text, options = {}) => {
1068
+ const previous = admissionTail;
1069
+ let release: () => void = () => {};
1070
+ const ticket = new Promise<void>((resolve) => {
1071
+ release = resolve;
1072
+ });
1073
+ admissionTail = ticket;
1074
+ const releaseTicket = (): void => {
1075
+ release();
1076
+ if (admissionTail === ticket) admissionTail = null;
1077
+ };
1078
+ const start = (): Promise<void> =>
1079
+ submitTracked(text, {
1080
+ ...options,
1081
+ onAdmitted: () => {
1082
+ releaseTicket();
1083
+ options.onAdmitted?.();
1084
+ },
1085
+ }).finally(releaseTicket);
1086
+ return previous ? previous.then(start) : start();
1087
+ };
1088
+
1089
+ return api;
1090
+ }