@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,5 +1,6 @@
1
1
  import { existsSync, readdirSync, readFileSync } from "node:fs";
2
2
  import path from "node:path";
3
+ import { resolvePackageRoot } from "../../../core/package-root.js";
3
4
  import { clioConfigDir } from "../../../core/xdg.js";
4
5
  import {
5
6
  type InstallSkillInput,
@@ -13,12 +14,21 @@ import { loadSkills, type Skill } from "./loader.js";
13
14
  /**
14
15
  * Local skill marketplace. Entries come from two real sources only:
15
16
  *
16
- * 1. A catalog directory of actual SKILL.md packages (for example the
17
- * repo-level skills/ folder, or CLIO_CODER_SKILL_CATALOG_DIR). Metadata is read
18
- * from the packages themselves via the normal skill loader.
19
- * 2. A JSON index file (CLIO_CODER_SKILL_MARKETPLACE_INDEX or
20
- * <config>/skill-marketplace.json) whose entries point at installable
21
- * sources.
17
+ * 1. A catalog directory of actual SKILL.md packages: CLIO_CODER_SKILL_CATALOG_DIR,
18
+ * else a repo-level skills/ folder in the working tree, else the skills/
19
+ * catalog the installed clio-coder package carries. Metadata is read from
20
+ * the packages themselves via the normal skill loader.
21
+ * 2. A JSON index file: CLIO_CODER_SKILL_MARKETPLACE_INDEX, else
22
+ * <config>/skill-marketplace.json, else the skill-marketplace.json the
23
+ * package carries. Entries point at installable sources.
24
+ *
25
+ * The package fallbacks are what make a fresh npm install a marketplace at
26
+ * all: before them, an operator outside this repository with no env var set
27
+ * had no catalog and no index, so every bare-name install and every
28
+ * `/skill <name>` for a catalog skill failed. The package catalog is a
29
+ * marketplace source only, never a discovery root; catalog skills stay
30
+ * uninstalled until the operator asks, and install copies them out of the
31
+ * package into a Clio root without touching the network.
22
32
  *
23
33
  * There is no synthetic or hardcoded marketplace data; an empty result means
24
34
  * no marketplace is configured.
@@ -62,14 +72,45 @@ export interface DiscoverMarketplaceOptions {
62
72
  catalogDir?: string | null;
63
73
  }
64
74
 
65
- function defaultIndexPath(): string | null {
75
+ /**
76
+ * The catalog directory and index the installed package carries. Resolved
77
+ * lazily and defensively: a source checkout that has not built, or a package
78
+ * root the harness cannot locate, must degrade to "no package catalog" rather
79
+ * than throw out of a listing.
80
+ */
81
+ function packageCatalogDir(): string | null {
82
+ try {
83
+ return path.join(resolvePackageRoot(), "skills");
84
+ } catch {
85
+ return null;
86
+ }
87
+ }
88
+
89
+ function packageIndexPath(): string | null {
66
90
  try {
67
- return path.join(clioConfigDir(), "skill-marketplace.json");
91
+ return path.join(resolvePackageRoot(), "skills", "skill-marketplace.json");
68
92
  } catch {
69
93
  return null;
70
94
  }
71
95
  }
72
96
 
97
+ /**
98
+ * Index precedence when no explicit path is given: the operator's config-dir
99
+ * copy beats the package's, so a hand-curated index still wins, and the
100
+ * package's own index is what a fresh install falls back to.
101
+ */
102
+ function defaultIndexPath(): string | null {
103
+ try {
104
+ const configured = path.join(clioConfigDir(), "skill-marketplace.json");
105
+ if (existsSync(configured)) return configured;
106
+ } catch {
107
+ // Fall through: no config dir is not "no marketplace" once the package
108
+ // carries an index of its own.
109
+ }
110
+ const bundled = packageIndexPath();
111
+ return bundled && existsSync(bundled) ? bundled : null;
112
+ }
113
+
73
114
  function isIndexSkill(value: unknown): value is { name: string; description: string; sourceUrl: string } {
74
115
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
75
116
  const record = value as Record<string, unknown>;
@@ -154,7 +195,12 @@ function resolveCatalogDir(options: DiscoverMarketplaceOptions): string | null {
154
195
  const fromEnv = process.env.CLIO_CODER_SKILL_CATALOG_DIR;
155
196
  if (fromEnv && fromEnv.trim().length > 0) return path.resolve(fromEnv.trim());
156
197
  const repoCatalog = path.join(options.cwd ?? process.cwd(), "skills");
157
- return looksLikeSkillCatalog(repoCatalog) ? repoCatalog : null;
198
+ if (looksLikeSkillCatalog(repoCatalog)) return repoCatalog;
199
+ // The package's own catalog: rows resolve to local files, so a bare-name
200
+ // install copies out of the package and needs no network. From a checkout
201
+ // of this repository the two paths coincide.
202
+ const bundled = packageCatalogDir();
203
+ return bundled && looksLikeSkillCatalog(bundled) ? bundled : null;
158
204
  }
159
205
 
160
206
  /**
@@ -95,8 +95,10 @@ function baseClassify(tool: string): ActionClass | null {
95
95
  case ToolNames.Monitor:
96
96
  case ToolNames.AskUser:
97
97
  case ToolNames.CredentialPresent:
98
- // tasks mutates only the session's task ledger, never the workspace,
99
- // so it stays read class and is never gated behind a confirmation.
98
+ // tasks pick mutates only Clio-owned session-ledger and project-local
99
+ // .clio-coder runtime state, never source-workspace files. By intentional
100
+ // policy it stays read class and ungated; the tool itself still requires
101
+ // a durable operator task id before it can mutate either store.
100
102
  case ToolNames.Tasks:
101
103
  // ledger posts a typed contribution to a coordination board and reads a
102
104
  // local mirror. Neither touches the workspace, so it is never gated
@@ -85,7 +85,7 @@ export interface PermissionAuditRecord {
85
85
  kind: "permission";
86
86
  ts: string;
87
87
  correlationId: string;
88
- status: "requested" | "granted" | "denied";
88
+ status: "requested" | "granted" | "denied" | "expired";
89
89
  requestId?: string;
90
90
  origin?: string;
91
91
  decidedBy?: string;
@@ -204,7 +204,13 @@ let dateFormatter = new Intl.DateTimeFormat("en-CA", DATE_OPTIONS);
204
204
  function localDateString(d: Date): string {
205
205
  if (process.env.TZ !== dateFormatterZone) {
206
206
  dateFormatterZone = process.env.TZ;
207
- dateFormatter = new Intl.DateTimeFormat("en-CA", DATE_OPTIONS);
207
+ // The zone is passed explicitly, not left for Intl to pick up from
208
+ // process.env.TZ implicitly: see src/interactive/format-time.ts's
209
+ // syncZone() for the traced repro (issue #84) of a rebuilt formatter
210
+ // resolving to the wrong zone while process.env.TZ read correctly at
211
+ // both construction and format time. Same idiom, same fix.
212
+ const zone = dateFormatterZone === undefined ? undefined : { timeZone: dateFormatterZone };
213
+ dateFormatter = new Intl.DateTimeFormat("en-CA", { ...DATE_OPTIONS, ...zone });
208
214
  }
209
215
  return dateFormatter.format(d);
210
216
  }
@@ -31,7 +31,7 @@ import { CONFIRMED_SCOPE, isSubset, READONLY_SCOPE, WORKSPACE_SCOPE } from "./sc
31
31
  function isPermissionResolvedPayload(value: unknown): value is PermissionResolvedPayload {
32
32
  if (!value || typeof value !== "object") return false;
33
33
  const p = value as Record<string, unknown>;
34
- if (p.status !== "granted" && p.status !== "denied") return false;
34
+ if (p.status !== "granted" && p.status !== "denied" && p.status !== "expired") return false;
35
35
  if (p.tool !== undefined && typeof p.tool !== "string") return false;
36
36
  if (p.actionClass !== undefined && typeof p.actionClass !== "string") return false;
37
37
  if (p.reason !== undefined && typeof p.reason !== "string") return false;
@@ -123,7 +123,7 @@ function toolResultText(entry: MessageEntry): string {
123
123
  * stable for a given input. Tests rely on this determinism.
124
124
  *
125
125
  * Non-context-bearing kinds (modelChange, thinkingLevelChange, fileEntry,
126
- * sessionInfo, protectedArtifact, custom) are skipped: they never contribute
126
+ * sessionInfo, protectedArtifact, taskLedger, decisionLedger, custom) are skipped: they never contribute
127
127
  * to the replayed LLM context, so summarizing them would waste tokens on
128
128
  * bookkeeping.
129
129
  */
@@ -180,7 +180,8 @@ export function serializeConversation(entries: ReadonlyArray<SessionEntry>): str
180
180
  );
181
181
  }
