@iowarp/clio-coder 0.4.1 → 0.4.3

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 (604) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/CONTRIBUTING.md +142 -52
  3. package/README.md +434 -473
  4. package/SECURITY.md +2 -1
  5. package/dist/{acp-ZILU3AUO.js → acp-H2NGRPWO.js} +12 -12
  6. package/dist/{agents-HYWGBGQR.js → agents-TL5LLUQP.js} +56 -55
  7. package/dist/assets/codewiki.json +1 -1
  8. package/dist/{auth-N3QT7CBO.js → auth-E5SW4HMS.js} +23 -21
  9. package/dist/builtins-IA7V7FUC.js +22 -0
  10. package/dist/{chunk-7RY5VZPH.js → chunk-2APPQIER.js} +8 -8
  11. package/dist/{chunk-72GZI5EV.js → chunk-2JH2WHGE.js} +2 -2
  12. package/dist/{chunk-JA5QWE4Z.js → chunk-2UG5F4C5.js} +1973 -1664
  13. package/dist/{chunk-5YHDIDBP.js → chunk-2UH2KFUP.js} +2 -2
  14. package/dist/{chunk-CTJ4RNAA.js → chunk-2VIKGWFZ.js} +2 -2
  15. package/dist/{chunk-I66EAJFY.js → chunk-2WZ546HR.js} +267 -232
  16. package/dist/{chunk-GIZNH63R.js → chunk-35MSIRKH.js} +9 -4
  17. package/dist/chunk-3EBYEESD.js +314 -0
  18. package/dist/{chunk-J5LZHVIT.js → chunk-3M6DQK6S.js} +113 -35
  19. package/dist/{chunk-RKSR6VSF.js → chunk-4IUZQIJ3.js} +29 -1
  20. package/dist/{chunk-6FN3E6KX.js → chunk-4O6MANBS.js} +2 -2
  21. package/dist/chunk-4UVU7BJ5.js +39 -0
  22. package/dist/{chunk-VKRH2TCS.js → chunk-4WR7VSYB.js} +2 -2
  23. package/dist/{chunk-BBTJOK6Y.js → chunk-54CBCGIR.js} +5 -5
  24. package/dist/{chunk-AP73CFDC.js → chunk-5ICU3EUH.js} +2 -2
  25. package/dist/chunk-5MEZN6CB.js +1334 -0
  26. package/dist/{chunk-O42A54GG.js → chunk-5OIVVPHF.js} +2 -2
  27. package/dist/{chunk-ABLSQ6JX.js → chunk-64I3JVYM.js} +8 -2
  28. package/dist/{chunk-AFKWHWXF.js → chunk-6PTFB5VS.js} +39 -22
  29. package/dist/{chunk-VN3SHNBN.js → chunk-7DICMOS6.js} +2 -2
  30. package/dist/chunk-7DRAWPTZ.js +360 -0
  31. package/dist/chunk-7E7I3WLS.js +3762 -0
  32. package/dist/{chunk-BJGUKIG4.js → chunk-7ZYNNDKC.js} +7 -7
  33. package/dist/{chunk-XKA2ICR3.js → chunk-AF4YM7Z4.js} +652 -252
  34. package/dist/{chunk-GVQJ5CCZ.js → chunk-AX2THNSA.js} +12 -12
  35. package/dist/{chunk-IG7BCQBA.js → chunk-B4OAX3SI.js} +65 -3
  36. package/dist/{chunk-TD3PGPQA.js → chunk-B4VEBZKF.js} +3 -3
  37. package/dist/{chunk-74YWRRU5.js → chunk-BEPZRGGU.js} +10 -10
  38. package/dist/{chunk-FEFIFZTL.js → chunk-CE5AX47J.js} +2 -2
  39. package/dist/{chunk-UAPGZHYC.js → chunk-DWUOQKRU.js} +25 -11
  40. package/dist/{chunk-THYWACCR.js → chunk-E3TPLWFX.js} +3 -3
  41. package/dist/{chunk-7EPLI7VL.js → chunk-EKCHAPYA.js} +2 -2
  42. package/dist/{chunk-HLW2MRKE.js → chunk-F4EKGO4N.js} +3 -1
  43. package/dist/{chunk-PJJ6MY27.js → chunk-F5JHEYZM.js} +7 -7
  44. package/dist/{chunk-6CCS4G3W.js → chunk-FTMGRKEF.js} +3 -3
  45. package/dist/{chunk-SINK3QR6.js → chunk-G76U63X4.js} +17 -17
  46. package/dist/{chunk-EIMVLWB3.js → chunk-GHS5EBTQ.js} +64 -9
  47. package/dist/{chunk-QMXC4JB7.js → chunk-GI7YYQ3F.js} +187 -1419
  48. package/dist/{chunk-TZSKNMZG.js → chunk-GTUD2WMY.js} +2 -1
  49. package/dist/{chunk-6HMJX2VU.js → chunk-GWZNEVM2.js} +44 -12
  50. package/dist/chunk-GYV6VZOC.js +26 -0
  51. package/dist/{chunk-MQXIVJ35.js → chunk-HAXOFFRH.js} +5 -5
  52. package/dist/{chunk-UXN6JT4W.js → chunk-HEQY7ZFI.js} +3 -3
  53. package/dist/{chunk-7PWAODYW.js → chunk-I7XBWTYH.js} +2 -2
  54. package/dist/{chunk-GCSMB2KY.js → chunk-I7ZPNEJM.js} +145 -102
  55. package/dist/{chunk-WNP7O5WZ.js → chunk-ID64D7PE.js} +4 -4
  56. package/dist/{chunk-QTFGO774.js → chunk-IGLP3ODT.js} +29 -16
  57. package/dist/chunk-IJNZMHLA.js +101 -0
  58. package/dist/{chunk-BDPT6GTK.js → chunk-INY6HTFL.js} +7 -7
  59. package/dist/{chunk-PBP4B7XR.js → chunk-IUE3Y34X.js} +2 -2
  60. package/dist/{chunk-6NJQITNH.js → chunk-IWT4SF4R.js} +6 -3
  61. package/dist/{chunk-R23Z6K6I.js → chunk-JDAY6FIL.js} +19 -19
  62. package/dist/chunk-JEQ3XTHC.js +42 -0
  63. package/dist/{chunk-FSP7CMNU.js → chunk-JGRC33J2.js} +50 -4
  64. package/dist/{chunk-TVH4ONAM.js → chunk-JKKCYP3C.js} +10 -10
  65. package/dist/{chunk-HJWWJ6IL.js → chunk-JSC3U7TI.js} +16 -4
  66. package/dist/{chunk-C537JADH.js → chunk-KK4JZPBQ.js} +19 -141
  67. package/dist/{chunk-K6BF4U2H.js → chunk-KKOJXO6R.js} +62 -14
  68. package/dist/{chunk-IHXBNWMM.js → chunk-KXDSS5WJ.js} +7 -3
  69. package/dist/{chunk-6DWBAZ5U.js → chunk-L47TF46W.js} +5 -7
  70. package/dist/{chunk-HUAS7ITX.js → chunk-LDJG7DW3.js} +91 -42
  71. package/dist/{chunk-CDNVLKUX.js → chunk-LLDJM5XK.js} +13 -7
  72. package/dist/{chunk-YPI3QQCF.js → chunk-MCEPRMZW.js} +2 -4
  73. package/dist/{chunk-Y4CAGMM6.js → chunk-MNJGS2IN.js} +5 -6
  74. package/dist/{chunk-VKFQTNDV.js → chunk-MUW2BDDH.js} +4 -4
  75. package/dist/{chunk-E67WX76H.js → chunk-MWUZBSAQ.js} +104 -152
  76. package/dist/{chunk-OJTRZGR3.js → chunk-N2Z7HLVY.js} +21 -21
  77. package/dist/{chunk-TVHHYFHE.js → chunk-NEDJ26B5.js} +2 -2
  78. package/dist/{chunk-FYUN5KZ3.js → chunk-NIQJ66N4.js} +21 -21
  79. package/dist/{chunk-U2WB7TZS.js → chunk-NMJXSHBJ.js} +97 -85
  80. package/dist/{chunk-CWVRRIEI.js → chunk-NZMNUPZZ.js} +2 -2
  81. package/dist/{chunk-VEGN6WIQ.js → chunk-O5CVSAG5.js} +3 -3
  82. package/dist/{chunk-MOPSG2X7.js → chunk-OML5D5V5.js} +8 -8
  83. package/dist/{chunk-2VG7KLYV.js → chunk-PAJQJ7BS.js} +5816 -3255
  84. package/dist/{chunk-ZW55JB7N.js → chunk-PUVDKJ2Y.js} +2 -2
  85. package/dist/{chunk-BTGG6BG2.js → chunk-QWGDJJYJ.js} +158 -19
  86. package/dist/chunk-R6Q67RJH.js +134 -0
  87. package/dist/{chunk-ZJLUDYFY.js → chunk-RRNP2ANY.js} +6 -6
  88. package/dist/{chunk-PVAMAVBB.js → chunk-RSJ25QSL.js} +102 -2
  89. package/dist/{chunk-NLFAQR7Z.js → chunk-S66XZJOF.js} +3 -23
  90. package/dist/chunk-SKHCAU7K.js +385 -0
  91. package/dist/chunk-SZAA6XDG.js +30 -0
  92. package/dist/{chunk-J4HBWF6Y.js → chunk-TM6LQDI3.js} +131 -28
  93. package/dist/chunk-UOIZ7DA4.js +41 -0
  94. package/dist/{chunk-MA3H6DM5.js → chunk-UPZU6GE4.js} +25 -3
  95. package/dist/{chunk-BWW4HLO4.js → chunk-UXCU4E3T.js} +8 -6
  96. package/dist/{chunk-N5UK64DP.js → chunk-V2ANDPVT.js} +4 -4
  97. package/dist/{chunk-AK5XEFVZ.js → chunk-VA5FNYMT.js} +26 -13
  98. package/dist/{chunk-6VC4OV3Z.js → chunk-VIA6RFQZ.js} +3 -11
  99. package/dist/{chunk-ZAZB4JMW.js → chunk-VKPAQYEB.js} +27 -8
  100. package/dist/{chunk-QKIFBZKT.js → chunk-VW6DOEDG.js} +497 -81
  101. package/dist/{chunk-SCYB3HA4.js → chunk-W6RRQCPQ.js} +63 -19
  102. package/dist/{chunk-2NM363SV.js → chunk-WBKFA554.js} +10 -10
  103. package/dist/{chunk-R32CLGZ6.js → chunk-WCXUNS7U.js} +82 -21
  104. package/dist/{chunk-GPPB3JBE.js → chunk-WRBAGUNF.js} +3 -3
  105. package/dist/{chunk-IXJT6DCX.js → chunk-XIVNBFZS.js} +85 -30
  106. package/dist/{chunk-UEDMSP56.js → chunk-XPWWI35G.js} +417 -201
  107. package/dist/chunk-XRZT5WY5.js +47 -0
  108. package/dist/{chunk-3QSOM6PA.js → chunk-Y3CBHOR6.js} +2 -2
  109. package/dist/{chunk-VXMFAE2W.js → chunk-YPC6ZR5L.js} +19 -6
  110. package/dist/{chunk-AKB4GYDL.js → chunk-YQWYVTMC.js} +5 -5
  111. package/dist/{chunk-6I5ILFOF.js → chunk-ZA4VCIGV.js} +3 -3
  112. package/dist/{chunk-7OBGU7UB.js → chunk-ZDN3Y73Y.js} +12 -18
  113. package/dist/{chunk-3I5NY75V.js → chunk-ZWPRK62N.js} +8 -5
  114. package/dist/cli/index.js +41 -39
  115. package/dist/{clio-IT3G3VQH.js → clio-CMMK4KRR.js} +9 -9
  116. package/dist/{code-nav-RK6S7F6E.js → code-nav-MDZNQS33.js} +89 -21
  117. package/dist/{components-UBWCQSRW.js → components-UCUQ4QXW.js} +4 -4
  118. package/dist/{config-3QZRWZJF.js → config-SVM5P5YI.js} +131 -84
  119. package/dist/{configure-FL7Y3KJF.js → configure-LE3IK2TJ.js} +28 -26
  120. package/dist/{context-5HE7ODYK.js → context-2OHRKS42.js} +69 -64
  121. package/dist/{context-KYQFRVDC.js → context-E3VC7RX5.js} +15 -11
  122. package/dist/{context-XNHL75JV.js → context-VNCR7KAG.js} +93 -65
  123. package/dist/{context-clear-N545L53A.js → context-clear-BW4O37TG.js} +64 -60
  124. package/dist/context-map-COB37XXN.js +505 -0
  125. package/dist/{context-working-set-QHKXSV2F.js → context-working-set-VDS25HXZ.js} +19 -18
  126. package/dist/{dispatch-runner-RGIE5PCT.js → dispatch-runner-5AHT53RF.js} +93 -82
  127. package/dist/{docs-5NAF6AU7.js → docs-PD3EXDKU.js} +21 -20
  128. package/dist/{doctor-ZGPEGHIP.js → doctor-WNNVO6FY.js} +48 -47
  129. package/dist/{eval-GXLL44RD.js → eval-7G7SGAYO.js} +287 -115
  130. package/dist/{eval-inventory-HBWSWQOK.js → eval-inventory-Y6QRFOH5.js} +4 -4
  131. package/dist/{evidence-HWLBRH3Q.js → evidence-VD6736FQ.js} +67 -64
  132. package/dist/{evolve-FTZBMNVW.js → evolve-AL3NGVRL.js} +65 -62
  133. package/dist/{extensions-VHRBEID7.js → extensions-MOVJ32NM.js} +9 -7
  134. package/dist/{fleet-CKZHJWZJ.js → fleet-QZHUMAGI.js} +114 -111
  135. package/dist/{fleet-commands-EXDXBMV6.js → fleet-commands-BAYT5FJZ.js} +10 -10
  136. package/dist/{fleet-decisions-OTHB6KRL.js → fleet-decisions-IREVMRU4.js} +7 -6
  137. package/dist/{fleet-graph-YTEZUCUT.js → fleet-graph-YCTT3HTI.js} +22 -19
  138. package/dist/{fleet-inspect-SS6YMDCK.js → fleet-inspect-QVJTDAVB.js} +58 -55
  139. package/dist/{fleet-preflight-PBY4VYOM.js → fleet-preflight-25QAFPK4.js} +4 -4
  140. package/dist/{fleet-validate-KMEM5L3S.js → fleet-validate-5O57AAJ7.js} +26 -23
  141. package/dist/{fleet-verify-QD5M7E7Q.js → fleet-verify-CPH2W2T6.js} +59 -56
  142. package/dist/{fleet-view-WAMJYNDT.js → fleet-view-SWBR3VGQ.js} +58 -55
  143. package/dist/{init-5XQRBOFV.js → init-J477LKZH.js} +82 -79
  144. package/dist/{interop-34TVO25M.js → interop-3FCM6XLG.js} +11 -11
  145. package/dist/{library-3QY6KF57.js → library-QUQEIUG6.js} +30 -27
  146. package/dist/{memory-L4UTIIIW.js → memory-SGGSEP65.js} +67 -64
  147. package/dist/{models-ZVX3QOWE.js → models-HEKUAXXK.js} +53 -46
  148. package/dist/{monitor-CEKVSYTS.js → monitor-HKU57TYQ.js} +63 -60
  149. package/dist/{orchestrator-77BAP6BC.js → orchestrator-VDFAEFAI.js} +1831 -1057
  150. package/dist/{panes-7STHOAUJ.js → panes-DN2SSFOH.js} +5 -5
  151. package/dist/{panes-SHAUIRXY.js → panes-TALGNPZT.js} +29 -14
  152. package/dist/{paths-L7LGY6RN.js → paths-NBMFAIEZ.js} +5 -5
  153. package/dist/reset-EAJFFJVB.js +344 -0
  154. package/dist/{resources-74GKTLSF.js → resources-OVKSEFVE.js} +29 -20
  155. package/dist/{run-HBAUJNNZ.js → run-7DP7ZF2J.js} +120 -115
  156. package/dist/{share-G3APVLVP.js → share-WML67FT3.js} +32 -27
  157. package/dist/{skills-35HHUKCR.js → skills-SG662R2K.js} +41 -31
  158. package/dist/{skills-eval-QN4HSHDC.js → skills-eval-VVZEUU46.js} +78 -77
  159. package/dist/{skills-inventory-J357J34F.js → skills-inventory-I2E23GET.js} +23 -20
  160. package/dist/{slash-commands-JZZCQA32.js → slash-commands-S7MBJDQK.js} +40 -36
  161. package/dist/{steer-XAVHJM22.js → steer-2LQOMCPB.js} +3 -3
  162. package/dist/{support-U7QOWY26.js → support-CC2UJBJ6.js} +6 -6
  163. package/dist/{targets-DSM6CY3M.js → targets-4QC3HIEW.js} +54 -54
  164. package/dist/{terminal-lease-JOPFUVEM.js → terminal-lease-TUHIJ6Y2.js} +5 -5
  165. package/dist/{tools-MKNWVPBH.js → tools-TFGJICCU.js} +10 -10
  166. package/dist/{trace-ECQ7TIYZ.js → trace-FXMXUZUF.js} +55 -7
  167. package/dist/uninstall-5PEVOE5B.js +408 -0
  168. package/dist/upgrade-M4WXY6KN.js +303 -0
  169. package/dist/{usage-X52N3IDJ.js → usage-N7ZNVLEM.js} +151 -104
  170. package/dist/{verifiers-EJTVVSMA.js → verifiers-DJTP4XX6.js} +15 -15
  171. package/dist/{verify-YJL6XET2.js → verify-RWE4PPEK.js} +9 -9
  172. package/dist/{web-fetch-MPIFL3LL.js → web-fetch-MPARV2K7.js} +2 -2
  173. package/dist/{wiki-generate-4NDZTQ4B.js → wiki-generate-C7IQOXSP.js} +89 -86
  174. package/dist/{with-panes-OBOBFIIR.js → with-panes-4GCGSL7J.js} +53 -257
  175. package/dist/worker/entry.js +90 -74
  176. package/docs/README.md +176 -81
  177. package/docs/{acp.md → architecture/acp.md} +36 -20
  178. package/docs/{alcf-provider.md → architecture/alcf-provider.md} +8 -5
  179. package/docs/{architecture.md → architecture/architecture.md} +43 -22
  180. package/docs/{artifact-placement.md → architecture/artifact-placement.md} +27 -23
  181. package/docs/architecture/artifact-versions.md +90 -0
  182. package/docs/{capacity-and-scheduling.md → architecture/capacity-and-scheduling.md} +26 -13
  183. package/docs/{context-engine.md → architecture/context-engine.md} +29 -25
  184. package/docs/{context-working-set.md → architecture/context-working-set.md} +13 -10
  185. package/docs/{dispatch-architecture-rationale.md → architecture/dispatch-architecture-rationale.md} +12 -9
  186. package/docs/{dispatch-typed-intent.md → architecture/dispatch-typed-intent.md} +68 -46
  187. package/docs/{evidence-and-memory.md → architecture/evidence-and-memory.md} +23 -16
  188. package/docs/{middleware-and-components.md → architecture/middleware-and-components.md} +11 -5
  189. package/docs/{model-catalog.md → architecture/model-catalog.md} +61 -27
  190. package/docs/{observability.md → architecture/observability.md} +38 -14
  191. package/docs/{pi-boundary.md → architecture/pi-boundary.md} +24 -11
  192. package/docs/{prompt-envelope-and-tools.md → architecture/prompt-envelope-and-tools.md} +57 -20
  193. package/docs/{provider-adapter-cookbook.md → architecture/provider-adapter-cookbook.md} +99 -25
  194. package/docs/{safety-model.md → architecture/safety-model.md} +35 -20
  195. package/docs/{session-lifecycle.md → architecture/session-lifecycle.md} +8 -5
  196. package/docs/architecture/time-conventions.md +125 -0
  197. package/docs/{trace-store.md → architecture/trace-store.md} +13 -5
  198. package/docs/{tui-design.md → architecture/tui-design.md} +13 -13
  199. package/docs/{worker-dispatch-mechanics.md → architecture/worker-dispatch-mechanics.md} +27 -30
  200. package/docs/{built-in-agents.md → guide/built-in-agents.md} +65 -35
  201. package/docs/{commands-and-modes.md → guide/commands-and-modes.md} +66 -61
  202. package/docs/{configuration-and-targets.md → guide/configuration-and-targets.md} +323 -297
  203. package/docs/guide/configuration-reference.md +1163 -0
  204. package/docs/{environment-variables.md → guide/environment-variables.md} +33 -28
  205. package/docs/{exit-codes-and-output.md → guide/exit-codes-and-output.md} +6 -3
  206. package/docs/{extensions-and-sharing.md → guide/extensions-and-sharing.md} +41 -14
  207. package/docs/{fleet-dispatch.md → guide/fleet-dispatch.md} +39 -43
  208. package/docs/{glossary.md → guide/glossary.md} +14 -11
  209. package/docs/{installation-and-lifecycle.md → guide/installation-and-lifecycle.md} +81 -17
  210. package/docs/guide/panes-and-files.md +290 -0
  211. package/docs/{proactive-memory.md → guide/proactive-memory.md} +131 -107
  212. package/docs/{resource-library.md → guide/resource-library.md} +13 -4
  213. package/docs/{skills-marketplace.md → guide/skills-marketplace.md} +25 -3
  214. package/docs/{tool-usage.md → guide/tool-usage.md} +87 -23
  215. package/docs/{troubleshooting.md → guide/troubleshooting.md} +9 -4
  216. package/docs/{config-knobs-audit.md → history/config-knobs-audit.md} +11 -11
  217. package/docs/{release-cut-checklist.md → history/release-cut-checklist.md} +29 -2
  218. package/docs/process/development-pipeline.md +152 -0
  219. package/docs/process/documentation-coverage.md +100 -0
  220. package/docs/process/documentation-guide.md +187 -0
  221. package/docs/{eval-runner.md → process/eval-runner.md} +108 -53
  222. package/docs/{evals-internal.md → process/evals-internal.md} +10 -10
  223. package/docs/{evolution.md → process/evolution.md} +2 -2
  224. package/docs/{fleet-demo-runbook.md → process/fleet-demo-runbook.md} +11 -7
  225. package/docs/{git-commit-provenance.md → process/git-commit-provenance.md} +11 -4
  226. package/docs/{performance-methodology.md → process/performance-methodology.md} +87 -69
  227. package/docs/{scientific-validation.md → process/scientific-validation.md} +4 -4
  228. package/evals/README.md +2 -2
  229. package/evals/behavioral-model.yaml +3 -2
  230. package/package.json +10 -8
  231. package/skills/README.md +52 -41
  232. package/skills/coding/ast-grep/SKILL.md +102 -31
  233. package/skills/coding/ast-grep/evals.md +26 -0
  234. package/skills/coding/coding-standards/SKILL.md +41 -6
  235. package/skills/coding/coding-standards/evals.md +23 -0
  236. package/skills/coding/prototype/SKILL.md +88 -29
  237. package/skills/coding/prototype/evals.md +19 -0
  238. package/skills/coding/tdd/SKILL.md +81 -54
  239. package/skills/coding/tdd/evals.md +20 -0
  240. package/skills/context/context-handoff/SKILL.md +44 -3
  241. package/skills/context/context-handoff/evals.md +44 -0
  242. package/skills/context/context-prime/SKILL.md +46 -16
  243. package/skills/context/context-prime/evals.md +45 -0
  244. package/skills/git/branch-closeout/SKILL.md +132 -0
  245. package/skills/git/branch-closeout/evals.md +133 -0
  246. package/skills/git/branch-closeout/references/closeout-checklist.md +81 -0
  247. package/skills/git/file-ticket/SKILL.md +78 -64
  248. package/skills/git/file-ticket/assets/issue-template.md +22 -0
  249. package/skills/git/file-ticket/evals.md +31 -26
  250. package/skills/git/file-ticket/references/issue-discovery.md +49 -0
  251. package/skills/git/fix-issue/SKILL.md +88 -65
  252. package/skills/git/fix-issue/evals.md +35 -31
  253. package/skills/git/fix-issue/references/diagnosis-and-rca.md +46 -0
  254. package/skills/git/resolve-merge-conflicts/SKILL.md +101 -52
  255. package/skills/git/resolve-merge-conflicts/evals.md +52 -25
  256. package/skills/git/resolve-merge-conflicts/references/conflict-matrix.md +126 -0
  257. package/skills/git/ship/SKILL.md +103 -67
  258. package/skills/git/ship/assets/pr-template.md +21 -0
  259. package/skills/git/ship/evals.md +44 -28
  260. package/skills/git/ship/references/remote-and-branch-policy.md +62 -0
  261. package/skills/git/worktree-create/SKILL.md +80 -50
  262. package/skills/git/worktree-create/evals.md +40 -33
  263. package/skills/git/worktree-create/references/worktree-setup.md +62 -66
  264. package/skills/git/worktree-merge/SKILL.md +112 -65
  265. package/skills/git/worktree-merge/evals.md +42 -34
  266. package/skills/git/worktree-merge/references/merge-strategies.md +52 -0
  267. package/skills/meta/clio-coder-dev/SKILL.md +9 -5
  268. package/skills/meta/clio-coder-dev/evals.md +3 -2
  269. package/skills/meta/clio-coder-test/SKILL.md +102 -95
  270. package/skills/meta/clio-coder-test/evals.md +9 -4
  271. package/skills/meta/clio-coder-test/references/harness.md +100 -124
  272. package/skills/meta/clio-coder-test/references/test-map.md +77 -50
  273. package/skills/meta/credentials/SKILL.md +2 -2
  274. package/skills/meta/find-skills/SKILL.md +2 -2
  275. package/skills/meta/herdr/SKILL.md +2 -2
  276. package/skills/meta/skill-craft/SKILL.md +22 -16
  277. package/skills/planning/archify/SKILL.md +196 -0
  278. package/skills/planning/archify/evals.md +65 -0
  279. package/skills/planning/architecture/SKILL.md +62 -13
  280. package/skills/planning/architecture/evals.md +65 -0
  281. package/skills/planning/backlog/SKILL.md +131 -15
  282. package/skills/planning/backlog/evals.md +142 -0
  283. package/skills/planning/prd/SKILL.md +47 -7
  284. package/skills/planning/prd/evals.md +54 -0
  285. package/skills/planning/product-intent/SKILL.md +58 -3
  286. package/skills/planning/product-intent/evals.md +70 -0
  287. package/skills/planning/tech-spec/SKILL.md +54 -3
  288. package/skills/planning/tech-spec/evals.md +73 -0
  289. package/skills/registry.yaml +70 -62
  290. package/skills/remote.yaml +13 -0
  291. package/skills/research/arxiv-literature/SKILL.md +77 -19
  292. package/skills/research/arxiv-literature/evals.md +50 -0
  293. package/skills/research/experiment-protocol/SKILL.md +21 -2
  294. package/skills/research/experiment-protocol/evals.md +23 -0
  295. package/skills/research/scientific-debugging/SKILL.md +24 -2
  296. package/skills/research/scientific-debugging/evals.md +18 -0
  297. package/skills/research/scientific-modernization/SKILL.md +27 -2
  298. package/skills/research/scientific-modernization/evals.md +27 -0
  299. package/skills/skill-marketplace.json +97 -62
  300. package/skills/workflow/cut-it/SKILL.md +66 -6
  301. package/skills/workflow/cut-it/evals.md +101 -0
  302. package/skills/workflow/design-council/SKILL.md +118 -28
  303. package/skills/workflow/design-council/evals.md +161 -0
  304. package/skills/workflow/grill-me/SKILL.md +87 -11
  305. package/skills/workflow/grill-me/evals.md +153 -0
  306. package/skills/workflow/workflow-distiller/SKILL.md +77 -18
  307. package/skills/workflow/workflow-distiller/evals.md +118 -0
  308. package/src/cli/args.ts +2 -2
  309. package/src/cli/bootstrap-generate.ts +1 -1
  310. package/src/cli/config-inspect.ts +65 -12
  311. package/src/cli/configure-interop.ts +105 -13
  312. package/src/cli/configure-oauth.ts +57 -0
  313. package/src/cli/configure-onboarding.ts +980 -0
  314. package/src/cli/configure-target.ts +594 -0
  315. package/src/cli/configure.ts +1082 -532
  316. package/src/cli/context-map.ts +114 -0
  317. package/src/cli/context.ts +4 -0
  318. package/src/cli/docs.ts +22 -14
  319. package/src/cli/doctor-naming.ts +5 -5
  320. package/src/cli/doctor-toolchain.ts +3 -3
  321. package/src/cli/eval.ts +1 -2
  322. package/src/cli/extensions.ts +2 -1
  323. package/src/cli/fleet.ts +1 -1
  324. package/src/cli/index.ts +3 -1
  325. package/src/cli/internal-dispatch.ts +3 -4
  326. package/src/cli/lifecycle-presenter.ts +436 -0
  327. package/src/cli/models.ts +10 -2
  328. package/src/cli/modes/print.ts +5 -1
  329. package/src/cli/panes.ts +19 -5
  330. package/src/cli/reset.ts +228 -106
  331. package/src/cli/run.ts +9 -4
  332. package/src/cli/select.ts +664 -0
  333. package/src/cli/share.ts +5 -1
  334. package/src/cli/skills-eval.ts +3 -3
  335. package/src/cli/skills.ts +9 -2
  336. package/src/cli/targets.ts +5 -6
  337. package/src/cli/trace.ts +55 -4
  338. package/src/cli/uninstall.ts +233 -165
  339. package/src/cli/upgrade.ts +204 -149
  340. package/src/cli/usage.ts +86 -27
  341. package/src/cli/validate-model.ts +3 -3
  342. package/src/cli/wiki-generate.ts +1 -1
  343. package/src/core/artifact-paths.ts +1 -1
  344. package/src/core/bash-exec.ts +131 -86
  345. package/src/core/bus-events.ts +51 -6
  346. package/src/core/config.ts +61 -1
  347. package/src/core/defaults.ts +7 -4
  348. package/src/core/dispatch-outcome.ts +16 -0
  349. package/src/core/external-diagnostic.ts +44 -0
  350. package/src/core/gateway-routing.ts +157 -0
  351. package/src/core/guardrails.ts +10 -49
  352. package/src/core/prompt-hint.ts +9 -0
  353. package/src/core/safe-exec.ts +17 -2
  354. package/src/core/skill-activation.ts +89 -2
  355. package/src/domains/agents/builtins/architect.md +2 -3
  356. package/src/domains/agents/builtins/coder.md +3 -2
  357. package/src/domains/agents/builtins/debugger.md +2 -2
  358. package/src/domains/agents/builtins/documenter.md +2 -2
  359. package/src/domains/agents/builtins/git-master.md +1 -1
  360. package/src/domains/agents/builtins/oracle.md +1 -1
  361. package/src/domains/agents/builtins/provenance.md +1 -1
  362. package/src/domains/agents/builtins/researcher.md +1 -1
  363. package/src/domains/agents/builtins/scout.md +1 -1
  364. package/src/domains/agents/builtins/tester.md +2 -2
  365. package/src/domains/agents/builtins/verifier.md +2 -2
  366. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  367. package/src/domains/agents/builtins/world-knowledge.md +31 -0
  368. package/src/domains/agents/catalog.ts +13 -15
  369. package/src/domains/agents/contract.ts +2 -0
  370. package/src/domains/agents/extension.ts +23 -1
  371. package/src/domains/agents/result-contract.ts +70 -0
  372. package/src/domains/config/keybindings.ts +8 -0
  373. package/src/domains/context/extension.ts +0 -3
  374. package/src/domains/context/wiki/map-seed.ts +589 -0
  375. package/src/domains/context/wiki/plan.ts +2 -2
  376. package/src/domains/context/working-set/path-index.ts +1 -0
  377. package/src/domains/dispatch/admission.ts +29 -0
  378. package/src/domains/dispatch/agent-candidates.ts +10 -0
  379. package/src/domains/dispatch/budget-envelope.ts +86 -1
  380. package/src/domains/dispatch/capability-match.ts +11 -0
  381. package/src/domains/dispatch/capacity-lease.ts +17 -0
  382. package/src/domains/dispatch/contract.ts +11 -1
  383. package/src/domains/dispatch/extension.ts +237 -49
  384. package/src/domains/dispatch/host-verification.ts +435 -39
  385. package/src/domains/dispatch/intent-requirements.ts +10 -0
  386. package/src/domains/dispatch/intent.ts +18 -1
  387. package/src/domains/dispatch/path-scope.ts +235 -24
  388. package/src/domains/dispatch/run-event-journal.ts +4 -15
  389. package/src/domains/dispatch/state.ts +2 -3
  390. package/src/domains/dispatch/transport.ts +45 -21
  391. package/src/domains/dispatch/types.ts +58 -3
  392. package/src/domains/dispatch/worker-model-metadata.ts +38 -0
  393. package/src/domains/eval/artifacts/store.ts +5 -0
  394. package/src/domains/eval/metrics/call-ledger-stream.ts +34 -11
  395. package/src/domains/eval/metrics/token-stream.ts +201 -31
  396. package/src/domains/eval/metrics/tracked.ts +40 -4
  397. package/src/domains/eval/runners/clio-run.ts +5 -2
  398. package/src/domains/eval/schema/suite.ts +28 -0
  399. package/src/domains/eval/schema/verdict.ts +2 -2
  400. package/src/domains/eval/store.ts +8 -1
  401. package/src/domains/eval/suites/resolve.ts +13 -1
  402. package/src/domains/eval/suites/run.ts +24 -3
  403. package/src/domains/evidence/trust-status.ts +10 -1
  404. package/src/domains/extensions/contract.ts +15 -1
  405. package/src/domains/extensions/discovery.ts +238 -41
  406. package/src/domains/extensions/extension.ts +105 -6
  407. package/src/domains/extensions/index.ts +24 -0
  408. package/src/domains/extensions/integrity.ts +189 -0
  409. package/src/domains/extensions/manager.ts +17 -1
  410. package/src/domains/extensions/resource-path.ts +27 -0
  411. package/src/domains/extensions/resources.ts +18 -38
  412. package/src/domains/extensions/snapshot-store.ts +39 -0
  413. package/src/domains/extensions/snapshot.ts +180 -0
  414. package/src/domains/extensions/state.ts +385 -57
  415. package/src/domains/extensions/types.ts +118 -1
  416. package/src/domains/interop/registry.ts +6 -2
  417. package/src/domains/interop/types.ts +4 -0
  418. package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +27 -0
  419. package/src/domains/lifecycle/migrations/index.ts +6 -0
  420. package/src/domains/lifecycle/naming-resources.ts +19 -4
  421. package/src/domains/lifecycle/naming-yazi.ts +10 -5
  422. package/src/domains/memory/task-memory-policy.ts +70 -26
  423. package/src/domains/memory/task-memory-telemetry.ts +1 -0
  424. package/src/domains/middleware/contract.ts +26 -0
  425. package/src/domains/middleware/extension.ts +24 -24
  426. package/src/domains/middleware/hook-receipts.ts +27 -4
  427. package/src/domains/middleware/hooks-io.ts +65 -32
  428. package/src/domains/middleware/hooks.ts +64 -0
  429. package/src/domains/middleware/index.ts +28 -5
  430. package/src/domains/middleware/marketplace-offer.ts +3 -35
  431. package/src/domains/middleware/memory-intervention.ts +127 -32
  432. package/src/domains/middleware/memory-step-endpoint.ts +3 -2
  433. package/src/domains/middleware/registrations.ts +326 -0
  434. package/src/domains/middleware/runtime.ts +28 -0
  435. package/src/domains/middleware/skills-reminder.ts +31 -2
  436. package/src/domains/middleware/snapshot.ts +20 -7
  437. package/src/domains/mux/contract.ts +38 -0
  438. package/src/domains/mux/detect.ts +6 -13
  439. package/src/domains/mux/index.ts +1 -1
  440. package/src/domains/mux/operations.ts +44 -5
  441. package/src/domains/mux/yazi/assets/yazi.toml +2 -2
  442. package/src/domains/mux/yazi/session.ts +53 -4
  443. package/src/domains/mux/yazi/theme.ts +117 -17
  444. package/src/domains/observability/compaction-usage.ts +118 -0
  445. package/src/domains/observability/contract.ts +10 -11
  446. package/src/domains/observability/cost.ts +1 -1
  447. package/src/domains/observability/extension.ts +17 -4
  448. package/src/domains/observability/out-of-turn-usage.ts +52 -21
  449. package/src/domains/observability/projection.ts +14 -90
  450. package/src/domains/observability/trace-store.ts +43 -7
  451. package/src/domains/prompts/compiler.ts +73 -53
  452. package/src/domains/prompts/contract.ts +15 -3
  453. package/src/domains/prompts/extension.ts +97 -9
  454. package/src/domains/prompts/fragments/identity/clio-worker.md +1 -3
  455. package/src/domains/prompts/fragments/identity/clio.md +6 -12
  456. package/src/domains/prompts/fragments/identity/docs-routing.md +1 -2
  457. package/src/domains/prompts/fragments/identity/self-awareness.md +3 -11
  458. package/src/domains/prompts/fragments/operating/contract.md +7 -15
  459. package/src/domains/prompts/fragments/operating/delegation.md +32 -34
  460. package/src/domains/prompts/fragments/operating/skills.md +10 -24
  461. package/src/domains/prompts/fragments/operating/worker.md +1 -8
  462. package/src/domains/providers/contract.ts +4 -1
  463. package/src/domains/providers/extension.ts +40 -9
  464. package/src/domains/providers/index.ts +1 -1
  465. package/src/domains/providers/model-capabilities.ts +9 -0
  466. package/src/domains/providers/model-discovery.ts +2 -0
  467. package/src/domains/providers/model-runtime-capabilities.ts +99 -25
  468. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +699 -114
  469. package/src/domains/providers/runtime-resolution.ts +31 -0
  470. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +225 -45
  471. package/src/domains/providers/runtimes/common/lmstudio-http.ts +6 -2
  472. package/src/domains/providers/runtimes/common/local-synth.ts +2 -0
  473. package/src/domains/providers/runtimes/common/probe-helpers.ts +7 -2
  474. package/src/domains/providers/runtimes/local-native/llamacpp.ts +9 -1
  475. package/src/domains/providers/runtimes/protocol/litellm.ts +119 -29
  476. package/src/domains/providers/support.ts +11 -5
  477. package/src/domains/providers/target-model-cache.ts +25 -2
  478. package/src/domains/providers/types/capability-flags.ts +2 -0
  479. package/src/domains/providers/types/cost-provenance.ts +19 -0
  480. package/src/domains/providers/types/local-model-quirks.ts +85 -37
  481. package/src/domains/providers/types/runtime-descriptor.ts +20 -1
  482. package/src/domains/providers/types/target-descriptor.ts +19 -0
  483. package/src/domains/resources/index.ts +3 -0
  484. package/src/domains/resources/skills/install.ts +72 -7
  485. package/src/domains/resources/skills/loader.ts +23 -19
  486. package/src/domains/resources/skills/marketplace.ts +63 -11
  487. package/src/domains/safety/autonomy.ts +15 -0
  488. package/src/domains/safety/call-target.ts +1 -1
  489. package/src/domains/safety/index.ts +1 -0
  490. package/src/domains/safety/loop-detector.ts +7 -4
  491. package/src/domains/safety/path-policy.ts +1 -1
  492. package/src/domains/safety/policy-engine.ts +34 -11
  493. package/src/domains/safety/protected-artifacts.ts +191 -88
  494. package/src/domains/safety/run-effects.ts +2 -22
  495. package/src/domains/safety/skill-authority.ts +55 -0
  496. package/src/domains/session/compaction/compact.ts +72 -22
  497. package/src/domains/session/entries.ts +6 -0
  498. package/src/domains/session/task-board.ts +10 -9
  499. package/src/domains/session/usage.ts +3 -3
  500. package/src/domains/share/archive.ts +164 -7
  501. package/src/engine/acp/server.ts +62 -9
  502. package/src/engine/agent.ts +13 -3
  503. package/src/engine/ai.ts +26 -8
  504. package/src/engine/antigravity/subprocess-runtime.ts +386 -120
  505. package/src/engine/api-registry.ts +3 -0
  506. package/src/engine/apis/llamacpp-residency.ts +3 -4
  507. package/src/engine/apis/lmstudio.ts +3 -3
  508. package/src/engine/apis/ollama-native.ts +6 -6
  509. package/src/engine/apis/openai-completions.ts +145 -39
  510. package/src/engine/apis/output-budget.ts +8 -18
  511. package/src/engine/apis/residency.ts +8 -27
  512. package/src/engine/external-subprocess.ts +114 -6
  513. package/src/engine/gemma-channel-filter.ts +19 -0
  514. package/src/engine/loop-guard.ts +92 -12
  515. package/src/engine/worker-runtime.ts +40 -11
  516. package/src/engine/worker-tools.ts +3 -1
  517. package/src/entry/background-model-metadata.ts +18 -0
  518. package/src/entry/compaction-prompt.ts +57 -0
  519. package/src/entry/extension-hook-sources.ts +28 -0
  520. package/src/entry/extension-reload.ts +309 -0
  521. package/src/entry/orchestrator.ts +464 -251
  522. package/src/entry/task-memory-lifecycle.ts +35 -0
  523. package/src/interactive/application-controller.ts +2 -1
  524. package/src/interactive/bus-notices.ts +8 -1
  525. package/src/interactive/chat-loop-messages.ts +16 -17
  526. package/src/interactive/chat-loop.ts +75 -3
  527. package/src/interactive/chat-panel.ts +36 -13
  528. package/src/interactive/chat-renderer.ts +72 -7
  529. package/src/interactive/cost-overlay.ts +26 -2
  530. package/src/interactive/dispatch-board.ts +6 -11
  531. package/src/interactive/footer/widgets.ts +13 -0
  532. package/src/interactive/interactive-application.ts +39 -4
  533. package/src/interactive/interactive-input-runtime.ts +4 -0
  534. package/src/interactive/interactive-presentation.ts +2 -2
  535. package/src/interactive/interactive-slash-runtime.ts +4 -1
  536. package/src/interactive/overlays/extensions.ts +9 -1
  537. package/src/interactive/overlays/help-reference.ts +13 -0
  538. package/src/interactive/overlays/settings.ts +27 -16
  539. package/src/interactive/panes-runtime.ts +111 -35
  540. package/src/interactive/prompt-cache-identity.ts +88 -0
  541. package/src/interactive/renderers/worker-entry.ts +32 -0
  542. package/src/interactive/slash-commands.ts +153 -20
  543. package/src/interactive/stream-pacing-policy.ts +0 -23
  544. package/src/interactive/theme/labels.ts +19 -13
  545. package/src/interactive/turn-context.ts +39 -20
  546. package/src/interactive/turn-recovery.ts +8 -0
  547. package/src/interactive/turn-runtime.ts +27 -11
  548. package/src/interactive/turn-state.ts +7 -0
  549. package/src/interactive/worker-receipts.ts +1 -0
  550. package/src/interactive/worker-stream.ts +6 -1
  551. package/src/interactive/yazi-bridge.ts +60 -6
  552. package/src/tools/agent-tools.ts +30 -1
  553. package/src/tools/artifact.ts +2 -2
  554. package/src/tools/ask-user.ts +3 -3
  555. package/src/tools/bash.ts +1 -1
  556. package/src/tools/bootstrap.ts +4 -0
  557. package/src/tools/builtin-tool-catalog.ts +52 -22
  558. package/src/tools/codewiki/code-nav-surface.ts +6 -0
  559. package/src/tools/codewiki/code-nav.ts +99 -13
  560. package/src/tools/context/docs-engine.ts +20 -7
  561. package/src/tools/context/index.ts +59 -21
  562. package/src/tools/core-bootstrap.ts +28 -6
  563. package/src/tools/credential-present.ts +1 -2
  564. package/src/tools/dispatch-arguments.ts +6 -1
  565. package/src/tools/dispatch-event-text.ts +10 -0
  566. package/src/tools/dispatch-plan.ts +49 -4
  567. package/src/tools/dispatch-run-events.ts +1 -1
  568. package/src/tools/dispatch-runner.ts +12 -0
  569. package/src/tools/dispatch-schema.ts +338 -0
  570. package/src/tools/dispatch-types.ts +3 -0
  571. package/src/tools/dispatch.ts +9 -254
  572. package/src/tools/ledger.ts +3 -5
  573. package/src/tools/monitor-surface.ts +5 -13
  574. package/src/tools/observation.ts +4 -5
  575. package/src/tools/panes-surface.ts +4 -11
  576. package/src/tools/panes.ts +4 -2
  577. package/src/tools/policy.ts +15 -2
  578. package/src/tools/read.ts +5 -6
  579. package/src/tools/registry.ts +41 -12
  580. package/src/tools/result-shaping.ts +18 -14
  581. package/src/tools/steer-surface.ts +1 -1
  582. package/src/tools/tasks.ts +1 -1
  583. package/src/tools/truncate.ts +6 -5
  584. package/src/tools/verify/surface.ts +6 -12
  585. package/src/tools/web-fetch-surface.ts +1 -3
  586. package/src/tools/worker-evidence.ts +3 -1
  587. package/src/worker/spec-contract.ts +4 -0
  588. package/dist/builtins-UJLMOVOV.js +0 -17
  589. package/dist/chunk-5QIAJV2D.js +0 -48
  590. package/dist/chunk-JZWT5J3Y.js +0 -814
  591. package/dist/chunk-K7VKOLQQ.js +0 -15
  592. package/dist/chunk-PMZCIOCJ.js +0 -25
  593. package/dist/chunk-SUW5DORT.js +0 -819
  594. package/dist/chunk-UOV2BYIW.js +0 -107
  595. package/dist/chunk-WR6U3OVP.js +0 -45
  596. package/dist/chunk-Y45G3AXC.js +0 -1558
  597. package/dist/reset-EOLM7GVE.js +0 -230
  598. package/dist/uninstall-N34PCTGJ.js +0 -331
  599. package/dist/upgrade-H7TOM7YL.js +0 -323
  600. package/docs/artifact-versions.md +0 -67
  601. package/docs/development-pipeline.md +0 -121
  602. package/docs/documentation-coverage.md +0 -46
  603. package/docs/documentation-guide.md +0 -167
  604. package/docs/time-conventions.md +0 -101
