@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
@@ -2,16 +2,17 @@ import { join } from "node:path";
2
2
  import chalk from "chalk";
3
3
  import { modelBootstrapGenerate, resolveBootstrapRoute } from "../cli/bootstrap-generate.js";
4
4
  import { runHeadlessMainAgent } from "../cli/modes/print.js";
5
+ import { formatBootTrace } from "../core/boot-trace.js";
5
6
  import { BusChannels } from "../core/bus-events.js";
6
7
  import { installBusTracer } from "../core/bus-trace.js";
7
8
  import { type ClioSettings, readSettings, type SettingsMutator, updateSettings } from "../core/config.js";
8
9
  import { DEFAULT_DELEGATION_PERMISSION_TIMEOUT_MS } from "../core/defaults.js";
9
10
  import { loadDomains } from "../core/domain-loader.js";
10
11
  import { expandInlineFileReferencesAsync } from "../core/file-references.js";
12
+ import { setGitCommitAttributionEnabled } from "../core/git-commit-attribution.js";
11
13
  import { configureGuardrails } from "../core/guardrails.js";
12
14
  import { HEADLESS_PERMISSION_DENIED_REASON } from "../core/headless-permission.js";
13
15
  import { rememberRecentModel } from "../core/recent-models.js";
14
- import { EXPERIMENTAL_RELEASE_WARNING } from "../core/release.js";
15
16
  import { protectedResidencyModels } from "../core/residency-protection.js";
