@iowarp/clio-coder 0.3.1 → 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 (595) hide show
  1. package/CHANGELOG.md +90 -2
  2. package/CONTRIBUTING.md +23 -23
  3. package/README.md +284 -613
  4. package/dist/{acp-FPR54DGL.js → acp-BIYHVZIM.js} +43 -53
  5. package/dist/{agents-OGPIHPJH.js → agents-YT6SSRIT.js} +43 -26
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-IC3K6NIZ.js → auth-5TWEIYDN.js} +20 -12
  8. package/dist/{chunk-PV4JUBVJ.js → chunk-2EHAIA3X.js} +40 -21
  9. package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
  10. package/dist/chunk-2SFS6XQE.js +122 -0
  11. package/dist/chunk-2VTFPG5O.js +48 -0
  12. package/dist/{chunk-MAR7Y6HW.js → chunk-3ZXDFGR5.js} +23 -16
  13. package/dist/chunk-4BJ5BYCE.js +61 -0
  14. package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
  15. package/dist/chunk-4KLWL3UC.js +18 -0
  16. package/dist/chunk-4VP4KH3K.js +962 -0
  17. package/dist/chunk-4ZG3XFUR.js +77 -0
  18. package/dist/chunk-5B2AEOW5.js +5407 -0
  19. package/dist/{chunk-K2ITRMHZ.js → chunk-5TSRNF4G.js} +6 -138
  20. package/dist/{chunk-OLBBMFRD.js → chunk-5UUP6MWO.js} +24 -62
  21. package/dist/chunk-65DEGPJ6.js +52 -0
  22. package/dist/chunk-6EJMN2Y3.js +17 -0
  23. package/dist/chunk-6EJV5X2W.js +16405 -0
  24. package/dist/chunk-6N5PTWMY.js +136 -0
  25. package/dist/chunk-6XLNIQDB.js +27 -0
  26. package/dist/{chunk-TEKV33Q5.js → chunk-77VKQEHF.js} +65 -33
  27. package/dist/chunk-7CR24IG7.js +242 -0
  28. package/dist/{chunk-M5T5VO65.js → chunk-7EYHLWU7.js} +837 -635
  29. package/dist/chunk-7MNJORFF.js +22 -0
  30. package/dist/{chunk-KY56HMHH.js → chunk-A3CYT5EX.js} +125 -31
  31. package/dist/chunk-AGYYIBLL.js +1069 -0
  32. package/dist/chunk-AO4RKG4M.js +277 -0
  33. package/dist/{chunk-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
  34. package/dist/chunk-ARBGF5F7.js +174 -0
  35. package/dist/{chunk-673JJUWJ.js → chunk-BMEMKKIT.js} +2 -2
  36. package/dist/chunk-CBCAPZAA.js +229 -0
  37. package/dist/chunk-CMZWFGD2.js +352 -0
  38. package/dist/chunk-ECH6PKUQ.js +39 -0
  39. package/dist/chunk-ED4KHGC3.js +143 -0
  40. package/dist/chunk-EKMEHE4H.js +340 -0
  41. package/dist/{chunk-RPTR2H26.js → chunk-EPVUXGXG.js} +21 -15
  42. package/dist/chunk-FCSXB6T2.js +338 -0
  43. package/dist/chunk-FJ3H4MN5.js +48 -0
  44. package/dist/chunk-FQ4SKYE4.js +29 -0
  45. package/dist/chunk-G2DE3C7R.js +644 -0
  46. package/dist/chunk-G4BMMOKF.js +182 -0
  47. package/dist/{chunk-ZPY3JZ5E.js → chunk-GGXXDWE4.js} +183 -1233
  48. package/dist/chunk-HC4CLZ2Y.js +68 -0
  49. package/dist/{chunk-LU4TK2PR.js → chunk-HFSBBKSQ.js} +5 -56
  50. package/dist/{chunk-PIUMUEMV.js → chunk-HKIYEGME.js} +10 -6
  51. package/dist/chunk-I4HZDVNP.js +73 -0
  52. package/dist/{chunk-4QKXUHSR.js → chunk-IGLFWIYI.js} +70 -20
  53. package/dist/chunk-IKCO5N3L.js +162 -0
  54. package/dist/chunk-IR4CFBFN.js +56 -0
  55. package/dist/{chunk-PFEFKVGL.js → chunk-J5HN4RYU.js} +13 -11
  56. package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
  57. package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
  58. package/dist/chunk-KJ5LWLOE.js +1077 -0
  59. package/dist/chunk-LBMZMYH2.js +285 -0
  60. package/dist/{chunk-G34LV2PF.js → chunk-LBNRH5WM.js} +84 -170
  61. package/dist/{chunk-H6F6BYOH.js → chunk-LZSJBIVT.js} +7003 -7434
  62. package/dist/{chunk-HQQID6OA.js → chunk-M6SHUN7Q.js} +5 -5
  63. package/dist/chunk-MAW544W2.js +1882 -0
  64. package/dist/chunk-MBS4V7ZP.js +217 -0
  65. package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
  66. package/dist/chunk-MNA4JGU4.js +255 -0
  67. package/dist/chunk-MQSRRFWA.js +3428 -0
  68. package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
  69. package/dist/chunk-OAO4GE4M.js +619 -0
  70. package/dist/chunk-OHHN2SO4.js +5135 -0
  71. package/dist/chunk-OKGUZO2U.js +34 -0
  72. package/dist/{chunk-GAEBEQVI.js → chunk-OOJYHWRB.js} +32 -346
  73. package/dist/{chunk-Q5WJOSJ7.js → chunk-OQ33BKR3.js} +2 -1
  74. package/dist/chunk-OQE5J4C6.js +73 -0
  75. package/dist/{chunk-KKNLWXI6.js → chunk-ORBHGJC5.js} +8 -8
  76. package/dist/chunk-POHLU5DW.js +1186 -0
  77. package/dist/chunk-QKMUKYO7.js +4961 -0
  78. package/dist/{chunk-ASND7OZK.js → chunk-QTYWRVRA.js} +13 -13
  79. package/dist/{chunk-EYOKLTMF.js → chunk-SRF2PJNW.js} +17 -3
  80. package/dist/chunk-SST6Z5JA.js +80 -0
  81. package/dist/chunk-STBPMHSX.js +2456 -0
  82. package/dist/chunk-T6YILFSB.js +80 -0
  83. package/dist/chunk-TZTZS7QK.js +227 -0
  84. package/dist/chunk-UOV2BYIW.js +107 -0
  85. package/dist/{chunk-Q3RUPKEJ.js → chunk-V4RXGQ5Q.js} +58 -189
  86. package/dist/chunk-VAKQQHWR.js +434 -0
  87. package/dist/chunk-VG7TBQIY.js +128 -0
  88. package/dist/chunk-VJWL6YS5.js +244 -0
  89. package/dist/chunk-WEH5XRJQ.js +32 -0
  90. package/dist/chunk-WMSVI4G2.js +2095 -0
  91. package/dist/chunk-WVO7V2QY.js +797 -0
  92. package/dist/chunk-X4RCMKVQ.js +641 -0
  93. package/dist/chunk-X75S7HFS.js +374 -0
  94. package/dist/chunk-XN3L4EYL.js +46 -0
  95. package/dist/{chunk-RDLVBZEO.js → chunk-YCWGATWI.js} +6 -4
  96. package/dist/chunk-YHZX5GEU.js +193 -0
  97. package/dist/chunk-YXLYO42X.js +91 -0
  98. package/dist/{chunk-NMOX6HFD.js → chunk-ZDOOVTXZ.js} +29 -77
  99. package/dist/chunk-ZI647VB5.js +37 -0
  100. package/dist/{chunk-C4PTHK7P.js → chunk-ZWLZP4ZT.js} +5 -5
  101. package/dist/cli/index.js +62 -54
  102. package/dist/clio-4LY5K2AC.js +25 -0
  103. package/dist/code-nav-7AX6FYE6.js +600 -0
  104. package/dist/codewiki/build-worker.js +66 -0
  105. package/dist/compile-cache-CVJMMODC.js +18 -0
  106. package/dist/{components-DMAOEKFB.js → components-KELWS457.js} +11 -6
  107. package/dist/{config-IRUQ7SE4.js → config-GTLUW2PR.js} +92 -55
  108. package/dist/configure-R6A64DHX.js +42 -0
  109. package/dist/context-5VKGUVJJ.js +866 -0
  110. package/dist/{context-3KWFLHJG.js → context-JFZEJ7W5.js} +15 -13
  111. package/dist/{context-5RADCKTR.js → context-RW5HC47S.js} +71 -35
  112. package/dist/{context-clear-7TSNPAAI.js → context-clear-6ZHBAZZT.js} +54 -28
  113. package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
  114. package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
  115. package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
  116. package/dist/{doctor-UC5NAJYQ.js → doctor-KI767GSN.js} +27 -17
  117. package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
  118. package/dist/{evidence-YEGUW4L3.js → evidence-UA6AWDQQ.js} +46 -26
  119. package/dist/{evolve-TXARCTPG.js → evolve-QNTFGV6Z.js} +45 -25
  120. package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
  121. package/dist/{fleet-6G3DHNYE.js → fleet-Q7UOMUSG.js} +163 -54
  122. package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
  123. package/dist/{init-KZ5QTF6M.js → init-WBB65ZHQ.js} +69 -32
  124. package/dist/{memory-73ESV5YC.js → memory-MD3O64RI.js} +48 -27
  125. package/dist/{models-A4PVNWJK.js → models-BZU34YWD.js} +39 -25
  126. package/dist/monitor-MEQA5C3I.js +661 -0
  127. package/dist/{chunk-FCIH3BIZ.js → orchestrator-CGFKEP27.js} +11832 -8687
  128. package/dist/{paths-C4H6IV77.js → paths-UXLN5YYZ.js} +10 -5
  129. package/dist/{preload-6WVMHX3A.js → preload-P6DGH2PZ.js} +2 -2
  130. package/dist/{reset-BGW6OGMV.js → reset-L2FQEE3E.js} +16 -10
  131. package/dist/{run-YTPEYQOH.js → run-IV4Q6RLN.js} +101 -61
  132. package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
  133. package/dist/{skills-2V6RA3OQ.js → skills-LQEKRDTN.js} +34 -14
  134. package/dist/{skills-eval-S2TVJO4F.js → skills-eval-3DC4HEWS.js} +70 -34
  135. package/dist/steer-GGWFUJUD.js +77 -0
  136. package/dist/{targets-TYXLPB23.js → targets-C4SSGQOB.js} +43 -27
  137. package/dist/terminal-lease-IT5JW2NR.js +395 -0
  138. package/dist/{trace-GGOJ6Q6Z.js → trace-PNCASAXC.js} +41 -16
  139. package/dist/{chunk-N6F52NLF.js → tree-sitter-HGKH6LG4.js} +28 -2306
  140. package/dist/{uninstall-LLLT4F4W.js → uninstall-FZCQCDKC.js} +10 -5
  141. package/dist/{upgrade-33G2LMM5.js → upgrade-7TT7SQ3G.js} +45 -25
  142. package/dist/{usage-ZAFSXKKG.js → usage-GV4PKT3M.js} +62 -31
  143. package/dist/verify-G6V4D2G7.js +716 -0
  144. package/dist/web-fetch-2YHJ3KTG.js +638 -0
  145. package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-DQF6Z66B.js} +74 -34
  146. package/dist/worker/entry.js +221 -36
  147. package/dist/workspace-G4ZWUIPR.js +22 -0
  148. package/docs/README.md +22 -17
  149. package/docs/acp.md +168 -16
  150. package/docs/alcf-provider.md +1 -1
  151. package/docs/architecture.md +136 -7
  152. package/docs/artifact-versions.md +1 -1
  153. package/docs/built-in-agents.md +1 -1
  154. package/docs/capacity-and-scheduling.md +1 -1
  155. package/docs/commands-and-modes.md +114 -71
  156. package/docs/config-knobs-audit.md +1 -3
  157. package/docs/configuration-and-targets.md +174 -46
  158. package/docs/context-engine.md +29 -6
  159. package/docs/development-pipeline.md +26 -1
  160. package/docs/dispatch-architecture-rationale.md +1 -1
  161. package/docs/documentation-coverage.md +2 -2
  162. package/docs/documentation-guide.md +1 -1
  163. package/docs/environment-variables.md +13 -5
  164. package/docs/eval-runner.md +1 -1
  165. package/docs/evals-internal.md +1 -1
  166. package/docs/evidence-and-memory.md +6 -2
  167. package/docs/evolution.md +2 -2
  168. package/docs/exit-codes-and-output.md +15 -9
  169. package/docs/extensions-and-sharing.md +9 -9
  170. package/docs/fleet-dispatch.md +7 -5
  171. package/docs/git-commit-provenance.md +120 -0
  172. package/docs/glossary.md +1 -1
  173. package/docs/installation-and-lifecycle.md +34 -27
  174. package/docs/middleware-and-components.md +1 -1
  175. package/docs/model-catalog.md +45 -14
  176. package/docs/observability.md +8 -5
  177. package/docs/performance-methodology.md +491 -0
  178. package/docs/pi-boundary.md +72 -0
  179. package/docs/proactive-memory.md +3 -3
  180. package/docs/prompt-envelope-and-tools.md +24 -3
  181. package/docs/provider-adapter-cookbook.md +57 -4
  182. package/docs/release-cut-checklist.md +129 -115
  183. package/docs/safety-model.md +9 -5
  184. package/docs/scientific-validation.md +3 -3
  185. package/docs/session-lifecycle.md +55 -12
  186. package/docs/skills-marketplace.md +12 -8
  187. package/docs/time-conventions.md +1 -1
  188. package/docs/tool-usage.md +3 -3
  189. package/docs/trace-store.md +1 -1
  190. package/docs/troubleshooting.md +10 -7
  191. package/docs/tui-design.md +47 -10
  192. package/docs/worker-dispatch-mechanics.md +1 -1
  193. package/package.json +19 -22
  194. package/skills/coding/ast-grep/SKILL.md +136 -0
  195. package/skills/coding/ast-grep/evals.md +56 -0
  196. package/skills/coding/ast-grep/references/rule_reference.md +297 -0
  197. package/skills/coding/coding-standards/SKILL.md +113 -0
  198. package/skills/coding/coding-standards/evals.md +34 -0
  199. package/skills/coding/prototype/SKILL.md +86 -0
  200. package/skills/coding/prototype/evals.md +42 -0
  201. package/skills/coding/prototype/references/LOGIC.md +67 -0
  202. package/skills/coding/prototype/references/UI.md +112 -0
  203. package/skills/coding/tdd/SKILL.md +101 -0
  204. package/skills/coding/tdd/evals.md +41 -0
  205. package/skills/coding/tdd/references/mocking.md +59 -0
  206. package/skills/coding/tdd/references/tests.md +77 -0
  207. package/skills/context/context-handoff/SKILL.md +126 -0
  208. package/skills/context/context-handoff/evals.md +57 -0
  209. package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
  210. package/skills/context/context-prime/SKILL.md +95 -0
  211. package/skills/context/context-prime/evals.md +54 -0
  212. package/skills/meta/clio-dev/SKILL.md +91 -0
  213. package/skills/meta/clio-dev/evals.md +45 -0
  214. package/skills/meta/clio-test/SKILL.md +130 -0
  215. package/skills/meta/clio-test/evals.md +43 -0
  216. package/skills/meta/clio-test/references/harness.md +97 -0
  217. package/skills/meta/clio-test/references/test-map.md +59 -0
  218. package/skills/meta/credentials/SKILL.md +125 -0
  219. package/skills/meta/credentials/evals.md +104 -0
  220. package/skills/meta/find-skills/SKILL.md +72 -0
  221. package/skills/meta/find-skills/evals.md +47 -0
  222. package/skills/meta/herdr/SKILL.md +127 -0
  223. package/skills/meta/herdr/evals.md +38 -0
  224. package/skills/meta/skill-craft/SKILL.md +102 -0
  225. package/skills/meta/skill-craft/evals.md +41 -0
  226. package/skills/planning/architecture/SKILL.md +129 -0
  227. package/skills/planning/architecture/evals.md +36 -0
  228. package/skills/planning/backlog/SKILL.md +90 -0
  229. package/skills/planning/backlog/evals.md +43 -0
  230. package/skills/planning/prd/SKILL.md +82 -0
  231. package/skills/planning/prd/evals.md +49 -0
  232. package/skills/planning/product-intent/SKILL.md +112 -0
  233. package/skills/planning/product-intent/evals.md +36 -0
  234. package/skills/planning/tech-spec/SKILL.md +115 -0
  235. package/skills/planning/tech-spec/evals.md +47 -0
  236. package/skills/registry.yaml +136 -0
  237. package/skills/research/arxiv-literature/SKILL.md +104 -0
  238. package/skills/research/arxiv-literature/evals.md +58 -0
  239. package/skills/research/experiment-protocol/SKILL.md +122 -0
  240. package/skills/research/experiment-protocol/evals.md +91 -0
  241. package/skills/research/scientific-debugging/SKILL.md +119 -0
  242. package/skills/research/scientific-debugging/evals.md +138 -0
  243. package/skills/research/scientific-modernization/SKILL.md +138 -0
  244. package/skills/research/scientific-modernization/evals.md +84 -0
  245. package/skills/workflow/design-council/SKILL.md +139 -0
  246. package/skills/workflow/design-council/evals.md +97 -0
  247. package/skills/workflow/grill-me/SKILL.md +186 -0
  248. package/skills/workflow/grill-me/evals.md +78 -0
  249. package/skills/workflow/workflow-distiller/SKILL.md +136 -0
  250. package/skills/workflow/workflow-distiller/evals.md +107 -0
  251. package/src/cli/acp.ts +31 -4
  252. package/src/cli/clio.ts +68 -6
  253. package/src/cli/config-inspect.ts +28 -22
  254. package/src/cli/configure.ts +47 -9
  255. package/src/cli/context-clear.ts +2 -2
  256. package/src/cli/context-index.ts +21 -23
  257. package/src/cli/context.ts +13 -8
  258. package/src/cli/default-target.ts +9 -17
  259. package/src/cli/docs.ts +11 -5
  260. package/src/cli/evidence.ts +4 -1
  261. package/src/cli/extensions.ts +10 -1
  262. package/src/cli/fleet.ts +47 -6
  263. package/src/cli/index.ts +55 -26
  264. package/src/cli/memory.ts +3 -1
  265. package/src/cli/models.ts +1 -1
  266. package/src/cli/modes/json-stream.ts +37 -1
  267. package/src/cli/modes/print.ts +24 -9
  268. package/src/cli/run.ts +2 -2
  269. package/src/cli/skills-eval.ts +23 -8
  270. package/src/cli/skills.ts +19 -4
  271. package/src/cli/targets.ts +4 -0
  272. package/src/cli/text-layout.ts +15 -5
  273. package/src/cli/trace.ts +62 -14
  274. package/src/cli/upgrade.ts +18 -2
  275. package/src/cli/usage.ts +10 -3
  276. package/src/cli/wiki-generate.ts +2 -1
  277. package/src/core/agent-environment.ts +7 -0
  278. package/src/core/bash-exec.ts +72 -1
  279. package/src/core/boot-trace.ts +9 -4
  280. package/src/core/bus-events.ts +20 -4
  281. package/src/core/commit-attribution.ts +157 -0
  282. package/src/core/compile-cache.ts +159 -0
  283. package/src/core/config.ts +131 -2
  284. package/src/core/defaults.ts +39 -5
  285. package/src/core/domain-loader.ts +12 -5
  286. package/src/core/git-commit-attribution.ts +362 -0
  287. package/src/core/incomplete-installation.ts +45 -0
  288. package/src/core/response-schema.ts +1 -1
  289. package/src/core/safe-exec.ts +13 -1
  290. package/src/core/settings-layers.ts +155 -21
  291. package/src/core/skill-activation.ts +1 -1
  292. package/src/core/startup-timer.ts +3 -3
  293. package/src/core/state-file-lock.ts +13 -1
  294. package/src/core/termination.ts +78 -5
  295. package/src/domains/config/classify.ts +15 -3
  296. package/src/domains/config/extension.ts +19 -13
  297. package/src/domains/config/index.ts +10 -0
  298. package/src/domains/config/keybindings.ts +42 -6
  299. package/src/domains/context/bootstrap-prompt.ts +1 -1
  300. package/src/domains/context/bootstrap.ts +111 -18
  301. package/src/domains/context/clear.ts +16 -11
  302. package/src/domains/context/clio-md.ts +111 -9
  303. package/src/domains/context/codewiki/artifact.ts +400 -0
  304. package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
  305. package/src/domains/context/codewiki/build-worker.ts +54 -0
  306. package/src/domains/context/codewiki/coordinator.ts +182 -0
  307. package/src/domains/context/codewiki/indexer.ts +59 -144
  308. package/src/domains/context/codewiki/paths.ts +67 -0
  309. package/src/domains/context/codewiki/schema.ts +80 -0
  310. package/src/domains/context/codewiki/tree-sitter.ts +1 -1
  311. package/src/domains/context/contract.ts +11 -5
  312. package/src/domains/context/extension.ts +94 -143
  313. package/src/domains/context/fingerprint.ts +3 -1
  314. package/src/domains/context/index.ts +12 -22
  315. package/src/domains/context/project-metadata.ts +19 -0
  316. package/src/domains/context/prompt-context.ts +9 -10
  317. package/src/domains/context/refresh.ts +29 -21
  318. package/src/domains/context/runtime.ts +17 -0
  319. package/src/domains/context/wiki/generate.ts +39 -34
  320. package/src/domains/context/wiki/plan.ts +1 -1
  321. package/src/domains/context/wiki/prompts.ts +21 -8
  322. package/src/domains/dispatch/code-step.ts +20 -1
  323. package/src/domains/dispatch/extension.ts +158 -21
  324. package/src/domains/dispatch/failure-classification.ts +6 -0
  325. package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
  326. package/src/domains/dispatch/orphan-recovery.ts +50 -8
  327. package/src/domains/dispatch/receipt-integrity.ts +5 -0
  328. package/src/domains/dispatch/state.ts +31 -6
  329. package/src/domains/dispatch/transport.ts +2 -1
  330. package/src/domains/dispatch/types.ts +14 -0
  331. package/src/domains/dispatch/worker-spawn.ts +21 -2
  332. package/src/domains/eval/metrics/context.ts +1 -1
  333. package/src/domains/eval/types.ts +0 -1
  334. package/src/domains/evidence/build.ts +41 -1
  335. package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
  336. package/src/domains/lifecycle/migrations/index.ts +24 -4
  337. package/src/domains/middleware/hooks-io.ts +12 -0
  338. package/src/domains/middleware/skills-reminder.ts +30 -15
  339. package/src/domains/prompts/compiler.ts +142 -84
  340. package/src/domains/prompts/contract.ts +18 -2
  341. package/src/domains/prompts/extension.ts +39 -7
  342. package/src/domains/prompts/fragment-loader.ts +0 -1
  343. package/src/domains/prompts/fragments/identity/clio.md +2 -4
  344. package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
  345. package/src/domains/prompts/fragments/identity/self-awareness.md +1 -45
  346. package/src/domains/prompts/fragments/operating/contract.md +4 -50
  347. package/src/domains/prompts/fragments/operating/delegation.md +42 -0
  348. package/src/domains/prompts/fragments/operating/skills.md +26 -0
  349. package/src/domains/prompts/fragments/operating/worker.md +16 -0
  350. package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
  351. package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
  352. package/src/domains/prompts/fragments/safety/read-only.md +4 -4
  353. package/src/domains/prompts/fragments/safety/suggest.md +2 -2
  354. package/src/domains/prompts/fragments/wiki/page.md +10 -0
  355. package/src/domains/prompts/fragments/wiki/plan.md +10 -0
  356. package/src/domains/prompts/preload.ts +3 -3
  357. package/src/domains/providers/auth/api-key.ts +1 -1
  358. package/src/domains/providers/auth/backend-file.ts +20 -10
  359. package/src/domains/providers/auth/backend-memory.ts +59 -4
  360. package/src/domains/providers/auth/boot-status.ts +65 -0
  361. package/src/domains/providers/auth/oauth.ts +2 -1
  362. package/src/domains/providers/auth/storage.ts +97 -38
  363. package/src/domains/providers/capabilities.ts +12 -4
  364. package/src/domains/providers/contract.ts +15 -4
  365. package/src/domains/providers/extension.ts +18 -6
  366. package/src/domains/providers/model-runtime-capabilities.ts +15 -4
  367. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +118 -35
  368. package/src/domains/providers/plugins.ts +5 -3
  369. package/src/domains/providers/probe/fingerprint.ts +25 -5
  370. package/src/domains/providers/registry.ts +31 -10
  371. package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
  372. package/src/domains/providers/runtimes/builtins.ts +2 -2
  373. package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
  374. package/src/domains/providers/runtimes/common/local-synth.ts +6 -7
  375. package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
  376. package/src/domains/providers/support.ts +6 -3
  377. package/src/domains/providers/types/local-model-quirks.ts +7 -9
  378. package/src/domains/providers/types/runtime-descriptor.ts +12 -1
  379. package/src/domains/providers/types/target-descriptor.ts +22 -0
  380. package/src/domains/resources/contract.ts +0 -1
  381. package/src/domains/resources/extension.ts +1 -3
  382. package/src/domains/resources/loader.ts +3 -4
  383. package/src/domains/resources/prompts/loader.ts +16 -2
  384. package/src/domains/resources/prompts/substitute.ts +1 -65
  385. package/src/domains/resources/skills/content-hash.ts +2 -0
  386. package/src/domains/resources/skills/install.ts +17 -0
  387. package/src/domains/resources/skills/loader.ts +17 -10
  388. package/src/domains/resources/skills/marketplace.ts +55 -9
  389. package/src/domains/safety/action-classifier.ts +4 -2
  390. package/src/domains/safety/audit.ts +8 -2
  391. package/src/domains/safety/extension.ts +1 -1
  392. package/src/domains/session/compaction/branch-summary.ts +3 -2
  393. package/src/domains/session/compaction/cut-point.ts +2 -1
  394. package/src/domains/session/compaction/tokens.ts +2 -1
  395. package/src/domains/session/context-ledger.ts +14 -0
  396. package/src/domains/session/contract.ts +15 -0
  397. package/src/domains/session/decision-board.ts +190 -0
  398. package/src/domains/session/entries.ts +66 -3
  399. package/src/domains/session/extension.ts +93 -12
  400. package/src/domains/session/retry.ts +10 -18
  401. package/src/domains/session/session-artifacts.ts +107 -0
  402. package/src/domains/session/task-board.ts +207 -13
  403. package/src/domains/session/tree/active-path.ts +44 -5
  404. package/src/domains/session/tree/fork.ts +26 -27
  405. package/src/domains/session/tree/preview.ts +2 -2
  406. package/src/domains/session/workspace/git-probe.ts +17 -11
  407. package/src/domains/user-tasks/store.ts +297 -0
  408. package/src/engine/acp/errors.ts +96 -0
  409. package/src/engine/acp/server.ts +1728 -146
  410. package/src/engine/acp/transport.ts +135 -14
  411. package/src/engine/acp/types.ts +26 -0
  412. package/src/engine/agent.ts +3 -3
  413. package/src/engine/ai.ts +32 -27
  414. package/src/engine/alcf-oauth.ts +26 -19
  415. package/src/engine/api-registry.ts +223 -0
  416. package/src/engine/apis/index.ts +3 -7
  417. package/src/engine/apis/llamacpp-residency.ts +49 -9
  418. package/src/engine/apis/lmstudio-residency.ts +5 -21
  419. package/src/engine/apis/lmstudio.ts +243 -0
  420. package/src/engine/apis/ollama-native.ts +24 -3
  421. package/src/engine/apis/openai-completions.ts +170 -91
  422. package/src/engine/apis/residency.ts +139 -3
  423. package/src/engine/apis/types.ts +16 -0
  424. package/src/engine/env-api-keys.ts +98 -0
  425. package/src/engine/gemma-channel-filter.ts +223 -0
  426. package/src/engine/instrumented-tui.ts +192 -0
  427. package/src/engine/messages.ts +14 -0
  428. package/src/engine/models.ts +42 -0
  429. package/src/engine/oauth.ts +16 -12
  430. package/src/engine/prompt-templates.ts +1 -0
  431. package/src/engine/provider-payload.ts +16 -59
  432. package/src/engine/strip-tokenizer-sentinels.ts +1 -1
  433. package/src/engine/truncate.ts +9 -0
  434. package/src/engine/tui.ts +17 -9
  435. package/src/engine/types.ts +3 -6
  436. package/src/engine/worker-runtime-capabilities.ts +5 -0
  437. package/src/engine/worker-runtime.ts +1 -1
  438. package/src/engine/worker-tools.ts +9 -4
  439. package/src/entry/boot-options.ts +50 -0
  440. package/src/entry/orchestrator.ts +288 -150
  441. package/src/interactive/application-controller.ts +89 -2
  442. package/src/interactive/chat-loop.ts +266 -41
  443. package/src/interactive/chat-panel.ts +173 -47
  444. package/src/interactive/chat-renderer.ts +262 -72
  445. package/src/interactive/clio-editor.ts +3 -8
  446. package/src/interactive/command-fallbacks.ts +2 -2
  447. package/src/interactive/context-overlay.ts +27 -1
  448. package/src/interactive/editor-submit.ts +228 -24
  449. package/src/interactive/export-html/ansi-to-html.ts +161 -0
  450. package/src/interactive/export-html/index.ts +51 -0
  451. package/src/interactive/export-html/template.ts +45 -0
  452. package/src/interactive/export-html/tool-renderer.ts +54 -0
  453. package/src/interactive/footer/dashboard.ts +4 -0
  454. package/src/interactive/footer/notifications.ts +1 -1
  455. package/src/interactive/footer/widgets.ts +20 -2
  456. package/src/interactive/footer-panel.ts +2 -2
  457. package/src/interactive/format-time.ts +14 -2
  458. package/src/interactive/interactive-application.ts +201 -17
  459. package/src/interactive/interactive-event-projection.ts +6 -1
  460. package/src/interactive/interactive-input-runtime.ts +50 -4
  461. package/src/interactive/interactive-presentation.ts +151 -19
  462. package/src/interactive/interactive-shell.ts +268 -14
  463. package/src/interactive/interactive-slash-runtime.ts +176 -114
  464. package/src/interactive/interactive-tickers.ts +38 -7
  465. package/src/interactive/keybinding-manager.ts +1 -1
  466. package/src/interactive/layout.ts +40 -3
  467. package/src/interactive/overlay-frame.ts +1 -1
  468. package/src/interactive/overlay-general-openers.ts +58 -1
  469. package/src/interactive/overlay-key-routing.ts +3 -0
  470. package/src/interactive/overlay-lifecycle.ts +13 -0
  471. package/src/interactive/overlay-permission-lifecycle.ts +2 -1
  472. package/src/interactive/overlay-session-lifecycle.ts +69 -12
  473. package/src/interactive/overlays/decisions.ts +300 -0
  474. package/src/interactive/overlays/help-reference.ts +15 -10
  475. package/src/interactive/overlays/model-selector.ts +34 -16
  476. package/src/interactive/overlays/session-selector.ts +18 -0
  477. package/src/interactive/overlays/settings.ts +105 -17
  478. package/src/interactive/overlays/skills-hub.ts +4 -4
  479. package/src/interactive/overlays/tree-selector.ts +41 -6
  480. package/src/interactive/render-trace.ts +499 -90
  481. package/src/interactive/renderers/compaction-summary.ts +2 -2
  482. package/src/interactive/renderers/diff.ts +115 -104
  483. package/src/interactive/renderers/mermaid.ts +53 -0
  484. package/src/interactive/renderers/tool-execution.ts +386 -133
  485. package/src/interactive/renderers/worker-entry.ts +20 -4
  486. package/src/interactive/session-switch-settlement.ts +10 -0
  487. package/src/interactive/slash-autocomplete.ts +6 -114
  488. package/src/interactive/slash-commands.ts +135 -47
  489. package/src/interactive/slash-spec.ts +9 -38
  490. package/src/interactive/status/controller.ts +5 -1
  491. package/src/interactive/stdout-backpressure.ts +99 -0
  492. package/src/interactive/stream-pacer.ts +530 -0
  493. package/src/interactive/stream-pacing-policy.ts +66 -0
  494. package/src/interactive/tasks-overlay.ts +368 -14
  495. package/src/interactive/terminal-lease.ts +485 -0
  496. package/src/interactive/theme/tokens.ts +1 -1
  497. package/src/interactive/turn-context.ts +4 -3
  498. package/src/interactive/turn-persistence.ts +30 -13
  499. package/src/interactive/turn-queues.ts +12 -0
  500. package/src/interactive/turn-recovery.ts +25 -8
  501. package/src/interactive/turn-runtime.ts +79 -12
  502. package/src/interactive/turn-state.ts +10 -0
  503. package/src/interactive/view/artifacts.ts +114 -4
  504. package/src/interactive/view/view-overlay.ts +3 -0
  505. package/src/interactive/welcome-dashboard.ts +17 -16
  506. package/src/interactive/worker-receipts.ts +52 -3
  507. package/src/interactive/worker-stream.ts +5 -1
  508. package/src/tools/agent-tools.ts +23 -3
  509. package/src/tools/artifact.ts +2 -2
  510. package/src/tools/ask-user.ts +23 -13
  511. package/src/tools/bash.ts +30 -2
  512. package/src/tools/bootstrap.ts +34 -431
  513. package/src/tools/builtin-tool-catalog.ts +265 -0
  514. package/src/tools/codewiki/code-nav-surface.ts +29 -0
  515. package/src/tools/codewiki/code-nav.ts +8 -22
  516. package/src/tools/codewiki/shared.ts +41 -38
  517. package/src/tools/context/docs-engine.ts +14 -3
  518. package/src/tools/context/index.ts +107 -28
  519. package/src/tools/context/surface.ts +19 -0
  520. package/src/tools/core-bootstrap.ts +168 -0
  521. package/src/tools/credential-present.ts +5 -5
  522. package/src/tools/dispatch-admission.ts +533 -0
  523. package/src/tools/dispatch-background.ts +54 -0
  524. package/src/tools/dispatch-event-text.ts +6 -0
  525. package/src/tools/dispatch-plan.ts +9 -4
  526. package/src/tools/dispatch-run-events.ts +238 -0
  527. package/src/tools/dispatch-runner.ts +2370 -0
  528. package/src/tools/dispatch-scout-admission.ts +295 -0
  529. package/src/tools/dispatch-types.ts +77 -0
  530. package/src/tools/dispatch.ts +67 -3161
  531. package/src/tools/find.ts +4 -2
  532. package/src/tools/grep.ts +2 -2
  533. package/src/tools/lazy-tool.ts +60 -0
  534. package/src/tools/ledger.ts +3 -3
  535. package/src/tools/monitor-surface.ts +36 -0
  536. package/src/tools/monitor.ts +2 -32
  537. package/src/tools/observers.ts +2 -2
  538. package/src/tools/registry.ts +39 -27
  539. package/src/tools/safe-exec.ts +2 -2
  540. package/src/tools/steer-surface.ts +17 -0
  541. package/src/tools/steer.ts +2 -13
  542. package/src/tools/tasks.ts +108 -11
  543. package/src/tools/truncate.ts +25 -184
  544. package/src/tools/verify/frontend.ts +3 -1
  545. package/src/tools/verify/index.ts +3 -38
  546. package/src/tools/verify/surface.ts +46 -0
  547. package/src/tools/web-fetch-surface.ts +23 -0
  548. package/src/tools/web-fetch.ts +2 -20
  549. package/src/tools/write.ts +7 -2
  550. package/src/worker/entry.ts +39 -2
  551. package/src/worker/spec-contract.ts +26 -5
  552. package/dist/chunk-7SS2CTV2.js +0 -61361
  553. package/dist/chunk-DKGKUHFA.js +0 -924
  554. package/dist/chunk-GEP36Y4X.js +0 -12796
  555. package/dist/chunk-XYWBQRDM.js +0 -137
  556. package/dist/clio-BZVGEUFJ.js +0 -58
  557. package/dist/configure-S7S6F6CL.js +0 -32
  558. package/docs/html/agents_blueprint.html +0 -936
  559. package/docs/html/alcf_blueprint.html +0 -324
  560. package/docs/html/architecture_blueprint.html +0 -850
  561. package/docs/html/commands_blueprint.html +0 -939
  562. package/docs/html/config_knobs_audit_blueprint.html +0 -178
  563. package/docs/html/configuration_blueprint.html +0 -1080
  564. package/docs/html/context_blueprint.html +0 -603
  565. package/docs/html/documentation_blueprint.html +0 -832
  566. package/docs/html/environment_blueprint.html +0 -404
  567. package/docs/html/eval_blueprint.html +0 -743
  568. package/docs/html/evals_internal_blueprint.html +0 -190
  569. package/docs/html/evolution_blueprint.html +0 -674
  570. package/docs/html/extensions_blueprint.html +0 -2065
  571. package/docs/html/fleet_dispatch_blueprint.html +0 -286
  572. package/docs/html/index.html +0 -919
  573. package/docs/html/lifecycle_blueprint.html +0 -723
  574. package/docs/html/memory_blueprint.html +0 -699
  575. package/docs/html/middleware_blueprint.html +0 -664
  576. package/docs/html/models_blueprint.html +0 -2366
  577. package/docs/html/observability_blueprint.html +0 -683
  578. package/docs/html/provider_adapter_blueprint.html +0 -245
  579. package/docs/html/safety_blueprint.html +0 -1386
  580. package/docs/html/shared.css +0 -571
  581. package/docs/html/shared.js +0 -143
  582. package/docs/html/skills_blueprint.html +0 -671
  583. package/docs/html/soak_blueprint.html +0 -182
  584. package/docs/html/tool_usage_blueprint.html +0 -350
  585. package/docs/html/tools_blueprint.html +0 -2249
  586. package/docs/html/trace_blueprint.html +0 -235
  587. package/docs/html/tui_design_blueprint.html +0 -374
  588. package/docs/html/validation_blueprint.html +0 -961
  589. package/docs/html/worker_dispatch_blueprint.html +0 -231
  590. package/src/core/release.ts +0 -2
  591. package/src/domains/providers/runtimes/common/lmstudio-logger.ts +0 -32
  592. package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +0 -491
  593. package/src/engine/apis/lmstudio-native.ts +0 -1438
  594. package/src/engine/apis/thinking-replay.ts +0 -11
  595. package/src/tools/string-enum.ts +0 -15