@@ -27,6 +27,19 @@ export interface ExtensionDiagnostic {
27
27
  path?: string;
28
28
  }
29
29
 
30
+ export interface ExtensionProvenance {
31
+ id: string;
32
+ scope: ExtensionScope;
33
+ /** Path recorded in install state, when known. */
34
+ sourcePath?: string;
35
+ /** Canonical filesystem identity of the installed package root. */
36
+ canonicalRoot: string;
37
+ /** SHA-256 of the manifest bytes covered by the installed-tree digest. */
38
+ manifestDigest: string;
39
+ /** Installed-tree digest recorded at install and reverified on this load. */
40
+ contentDigest: string;
41
+ }
42
+
30
43
  export interface InstalledExtension {
31
44
  id: string;
32
45
  name: string;
@@ -36,14 +49,28 @@ export interface InstalledExtension {
36
49
  rootPath: string;
37
50
  manifestPath: string;
38
51
  enabled: boolean;
52
+ /** Whether the complete manifest and declared resource tree are valid. */
53
+ valid: boolean;
39
54
  /** Whether this package admits the running Clio version. */
40
55
  compatible: boolean;
41
56
  effective: boolean;
57
+ /** The single admission decision for extension-owned resources and hooks. */
58
+ loadable: boolean;
59
+ /** Present exactly when the installed tree and manifest bytes were reverified. */
60
+ provenance?: ExtensionProvenance;
61
+ /** Digest observed while checking installed content on this load. */
62
+ observedContentDigest?: string;
42
63
  resources: ExtensionManifestResources;
43
64
  overriddenBy?: ExtensionScope;
44
65
  diagnostics: ExtensionDiagnostic[];
45
66
  }
46
67
 
68
+ export type LoadableExtension = InstalledExtension & { loadable: true; provenance: ExtensionProvenance };
69
+
70
+ export function isLoadableExtension(entry: InstalledExtension): entry is LoadableExtension {
71
+ return entry.loadable && entry.provenance !== undefined;
72
+ }
73
+
47
74
  export interface ExtensionCandidate {
48
75
  path: string;
49
76
  manifestPath?: string;
@@ -58,8 +85,88 @@ export interface ExtensionResourceRoot {
58
85
  path: string;
59
86
  rootPath: string;
60
87
  source: string;
88
+ provenance: ExtensionProvenance;
89
+ /** Zero denotes an ephemeral, uncommitted projection. */
90
+ generation: number;
91
+ }
92
+
93
+ export interface ExtensionHookSource {
94
+ provenance: ExtensionProvenance;
95
+ /** SHA-256 of the captured hooks.yaml bytes. */
96
+ declarationsDigest: string;
97
+ /** Parsed captured YAML, or an empty list when parsing failed. */
98
+ declarations: unknown;
99
+ parseError?: string;
61
100
  }
62
101
 
102
+ export interface ExtensionSnapshotDiagnostics {
103
+ entries: ReadonlyArray<ExtensionDiagnostic & { extensionId?: string }>;
104
+ truncated: number;
105
+ }
106
+
107
+ export interface ExtensionSnapshot {
108
+ version: 1;
109
+ generation: number;
110
+ cwd: string;
111
+ builtAt: string;
112
+ /** Content identity; generation, timestamp, and diagnostic text are excluded. */
113
+ digest: string;
114
+ packages: ReadonlyArray<InstalledExtension>;
115
+ resourceRoots: Readonly<Record<ExtensionResourceKind, ReadonlyArray<ExtensionResourceRoot>>>;
116
+ hookSources: ReadonlyArray<ExtensionHookSource>;
117
+ diagnostics: ExtensionSnapshotDiagnostics;
118
+ }
119
+
120
+ export type ExtensionReloadRejectionReason = "build-failed" | "reentrant" | "stale" | "workspace-changed";
121
+
122
+ export interface ExtensionReloadRejection {
123
+ status: "rejected";
124
+ reason: ExtensionReloadRejectionReason;
125
+ /** Generation that remains committed. */
126
+ generation: number;
127
+ diagnostics: ExtensionSnapshotDiagnostics;
128
+ }
129
+
130
+ /**
131
+ * A fully built and validated generation that has not been published. The
132
+ * bundle holds at most one candidate at a time. `publish` is one reference
133
+ * assignment that never validates, refuses, throws, or calls out; the caller
134
+ * checks `current()` on the same stack immediately before it. `discard`
135
+ * releases the candidate without any visible change.
136
+ */
137
+ export interface ExtensionReloadCandidate {
138
+ generation: number;
139
+ previousGeneration: number;
140
+ snapshot: ExtensionSnapshot;
141
+ /** False when the candidate digest equals the committed digest. */
142
+ changed: boolean;
143
+ added: ReadonlyArray<string>;
144
+ removed: ReadonlyArray<string>;
145
+ modified: ReadonlyArray<string>;
146
+ /** True while this is the in-flight candidate and the committed snapshot it was diffed against is still live. */
147
+ current(): boolean;
148
+ publish(): void;
149
+ discard(): void;
150
+ }
151
+
152
+ export type ExtensionReloadPrepareResult =
153
+ | { status: "prepared"; candidate: ExtensionReloadCandidate }
154
+ | ExtensionReloadRejection;
155
+
156
+ export interface ExtensionReloadCommitted {
157
+ status: "committed";
158
+ generation: number;
159
+ previousGeneration: number;
160
+ changed: boolean;
161
+ digest: string;
162
+ added: ReadonlyArray<string>;
163
+ removed: ReadonlyArray<string>;
164
+ modified: ReadonlyArray<string>;
165
+ diagnostics: ExtensionSnapshotDiagnostics;
166
+ }
167
+
168
+ export type ExtensionReloadResult = ExtensionReloadCommitted | ExtensionReloadRejection;
169
+
63
170
  export interface ExtensionListOptions {
64
171
  scope?: ExtensionScope;
65
172
  cwd?: string;
@@ -72,17 +179,27 @@ export interface ExtensionInstallOptions extends ExtensionListOptions {
72
179
 
73
180
  export interface ExtensionInstallResult {
74
181
  extension?: InstalledExtension;
182
+ recovery?: { stateBackup?: string; packageBackup?: string };
75
183
  diagnostics: ExtensionDiagnostic[];
76
184
  }
77
185
 
78
186
  export interface ExtensionMutationResult {
79
187
  extension?: InstalledExtension;
80
188
  removed?: { id: string; scope: ExtensionScope; path: string };
189
+ recovery?: { stateBackup?: string; packageBackup?: string };
81
190
  diagnostics: ExtensionDiagnostic[];
82
191
  }
83
192
 
193
+ export interface ExtensionStateUpgradeReport {
194
+ scope: ExtensionScope;
195
+ statePath: string;
196
+ backupPath?: string;
197
+ upgraded: string[];
198
+ refused: Array<{ id: string; reason: string }>;
199
+ }
200
+
84
201
  export interface ExtensionState {
85
202
  version: 1;
86
203
  disabled: string[];
87
- installed: Record<string, { installedAt: string; source?: string }>;
204
+ installed: Record<string, { installedAt: string; source?: string; contentDigest?: string }>;
88
205
  }
@@ -94,8 +94,10 @@ export const INTEROP_AGENT_KINDS: ReadonlyArray<InteropAgentKind> = [
94
94
  id: "antigravity",
95
95
  label: "Antigravity CLI",
96
96
  binaryNames: ["agy"],
97
- userDir: ".antigravitycli",
98
- projectDir: ".antigravitycli",
97
+ userDir: ".gemini/antigravity-cli",
98
+ legacyUserDirs: [".antigravitycli"],
99
+ projectDir: ".gemini/antigravity-cli",
100
+ legacyProjectDirs: [".antigravitycli"],
99
101
  instructionFiles: [],
100
102
  },
101
103
  {
@@ -133,7 +135,9 @@ export function foreignAgentDirs(): ReadonlyArray<string> {
133
135
  const dirs: string[] = [];
134
136
  for (const kind of INTEROP_AGENT_KINDS) {
135
137
  dirs.push(`~/${kind.userDir}/`);
138
+ for (const legacy of kind.legacyUserDirs ?? []) dirs.push(`~/${legacy}/`);
136
139
  if (kind.projectDir !== undefined) dirs.push(`${kind.projectDir}/`);
140
+ for (const legacy of kind.legacyProjectDirs ?? []) dirs.push(`${legacy}/`);
137
141
  }
138
142
  return [...new Set(dirs)];
139
143
  }
@@ -33,8 +33,12 @@ export interface InteropAgentKind {
33
33
  binaryNames: ReadonlyArray<string>;
34
34
  /** Home-relative directory the agent owns. */
35
35
  userDir: string;
36
+ /** Older home-relative roots still owned by supported installations. */
37
+ legacyUserDirs?: ReadonlyArray<string>;
36
38
  /** Project-relative directory the agent owns, when it has one distinct from the repo's own. */
37
39
  projectDir?: string;
40
+ /** Older project-relative roots still protected from Clio writes. */
41
+ legacyProjectDirs?: ReadonlyArray<string>;
38
42
  userSkillRoot?: string;
39
43
  projectSkillRoot?: string;
40
44
  userPromptRoot?: string;
@@ -0,0 +1,27 @@
1
+ import { mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { safeResourceWrite } from "../../../core/safe-resource-write.js";
4
+ import { upgradeLegacyExtensionInstallState } from "../../extensions/state.js";
5
+ import type { Migration } from "./index.js";
6
+
7
+ export const EXTENSION_INSTALL_DIGESTS_MIGRATION_ID = "2026-09-01-extension-install-digests";
8
+
9
+ function migrateExtensionInstallDigests(stateDir: string, cwd = process.cwd()): void {
10
+ const scopes = upgradeLegacyExtensionInstallState(cwd);
11
+ const reportDir = join(stateDir, "migration-reports");
12
+ mkdirSync(reportDir, { recursive: true });
13
+ safeResourceWrite(
14
+ join(reportDir, `${EXTENSION_INSTALL_DIGESTS_MIGRATION_ID}.json`),
15
+ `${JSON.stringify({ migration: EXTENSION_INSTALL_DIGESTS_MIGRATION_ID, scopes }, null, 2)}\n`,
16
+ { encoding: "utf8", mode: 0o644 },
17
+ );
18
+ }
19
+
20
+ const migration: Migration = {
21
+ id: EXTENSION_INSTALL_DIGESTS_MIGRATION_ID,
22
+ async up(stateDir: string): Promise<void> {
23
+ migrateExtensionInstallDigests(stateDir);
24
+ },
25
+ };
26
+
27
+ export default migration;
@@ -34,6 +34,7 @@ import { join } from "node:path";
34
34
 
35
35
  import lmStudioRuntimeId from "./2026-08-18-lmstudio-runtime-id.js";
36
36
  import clioCoderNaming from "./2026-09-01-clio-coder-naming.js";
37
+ import extensionInstallDigests from "./2026-09-01-extension-install-digests.js";
37
38
  import retirePanesKnobs from "./2026-09-01-retire-panes-knobs.js";
38
39
  import settingsV2 from "./2026-09-01-settings-v2.js";
39
40
 
@@ -61,6 +62,7 @@ export interface MigrationRunResult {
61
62
  // migration independently and for manifest continuity; it is a no-op on v2.
62
63
  const REGISTRY: ReadonlyArray<Migration> = Object.freeze([
63
64
  settingsV2,
65
+ extensionInstallDigests,
64
66
  clioCoderNaming,
65
67
  retirePanesKnobs,
66
68
  lmStudioRuntimeId,
@@ -70,6 +72,10 @@ export function listMigrations(): ReadonlyArray<Migration> {
70
72
  return REGISTRY;
71
73
  }
72
74
 
75
+ export function readMigrationManifest(stateDir: string): MigrationManifest {
76
+ return readManifest(manifestPath(stateDir));
77
+ }
78
+
73
79
  function manifestPath(stateDir: string): string {
74
80
  return join(stateDir, "migrations.json");
75
81
  }
@@ -9,12 +9,14 @@ import {
9
9
  statSync,
10
10
  writeFileSync,
11
11
  } from "node:fs";
12
+ import { homedir } from "node:os";
12
13
  import path from "node:path";
13
14
 
14
15
  import { parse as parseYaml } from "yaml";
15
16
  import { resolvePackageRoot } from "../../core/package-root.js";
16
17
  import { fsyncDirectory } from "../../core/safe-resource-write.js";
17
18
  import { resolveClioDirs } from "../../core/xdg.js";
19
+ import { INTEROP_AGENT_KINDS } from "../interop/registry.js";
18
20
  import { normalizedSkillHash, stripProvenanceFrontmatter } from "../resources/skills/content-hash.js";
19
21
 
20
22
  const LEGACY_SKILL_NAMES = [
@@ -35,6 +37,8 @@ export interface NamingResourceReport {
35
37
  export interface NamingResourceOptions {
36
38
  cwd?: string;
37
39
  configDir?: string;
40
+ /** Home directory whose interop skill roots are inspected; defaults to the OS home. */
41
+ home?: string;
38
42
  packageRoot?: string;
39
43
  fix?: boolean;
40
44
  }
@@ -206,14 +210,25 @@ function collectSkillFiles(root: string, current = root): string[] {
206
210
  return out;
207
211
  }
208
212
 
209
- /** Read-only inventory of released skill metadata keys in selected Clio Coder roots. */
213
+ /**
214
+ * Read-only inventory of released skill metadata keys in every root the skill
215
+ * loader reads: the Clio user and project roots plus each interop agent's
216
+ * user and project compatibility roots (`.claude/skills`, `.agents/skills`,
217
+ * ...). The loader warns for a legacy key in any of them, so the doctor has to
218
+ * look where the loader looks or it reports "canonical" while boot warns.
219
+ */
210
220
  export function inspectSkillMetadataNaming(
211
- options: Pick<NamingResourceOptions, "cwd" | "configDir"> = {},
221
+ options: Pick<NamingResourceOptions, "cwd" | "configDir" | "home"> = {},
212
222
  ): SkillMetadataNamingInspection[] {
213
223
  const cwd = options.cwd ?? process.cwd();
214
224
  const configDir = options.configDir ?? resolveClioDirs().config;
215
- const roots = [path.join(configDir, "skills"), path.join(cwd, ".clio-coder", "skills")];
216
- return roots.flatMap((root) =>
225
+ const home = options.home ?? homedir();
226
+ const roots = new Set<string>([path.join(configDir, "skills"), path.join(cwd, ".clio-coder", "skills")]);
227
+ for (const kind of INTEROP_AGENT_KINDS) {
228
+ if (kind.userSkillRoot !== undefined) roots.add(path.join(home, kind.userSkillRoot));
229
+ if (kind.projectSkillRoot !== undefined) roots.add(path.join(cwd, kind.projectSkillRoot));
230
+ }
231
+ return [...roots].flatMap((root) =>
217
232
  collectSkillFiles(root).map((file) => ({
218
233
  path: file,
219
234
  legacyMetadataKey: /^clio:\s*(?:#.*)?$/mu.test(readFileSync(file, "utf8")),
@@ -54,10 +54,14 @@ export function regenerateYaziNamingProfile(options: YaziNamingOptions = {}): Ya
54
54
  const cacheDir = options.cacheDir ?? resolveClioDirs().cache;
55
55
  const before = inspectYaziNaming(cacheDir);
56
56
  if (!before.present) {
57
- return { ...before, status: "absent", detail: "managed Yazi profile is absent; next open writes canonical names" };
57
+ return {
58
+ ...before,
59
+ status: "absent",
60
+ detail: "managed files pane profile is absent; next open writes canonical names",
61
+ };
58
62
  }
59
63
  if (before.legacyEvents === 0 && before.legacyEnvironmentNames === 0) {
60
- return { ...before, status: "canonical", detail: "managed Yazi profile already uses canonical names" };
64
+ return { ...before, status: "canonical", detail: "managed files pane profile already uses canonical names" };
61
65
  }
62
66
  const yaziPath = options.yaziPath === undefined ? resolveToolBinary("yazi").binaryPath : options.yaziPath;
63
67
  const yaPath = options.yaPath === undefined ? resolveToolBinary("ya").binaryPath : options.yaPath;
@@ -66,7 +70,8 @@ export function regenerateYaziNamingProfile(options: YaziNamingOptions = {}): Ya
66
70
  return {
67
71
  ...before,
68
72
  status: "removed-unresolved",
69
- detail: "legacy managed profile removed; Yazi/ya is unresolved, so the next managed open will regenerate it",
73
+ detail:
74
+ "legacy managed profile removed; the files pane engine is unresolved, so the next managed open will regenerate it",
70
75
  };
71
76
  }
72
77
  const profile = ensureYaziProfile({ yaziPath, yaPath, profileDir: before.profileDir });
@@ -74,8 +79,8 @@ export function regenerateYaziNamingProfile(options: YaziNamingOptions = {}): Ya
74
79
  return {
75
80
  ...before,
76
81
  status: "regeneration-failed",
77
- detail: "legacy managed profile removed, but current Yazi rejected the regenerated profile",
82
+ detail: "legacy managed profile removed, but the files pane engine rejected the regenerated profile",
78
83
  };
79
84
  }
80
- return { ...before, status: "regenerated", detail: "managed Yazi profile regenerated with canonical names" };
85
+ return { ...before, status: "regenerated", detail: "managed files pane profile regenerated with canonical names" };
81
86
  }
@@ -29,11 +29,16 @@ export interface TaskMemoryTrajectoryStep {
29
29
  resultDigestProvenance: ToolResultDigestProvenance;
30
30
  }
31
31
 
32
+ /** Admission changed while a client prepared; no inference request was sent. */
33
+ export class TaskMemoryEndpointBusyError extends Error {}
34
+
32
35
  export interface TaskMemoryModelRequest {
33
36
  systemPrompt: string;
34
37
  userPrompt: string;
35
38
  maxTokens: number;
36
39
  signal: AbortSignal;
40
+ /** Known usage may arrive even when completion rejects or the policy has been canceled. */
41
+ onUsage?: (usage: TaskMemoryStepUsage) => void;
37
42
  }
38
43
 
39
44
  /**
@@ -116,10 +121,8 @@ export type TaskMemoryPolicyReason =
116
121
  */
117
122
  | "timed_out"
118
123
  /**
119
- * The step would have run on the endpoint the chat target is streaming
120
- * against, so it never started. A single-slot local server queues the memory
121
- * call behind the operator's own turn, or evicts the resident model to serve
122
- * it; neither is a cost a background step may impose.
124
+ * Known occupancy exhausts the endpoint request capacity, so no step starts.
125
+ * A shared gateway URL alone does not establish a one-slot capacity bound.
123
126
  */
124
127
  | "endpoint_busy"
125
128
  /** The model client threw: unreachable route, auth failure, malformed request. */
@@ -139,7 +142,9 @@ export type TaskMemoryPolicyReason =
139
142
  /** Rules tier: the turn ended with no repeated failure worth reporting. */
140
143
  | "no_repeated_failure"
141
144
  /** Rules tier: compaction reactivation found no knowledge entries to restore. */
142
- | "bank_empty";
145
+ | "bank_empty"
146
+ /** The owning session/branch generation was invalidated. */
147
+ | "scope_changed";
143
148
 
144
149
  /**
145
150
  * The model's own words for one step, handed to an observer before they are
@@ -161,6 +166,12 @@ export interface TaskMemoryEnvelope {
161
166
  }
162
167
 
163
168
  export interface TaskMemoryPolicyInput {
169
+ /** Content authority, checked after inference and before any bank write. */
170
+ isCurrent?: () => boolean;
171
+ /** Cancellation releases policy bookkeeping even if the transport ignores abort. */
172
+ signal?: AbortSignal;
173
+ /** Reports actual provider usage, including responses arriving after cancellation/deadline. */
174
+ onStepUsage?: (usage: TaskMemoryStepUsage) => void;
164
175
  task: string;
165
176
  trajectory: ReadonlyArray<TaskMemoryTrajectoryStep>;
166
177
  deterministicTrigger: boolean;
@@ -246,10 +257,31 @@ export async function runTaskMemoryPolicy(
246
257
  const timeoutMs = positiveInteger(input.timeoutMs, TASK_MEMORY_POLICY_DEFAULT_TIMEOUT_MS);
247
258
  const timeoutMarker = Symbol("task-memory-timeout");
248
259
  let timer: NodeJS.Timeout | undefined;
260
+ const cancelledMarker = Symbol("task-memory-cancelled");
261
+ let cancel: () => void = () => {};
262
+ const cancelled = new Promise<typeof cancelledMarker>((resolve) => {
263
+ cancel = () => {
264
+ controller.abort();
265
+ resolve(cancelledMarker);
266
+ };
267
+ });
268
+ input.signal?.addEventListener("abort", cancel, { once: true });
269
+ if (input.signal?.aborted) cancel();
249
270
  let userPrompt = "";
250
271
  let rawResponse = "";
251
272
  let clientError: string | null = null;
252
273
  let stepUsage: TaskMemoryStepUsage | null = null;
274
+ let usageReported = false;
275
+ const reportUsage = (usage: TaskMemoryStepUsage): void => {
276
+ if (usageReported) return;
277
+ usageReported = true;
278
+ stepUsage = usage;
279
+ try {
280
+ input.onStepUsage?.(usage);
281
+ } catch {
282
+ /* Accounting cannot steer content. */
283
+ }
284
+ };
253
285
  // Every exit reports through here so the trace sees the same envelope the
254
286
  // telemetry row summarizes, including the paths that used to throw away both.
255
287
  const settle = (
@@ -263,54 +295,64 @@ export async function runTaskMemoryPolicy(
263
295
  bankOperations: parts.bankOperations ?? 0,
264
296
  droppedOperations: parts.droppedOperations ?? 0,
265
297
  reminder: parts.reminder ?? null,
266
- inputTokens: parts.inputTokens ?? 0,
267
- outputTokens: parts.outputTokens ?? 0,
298
+ inputTokens: parts.inputTokens ?? stepUsage?.input ?? 0,
299
+ outputTokens: parts.outputTokens ?? stepUsage?.output ?? 0,
268
300
  usage: stepUsage,
269
301
  };
270
302
  try {
271
- input.onEnvelope?.({
272
- systemPrompt: MEMORY_INTERVENTION_SYSTEM_PROMPT,
273
- userPrompt,
274
- response: rawResponse,
275
- decision,
276
- reason,
277
- bankOperations: result.bankOperations,
278
- droppedOperations: result.droppedOperations,
279
- reminder: result.reminder,
280
- error: clientError,
281
- });
303
+ if (input.isCurrent?.() !== false)
304
+ input.onEnvelope?.({
305
+ systemPrompt: MEMORY_INTERVENTION_SYSTEM_PROMPT,
306
+ userPrompt,
307
+ response: rawResponse,
308
+ decision,
309
+ reason,
310
+ bankOperations: result.bankOperations,
311
+ droppedOperations: result.droppedOperations,
312
+ reminder: result.reminder,
313
+ error: clientError,
314
+ });
282
315
  } catch {
283
316
  // A failing observer is an operator's diagnostic, never the policy's problem.
284
317
  }
285
318
  return result;
286
319
  };
287
320
  try {
321
+ if (input.signal?.aborted || input.isCurrent?.() === false) return settle("silent", "scope_changed");
288
322
  userPrompt = buildMemoryInterventionUserPrompt({
289
323
  task: input.task.slice(0, TASK_PROMPT_MAX_CHARS),
290
324
  bank: bank.render(input.maxTokens),
291
325
  trajectory: renderTrajectory(input.trajectory),
292
326
  });
293
- const completion = client.complete({
294
- systemPrompt: MEMORY_INTERVENTION_SYSTEM_PROMPT,
295
- userPrompt,
296
- maxTokens: positiveInteger(input.modelMaxTokens, input.maxTokens),
297
- signal: controller.signal,
298
- });
327
+ const completion = client
328
+ .complete({
329
+ systemPrompt: MEMORY_INTERVENTION_SYSTEM_PROMPT,
330
+ userPrompt,
331
+ maxTokens: positiveInteger(input.modelMaxTokens, input.maxTokens),
332
+ signal: controller.signal,
333
+ onUsage: reportUsage,
334
+ })
335
+ .then((response) => {
336
+ if (response.usage !== undefined) reportUsage(response.usage);
337
+ return response;
338
+ });
299
339
  const timeout = new Promise<typeof timeoutMarker>((resolve) => {
300
340
  timer = setTimeout(() => resolve(timeoutMarker), timeoutMs);
301
341
  });
302
- const response = await Promise.race([completion, timeout]);
342
+ const response = await Promise.race([completion, timeout, cancelled]);
343
+ if (response === cancelledMarker) return settle("silent", "scope_changed");
303
344
  if (response === timeoutMarker) {
304
345
  controller.abort();
305
346
  void completion.catch(() => undefined);
306
347
  return settle("timeout", "deadline");
307
348
  }
308
349
  rawResponse = typeof response.text === "string" ? response.text : "";
309
- stepUsage = response.usage ?? null;
350
+ stepUsage = response.usage ?? stepUsage;
310
351
  const usage = {
311
352
  inputTokens: nonNegativeInteger(response.inputTokens ?? stepUsage?.input),
312
353
  outputTokens: nonNegativeInteger(response.outputTokens ?? stepUsage?.output),
313
354
  };
355
+ if (input.signal?.aborted || input.isCurrent?.() === false) return settle("silent", "scope_changed", usage);
314
356
  const read = readPolicyStep(rawResponse);
315
357
  if (!read.ok) return settle("malformed", read.reason, { ...usage, droppedOperations: read.dropped });
316
358
  const operations = resolveOperations(bank, read.step.operations);
@@ -336,6 +378,7 @@ export async function runTaskMemoryPolicy(
336
378
  bank.recordInjection(citedIds);
337
379
  return settle("injected", "intervened", { ...counts, reminder });
338
380
  } catch (error) {
381
+ if (error instanceof TaskMemoryEndpointBusyError) return settle("silent", "endpoint_busy");
339
382
  clientError = errorMessage(error);
340
383
  // A transport that aborted at its own deadline spent the whole budget and
341
384
  // produced nothing. Reporting it as silence made a step that held a local
@@ -345,6 +388,7 @@ export async function runTaskMemoryPolicy(
345
388
  return settle("silent", "client_error");
346
389
  } finally {
347
390
  if (timer !== undefined) clearTimeout(timer);
391
+ input.signal?.removeEventListener("abort", cancel);
348
392
  }
349
393
  }
350
394
 
@@ -229,6 +229,7 @@ const REASONS = new Set<TaskMemoryPolicyReason>([
229
229
  "llm_timeout_backoff",
230
230
  "no_repeated_failure",
231
231
  "bank_empty",
232
+ "scope_changed",
232
233
  ]);
233
234
 
234
235
  function entryDelta(
@@ -1,3 +1,8 @@
1
+ import type {
2
+ MiddlewareRegistrationOwner,
3
+ PrepareRegistrationReplacementResult,
4
+ ReplaceRegistrationsReport,
5
+ } from "./registrations.js";
1
6
  import type { MiddlewareDiagnosticSink, MiddlewareHookRegistration } from "./runtime.js";
2
7
  import type {
3
8
  MiddlewareEffect,
@@ -32,4 +37,25 @@ export interface MiddlewareContract {
32
37
  * stderr writer default.
33
38
  */
34
39
  setDiagnosticSink(sink: MiddlewareDiagnosticSink): void;
40
+ /**
41
+ * Validate an owner's replacement registration set against the current
42
+ * builtin and host ids and build its evaluation list without publishing.
43
+ * Rejected when `generation` is not strictly greater than the owner's
44
+ * active generation. The returned replacement publishes with one reference
45
+ * assignment that cannot refuse or call out, so a composition root can publish it
46
+ * back-to-back with another domain's generation on the same stack.
47
+ */
48
+ prepareRegistrationReplacement(
49
+ owner: MiddlewareRegistrationOwner,
50
+ generation: number,
51
+ registrations: ReadonlyArray<MiddlewareHookRegistration>,
52
+ ): PrepareRegistrationReplacementResult;
53
+ /** Prepare, check currentness, publish, then emit any conflict diagnostics. */
54
+ replaceRegistrations(
55
+ owner: MiddlewareRegistrationOwner,
56
+ generation: number,
57
+ registrations: ReadonlyArray<MiddlewareHookRegistration>,
58
+ ): ReplaceRegistrationsReport;
59
+ /** Active generation for an owner; 0 when nothing was ever applied. */
60
+ ownedGeneration(owner: MiddlewareRegistrationOwner): number;
35
61
  }
@@ -6,6 +6,7 @@ import {
6
6
  resolveHookBudgetTunablesFromEnv,
7
7
  } from "./budget.js";
8
8
  import type { MiddlewareContract } from "./contract.js";
9
+ import { createMiddlewareRegistrationTable } from "./registrations.js";
9
10
  import { cloneMiddlewareRule, listMiddlewareRuleDefinitions } from "./rules.js";
10
11
  import {
11
12
  type MiddlewareDiagnosticSink,
@@ -14,6 +15,7 @@ import {
14
15
  registrationFromRuleDefinition,
15
16
  runMiddlewareAsyncRegistrations,
16
17
  runMiddlewareRegistrations,
18
+ writeMiddlewareDiagnosticToStderr,
17
19
  } from "./runtime.js";
18
20
  import { createMiddlewareSnapshot } from "./snapshot.js";
19
21
 
@@ -54,18 +56,28 @@ export interface MiddlewareBundleOptions {
54
56
 
55
57
  export function createMiddlewareBundle(options: MiddlewareBundleOptions = {}): DomainBundle<MiddlewareContract> {
56
58
  const ruleDefinitions = combineRuleDefinitions(listMiddlewareRuleDefinitions(), options.ruleDefinitions ?? []);
57
- const registrations = combineRegistrations(ruleDefinitions, options.registrations ?? []);
58
- const registeredIds = new Set(registrations.map((registration) => registration.id));
59
59
  let diagnosticSink = options.onDiagnostic;
60
+ // Declarative rules are the fixed tier; construction-time coded
61
+ // registrations are the first host entries, deduplicated first-wins across
62
+ // the shared id namespace exactly as before.
63
+ const table = createMiddlewareRegistrationTable({
64
+ fixed: ruleDefinitions.map(registrationFromRuleDefinition),
65
+ diagnosticSink: () => diagnosticSink ?? writeMiddlewareDiagnosticToStderr,
66
+ });
67
+ for (const registration of options.registrations ?? []) table.registerHook(registration);
60
68
  const budgetTracker = options.budgetTracker ?? createEnvHookBudgetTracker();
61
69
  const contract: MiddlewareContract = {
62
70
  runHook(input) {
71
+ // Capture the list once; a replacement published mid-evaluation
72
+ // takes effect for the next evaluation, never this one.
73
+ const registrations = table.list();
63
74
  return runMiddlewareRegistrations(input, registrations, {
64
75
  budgetTracker,
65
76
  ...(diagnosticSink !== undefined ? { onDiagnostic: diagnosticSink } : {}),
66
77
  });
67
78
  },
68
79
  runAsyncHook(input, priorEffects = []) {
80
+ const registrations = table.list();
69
81
  return runMiddlewareAsyncRegistrations(input, registrations, priorEffects, {
70
82
  ...(diagnosticSink !== undefined ? { onDiagnostic: diagnosticSink } : {}),
71
83
  });
@@ -77,13 +89,20 @@ export function createMiddlewareBundle(options: MiddlewareBundleOptions = {}): D
77
89
  return createMiddlewareSnapshot(ruleDefinitions.map((definition) => definition.rule));
78
90
  },
79
91
  registerHook(registration) {
80
- if (registeredIds.has(registration.id)) return;
81
- registeredIds.add(registration.id);
82
- registrations.push(registration);
92
+ table.registerHook(registration);
83
93
  },
84
94
  setDiagnosticSink(sink) {
85
95
  diagnosticSink = sink;
86
96
  },
97
+ prepareRegistrationReplacement(owner, generation, registrations) {
98
+ return table.prepareReplacement(owner, generation, registrations);
99
+ },
100
+ replaceRegistrations(owner, generation, registrations) {
101
+ return table.replaceRegistrations(owner, generation, registrations);
102
+ },
103
+ ownedGeneration(owner) {
104
+ return table.ownedGeneration(owner);
105
+ },
87
106
  };
88
107
  return {
89
108
  extension: {
@@ -108,22 +127,3 @@ function combineRuleDefinitions(
108
127
  }
109
128
  return combined;
110
129
  }
111
-
112
- /**
113
- * One ordered evaluation list: declarative rules first (builtin, then
114
- * composition-root), then coded registrations, deduplicated across the shared
115
- * id namespace with the earlier entry winning.
116
- */
117
- function combineRegistrations(
118
- ruleDefinitions: ReadonlyArray<MiddlewareRuleDefinition>,
119
- coded: ReadonlyArray<MiddlewareHookRegistration>,
120
- ): MiddlewareHookRegistration[] {
121
- const seen = new Set<string>(ruleDefinitions.map((definition) => definition.rule.id));
122
- const combined: MiddlewareHookRegistration[] = ruleDefinitions.map(registrationFromRuleDefinition);
123
- for (const registration of coded) {
124
- if (seen.has(registration.id)) continue;
125
- seen.add(registration.id);
126
- combined.push(registration);
127
- }
128
- return combined;
129
- }