@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
@@ -0,0 +1,189 @@
1
+ import { createHash } from "node:crypto";
2
+ import {
3
+ closeSync,
4
+ constants,
5
+ fstatSync,
6
+ lstatSync,
7
+ openSync,
8
+ readdirSync,
9
+ readFileSync,
10
+ readlinkSync,
11
+ realpathSync,
12
+ type Stats,
13
+ } from "node:fs";
14
+ import path from "node:path";
15
+
16
+ export interface ExtensionContentDigestOptions {
17
+ /** Root-relative regular files whose exact hashed bytes should be returned. */
18
+ capture?: ReadonlyArray<string>;
19
+ }
20
+
21
+ export interface ExtensionContentDigestResult {
22
+ digest: string;
23
+ captured: ReadonlyMap<string, Buffer>;
24
+ }
25
+
26
+ function contained(root: string, candidate: string): boolean {
27
+ const relative = path.relative(root, candidate);
28
+ return relative === "" || (!relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative));
29
+ }
30
+
31
+ function digestFrame(hash: ReturnType<typeof createHash>, kind: string, relativePath: string, payload?: Buffer): void {
32
+ const header = Buffer.from(
33
+ `${kind}\0${relativePath.replaceAll(path.sep, "/")}\0${payload?.byteLength ?? 0}\0`,
34
+ "utf8",
35
+ );
36
+ hash.update(header);
37
+ if (payload) hash.update(payload);
38
+ hash.update("\0");
39
+ }
40
+
41
+ function sameFileState(left: Stats, right: Stats): boolean {
42
+ return (
43
+ left.dev === right.dev &&
44
+ left.ino === right.ino &&
45
+ left.mode === right.mode &&
46
+ left.nlink === right.nlink &&
47
+ left.size === right.size &&
48
+ left.mtimeMs === right.mtimeMs &&
49
+ left.ctimeMs === right.ctimeMs
50
+ );
51
+ }
52
+
53
+ function readStableRegularFile(filePath: string, inspected: Stats): Buffer {
54
+ const fd = openSync(filePath, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
55
+ try {
56
+ const opened = fstatSync(fd);
57
+ if (!opened.isFile() || opened.nlink !== 1 || !sameFileState(inspected, opened)) {
58
+ throw new Error(`extension file changed while being opened: ${filePath}`);
59
+ }
60
+ const payload = readFileSync(fd);
61
+ if (!sameFileState(opened, fstatSync(fd))) {
62
+ throw new Error(`extension file changed while being hashed: ${filePath}`);
63
+ }
64
+ return payload;
65
+ } finally {
66
+ closeSync(fd);
67
+ }
68
+ }
69
+
70
+ function readStableContainedLink(linkPath: string, inspected: Stats, canonicalRoot: string): Buffer {
71
+ const canonicalTarget = realpathSync(linkPath);
72
+ if (!contained(canonicalRoot, canonicalTarget)) {
73
+ throw new Error(`symbolic link escapes the extension root: ${linkPath}`);
74
+ }
75
+ const target = readlinkSync(linkPath);
76
+ const after = lstatSync(linkPath);
77
+ if (!after.isSymbolicLink() || !sameFileState(inspected, after)) {
78
+ throw new Error(`symbolic link changed while being hashed: ${linkPath}`);
79
+ }
80
+ const canonicalAfter = realpathSync(linkPath);
81
+ if (canonicalAfter !== canonicalTarget || !contained(canonicalRoot, canonicalAfter)) {
82
+ throw new Error(`symbolic link changed or escapes the extension root: ${linkPath}`);
83
+ }
84
+ return Buffer.from(target, "utf8");
85
+ }
86
+
87
+ function assertStableDirectory(
88
+ directoryPath: string,
89
+ inspected: Stats,
90
+ canonicalDirectory: string,
91
+ canonicalRoot: string,
92
+ expectedEntries?: readonly string[],
93
+ ): void {
94
+ const after = lstatSync(directoryPath);
95
+ if (!after.isDirectory() || !sameFileState(inspected, after)) {
96
+ throw new Error(`extension directory changed while being hashed: ${directoryPath}`);
97
+ }
98
+ const canonicalAfter = realpathSync(directoryPath);
99
+ if (canonicalAfter !== canonicalDirectory || !contained(canonicalRoot, canonicalAfter)) {
100
+ throw new Error(`extension directory changed or escapes the extension root: ${directoryPath}`);
101
+ }
102
+ if (expectedEntries !== undefined) {
103
+ const currentEntries = readdirSync(directoryPath).sort();
104
+ if (
105
+ currentEntries.length !== expectedEntries.length ||
106
+ currentEntries.some((entry, index) => entry !== expectedEntries[index])
107
+ ) {
108
+ throw new Error(`extension directory entries changed while being hashed: ${directoryPath}`);
109
+ }
110
+ }
111
+ }
112
+
113
+ function readStableDirectory(
114
+ directoryPath: string,
115
+ inspected: Stats,
116
+ canonicalRoot: string,
117
+ ): { canonicalDirectory: string; entries: string[] } {
118
+ const canonicalDirectory = realpathSync(directoryPath);
119
+ if (!contained(canonicalRoot, canonicalDirectory)) {
120
+ throw new Error(`extension directory escapes the extension root: ${directoryPath}`);
121
+ }
122
+ const entries = readdirSync(directoryPath).sort();
123
+ assertStableDirectory(directoryPath, inspected, canonicalDirectory, canonicalRoot);
124
+ return { canonicalDirectory, entries };
125
+ }
126
+
127
+ /**
128
+ * Hash an extension tree in stable relative-path order. File names, node kinds,
129
+ * symlink targets, empty directories, and file bytes are all integrity-bound.
130
+ * Symlinks must resolve within the package so their content cannot drift outside
131
+ * the tree without changing the digest.
132
+ */
133
+ export function extensionContentDigestWithCapture(
134
+ root: string,
135
+ options: ExtensionContentDigestOptions = {},
136
+ ): ExtensionContentDigestResult {
137
+ const resolvedRoot = path.resolve(root);
138
+ const rootStat = lstatSync(resolvedRoot);
139
+ if (rootStat.isSymbolicLink()) {
140
+ throw new Error(`extension root must be a directory, not a symbolic link: ${resolvedRoot}`);
141
+ }
142
+ if (!rootStat.isDirectory()) {
143
+ throw new Error(`extension root must be a directory: ${resolvedRoot}`);
144
+ }
145
+ const canonicalRoot = realpathSync(resolvedRoot);
146
+ const canonicalizedRootStat = lstatSync(resolvedRoot);
147
+ if (!canonicalizedRootStat.isDirectory() || !sameFileState(rootStat, canonicalizedRootStat)) {
148
+ throw new Error(`extension root changed while being canonicalized: ${resolvedRoot}`);
149
+ }
150
+ const hash = createHash("sha256");
151
+ const requested = new Set((options.capture ?? []).map((entry) => entry.replaceAll(path.sep, "/")));
152
+ const captured = new Map<string, Buffer>();
153
+ const visit = (absolutePath: string, relativePath: string): void => {
154
+ const stat = lstatSync(absolutePath);
155
+ if (stat.isSymbolicLink()) {
156
+ if (relativePath === "") {
157
+ throw new Error(`extension root changed to a symbolic link while being hashed: ${absolutePath}`);
158
+ }
159
+ digestFrame(hash, "link", relativePath, readStableContainedLink(absolutePath, stat, canonicalRoot));
160
+ return;
161
+ }
162
+ if (stat.isDirectory()) {
163
+ digestFrame(hash, "directory", relativePath);
164
+ const { canonicalDirectory, entries } = readStableDirectory(absolutePath, stat, canonicalRoot);
165
+ for (const entry of entries) {
166
+ visit(path.join(absolutePath, entry), relativePath ? path.join(relativePath, entry) : entry);
167
+ }
168
+ assertStableDirectory(absolutePath, stat, canonicalDirectory, canonicalRoot, entries);
169
+ return;
170
+ }
171
+ if (stat.isFile()) {
172
+ if (stat.nlink !== 1) {
173
+ throw new Error(`hard-linked file is unsupported in an extension: ${absolutePath}`);
174
+ }
175
+ const payload = readStableRegularFile(absolutePath, stat);
176
+ digestFrame(hash, "file", relativePath, payload);
177
+ const key = relativePath.replaceAll(path.sep, "/");
178
+ if (requested.has(key)) captured.set(key, payload);
179
+ return;
180
+ }
181
+ throw new Error(`unsupported filesystem entry in extension: ${absolutePath}`);
182
+ };
183
+ visit(resolvedRoot, "");
184
+ return { digest: hash.digest("hex"), captured };
185
+ }
186
+
187
+ export function extensionContentDigest(root: string): string {
188
+ return extensionContentDigestWithCapture(root).digest;
189
+ }
@@ -4,27 +4,43 @@ export {
4
4
  findExtensionManifestPath,
5
5
  parseExtensionManifest,
6
6
  } from "./discovery.js";
7
- export { enabledExtensionResourceRoots, extensionResourcePath } from "./resources.js";
7
+ export { enabledExtensionResourceRoots, extensionResourcePath, extensionSnapshotFor } from "./resources.js";
8
+ export type { InstalledExtensionRecord } from "./state.js";
8
9
  export {
9
10
  disableExtension,
10
11
  enableExtension,
11
12
  extensionBaseDir,
12
13
  installExtension,
14
+ listInstalledExtensionRecords,
13
15
  listInstalledExtensions,
14
16
  removeExtension,
17
+ upgradeLegacyExtensionInstallState,
15
18
  } from "./state.js";
16
19
  export type {
17
20
  ClioExtensionManifest,
18
21
  ExtensionCandidate,
19
22
  ExtensionDiagnostic,
23
+ ExtensionHookSource,
20
24
  ExtensionInstallOptions,
21
25
  ExtensionInstallResult,
22
26
  ExtensionListOptions,
23
27
  ExtensionManifestResources,
24
28
  ExtensionMutationResult,
29
+ ExtensionProvenance,
30
+ ExtensionReloadCandidate,
31
+ ExtensionReloadCommitted,
32
+ ExtensionReloadPrepareResult,
33
+ ExtensionReloadRejection,
34
+ ExtensionReloadRejectionReason,
35
+ ExtensionReloadResult,
25
36
  ExtensionResourceKind,
26
37
  ExtensionResourceRoot,
27
38
  ExtensionScope,
39
+ ExtensionSnapshot,
40
+ ExtensionSnapshotDiagnostics,
28
41
  ExtensionState,
42
+ ExtensionStateUpgradeReport,
29
43
  InstalledExtension,
44
+ LoadableExtension,
30
45
  } from "./types.js";
46
+ export { isLoadableExtension } from "./types.js";
@@ -0,0 +1,27 @@
1
+ import { realpathSync, statSync } from "node:fs";
2
+ import path from "node:path";
3
+
4
+ export function extensionResourcePath(rootPath: string, resourcePath: string): string | null {
5
+ const root = path.resolve(rootPath);
6
+ const full = path.resolve(root, resourcePath);
7
+ const relative = path.relative(root, full);
8
+ if (relative === "" || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
9
+ return null;
10
+ }
11
+ try {
12
+ const rootReal = realpathSync(root);
13
+ const fullReal = realpathSync(full);
14
+ const canonicalRelative = path.relative(rootReal, fullReal);
15
+ if (
16
+ canonicalRelative === ".." ||
17
+ canonicalRelative.startsWith(`..${path.sep}`) ||
18
+ path.isAbsolute(canonicalRelative)
19
+ ) {
20
+ return null;
21
+ }
22
+ if (!statSync(fullReal).isDirectory()) return null;
23
+ return fullReal;
24
+ } catch {
25
+ return null;
26
+ }
27
+ }
@@ -1,50 +1,30 @@
1
- import { lstatSync, realpathSync } from "node:fs";
1
+ import { realpathSync } from "node:fs";
2
2
  import path from "node:path";
3
- import { listInstalledExtensions } from "./state.js";
4
- import type { ExtensionResourceKind, ExtensionResourceRoot } from "./types.js";
3
+ import { buildExtensionSnapshot } from "./snapshot.js";
4
+ import { committedExtensionSnapshot } from "./snapshot-store.js";
5
+ import type { ExtensionResourceKind, ExtensionResourceRoot, ExtensionSnapshot } from "./types.js";
5
6
 
6
- export function extensionResourcePath(rootPath: string, resourcePath: string): string | null {
7
- const root = path.resolve(rootPath);
8
- const full = path.resolve(root, resourcePath);
9
- const relative = path.relative(root, full);
10
- if (relative === "" || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative))
11
- return null;
7
+ export { extensionResourcePath } from "./resource-path.js";
8
+
9
+ /**
10
+ * The committed snapshot when a store is bound for this cwd; otherwise an
11
+ * ephemeral generation-0 build that never touches the store. The ephemeral
12
+ * branch serves the CLI, `config inspect` with an explicit cwd, and any
13
+ * process that never booted the extensions bundle.
14
+ */
15
+ export function extensionSnapshotFor(cwd = process.cwd()): ExtensionSnapshot {
16
+ const committed = committedExtensionSnapshot();
12
17
  try {
13
- const rootReal = realpathSync(root);
14
- const fullReal = realpathSync(full);
15
- const canonicalRelative = path.relative(rootReal, fullReal);
16
- if (
17
- canonicalRelative === ".." ||
18
- canonicalRelative.startsWith(`..${path.sep}`) ||
19
- path.isAbsolute(canonicalRelative)
20
- ) {
21
- return null;
22
- }
23
- if (!lstatSync(full).isDirectory()) return null;
24
- return full;
18
+ if (committed !== null && committed.cwd === realpathSync(path.resolve(cwd))) return committed;
25
19
  } catch {
26
- return null;
20
+ // Fall through to an ephemeral build, which retains the original error semantics.
27
21
  }
22
+ return buildExtensionSnapshot({ cwd, generation: 0 });
28
23
  }
29
24
 
30
25
  export function enabledExtensionResourceRoots(
31
26
  kind: ExtensionResourceKind,
32
27
  cwd = process.cwd(),
33
28
  ): ExtensionResourceRoot[] {
34
- const roots: ExtensionResourceRoot[] = [];
35
- for (const entry of listInstalledExtensions(cwd)) {
36
- if (!entry.enabled || !entry.compatible || !entry.effective) continue;
37
- const rel = entry.resources[kind];
38
- if (!rel) continue;
39
- const full = extensionResourcePath(entry.rootPath, rel);
40
- if (!full) continue;
41
- roots.push({
42
- id: entry.id,
43
- scope: entry.scope,
44
- path: full,
45
- rootPath: entry.rootPath,
46
- source: `extension:${entry.scope}:${entry.id}`,
47
- });
48
- }
49
- return roots;
29
+ return [...extensionSnapshotFor(cwd).resourceRoots[kind]];
50
30
  }
@@ -0,0 +1,39 @@
1
+ import type { ExtensionSnapshot } from "./types.js";
2
+
3
+ /**
4
+ * Holder for the committed snapshot reference plus the process-local
5
+ * generation counter. `publish` is assignment-only: validation that a
6
+ * snapshot is strictly newer belongs to the candidate that prepared it, on
7
+ * the same stack, immediately before publishing.
8
+ */
9
+ export interface ExtensionSnapshotStore {
10
+ current(): ExtensionSnapshot | null;
11
+ publish(snapshot: ExtensionSnapshot): void;
12
+ /** Reserve and return the next process-local generation. Reservations are never reused. */
13
+ nextGeneration(): number;
14
+ }
15
+
16
+ export function createExtensionSnapshotStore(): ExtensionSnapshotStore {
17
+ let committed: ExtensionSnapshot | null = null;
18
+ let reservedGeneration = 0;
19
+ return {
20
+ current: () => committed,
21
+ publish(snapshot) {
22
+ committed = snapshot;
23
+ },
24
+ nextGeneration() {
25
+ reservedGeneration += 1;
26
+ return reservedGeneration;
27
+ },
28
+ };
29
+ }
30
+
31
+ let boundStore: ExtensionSnapshotStore | null = null;
32
+
33
+ export function committedExtensionSnapshot(): ExtensionSnapshot | null {
34
+ return boundStore?.current() ?? null;
35
+ }
36
+
37
+ export function bindExtensionSnapshotStore(store: ExtensionSnapshotStore | null): void {
38
+ boundStore = store;
39
+ }
@@ -0,0 +1,180 @@
1
+ import { createHash } from "node:crypto";
2
+ import { realpathSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { parse as parseYaml } from "yaml";
5
+ import { extensionResourcePath } from "./resource-path.js";
6
+ import { type InstalledExtensionRecord, listInstalledExtensionRecords } from "./state.js";
7
+ import {
8
+ type ExtensionDiagnostic,
9
+ type ExtensionHookSource,
10
+ type ExtensionResourceKind,
11
+ type ExtensionResourceRoot,
12
+ type ExtensionSnapshot,
13
+ type ExtensionSnapshotDiagnostics,
14
+ isLoadableExtension,
15
+ } from "./types.js";
16
+
17
+ export const EXTENSION_SNAPSHOT_DIAGNOSTIC_CAP = 200;
18
+ export const EXTENSION_SNAPSHOT_DIAGNOSTIC_PER_PACKAGE_CAP = 20;
19
+ export const EXTENSION_SNAPSHOT_DIAGNOSTIC_MESSAGE_CAP = 512;
20
+
21
+ const RESOURCE_KINDS: ReadonlyArray<ExtensionResourceKind> = ["skills", "prompts", "agents", "fleets", "themes"];
22
+
23
+ export interface BuildExtensionSnapshotInput {
24
+ cwd: string;
25
+ generation: number;
26
+ now?: () => Date;
27
+ listRecords?: (cwd?: string, options?: { all?: boolean }) => InstalledExtensionRecord[];
28
+ }
29
+
30
+ function canonicalJson(value: unknown): string {
31
+ if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
32
+ if (value !== null && typeof value === "object") {
33
+ const record = value as Record<string, unknown>;
34
+ return `{${Object.keys(record)
35
+ .sort()
36
+ .map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`)
37
+ .join(",")}}`;
38
+ }
39
+ return JSON.stringify(value) ?? "null";
40
+ }
41
+
42
+ function deepFreeze<T>(value: T, seen = new Set<object>()): T {
43
+ if (value === null || typeof value !== "object" || seen.has(value as object)) return value;
44
+ seen.add(value as object);
45
+ for (const child of Object.values(value as Record<string, unknown>)) deepFreeze(child, seen);
46
+ return Object.freeze(value);
47
+ }
48
+
49
+ function boundedDiagnostics(records: ReadonlyArray<InstalledExtensionRecord>): ExtensionSnapshotDiagnostics {
50
+ const entries: Array<ExtensionDiagnostic & { extensionId?: string }> = [];
51
+ let truncated = 0;
52
+ for (const { entry } of records) {
53
+ let admittedForPackage = 0;
54
+ for (const diagnostic of entry.diagnostics) {
55
+ if (
56
+ admittedForPackage >= EXTENSION_SNAPSHOT_DIAGNOSTIC_PER_PACKAGE_CAP ||
57
+ entries.length >= EXTENSION_SNAPSHOT_DIAGNOSTIC_CAP
58
+ ) {
59
+ truncated += 1;
60
+ continue;
61
+ }
62
+ entries.push({
63
+ type: diagnostic.type,
64
+ message: diagnostic.message.slice(0, EXTENSION_SNAPSHOT_DIAGNOSTIC_MESSAGE_CAP),
65
+ ...(diagnostic.path ? { path: diagnostic.path } : {}),
66
+ extensionId: entry.id,
67
+ });
68
+ admittedForPackage += 1;
69
+ }
70
+ }
71
+ return { entries, truncated };
72
+ }
73
+
74
+ export function buildExtensionSnapshot(input: BuildExtensionSnapshotInput): ExtensionSnapshot {
75
+ const cwd = realpathSync(path.resolve(input.cwd));
76
+ const records = (input.listRecords ?? listInstalledExtensionRecords)(cwd, { all: true });
77
+ const resourceRoots: Record<ExtensionResourceKind, ExtensionResourceRoot[]> = {
78
+ skills: [],
79
+ prompts: [],
80
+ agents: [],
81
+ fleets: [],
82
+ themes: [],
83
+ };
84
+ const hookSources: ExtensionHookSource[] = [];
85
+ const digestPackages: unknown[] = [];
86
+
87
+ for (const record of records) {
88
+ const { entry } = record;
89
+ const packageRoots: Array<{ kind: ExtensionResourceKind; path: string }> = [];
90
+ let hooksDigest: string | undefined;
91
+ if (isLoadableExtension(entry)) {
92
+ for (const kind of RESOURCE_KINDS) {
93
+ const relative = entry.resources[kind];
94
+ if (!relative) continue;
95
+ const resolved = extensionResourcePath(entry.rootPath, relative);
96
+ if (!resolved) continue;
97
+ resourceRoots[kind].push({
98
+ id: entry.id,
99
+ scope: entry.scope,
100
+ path: resolved,
101
+ rootPath: entry.rootPath,
102
+ source: `extension:${entry.scope}:${entry.id}`,
103
+ provenance: entry.provenance,
104
+ generation: input.generation,
105
+ });
106
+ packageRoots.push({ kind, path: resolved });
107
+ }
108
+ const hookBytes = record.captured?.get("hooks.yaml");
109
+ if (hookBytes !== undefined) {
110
+ hooksDigest = createHash("sha256").update(hookBytes).digest("hex");
111
+ let declarations: unknown = [];
112
+ let parseError: string | undefined;
113
+ try {
114
+ declarations = parseYaml(hookBytes.toString("utf8")) ?? [];
115
+ } catch (error) {
116
+ parseError = error instanceof Error ? error.message : String(error);
117
+ }
118
+ hookSources.push({
119
+ provenance: entry.provenance,
120
+ declarationsDigest: hooksDigest,
121
+ declarations,
122
+ ...(parseError ? { parseError } : {}),
123
+ });
124
+ }
125
+ }
126
+ digestPackages.push({
127
+ id: entry.id,
128
+ scope: entry.scope,
129
+ loadable: entry.loadable,
130
+ ...(entry.provenance ? { provenance: entry.provenance } : {}),
131
+ resourceRoots: packageRoots,
132
+ ...(hooksDigest ? { hooksDigest } : {}),
133
+ });
134
+ }
135
+
136
+ const snapshot: ExtensionSnapshot = {
137
+ version: 1,
138
+ generation: input.generation,
139
+ cwd,
140
+ builtAt: (input.now ?? (() => new Date()))().toISOString(),
141
+ digest: createHash("sha256").update(canonicalJson(digestPackages)).digest("hex"),
142
+ packages: records.map((record) => record.entry),
143
+ resourceRoots,
144
+ hookSources,
145
+ diagnostics: boundedDiagnostics(records),
146
+ };
147
+ return deepFreeze(snapshot);
148
+ }
149
+
150
+ function packageFingerprints(snapshot: ExtensionSnapshot): Map<string, string> {
151
+ const grouped = new Map<string, unknown[]>();
152
+ for (const entry of snapshot.packages) {
153
+ const list = grouped.get(entry.id) ?? [];
154
+ list.push({
155
+ scope: entry.scope,
156
+ loadable: entry.loadable,
157
+ provenance: entry.provenance ?? null,
158
+ resources: entry.resources,
159
+ });
160
+ grouped.set(entry.id, list);
161
+ }
162
+ return new Map(
163
+ [...grouped].map(([id, values]) => [id, createHash("sha256").update(canonicalJson(values)).digest("hex")]),
164
+ );
165
+ }
166
+
167
+ export function diffExtensionSnapshots(
168
+ previous: ExtensionSnapshot | null,
169
+ next: ExtensionSnapshot,
170
+ ): { changed: boolean; added: string[]; removed: string[]; modified: string[] } {
171
+ if (previous === null) {
172
+ return { changed: true, added: [...new Set(next.packages.map((entry) => entry.id))], removed: [], modified: [] };
173
+ }
174
+ const before = packageFingerprints(previous);
175
+ const after = packageFingerprints(next);
176
+ const added = [...after.keys()].filter((id) => !before.has(id));
177
+ const removed = [...before.keys()].filter((id) => !after.has(id));
178
+ const modified = [...after.keys()].filter((id) => before.has(id) && before.get(id) !== after.get(id));
179
+ return { changed: previous.digest !== next.digest, added, removed, modified };
180
+ }