@@ -1,14 +1,16 @@
1
1
  /**
2
2
  * Coalescing wrapper around chat events (slice 12.5d).
3
3
  *
4
- * Streaming responses fire `text_delta` / `thinking_delta` events at very
5
- * high frequency. The TUI's per-event `requestRender()` call rebuilt the
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
6
  * entire transcript on every delta, which scaled linearly with response
7
- * length and made long answers visibly lag. This wrapper applies every
8
- * event to the panel synchronously (so internal state stays consistent)
9
- * but defers `requestRender()` for delta events to a single coalesced
10
- * timer (~16ms = one frame at 60fps). Non-delta events render
11
- * synchronously so finalizers like `message_end` are never deferred.
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`.
12
14
  */
13
15
 
14
16
  import type {
@@ -26,6 +28,14 @@ import type {
26
28
  WorkerRunEntry,
27
29
  } from "../domains/session/entries.js";
28
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";
29
39
  import { wrapTextWithAnsi } from "../engine/tui.js";
30
40
  import type { AgentMessage } from "../engine/types.js";
31
41
  import type { ChatLoopEvent, RetryStatusPayload } from "./chat-loop.js";
@@ -35,8 +45,15 @@ import { renderBranchSummaryEntry } from "./renderers/branch-summary.js";
35
45
  import { renderCompactionSummaryEntry } from "./renderers/compaction-summary.js";
36
46
  import { styleTaggedNotice } from "./renderers/notice.js";
37
47
  import { formatRetryStatus } from "./renderers/retry-status.js";
38
- import { renderToolResultOnly } from "./renderers/tool-execution.js";
39
- import { readWorkerReceiptFacts } from "./worker-receipts.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";
40
57
  import { workerEntriesFromRunEntries } from "./worker-replay.js";
41
58
  import type { WorkerReceiptReader } from "./worker-stream.js";
42
59
 
@@ -47,7 +64,28 @@ const MAX_REPLAY_TEXT_CHARS = 20_000;
47
64
  * Event kinds whose render is deferred into a coalesce window. All other
48
65
  * `ChatLoopEvent` kinds render synchronously and cancel any pending timer.
49
66
  */
50
- const DELTA_TYPES: ReadonlySet<ChatLoopEvent["type"]> = new Set(["text_delta", "thinking_delta"]);
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
+ }
51
89
 
