@iowarp/clio-coder 0.4.1 → 0.4.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 (437) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/CONTRIBUTING.md +59 -36
  3. package/README.md +404 -472
  4. package/SECURITY.md +2 -1
  5. package/dist/{acp-ZILU3AUO.js → acp-TMDQZDIG.js} +7 -7
  6. package/dist/{agents-HYWGBGQR.js → agents-5N5NG3XG.js} +28 -28
  7. package/dist/assets/codewiki.json +1 -1
  8. package/dist/{auth-N3QT7CBO.js → auth-Z5CCBXKQ.js} +8 -9
  9. package/dist/{builtins-UJLMOVOV.js → builtins-K6TNDT24.js} +4 -4
  10. package/dist/{chunk-GVQJ5CCZ.js → chunk-2HFQNRV3.js} +7 -7
  11. package/dist/{chunk-QMXC4JB7.js → chunk-2NHR3NAY.js} +163 -1401
  12. package/dist/chunk-2X4RYJTJ.js +39 -0
  13. package/dist/{chunk-Y45G3AXC.js → chunk-2Z2IKEXI.js} +6 -10
  14. package/dist/{chunk-EIMVLWB3.js → chunk-34BHNEE3.js} +7 -3
  15. package/dist/{chunk-GIZNH63R.js → chunk-35MSIRKH.js} +9 -4
  16. package/dist/chunk-3EBYEESD.js +314 -0
  17. package/dist/{chunk-CTJ4RNAA.js → chunk-3F7VUY77.js} +2 -2
  18. package/dist/{chunk-AP73CFDC.js → chunk-3KIPBMUA.js} +2 -2
  19. package/dist/{chunk-J5LZHVIT.js → chunk-3M6DQK6S.js} +113 -35
  20. package/dist/{chunk-VEGN6WIQ.js → chunk-462T4EGZ.js} +2 -2
  21. package/dist/{chunk-AFKWHWXF.js → chunk-4JDLP6ZS.js} +33 -16
  22. package/dist/{chunk-6FN3E6KX.js → chunk-4O6MANBS.js} +2 -2
  23. package/dist/{chunk-AKB4GYDL.js → chunk-54ODD65L.js} +5 -5
  24. package/dist/{chunk-BBTJOK6Y.js → chunk-5KW52TEP.js} +3 -3
  25. package/dist/{chunk-6CCS4G3W.js → chunk-5PFYMY2V.js} +2 -2
  26. package/dist/chunk-77QIVUZB.js +1334 -0
  27. package/dist/{chunk-7OBGU7UB.js → chunk-7BHIY2MW.js} +7 -13
  28. package/dist/{chunk-3QSOM6PA.js → chunk-AZ4WMN4W.js} +2 -2
  29. package/dist/{chunk-6NJQITNH.js → chunk-B74PXLU7.js} +6 -3
  30. package/dist/{chunk-R23Z6K6I.js → chunk-B7HM5Z7T.js} +15 -15
  31. package/dist/{chunk-R32CLGZ6.js → chunk-BO7Y52RY.js} +81 -20
  32. package/dist/{chunk-UEDMSP56.js → chunk-BYMNWQ7O.js} +123 -148
  33. package/dist/{chunk-ZJLUDYFY.js → chunk-CRFOIAX3.js} +4 -4
  34. package/dist/{chunk-2NM363SV.js → chunk-CYZW7JHJ.js} +7 -7
  35. package/dist/{chunk-6HMJX2VU.js → chunk-DYHAXKHD.js} +38 -10
  36. package/dist/{chunk-THYWACCR.js → chunk-DZAW46HP.js} +3 -3
  37. package/dist/{chunk-FYUN5KZ3.js → chunk-DZEK6CJN.js} +17 -17
  38. package/dist/{chunk-3I5NY75V.js → chunk-E7GT7O5N.js} +5 -5
  39. package/dist/{chunk-VKFQTNDV.js → chunk-F2I26BDK.js} +4 -4
  40. package/dist/{chunk-HLW2MRKE.js → chunk-F4EKGO4N.js} +3 -1
  41. package/dist/{chunk-IXJT6DCX.js → chunk-FVDGR2ZL.js} +3 -3
  42. package/dist/{chunk-TZSKNMZG.js → chunk-GTUD2WMY.js} +2 -1
  43. package/dist/{chunk-7EPLI7VL.js → chunk-HIICAHCJ.js} +2 -2
  44. package/dist/{chunk-E67WX76H.js → chunk-HKMD33FO.js} +29 -80
  45. package/dist/chunk-HLAFFSEK.js +360 -0
  46. package/dist/{chunk-UAPGZHYC.js → chunk-I64IFBLB.js} +9 -2
  47. package/dist/{chunk-XKA2ICR3.js → chunk-I66ZTYNP.js} +440 -175
  48. package/dist/{chunk-7PWAODYW.js → chunk-I7XBWTYH.js} +2 -2
  49. package/dist/{chunk-PVAMAVBB.js → chunk-IDNA72AH.js} +102 -2
  50. package/dist/{chunk-GCSMB2KY.js → chunk-IKOZFYBN.js} +1 -1
  51. package/dist/{chunk-2VG7KLYV.js → chunk-IKSLQ4XV.js} +5460 -3241
  52. package/dist/{chunk-QKIFBZKT.js → chunk-IMXMHHMQ.js} +166 -25
  53. package/dist/{chunk-74YWRRU5.js → chunk-JBCS7CRR.js} +2 -2
  54. package/dist/{chunk-BDPT6GTK.js → chunk-JWJGP5DQ.js} +2 -2
  55. package/dist/{chunk-K6BF4U2H.js → chunk-KKOJXO6R.js} +62 -14
  56. package/dist/chunk-KPXDY6QF.js +47 -0
  57. package/dist/{chunk-ABLSQ6JX.js → chunk-LJID3DYZ.js} +7 -1
  58. package/dist/{chunk-VKRH2TCS.js → chunk-M2DAX4F6.js} +2 -2
  59. package/dist/{chunk-6I5ILFOF.js → chunk-M2WXEHER.js} +2 -2
  60. package/dist/{chunk-YPI3QQCF.js → chunk-MCEPRMZW.js} +2 -4
  61. package/dist/{chunk-N5UK64DP.js → chunk-MCMZMDAC.js} +2 -2
  62. package/dist/{chunk-Y4CAGMM6.js → chunk-MNJGS2IN.js} +5 -6
  63. package/dist/{chunk-TVHHYFHE.js → chunk-NEDJ26B5.js} +2 -2
  64. package/dist/{chunk-U2WB7TZS.js → chunk-NMJXSHBJ.js} +97 -85
  65. package/dist/{chunk-HUAS7ITX.js → chunk-O3YUNJZ2.js} +13 -21
  66. package/dist/{chunk-MA3H6DM5.js → chunk-P75RZCJW.js} +25 -3
  67. package/dist/{chunk-IG7BCQBA.js → chunk-PGF63K6I.js} +2 -2
  68. package/dist/chunk-PJX3WQUQ.js +42 -0
  69. package/dist/{chunk-6DWBAZ5U.js → chunk-Q4XWMHX6.js} +4 -6
  70. package/dist/{chunk-OJTRZGR3.js → chunk-QQLGQY2A.js} +8 -8
  71. package/dist/{chunk-J4HBWF6Y.js → chunk-RLYRBIYQ.js} +115 -20
  72. package/dist/{chunk-NLFAQR7Z.js → chunk-S66XZJOF.js} +3 -23
  73. package/dist/{chunk-C537JADH.js → chunk-SSEYRH53.js} +6 -7
  74. package/dist/chunk-SZAA6XDG.js +30 -0
  75. package/dist/{chunk-MOPSG2X7.js → chunk-TPEQIQIE.js} +6 -6
  76. package/dist/{chunk-JA5QWE4Z.js → chunk-UBRFI4HS.js} +1879 -1650
  77. package/dist/{chunk-BTGG6BG2.js → chunk-UH347SHR.js} +154 -15
  78. package/dist/{chunk-5YHDIDBP.js → chunk-UH632ZYL.js} +2 -2
  79. package/dist/{chunk-BWW4HLO4.js → chunk-UXCU4E3T.js} +8 -6
  80. package/dist/{chunk-6VC4OV3Z.js → chunk-VIA6RFQZ.js} +3 -11
  81. package/dist/{chunk-ZAZB4JMW.js → chunk-VKPAQYEB.js} +27 -8
  82. package/dist/{chunk-UXN6JT4W.js → chunk-W4YEMFBX.js} +2 -2
  83. package/dist/{chunk-TD3PGPQA.js → chunk-W6NIE6OW.js} +2 -2
  84. package/dist/{chunk-TVH4ONAM.js → chunk-X7IARSHT.js} +3 -3
  85. package/dist/{chunk-PJJ6MY27.js → chunk-XE3PCIXH.js} +3 -3
  86. package/dist/{chunk-FEFIFZTL.js → chunk-XGDPUNND.js} +2 -2
  87. package/dist/{chunk-SCYB3HA4.js → chunk-XOXV5GKE.js} +51 -16
  88. package/dist/{chunk-QTFGO774.js → chunk-XQRY4DTA.js} +24 -11
  89. package/dist/{chunk-BJGUKIG4.js → chunk-YJISEZKC.js} +2 -2
  90. package/dist/{chunk-GPPB3JBE.js → chunk-ZGNYYXQ6.js} +2 -2
  91. package/dist/{chunk-SINK3QR6.js → chunk-ZNT2M6TG.js} +7 -7
  92. package/dist/{chunk-7RY5VZPH.js → chunk-ZW4HH5JJ.js} +6 -6
  93. package/dist/cli/index.js +33 -32
  94. package/dist/{clio-IT3G3VQH.js → clio-7VB377CC.js} +7 -7
  95. package/dist/{code-nav-RK6S7F6E.js → code-nav-YVLCYA7V.js} +85 -17
  96. package/dist/{config-3QZRWZJF.js → config-4HVOS65E.js} +88 -43
  97. package/dist/{configure-FL7Y3KJF.js → configure-PIWO7B24.js} +10 -10
  98. package/dist/{context-5HE7ODYK.js → context-IYEHL3WQ.js} +33 -31
  99. package/dist/{context-XNHL75JV.js → context-KQYIWPWT.js} +47 -34
  100. package/dist/{context-KYQFRVDC.js → context-N6ZE3LGJ.js} +11 -11
  101. package/dist/{context-clear-N545L53A.js → context-clear-G4OGZJDS.js} +33 -31
  102. package/dist/{context-working-set-QHKXSV2F.js → context-working-set-BWLF6LJP.js} +7 -7
  103. package/dist/{dispatch-runner-RGIE5PCT.js → dispatch-runner-2QQAITS3.js} +38 -38
  104. package/dist/{docs-5NAF6AU7.js → docs-PD3EXDKU.js} +21 -20
  105. package/dist/{doctor-ZGPEGHIP.js → doctor-LHBD36VU.js} +23 -22
  106. package/dist/{eval-GXLL44RD.js → eval-C45FYRJ6.js} +21 -20
  107. package/dist/{eval-inventory-HBWSWQOK.js → eval-inventory-6DEJPLBF.js} +2 -2
  108. package/dist/{evidence-HWLBRH3Q.js → evidence-6SHONYAF.js} +30 -28
  109. package/dist/{evolve-FTZBMNVW.js → evolve-KRKMV72X.js} +30 -28
  110. package/dist/{extensions-VHRBEID7.js → extensions-KPZ2UHBB.js} +5 -3
  111. package/dist/{fleet-CKZHJWZJ.js → fleet-IVTCKDHT.js} +62 -61
  112. package/dist/{fleet-commands-EXDXBMV6.js → fleet-commands-EDWL3IT7.js} +5 -5
  113. package/dist/{fleet-decisions-OTHB6KRL.js → fleet-decisions-YP3YEFGK.js} +4 -4
  114. package/dist/{fleet-graph-YTEZUCUT.js → fleet-graph-ZFWKHY2M.js} +16 -14
  115. package/dist/{fleet-inspect-SS6YMDCK.js → fleet-inspect-FVUNCBML.js} +31 -29
  116. package/dist/{fleet-preflight-PBY4VYOM.js → fleet-preflight-UN5XED4R.js} +2 -2
  117. package/dist/{fleet-validate-KMEM5L3S.js → fleet-validate-XOWC4HSX.js} +17 -15
  118. package/dist/{fleet-verify-QD5M7E7Q.js → fleet-verify-UN3SODEL.js} +30 -28
  119. package/dist/{fleet-view-WAMJYNDT.js → fleet-view-TWHJKCN6.js} +31 -29
  120. package/dist/{init-5XQRBOFV.js → init-T2QORQ3Y.js} +50 -49
  121. package/dist/{interop-34TVO25M.js → interop-IN5I2A66.js} +5 -5
  122. package/dist/{library-3QY6KF57.js → library-LSCATDLZ.js} +15 -13
  123. package/dist/{memory-L4UTIIIW.js → memory-HYOKAGGJ.js} +31 -29
  124. package/dist/{models-ZVX3QOWE.js → models-2GPMFYCM.js} +22 -21
  125. package/dist/{monitor-CEKVSYTS.js → monitor-E4ASVUJH.js} +34 -32
  126. package/dist/{orchestrator-77BAP6BC.js → orchestrator-DDMPR3PY.js} +984 -583
  127. package/dist/{panes-7STHOAUJ.js → panes-E3RUXOW5.js} +4 -4
  128. package/dist/{panes-SHAUIRXY.js → panes-IXKLOKA2.js} +23 -8
  129. package/dist/{reset-EOLM7GVE.js → reset-OAQP3W4O.js} +4 -4
  130. package/dist/{resources-74GKTLSF.js → resources-OTRSN34L.js} +15 -13
  131. package/dist/{run-HBAUJNNZ.js → run-5DEYH5QK.js} +60 -59
  132. package/dist/{share-G3APVLVP.js → share-IHWTLO3M.js} +19 -15
  133. package/dist/{skills-35HHUKCR.js → skills-IYMXMKW4.js} +17 -15
  134. package/dist/{skills-eval-QN4HSHDC.js → skills-eval-DROHSJAR.js} +36 -36
  135. package/dist/{skills-inventory-J357J34F.js → skills-inventory-D7X4L4ZX.js} +15 -13
  136. package/dist/{slash-commands-JZZCQA32.js → slash-commands-QBM7UZ3B.js} +21 -18
  137. package/dist/{steer-XAVHJM22.js → steer-Z5DO23FJ.js} +2 -2
  138. package/dist/{targets-DSM6CY3M.js → targets-P2FUC4IL.js} +25 -28
  139. package/dist/{terminal-lease-JOPFUVEM.js → terminal-lease-YREJ3JX2.js} +5 -5
  140. package/dist/{tools-MKNWVPBH.js → tools-5B7RO6MV.js} +4 -4
  141. package/dist/{trace-ECQ7TIYZ.js → trace-YMGMUM6A.js} +55 -7
  142. package/dist/{upgrade-H7TOM7YL.js → upgrade-PXK3S2YM.js} +11 -9
  143. package/dist/{usage-X52N3IDJ.js → usage-ME5MPXGX.js} +36 -34
  144. package/dist/{verifiers-EJTVVSMA.js → verifiers-BVZ7IWOO.js} +5 -5
  145. package/dist/{verify-YJL6XET2.js → verify-5K7ZKQFC.js} +4 -4
  146. package/dist/{web-fetch-MPIFL3LL.js → web-fetch-MPARV2K7.js} +2 -2
  147. package/dist/{wiki-generate-4NDZTQ4B.js → wiki-generate-F5W5QTYY.js} +48 -47
  148. package/dist/{with-panes-OBOBFIIR.js → with-panes-BYOJCLAM.js} +51 -255
  149. package/dist/worker/entry.js +45 -30
  150. package/docs/README.md +176 -81
  151. package/docs/{acp.md → architecture/acp.md} +36 -20
  152. package/docs/{alcf-provider.md → architecture/alcf-provider.md} +8 -5
  153. package/docs/{architecture.md → architecture/architecture.md} +43 -22
  154. package/docs/{artifact-placement.md → architecture/artifact-placement.md} +26 -23
  155. package/docs/architecture/artifact-versions.md +90 -0
  156. package/docs/{capacity-and-scheduling.md → architecture/capacity-and-scheduling.md} +26 -13
  157. package/docs/{context-engine.md → architecture/context-engine.md} +25 -25
  158. package/docs/{context-working-set.md → architecture/context-working-set.md} +13 -10
  159. package/docs/{dispatch-architecture-rationale.md → architecture/dispatch-architecture-rationale.md} +12 -9
  160. package/docs/{dispatch-typed-intent.md → architecture/dispatch-typed-intent.md} +68 -46
  161. package/docs/{evidence-and-memory.md → architecture/evidence-and-memory.md} +23 -16
  162. package/docs/{middleware-and-components.md → architecture/middleware-and-components.md} +11 -5
  163. package/docs/{model-catalog.md → architecture/model-catalog.md} +40 -17
  164. package/docs/{observability.md → architecture/observability.md} +26 -13
  165. package/docs/{pi-boundary.md → architecture/pi-boundary.md} +24 -11
  166. package/docs/{prompt-envelope-and-tools.md → architecture/prompt-envelope-and-tools.md} +55 -20
  167. package/docs/{provider-adapter-cookbook.md → architecture/provider-adapter-cookbook.md} +35 -24
  168. package/docs/{safety-model.md → architecture/safety-model.md} +20 -15
  169. package/docs/{session-lifecycle.md → architecture/session-lifecycle.md} +8 -5
  170. package/docs/architecture/time-conventions.md +125 -0
  171. package/docs/{trace-store.md → architecture/trace-store.md} +13 -5
  172. package/docs/{tui-design.md → architecture/tui-design.md} +13 -13
  173. package/docs/{worker-dispatch-mechanics.md → architecture/worker-dispatch-mechanics.md} +27 -30
  174. package/docs/{built-in-agents.md → guide/built-in-agents.md} +50 -34
  175. package/docs/{commands-and-modes.md → guide/commands-and-modes.md} +65 -60
  176. package/docs/{configuration-and-targets.md → guide/configuration-and-targets.md} +227 -289
  177. package/docs/guide/configuration-reference.md +1158 -0
  178. package/docs/{environment-variables.md → guide/environment-variables.md} +31 -28
  179. package/docs/{exit-codes-and-output.md → guide/exit-codes-and-output.md} +6 -3
  180. package/docs/{extensions-and-sharing.md → guide/extensions-and-sharing.md} +41 -14
  181. package/docs/{fleet-dispatch.md → guide/fleet-dispatch.md} +39 -43
  182. package/docs/{glossary.md → guide/glossary.md} +14 -11
  183. package/docs/{installation-and-lifecycle.md → guide/installation-and-lifecycle.md} +44 -13
  184. package/docs/guide/panes-and-files.md +290 -0
  185. package/docs/{proactive-memory.md → guide/proactive-memory.md} +79 -66
  186. package/docs/{resource-library.md → guide/resource-library.md} +13 -4
  187. package/docs/{skills-marketplace.md → guide/skills-marketplace.md} +7 -3
  188. package/docs/{tool-usage.md → guide/tool-usage.md} +87 -23
  189. package/docs/{troubleshooting.md → guide/troubleshooting.md} +9 -4
  190. package/docs/{config-knobs-audit.md → history/config-knobs-audit.md} +11 -11
  191. package/docs/{release-cut-checklist.md → history/release-cut-checklist.md} +29 -2
  192. package/docs/{development-pipeline.md → process/development-pipeline.md} +24 -26
  193. package/docs/process/documentation-coverage.md +100 -0
  194. package/docs/process/documentation-guide.md +187 -0
  195. package/docs/{eval-runner.md → process/eval-runner.md} +41 -50
  196. package/docs/{evals-internal.md → process/evals-internal.md} +10 -10
  197. package/docs/{evolution.md → process/evolution.md} +2 -2
  198. package/docs/{fleet-demo-runbook.md → process/fleet-demo-runbook.md} +11 -7
  199. package/docs/{git-commit-provenance.md → process/git-commit-provenance.md} +11 -4
  200. package/docs/{performance-methodology.md → process/performance-methodology.md} +87 -69
  201. package/docs/{scientific-validation.md → process/scientific-validation.md} +4 -4
  202. package/evals/README.md +2 -2
  203. package/package.json +9 -7
  204. package/skills/README.md +46 -37
  205. package/skills/coding/ast-grep/SKILL.md +2 -2
  206. package/skills/coding/coding-standards/SKILL.md +2 -2
  207. package/skills/coding/prototype/SKILL.md +2 -2
  208. package/skills/coding/tdd/SKILL.md +2 -2
  209. package/skills/context/context-handoff/SKILL.md +2 -2
  210. package/skills/context/context-prime/SKILL.md +2 -2
  211. package/skills/git/file-ticket/SKILL.md +2 -2
  212. package/skills/git/fix-issue/SKILL.md +3 -3
  213. package/skills/git/resolve-merge-conflicts/SKILL.md +2 -2
  214. package/skills/git/ship/SKILL.md +2 -2
  215. package/skills/git/worktree-create/SKILL.md +2 -2
  216. package/skills/git/worktree-merge/SKILL.md +2 -2
  217. package/skills/meta/clio-coder-dev/SKILL.md +9 -5
  218. package/skills/meta/clio-coder-dev/evals.md +3 -2
  219. package/skills/meta/clio-coder-test/SKILL.md +102 -95
  220. package/skills/meta/clio-coder-test/evals.md +9 -4
  221. package/skills/meta/clio-coder-test/references/harness.md +100 -124
  222. package/skills/meta/clio-coder-test/references/test-map.md +77 -50
  223. package/skills/meta/credentials/SKILL.md +2 -2
  224. package/skills/meta/find-skills/SKILL.md +2 -2
  225. package/skills/meta/herdr/SKILL.md +2 -2
  226. package/skills/meta/skill-craft/SKILL.md +22 -16
  227. package/skills/planning/architecture/SKILL.md +2 -2
  228. package/skills/planning/backlog/SKILL.md +2 -2
  229. package/skills/planning/prd/SKILL.md +2 -2
  230. package/skills/planning/product-intent/SKILL.md +2 -2
  231. package/skills/planning/tech-spec/SKILL.md +2 -2
  232. package/skills/registry.yaml +62 -62
  233. package/skills/research/arxiv-literature/SKILL.md +2 -2
  234. package/skills/research/experiment-protocol/SKILL.md +2 -2
  235. package/skills/research/scientific-debugging/SKILL.md +2 -2
  236. package/skills/research/scientific-modernization/SKILL.md +2 -2
  237. package/skills/skill-marketplace.json +62 -62
  238. package/skills/workflow/cut-it/SKILL.md +2 -2
  239. package/skills/workflow/design-council/SKILL.md +2 -2
  240. package/skills/workflow/grill-me/SKILL.md +2 -2
  241. package/skills/workflow/workflow-distiller/SKILL.md +2 -2
  242. package/src/cli/args.ts +2 -2
  243. package/src/cli/bootstrap-generate.ts +1 -1
  244. package/src/cli/config-inspect.ts +65 -12
  245. package/src/cli/configure.ts +0 -4
  246. package/src/cli/docs.ts +22 -14
  247. package/src/cli/doctor-naming.ts +5 -5
  248. package/src/cli/doctor-toolchain.ts +3 -3
  249. package/src/cli/eval.ts +1 -2
  250. package/src/cli/extensions.ts +2 -1
  251. package/src/cli/fleet.ts +1 -1
  252. package/src/cli/index.ts +2 -1
  253. package/src/cli/internal-dispatch.ts +3 -4
  254. package/src/cli/panes.ts +19 -5
  255. package/src/cli/run.ts +2 -2
  256. package/src/cli/share.ts +5 -1
  257. package/src/cli/skills-eval.ts +3 -3
  258. package/src/cli/targets.ts +2 -6
  259. package/src/cli/trace.ts +55 -4
  260. package/src/cli/wiki-generate.ts +1 -1
  261. package/src/core/artifact-paths.ts +1 -1
  262. package/src/core/bash-exec.ts +131 -86
  263. package/src/core/bus-events.ts +51 -6
  264. package/src/core/config.ts +5 -1
  265. package/src/core/defaults.ts +7 -4
  266. package/src/core/dispatch-outcome.ts +16 -0
  267. package/src/core/guardrails.ts +10 -49
  268. package/src/core/prompt-hint.ts +9 -0
  269. package/src/domains/agents/builtins/architect.md +2 -3
  270. package/src/domains/agents/builtins/coder.md +3 -2
  271. package/src/domains/agents/builtins/debugger.md +2 -2
  272. package/src/domains/agents/builtins/documenter.md +2 -2
  273. package/src/domains/agents/builtins/git-master.md +1 -1
  274. package/src/domains/agents/builtins/oracle.md +1 -1
  275. package/src/domains/agents/builtins/provenance.md +1 -1
  276. package/src/domains/agents/builtins/researcher.md +1 -1
  277. package/src/domains/agents/builtins/scout.md +1 -1
  278. package/src/domains/agents/builtins/tester.md +2 -2
  279. package/src/domains/agents/builtins/verifier.md +2 -2
  280. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  281. package/src/domains/agents/catalog.ts +12 -14
  282. package/src/domains/agents/contract.ts +2 -0
  283. package/src/domains/agents/extension.ts +23 -1
  284. package/src/domains/config/keybindings.ts +8 -0
  285. package/src/domains/context/extension.ts +0 -3
  286. package/src/domains/context/working-set/path-index.ts +1 -0
  287. package/src/domains/dispatch/capability-match.ts +10 -0
  288. package/src/domains/dispatch/extension.ts +105 -22
  289. package/src/domains/dispatch/host-verification.ts +435 -39
  290. package/src/domains/dispatch/intent-requirements.ts +10 -0
  291. package/src/domains/dispatch/intent.ts +18 -1
  292. package/src/domains/dispatch/path-scope.ts +235 -24
  293. package/src/domains/dispatch/run-event-journal.ts +4 -15
  294. package/src/domains/dispatch/state.ts +2 -3
  295. package/src/domains/dispatch/transport.ts +45 -21
  296. package/src/domains/dispatch/types.ts +55 -3
  297. package/src/domains/eval/artifacts/store.ts +5 -0
  298. package/src/domains/eval/store.ts +8 -1
  299. package/src/domains/evidence/trust-status.ts +10 -1
  300. package/src/domains/extensions/contract.ts +15 -1
  301. package/src/domains/extensions/discovery.ts +238 -41
  302. package/src/domains/extensions/extension.ts +105 -6
  303. package/src/domains/extensions/index.ts +24 -0
  304. package/src/domains/extensions/integrity.ts +189 -0
  305. package/src/domains/extensions/manager.ts +17 -1
  306. package/src/domains/extensions/resource-path.ts +27 -0
  307. package/src/domains/extensions/resources.ts +18 -38
  308. package/src/domains/extensions/snapshot-store.ts +39 -0
  309. package/src/domains/extensions/snapshot.ts +180 -0
  310. package/src/domains/extensions/state.ts +385 -57
  311. package/src/domains/extensions/types.ts +118 -1
  312. package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +27 -0
  313. package/src/domains/lifecycle/migrations/index.ts +2 -0
  314. package/src/domains/lifecycle/naming-resources.ts +19 -4
  315. package/src/domains/lifecycle/naming-yazi.ts +10 -5
  316. package/src/domains/middleware/contract.ts +26 -0
  317. package/src/domains/middleware/extension.ts +24 -24
  318. package/src/domains/middleware/hook-receipts.ts +27 -4
  319. package/src/domains/middleware/hooks-io.ts +65 -32
  320. package/src/domains/middleware/hooks.ts +64 -0
  321. package/src/domains/middleware/index.ts +28 -4
  322. package/src/domains/middleware/registrations.ts +326 -0
  323. package/src/domains/middleware/runtime.ts +28 -0
  324. package/src/domains/middleware/snapshot.ts +20 -7
  325. package/src/domains/mux/contract.ts +38 -0
  326. package/src/domains/mux/detect.ts +6 -13
  327. package/src/domains/mux/index.ts +1 -1
  328. package/src/domains/mux/operations.ts +44 -5
  329. package/src/domains/mux/yazi/assets/yazi.toml +2 -2
  330. package/src/domains/mux/yazi/session.ts +53 -4
  331. package/src/domains/mux/yazi/theme.ts +117 -17
  332. package/src/domains/observability/contract.ts +10 -11
  333. package/src/domains/observability/extension.ts +11 -3
  334. package/src/domains/observability/projection.ts +14 -90
  335. package/src/domains/observability/trace-store.ts +43 -7
  336. package/src/domains/prompts/compiler.ts +73 -53
  337. package/src/domains/prompts/contract.ts +15 -3
  338. package/src/domains/prompts/extension.ts +97 -9
  339. package/src/domains/prompts/fragments/identity/clio-worker.md +1 -3
  340. package/src/domains/prompts/fragments/identity/clio.md +6 -12
  341. package/src/domains/prompts/fragments/identity/docs-routing.md +1 -2
  342. package/src/domains/prompts/fragments/identity/self-awareness.md +3 -11
  343. package/src/domains/prompts/fragments/operating/contract.md +7 -15
  344. package/src/domains/prompts/fragments/operating/delegation.md +32 -34
  345. package/src/domains/prompts/fragments/operating/skills.md +10 -24
  346. package/src/domains/prompts/fragments/operating/worker.md +1 -8
  347. package/src/domains/providers/index.ts +1 -1
  348. package/src/domains/providers/model-runtime-capabilities.ts +85 -21
  349. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +669 -104
  350. package/src/domains/providers/runtime-resolution.ts +31 -0
  351. package/src/domains/providers/runtimes/common/probe-helpers.ts +7 -2
  352. package/src/domains/providers/runtimes/local-native/llamacpp.ts +9 -1
  353. package/src/domains/providers/types/cost-provenance.ts +19 -0
  354. package/src/domains/providers/types/local-model-quirks.ts +85 -37
  355. package/src/domains/resources/skills/loader.ts +16 -19
  356. package/src/domains/safety/call-target.ts +1 -1
  357. package/src/domains/safety/loop-detector.ts +7 -4
  358. package/src/domains/session/task-board.ts +10 -9
  359. package/src/domains/share/archive.ts +164 -7
  360. package/src/engine/acp/server.ts +62 -9
  361. package/src/engine/apis/llamacpp-residency.ts +3 -4
  362. package/src/engine/apis/lmstudio.ts +3 -3
  363. package/src/engine/apis/ollama-native.ts +6 -6
  364. package/src/engine/apis/openai-completions.ts +28 -25
  365. package/src/engine/apis/output-budget.ts +8 -18
  366. package/src/engine/apis/residency.ts +8 -27
  367. package/src/engine/gemma-channel-filter.ts +19 -0
  368. package/src/engine/loop-guard.ts +92 -12
  369. package/src/engine/worker-runtime.ts +40 -11
  370. package/src/engine/worker-tools.ts +3 -1
  371. package/src/entry/extension-hook-sources.ts +28 -0
  372. package/src/entry/extension-reload.ts +309 -0
  373. package/src/entry/orchestrator.ts +59 -35
  374. package/src/interactive/application-controller.ts +2 -1
  375. package/src/interactive/bus-notices.ts +8 -1
  376. package/src/interactive/chat-loop-messages.ts +3 -13
  377. package/src/interactive/chat-loop.ts +10 -1
  378. package/src/interactive/chat-panel.ts +36 -13
  379. package/src/interactive/chat-renderer.ts +71 -7
  380. package/src/interactive/dispatch-board.ts +6 -11
  381. package/src/interactive/footer/widgets.ts +13 -0
  382. package/src/interactive/interactive-application.ts +39 -4
  383. package/src/interactive/interactive-input-runtime.ts +4 -0
  384. package/src/interactive/interactive-presentation.ts +2 -2
  385. package/src/interactive/interactive-slash-runtime.ts +2 -0
  386. package/src/interactive/overlays/extensions.ts +9 -1
  387. package/src/interactive/overlays/help-reference.ts +13 -0
  388. package/src/interactive/overlays/settings.ts +27 -16
  389. package/src/interactive/panes-runtime.ts +111 -35
  390. package/src/interactive/prompt-cache-identity.ts +88 -0
  391. package/src/interactive/slash-commands.ts +129 -14
  392. package/src/interactive/stream-pacing-policy.ts +0 -23
  393. package/src/interactive/turn-context.ts +30 -15
  394. package/src/interactive/yazi-bridge.ts +60 -6
  395. package/src/tools/agent-tools.ts +30 -1
  396. package/src/tools/artifact.ts +2 -2
  397. package/src/tools/ask-user.ts +3 -3
  398. package/src/tools/bash.ts +1 -1
  399. package/src/tools/bootstrap.ts +4 -0
  400. package/src/tools/builtin-tool-catalog.ts +52 -22
  401. package/src/tools/codewiki/code-nav-surface.ts +6 -0
  402. package/src/tools/codewiki/code-nav.ts +99 -13
  403. package/src/tools/context/docs-engine.ts +20 -7
  404. package/src/tools/context/index.ts +29 -12
  405. package/src/tools/core-bootstrap.ts +28 -6
  406. package/src/tools/credential-present.ts +1 -2
  407. package/src/tools/dispatch-arguments.ts +5 -1
  408. package/src/tools/dispatch-plan.ts +48 -4
  409. package/src/tools/dispatch-run-events.ts +1 -1
  410. package/src/tools/dispatch-schema.ts +338 -0
  411. package/src/tools/dispatch-types.ts +3 -0
  412. package/src/tools/dispatch.ts +9 -254
  413. package/src/tools/ledger.ts +3 -5
  414. package/src/tools/monitor-surface.ts +5 -13
  415. package/src/tools/observation.ts +4 -5
  416. package/src/tools/panes-surface.ts +4 -11
  417. package/src/tools/panes.ts +4 -2
  418. package/src/tools/policy.ts +15 -2
  419. package/src/tools/read.ts +5 -6
  420. package/src/tools/registry.ts +30 -7
  421. package/src/tools/result-shaping.ts +18 -14
  422. package/src/tools/steer-surface.ts +1 -1
  423. package/src/tools/tasks.ts +1 -1
  424. package/src/tools/truncate.ts +6 -5
  425. package/src/tools/verify/surface.ts +6 -12
  426. package/src/tools/web-fetch-surface.ts +1 -3
  427. package/dist/chunk-5QIAJV2D.js +0 -48
  428. package/dist/chunk-JZWT5J3Y.js +0 -814
  429. package/dist/chunk-K7VKOLQQ.js +0 -15
  430. package/dist/chunk-PMZCIOCJ.js +0 -25
  431. package/dist/chunk-SUW5DORT.js +0 -819
  432. package/dist/chunk-UOV2BYIW.js +0 -107
  433. package/dist/chunk-WR6U3OVP.js +0 -45
  434. package/docs/artifact-versions.md +0 -67
  435. package/docs/documentation-coverage.md +0 -46
  436. package/docs/documentation-guide.md +0 -167
  437. package/docs/time-conventions.md +0 -101
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Composition-root coordinator for extension generations.
3
+ *
4
+ * The extensions bundle owns the snapshot store and the middleware bundle
5
+ * owns the registration table; neither knows the other exists. This module
6
+ * is the only writer of both for the "user-hooks" owner and the only caller
7
+ * of the extensions reload, and it sequences them so no observer can see
8
+ * resources from one generation paired with hooks from another:
9
+ *
10
+ * 1. capture and canonicalize the workspace once;
11
+ * 2. prepare the extension candidate (build, validate, reserve generation)
12
+ * and require its snapshot to be for that exact workspace;
13
+ * 3. build the user-hook registrations from the candidate's captured
14
+ * declarations plus the project files under that workspace;
15
+ * 4. prepare the middleware replacement (validate, build the next state);
16
+ * 5. confirm both prepared states are still current, then publish both
17
+ * with two assignment-only calls in adjacent statements;
18
+ * 6. only then emit conflicts, the reload event, and issue lines.
19
+ *
20
+ * Neither publish primitive validates, refuses, throws, or calls out, so a
21
+ * partial publication is impossible by construction: every failure or stale
22
+ * state is detected before step 5 and discards both prepared states. Boot
23
+ * uses the same path, so the first extension generation and the first hook
24
+ * set become live together; before that, readers take the ephemeral
25
+ * generation-0 path. Everything here is synchronous; the reentrancy guard
26
+ * exists for a caller that re-enters from a callback.
27
+ */
28
+
29
+ import { realpathSync } from "node:fs";
30
+ import path from "node:path";
31
+ import type { ExtensionsReloadedPayload } from "../core/bus-events.js";
32
+ import type {
33
+ ExtensionReloadCommitted,
34
+ ExtensionReloadRejection,
35
+ ExtensionSnapshotDiagnostics,
36
+ ExtensionsContract,
37
+ } from "../domains/extensions/index.js";
38
+ import { EXTENSION_SNAPSHOT_DIAGNOSTIC_MESSAGE_CAP } from "../domains/extensions/index.js";
39
+ import {
40
+ type BuildUserHookRegistrationsResult,
41
+ buildUserHookRegistrations,
42
+ type CapturedHookSourceSet,
43
+ type HookReceiptSink,
44
+ type MiddlewareContract,
45
+ type MiddlewareRegistrationConflict,
46
+ type UserHookCommandRunner,
47
+ } from "../domains/middleware/index.js";
48
+ import { capturedHookSourcesFor } from "./extension-hook-sources.js";
49
+
50
+ export interface ExtensionReloadHookSummary {
51
+ /** Registrations published for the owner in this generation. */
52
+ registered: number;
53
+ dropped: number;
54
+ fileIssues: number;
55
+ issues: number;
56
+ overridden: number;
57
+ }
58
+
59
+ export type ExtensionReloadOutcome =
60
+ | (ExtensionReloadCommitted & { hooks: ExtensionReloadHookSummary; lines: ReadonlyArray<string> })
61
+ | (ExtensionReloadRejection & { lines: ReadonlyArray<string> });
62
+
63
+ export interface ExtensionReloadCoordinatorDeps {
64
+ /** Absent on a degraded boot where the extensions domain failed to start. */
65
+ extensions: Pick<ExtensionsContract, "prepareReload" | "snapshot"> | undefined;
66
+ middleware: Pick<MiddlewareContract, "prepareRegistrationReplacement" | "replaceRegistrations" | "ownedGeneration">;
67
+ /** Read once per run and canonicalized; the candidate must be for exactly this workspace. */
68
+ cwd: () => string;
69
+ recordReceipt: HookReceiptSink;
70
+ runCommand?: UserHookCommandRunner;
71
+ now?: () => number;
72
+ /** One operator line per issue; stderr in headless runs, dropped or noticed by the host in interactive runs. */
73
+ report: (line: string) => void;
74
+ /** Called once per published generation, after both references are live. */
75
+ onCommitted?: (event: ExtensionsReloadedPayload) => void;
76
+ }
77
+
78
+ export interface ExtensionReloadCoordinator {
79
+ /**
80
+ * Boot: publish generation 1 and its user hooks together. On a rejected
81
+ * build, or without an extensions domain, the project's own hooks are
82
+ * published under generation 1 and no extension generation exists.
83
+ */
84
+ applyBoot(): ExtensionReloadOutcome;
85
+ /** Operator or programmatic reload. Synchronous and never throws. */
86
+ reload(): ExtensionReloadOutcome;
87
+ }
88
+
89
+ /** Cap on issue lines carried in one outcome so an operator surface stays bounded. */
90
+ export const EXTENSION_RELOAD_REPORT_LINE_CAP = 40;
91
+
92
+ function failure(message: string): ExtensionSnapshotDiagnostics {
93
+ return {
94
+ entries: [{ type: "error", message: message.slice(0, EXTENSION_SNAPSHOT_DIAGNOSTIC_MESSAGE_CAP) }],
95
+ truncated: 0,
96
+ };
97
+ }
98
+
99
+ function issueLines(
100
+ built: BuildUserHookRegistrationsResult,
101
+ dropped: ReadonlyArray<MiddlewareRegistrationConflict>,
102
+ ): string[] {
103
+ const lines: string[] = [];
104
+ for (const issue of built.fileIssues) lines.push(`[clio-coder:hooks] ${issue.message}`);
105
+ for (const issue of built.issues) {
106
+ lines.push(`[clio-coder:hooks] ${issue.source.sourcePath}#${issue.index}: ${issue.issues.join("; ")}`);
107
+ }
108
+ for (const { loser, winner } of built.overridden) {
109
+ lines.push(`[clio-coder:hooks] ${loser.source.sourcePath} hook '${loser.id}' overridden by ${winner.sourcePath}`);
110
+ }
111
+ for (const conflict of dropped) {
112
+ lines.push(
113
+ `[clio-coder:hooks] hook '${conflict.id}' dropped: id is held by a ${conflict.conflictsWith} registration`,
114
+ );
115
+ }
116
+ return lines;
117
+ }
118
+
119
+ export function createExtensionReloadCoordinator(deps: ExtensionReloadCoordinatorDeps): ExtensionReloadCoordinator {
120
+ let inFlight = false;
121
+
122
+ const build = (workspace: string, captured: CapturedHookSourceSet | null): BuildUserHookRegistrationsResult =>
123
+ buildUserHookRegistrations({
124
+ cwd: workspace,
125
+ workspaceRoot: workspace,
126
+ ...(captured !== null ? { capturedSources: captured } : {}),
127
+ recordReceipt: deps.recordReceipt,
128
+ ...(deps.runCommand !== undefined ? { runCommand: deps.runCommand } : {}),
129
+ ...(deps.now !== undefined ? { now: deps.now } : {}),
130
+ });
131
+
132
+ const emitLines = (lines: ReadonlyArray<string>): void => {
133
+ for (const line of lines) {
134
+ try {
135
+ deps.report(line);
136
+ } catch {
137
+ // Reporting is observability; it must never affect the reload.
138
+ }
139
+ }
140
+ };
141
+
142
+ const rejected = (rejection: ExtensionReloadRejection): ExtensionReloadOutcome => {
143
+ const lines = rejection.diagnostics.entries.map((entry) => `[clio-coder:extensions] ${entry.message}`);
144
+ emitLines(lines);
145
+ return { ...rejection, lines: lines.slice(0, EXTENSION_RELOAD_REPORT_LINE_CAP) };
146
+ };
147
+
148
+ const canonicalWorkspace = (): string | null => {
149
+ try {
150
+ return realpathSync(path.resolve(deps.cwd()));
151
+ } catch {
152
+ return null;
153
+ }
154
+ };
155
+
156
+ /**
157
+ * Degraded boot: no extension generation will ever exist, so the project's
158
+ * own hooks are published alone under generation 1. Readers keep taking
159
+ * the ephemeral path, which pairs no generation with no generation.
160
+ */
161
+ const publishProjectHooksOnly = (workspace: string): void => {
162
+ if (deps.middleware.ownedGeneration("user-hooks") !== 0) return;
163
+ const built = build(workspace, null);
164
+ const report = deps.middleware.replaceRegistrations("user-hooks", 1, built.registrations);
165
+ const lines = issueLines(built, report.dropped);
166
+ if (!report.applied) lines.push(`[clio-coder:hooks] project hooks were not applied: ${report.reason ?? "refused"}`);
167
+ emitLines(lines);
168
+ };
169
+
170
+ const run = (boot: boolean): ExtensionReloadOutcome => {
171
+ const activeGeneration = deps.extensions?.snapshot()?.generation ?? 0;
172
+ if (inFlight) {
173
+ return rejected({
174
+ status: "rejected",
175
+ reason: "reentrant",
176
+ generation: activeGeneration,
177
+ diagnostics: { entries: [], truncated: 0 },
178
+ });
179
+ }
180
+ inFlight = true;
181
+ try {
182
+ const workspace = canonicalWorkspace();
183
+ if (workspace === null) {
184
+ return rejected({
185
+ status: "rejected",
186
+ reason: "build-failed",
187
+ generation: activeGeneration,
188
+ diagnostics: failure("the working directory could not be resolved"),
189
+ });
190
+ }
191
+ if (deps.extensions === undefined) {
192
+ if (boot) publishProjectHooksOnly(workspace);
193
+ return rejected({
194
+ status: "rejected",
195
+ reason: "build-failed",
196
+ generation: 0,
197
+ diagnostics: failure("extensions domain is not loaded; restart to recover it"),
198
+ });
199
+ }
200
+ const prepared = deps.extensions.prepareReload();
201
+ if (prepared.status === "rejected") {
202
+ if (boot) publishProjectHooksOnly(workspace);
203
+ return rejected(prepared);
204
+ }
205
+ const candidate = prepared.candidate;
206
+ if (candidate.snapshot.cwd !== workspace) {
207
+ candidate.discard();
208
+ return rejected({
209
+ status: "rejected",
210
+ reason: "workspace-changed",
211
+ generation: candidate.previousGeneration,
212
+ diagnostics: failure(
213
+ `extension snapshot was built for ${candidate.snapshot.cwd} but the session workspace is ${workspace}`,
214
+ ),
215
+ });
216
+ }
217
+ let built: BuildUserHookRegistrationsResult;
218
+ try {
219
+ built = build(workspace, capturedHookSourcesFor(candidate.snapshot));
220
+ } catch (error) {
221
+ candidate.discard();
222
+ return rejected({
223
+ status: "rejected",
224
+ reason: "build-failed",
225
+ generation: candidate.previousGeneration,
226
+ diagnostics: failure(
227
+ `user hook registrations could not be built: ${error instanceof Error ? error.message : String(error)}`,
228
+ ),
229
+ });
230
+ }
231
+ const preparedReplacement = deps.middleware.prepareRegistrationReplacement(
232
+ "user-hooks",
233
+ candidate.generation,
234
+ built.registrations,
235
+ );
236
+ if (preparedReplacement.status === "rejected") {
237
+ candidate.discard();
238
+ return rejected({
239
+ status: "rejected",
240
+ reason: "stale",
241
+ generation: candidate.previousGeneration,
242
+ diagnostics: failure(
243
+ `middleware refused generation ${candidate.generation} (${preparedReplacement.reason}; active ${preparedReplacement.activeGeneration})`,
244
+ ),
245
+ });
246
+ }
247
+ const replacement = preparedReplacement.replacement;
248
+ // Final freshness validation. After this point neither primitive can
249
+ // refuse, so a stale side here discards both and publishes neither.
250
+ if (!candidate.current() || !replacement.current()) {
251
+ replacement.discard();
252
+ candidate.discard();
253
+ return rejected({
254
+ status: "rejected",
255
+ reason: "stale",
256
+ generation: candidate.previousGeneration,
257
+ diagnostics: failure(`generation ${candidate.generation} was superseded before it could be published`),
258
+ });
259
+ }
260
+ candidate.publish();
261
+ replacement.publish();
262
+ // Both references are live. Observers may run from here on.
263
+ replacement.emitConflicts();
264
+ const lines = issueLines(built, replacement.dropped);
265
+ try {
266
+ deps.onCommitted?.({
267
+ generation: candidate.generation,
268
+ previousGeneration: candidate.previousGeneration,
269
+ changed: candidate.changed,
270
+ digest: candidate.snapshot.digest,
271
+ });
272
+ } catch (error) {
273
+ // Publication is already complete. An observability callback cannot
274
+ // turn a live paired generation into a thrown or rejected outcome.
275
+ const message = error instanceof Error ? error.message : String(error);
276
+ lines.push(
277
+ `[clio-coder:extensions] committed generation observer failed: ${message.slice(0, EXTENSION_SNAPSHOT_DIAGNOSTIC_MESSAGE_CAP)}`,
278
+ );
279
+ }
280
+ emitLines(lines);
281
+ return {
282
+ status: "committed",
283
+ generation: candidate.generation,
284
+ previousGeneration: candidate.previousGeneration,
285
+ changed: candidate.changed,
286
+ digest: candidate.snapshot.digest,
287
+ added: candidate.added,
288
+ removed: candidate.removed,
289
+ modified: candidate.modified,
290
+ diagnostics: candidate.snapshot.diagnostics,
291
+ hooks: {
292
+ registered: replacement.size,
293
+ dropped: replacement.dropped.length,
294
+ fileIssues: built.fileIssues.length,
295
+ issues: built.issues.length,
296
+ overridden: built.overridden.length,
297
+ },
298
+ lines: lines.slice(0, EXTENSION_RELOAD_REPORT_LINE_CAP),
299
+ };
300
+ } finally {
301
+ inFlight = false;
302
+ }
303
+ };
304
+
305
+ return {
306
+ applyBoot: () => run(true),
307
+ reload: () => run(false),
308
+ };
309
+ }
@@ -88,8 +88,7 @@ import {
88
88
  createMarketplaceOfferRegistration,
89
89
  createMiddlewareToolChoiceControl,
90
90
  createSkillsReminderRegistration,
91
- type ExtensionHookRoot,
92
- installUserHooks,
91
+ formatRegistrationConflict,
93
92
  type MiddlewareContract,
94
93
  MiddlewareDomainModule,
95
94
  writeMiddlewareDiagnosticToStderr,
@@ -181,6 +180,7 @@ import { createChatLoop } from "../interactive/chat-loop.js";
181
180
  import { type RunIo, startInteractive } from "../interactive/index.js";
182
181
  import { buildModelReplayAgentMessagesFromTurns } from "../interactive/model-session-replay.js";
183
182
  import type { BootOptions } from "./boot-options.js";
183
+ import { createExtensionReloadCoordinator } from "./extension-reload.js";
184
184
  import { resolvePanesEnablement } from "./panes-activation.js";
185
185
 
186
186
  export type { BootOptions, HeadlessSamplingOverrides } from "./boot-options.js";
@@ -200,6 +200,7 @@ import { type AskUserHandler, cancelledAskUserResult } from "../tools/ask-user.j
200
200
  import { registerAllTools } from "../tools/bootstrap.js";
201
201
  import { isGitRepository, recoverCleanupReadyCompeteGroups } from "../tools/compete-worktrees.js";
202
202
  import { createDispatchBackgroundRegistry } from "../tools/dispatch-background.js";
203
+ import { dispatchSchemaCompositionFor } from "../tools/dispatch-schema.js";
203
204
  import { createFileMutationObserver, createSkillActivationObserver } from "../tools/observers.js";
204
205
  import { createRegistry } from "../tools/registry.js";
205
206
  import { sweepExpiredToolOffloads } from "../tools/result-shaping.js";
@@ -1026,7 +1027,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1026
1027
  else resolvedResumeId = latest.id;
1027
1028
  }
