@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
@@ -17,8 +17,10 @@ import {
17
17
  } from "../domains/providers/index.js";
18
18
  import type { ResourcesContract } from "../domains/resources/index.js";
19
19
  import { installSkill } from "../domains/resources/skills/marketplace.js";
20
- import type { SessionEntry } from "../domains/session/index.js";
20
+ import type { SessionContract, SessionEntry } from "../domains/session/index.js";
21
21
  import type { ShareContract } from "../domains/share/index.js";
22
+ import type { UserTasksStore } from "../domains/user-tasks/store.js";
23
+ import { stripTerminalSequences } from "../engine/tui.js";
22
24
  import type { ImageContent } from "../engine/types.js";
23
25
  import type { AskUserHandler } from "../tools/ask-user.js";
24
26
  import type { ChatLoop } from "./chat-loop.js";
@@ -26,6 +28,7 @@ import { type ChatPanel, createChatPanel } from "./chat-panel.js";
26
28
  import { rehydrateChatPanelFromTurns } from "./chat-renderer.js";
27
29
  import { runCompactWithNotice } from "./command-fallbacks.js";
28
30
  import { appendNotice, appendOperatorCommand } from "./command-output.js";
31
+ import { renderSessionHtml } from "./export-html/index.js";
29
32
  import { dateLocal } from "./format-time.js";
30
33
  import type { SettingsCenterRowId, SettingsSectionId } from "./overlays/settings.js";