52
90
  export interface CreateCoalescingChatRendererDeps {
53
91
  chatPanel: ChatPanel;
@@ -58,14 +96,35 @@ export interface CreateCoalescingChatRendererDeps {
58
96
  setTimer?: (cb: () => void, ms: number) => unknown;
59
97
  /** Override for tests. Mirrors the clearTimeout signature. */
60
98
  clearTimer?: (id: unknown) => void;
61
- /** Opt-in instrument; counts deltas so a frame row can report how many it absorbed. */
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. */
62
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>;
63
113
  }
64
114
 
65
115
  export interface CoalescingChatRenderer {
66
116
  applyEvent(event: ChatLoopEvent): void;
67
117
  /** Cancel the pending coalesce timer (if any) and request one synchronous render. */
68
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;
69
128
  }
70
129
 
71
130
  export function createCoalescingChatRenderer(deps: CreateCoalescingChatRendererDeps): CoalescingChatRenderer {
@@ -78,8 +137,13 @@ export function createCoalescingChatRenderer(deps: CreateCoalescingChatRendererD
78
137
  const coalesceMs = deps.coalesceMs ?? DEFAULT_COALESCE_MS;
79
138
 
80
139
  let pendingTimer: unknown = null;
140
+ let mutationDepth = 0;
141
+ let transactionNeedsRender = false;
142
+ let disposed = false;
143
+ let pacer: StreamPacer | null = null;
81
144
 
82
145
  const fireCoalesced = (): void => {
146
+ if (disposed) return;
83
147
  pendingTimer = null;
84
148
  deps.requestRender();
85
149
  };
@@ -91,24 +155,165 @@ export function createCoalescingChatRenderer(deps: CreateCoalescingChatRendererD
91
155
  return true;
92
156
  };
93
157
 
94
- return {
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 = {
95
230
  applyEvent(event) {
96
- deps.chatPanel.applyEvent(event);
97
- if (DELTA_TYPES.has(event.type)) {
98
- deps.onDelta?.();
99
- if (pendingTimer !== null) return;
100
- pendingTimer = setTimer(fireCoalesced, coalesceMs);
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);
101
237
  return;
102
238
  }
103
- cancelPending();
104
- deps.requestRender();
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
+ });
105
275
  },
106
276
  flush() {
277
+ if (disposed) return;
278
+ transaction(() => drainPacer("explicit-flush"));
107
279
  const wasPending = cancelPending();
108
- if (!wasPending) return;
109
- deps.requestRender();
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;
110
314
  },
111
315
  };
316
+ return renderer;
112
317
  }