1028
1029
  }
1029
- const resumeId = resolvedResumeId ?? process.env.CLIO_CODER_RESUME_SESSION_ID?.trim();
1030
+ const resumeId = resolvedResumeId;
1030
1031
  let resumedSessionAtBoot = false;
1031
1032
  if (resumeId && session && headlessResumeFailure === null) {
1032
1033
  try {
@@ -1038,7 +1039,6 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1038
1039
  else bootStderr(`Clio Coder: failed to resume session ${resumeId}: ${detail}\n`);
1039
1040
  }
1040
1041
  }
1041
- Reflect.deleteProperty(process.env, "CLIO_CODER_RESUME_SESSION_ID");
1042
1042
  if (headlessResumeFailure !== null) {
1043
1043
  bootStderr(`clio-coder run: ${headlessResumeFailure}\n`);
1044
1044
  await termination.shutdown(2);
@@ -1050,6 +1050,20 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1050
1050
  // middleware.hookFailed (the interactive warn notice consumes it) and keep
1051
1051
  // stderr for non-interactive runs, which have no notice subscriber.
1052
1052
  middleware.setDiagnosticSink((diagnostic) => {
1053
+ if (diagnostic.kind === "registration_conflict") {
1054
+ // Registration bookkeeping has no hook occurrence; the affected owner
1055
+ // today declares user hooks, which never run on on_compaction, so the
1056
+ // payload's hook slot carries that as the "no evaluation" marker.
1057
+ bus.emit(BusChannels.MiddlewareHookFailed, {
1058
+ kind: "registration_conflict",
1059
+ registrationId: diagnostic.registrationId,
1060
+ hook: "on_compaction",
1061
+ at: Date.now(),
1062
+ message: formatRegistrationConflict(diagnostic),
1063
+ });
1064
+ if (!interactive) writeMiddlewareDiagnosticToStderr(diagnostic);
1065
+ return;
1066
+ }
1053
1067
  bus.emit(BusChannels.MiddlewareHookFailed, {
1054
1068
  kind: diagnostic.kind,
1055
1069
  registrationId: diagnostic.registrationId,
@@ -1082,15 +1096,14 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1082
1096
  });
1083
1097
  }
1084
1098
 
1085
- // Guardrail policy (tool-call budgets, tool byte caps, dispatch ledger cap)
1086
- // resolves settings-first with env as emergency override; install the
1087
- // settings section before any guard registration or tool reads it.
1099
+ // Install guardrail policy before any guard registration or tool reads it.
1100
+ // The effective session view replaces this boot projection below.
1088
1101
  const resolvedSettings = config?.get() ?? readSettings();
1089
1102
  configureGuardrails(guardrailValuesFromSettings(resolvedSettings));
1090
1103
 
1091
- // The run event journal resolves the same way for the same reason: the sink
1092
- // sits on the dispatch event path, where reading settings.yaml would be both
1093
- // a cost and a throw site, so the composition root installs the value once.
1104
+ // The journal sink sits on the dispatch event path, where reading settings
1105
+ // would be both a cost and a throw site. The effective session view replaces
1106
+ // this boot projection below.
1094
1107
  configureRunEventJournal(resolvedSettings.fleet.history.journal);
1095
1108
 
1096
1109
  // Guard registrations on the middleware contract, in order: loop guard,
@@ -1104,7 +1117,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1104
1117
  safety,
1105
1118
  bus,
1106
1119
  turnBlockBudget: INTERACTIVE_LOOP_BLOCK_BUDGET,
1107
- turnToolCallBudget: readOrchTurnToolCallBudget(),
1120
+ turnToolCallBudget: () => readOrchTurnToolCallBudget(),
1108
1121
  // Interactive/headless/ACP all share this orchestrator guard: at the
1109
1122
  // block budget, lock tools for the rest of the turn so the model
1110
1123
  // answers from what it gathered instead of hard-cancelling a turn that
@@ -1299,24 +1312,26 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1299
1312
  // same effect machinery. They register after the guards, so safety stays
1300
1313
  // authoritative: a hook may add effects (including request block_tool) but
1301
1314
  // cannot grant a permission safety would deny. Loading is best-effort.
1315
+ // The coordinator is the only writer of the "user-hooks" owner and the only
1316
+ // caller of the extensions reload; it publishes the extension generation
1317
+ // and the hook registrations with two adjacent assignments on one stack
1318
+ // and emits extensions.reloaded only after both. The boot generation is
1319
+ // published here too (the extensions bundle publishes nothing at start),
1320
+ // so no consumer ever sees extension resources paired with hooks from a
1321
+ // different generation. The owner slot is anchored here, so user hooks
1322
+ // keep evaluating after the guards and before the assessors below.
1302
1323
  const hookReceiptLog = createHookReceiptLog({ persistPath: join(clioStateDir(), "hook-receipts.json") });
1303
- const extensionHookRoots: ExtensionHookRoot[] = (extensions?.list(process.cwd()) ?? [])
1304
- .filter((ext) => ext.enabled && ext.effective)
1305
- .map((ext) => ({ id: ext.id, rootPath: ext.rootPath }));
1306
- const userHooks = installUserHooks({
1307
- cwd: process.cwd(),
1308
- extensions: extensionHookRoots,
1309
- registerHook: (registration) => middleware.registerHook(registration),
1324
+ const extensionReload = createExtensionReloadCoordinator({
1325
+ extensions,
1326
+ middleware,
1327
+ cwd: () => process.cwd(),
1310
1328
  recordReceipt: (receipt) => hookReceiptLog.record(receipt),
1329
+ report: (line) => {
1330
+ if (!interactive) process.stderr.write(`${line}\n`);
1331
+ },
1332
+ onCommitted: (event) => bus.emit(BusChannels.ExtensionsReloaded, event),
1311
1333
  });
1312
- if (!interactive) {
1313
- for (const issue of userHooks.fileIssues) {
1314
- process.stderr.write(`[clio-coder:hooks] ${issue.message}\n`);
1315
- }
1316
- for (const issue of userHooks.issues) {
1317
- process.stderr.write(`[clio-coder:hooks] ${issue.source.sourcePath}#${issue.index}: ${issue.issues.join("; ")}\n`);
1318
- }
1319
- }
1334
+ extensionReload.applyBoot();
1320
1335
  termination.onDrain(() => hookReceiptLog.flush());
1321
1336
  // Autonomy is hot-reloaded for interactive and headless admissions. ACP
1322
1337
  // server prompts use the snapshot captured at session/new.
@@ -1494,6 +1509,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1494
1509
  ...(panes && mux?.mode !== "none" ? { panes } : {}),
1495
1510
  getCostCeilingUsd: () => result.getContract<SchedulingContract>("scheduling")?.ceilingUsd() ?? 0,
1496
1511
  ...(config ? { getWorkerRosters: () => config.get().fleet.rosters } : {}),
1512
+ ...(config ? { getDispatchSchemaComposition: () => dispatchSchemaCompositionFor(config.get().fleet) } : {}),
1497
1513
  getSkillLoaderOptions: () => ({
1498
1514
  trustProjectCompatRoots: config?.get().integrations.projectResources.trustProjectImports === true,
1499
1515
  disableDiscovery: options.noSkills === true || options.headless?.noSkills === true,
@@ -1518,8 +1534,13 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1518
1534
  // view, so the live session reflects them immediately while settings.yaml
1519
1535
  // (the global default for new sessions) stays untouched until the operator
1520
1536
  // chooses to save globally.
1537
+ // Overrides are keyed by settings path, the same ids the /settings overlay
1538
+ // commits (`setAtPath` walks the dotted path). The headless `--autonomy`
1539
+ // flag was keyed by the bare word, which wrote a top-level `autonomy` key
1540
+ // nothing reads, so `run --autonomy full-auto` compiled and admitted at
1541
+ // whatever settings.yaml said.
1521
1542
  const sessionOverrides: SessionOverrides = new Map(
1522
- options.headless?.autonomy === undefined ? [] : [["autonomy", options.headless.autonomy]],
1543
+ options.headless?.autonomy === undefined ? [] : [["safety.autonomy", options.headless.autonomy]],
1523
1544
  );
1524
1545
  // The effective view is derived by deep-cloning the saved snapshot, and it
1525
1546
  // is read on the tool-admission hot path (every call resolves autonomy
@@ -1534,9 +1555,10 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1534
1555
  let cachedSettingsView: ClioSettings | null = null;
1535
1556
  const bumpSessionState = (): void => {
1536
1557
  sessionStateGeneration += 1;
1537
- // Child-process seams read the effective setting from the environment,
1538
- // and the session view may override the saved value.
1539
- setGitCommitAttributionEnabled(getCurrentSettings().integrations.git.commitAttribution);
1558
+ const settings = getCurrentSettings();
1559
+ configureGuardrails(guardrailValuesFromSettings(settings));
1560
+ configureRunEventJournal(settings.fleet.history.journal);
1561
+ setGitCommitAttributionEnabled(settings.integrations.git.commitAttribution);
1540
1562
  };
1541
1563
  const getCurrentSettings = (): ClioSettings => {
1542
1564
  // Recents live in the data dir (core/recent-models.ts), never in
@@ -1562,10 +1584,11 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1562
1584
  };
1563
1585
  effectiveSettingsForDispatch = getCurrentSettings;
1564
1586
  bumpSessionState();
1565
- // The config bundle publishes the saved value on reload; a session-scoped
1566
- // override must win, so re-derive from the session view after it.
1567
- const unsubscribeCommitAttributionSync = bus.on(BusChannels.ConfigHotReload, () => bumpSessionState());
1568
- termination.onDrain(() => unsubscribeCommitAttributionSync());
1587
+ // The config bundle publishes saved values on reload; session-scoped
1588
+ // overrides must win, so re-derive every process-local projection from the
1589
+ // effective session view after it.
1590
+ const unsubscribeSettingsProjectionSync = bus.on(BusChannels.ConfigHotReload, () => bumpSessionState());
1591
+ termination.onDrain(() => unsubscribeSettingsProjectionSync());
1569
1592
  const getTaskMemorySeedOffer = (): { source: string; count: number } | null => {
1570
1593
  return taskMemoryHandoffSeedOffer(process.cwd(), getCurrentSettings().context.memory.enabled);
1571
1594
  };
@@ -1892,7 +1915,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1892
1915
  await chat.whenSettled();
1893
1916
  });
1894
1917
 
1895
- // A boot-time resume (CLIO_CODER_RESUME_SESSION_ID) must replay the resumed
1918
+ // A boot-time resume (headless --session or --continue) must replay the resumed
1896
1919
  // session into the chat loop the same way the interactive /resume overlay
1897
1920
  // does. Without this, the first submit runs with an empty provider context
1898
1921
  // and parents its user turn at null, appending a second root that silently
@@ -2117,6 +2140,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
2117
2140
  ...(initialNotices.length > 0 ? { initialNotices } : {}),
2118
2141
  ...(resources ? { resources } : {}),
2119
2142
  ...(extensions ? { extensions } : {}),
2143
+ reloadExtensions: () => extensionReload.reload(),
2120
2144
  ...(interop ? { interop } : {}),
2121
2145
  ...(share ? { share } : {}),
2122
2146
  ...(mux ? { mux } : {}),
@@ -18,11 +18,12 @@ const CLOSED_ACTION_ORDER = [
18
18
  "clio-coder.thinking.expandAll",
19
19
  ] as const satisfies ReadonlyArray<ClioKeybinding>;
20
20
 
21
- const GLOBAL_ACTION_ORDER = [
21
+ export const GLOBAL_ACTION_ORDER = [
22
22
  "clio-coder.status.toggle",
23
23
  "clio-coder.thinking.cycle",
24
24
  "clio-coder.session.tree",
25
25
  "clio-coder.dispatchBoard.toggle",
26
+ "clio-coder.files.toggle",
26
27
  "clio-coder.tasks.open",
27
28
  "clio-coder.decisions.open",
28
29
  "clio-coder.dispatch.background",
@@ -72,7 +72,7 @@ function isSafetyBlockedPayload(value: unknown): value is SafetyBlockedPayload {
72
72
  function isMiddlewareHookFailedPayload(value: unknown): value is MiddlewareHookFailedPayload {
73
73
  if (!value || typeof value !== "object") return false;
74
74
  const p = value as Record<string, unknown>;
75
- if (p.kind !== "hook_failed" && p.kind !== "budget_exceeded") return false;
75
+ if (p.kind !== "hook_failed" && p.kind !== "budget_exceeded" && p.kind !== "registration_conflict") return false;
76
76
  if (typeof p.registrationId !== "string" || p.registrationId.length === 0) return false;
77
77
  if (typeof p.hook !== "string" || p.hook.length === 0) return false;
78
78
  if (p.message !== undefined && typeof p.message !== "string") return false;
@@ -142,6 +142,13 @@ function middlewareHookFailedNotice(
142
142
  options: MiddlewareHookFailedNoticeOptions = {},
143
143
  ): BusNotice | null {
144
144
  if (!isMiddlewareHookFailedPayload(payload)) return null;
145
+ if (payload.kind === "registration_conflict") {
146
+ const detail =
147
+ payload.message !== undefined && payload.message.length > 0
148
+ ? payload.message
149
+ : `registration '${payload.registrationId}' conflicts with an existing id`;
150
+ return { level: "warn", text: `[middleware] ${detail}` };
151
+ }
145
152
  if (payload.kind === "hook_failed") {
146
153
  const detail = payload.message !== undefined && payload.message.length > 0 ? `: ${payload.message}` : "";
147
154
  return {
@@ -21,12 +21,13 @@ import {
21
21
  } from "../core/response-model-id.js";
22
22
  import type { PendingSkillRequest, PendingSkillToolPolicy, SkillDeclaredToolPolicy } from "../core/skill-activation.js";
23
23
  import { ToolNames } from "../core/tool-names.js";
24
- import { canonicalJson, sha256 } from "../domains/prompts/hash.js";
24
+ import { sha256 } from "../domains/prompts/hash.js";
25
25
  import { toContextOverflowError } from "../domains/providers/errors.js";
26
26
  import type { ResolvedRuntimeTarget } from "../domains/providers/index.js";
27
27
  import { ceilChars, extractReasoningTokens } from "../domains/session/context-accounting.js";
28
28
  import type { AgentMessage } from "../engine/types.js";
29
29
  import type { AskUserToolPolicy } from "../tools/registry.js";
30
+ import { attachedToolSchemaBytes, attachedToolSchemasFromState } from "./prompt-cache-identity.js";
30
31
 
31
32
  /** Minimal structural view of the engine agent used by state-inspection helpers. */
32
33
  export interface AgentStateView {
@@ -291,18 +292,7 @@ export function pendingSkillRequestPreamble(requests: ReadonlyArray<PendingSkill
291
292
  * tool-surface change.
292
293
  */
293
294
  export function toolSignatureFromState(tools: ReadonlyArray<unknown>): string {
294
- const schemas: Array<{ name: string; description: string; parameters: unknown }> = [];
295
- for (const tool of tools) {
296
- if (!tool || typeof tool !== "object" || Array.isArray(tool)) continue;
297
- const record = tool as Record<string, unknown>;
298
- schemas.push({
299
- name: typeof record.name === "string" ? record.name : "",
300
- description: typeof record.description === "string" ? record.description : "",
301
- parameters: record.parameters ?? null,
302
- });
303
- }
304
- schemas.sort((a, b) => a.name.localeCompare(b.name));
305
- return sha256(canonicalJson(schemas));
295
+ return sha256(attachedToolSchemaBytes(attachedToolSchemasFromState(tools)));
306
296
  }
307
297
 
308
298
  /**
@@ -648,7 +648,9 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
648
648
  const retrySettings = (): RetrySettings => normalizeRetrySettings(deps.getSettings().chat.retry);
649
649
 
650
650
  const currentToolInvokeOptions = (): Partial<ToolInvokeOptions> => {
651
- const options: Partial<ToolInvokeOptions> = {};
651
+ const options: Partial<ToolInvokeOptions> = {
652
+ toolResultMaxBytes: deps.getSettings().context.toolResultMaxBytes,
653
+ };
652
654
  const sessionId = deps.session?.current()?.id ?? null;
653
655
  if (sessionId) options.sessionId = sessionId;
654
656
  const turnId = state.activeUserTurnId ?? state.lastTurnId;
@@ -764,6 +766,12 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
764
766
  deps.bus?.on(BusChannels.ConfigHotReload, () => {
765
767
  context.invalidateSessionPromptCache();
766
768
  }) ?? null;
769
+ // A committed extension generation with new content can change the skill
770
+ // and prompt inputs the session prompt compiles from; same invalidation.
771
+ const unsubscribeExtensionsReload =
772
+ deps.bus?.on(BusChannels.ExtensionsReloaded, (payload) => {
773
+ if (payload.changed) context.invalidateSessionPromptCache();
774
+ }) ?? null;
767
775
 
768
776
  const unsubscribeSynthesisLock =
769
777
  deps.bus?.on(BusChannels.LoopBlocked, (payload) => {
@@ -1417,6 +1425,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
1417
1425
 
1418
1426
  dispose(): void {
1419
1427
  unsubscribeConfigReload?.();
1428
+ unsubscribeExtensionsReload?.();
1420
1429
  unsubscribeSynthesisLock?.();
1421
1430
  unsubscribePrewarmCompaction();
1422
1431
  prewarm.dispose();