182
182
  // custom, modelChange, thinkingLevelChange, fileEntry, sessionInfo,
183
- // protectedArtifact do not project into the serialized conversation.
183
+ // protectedArtifact, taskLedger, decisionLedger, and workerRun do not
184
+ // project into the serialized conversation.
184
185
  }
185
186
  return parts.join("\n\n");
186
187
  }
@@ -70,6 +70,7 @@ function isValidCutPoint(entry: SessionEntry): boolean {
70
70
  case "label":
71
71
  case "protectedArtifact":
72
72
  case "taskLedger":
73
+ case "decisionLedger":
73
74
  case "workerRun":
74
75
  return false;
75
76
  }
@@ -96,7 +97,7 @@ function findValidCutPoints(entries: ReadonlyArray<SessionEntry>, startIndex: nu
96
97
  * accumulating `keepRecentTokens`, the pi-coding-agent reference left
97
98
  * `cutIndex` at the oldest valid cut, which made `compact()` produce an
98
99
  * empty `pre` slice and the chat-loop report "nothing to compact" on
99
- * populated sessions below the keep-recent window. Clio's manual `/compact`
100
+ * populated sessions below the keep-recent window. Clio's manual `/context compact`
100
101
  * expects to summarize whatever older history exists, so when no suffix
101
102
  * crosses the threshold the cut falls back to the newest turn start (user
102
103
  * message, bashExecution, or branchSummary). Sessions with only a single
@@ -53,7 +53,7 @@ function estimateSummary(entry: BranchSummaryEntry | CompactionSummaryEntry): nu
53
53
  /**
54
54
  * Estimate the token load of a single session entry. Non-context-bearing
55
55
  * kinds (modelChange, thinkingLevelChange, fileEntry, sessionInfo,
56
- * label, protectedArtifact, taskLedger, workerRun) return 0 so they never
56
+ * label, protectedArtifact, taskLedger, decisionLedger, workerRun) return 0 so they never
57
57
  * distort the context budget.
58
58
  */
59
59
  export function estimateTokens(entry: SessionEntry): number {
@@ -76,6 +76,7 @@ export function estimateTokens(entry: SessionEntry): number {
76
76
  case "label":
77
77
  case "protectedArtifact":
78
78
  case "taskLedger":
79
+ case "decisionLedger":
79
80
  case "workerRun":
80
81
  return 0;
81
82
  }
@@ -84,6 +84,12 @@ export interface BuildContextLedgerInput {
84
84
  * a prompt has compiled.
85
85
  */
86
86
  projectPreload?: string | null;
87
+ /**
88
+ * Absolute paths of the effective project handbooks the compiled prompt
89
+ * selected, ancestor to nearest. Null before a prompt has compiled; empty
90
+ * when the workspace has no parseable handbook.
91
+ */
92
+ projectHandbookFiles?: ReadonlyArray<string> | null;
87
93
  lastCompaction?: {
88
94
  stage: string;
89
95
  tokensBefore: number;
@@ -152,6 +158,11 @@ export interface ContextLedger {
152
158
  compactionAuto: boolean;
153
159
  /** Preload class label for the project category detail line; null when unknown. */
154
160
  projectPreload: string | null;
161
+ /**
162
+ * Which handbook files won for this session, ancestor to nearest (an
163
+ * override resets the inherited chain). Null before a prompt has compiled.
164
+ */
165
+ projectHandbookFiles: ReadonlyArray<string> | null;
155
166
  toolCount: number;
156
167
  /** Non-empty content categories in display order (excludes reserve/free). */
157
168
  groups: ReadonlyArray<ContextLedgerGroup>;
@@ -170,6 +181,8 @@ export interface ContextLedger {
170
181
  const SEGMENT_CATEGORY: Readonly<Record<string, ContextLedgerCategory>> = {
171
182
  identity: "system",
172
183
  "operating-contract": "system",
184
+ delegation: "agents",
185
+ skills: "skills",
173
186
  safety: "system",
174
187
  runtime: "system",
175
188
  "tool-contract": "system",
@@ -339,6 +352,7 @@ export function buildContextLedger(input: BuildContextLedgerInput): ContextLedge
339
352
  compactionThreshold: effectiveThreshold,
340
353
  compactionAuto: input.compactionAuto === true,
341
354
  projectPreload: input.projectPreload ?? null,
355
+ projectHandbookFiles: input.projectHandbookFiles ?? null,
342
356
  toolCount: Math.max(0, Math.floor(input.toolCount ?? 0)),
343
357
  groups,
344
358
  meter,
@@ -47,6 +47,14 @@ export type ClioSessionMetaExtension = {
47
47
  workspace?: WorkspaceSnapshot;
48
48
  /** Ordered record of skills activated in this session. */
49
49
  skillActivations?: SkillActivation[];
50
+ /**
51
+ * The turn `/tree` last switched the append point to, persisted so it
52
+ * survives quit + resume. `resume()`/`switchBranch()` prefer this over
53
+ * inferring the leaf from timestamps (`computeLeafId`) when it still
54
+ * names a real turn; a plain append clears it, since once the tree grows
55
+ * past it the inferred newest-node leaf is correct again.
56
+ */
57
+ pinnedLeafTurnId?: string | null;
50
58
  };
51
59
 
52
60
  export type SessionMeta = ClioSessionMeta & ClioSessionMetaExtension;
@@ -130,6 +138,13 @@ export interface SessionContract {
130
138
  * otherwise the helper appends directly to that session's transcript.
131
139
  */
132
140
  editLabel(turnId: string, label: string, sessionId?: string): void;
141
+ /**
142
+ * Persist the session's display name as a session-wide SessionInfoEntry.
143
+ * Empty or whitespace-only names clear the name when history is rebuilt.
144
+ * If the target session is current, writes flow through the live writer;
145
+ * otherwise the entry is durably appended directly to its transcript.
146
+ */
147
+ setName(name: string, sessionId?: string): void;
133
148
  /**
134
149
  * Remove the given session. By default, wipes the session directory.
135
150
  * `opts.keepFiles` preserves the transcript and only tombstones meta.json.
@@ -0,0 +1,190 @@
1
+ import type { AskUserToolPolicy } from "../../tools/registry.js";
2
+ import type { DecisionLedgerEntry, DecisionRecord } from "./entries.js";
3
+
4
+ export interface DecisionLedgerEntryFields {
5
+ kind: "decisionLedger";
6
+ parentTurnId: string;
7
+ interviewId: string;
8
+ interviewStatus: "complete" | "cancelled";
9
+ startedAt: string;
10
+ endedAt: string;
11
+ roundCount: number;
12
+ summary?: string;
13
+ transcriptPath?: string;
14
+ decisions: DecisionRecord[];
15
+ }
16
+
17
+ export interface DecisionBoardStoreDeps {
18
+ /** Current session id, used to keep the in-memory fold scoped to one ledger. */
19
+ getSessionId?: () => string | null;
20
+ /** Active-path entries for the current session. */
21
+ readEntries?: () => ReadonlyArray<unknown>;
22
+ /** The current branch leaf used to anchor operator-authored revisions. */
23
+ getActiveLeafTurnId?: () => string | null;
24
+ /** Acknowledged session append. A throw means the board did not change. */
25
+ appendEntry?: (entry: DecisionLedgerEntryFields) => void;
26
+ now?: () => Date;
27
+ }
28
+
29
+ export interface DecisionBoardStore {
30
+ /** Latest snapshot per interview, newest interview first. */
31
+ snapshot(): ReadonlyArray<DecisionLedgerEntry>;
32
+ /** Persist the one host-finalized snapshot for a settled interview. */
33
+ recordFinalizedInterview(policy: AskUserToolPolicy): boolean;
34
+ /** Append an operator revision snapshot anchored to the active branch leaf. */
35
+ supersede(interviewId: string, key: string, correction?: string): DecisionLedgerEntryFields;
36
+ /** Force the next read to refold, including after a same-session tree switch. */
37
+ invalidate(): void;
38
+ }
39
+
40
+ function answeredAtForDecision(policy: AskUserToolPolicy, sourceQuestion: string): string | undefined {
41
+ for (let index = policy.rounds.length - 1; index >= 0; index -= 1) {
42
+ const round = policy.rounds[index];
43
+ if (!round?.answeredAt) continue;
44
+ if (round.answers.some((answer) => answer.question === sourceQuestion)) return round.answeredAt;
45
+ if (round.questions.some((question) => question.question === sourceQuestion)) return round.answeredAt;
46
+ }
47
+ return undefined;
48
+ }
49
+
50
+ /**
51
+ * Convert the settled, host-owned policy into the complete durable snapshot.
52
+ * The policy already keeps last-value-wins decisions; the defensive map also
53
+ * makes conversion deterministic for hand-built policies and older callers.
54
+ */
55
+ export function finalizedInterviewEntryFields(policy: AskUserToolPolicy): DecisionLedgerEntryFields | null {
56
+ if (policy.rounds.length === 0 && policy.decisions.length === 0) return null;
57
+ if (!policy.turnId) throw new Error(`decision board: interview ${policy.id} has no originating user turn`);
58
+ if (policy.status !== "complete" && policy.status !== "cancelled") {
59
+ throw new Error(`decision board: interview ${policy.id} finalized with status ${policy.status}`);
60
+ }
61
+ const endedAt = policy.endedAt ?? policy.updatedAt;
62
+ const decisionsByKey = new Map<string, DecisionRecord>();
63
+ for (const decision of policy.decisions) {
64
+ const decidedAt = decision.source_question
65
+ ? (answeredAtForDecision(policy, decision.source_question) ?? endedAt)
66
+ : endedAt;
67
+ decisionsByKey.set(decision.key, {
68
+ key: decision.key,
69
+ value: decision.value,
70
+ ...(decision.label ? { label: decision.label } : {}),
71
+ ...(decision.source_question ? { source_question: decision.source_question } : {}),
72
+ status: "active",
73
+ decidedAt,
74
+ });
75
+ }
76
+ return {
77
+ kind: "decisionLedger",
78
+ parentTurnId: policy.turnId,
79
+ interviewId: policy.id,
80
+ interviewStatus: policy.status,
81
+ startedAt: policy.startedAt,
82
+ endedAt,
83
+ roundCount: policy.rounds.length,
84
+ ...(policy.summary ? { summary: policy.summary } : {}),
85
+ ...(policy.transcriptPath ? { transcriptPath: policy.transcriptPath } : {}),
86
+ decisions: [...decisionsByKey.values()],
87
+ };
88
+ }
89
+
90
+ function isDecisionLedgerEntry(value: unknown): value is DecisionLedgerEntry {
91
+ return !!value && typeof value === "object" && (value as { kind?: unknown }).kind === "decisionLedger";
92
+ }
93
+
94
+ /** Last full snapshot wins independently for each interview. */
95
+ export function foldDecisionBoard(entries: ReadonlyArray<unknown>): DecisionLedgerEntry[] {
96
+ const lastByInterview = new Map<string, { entry: DecisionLedgerEntry; index: number }>();
97
+ for (let index = 0; index < entries.length; index += 1) {
98
+ const raw = entries[index];
99
+ if (!isDecisionLedgerEntry(raw)) continue;
100
+ lastByInterview.set(raw.interviewId, { entry: raw, index });
101
+ }
102
+ return [...lastByInterview.values()]
103
+ .sort((left, right) => {
104
+ const byEndedAt = right.entry.endedAt.localeCompare(left.entry.endedAt);
105
+ return byEndedAt !== 0 ? byEndedAt : right.index - left.index;
106
+ })
107
+ .map(({ entry }) => entry);
108
+ }
109
+
110
+ function activeLeafFromEntries(entries: ReadonlyArray<unknown>): string | null {
111
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
112
+ const entry = entries[index];
113
+ if (entry && typeof entry === "object" && (entry as { kind?: unknown }).kind === "message") {
114
+ const turnId = (entry as { turnId?: unknown }).turnId;
115
+ if (typeof turnId === "string" && turnId.length > 0) return turnId;
116
+ }
117
+ }
118
+ return null;
119
+ }
120
+
121
+ export function createDecisionBoardStore(deps: DecisionBoardStoreDeps = {}): DecisionBoardStore {
122
+ let cachedSessionId: string | null | undefined;
123
+ let dirty = true;
124
+ let interviews: DecisionLedgerEntry[] = [];
125
+
126
+ const syncToSession = (): void => {
127
+ const sessionId = deps.getSessionId?.() ?? null;
128
+ if (!dirty && sessionId === cachedSessionId) return;
129
+ const entries = deps.readEntries?.() ?? [];
130
+ interviews = foldDecisionBoard(entries);
131
+ cachedSessionId = sessionId;
132
+ dirty = false;
133
+ };
134
+
135
+ const append = (entry: DecisionLedgerEntryFields): void => {
136
+ if (!deps.appendEntry) throw new Error("decision board: no session ledger is available");
137
+ deps.appendEntry(entry);
138
+ // Read the acknowledged append back through the active-path source. This
139
+ // never publishes a snapshot the ledger did not accept.
140
+ dirty = true;
141
+ };
142
+
143
+ return {
144
+ snapshot(): ReadonlyArray<DecisionLedgerEntry> {
145
+ syncToSession();
146
+ return interviews;
147
+ },
148
+ recordFinalizedInterview(policy: AskUserToolPolicy): boolean {
149
+ const entry = finalizedInterviewEntryFields(policy);
150
+ if (entry === null) return false;
151
+ append(entry);
152
+ return true;
153
+ },
154
+ supersede(interviewId: string, key: string, correction?: string): DecisionLedgerEntryFields {
155
+ syncToSession();
156
+ const interview = interviews.find((candidate) => candidate.interviewId === interviewId);
157
+ if (!interview) throw new Error(`decision board: interview ${interviewId} was not found on the active branch`);
158
+ const selected = interview.decisions.find((decision) => decision.key === key);
159
+ if (!selected) throw new Error(`decision board: decision ${key} was not found in interview ${interviewId}`);
160
+ const revisedAt = (deps.now?.() ?? new Date()).toISOString();
161
+ const normalizedCorrection = correction?.trim();
162
+ const entries = deps.readEntries?.() ?? [];
163
+ const parentTurnId = deps.getActiveLeafTurnId?.() ?? activeLeafFromEntries(entries);
164
+ if (!parentTurnId) throw new Error("decision board: no active branch leaf is available for the revision");
165
+ const revision: DecisionLedgerEntryFields = {
166
+ kind: "decisionLedger",
167
+ parentTurnId,
168
+ interviewId: interview.interviewId,
169
+ interviewStatus: interview.interviewStatus,
170
+ startedAt: interview.startedAt,
171
+ endedAt: interview.endedAt,
172
+ roundCount: interview.roundCount,
173
+ ...(interview.summary ? { summary: interview.summary } : {}),
174
+ ...(interview.transcriptPath ? { transcriptPath: interview.transcriptPath } : {}),
175
+ decisions: interview.decisions.map((decision) => {
176
+ if (decision.key !== selected.key) return { ...decision };
177
+ const next: DecisionRecord = { ...decision, status: "superseded", revisedAt };
178
+ if (normalizedCorrection) next.correction = normalizedCorrection;
179
+ else delete next.correction;
180
+ return next;
181
+ }),
182
+ };
183
+ append(revision);
184
+ return revision;
185
+ },
186
+ invalidate(): void {
187
+ dirty = true;
188
+ },
189
+ };
190
+ }
@@ -85,10 +85,10 @@ export interface BranchSummaryEntry extends BaseSessionEntry {
85
85
 
86
86
  /**
87
87
  * Why a compaction run fired. Persisted on CompactionSummaryEntry so post-mortem
88
- * tools can distinguish a threshold-driven shrink from a user-issued /compact
88
+ * tools can distinguish a threshold-driven shrink from a user-issued `/context compact`
89
89
  * and from a context-overflow retry.
90
90
  * - "auto" : pre-submit context-pressure trigger via shouldCompact().
91
- * - "force" : explicit /compact slash command or CLIO_CODER_FORCE_COMPACT=1.
91
+ * - "force" : explicit `/context compact` command or CLIO_CODER_FORCE_COMPACT=1.
92
92
  * - "overflow" : compact-and-retry path after a context overflow error.
93
93
  */
94
94
  export type CompactionTrigger = "auto" | "force" | "overflow";
@@ -183,6 +183,8 @@ export interface TaskLedgerGoal {
183
183
  status: TaskLedgerStatus;
184
184
  parentGoalId?: string | null;
185
185
  description?: string;
186
+ origin?: "agent" | "user";
187
+ userTaskId?: string;
186
188
  }
187
189
 
188
190
  export interface TaskLedgerValidationEvidence {
@@ -197,12 +199,39 @@ export interface TaskLedgerValidationEvidence {
197
199
 
198
200
  export interface TaskLedgerEntry extends BaseSessionEntry {
199
201
  kind: "taskLedger";
202
+ boardId?: string;
200
203
  goals: TaskLedgerGoal[];
201
204
  subgoals: TaskLedgerGoal[];
202
205
  activeRunIds: string[];
203
206
  requiredValidationEvidence: TaskLedgerValidationEvidence[];
204
207
  }
205
208
 
209
+ export type DecisionStatus = "active" | "superseded";
210
+
211
+ export interface DecisionRecord {
212
+ key: string;
213
+ value: string;
214
+ label?: string;
215
+ source_question?: string;
216
+ status: DecisionStatus;
217
+ decidedAt: string;
218
+ revisedAt?: string;
219
+ correction?: string;
220
+ }
221
+
222
+ /** One complete, branch-anchored snapshot of a settled operator interview. */
223
+ export interface DecisionLedgerEntry extends BaseSessionEntry {
224
+ kind: "decisionLedger";
225
+ interviewId: string;
226
+ interviewStatus: "complete" | "cancelled";
227
+ startedAt: string;
228
+ endedAt: string;
229
+ roundCount: number;
230
+ summary?: string;
231
+ transcriptPath?: string;
232
+ decisions: DecisionRecord[];
233
+ }
234
+
206
235
  /** Who asked for a dispatched run. Internal runs never reach the transcript, so they never reach this entry. */
207
236
  export type WorkerRunOrigin = "user" | "agent";
208
237
 
@@ -261,6 +290,7 @@ export type SessionEntry =
261
290
  | ProtectedArtifactEntry
262
291
  | SkillActivationEntry
263
292
  | TaskLedgerEntry
293
+ | DecisionLedgerEntry
264
294
  | WorkerRunEntry;
265
295
 
266
296
  export type SessionFileEntry = SessionHeader | SessionEntry;
@@ -285,6 +315,7 @@ export const SESSION_ENTRY_KINDS = [
285
315
  "protectedArtifact",
286
316
  "skillActivation",
287
317
  "taskLedger",
318
+ "decisionLedger",
288
319
  "workerRun",
289
320
  ] as const;
290
321
 
@@ -354,6 +385,8 @@ const TASK_LEDGER_EVIDENCE_STATUSES: readonly TaskLedgerEvidenceStatus[] = [
354
385
  "failed",
355
386
  "missing",
356
387
  ];
388
+ const DECISION_STATUSES: readonly DecisionStatus[] = ["active", "superseded"];
389
+ const DECISION_INTERVIEW_STATUSES = ["complete", "cancelled"] as const;
357
390
  const WORKER_RUN_ORIGINS: readonly WorkerRunOrigin[] = ["user", "agent"];
358
391
  const WORKER_RUN_RUNTIME_KINDS: readonly WorkerRunRuntimeKind[] = ["clio", "acp", "claude-sdk", "claude-code"];
359
392
 
@@ -372,7 +405,11 @@ function isTaskLedgerGoal(value: unknown): value is TaskLedgerGoal {
372
405
  if (!isString(value.id) || !isString(value.title)) return false;
373
406
  if (!isOneOf(value.status, TASK_LEDGER_STATUSES)) return false;
374
407
  if (value.parentGoalId !== undefined && !isNullableString(value.parentGoalId)) return false;
375
- return isOptionalString(value.description);
408
+ const hasPairedProvenance =
409
+ value.origin === "user"
410
+ ? isString(value.userTaskId) && /^u[1-9]\d*$/.test(value.userTaskId)
411
+ : (value.origin === undefined || value.origin === "agent") && value.userTaskId === undefined;
412
+ return isOptionalString(value.description) && hasPairedProvenance;
376
413
  }
377
414
 
378
415
  function isTaskLedgerEvidence(value: unknown): value is TaskLedgerValidationEvidence {
@@ -387,6 +424,17 @@ function isTaskLedgerEvidence(value: unknown): value is TaskLedgerValidationEvid
387
424
  );
388
425
  }
389
426
 
427
+ function isDecisionRecord(value: unknown): value is DecisionRecord {
428
+ if (!isRecord(value)) return false;
429
+ if (!isString(value.key) || !/^[a-z0-9]+(?:_[a-z0-9]+)*$/.test(value.key)) return false;
430
+ if (!isString(value.value) || !isOneOf(value.status, DECISION_STATUSES) || !isString(value.decidedAt)) return false;
431
+ if (!isOptionalString(value.label) || !isOptionalString(value.source_question)) return false;
432
+ if (!isOptionalString(value.revisedAt) || !isOptionalString(value.correction)) return false;
433
+ return value.status === "superseded"
434
+ ? isString(value.revisedAt)
435
+ : value.revisedAt === undefined && value.correction === undefined;
436
+ }
437
+
390
438
  function isOptionalCompactionUsage(value: unknown): boolean {
391
439
  if (value === undefined) return true;
392
440
  if (!isRecord(value)) return false;
@@ -487,6 +535,7 @@ export function isSessionEntry(value: unknown): value is SessionEntry {
487
535
  return isSkillActivation(v.activation);
488
536
  case "taskLedger":
489
537
  return (
538
+ isOptionalString(v.boardId) &&
490
539
  Array.isArray(v.goals) &&
491
540
  v.goals.every(isTaskLedgerGoal) &&
492
541
  Array.isArray(v.subgoals) &&
@@ -495,6 +544,20 @@ export function isSessionEntry(value: unknown): value is SessionEntry {
495
544
  Array.isArray(v.requiredValidationEvidence) &&
496
545
  v.requiredValidationEvidence.every(isTaskLedgerEvidence)
497
546
  );
547
+ case "decisionLedger":
548
+ return (
549
+ isString(v.interviewId) &&
550
+ isOneOf(v.interviewStatus, DECISION_INTERVIEW_STATUSES) &&
551
+ isString(v.startedAt) &&
552
+ isString(v.endedAt) &&
553
+ isNumber(v.roundCount) &&
554
+ Number.isInteger(v.roundCount) &&
555
+ v.roundCount >= 0 &&
556
+ isOptionalString(v.summary) &&
557
+ isOptionalString(v.transcriptPath) &&
558
+ Array.isArray(v.decisions) &&
559
+ v.decisions.every(isDecisionRecord)
560
+ );
498
561
  case "workerRun":
499
562
  return (
500
563
  isString(v.assignmentId) &&