113
318
 
114
319
  /**
@@ -499,30 +704,20 @@ function appendReplayLine(chatPanel: ChatPanel, text: string): void {
499
704
  chatPanel.appendReplayBlock((width) => renderReplayLine(truncateReplayText(text), width));
500
705
  }
501
706
 
502
- const BASH_REPLAY_MAX_LINES = 12;
503
-
504
- export function renderBashExecutionEntry(entry: BashExecutionEntry, width: number): string[] {
505
- const lines: string[] = [];
506
- lines.push(...wrapTextWithAnsi(`bash: $ ${entry.command}`, width));
507
- const output = truncateReplayText(entry.output.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\s+$/g, ""));
508
- if (output.length > 0) {
509
- const outputLines = output.split("\n");
510
- const hidden = Math.max(0, outputLines.length - BASH_REPLAY_MAX_LINES);
511
- const visible = outputLines.slice(-BASH_REPLAY_MAX_LINES);
512
- if (hidden > 0) lines.push(...wrapTextWithAnsi(` ... ${hidden} earlier lines`, width));
513
- for (const line of visible) {
514
- lines.push(...wrapTextWithAnsi(` ${line}`, width));
515
- }
516
- } else {
517
- lines.push(...wrapTextWithAnsi(" (no output)", width));
518
- }
519
- const status: string[] = [];
520
- if (entry.cancelled) status.push("cancelled");
521
- if (entry.exitCode !== null && entry.exitCode !== 0) status.push(`exit ${entry.exitCode}`);
522
- if (entry.truncated) status.push(entry.fullOutputPath ? `truncated: ${entry.fullOutputPath}` : "truncated");
523
- if (entry.excludeFromContext) status.push("excluded from context");
524
- if (status.length > 0) lines.push(...wrapTextWithAnsi(` (${status.join(", ")})`, width));
525
- return lines;
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
+ );
526
721
  }
527
722
 
528
723
  function renderRetryStatusEntry(entry: CustomEntry, width: number): string[] {
@@ -746,33 +941,26 @@ function dropLegacyToolResultAssistantDuplicates(entries: ReadonlyArray<SessionE
746
941
  }
747
942
 
748
943
  function compactionContextText(entry: CompactionSummaryEntry): string {
749
- return [
750
- "The conversation history before this point was compacted into the following summary:",
751
- "",
752
- "<summary>",
753
- entry.summary,
754
- "</summary>",
755
- ].join("\n");
944
+ return `${COMPACTION_SUMMARY_PREFIX}${entry.summary}${COMPACTION_SUMMARY_SUFFIX}`;
756
945
  }
757
946
 
758
947
  function branchContextText(entry: BranchSummaryEntry): string {
759
- return [
760
- "The following is a summary of a branch that this conversation came back from:",
761
- "",
762
- "<summary>",
763
- entry.summary,
764
- "</summary>",
765
- ].join("\n");
948
+ return `${BRANCH_SUMMARY_PREFIX}${entry.summary}${BRANCH_SUMMARY_SUFFIX}`;
766
949
  }
767
950
 
951
+ /** Project Clio's ledger entry onto pi's bash message so pi owns the replay wording. */
768
952
  function bashContextText(entry: BashExecutionEntry): string {
769
- let text = `Ran \`${entry.command}\`\n`;
770
- const output = truncateReplayText(entry.output);
771
- text += output.length > 0 ? `\`\`\`\n${output}\n\`\`\`` : "(no output)";
772
- if (entry.cancelled) text += "\n\n(command cancelled)";
773
- else if (entry.exitCode !== null && entry.exitCode !== 0) text += `\n\nCommand exited with code ${entry.exitCode}`;
774
- if (entry.truncated && entry.fullOutputPath) text += `\n\n[Output truncated. Full output: ${entry.fullOutputPath}]`;
775
- return text;
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);
776
964
  }
