@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,1228 @@
1
+ /**
2
+ * Coalescing wrapper around chat events (slice 12.5d).
3
+ *
4
+ * Streaming responses fire text, thinking, and cumulative tool-result updates
5
+ * at very high frequency. The TUI's per-event `requestRender()` call rebuilt the
6
+ * entire transcript on every delta, which scaled linearly with response
7
+ * length and made long answers visibly lag. This wrapper applies events to
8
+ * the panel synchronously (so internal state stays consistent) but defers
9
+ * `requestRender()` for delta events to a single coalesced timer (~16ms =
10
+ * one frame at 60fps). Non-delta events render synchronously so finalizers
11
+ * like `message_end` are never deferred. The one exception is the raw
12
+ * text/thinking wrapper, which is dropped before the panel entirely; see
13
+ * `isTransparentAssistantWrapper`.
14
+ */
15
+
16
+ import type {
17
+ BashExecutionEntry,
18
+ BranchSummaryEntry,
19
+ CompactionSummaryEntry,
20
+ CustomEntry,
21
+ FileEntryEntry,
22
+ MessageEntry,
23
+ ModelChangeEntry,
24
+ ProtectedArtifactEntry,
25
+ SessionEntry,
26
+ SessionInfoEntry,
27
+ ThinkingLevelChangeEntry,
28
+ WorkerRunEntry,
29
+ } from "../domains/session/entries.js";
30
+ import { filterEntriesToActivePath } from "../domains/session/tree/active-path.js";
31
+ import {
32
+ type BashExecutionMessage,
33
+ BRANCH_SUMMARY_PREFIX,
34
+ BRANCH_SUMMARY_SUFFIX,
35
+ bashExecutionToText,
36
+ COMPACTION_SUMMARY_PREFIX,
37
+ COMPACTION_SUMMARY_SUFFIX,
38
+ } from "../engine/messages.js";
39
+ import { wrapTextWithAnsi } from "../engine/tui.js";
40
+ import type { AgentMessage } from "../engine/types.js";
41
+ import type { ChatLoopEvent, RetryStatusPayload } from "./chat-loop.js";
42
+ import { isSelfExplainingAbort } from "./chat-loop-messages.js";
43
+ import type { ChatPanel } from "./chat-panel.js";
44
+ import { renderBranchSummaryEntry } from "./renderers/branch-summary.js";
45
+ import { renderCompactionSummaryEntry } from "./renderers/compaction-summary.js";
46
+ import { styleTaggedNotice } from "./renderers/notice.js";
47
+ import { formatRetryStatus } from "./renderers/retry-status.js";
48
+ import { renderBashTranscriptExecution, renderToolResultOnly } from "./renderers/tool-execution.js";
49
+ import {
50
+ classifyStreamEvent,
51
+ createStreamPacer,
52
+ type SmoothStreamingMode,
53
+ type StreamPacer,
54
+ type StreamPacerSlice,
55
+ } from "./stream-pacer.js";
56
+ import { readWorkerReceiptFactsForReplay } from "./worker-receipts.js";
57
+ import { workerEntriesFromRunEntries } from "./worker-replay.js";
58
+ import type { WorkerReceiptReader } from "./worker-stream.js";
59
+
60
+ const DEFAULT_COALESCE_MS = 16;
61
+ const MAX_REPLAY_TEXT_CHARS = 20_000;
62
+
63
+ /**
64
+ * Event kinds whose render is deferred into a coalesce window. All other
65
+ * `ChatLoopEvent` kinds render synchronously and cancel any pending timer.
66
+ */
67
+ const DELTA_TYPES: ReadonlySet<ChatLoopEvent["type"]> = new Set([
68
+ "text_delta",
69
+ "thinking_delta",
70
+ "tool_execution_update",
71
+ ]);
72
+
73
+ /**
74
+ * A raw `message_update` wrapper whose inner event is a text or thinking
75
+ * delta is transparent to the transcript: the panel ignores it, and the
76
+ * derived `text_delta`/`thinking_delta` emitted in the same stack (see
77
+ * turn-runtime's public-event fan-out) is the canonical display input. Yet
78
+ * this renderer classified the wrapper as non-delta, so every provider chunk
79
+ * cancelled the pending coalesce window and requested an immediate render.
80
+ * The coalescer was defeated exactly while streaming, which is the one time
81
+ * it matters. Wrappers carrying tool-call formation stay on the synchronous
82
+ * path, because the panel consumes those directly.
83
+ */
84
+ function isTransparentAssistantWrapper(event: ChatLoopEvent): boolean {
85
+ if (event.type !== "message_update") return false;
86
+ const inner = (event as { assistantMessageEvent?: { type?: unknown } }).assistantMessageEvent;
87
+ return inner?.type === "text_delta" || inner?.type === "thinking_delta";
88
+ }
89
+
90
+ export interface CreateCoalescingChatRendererDeps {
91
+ chatPanel: ChatPanel;
92
+ requestRender: () => void;
93
+ /** Coalesce window in ms. Defaults to 16 (one frame at 60fps). */
94
+ coalesceMs?: number;
95
+ /** Override for tests. Mirrors the setTimeout signature. */
96
+ setTimer?: (cb: () => void, ms: number) => unknown;
97
+ /** Override for tests. Mirrors the clearTimeout signature. */
98
+ clearTimer?: (id: unknown) => void;
99
+ /** Monotonic clock shared with the pacer; injectable for deterministic tests. */
100
+ now?: () => number;
101
+ /** Sequence captured at canonical projection ingress before this panel consumer runs. */
102
+ visibleEventSequence?: (event: ChatLoopEvent) => number | null;
103
+ onQueue?: (eventSeq: number, action: "admit" | "dequeue") => void;
104
+ onPanelApplied?: (eventSeq: number) => void;
105
+ /** Legacy aggregate callback retained for non-text cumulative tool-update observations. */
106
+ onDelta?: () => void;
107
+ /** Canonical presentation-ingress identity; absent keeps the exact legacy coalescer. */
108
+ streamIngress?: (event: ChatLoopEvent) => { sequence: number; generation: string | number; ingressAt: number } | null;
109
+ getSmoothStreamingMode?: () => SmoothStreamingMode;
110
+ isAutoPacingAllowed?: () => boolean;
111
+ /** Force and await one actual frame plus any stdout drain. */
112
+ commitFrame?: (reason?: string) => Promise<unknown>;
113
+ }
114
+
115
+ export interface CoalescingChatRenderer {
116
+ applyEvent(event: ChatLoopEvent): void;
117
+ /** Cancel the pending coalesce timer (if any) and request one synchronous render. */
118
+ flush(): void;
119
+ /** Ordered barrier for replay, worker, command-output, and other panel mutations. */
120
+ mutate(mutation: () => void, reason?: string): void;
121
+ /** Drop queued presentation content before replacing/resetting the transcript. */
122
+ reset(mutation: () => void): void;
123
+ /** Drain paced content and await the first committed frame containing it. */
124
+ flushAndCommit(reason?: string): Promise<void>;
125
+ /** Apply a live mode change as an immediate ordered drain boundary. */
126
+ setSmoothStreamingMode(mode: SmoothStreamingMode): void;
127
+ dispose(): void;
128
+ }
129
+
130
+ export function createCoalescingChatRenderer(deps: CreateCoalescingChatRendererDeps): CoalescingChatRenderer {
131
+ const setTimer = deps.setTimer ?? ((cb, ms) => setTimeout(cb, ms));
132
+ const clearTimer =
133
+ deps.clearTimer ??
134
+ ((id) => {
135
+ clearTimeout(id as ReturnType<typeof setTimeout>);
136
+ });
137
+ const coalesceMs = deps.coalesceMs ?? DEFAULT_COALESCE_MS;
138
+
139
+ let pendingTimer: unknown = null;
140
+ let mutationDepth = 0;
141
+ let transactionNeedsRender = false;
142
+ let disposed = false;
143
+ let pacer: StreamPacer | null = null;
144
+
145
+ const fireCoalesced = (): void => {
146
+ if (disposed) return;
147
+ pendingTimer = null;
148
+ deps.requestRender();
149
+ };
150
+
151
+ const cancelPending = (): boolean => {
152
+ if (pendingTimer === null) return false;
153
+ clearTimer(pendingTimer);
154
+ pendingTimer = null;
155
+ return true;
156
+ };
157
+
158
+ const requestTransactionalRender = (coalesce: boolean): void => {
159
+ if (mutationDepth > 0) {
160
+ transactionNeedsRender = true;
161
+ return;
162
+ }
163
+ if (!coalesce) {
164
+ cancelPending();
165
+ deps.requestRender();
166
+ return;
167
+ }
168
+ deps.onDelta?.();
169
+ if (pendingTimer === null) pendingTimer = setTimer(fireCoalesced, coalesceMs);
170
+ };
171
+ const transaction = (operation: () => void, coalesce = false): void => {
172
+ mutationDepth += 1;
173
+ try {
174
+ operation();
175
+ } finally {
176
+ mutationDepth -= 1;
177
+ if (mutationDepth === 0 && transactionNeedsRender) {
178
+ transactionNeedsRender = false;
179
+ requestTransactionalRender(coalesce);
180
+ }
181
+ }
182
+ };
183
+ const applySlice = (slice: StreamPacerSlice): void => {
184
+ const event =
185
+ slice.kind === "text"
186
+ ? ({ type: "text_delta", contentIndex: slice.contentIndex, delta: slice.text, partialText: "" } as const)
187
+ : ({ type: "thinking_delta", contentIndex: slice.contentIndex, delta: slice.text, partialThinking: "" } as const);
188
+ deps.chatPanel.applyEvent(event);
189
+ if (slice.finalForItem) {
190
+ deps.onPanelApplied?.(slice.sequence);
191
+ deps.onQueue?.(slice.sequence, "dequeue");
192
+ }
193
+ requestTransactionalRender(true);
194
+ };
195
+ if (deps.streamIngress && deps.getSmoothStreamingMode) {
196
+ pacer = createStreamPacer({
197
+ mode: deps.getSmoothStreamingMode(),
198
+ onSlice: applySlice,
199
+ onDiscard: (sequence) => deps.onQueue?.(sequence, "dequeue"),
200
+ ...(deps.now ? { now: deps.now } : {}),
201
+ ...(deps.setTimer ? { setTimer: deps.setTimer } : {}),
202
+ ...(deps.clearTimer ? { clearTimer: deps.clearTimer } : {}),
203
+ ...(deps.isAutoPacingAllowed ? { isAutoPacingAllowed: deps.isAutoPacingAllowed } : {}),
204
+ });
205
+ }
206
+ const syncPacerMode = (): SmoothStreamingMode => {
207
+ const mode = deps.getSmoothStreamingMode?.() ?? "off";
208
+ if (pacer && pacer.mode !== mode) transaction(() => pacer?.setMode(mode));
209
+ return mode;
210
+ };
211
+ const drainPacer = (reason: string): void => {
212
+ if (pacer?.snapshot().queuedItems) pacer.flush(reason);
213
+ };
214
+ const applyLegacy = (event: ChatLoopEvent): void => {
215
+ const visibleEventSeq = deps.visibleEventSequence?.(event) ?? null;
216
+ if (visibleEventSeq !== null) deps.onQueue?.(visibleEventSeq, "admit");
217
+ deps.chatPanel.applyEvent(event);
218
+ if (visibleEventSeq !== null) {
219
+ deps.onPanelApplied?.(visibleEventSeq);
220
+ deps.onQueue?.(visibleEventSeq, "dequeue");
221
+ }
222
+ if (DELTA_TYPES.has(event.type)) {
223
+ requestTransactionalRender(true);
224
+ return;
225
+ }
226
+ requestTransactionalRender(false);
227
+ };
228
+
229
+ const renderer: CoalescingChatRenderer = {
230
+ applyEvent(event) {
231
+ if (disposed) return;
232
+ if (isTransparentAssistantWrapper(event)) return;
233
+ const mode = syncPacerMode();
234
+ const ingress = deps.streamIngress?.(event) ?? null;
235
+ if (!pacer || mode === "off") {
236
+ applyLegacy(event);
237
+ return;
238
+ }
239
+ const classification = classifyStreamEvent(event);
240
+ if (classification === "paced-display-content") {
241
+ if (ingress === null) {
242
+ applyLegacy(event);
243
+ return;
244
+ }
245
+ const delta = event as Extract<ChatLoopEvent, { type: "text_delta" | "thinking_delta" }>;
246
+ if (delta.delta.length === 0) {
247
+ applyLegacy(event);
248
+ return;
249
+ }
250
+ deps.onQueue?.(ingress.sequence, "admit");
251
+ transaction(() => {
252
+ pacer?.enqueue({
253
+ sequence: ingress.sequence,
254
+ generation: ingress.generation,
255
+ kind: delta.type === "text_delta" ? "text" : "thinking",
256
+ contentIndex: delta.contentIndex,
257
+ text: delta.delta,
258
+ ingressAt: ingress.ingressAt,
259
+ folded: delta.type === "thinking_delta" && !deps.chatPanel.isThinkingExpanded(),
260
+ });
261
+ }, true);
262
+ return;
263
+ }
264
+ if (classification === "cumulative-live-state") {
265
+ transaction(() => {
266
+ drainPacer("cumulative-live-state");
267
+ applyLegacy(event);
268
+ }, true);
269
+ return;
270
+ }
271
+ transaction(() => {
272
+ drainPacer(`boundary:${event.type}`);
273
+ applyLegacy(event);
274
+ });
275
+ },
276
+ flush() {
277
+ if (disposed) return;
278
+ transaction(() => drainPacer("explicit-flush"));
279
+ const wasPending = cancelPending();
280
+ if (wasPending) deps.requestRender();
281
+ },
282
+ mutate(mutation, reason = "panel-mutation") {
283
+ if (disposed) return;
284
+ transaction(() => {
285
+ drainPacer(reason);
286
+ mutation();
287
+ requestTransactionalRender(false);
288
+ });
289
+ },
290
+ reset(mutation) {
291
+ if (disposed) return;
292
+ transaction(() => {
293
+ pacer?.invalidateEpoch();
294
+ mutation();
295
+ requestTransactionalRender(false);
296
+ });
297
+ },
298
+ async flushAndCommit(reason = "final-frame") {
299
+ if (disposed) return;
300
+ transaction(() => drainPacer(reason));
301
+ cancelPending();
302
+ if (deps.commitFrame) await deps.commitFrame(reason);
303
+ else deps.requestRender();
304
+ },
305
+ setSmoothStreamingMode(mode) {
306
+ if (disposed || !pacer || pacer.mode === mode) return;
307
+ transaction(() => pacer?.setMode(mode));
308
+ },
309
+ dispose() {
310
+ if (disposed) return;
311
+ transaction(() => pacer?.dispose("renderer-dispose"));
312
+ cancelPending();
313
+ disposed = true;
314
+ },
315
+ };
316
+ return renderer;
317
+ }
318
+
319
+ /**
320
+ * Options for the rehydrate helper used by /resume and /fork.
321
+ */
322
+ export interface RehydrateChatPanelOptions {
323
+ /**
324
+ * Select the active branch ancestry without truncating later sidecars.
325
+ * Live compaction replay uses this so a summary appended after the current
326
+ * message leaf remains visible. Unset offline readers retain their
327
+ * file-order fallback.
328
+ */
329
+ activeLeafTurnId?: string;
330
+ /**
331
+ * Pin the active-branch leaf and stop replay after that turn (inclusive).
332
+ * /tree switches and /fork pass the selected turn id so replay follows
333
+ * that turn's ancestry. Unset (default) treats the most recently appended
334
+ * message turn as the leaf.
335
+ */
336
+ uptoTurnId?: string;
337
+ /**
338
+ * Render orphan tool results (results with no matching prior call) in full,
339
+ * without the live view's middle-elision. `/export` sets this so its
340
+ * throwaway panel writes complete tool bodies; the paired-result path reads
341
+ * the same intent from the panel's `unboundedToolBodies` option.
342
+ */
343
+ unboundedToolBodies?: boolean;
344
+ /**
345
+ * Sealed-receipt reader for the worker blocks a `workerRun` entry names.
346
+ * Defaults to `<state>/receipts/<runId>.json`; tests inject their own. This
347
+ * is the one place replay reads outside the entry stream, and it swallows
348
+ * every failure, so a session whose receipts are gone still replays.
349
+ */
350
+ readWorkerReceipt?: WorkerReceiptReader;
351
+ }
352
+
353
+ function extractTurnText(payload: unknown): string {
354
+ if (typeof payload === "string") return payload;
355
+ if (!payload || typeof payload !== "object") return "";
356
+ const p = payload as Record<string, unknown>;
357
+ if (typeof p.text === "string") return p.text;
358
+ if (Array.isArray(p.content)) {
359
+ for (const block of p.content) {
360
+ if (!block || typeof block !== "object") continue;
361
+ const b = block as Record<string, unknown>;
362
+ if (b.type === "text" && typeof b.text === "string") return b.text;
363
+ }
364
+ }
365
+ return "";
366
+ }
367
+
368
+ function stringifyPreview(value: unknown, limit = 600): string {
369
+ if (value === undefined) return "";
370
+ if (typeof value === "string") return value.length <= limit ? value : `${value.slice(0, limit - 3)}...`;
371
+ try {
372
+ const text = JSON.stringify(value);
373
+ if (!text) return "";
374
+ return text.length <= limit ? text : `${text.slice(0, limit - 3)}...`;
375
+ } catch {
376
+ const text = String(value);
377
+ return text.length <= limit ? text : `${text.slice(0, limit - 3)}...`;
378
+ }
379
+ }
380
+
381
+ function truncateReplayText(text: string, limit = MAX_REPLAY_TEXT_CHARS): string {
382
+ if (text.length <= limit) return text;
383
+ const omitted = text.length - limit;
384
+ return `${text.slice(0, limit)}\n\n[... ${omitted} more characters truncated from replay context]`;
385
+ }
386
+
387
+ function timestampMillis(timestamp: string): number {
388
+ const parsed = Date.parse(timestamp);
389
+ return Number.isNaN(parsed) ? 0 : parsed;
390
+ }
391
+
392
+ function makeTextMessage(role: "user" | "assistant", text: string, timestamp: string): AgentMessage {
393
+ const message: Record<string, unknown> = {
394
+ role,
395
+ content: [{ type: "text", text }],
396
+ timestamp: timestampMillis(timestamp),
397
+ };
398
+ if (role === "assistant") message.stopReason = "stop";
399
+ return message as unknown as AgentMessage;
400
+ }
401
+
402
+ function cloneContentBlocks(content: unknown, maxTextChars?: number): unknown[] | null {
403
+ if (!Array.isArray(content)) return null;
404
+ return content
405
+ .filter((block) => !!block && typeof block === "object")
406
+ .map((block) => {
407
+ const cloned: Record<string, unknown> = { ...(block as Record<string, unknown>) };
408
+ if (typeof maxTextChars === "number") {
409
+ if (typeof cloned.text === "string") cloned.text = truncateReplayText(cloned.text, maxTextChars);
410
+ if (typeof cloned.thinking === "string") cloned.thinking = truncateReplayText(cloned.thinking, maxTextChars);
411
+ }
412
+ return cloned;
413
+ });
414
+ }
415
+
416
+ function richMessageFromEntry(entry: MessageEntry, maxTextChars?: number): AgentMessage | null {
417
+ if (entry.role !== "user" && entry.role !== "assistant") return null;
418
+ const obj = payloadObject(entry.payload);
419
+ const content = cloneContentBlocks(obj?.content, maxTextChars);
420
+ const text = truncateReplayText(extractTurnText(entry.payload), maxTextChars);
421
+ const stopReason = typeof obj?.stopReason === "string" ? obj.stopReason : undefined;
422
+ if (!content && text.length === 0 && !messageFailure(entry) && stopReason !== "length") return null;
423
+ const message: Record<string, unknown> = {
424
+ role: entry.role,
425
+ content: content ?? [{ type: "text", text }],
426
+ timestamp: timestampMillis(entry.timestamp),
427
+ };
428
+ if (entry.role === "assistant") {
429
+ const failure = messageFailure(entry);
430
+ message.stopReason = failure?.stopReason ?? stopReason ?? "stop";
431
+ if (failure) message.errorMessage = failure.errorMessage;
432
+ for (const key of [
433
+ "usage",
434
+ "api",
435
+ "provider",
436
+ "model",
437
+ "responseModel",
438
+ "responseId",
439
+ "diagnostics",
440
+ "contextUsageInvalidated",
441
+ ]) {
442
+ if (obj?.[key] !== undefined) message[key] = obj[key];
443
+ }
444
+ }
445
+ return message as unknown as AgentMessage;
446
+ }
447
+
448
+ function recordToolCallsFromMessage(message: AgentMessage, seen: Set<string>): void {
449
+ const content = (message as { content?: unknown }).content;
450
+ if (!Array.isArray(content)) return;
451
+ for (const block of content) {
452
+ if (!block || typeof block !== "object") continue;
453
+ const b = block as Record<string, unknown>;
454
+ if (b.type !== "toolCall") continue;
455
+ if (typeof b.id === "string" && b.id.length > 0) seen.add(b.id);
456
+ }
457
+ }
458
+
459
+ function toolCallMessageFromEntry(entry: MessageEntry): AgentMessage {
460
+ const call = extractToolCall(entry);
461
+ const block: Record<string, unknown> = { type: "toolCall", id: call.id, name: call.name };
462
+ if (call.args !== undefined) block.arguments = call.args;
463
+ return {
464
+ role: "assistant",
465
+ content: [block],
466
+ stopReason: "toolUse",
467
+ timestamp: timestampMillis(entry.timestamp),
468
+ } as unknown as AgentMessage;
469
+ }
470
+
471
+ function toolResultContent(result: unknown): unknown[] {
472
+ const obj = payloadObject(result);
473
+ if (Array.isArray(obj?.content)) {
474
+ return cloneContentBlocks(obj.content, MAX_REPLAY_TEXT_CHARS) ?? [];
475
+ }
476
+ if (isTextResult(result)) return [{ type: "text", text: truncateReplayText(result.text) }];
477
+ if (typeof result === "string") return [{ type: "text", text: truncateReplayText(result) }];
478
+ return [{ type: "text", text: stringifyPreview(result, 10_000) }];
479
+ }
480
+
481
+ function displayReplayToolResult(result: unknown): unknown {
482
+ const content = toolResultContent(result);
483
+ // Preserve the details record (observation envelope, exec records) so the
484
+ // replayed ledger line carries the same outcome facts as the live one.
485
+ const details = payloadObject(result)?.details;
486
+ return details !== null && details !== undefined && typeof details === "object" ? { content, details } : content;
487
+ }
488
+
489
+ function textFromContentBlocks(content: unknown): string {
490
+ if (!Array.isArray(content)) return "";
491
+ const parts: string[] = [];
492
+ for (const block of content) {
493
+ if (!block || typeof block !== "object") continue;
494
+ const b = block as Record<string, unknown>;
495
+ if (b.type === "text" && typeof b.text === "string") parts.push(b.text);
496
+ }
497
+ return parts.join("");
498
+ }
499
+
500
+ function toolResultText(result: unknown): string {
501
+ const obj = payloadObject(result);
502
+ const contentText = textFromContentBlocks(obj?.content);
503
+ if (contentText.length > 0) return contentText;
504
+ if (isTextResult(result)) return result.text;
505
+ if (typeof result === "string") return result;
506
+ return stringifyPreview(result, 10_000);
507
+ }
508
+
509
+ function comparableReplayText(text: string): string {
510
+ return text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").trim();
511
+ }
512
+
513
+ function messagePayloadComparableText(payload: unknown): string {
514
+ const text = extractTurnText(payload);
515
+ if (text.length > 0) return text;
516
+ return textFromContentBlocks(payloadObject(payload)?.content);
517
+ }
518
+
519
+ function isLegacyToolResultAssistantDuplicate(toolResult: MessageEntry, assistant: MessageEntry): boolean {
520
+ const priorText = comparableReplayText(toolResultText(extractToolResult(toolResult).result));
521
+ if (priorText.length === 0) return false;
522
+ const assistantText = comparableReplayText(messagePayloadComparableText(assistant.payload));
523
+ return assistantText.length > 0 && assistantText === priorText;
524
+ }
525
+
526
+ function isTextResult(value: unknown): value is { text: string } {
527
+ return payloadObject(value)?.text !== undefined && typeof (value as { text?: unknown }).text === "string";
528
+ }
529
+
530
+ function toolResultMessageFromEntry(entry: MessageEntry): AgentMessage {
531
+ const result = extractToolResult(entry);
532
+ return {
533
+ role: "toolResult",
534
+ content: toolResultContent(result.result),
535
+ toolCallId: result.id ?? entry.turnId,
536
+ toolName: result.name,
537
+ isError: result.isError,
538
+ timestamp: timestampMillis(entry.timestamp),
539
+ } as AgentMessage;
540
+ }
541
+
542
+ function textBlockFromEntry(entry: MessageEntry): string {
543
+ const text = extractTurnText(entry.payload);
544
+ if (text.length > 0) return text;
545
+ return stringifyPreview(entry.payload);
546
+ }
547
+
548
+ function chatMessageText(entry: MessageEntry): string {
549
+ return extractTurnText(entry.payload);
550
+ }
551
+
552
+ const LEADING_SYSTEM_REMINDER = /^\s*<system-reminder>[\s\S]*?<\/system-reminder>\s*/u;
553
+
554
+ /**
555
+ * What the operator typed for a replayed user turn. The persisted text is the
556
+ * composed prompt (a system-reminder block and any skill preamble ride ahead of
557
+ * the operator's words, as visible text the model receives), and the live
558
+ * transcript only ever showed the typed part. Entries written since the
559
+ * operator text was persisted carry it directly; older entries drop the
560
+ * leading reminder scaffolding so a /fork or /resume redraw does not attribute
561
+ * it to the operator (#81).
562
+ */
563
+ function replayedUserText(entry: MessageEntry): string {
564
+ const obj = payloadObject(entry.payload);
565
+ if (typeof obj?.operatorText === "string") return obj.operatorText;
566
+ let text = extractTurnText(entry.payload);
567
+ for (;;) {
568
+ const stripped = text.replace(LEADING_SYSTEM_REMINDER, "");
569
+ if (stripped === text) return text;
570
+ text = stripped;
571
+ }
572
+ }
573
+
574
+ function messageFailure(entry: MessageEntry): { stopReason: "error" | "aborted"; errorMessage: string } | null {
575
+ const obj = payloadObject(entry.payload);
576
+ if (!obj) return null;
577
+ const stopReason = obj?.stopReason;
578
+ if (stopReason !== "error" && stopReason !== "aborted") return null;
579
+ const raw = obj.errorMessage;
580
+ if (isSelfExplainingAbort({ stopReason, errorMessage: raw, text: extractTurnText(entry.payload) })) return null;
581
+ const errorMessage =
582
+ typeof raw === "string" && raw.length > 0
583
+ ? raw
584
+ : stopReason === "aborted"
585
+ ? "request aborted"
586
+ : "model target returned an error";
587
+ return { stopReason, errorMessage };
588
+ }
589
+
590
+ function payloadObject(payload: unknown): Record<string, unknown> | null {
591
+ return payload && typeof payload === "object" && !Array.isArray(payload) ? (payload as Record<string, unknown>) : null;
592
+ }
593
+
594
+ function parseMaybeJson(value: unknown): unknown {
595
+ if (typeof value !== "string") return value;
596
+ const trimmed = value.trim();
597
+ if (!trimmed) return value;
598
+ try {
599
+ return JSON.parse(trimmed) as unknown;
600
+ } catch {
601
+ return value;
602
+ }
603
+ }
604
+
605
+ function firstContentBlock(payload: unknown, type: string): Record<string, unknown> | null {
606
+ const obj = payloadObject(payload);
607
+ const content = obj?.content;
608
+ if (!Array.isArray(content)) return null;
609
+ for (const block of content) {
610
+ if (!block || typeof block !== "object") continue;
611
+ const b = block as Record<string, unknown>;
612
+ if (b.type === type) return b;
613
+ }
614
+ return null;
615
+ }
616
+
617
+ interface ReplayToolCall {
618
+ id: string;
619
+ name: string;
620
+ args: unknown;
621
+ }
622
+
623
+ function extractToolCall(entry: MessageEntry): ReplayToolCall {
624
+ const payload = entry.payload;
625
+ const obj = payloadObject(payload);
626
+ const block = firstContentBlock(payload, "toolCall");
627
+ const fn = payloadObject(obj?.function);
628
+ const id =
629
+ (typeof obj?.id === "string" && obj.id) ||
630
+ (typeof obj?.toolCallId === "string" && obj.toolCallId) ||
631
+ (typeof obj?.tool_call_id === "string" && obj.tool_call_id) ||
632
+ (typeof block?.id === "string" && block.id) ||
633
+ entry.turnId;
634
+ const name =
635
+ (typeof obj?.name === "string" && obj.name) ||
636
+ (typeof obj?.toolName === "string" && obj.toolName) ||
637
+ (typeof obj?.tool === "string" && obj.tool) ||
638
+ (typeof fn?.name === "string" && fn.name) ||
639
+ (typeof block?.name === "string" && block.name) ||
640
+ "tool";
641
+ const args =
642
+ obj?.arguments ??
643
+ obj?.args ??
644
+ obj?.input ??
645
+ parseMaybeJson(fn?.arguments) ??
646
+ block?.arguments ??
647
+ block?.args ??
648
+ undefined;
649
+ return { id, name, args };
650
+ }
651
+
652
+ interface ReplayToolResult {
653
+ id: string | null;
654
+ name: string;
655
+ result: unknown;
656
+ isError: boolean;
657
+ durationMs?: number;
658
+ resultSummary?: Record<string, unknown>;
659
+ /** Persisted admission verdict; absent on history written before it was recorded. */
660
+ outcome?: string;
661
+ blockReason?: string;
662
+ }
663
+
664
+ function extractToolResult(entry: MessageEntry): ReplayToolResult {
665
+ const payload = entry.payload;
666
+ const obj = payloadObject(payload);
667
+ const contentText = extractTurnText(payload);
668
+ const id =
669
+ (typeof obj?.toolCallId === "string" && obj.toolCallId) ||
670
+ (typeof obj?.tool_call_id === "string" && obj.tool_call_id) ||
671
+ (typeof obj?.id === "string" && obj.id) ||
672
+ null;
673
+ const name =
674
+ (typeof obj?.toolName === "string" && obj.toolName) ||
675
+ (typeof obj?.name === "string" && obj.name) ||
676
+ (typeof obj?.tool === "string" && obj.tool) ||
677
+ "tool";
678
+ const result =
679
+ obj?.result ?? obj?.output ?? obj?.out ?? obj?.content ?? (contentText.length > 0 ? contentText : payload);
680
+ const durationMs = typeof obj?.durationMs === "number" && Number.isFinite(obj.durationMs) ? obj.durationMs : undefined;
681
+ const resultSummary = payloadObject(obj?.resultSummary) ?? undefined;
682
+ const outcome = typeof obj?.outcome === "string" && obj.outcome.length > 0 ? obj.outcome : undefined;
683
+ const blockReason = typeof obj?.blockReason === "string" && obj.blockReason.length > 0 ? obj.blockReason : undefined;
684
+ return {
685
+ id,
686
+ name,
687
+ result,
688
+ isError: obj?.isError === true || obj?.error === true,
689
+ ...(durationMs !== undefined ? { durationMs } : {}),
690
+ ...(resultSummary !== undefined ? { resultSummary } : {}),
691
+ ...(outcome !== undefined ? { outcome } : {}),
692
+ ...(blockReason !== undefined ? { blockReason } : {}),
693
+ };
694
+ }
695
+
696
+ function renderReplayLine(text: string, width: number): string[] {
697
+ // Style a leading bracketed tag (`[skill]`, `[checkpoint]`, ...) dim with a
698
+ // muted body; free-form lines such as `system:` prefixes pass through
699
+ // unchanged so only bracketed notices pick up the treatment.
700
+ return wrapTextWithAnsi(styleTaggedNotice(text), width);
701
+ }
702
+
703
+ function appendReplayLine(chatPanel: ChatPanel, text: string): void {
704
+ chatPanel.appendReplayBlock((width) => renderReplayLine(truncateReplayText(text), width));
705
+ }
706
+
707
+ function renderBashExecutionEntry(entry: BashExecutionEntry, width: number): string[] {
708
+ return renderBashTranscriptExecution(
709
+ {
710
+ command: entry.command,
711
+ output: truncateReplayText(entry.output.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\s+$/g, "")),
712
+ running: false,
713
+ exitCode: entry.exitCode,
714
+ cancelled: entry.cancelled,
715
+ truncated: entry.truncated,
716
+ fullOutputPath: entry.fullOutputPath,
717
+ excludeFromContext: entry.excludeFromContext,
718
+ },
719
+ width,
720
+ );
721
+ }
722
+
723
+ function renderRetryStatusEntry(entry: CustomEntry, width: number): string[] {
724
+ const data = payloadObject(entry.data);
725
+ if (!data) return wrapTextWithAnsi(styleTaggedNotice("[retry] status"), width);
726
+ const rawPhase = data.phase;
727
+ if (
728
+ rawPhase !== "scheduled" &&
729
+ rawPhase !== "waiting" &&
730
+ rawPhase !== "retrying" &&
731
+ rawPhase !== "cancelled" &&
732
+ rawPhase !== "exhausted" &&
733
+ rawPhase !== "recovered"
734
+ ) {
735
+ return wrapTextWithAnsi(styleTaggedNotice("[retry] status"), width);
736
+ }
737
+ const attempt = typeof data.attempt === "number" ? data.attempt : null;
738
+ const maxAttempts = typeof data.maxAttempts === "number" ? data.maxAttempts : null;
739
+ if (attempt === null || maxAttempts === null) return wrapTextWithAnsi(styleTaggedNotice("[retry] status"), width);
740
+ const status: RetryStatusPayload = {
741
+ phase: rawPhase,
742
+ attempt,
743
+ maxAttempts,
744
+ ...(typeof data.errorMessage === "string" && data.errorMessage.length > 0 ? { errorMessage: data.errorMessage } : {}),
745
+ ...(typeof data.delayMs === "number" ? { delayMs: data.delayMs } : {}),
746
+ ...(typeof data.seconds === "number" ? { seconds: data.seconds } : {}),
747
+ };
748
+ return wrapTextWithAnsi(formatRetryStatus(status), width);
749
+ }
750
+
751
+ /**
752
+ * Custom entries the replay renders. A custom entry is an extension point: some
753
+ * carry operator-facing text, and the rest are diagnostics the live transcript
754
+ * never shows. `promptRecompiled` is the latter, and replay dumped it as the
755
+ * literal type name plus a JSON blob of hashes in the middle of a resumed
756
+ * conversation, so a fork or resume showed a line the session itself never did.
757
+ * Rendering is opt-in: a known type, or `display: true` from a writer that means
758
+ * the entry to be seen.
759
+ */
760
+ function rendersCustomEntry(entry: CustomEntry): boolean {
761
+ if (entry.display === false) return false;
762
+ if (entry.customType === "retryStatus") return true;
763
+ if (entry.customType === "finishContractAdvisory" || entry.customType === "middlewareReminder") return true;
764
+ return entry.display === true;
765
+ }
766
+
767
+ function renderCustomEntry(entry: CustomEntry, width: number): string[] {
768
+ if (entry.customType === "retryStatus") return renderRetryStatusEntry(entry, width);
769
+ // "finishContractAdvisory" is the pre-middleware name for the same entry
770
+ // shape; older session ledgers still carry it.
771
+ if (entry.customType === "finishContractAdvisory" || entry.customType === "middlewareReminder") {
772
+ return renderReminderMessageEntry(entry, width);
773
+ }
774
+ if (entry.display !== true) return [];
775
+ const body = stringifyPreview(entry.data);
776
+ const suffix = body.length > 0 ? ` ${body}` : "";
777
+ return wrapTextWithAnsi(`custom:${entry.customType}${suffix}`, width);
778
+ }
779
+
780
+ function renderReminderMessageEntry(entry: CustomEntry, width: number): string[] {
781
+ const data = payloadObject(entry.data);
782
+ const message = typeof data?.message === "string" && data.message.length > 0 ? data.message : "middleware reminder";
783
+ return wrapTextWithAnsi(message, width);
784
+ }
785
+
786
+ function renderModelChangeEntry(entry: ModelChangeEntry, width: number): string[] {
787
+ const target = entry.target ? `${entry.target}/` : "";
788
+ return wrapTextWithAnsi(styleTaggedNotice(`[model] ${target}${entry.provider}/${entry.modelId}`), width);
789
+ }
790
+
791
+ function renderThinkingChangeEntry(entry: ThinkingLevelChangeEntry, width: number): string[] {
792
+ return wrapTextWithAnsi(styleTaggedNotice(`[thinking] ${entry.thinkingLevel}`), width);
793
+ }
794
+
795
+ function renderFileEntry(entry: FileEntryEntry, width: number): string[] {
796
+ const bytes = typeof entry.bytes === "number" ? `, ${entry.bytes} bytes` : "";
797
+ return wrapTextWithAnsi(styleTaggedNotice(`[file ${entry.operation}] ${entry.path}${bytes}`), width);
798
+ }
799
+
800
+ function renderProtectedArtifactEntry(entry: ProtectedArtifactEntry, width: number): string[] {
801
+ const validation =
802
+ entry.artifact.validationCommand === undefined
803
+ ? ""
804
+ : ` after ${entry.artifact.validationCommand}${entry.artifact.validationExitCode === undefined ? "" : ` exit ${entry.artifact.validationExitCode}`}`;
805
+ return wrapTextWithAnsi(
806
+ styleTaggedNotice(`[protected] ${entry.artifact.path}${validation}: ${entry.artifact.reason}`),
807
+ width,
808
+ );
809
+ }
810
+
811
+ function renderSessionInfoEntry(entry: SessionInfoEntry, width: number): string[] {
812
+ if (entry.name) return wrapTextWithAnsi(styleTaggedNotice(`[session] ${entry.name}`), width);
813
+ if (entry.label && entry.targetTurnId) {
814
+ return wrapTextWithAnsi(styleTaggedNotice(`[label] ${entry.targetTurnId}: ${entry.label}`), width);
815
+ }
816
+ return [];
817
+ }
818
+
819
+ function truncateAtTurn(entries: ReadonlyArray<SessionEntry>, uptoTurnId?: string): SessionEntry[] {
820
+ if (!uptoTurnId) return [...entries];
821
+ const index = entries.findIndex((entry) => entry.turnId === uptoTurnId);
822
+ if (index < 0) return [...entries];
823
+ return entries.slice(0, index + 1);
824
+ }
825
+
826
+ function latestCompactionIndex(entries: ReadonlyArray<SessionEntry>): number {
827
+ for (let i = entries.length - 1; i >= 0; i--) {
828
+ if (entries[i]?.kind === "compactionSummary") return i;
829
+ }
830
+ return -1;
831
+ }
832
+
833
+ function toolCallIdsInEntry(entry: SessionEntry): string[] {
834
+ if (entry.kind !== "message") return [];
835
+ if (entry.role === "tool_call") return [extractToolCall(entry).id];
836
+ if (entry.role !== "assistant") return [];
837
+ const obj = payloadObject(entry.payload);
838
+ if (!Array.isArray(obj?.content)) return [];
839
+ const ids: string[] = [];
840
+ for (const block of obj.content) {
841
+ if (!block || typeof block !== "object") continue;
842
+ const record = block as Record<string, unknown>;
843
+ if (record.type !== "toolCall") continue;
844
+ if (typeof record.id === "string" && record.id.length > 0) ids.push(record.id);
845
+ }
846
+ return ids;
847
+ }
848
+
849
+ function toolResultIdInEntry(entry: SessionEntry): string | null {
850
+ if (entry.kind !== "message" || entry.role !== "tool_result") return null;
851
+ return extractToolResult(entry).id;
852
+ }
853
+
854
+ function findPriorToolCallEntry(
855
+ entries: ReadonlyArray<SessionEntry>,
856
+ toolCallId: string,
857
+ endExclusive: number,
858
+ ): SessionEntry | null {
859
+ for (let index = Math.min(endExclusive, entries.length) - 1; index >= 0; index -= 1) {
860
+ const entry = entries[index];
861
+ if (!entry) continue;
862
+ if (toolCallIdsInEntry(entry).includes(toolCallId)) return entry;
863
+ }
864
+ return null;
865
+ }
866
+
867
+ function repairToolResultOrphans(
868
+ allEntries: ReadonlyArray<SessionEntry>,
869
+ selected: ReadonlyArray<SessionEntry>,
870
+ compactionIndex: number,
871
+ ): SessionEntry[] {
872
+ const out: SessionEntry[] = [];
873
+ const seenToolCalls = new Set<string>();
874
+ const emittedTurnIds = new Set<string>();
875
+ const remember = (entry: SessionEntry): void => {
876
+ emittedTurnIds.add(entry.turnId);
877
+ for (const id of toolCallIdsInEntry(entry)) seenToolCalls.add(id);
878
+ };
879
+ for (const entry of selected) {
880
+ const resultId = toolResultIdInEntry(entry);
881
+ if (resultId !== null && !seenToolCalls.has(resultId)) {
882
+ const dependency = findPriorToolCallEntry(allEntries, resultId, compactionIndex);
883
+ if (dependency !== null && !emittedTurnIds.has(dependency.turnId)) {
884
+ out.push(dependency);
885
+ remember(dependency);
886
+ }
887
+ }
888
+ out.push(entry);
889
+ remember(entry);
890
+ }
891
+ return out;
892
+ }
893
+
894
+ /**
895
+ * Normalize a heterogeneous session JSONL stream into the entry sequence the
896
+ * replay surfaces should show. The stream is first narrowed to the active
897
+ * branch of the turn tree (activeLeafTurnId selects a live branch;
898
+ * uptoTurnId selects and historically truncates; otherwise the most recent
899
+ * append wins), so abandoned sibling turns from earlier /tree switches never
900
+ * replay. When the remaining slice contains a compaction boundary, render the
901
+ * latest summary first and keep only the retained suffix plus later entries,
902
+ * mirroring pi-coding-agent's buildSessionContext behavior.
903
+ */
904
+ export function selectReplayEntries(
905
+ turns: ReadonlyArray<SessionEntry>,
906
+ options: RehydrateChatPanelOptions = {},
907
+ ): SessionEntry[] {
908
+ const active = filterEntriesToActivePath(turns, options.activeLeafTurnId ?? options.uptoTurnId);
909
+ const entries = truncateAtTurn(active, options.uptoTurnId);
910
+ const compactionIndex = latestCompactionIndex(entries);
911
+ if (compactionIndex < 0) return dropLegacyToolResultAssistantDuplicates(entries);
912
+
913
+ const compaction = entries[compactionIndex] as CompactionSummaryEntry;
914
+ const selected: SessionEntry[] = [compaction];
915
+ const firstKeptIndex = compaction.firstKeptTurnId
916
+ ? entries.findIndex((entry) => entry.turnId === compaction.firstKeptTurnId)
917
+ : -1;
918
+ if (firstKeptIndex >= 0 && firstKeptIndex < compactionIndex) {
919
+ selected.push(...entries.slice(firstKeptIndex, compactionIndex));
920
+ }
921
+ selected.push(...entries.slice(compactionIndex + 1));
922
+ return dropLegacyToolResultAssistantDuplicates(repairToolResultOrphans(entries, selected, compactionIndex));
923
+ }
924
+
925
+ function dropLegacyToolResultAssistantDuplicates(entries: ReadonlyArray<SessionEntry>): SessionEntry[] {
926
+ const out: SessionEntry[] = [];
927
+ for (const entry of entries) {
928
+ const previous = out[out.length - 1];
929
+ if (
930
+ entry.kind === "message" &&
931
+ entry.role === "assistant" &&
932
+ previous?.kind === "message" &&
933
+ previous.role === "tool_result" &&
934
+ isLegacyToolResultAssistantDuplicate(previous, entry)
935
+ ) {
936
+ continue;
937
+ }
938
+ out.push(entry);
939
+ }
940
+ return out;
941
+ }
942
+
943
+ function compactionContextText(entry: CompactionSummaryEntry): string {
944
+ return `${COMPACTION_SUMMARY_PREFIX}${entry.summary}${COMPACTION_SUMMARY_SUFFIX}`;
945
+ }
946
+
947
+ function branchContextText(entry: BranchSummaryEntry): string {
948
+ return `${BRANCH_SUMMARY_PREFIX}${entry.summary}${BRANCH_SUMMARY_SUFFIX}`;
949
+ }
950
+
951
+ /** Project Clio's ledger entry onto pi's bash message so pi owns the replay wording. */
952
+ function bashContextText(entry: BashExecutionEntry): string {
953
+ const message: BashExecutionMessage = {
954
+ role: "bashExecution",
955
+ command: entry.command,
956
+ output: truncateReplayText(entry.output),
957
+ exitCode: entry.exitCode ?? undefined,
958
+ cancelled: entry.cancelled,
959
+ truncated: entry.truncated,
960
+ ...(entry.fullOutputPath !== undefined ? { fullOutputPath: entry.fullOutputPath } : {}),
961
+ timestamp: Date.parse(entry.timestamp) || 0,
962
+ };
963
+ return bashExecutionToText(message);
964
+ }
965
+
966
+ function appendContextMessage(out: AgentMessage[], role: "user" | "assistant", text: string, timestamp: string): void {
967
+ const trimmed = text.trim();
968
+ if (trimmed.length === 0) return;
969
+ out.push(makeTextMessage(role, truncateReplayText(trimmed), timestamp));
970
+ }
971
+
972
+ function skillActivationContextText(entry: Extract<SessionEntry, { kind: "skillActivation" }>): string {
973
+ const activation = entry.activation;
974
+ const turn = activation.turnId ? ` turn=${activation.turnId}` : "";
975
+ return `Active skill loaded: ${activation.name} source=${activation.source} hash=${activation.hash} path=${activation.filePath} triggeredBy=${activation.triggeredBy}${turn}. Continue honoring this skill unless the user changes direction.`;
976
+ }
977
+
978
+ export function buildReplayAgentMessagesFromTurns(
979
+ turns: ReadonlyArray<SessionEntry>,
980
+ options: RehydrateChatPanelOptions = {},
981
+ ): AgentMessage[] {
982
+ const out: AgentMessage[] = [];
983
+ const seenToolCalls = new Set<string>();
984
+ for (const entry of selectReplayEntries(turns, options)) {
985
+ switch (entry.kind) {
986
+ case "message": {
987
+ const text = textBlockFromEntry(entry);
988
+ if (entry.role === "user" || entry.role === "assistant") {
989
+ if (entry.role === "assistant" && messageFailure(entry)) break;
990
+ const message = richMessageFromEntry(entry, MAX_REPLAY_TEXT_CHARS);
991
+ if (message) {
992
+ out.push(message);
993
+ recordToolCallsFromMessage(message, seenToolCalls);
994
+ }
995
+ } else if (entry.role === "tool_call") {
996
+ const call = extractToolCall(entry);
997
+ if (!seenToolCalls.has(call.id)) {
998
+ const message = toolCallMessageFromEntry(entry);
999
+ out.push(message);
1000
+ recordToolCallsFromMessage(message, seenToolCalls);
1001
+ }
1002
+ } else if (entry.role === "tool_result") {
1003
+ out.push(toolResultMessageFromEntry(entry));
1004
+ } else if (entry.role === "system") {
1005
+ appendContextMessage(out, "user", `System note: ${text}`, entry.timestamp);
1006
+ }
1007
+ break;
1008
+ }
1009
+ case "bashExecution":
1010
+ if (!entry.excludeFromContext) appendContextMessage(out, "user", bashContextText(entry), entry.timestamp);
1011
+ break;
1012
+ case "branchSummary":
1013
+ appendContextMessage(out, "user", branchContextText(entry), entry.timestamp);
1014
+ break;
1015
+ case "compactionSummary":
1016
+ appendContextMessage(out, "user", compactionContextText(entry), entry.timestamp);
1017
+ break;
1018
+ case "skillActivation":
1019
+ appendContextMessage(out, "user", skillActivationContextText(entry), entry.timestamp);
1020
+ break;
1021
+ case "custom":
1022
+ case "modelChange":
1023
+ case "thinkingLevelChange":
1024
+ case "fileEntry":
1025
+ case "sessionInfo":
1026
+ case "label":
1027
+ case "protectedArtifact":
1028
+ case "taskLedger":
1029
+ case "decisionLedger":
1030
+ // A worker's answer is not the operator's words and not the model's.
1031
+ // It reaches the model only when an operator shares it, and a share
1032
+ // is already a user message by the time it lands in the ledger.
1033
+ case "workerRun":
1034
+ break;
1035
+ }
1036
+ }
1037
+ return out;
1038
+ }
1039
+
1040
+ /**
1041
+ * Rehydrate a chat panel from a persisted session's turn list. The
1042
+ * interactive layer calls this after /resume or /fork so the user sees the
1043
+ * prior transcript instead of a blank pane; without it, swapping the
1044
+ * session contract updated meta but left the visible chat untouched
1045
+ * (Row 51 and Row 52 on the Phase 12 ledger).
1046
+ *
1047
+ * Replays a structured SessionEntry stream. Compaction summaries, branch
1048
+ * summaries, bash executions, custom entries, and metadata entries are
1049
+ * rendered explicitly. Tool call/result entries are best-effort: when a
1050
+ * result can be paired to a prior call id it updates that tool segment,
1051
+ * otherwise it falls back to a standalone transcript line.
1052
+ *
1053
+ * Worker blocks are rebuilt from their `workerRun` entries plus the sealed
1054
+ * receipts those entries name, so a resumed session shows the answer a `/run`
1055
+ * produced rather than a header with nothing under it. The block is applied
1056
+ * through the same panel call the live reducer uses, which is what makes an
1057
+ * agent-origin card land under the tool segment that spawned it here too.
1058
+ *
1059
+ * Callers read turns via `openSession(id).turns()` and pass them in explicitly.
1060
+ * The receipt reader is the one thing this touches beyond the panel; it is a
1061
+ * parameter with a disk-backed default, and it never throws.
1062
+ */
1063
+ export function rehydrateChatPanelFromTurns(
1064
+ chatPanel: ChatPanel,
1065
+ turns: ReadonlyArray<SessionEntry>,
1066
+ options: RehydrateChatPanelOptions = {},
1067
+ ): void {
1068
+ const pendingToolIds: string[] = [];
1069
+ const selected = selectReplayEntries(turns, options);
1070
+ // One block per assignment, drawn where its first attempt started. Later
1071
+ // attempts of the same assignment fold into that block as `↻` rail lines, so
1072
+ // a failover replays as the one run it was rather than as two.
1073
+ const workerStates = workerEntriesFromRunEntries(
1074
+ selected.filter((entry): entry is WorkerRunEntry => entry.kind === "workerRun"),
1075
+ options.readWorkerReceipt ?? readWorkerReceiptFactsForReplay,
1076
+ );
1077
+ const placedAssignments = new Set<string>();
1078
+ for (const entry of selected) {
1079
+ switch (entry.kind) {
1080
+ case "message": {
1081
+ if (entry.role === "user") {
1082
+ const text = truncateReplayText(replayedUserText(entry));
1083
+ if (text.length > 0) chatPanel.appendUser(text);
1084
+ break;
1085
+ }
1086
+ if (entry.role === "assistant") {
1087
+ const text = chatMessageText(entry);
1088
+ const failure = messageFailure(entry);
1089
+ const richMessage = richMessageFromEntry(entry, MAX_REPLAY_TEXT_CHARS);
1090
+ if (richMessage || text.length > 0 || failure) {
1091
+ const message = richMessage ?? makeTextMessage("assistant", truncateReplayText(text), entry.timestamp);
1092
+ if (failure) {
1093
+ (message as { stopReason?: string; errorMessage?: string }).stopReason = failure.stopReason;
1094
+ (message as { stopReason?: string; errorMessage?: string }).errorMessage = failure.errorMessage;
1095
+ }
1096
+ chatPanel.applyEvent({ type: "message_end", message });
1097
+ chatPanel.applyEvent({ type: "agent_end", messages: [message] });
1098
+ }
1099
+ break;
1100
+ }
1101
+ if (entry.role === "tool_call") {
1102
+ const call = extractToolCall(entry);
1103
+ pendingToolIds.push(call.id);
1104
+ chatPanel.applyEvent({
1105
+ type: "tool_execution_start",
1106
+ toolCallId: call.id,
1107
+ toolName: call.name,
1108
+ args: call.args,
1109
+ });
1110
+ chatPanel.markToolReplayed?.(call.id);
1111
+ break;
1112
+ }
1113
+ if (entry.role === "tool_result") {
1114
+ const result = extractToolResult(entry);
1115
+ const fallbackId = result.id ?? pendingToolIds.pop() ?? null;
1116
+ if (fallbackId) {
1117
+ const pendingIndex = pendingToolIds.indexOf(fallbackId);
1118
+ if (pendingIndex >= 0) pendingToolIds.splice(pendingIndex, 1);
1119
+ chatPanel.applyEvent({
1120
+ type: "tool_execution_end",
1121
+ toolCallId: fallbackId,
1122
+ toolName: result.name,
1123
+ result: displayReplayToolResult(result.result),
1124
+ isError: result.isError,
1125
+ ...(result.durationMs !== undefined ? { durationMs: result.durationMs } : {}),
1126
+ ...(result.resultSummary !== undefined ? { resultSummary: result.resultSummary } : {}),
1127
+ ...(result.outcome !== undefined ? { outcome: result.outcome } : {}),
1128
+ ...(result.blockReason !== undefined ? { blockReason: result.blockReason } : {}),
1129
+ } as ChatLoopEvent);
1130
+ } else {
1131
+ chatPanel.appendReplayBlock((width) =>
1132
+ renderToolResultOnly(
1133
+ {
1134
+ toolCallId: result.id ?? "",
1135
+ toolName: result.name,
1136
+ result: displayReplayToolResult(result.result),
1137
+ isError: result.isError,
1138
+ ...(result.durationMs !== undefined ? { durationMs: result.durationMs } : {}),
1139
+ ...(result.resultSummary !== undefined ? { resultSummary: result.resultSummary } : {}),
1140
+ ...(result.outcome === "blocked" ? { outcome: "blocked" as const } : {}),
1141
+ ...(result.blockReason !== undefined ? { blockReason: result.blockReason } : {}),
1142
+ },
1143
+ width,
1144
+ { unbounded: options.unboundedToolBodies === true },
1145
+ ),
1146
+ );
1147
+ }
1148
+ break;
1149
+ }
1150
+ if (entry.role === "system") {
1151
+ const text = textBlockFromEntry(entry);
1152
+ if (text.length > 0) appendReplayLine(chatPanel, `system: ${text}`);
1153
+ break;
1154
+ }
1155
+ if (entry.role === "checkpoint") {
1156
+ const text = textBlockFromEntry(entry);
1157
+ appendReplayLine(chatPanel, text.length > 0 ? `[checkpoint] ${text}` : "[checkpoint]");
1158
+ break;
1159
+ }
1160
+ break;
1161
+ }
1162
+ case "bashExecution":
1163
+ chatPanel.appendReplayBlock((width) => renderBashExecutionEntry(entry, width));
1164
+ break;
1165
+ case "custom":
1166
+ if (rendersCustomEntry(entry)) chatPanel.appendReplayBlock((width) => renderCustomEntry(entry, width));
1167
+ break;
1168
+ case "modelChange":
1169
+ chatPanel.appendReplayBlock((width) => renderModelChangeEntry(entry, width));
1170
+ break;
1171
+ case "thinkingLevelChange":
1172
+ chatPanel.appendReplayBlock((width) => renderThinkingChangeEntry(entry, width));
1173
+ break;
1174
+ case "fileEntry":
1175
+ chatPanel.appendReplayBlock((width) => renderFileEntry(entry, width));
1176
+ break;
1177
+ case "protectedArtifact":
1178
+ chatPanel.appendReplayBlock((width) => renderProtectedArtifactEntry(entry, width));
1179
+ break;
1180
+ case "skillActivation":
1181
+ appendReplayLine(chatPanel, `[skill] ${entry.activation.name} ${entry.activation.triggeredBy}`);
1182
+ break;
1183
+ case "branchSummary":
1184
+ if (entry.summary.trim().length > 0) {
1185
+ chatPanel.appendReplayBlock((width) =>
1186
+ renderBranchSummaryEntry({ ...entry, summary: truncateReplayText(entry.summary) }, width),
1187
+ );
1188
+ }
1189
+ break;
1190
+ case "compactionSummary":
1191
+ if (entry.summary.trim().length > 0) {
1192
+ chatPanel.appendReplayBlock((width) =>
1193
+ renderCompactionSummaryEntry({ ...entry, summary: truncateReplayText(entry.summary) }, width),
1194
+ );
1195
+ }
1196
+ break;
1197
+ case "sessionInfo":
1198
+ if (entry.name || entry.label) chatPanel.appendReplayBlock((width) => renderSessionInfoEntry(entry, width));
1199
+ break;
1200
+ case "workerRun": {
1201
+ if (placedAssignments.has(entry.assignmentId)) break;
1202
+ const state = workerStates.get(entry.assignmentId);
1203
+ if (state === undefined) break;
1204
+ placedAssignments.add(entry.assignmentId);
1205
+ chatPanel.applyWorkerState(state);
1206
+ break;
1207
+ }
1208
+ case "label":
1209
+ case "taskLedger":
1210
+ case "decisionLedger":
1211
+ break;
1212
+ }
1213
+ }
1214
+ for (const pendingId of pendingToolIds) {
1215
+ chatPanel.applyEvent({
1216
+ type: "tool_execution_end",
1217
+ toolCallId: pendingId,
1218
+ toolName: "tool",
1219
+ result: "missing result; session ended before the tool completed",
1220
+ isError: true,
1221
+ });
1222
+ }
1223
+ // Replay favors a compact historical ledger even though fresh non-resource
1224
+ // calls auto-expand for live arguments and output. Collapse reconstructed
1225
+ // tools explicitly; /export re-expands them afterward via
1226
+ // toggleAllToolsExpanded, while /resume and /fork retain the compact form.
1227
+ chatPanel.collapseAllTools();
1228
+ }