16
17
  import {
17
18
  applyOverrides,
@@ -38,9 +39,10 @@ import { renderAgentCatalogSectionsFromSpecs } from "../domains/agents/catalog.j
38
39
  import type { AgentsContract } from "../domains/agents/contract.js";
39
40
  import { AgentsDomainModule } from "../domains/agents/index.js";
40
41
  import type { ConfigContract } from "../domains/config/contract.js";
41
- import { ConfigDomainModule } from "../domains/config/index.js";
42
- import { type ContextContract, createContextDomainModule } from "../domains/context/index.js";
42
+ import { ConfigDomainModule, createConfigDomainModule } from "../domains/config/index.js";
43
+ import type { ContextContract } from "../domains/context/contract.js";
43
44
  import { bootstrapInputFromInitOptions } from "../domains/context/init-options.js";
45
+ import { createContextDomainModule } from "../domains/context/runtime.js";
44
46
  import type { DispatchContract } from "../domains/dispatch/contract.js";
45
47
  import { createDispatchDedupRegistration } from "../domains/dispatch/dedup.js";
46
48
  import { agentRoleFactsResolver } from "../domains/dispatch/execution-role.js";
@@ -109,7 +111,12 @@ import {
109
111
  } from "../domains/providers/index.js";
110
112
  import { getRuntimeRegistry } from "../domains/providers/registry.js";
111
113
  import { registerBuiltinRuntimes } from "../domains/providers/runtimes/builtins.js";
112
- import { createResourcesDomainModule, modelVisibleSkills, type ResourcesContract } from "../domains/resources/index.js";
114
+ import {
115
+ createResourcesDomainModule,
116
+ discoverMarketplaceSkills,
117
+ modelVisibleSkills,
118
+ type ResourcesContract,
119
+ } from "../domains/resources/index.js";
113
120
  import { DEFAULT_RECENT_ENTRY_LIMIT } from "../domains/safety/finish-contract.js";
114
121
  import { createFinishContractRegistration } from "../domains/safety/finish-contract-registration.js";
115
122
  import type { AutonomyLevel, SafetyContract } from "../domains/safety/index.js";
@@ -123,8 +130,10 @@ import type { SchedulingContract } from "../domains/scheduling/contract.js";
123
130
  import { SchedulingDomainModule } from "../domains/scheduling/index.js";
124
131
  import { type CompactResult, compact } from "../domains/session/compaction/compact.js";
125
132
  import { collectSessionEntries } from "../domains/session/compaction/session-entries.js";
126
- import { ceilChars, estimateAgentContextTokens } from "../domains/session/context-accounting.js";
133
+ import { estimateTokens } from "../domains/session/compaction/tokens.js";
134
+ import { ceilChars } from "../domains/session/context-accounting.js";
127
135
  import type { SessionContract, SessionMeta } from "../domains/session/contract.js";
136
+ import { createDecisionBoardStore } from "../domains/session/decision-board.js";
128
137
  import type { CompactionSummaryEntry, CompactionTrigger, SessionEntry } from "../domains/session/entries.js";
129
138
  import { SessionDomainModule } from "../domains/session/index.js";
130
139
  import {
@@ -139,12 +148,9 @@ import {
139
148
  import { createTaskBoardStore } from "../domains/session/task-board.js";
140
149
  import { filterEntriesToActivePath } from "../domains/session/tree/active-path.js";
141
150
  import { type ShareContract, ShareDomainModule } from "../domains/share/index.js";
142
- import { serveClioAcpAgent } from "../engine/acp/server.js";
143
- import {
144
- type AcpJsonRpcPeerTransport,
145
- createStdioServerTransport,
146
- type StdioServerTransportOptions,
147
- } from "../engine/acp/transport.js";
151
+ import { createUserTasksStore } from "../domains/user-tasks/store.js";
152
+ import { type AcpSafeSettingsPatch, type AcpSafeSettingsSnapshot, serveClioAcpAgent } from "../engine/acp/server.js";
153
+ import { createStdioServerTransport } from "../engine/acp/transport.js";
148
154
  import { completeEngineText } from "../engine/ai.js";
149
155
  import { setProtectedModelsProvider } from "../engine/apis/residency.js";
150
156
  import {
@@ -153,10 +159,14 @@ import {
153
159
  readOrchTurnToolCallBudget,
154
160
  } from "../engine/loop-guard.js";
155
161
  import { openSession, readSessionTailTurns, sessionCurrentPath, sessionPaths } from "../engine/session.js";
156
- import type { EngineModel, ImageContent } from "../engine/types.js";
162
+ import type { EngineModel } from "../engine/types.js";
157
163
  import { createChatLoop } from "../interactive/chat-loop.js";
158
164
  import { buildReplayAgentMessagesFromTurns } from "../interactive/chat-renderer.js";
159
165
  import { type RunIo, startInteractive } from "../interactive/index.js";
166
+ import type { BootOptions } from "./boot-options.js";
167
+
168
+ export type { BootOptions, HeadlessSamplingOverrides } from "./boot-options.js";
169
+
160
170
  import {
161
171
  detectPlatformKeybindingWarnings,
162
172
  detectTerminalKeySupport,
@@ -165,12 +175,13 @@ import {
165
175
  validateKeybindings,
166
176
  } from "../interactive/keybinding-manager.js";
167
177
  import { subscribeLoopGuardStop } from "../interactive/loop-guard-interrupt.js";
178
+ import { BUILTIN_SLASH_COMMANDS } from "../interactive/slash-commands.js";
168
179
  import { createToolProseRegistration } from "../interactive/tool-prose-registration.js";
169
180
  import { type AskUserHandler, cancelledAskUserResult } from "../tools/ask-user.js";
170
181
  import { registerAllTools } from "../tools/bootstrap.js";
171
182
  import { isGitRepository, recoverCleanupReadyCompeteGroups } from "../tools/compete-worktrees.js";
172
- import { createDispatchBackgroundRegistry } from "../tools/dispatch.js";
173
- import { coalescePathSink, createFileMutationObserver, createSkillActivationObserver } from "../tools/observers.js";
183
+ import { createDispatchBackgroundRegistry } from "../tools/dispatch-background.js";
184
+ import { createFileMutationObserver, createSkillActivationObserver } from "../tools/observers.js";
174
185
  import { createRegistry } from "../tools/registry.js";
175
186
 
176
187
  export interface BootResult {
@@ -178,57 +189,6 @@ export interface BootResult {
178
189
  bootTimeMs: number;
179
190
  }
180
191
 
181
- export interface HeadlessSamplingOverrides {
182
- temperature?: number;
183
- topP?: number;
184
- topK?: number;
185
- minP?: number;
186
- presencePenalty?: number;
187
- frequencyPenalty?: number;
188
- repeatPenalty?: number;
189
- }
190
-
191
- export interface BootOptions {
192
- /** Process-lifetime API key override applied to the active orchestrator target. */
193
- apiKey?: string;
194
- /** Suppress CLIO-CODER.md project-context injection for this run. */
195
- noContextFiles?: boolean;
196
- noSkills?: boolean;
197
- skillPaths?: ReadonlyArray<string>;
198
- /** Run one non-interactive main-agent turn. */
199
- headless?: {
200
- prompt: string;
201
- images?: ReadonlyArray<ImageContent>;
202
- workingContextPaths?: ReadonlyArray<string>;
203
- mode?: "text" | "json";
204
- jsonEvents?: "full" | "terminal";
205
- target?: string;
206
- model?: string;
207
- thinking?: ThinkingLevel;
208
- autonomy?: AutonomyLevel;
209
- sampling?: HeadlessSamplingOverrides;
210
- noSkills?: boolean;
211
- skillPaths?: ReadonlyArray<string>;
212
- steerChannel?: string;
213
- /**
214
- * Append this turn to an existing session instead of starting a fresh
215
- * one. `latest` means the most recent session recorded for this
216
- * workspace. A named session that cannot be resumed fails the run
217
- * rather than silently starting a new one, because a caller that asked
218
- * to continue a conversation would otherwise get an answer with no
219
- * history behind it.
220
- */
221
- resumeSession?: { kind: "id"; id: string } | { kind: "latest" };
222
- };
223
- /** Serve Clio as an Agent Client Protocol v1 agent over JSON-RPC stdio. */
224
- acp?: {
225
- transport?: AcpJsonRpcPeerTransport;
226
- transportOptions?: StdioServerTransportOptions;
227
- /** Overrides delegation.defaults.permissionTimeoutMs for this server only. */
228
- permissionTimeoutMs?: number;
229
- };
230
- }
231
-
232
192
  /**
233
193
  * The bannered boot is the whole of what a piped or CI invocation of bare
234
194
  * `clio` shows, so it is the entire first impression for a stranger who is not
@@ -264,7 +224,6 @@ function buildBanner(): string {
264
224
  return `
265
225
  ${chalk.cyan("Clio Coder")}
266
226
  ${chalk.dim(`v${clio} · CLIO: Context Layer for I/O · HPC & scientific software`)}
267
- ${chalk.yellow.bold(EXPERIMENTAL_RELEASE_WARNING)}
268
227
  ${bannerConfigurationLine()}
269
228
  `;
270
229
  }
@@ -334,6 +293,7 @@ const LOCAL_API_KEY_FALLBACK = "clio-local-target";
334
293
  export async function resolveApiKeyForTarget(
335
294
  target: TargetDescriptor,
336
295
  providers: ProvidersContract,
296
+ signal?: AbortSignal,
337
297
  ): Promise<string | undefined> {
338
298
  const runtime = providers.getRuntime(target.runtime);
339
299
  if (!runtime) return undefined;
@@ -343,7 +303,7 @@ export async function resolveApiKeyForTarget(
343
303
  // failed on exactly the local runtimes Clio is built for, while ordinary
344
304
  // turns against the same target succeeded.
345
305
  if (!targetRequiresAuth(target, runtime)) return LOCAL_API_KEY_FALLBACK;
346
- const resolved = await providers.auth.resolveForTarget(target, runtime);
306
+ const resolved = await providers.auth.resolveForTarget(target, runtime, signal ? { signal } : undefined);
347
307
  return resolved.apiKey;
348
308
  }
349
309
 
@@ -383,7 +343,7 @@ function createBackgroundMemoryModelClient(
383
343
  return {
384
344
  async complete(request) {
385
345
  const apiKey = targetRequiresAuth(refined.target, refined.runtime)
386
- ? (await providers.auth.resolveForTarget(refined.target, refined.runtime)).apiKey
346
+ ? (await providers.auth.resolveForTarget(refined.target, refined.runtime, { signal: request.signal })).apiKey
387
347
  : LOCAL_API_KEY_FALLBACK;
388
348
  return completeEngineText({
389
349
  model,
@@ -459,7 +419,7 @@ function backgroundSharesReasoningModelWithOrchestrator(
459
419
  }
460
420
  }
461
421
 
462
- function synthesizeOrchestratorModel(
422
+ export function synthesizeOrchestratorModel(
463
423
  providers: ProvidersContract,
464
424
  target: TargetDescriptor,
465
425
  wireModelId: string,
@@ -619,8 +579,11 @@ async function runCompactionFlow(
619
579
  // Summarize only the active branch: after a /tree switch the raw file
620
580
  // still holds abandoned sibling turns, and a summary that folds them in
621
581
  // would persist abandoned content back into the active context. The full
622
- // file read stays in place for the task board, protected artifacts, and
623
- // the masking rewrite, which are session-global.
582
+ // file read stays in place for protected artifacts and the masking
583
+ // rewrite, which are session-global. The task board is not: it used to
584
+ // read the full file too (last taskLedger entry in file order, with no
585
+ // branch filter at all), which was a second, independent instance of this
586
+ // same bug. See the taskBoard wiring below for the fix.
624
587
  const activeLeafTurnId = session.tree(meta.id).leafId ?? undefined;
625
588
  const entries = filterEntriesToActivePath(readSessionEntriesForCompact(meta.id), activeLeafTurnId);
626
589
  if (entries.length === 0) return null;
@@ -674,22 +637,30 @@ function estimateTokensFromSummary(summary: string): number {
674
637
  return Math.max(1, ceilChars(summary.length));
675
638
  }
676
639
 
640
+ /**
641
+ * The post-compaction size, on the same scale as `tokensBefore`.
642
+ *
643
+ * `tokensBefore` is a whole-prompt figure: `calculateContextTokens` anchors it
644
+ * on the last assistant call's measured usage, so it carries the system prompt
645
+ * and tool schemas that compaction never touches. The after figure has to stay
646
+ * on that scale to be comparable, and the persistence layer has no model handle
647
+ * to re-measure with, so it is arithmetic on that same scale: drop what stops
648
+ * being replayed and add the summary that replaces it.
649
+ *
650
+ * Estimating it from the rebuilt message list instead reported `tokensBefore`
651
+ * back unchanged, which is what made /tree render "~16276 -> ~16276 tokens"
652
+ * beside a footer that said 16276 -> 11008 for the same compaction. That
653
+ * estimator anchors on the newest assistant usage, and the retained suffix
654
+ * still holds the assistant message whose usage describes the pre-compaction
655
+ * prompt. Anchoring on it reports precisely the number compaction removed.
656
+ */
677
657
  function estimateTokensAfterCompaction(entries: ReadonlyArray<SessionEntry>, result: CompactResult): number {
678
- const synthetic: CompactionSummaryEntry = {
679
- kind: "compactionSummary",
680
- turnId: "__pending_compaction__",
681
- parentTurnId: result.firstKeptTurnId ?? null,
682
- timestamp: new Date(0).toISOString(),
683
- summary: result.summary,
684
- tokensBefore: result.tokensBefore,
685
- firstKeptTurnId: result.firstKeptTurnId ?? "",
686
- messagesSummarized: result.messagesSummarized,
687
- isSplitTurn: result.isSplitTurn,
688
- tokensAfter: estimateTokensFromSummary(result.summary),
689
- };
690
- const messages = buildReplayAgentMessagesFromTurns([...entries, synthetic]);
691
- const tokens = estimateAgentContextTokens({ messages });
692
- return tokens > 0 ? tokens : estimateTokensFromSummary(result.summary);
658
+ let droppedTokens = 0;
659
+ for (const entry of entries.slice(0, result.firstKeptEntryIndex)) droppedTokens += estimateTokens(entry);
660
+ const summaryTokens = estimateTokensFromSummary(result.summary);
661
+ // The summary alone is the floor: a session whose dropped estimate exceeds
662
+ // the measured anchor must not report a negative or sub-summary context.
663
+ return Math.max(summaryTokens, result.tokensBefore - droppedTokens + summaryTokens);
693
664
  }
694
665
 
695
666
  /**
@@ -733,7 +704,22 @@ export function advanceScopedTarget(
733
704
  }
734
705
 
735
706
  export async function bootOrchestrator(options: BootOptions = {}): Promise<BootResult> {
736
- const timer = new StartupTimer();
707
+ const bootStdout = (text: string): void => {
708
+ if (options.terminalLease) options.terminalLease.writeDiagnostic("stdout", text);
709
+ else process.stdout.write(text);
710
+ };
711
+ const bootStderr = (text: string): void => {
712
+ if (options.terminalLease) options.terminalLease.writeDiagnostic("stderr", text);
713
+ else process.stderr.write(text);
714
+ };
715
+ const timer = new StartupTimer(
716
+ options.terminalLease
717
+ ? (phase) => {
718
+ const line = formatBootTrace(phase);
719
+ if (line) options.terminalLease?.deferDiagnostic("stderr", line);
720
+ }
721
+ : undefined,
722
+ );
737
723
  const bus = getSharedBus();
738
724
  const termination = getTerminationCoordinator();
739
725
  installBusTracer();
@@ -776,54 +762,56 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
776
762
  preserveAllActive: pendingGate.errors.length > 0,
777
763
  });
778
764
  for (const failure of recovery.failed) {
779
- process.stderr.write(`[dispatch] compete recovery preserved ${failure.group}: ${failure.message}\n`);
765
+ bootStderr(`[dispatch] compete recovery preserved ${failure.group}: ${failure.message}\n`);
780
766
  }
781
767
  } catch (err) {
782
- process.stderr.write(
783
- `[dispatch] compete recovery failed closed: ${err instanceof Error ? err.message : String(err)}\n`,
784
- );
768
+ bootStderr(`[dispatch] compete recovery failed closed: ${err instanceof Error ? err.message : String(err)}\n`);
785
769
  }
786
770
  }
787
771
 
788
772
  let effectiveSettingsForDispatch: (() => Readonly<ClioSettings>) | null = null;
789
773
  let protectedArtifactStateForDispatch: (() => ProtectedArtifactState) | null = null;
790
774
 
791
- const result = await loadDomains([
792
- ConfigDomainModule,
793
- ExtensionsDomainModule,
794
- InteropDomainModule,
795
- createResourcesDomainModule({
796
- skills: () => ({
797
- disableDiscovery: options.noSkills === true || options.headless?.noSkills === true,
798
- ...(options.skillPaths && options.skillPaths.length > 0
799
- ? { explicitSkillPaths: options.skillPaths }
800
- : options.headless?.skillPaths && options.headless.skillPaths.length > 0
801
- ? { explicitSkillPaths: options.headless.skillPaths }
802
- : {}),
775
+ const result = await loadDomains(
776
+ [
777
+ options.startupSettings ? createConfigDomainModule(options.startupSettings) : ConfigDomainModule,
778
+ ExtensionsDomainModule,
779
+ InteropDomainModule,
780
+ createResourcesDomainModule({
781
+ reservedPromptNames: new Set(BUILTIN_SLASH_COMMANDS.map((entry) => entry.name)),
782
+ skills: () => ({
783
+ disableDiscovery: options.noSkills === true || options.headless?.noSkills === true,
784
+ ...(options.skillPaths && options.skillPaths.length > 0
785
+ ? { explicitSkillPaths: options.skillPaths }
786
+ : options.headless?.skillPaths && options.headless.skillPaths.length > 0
787
+ ? { explicitSkillPaths: options.headless.skillPaths }
788
+ : {}),
789
+ }),
803
790
  }),
804
- }),
805
- ShareDomainModule,
806
- createContextDomainModule({ noContextFiles: options.noContextFiles === true }),
807
- ProvidersDomainModule,
808
- SafetyDomainModule,
809
- createPromptsDomainModule({
810
- noContextFiles: options.noContextFiles === true,
811
- }),
812
- AgentsDomainModule,
813
- MiddlewareDomainModule,
814
- SessionDomainModule,
815
- ObservabilityDomainModule,
816
- SchedulingDomainModule,
817
- // Dispatch resolves worker targets through the session's effective
818
- // settings view once it exists (assigned below, after the config
819
- // contract loads); until then it falls back to the shared snapshot.
820
- createDispatchDomainModule({
821
- getSettings: () => effectiveSettingsForDispatch?.(),
822
- getProtectedArtifactState: () => protectedArtifactStateForDispatch?.() ?? { artifacts: [] },
823
- autonomyOverride: options.headless?.autonomy !== undefined,
824
- }),
825
- LifecycleDomainModule,
826
- ]);
791
+ ShareDomainModule,
792
+ createContextDomainModule({ noContextFiles: options.noContextFiles === true }),
793
+ ProvidersDomainModule,
794
+ SafetyDomainModule,
795
+ createPromptsDomainModule({
796
+ noContextFiles: options.noContextFiles === true,
797
+ }),
798
+ AgentsDomainModule,
799
+ MiddlewareDomainModule,
800
+ SessionDomainModule,
801
+ ObservabilityDomainModule,
802
+ SchedulingDomainModule,
803
+ // Dispatch resolves worker targets through the session's effective
804
+ // settings view once it exists (assigned below, after the config
805
+ // contract loads); until then it falls back to the shared snapshot.
806
+ createDispatchDomainModule({
807
+ getSettings: () => effectiveSettingsForDispatch?.(),
808
+ getProtectedArtifactState: () => protectedArtifactStateForDispatch?.() ?? { artifacts: [] },
809
+ autonomyOverride: options.headless?.autonomy !== undefined,
810
+ }),
811
+ LifecycleDomainModule,
812
+ ],
813
+ { diagnostic: bootStderr },
814
+ );
827
815
  timer.mark(`domains loaded (${result.loaded.length})`);
828
816
 
829
817
  const dispatch = result.getContract<DispatchContract>("dispatch");
@@ -842,8 +830,8 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
842
830
  const acpMode = options.acp !== undefined;
843
831
  const interactive = !options.headless && !acpMode && process.env.CLIO_CODER_INTERACTIVE === "1";
844
832
  if (!interactive && !options.headless && !acpMode) {
845
- process.stdout.write(buildBanner());
846
- if (process.env.CLIO_CODER_TIMING === "1") process.stdout.write(`${timer.report()}\n`);
833
+ bootStdout(buildBanner());
834
+ if (process.env.CLIO_CODER_TIMING === "1") bootStdout(`${timer.report()}\n`);
847
835
  }
848
836
 
849
837
  const config = result.getContract<ConfigContract>("config");
@@ -852,7 +840,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
852
840
 
853
841
  if (options.apiKey) {
854
842
  if (!providers) {
855
- process.stderr.write("Clio Coder: --api-key supplied but providers domain unavailable; ignoring.\n");
843
+ bootStderr("Clio Coder: --api-key supplied but providers domain unavailable; ignoring.\n");
856
844
  } else {
857
845
  const settingsNow = applyHeadlessSettingsOverlay(config?.get() ?? readSettings(), options.headless);
858
846
  const activeTargetId = settingsNow.orchestrator?.target;
@@ -861,13 +849,13 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
861
849
  if (target && runtime) {
862
850
  providers.auth.setRuntimeOverrideForTarget(target, runtime, options.apiKey);
863
851
  } else {
864
- process.stderr.write("Clio Coder: --api-key supplied but no active orchestrator target is configured; ignoring.\n");
852
+ bootStderr("Clio Coder: --api-key supplied but no active orchestrator target is configured; ignoring.\n");
865
853
  }
866
854
  }
867
855
  }
868
856
 
869
857
  if (!interactive && !options.headless && !acpMode) {
870
- process.stdout.write(`${chalk.dim(" (non-interactive boot. pass CLIO_CODER_INTERACTIVE=1 to launch the TUI.)")}\n`);
858
+ bootStdout(`${chalk.dim(" (non-interactive boot. pass CLIO_CODER_INTERACTIVE=1 to launch the TUI.)")}\n`);
871
859
  await termination.shutdown(0);
872
860
  return { exitCode: 0, bootTimeMs: timer.snapshot().totalMs };
873
861
  }
@@ -897,7 +885,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
897
885
  if (interopHint !== null) initialNotices.push(interopHint);
898
886
  }
899
887
  if (!providers || !dispatch || !observability || !safety || !middleware) {
900
- process.stderr.write(
888
+ bootStderr(
901
889
  "Clio Coder: chat mode requires safety + middleware + providers + dispatch + observability contracts; aborting.\n",
902
890
  );
903
891
  await termination.shutdown(1);
@@ -931,12 +919,12 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
931
919
  } catch (err) {
932
920
  const detail = err instanceof Error ? err.message : String(err);
933
921
  if (requestedResume !== undefined) headlessResumeFailure = `failed to resume session ${resumeId}: ${detail}`;
934
- else process.stderr.write(`Clio Coder: failed to resume session ${resumeId}: ${detail}\n`);
922
+ else bootStderr(`Clio Coder: failed to resume session ${resumeId}: ${detail}\n`);
935
923
  }
936
924
  }
937
925
  Reflect.deleteProperty(process.env, "CLIO_CODER_RESUME_SESSION_ID");
938
926
  if (headlessResumeFailure !== null) {
939
- process.stderr.write(`clio-coder run: ${headlessResumeFailure}\n`);
927
+ bootStderr(`clio-coder run: ${headlessResumeFailure}\n`);
940
928
  await termination.shutdown(2);
941
929
  return { exitCode: 2, bootTimeMs: timer.snapshot().totalMs };
942
930
  }
@@ -1051,6 +1039,14 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1051
1039
  middleware.registerHook(
1052
1040
  createSkillsReminderRegistration({
1053
1041
  countModelVisibleSkills: () => modelVisibleSkills(resources.skills(process.cwd()).items).length,
1042
+ // Same lookup context(scope="skills") lists under its Marketplace
1043
+ // heading, minus what is already installed, so the count the
1044
+ // reminder quotes is the count the listing will show.
1045
+ countInstallableSkills: () => {
1046
+ const installed = new Set(resources.skills(process.cwd()).items.map((skill) => skill.name));
1047
+ return discoverMarketplaceSkills({ cwd: process.cwd() }).skills.filter((skill) => !installed.has(skill.name))
1048
+ .length;
1049
+ },
1054
1050
  }),
1055
1051
  );
1056
1052
  }
@@ -1098,9 +1094,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1098
1094
  const unsubscribeMemoryLoop = bus.on(BusChannels.LoopBlocked, () => memoryIntervention.signalLoop());
1099
1095
  termination.onDrain(() => unsubscribeMemoryLoop());
1100
1096
  if (contextDomain) {
1101
- middleware.registerHook(
1102
- createFileMutationObserver(coalescePathSink((paths) => contextDomain.noteFileChanges(paths))),
1103
- );
1097
+ middleware.registerHook(createFileMutationObserver(({ paths }) => contextDomain.noteFileChanges(paths)));
1104
1098
  }
1105
1099
  // User-defined hooks: extensions and the project (.clio-coder/hooks.yaml,
1106
1100
  // .clio-coder/hooks.local.yaml) declare a conservative, receipted hook set on the
@@ -1167,19 +1161,58 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1167
1161
  // interview fall back to their stated defaults when the tool is absent.
1168
1162
  const askUserBridge: AskUserHandler = async (questions, invokeOptions) =>
1169
1163
  askUserHandler ? await askUserHandler(questions, invokeOptions) : cancelledAskUserResult();
1164
+ const userTasks = createUserTasksStore({ cwd: process.cwd() });
1170
1165
  // One task board per orchestrator: the tasks tool mutates it, the turn-end
1171
1166
  // open-tasks nudge reads it, and the footer/overlay render it. Keyed on the
1172
1167
  // current session id so resume/fork/new refolds it from taskLedger entries.
1168
+ // Folding through filterEntriesToActivePath (not the raw file) is what
1169
+ // keeps a /resume from picking up whichever branch happened to write its
1170
+ // taskLedger entry last in file order; readEntries here used to skip that
1171
+ // filter entirely (issue #94).
1173
1172
  const taskBoard = createTaskBoardStore({
1174
1173
  getSessionId: () => session?.current()?.id ?? null,
1175
1174
  readEntries: () => {
1176
1175
  const meta = session?.current();
1177
- return meta ? readSessionEntriesForCompact(meta.id) : [];
1176
+ if (!meta) return [];
1177
+ const leafTurnId = session?.tree(meta.id).leafId ?? undefined;
1178
+ return filterEntriesToActivePath(readSessionEntriesForCompact(meta.id), leafTurnId);
1178
1179
  },
1179
1180
  appendEntry: (entry) => {
1180
1181
  session?.appendEntry(entry);
1181
1182
  },
1182
1183
  });
1184
+ // Prime the projection once at composition. Interactive repaint paths use
1185
+ // cachedSnapshot() below, so a first paint can never become a ledger read.
1186
+ taskBoard.snapshot();
1187
+ const decisionBoard = createDecisionBoardStore({
1188
+ getSessionId: () => session?.current()?.id ?? null,
1189
+ readEntries: () => {
1190
+ const meta = session?.current();
1191
+ if (!meta) return [];
1192
+ const leafTurnId = session?.tree(meta.id).leafId ?? undefined;
1193
+ return filterEntriesToActivePath(readSessionEntriesForCompact(meta.id), leafTurnId);
1194
+ },
1195
+ getActiveLeafTurnId: () => {
1196
+ const meta = session?.current();
1197
+ return meta ? (session?.tree(meta.id).leafId ?? null) : null;
1198
+ },
1199
+ appendEntry: (entry) => {
1200
+ if (!session) throw new Error("decision board: no session ledger is available");
1201
+ session.appendEntry(entry);
1202
+ },
1203
+ });
1204
+ // getSessionId alone never notices a /tree switch: it moves the active
1205
+ // append point inside the same session, so the id-keyed cache above kept
1206
+ // showing the abandoned branch's board (issue #94). SessionTurnSwitched is
1207
+ // the signal that switch actually happened; invalidate() forces the next
1208
+ // read to refold from the now-current leaf.
1209
+ bus.on(BusChannels.SessionTurnSwitched, () => {
1210
+ taskBoard.invalidate();
1211
+ // The tree switch is the I/O boundary: refold eagerly here so the 250-ms
1212
+ // island ticker remains a cache-only consumer after changing branches.
1213
+ taskBoard.snapshot();
1214
+ decisionBoard.invalidate();
1215
+ });
1183
1216
  // Link in-flight dispatch runs to the live board via the ledger's
1184
1217
  // activeRunIds field: a run is tracked from the moment its child process is
1185
1218
  // live until it finalizes either way. attach/detach are no-ops when no board
@@ -1205,6 +1238,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1205
1238
  registerAllTools(toolRegistry, {
1206
1239
  ...(session ? { session } : {}),
1207
1240
  taskBoard,
1241
+ userTasks,
1208
1242
  dispatch,
1209
1243
  bus,
1210
1244
  ...(interactive ? { askUser: askUserBridge } : {}),
@@ -1256,6 +1290,9 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1256
1290
  let cachedSettingsView: ClioSettings | null = null;
1257
1291
  const bumpSessionState = (): void => {
1258
1292
  sessionStateGeneration += 1;
1293
+ // Child-process seams read the effective setting from the environment,
1294
+ // and the session view may override the saved value.
1295
+ setGitCommitAttributionEnabled(getCurrentSettings().attribution.gitCommits);
1259
1296
  };
1260
1297
  const getCurrentSettings = (): ClioSettings => {
1261
1298
  // Recents live in the data dir (core/recent-models.ts), never in
@@ -1280,6 +1317,11 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1280
1317
  return view;
1281
1318
  };
1282
1319
  effectiveSettingsForDispatch = getCurrentSettings;
1320
+ bumpSessionState();
1321
+ // The config bundle publishes the saved value on reload; a session-scoped
1322
+ // override must win, so re-derive from the session view after it.
1323
+ const unsubscribeCommitAttributionSync = bus.on(BusChannels.ConfigHotReload, () => bumpSessionState());
1324
+ termination.onDrain(() => unsubscribeCommitAttributionSync());
1283
1325
  const getTaskMemorySeedOffer = (): { source: string; count: number } | null => {
1284
1326
  return taskMemoryHandoffSeedOffer(process.cwd(), getCurrentSettings().memory.intervention.enabled);
1285
1327
  };
@@ -1333,11 +1375,9 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1333
1375
  * interleave and drop each other's patches.
1334
1376
  */
1335
1377
  const persistSavedMutation = (mutator: SettingsMutator): void => {
1336
- if (config?.update) {
1337
- config.update(mutator);
1338
- return;
1339
- }
1340
- updateSettings(mutator);
1378
+ if (config?.update) config.update(mutator);
1379
+ else updateSettings(mutator);
1380
+ bumpSessionState();
1341
1381
  };
1342
1382
  /**
1343
1383
  * Apply a routing change with one consistent scope: it takes effect in this
@@ -1353,6 +1393,38 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1353
1393
  mutateSaved?.(saved);
1354
1394
  });
1355
1395
  };
1396
+ const readAcpSafeSettings = (): AcpSafeSettingsSnapshot => {
1397
+ const settings = getCurrentSettings();
1398
+ return {
1399
+ target: settings.orchestrator.target,
1400
+ model: settings.orchestrator.model,
1401
+ thinkingLevel: settings.orchestrator.thinkingLevel ?? "off",
1402
+ autonomy: settings.autonomy,
1403
+ };
1404
+ };
1405
+ /**
1406
+ * ACP safe settings are one atomic persisted mutation followed by infallible
1407
+ * in-process routing assignment. Persisting first avoids reporting a live
1408
+ * route that failed to become the future-session default.
1409
+ */
1410
+ const commitAcpSafeSettings = (patch: AcpSafeSettingsPatch): AcpSafeSettingsSnapshot => {
1411
+ const orchestrator: NonNullable<RoutingPatch["orchestrator"]> = {};
1412
+ if (patch["orchestrator.target"] !== undefined) orchestrator.target = patch["orchestrator.target"];
1413
+ if (patch["orchestrator.model"] !== undefined) orchestrator.model = patch["orchestrator.model"];
1414
+ if (patch["orchestrator.thinkingLevel"] !== undefined) {
1415
+ orchestrator.thinkingLevel = patch["orchestrator.thinkingLevel"];
1416
+ }
1417
+ const routingPatch: RoutingPatch | null = Object.keys(orchestrator).length > 0 ? { orchestrator } : null;
1418
+ persistSavedMutation((saved) => {
1419
+ if (routingPatch !== null) mergeRoutingPatchIntoSettings(saved, routingPatch);
1420
+ if (patch.autonomy !== undefined) saved.autonomy = patch.autonomy;
1421
+ });
1422
+ if (routingPatch !== null) {
1423
+ applyRoutingPatch(sessionRouting, routingPatch);
1424
+ bumpSessionState();
1425
+ }
1426
+ return readAcpSafeSettings();
1427
+ };
1356
1428
  /**
1357
1429
  * Persist a whole-settings blob coming from the effective view (the
1358
1430
  * /settings overlay, favorites toggles). Routing edits in the blob are
@@ -1383,7 +1455,8 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1383
1455
  * every other id becomes a session override. settings.yaml is untouched.
1384
1456
  * - scope "global": apply live and persist just that leaf as the new
1385
1457
  * default, clearing any prior session override for it.
1386
- * Restart-required ids (budget.concurrency, runtimePlugins) cannot apply
1458
+ * Restart-required ids (budget.concurrency, runtimePlugins,
1459
+ * terminal.tuiMode, terminal.fullscreenScrollbar) cannot apply
1387
1460
  * live, so the overlay only offers "global" for them; the file write is what
1388
1461
  * a later restart picks up.
1389
1462
  */
@@ -1485,6 +1558,9 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1485
1558
  registerDeferredReminderSink: (sink) => {
1486
1559
  deferredMemoryReminderSink = sink;
1487
1560
  },
1561
+ onAskUserFinalized: (policy) => {
1562
+ decisionBoard.recordFinalizedInterview(policy);
1563
+ },
1488
1564
  ...(session
1489
1565
  ? {
1490
1566
  readSessionEntries: readCurrentSessionEntries,
@@ -1492,6 +1568,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1492
1568
  }
1493
1569
  : {}),
1494
1570
  toolRegistry,
1571
+ hasAttachedDispatch: () => dispatchBackground.size() > 0,
1495
1572
  });
1496
1573
 
1497
1574
  // Coordinated shutdown (SIGINT/SIGTERM, TUI quit) must abort any in-flight
@@ -1523,15 +1600,23 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1523
1600
  try {
1524
1601
  leafTurnId = session.tree(resumedMeta.id).leafId;
1525
1602
  } catch (err) {
1526
- process.stderr.write(
1603
+ bootStderr(
1527
1604
  `Clio Coder: failed to read resumed session tree ${resumedMeta.id}: ${err instanceof Error ? err.message : String(err)}\n`,
1528
1605
  );
1529
1606
  }
1530
1607
  try {
1531
- chat.resetForSession(leafTurnId, buildReplayAgentMessagesFromTurns(readCurrentSessionEntries()));
1608
+ // Scoped to the leaf resume landed on for the same reason the /resume
1609
+ // overlay is (issue #107): with a /tree pin persisted, the file still
1610
+ // holds the abandoned branch after the pinned turn, and replaying it
1611
+ // unfiltered seeds the provider with turns the next append does not
1612
+ // parent onto.
1613
+ chat.resetForSession(
1614
+ leafTurnId,
1615
+ buildReplayAgentMessagesFromTurns(readCurrentSessionEntries(), leafTurnId ? { activeLeafTurnId: leafTurnId } : {}),
1616
+ );
1532
1617
  } catch (err) {
1533
1618
  chat.resetForSession(leafTurnId);
1534
- process.stderr.write(
1619
+ bootStderr(
1535
1620
  `Clio Coder: failed to replay resumed session context ${resumedMeta.id}: ${err instanceof Error ? err.message : String(err)}\n`,
1536
1621
  );
1537
1622
  }
@@ -1575,19 +1660,50 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1575
1660
  transport,
1576
1661
  chat,
1577
1662
  ...(session ? { session } : {}),
1663
+ ...(session
1664
+ ? {
1665
+ readSessionEntries: readSessionEntriesForCompact,
1666
+ buildReplayMessages: (entries: ReadonlyArray<SessionEntry>, leafTurnId: string | null) =>
1667
+ buildReplayAgentMessagesFromTurns(entries, leafTurnId === null ? {} : { activeLeafTurnId: leafTurnId }),
1668
+ }
1669
+ : {}),
1670
+ providers,
1671
+ settings: {
1672
+ read: readAcpSafeSettings,
1673
+ commit: commitAcpSafeSettings,
1674
+ },
1578
1675
  toolRegistry,
1579
1676
  bus,
1580
1677
  autonomy: resolveBaselineAutonomy,
1678
+ routing: () => {
1679
+ const settings = getCurrentSettings();
1680
+ return {
1681
+ target: settings.orchestrator.target,
1682
+ model: settings.orchestrator.model,
1683
+ };
1684
+ },
1581
1685
  onActiveSessionAutonomyChange: (level) => {
1582
1686
  activeAcpSessionAutonomy = level;
1583
1687
  },
1584
1688
  cwd: process.cwd(),
1585
1689
  version: getVersionInfo().clio,
1690
+ // Stdout belongs to JSON-RPC. Text this process did not author, such
1691
+ // as a provider's failure body, is kept off the wire and written to
1692
+ // the unstructured stderr tail instead.
1693
+ diagnostics: (line) => {
1694
+ process.stderr.write(`[clio:acp] ${line}\n`);
1695
+ },
1586
1696
  permissionTimeoutMs:
1587
1697
  options.acp.permissionTimeoutMs ??
1588
1698
  config?.get().delegation.defaults.permissionTimeoutMs ??
1589
1699
  DEFAULT_DELEGATION_PERMISSION_TIMEOUT_MS,
1590
1700
  });
1701
+ // Same ordering the termination drain hook relies on: an aborted turn's
1702
+ // tool results still land and persist through the run's subscribers,
1703
+ // and the session writer stops in result.stop() below. Awaiting
1704
+ // settlement here makes a session append after session stop impossible
1705
+ // by ordering rather than by timing.
1706
+ await chat.whenSettled();
1591
1707
  chat.dispose();
1592
1708
  await dispatch.drain();
1593
1709
  await result.stop();
@@ -1665,7 +1781,13 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1665
1781
  }
1666
1782
  }
1667
1783
 
1668
- timer.mark("first TUI paint");
1784
+ if (options.terminalLease) {
1785
+ for (const diagnostic of options.terminalLease.takeDiagnostics()) {
1786
+ const text = diagnostic.text.trimEnd();
1787
+ if (text.length > 0) initialNotices.push(text);
1788
+ }
1789
+ }
1790
+
1669
1791
  await startInteractive({
1670
1792
  bus,
1671
1793
  providers,
@@ -1673,6 +1795,12 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1673
1795
  ...(agents ? { agents } : {}),
1674
1796
  observability,
1675
1797
  chat,
1798
+ ...(options.terminalLease
1799
+ ? {
1800
+ terminalLease: options.terminalLease,
1801
+ onHydratedFrameCommit: () => timer.mark("Stage 1 hydration"),
1802
+ }
1803
+ : { onFirstFrameCommit: () => timer.mark("first TUI paint") }),
1676
1804
  ...(initialNotices.length > 0 ? { initialNotices } : {}),
1677
1805
  ...(resources ? { resources } : {}),
1678
1806
  ...(extensions ? { extensions } : {}),
@@ -1681,7 +1809,10 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1681
1809
  toolRegistry,
1682
1810
  ...(session ? { session } : {}),
1683
1811
  ...(session ? { readSessionEntries: readCurrentSessionEntries } : {}),
1684
- getTaskBoard: () => taskBoard.snapshot(),
1812
+ getTaskBoard: () => taskBoard.cachedSnapshot(),
1813
+ getDecisionBoard: () => decisionBoard.snapshot(),
1814
+ supersedeDecision: (interviewId, key, correction) => decisionBoard.supersede(interviewId, key, correction),
1815
+ userTasks,
1685
1816
  getTaskMemoryStatus: () => {
1686
1817
  ensureTaskMemorySession();
1687
1818
  const settings = getCurrentSettings();
@@ -1837,6 +1968,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1837
1968
  try {
1838
1969
  const previousSessionId = session.current()?.id ?? null;
1839
1970
  session.resume(sessionId);
1971
+ taskBoard.snapshot();
1840
1972
  if (previousSessionId !== sessionId) ensureTaskMemorySession();
1841
1973
  } catch (err) {
1842
1974
  process.stderr.write(
@@ -1845,12 +1977,18 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1845
1977
  }
1846
1978
  },
1847
1979
  onNewSession: () => {
1848
- session.create({ cwd: process.cwd() });
1980
+ const settings = getCurrentSettings();
1981
+ const input: { cwd: string; target?: string; model?: string } = { cwd: process.cwd() };
1982
+ if (settings.orchestrator.target) input.target = settings.orchestrator.target;
1983
+ if (settings.orchestrator.model) input.model = settings.orchestrator.model;
1984
+ session.create(input);
1985
+ taskBoard.snapshot();
1849
1986
  ensureTaskMemorySession();
1850
1987
  },
1851
1988
  onForkSession: (parentTurnId) => {
1852
1989
  try {
1853
1990
  session.fork(parentTurnId);
1991
+ taskBoard.snapshot();
1854
1992
  ensureTaskMemorySession();
1855
1993
  } catch (err) {
1856
1994
  process.stderr.write(