777
965
 
778
966
  function appendContextMessage(out: AgentMessage[], role: "user" | "assistant", text: string, timestamp: string): void {
@@ -838,6 +1026,7 @@ export function buildReplayAgentMessagesFromTurns(
838
1026
  case "label":
839
1027
  case "protectedArtifact":
840
1028
  case "taskLedger":
1029
+ case "decisionLedger":
841
1030
  // A worker's answer is not the operator's words and not the model's.
842
1031
  // It reaches the model only when an operator shares it, and a share
843
1032
  // is already a user message by the time it lands in the ledger.
@@ -883,7 +1072,7 @@ export function rehydrateChatPanelFromTurns(
883
1072
  // a failover replays as the one run it was rather than as two.
884
1073
  const workerStates = workerEntriesFromRunEntries(
885
1074
  selected.filter((entry): entry is WorkerRunEntry => entry.kind === "workerRun"),
886
- options.readWorkerReceipt ?? readWorkerReceiptFacts,
1075
+ options.readWorkerReceipt ?? readWorkerReceiptFactsForReplay,
887
1076
  );
888
1077
  const placedAssignments = new Set<string>();
889
1078
  for (const entry of selected) {
@@ -918,6 +1107,7 @@ export function rehydrateChatPanelFromTurns(
918
1107
  toolName: call.name,
919
1108
  args: call.args,
920
1109
  });
1110
+ chatPanel.markToolReplayed?.(call.id);
921
1111
  break;
922
1112
  }
923
1113
  if (entry.role === "tool_result") {
@@ -1017,6 +1207,7 @@ export function rehydrateChatPanelFromTurns(
1017
1207
  }
1018
1208
  case "label":
1019
1209
  case "taskLedger":
1210
+ case "decisionLedger":
1020
1211
  break;
1021
1212
  }
1022
1213
  }
@@ -1029,10 +1220,9 @@ export function rehydrateChatPanelFromTurns(
1029
1220
  isError: true,
1030
1221
  });