31
34
  import {
@@ -35,18 +38,13 @@ import {
35
38
  parseSlashCommand,
36
39
  type RunIo,
37
40
  type SlashCommandContext,
41
+ type SlashCommandDispatchResult,
38
42
  type TaskMemorySeedCommandResult,
39
43
  } from "./slash-commands.js";
40
44
  import { verifyReceiptFile } from "./view/artifacts.js";
41
45
  import type { WorkerEntryState } from "./worker-stream.js";
42
46
 
43
47
  const EXPORT_RENDER_WIDTH = 100;
44
- // biome-ignore lint/suspicious/noControlCharactersInRegex: the ESC control character is the ANSI escape introducer this pattern exists to strip
45
- const ANSI_PATTERN = /\u001b\[[0-9;?]*[A-Za-z]/g;
46
-
47
- function stripAnsiForExport(line: string): string {
48
- return line.replace(ANSI_PATTERN, "");
49
- }
50
48
 
51
49
  export interface InteractiveSlashSubmitExpansion {
52
50
  text: string;
@@ -74,6 +72,7 @@ export interface InteractiveSlashRuntimeDeps {
74
72
  interop?: SlashCommandContext["interop"];
75
73
  agents?: SlashAgents;
76
74
  share?: SlashShare;
75
+ userTasks?: UserTasksStore;
77
76
  getSettings?: () => Readonly<ClioSettings>;
78
77
  writeSettings?: (next: ClioSettings) => void;
79
78
  /**
@@ -91,16 +90,25 @@ export interface InteractiveSlashRuntimeDeps {
91
90
  stateDir: string;
92
91
  shutdown: () => void | Promise<void>;
93
92
  requestRender: () => void;
93
+ beforeSemanticSubmit?: () => void;
94
+ settleVisibleFrame?: (reason: string) => Promise<void>;
94
95
  refreshFooter: () => void;
95
96
  dismissContextBootstrapNotices: () => void;
96
97
  recordSubmittedTurn: () => void;
97
98
  readStructuredEntries: (sessionId: string) => ReadonlyArray<SessionEntry>;
99
+ /**
100
+ * Leaf lookup for `/export`, so the export follows the branch the session
101
+ * is actually on. current.jsonl still holds the abandoned turns after a
102
+ * `/tree` pin, and an unscoped rehydrate reproduced them (issue #109).
103
+ */
104
+ session?: Pick<SessionContract, "tree">;
98
105
  expandSubmit: (text: string) => Promise<InteractiveSlashSubmitExpansion>;
99
106
  openAskUser: AskUserHandler;
100
107
  openSkillsHub: () => void;
101
108
  openCost: () => void;
102
109
  openContextView: () => void;
103
110
  openTasks: () => void;
111
+ openDecisions: () => void;
104
112
  openMemory: () => void;
105
113
  seedTaskMemory?: () => TaskMemorySeedCommandResult;
106
114
  openView: (filter?: string) => void;
@@ -128,7 +136,9 @@ export interface InteractiveSlashRuntimeDeps {
128
136
  export interface InteractiveSlashRuntime {
129
137
  context: SlashCommandContext;
130
138
  notice: SlashCommandContext["notice"];
131
- dispatchCommand(text: string): void;
139
+ dispatchCommand(text: string): SlashCommandDispatchResult;
140
+ /** Admit captured Stage 0 input without waiting for the model turn to finish. */
141
+ admitCommand(text: string, signal?: AbortSignal): Promise<void>;
132
142
  }
133
143
 
134
144
  /** Owns slash-command context construction and its asynchronous command state. */
@@ -166,8 +176,11 @@ export function resolveAvailableThinkingLevels(
166
176
 
167
177
  export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps): InteractiveSlashRuntime {
168
178
  let activeContextInit = false;
179
+ let latestAdmission: Promise<void> = Promise.resolve();
180
+ let activeAdmissionSignal: AbortSignal | undefined;
169
181
  const cwd = (): string => deps.getCwd?.() ?? process.cwd();
170
182
  const resources = deps.resources;
183
+ const userTasks = deps.userTasks;
171
184
 
172
185
  const appendCommandNotice: SlashCommandContext["notice"] = (level, text) => {
173
186
  appendNotice(level, text, {
@@ -177,31 +190,107 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
177
190
  };
178
191
 
179
192
  /** One expanded operator turn into the chat loop: record it, paint it, submit it. */
180
- const submitExpanded = (sub: InteractiveSlashSubmitExpansion): void => {
181
- void (async () => {
182
- try {
183
- // Enter while streaming becomes a steer inside chat.submit. The
184
- // queue panel shows it until the engine injects it, and the
185
- // injection emits queued_user_turn, which is when the transcript
186
- // renders it. Appending here too showed the text twice and at
187
- // the wrong point in the turn's order.
188
- const willQueue = deps.chat.isStreaming();
189
- deps.recordSubmittedTurn();
190
- deps.refreshFooter();
191
- if (!willQueue) deps.chatPanel.appendUser(sub.text);
192
- deps.requestRender();
193
- await deps.chat.submit(sub.text, {
194
- ...(sub.images.length > 0 ? { images: sub.images } : {}),
195
- ...(sub.workingContextPaths.length > 0 ? { workingContextPaths: sub.workingContextPaths } : {}),
196
- ...(sub.pendingSkillRequests.length > 0 ? { pendingSkillRequests: sub.pendingSkillRequests } : {}),
197
- });
198
- } catch (err) {
199
- const msg = err instanceof Error ? err.message : String(err);
200
- deps.io.stderr(`[interactive] chat failed: ${msg}\n`);
201
- } finally {
202
- deps.requestRender();
193
+ const submitExpanded = (sub: InteractiveSlashSubmitExpansion, awaitAdmission = false): Promise<void> => {
194
+ try {
195
+ // Enter while streaming becomes a steer inside chat.submit. The
196
+ // queue panel shows it until the engine injects it, and the
197
+ // injection emits queued_user_turn, which is when the transcript
198
+ // renders it. Appending here too showed the text twice and at
199
+ // the wrong point in the turn's order.
200
+ const willQueue = deps.chat.isStreaming();
201
+ deps.recordSubmittedTurn();
202
+ deps.refreshFooter();
203
+ if (!willQueue) deps.chatPanel.appendUser(sub.text);
204
+ deps.requestRender();
205
+ deps.beforeSemanticSubmit?.();
206
+ let acknowledgeAdmission = (): void => {};
207
+ const admitted = new Promise<void>((resolve) => {
208
+ acknowledgeAdmission = resolve;
209
+ });
210
+ const turn = deps.chat.submit(sub.text, {
211
+ ...(sub.images.length > 0 ? { images: sub.images } : {}),
212
+ ...(sub.workingContextPaths.length > 0 ? { workingContextPaths: sub.workingContextPaths } : {}),
213
+ ...(sub.pendingSkillRequests.length > 0 ? { pendingSkillRequests: sub.pendingSkillRequests } : {}),
214
+ ...(awaitAdmission && willQueue ? { steering: "end-of-turn" as const } : {}),
215
+ ...(awaitAdmission ? { onAdmitted: acknowledgeAdmission } : {}),
216
+ });
217
+ const settlement = turn
218
+ .then(() => deps.settleVisibleFrame?.("submit-return"))
219
+ .catch((err) => {
220
+ const msg = err instanceof Error ? err.message : String(err);
221
+ deps.io.stderr(`[interactive] chat failed: ${msg}\n`);
222
+ })
223
+ .finally(deps.requestRender);
224
+ return awaitAdmission ? Promise.race([admitted, settlement]) : settlement;
225
+ } catch (err) {
226
+ const msg = err instanceof Error ? err.message : String(err);
227
+ deps.io.stderr(`[interactive] chat failed: ${msg}\n`);
228
+ deps.requestRender();
229
+ return Promise.resolve();
230
+ }
231
+ };
232
+
233
+ const admitChat = async (text: string, signal?: AbortSignal): Promise<void> => {
234
+ try {
235
+ signal?.throwIfAborted();
236
+ const submitted = await deps.expandSubmit(text);
237
+ signal?.throwIfAborted();
238
+ const uninstalled = submitted.pendingSkillRequests.find((request) => !request.installed);
239
+ if (uninstalled && !uninstalled.marketplaceRef) {
240
+ deps.io.stderr(`Skill "${uninstalled.name}" is not installed and no local marketplace entry is available.\n`);
241
+ return;
203
242
  }
204
- })();
243
+ if (uninstalled) {
244
+ void deps
245
+ .openAskUser([
246
+ {
247
+ question: `Skill "${uninstalled.name}" is not installed. Would you like to install it?`,
248
+ options: [
249
+ { label: "Install and run", description: `Install from ${uninstalled.marketplaceRef}` },
250
+ { label: "Cancel", description: "Do not install." },
251
+ ],
252
+ },
253
+ ])
254
+ .then((res) => {
255
+ if (res.cancelled || res.answers[0]?.answer !== "Install and run") {
256
+ deps.io.stderr("Installation cancelled.\n");
257
+ return;
258
+ }
259
+ void (async () => {
260
+ try {
261
+ deps.io.stdout(`Installing skill "${uninstalled.name}"...\n`);
262
+ let configDir: string | undefined;
263
+ try {
264
+ configDir = (deps.getConfigDir ?? clioConfigDir)();
265
+ } catch (configErr) {
266
+ deps.io.stderr(
267
+ `Skill install: config dir unavailable (${configErr instanceof Error ? configErr.message : String(configErr)}); continuing without it.\n`,
268
+ );
269
+ }
270
+ (deps.installSkill ?? installSkill)({
271
+ source: uninstalled.name,
272
+ cwd: cwd(),
273
+ ...(configDir ? { configDir } : {}),
274
+ });
275
+ deps.io.stdout(`Successfully installed "${uninstalled.name}"!\n`);
276
+ await deps.resources?.reload();
277
+ const postInstallSubmitted = await deps.expandSubmit(text);
278
+ submitExpanded(postInstallSubmitted);
279
+ } catch (err) {
280
+ deps.io.stderr(
281
+ `Failed to install skill "${uninstalled.name}": ${err instanceof Error ? err.message : String(err)}\n`,
282
+ );
283
+ }
284
+ })();
285
+ });
286
+ return;
287
+ }
288
+ await submitExpanded(submitted, true);
289
+ } catch (err) {
290
+ const msg = err instanceof Error ? err.message : String(err);
291
+ deps.io.stderr(`[interactive] chat failed: ${msg}\n`);
292
+ deps.requestRender();
293
+ }
205
294
  };
206
295
  const context: SlashCommandContext = {
207
296
  io: deps.io,
@@ -251,6 +340,17 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
251
340
  openCost: deps.openCost,
252
341
  openContextView: deps.openContextView,
253
342
  openTasks: deps.openTasks,
343
+ openDecisions: deps.openDecisions,
344
+ ...(userTasks
345
+ ? {
346
+ userTasks: {
347
+ add: (title: string) => userTasks.add(title),
348
+ hand: (id: string) => userTasks.hand(id, deps.chat.getSessionId() ?? undefined),
349
+ done: (id: string) => userTasks.done(id),
350
+ drop: (id: string) => userTasks.drop(id),
351
+ },
352
+ }
353
+ : {}),
254
354
  openMemory: deps.openMemory,
255
355
  seedTaskMemory: () => {
256
356
  const result = deps.seedTaskMemory?.() ?? { status: "not-found" as const };
@@ -333,32 +433,43 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
333
433
  }
334
434
  try {
335
435
  const turns = deps.readStructuredEntries(sessionId);
336
- // Same pure render pipeline as the live panel and /resume replay:
337
- // a throwaway panel rehydrated from the ledger, every tool segment
338
- // expanded, rendered at a fixed width, ANSI stripped. Unlike the
339
- // live view, export renders full tool bodies (no middle-elision or
340
- // char truncation) so the transcript reproduces the complete output.
436
+ // Same pure render pipeline as the live panel and /resume replay: a
437
+ // throwaway panel is rehydrated from the ledger, every tool segment is
438
+ // expanded, and the transcript is rendered at a stable width. HTML
439
+ // converts the resulting ANSI presentation to inline styles; Markdown
440
+ // keeps the prior plain-text fenced transcript.
341
441
  const exportPanel = createChatPanel({ unboundedToolBodies: true });
342
- rehydrateChatPanelFromTurns(exportPanel, turns, { unboundedToolBodies: true });
442
+ // Scoped to the leaf the session is on, the same way /resume replays
443
+ // (issue #107): with a /tree pin persisted and not yet extended, the
444
+ // file still holds the abandoned branch after the pin, and an unscoped
445
+ // rehydrate exported it as ordinary history (issue #109). No session
446
+ // contract means no pin can exist for this reader, so the file replays whole.
447
+ const leafTurnId = deps.session?.tree(sessionId).leafId ?? null;
448
+ rehydrateChatPanelFromTurns(exportPanel, turns, {
449
+ unboundedToolBodies: true,
450
+ ...(leafTurnId ? { activeLeafTurnId: leafTurnId } : {}),
451
+ });
343
452
  exportPanel.toggleAllToolsExpanded();
344
- const lines = exportPanel.render(EXPORT_RENDER_WIDTH).map(stripAnsiForExport);
453
+ const ansiLines = exportPanel.render(EXPORT_RENDER_WIDTH);
345
454
  // The operator names this file by the day they ran the export, so the
346
455
  // date in it is their calendar date. The header below keeps the ISO
347
456
  // instant, which is the machine-readable half of the same fact.
348
- const date = dateLocal(deps.now?.() ?? new Date());
457
+ const exportedAt = deps.now?.() ?? new Date();
458
+ const date = dateLocal(exportedAt);
459
+ const requestedPath = pathArg?.trim() ?? "";
460
+ const markdown = requestedPath.toLowerCase().endsWith(".md");
349
461
  const target = resolve(
350
- pathArg && pathArg.trim().length > 0 ? pathArg.trim() : join(".clio-coder", "exports", `${sessionId}-${date}.md`),
462
+ requestedPath.length > 0 ? requestedPath : join(".clio-coder", "exports", `${sessionId}-${date}.html`),
351
463
  );
352
464
  mkdirSync(resolve(target, ".."), { recursive: true });
353
- const header = [
354
- `# Clio session ${sessionId}`,
355
- "",
356
- `Exported ${(deps.now?.() ?? new Date()).toISOString()}`,
357
- "",
358
- "```text",
359
- ];
360
- writeFileSync(target, `${[...header, ...lines, "```", ""].join("\n")}`, "utf8");
361
- appendCommandNotice("success", `[/export] wrote ${lines.length} lines to ${target}`);
465
+ if (markdown) {
466
+ const lines = ansiLines.map(stripTerminalSequences);
467
+ const header = [`# Clio session ${sessionId}`, "", `Exported ${exportedAt.toISOString()}`, "", "```text"];
468
+ writeFileSync(target, `${[...header, ...lines, "```", ""].join("\n")}`, "utf8");
469
+ } else {
470
+ writeFileSync(target, renderSessionHtml({ sessionId, exportedAt: exportedAt.toISOString(), ansiLines }), "utf8");
471
+ }
472
+ appendCommandNotice("success", `[/export] wrote ${ansiLines.length} lines to ${target}`);
362
473
  } catch (err) {
363
474
  appendCommandNotice("error", `[/export] ${err instanceof Error ? err.message : String(err)}`);
364
475
  }
@@ -416,70 +527,8 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
416
527
  // worker's output name a file the operator never mentioned.
417
528
  submitOperatorNote: (text) => submitExpanded({ text, images: [], workingContextPaths: [], pendingSkillRequests: [] }),
418
529
  submitChat: (text) => {
419
- void (async () => {
420
- try {
421
- const submitted = await deps.expandSubmit(text);
422
- const uninstalled = submitted.pendingSkillRequests.find((request) => !request.installed);
423
- if (uninstalled && !uninstalled.marketplaceRef) {
424
- deps.io.stderr(`Skill "${uninstalled.name}" is not installed and no local marketplace entry is available.\n`);
425
- return;
426
- }
427
- if (uninstalled) {
428
- void deps
429
- .openAskUser([
430
- {
431
- question: `Skill "${uninstalled.name}" is not installed. Would you like to install it?`,
432
- options: [
433
- {
434
- label: "Install and run",
435
- description: `Install from ${uninstalled.marketplaceRef}`,
436
- },
437
- { label: "Cancel", description: "Do not install." },
438
- ],
439
- },
440
- ])
441
- .then((res) => {
442
- if (res.cancelled || res.answers[0]?.answer !== "Install and run") {
443
- deps.io.stderr("Installation cancelled.\n");
444
- return;
445
- }
446
- void (async () => {
447
- try {
448
- deps.io.stdout(`Installing skill "${uninstalled.name}"...\n`);
449
- let configDir: string | undefined;
450
- try {
451
- configDir = (deps.getConfigDir ?? clioConfigDir)();
452
- } catch (configErr) {
453
- deps.io.stderr(
454
- `Skill install: config dir unavailable (${configErr instanceof Error ? configErr.message : String(configErr)}); continuing without it.\n`,
455
- );
456
- }
457
- (deps.installSkill ?? installSkill)({
458
- source: uninstalled.name,
459
- cwd: cwd(),
460
- ...(configDir ? { configDir } : {}),
461
- });
462
- deps.io.stdout(`Successfully installed "${uninstalled.name}"!\n`);
463
- await deps.resources?.reload();
464
- const postInstallSubmitted = await deps.expandSubmit(text);
465
- submitExpanded(postInstallSubmitted);
466
- } catch (err) {
467
- deps.io.stderr(
468
- `Failed to install skill "${uninstalled.name}": ${err instanceof Error ? err.message : String(err)}\n`,
469
- );
470
- }
471
- })();
472
- });
473
- return;
474
- }
475
-
476
- submitExpanded(submitted);
477
- } catch (err) {
478
- const msg = err instanceof Error ? err.message : String(err);
479
- deps.io.stderr(`[interactive] chat failed: ${msg}\n`);
480
- deps.requestRender();
481
- }
482
- })();
530
+ latestAdmission = admitChat(text, activeAdmissionSignal);
531
+ void latestAdmission;
483
532
  },
484
533
  render: deps.requestRender,
485
534
  };
@@ -488,5 +537,18 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
488
537
  context,
489
538
  notice: appendCommandNotice,
490
539
  dispatchCommand: (text) => dispatchSlashCommand(parseSlashCommand(text), context),
540
+ admitCommand: async (text, signal) => {
541
+ signal?.throwIfAborted();
542
+ const command = parseSlashCommand(text);
543
+ const before = latestAdmission;
544
+ const previousSignal = activeAdmissionSignal;
545
+ activeAdmissionSignal = signal;
546
+ try {
547
+ dispatchSlashCommand(command, context);
548
+ } finally {
549
+ activeAdmissionSignal = previousSignal;
550
+ }
551
+ if (latestAdmission !== before) await latestAdmission;
552
+ },
491
553
  };
492
554
  }
@@ -1,10 +1,12 @@
1
+ import { type TaskBoardSnapshot, type TaskBoardStore, taskBoardCounts } from "../domains/session/task-board.js";
1
2
  import { Text, type TUI, visibleWidth } from "../engine/tui.js";
2
3
  import {
3
4
  CONTEXT_ISLAND_WIDTH,
4
5
  type ContextActivitySnapshot,
5
6
  formatContextActivityIslandLines,
6
7
  } from "./context-activity.js";
7
- import { type DispatchBoardRow, formatTaskIslandLines } from "./dispatch-board.js";
8
+ import { type DispatchBoardRow, formatTaskIslandLines, TASK_ISLAND_WIDTH } from "./dispatch-board.js";
9
+ import { clioTheme, frame, GLYPH } from "./theme/index.js";
8
10
 
9
11
  export interface InteractiveTickerHandle {
10
12
  unref?(): void;
@@ -26,10 +28,30 @@ export interface InteractiveTickersDeps {
26
28
  contextActivityStore: InteractiveContextActivityStore;
27
29
  getOverlayState: () => string;
28
30
  isFooterExpanded: () => boolean;
31
+ /** Bound to TaskBoardStore.cachedSnapshot; repaint must never fold the session ledger. */
32
+ getTaskBoard?: TaskBoardStore["cachedSnapshot"];
29
33
  scheduleInterval?: (callback: () => void, intervalMs: number) => InteractiveTickerHandle;
30
34
  clearScheduledInterval?: (handle: InteractiveTickerHandle) => void;
31
35
  }
32
36
 
37
+ export function formatTaskBoardIslandLines(board: TaskBoardSnapshot): string[] {
38
+ const theme = clioTheme();
39
+ const counts = taskBoardCounts(board);
40
+ const active = board.tasks.find((task) => task.status === "active");
41
+ const next = active ?? board.tasks.find((task) => task.status === "pending");
42
+ const chips = [
43
+ `${counts.completed}/${counts.total} done`,
44
+ ...(counts.active > 0 ? [`${counts.active} active`] : []),
45
+ ...(counts.blocked > 0 ? [`${counts.blocked} blocked`] : []),
46
+ ].join(" · ");
47
+ const body = [theme.fg("accent", board.title), theme.fg("dim", chips)];
48
+ if (next) {
49
+ const glyph = active ? theme.fg("accent", GLYPH.running) : theme.fg("dim", GLYPH.queued);
50
+ body.push(`${glyph} ${theme.fg("dim", next.id)} ${theme.fg("muted", next.title)}`);
51
+ }
52
+ return frame(theme, "Tasks", body, TASK_ISLAND_WIDTH + 4);
53
+ }
54
+
33
55
  export interface InteractiveTickers {
34
56
  renderTaskIsland(): void;
35
57
  renderContextIsland(): void;
@@ -71,19 +93,28 @@ export function createInteractiveTickers(deps: InteractiveTickersDeps): Interact
71
93
 
72
94
  let taskIslandHidden = true;
73
95
 
74
- const renderTaskIsland = (): void => {
96
+ const renderTaskIsland = (): boolean => {
75
97
  const rows = deps.dispatchBoardStore.activeRows();
98
+ const board = rows.length === 0 ? (deps.getTaskBoard?.() ?? null) : null;
99
+ const boardHasOpenTasks = board !== null && taskBoardCounts(board).open > 0;
76
100
  const contextActive = deps.contextActivityStore.active();
77
- const hidden = deps.getOverlayState() !== "closed" || deps.isFooterExpanded() || contextActive || rows.length === 0;
101
+ const hidden =
102
+ deps.getOverlayState() !== "closed" ||
103
+ deps.isFooterExpanded() ||
104
+ contextActive ||
105
+ (rows.length === 0 && !boardHasOpenTasks);
106
+ const visibilityChanged = taskIslandHidden !== hidden;
78
107
  taskIslandHandle.setHidden(hidden);
79
108
  // A hidden island with nothing to show still ran the frame builder and two
80
109
  // truncateToWidth calls four times a second, forever, to produce lines no
81
110
  // one could see. Formatting the empty case is pure waste; staying hidden
82
111
  // leaves the last text in place, which is unreachable while hidden.
83
- if (hidden && taskIslandHidden && rows.length === 0) return;
112
+ if (hidden && taskIslandHidden && rows.length === 0 && !boardHasOpenTasks) return visibilityChanged;
84
113
  taskIslandHidden = hidden;
85
- taskIsland.setText(formatTaskIslandLines(rows).join("\n"));
114
+ if (rows.length > 0) taskIsland.setText(formatTaskIslandLines(rows).join("\n"));
115
+ else if (board) taskIsland.setText(formatTaskBoardIslandLines(board).join("\n"));
86
116
  taskIsland.invalidate();
117
+ return visibilityChanged || !hidden;
87
118
  };
88
119
 
89
120
  const renderContextIsland = (): void => {
@@ -124,9 +155,9 @@ export function createInteractiveTickers(deps: InteractiveTickersDeps): Interact
124
155
  stopContextIslandTicker();
125
156
  contextIslandTicker = scheduleInterval(() => {
126
157
  deps.dispatchBoardStore.reconcile();
127
- renderTaskIsland();
158
+ const taskNeedsRender = renderTaskIsland();
128
159
  const fleetActive = deps.dispatchBoardStore.activeRows().length > 0;
129
- if (!deps.contextActivityStore.active() && !contextIslandVisible && !fleetActive) return;
160
+ if (!deps.contextActivityStore.active() && !contextIslandVisible && !fleetActive && !taskNeedsRender) return;
130
161
  renderContextIsland();
131
162
  deps.tui.requestRender();
132
163
  }, 250);
@@ -68,7 +68,7 @@ export interface LeaderTarget {
68
68
  }
69
69
 
70
70
  export interface ClioKeybindingManager {
71
- matches(data: string, id: ClioKeybinding): boolean;
71
+ matches(data: string, id: Keybinding): boolean;
72
72
  getKeys(id: Keybinding): ReadonlyArray<KeyId>;
73
73
  getDescription(id: ClioKeybinding): string;
74
74
  getConflicts(): ReadonlyArray<KeybindingConflict>;
@@ -1,5 +1,6 @@
1
- import type { Component } from "../engine/tui.js";
2
- import { Container } from "../engine/tui.js";
1
+ import type { Component, ScrollViewScrollbar, TuiMode } from "../engine/tui.js";
2
+ import { Container, ScrollView, VStack } from "../engine/tui.js";
3
+ import { clioTheme, GLYPH } from "./theme/index.js";
3
4
 
4
5
  export interface LayoutParts {
5
6
  banner: Component;
@@ -9,7 +10,43 @@ export interface LayoutParts {
9
10
  footer: Component;
10
11
  }
11
12
 
12
- export function buildLayout(parts: LayoutParts): Container {
13
+ export interface LayoutOptions {
14
+ mode?: TuiMode;
15
+ fullscreenScrollbar?: ScrollViewScrollbar;
16
+ }
17
+
18
+ export interface FullscreenLayout {
19
+ root: VStack;
20
+ transcript: ScrollView;
21
+ }
22
+
23
+ export function buildFullscreenLayout(
24
+ parts: LayoutParts,
25
+ options: Pick<LayoutOptions, "fullscreenScrollbar"> = {},
26
+ ): FullscreenLayout {
27
+ const document = new Container();
28
+ document.addChild(parts.banner);
29
+ document.addChild(parts.chat);
30
+ const theme = clioTheme();
31
+ const transcript = new ScrollView(document, {
32
+ follow: "end",
33
+ primary: true,
34
+ overscroll: "chain",
35
+ scrollbar: options.fullscreenScrollbar ?? "auto",
36
+ scrollbarStyle: () => theme.fg("frameStrong", GLYPH.barFull),
37
+ });
38
+ const dock = new VStack();
39
+ if (parts.pending) dock.addChild(parts.pending, { shrink: 1, minSize: 0 });
40
+ dock.addChild(parts.editor, { shrink: 1, minSize: 3 });
41
+ dock.addChild(parts.footer, { shrink: 1, minSize: 1 });
42
+ const root = new VStack();
43
+ root.addChild(transcript, { basis: 0, grow: 1, shrink: 1, minSize: 1 });
44
+ root.addChild(dock, { basis: "auto", grow: 0, shrink: 1, minSize: 1 });
45
+ return { root, transcript };
46
+ }
47
+
48
+ export function buildLayout(parts: LayoutParts, options: LayoutOptions = {}): Component {
49
+ if (options.mode === "fullscreen") return buildFullscreenLayout(parts, options).root;
13
50
  const root = new Container();
14
51
  root.addChild(parts.banner);
15
52
  root.addChild(parts.chat);
@@ -182,7 +182,7 @@ export function fitHintEntries(entries: ReadonlyArray<HintEntry>, maxWidth: numb
182
182
  }
183
183
 
184
184
  /**
185
- * The one word for narrowing a list by typing. `/help` said `filter`, `/models`
185
+ * The one word for narrowing a list by typing. `/help` said `filter`, `/model`
186
186
  * and `/resume` said `search`, and they are the same gesture, so a reader who
187
187
  * learned one had to relearn it in the next overlay.
188
188
  */