1031
1222
  }
1032
- // Replay reproduces the settled view: tools collapse to their one-line
1033
- // ledger summary. The live path collapses tools because they fire while the
1034
- // assistant is streaming (pending), a state replay cannot reconstruct
1035
- // per-tool, so collapse them explicitly here. /export re-expands afterward
1036
- // via toggleAllToolsExpanded; /resume and /fork keep the collapsed form.
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.
1037
1227
  chatPanel.collapseAllTools();
1038
1228
  }
@@ -1,18 +1,13 @@
1
- import { Editor, type TUI, truncateToWidth, visibleWidth } from "../engine/tui.js";
1
+ import { Editor, stripTerminalSequences, type TUI, truncateToWidth, visibleWidth } from "../engine/tui.js";
2
2
  import type { ClioTheme } from "./theme/index.js";
3
3
  import { clioTheme, editorTheme, GLYPH, rule } from "./theme/index.js";
4
4
 
5
- const ANSI = new RegExp(`${String.fromCharCode(27)}\\[[0-9;?]*[A-Za-z]`, "g");
6
5
  const REVERSE_VIDEO_BLANK = `${String.fromCharCode(27)}[7m ${String.fromCharCode(27)}[0m`;
7
6
  const EMPTY_PROMPT = "Ask Clio… / for commands";
8
7
  const MIN_HINT_WIDTH = 60;
9
8
 
10
- function stripAnsi(text: string): string {
11
- return text.replace(ANSI, "");
12
- }
13
-
14
9
  function hasScrollIndicator(line: string): boolean {
15
- const stripped = stripAnsi(line);
10
+ const stripped = stripTerminalSequences(line);
16
11
  return stripped.includes(GLYPH.up) || stripped.includes(GLYPH.down);
17
12
  }
18
13
 
@@ -91,7 +86,7 @@ function renderEmptyPrompt(line: string, width: number, theme: ClioTheme): strin
91
86
  function findBottomRail(lines: readonly string[], width: number): number {
92
87
  const rail = "─".repeat(Math.max(0, width));
93
88
  for (let index = 1; index < lines.length; index += 1) {
94
- if (stripAnsi(lines[index] ?? "") === rail) return index;
89
+ if (stripTerminalSequences(lines[index] ?? "") === rail) return index;
95
90
  }
96
91
  return -1;
97
92
  }
@@ -12,12 +12,12 @@ export function runCompactWithNotice(
12
12
  instructions: string | undefined,
13
13
  ): void {
14
14
  if (!onCompact) {
15
- emitCommandNotice(notice, "error", "compact", "compaction not wired; pass onCompact to startInteractive");
15
+ emitCommandNotice(notice, "error", "context compact", "compaction not wired; pass onCompact to startInteractive");
16
16
  return;
17
17
  }
18
18
  const task = onCompact(instructions);
19
19
  void task.catch((err) => {
20
20
  const msg = err instanceof Error ? err.message : String(err);
21
- emitCommandNotice(notice, "error", "compact", msg);
21
+ emitCommandNotice(notice, "error", "context compact", msg);
22
22
  });
23
23
  }
@@ -1,3 +1,5 @@
1
+ import { homedir } from "node:os";
2
+ import { relative } from "node:path";
1
3
  import { BusChannels } from "../core/bus-events.js";
2
4
  import type { SafeEventBus } from "../core/event-bus.js";
3
5
  import type { ContextLedger, ContextLedgerGroup } from "../domains/session/context-ledger.js";
@@ -40,6 +42,27 @@ function contextWindowProvenanceLabel(source: ContextLedger["contextWindowSource
40
42
  }
41
43
  }
42
44
 
45
+ /** A handbook path the operator can read at a glance: workspace-relative when
46
+ * the file sits under the current directory, `~`-shortened otherwise. */
47
+ function displayHandbookPath(filePath: string): string {
48
+ const rel = relative(process.cwd(), filePath);
49
+ if (rel.length > 0 && !rel.startsWith("..")) return rel;
50
+ const home = homedir();
51
+ return home.length > 0 && filePath.startsWith(`${home}/`) ? `~${filePath.slice(home.length)}` : filePath;
52
+ }
53
+
54
+ /**
55
+ * Which CLIO-CODER*.md file(s) the compiled prompt actually selected. With
56
+ * override semantics the operator cannot infer the winner from the preload
57
+ * size alone, so the effective chain is named explicitly, nearest last.
58
+ */
59
+ function handbookProvenanceLines(handbookFiles: ReadonlyArray<string> | null): string[] {
60
+ if (!handbookFiles || handbookFiles.length === 0) return [];
61
+ const first = handbookFiles[0];
62
+ if (handbookFiles.length === 1 && first !== undefined) return [`handbook: ${displayHandbookPath(first)}`];
63
+ return ["handbooks (ancestor → nearest):", ...handbookFiles.map((filePath) => ` ${displayHandbookPath(filePath)}`)];
64
+ }
65
+
43
66
  function gridDimensions(ledger: ContextLedger, contentWidth: number): { cols: number; rows: number } {
44
67
  const cols = Math.max(12, Math.min(contentWidth, 40));
45
68
  const rows = ledger.contextWindow >= 200_000 ? 8 : 6;
@@ -58,7 +81,7 @@ function legendRow(group: ContextLedgerGroup, contentWidth: number): string {
58
81
  return `${swatch} ${theme.fg(labelToken, labelText)} ${theme.fg("muted", right)}`;
59
82
  }
60
83
 
61
- function renderContextLedgerLines(ledger: ContextLedger, contentWidth: number): string[] {
84
+ export function renderContextLedgerLines(ledger: ContextLedger, contentWidth: number): string[] {
62
85
  const theme = clioTheme();
63
86
  const lines: string[] = [];
64
87
 
@@ -92,6 +115,9 @@ function renderContextLedgerLines(ledger: ContextLedger, contentWidth: number):
92
115
  if (ledger.projectPreload && ledger.groups.some((group) => group.category === "project")) {
93
116
  lines.push(theme.fg("dim", `project preload: ${ledger.projectPreload}`));
94
117
  }
118
+ for (const handbookLine of handbookProvenanceLines(ledger.projectHandbookFiles)) {
119
+ lines.push(theme.fg("dim", handbookLine));
120
+ }
95
121
  const compaction =
96
122
  ledger.compactionThreshold !== null
97
123
  ? `autocompact at ${Math.round(ledger.compactionThreshold * 100)}% (${ledger.compactionAuto ? "auto" : "manual"})`