@iowarp/clio-coder 0.4.6 → 0.4.7

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 (657) hide show
  1. package/.claude-plugin/marketplace.json +283 -0
  2. package/CHANGELOG.md +50 -0
  3. package/CONTRIBUTING.md +102 -29
  4. package/NOTICE +8 -0
  5. package/README.md +37 -5
  6. package/dist/{acp-UVEVWSDL.js → acp-W3Y3TRHD.js} +12 -12
  7. package/dist/{agents-VWY37DTK.js → agents-J4ICNLQ3.js} +52 -52
  8. package/dist/assets/codewiki.json +1 -1
  9. package/dist/assets/tui-notices/get-east-asian-width-LICENSE +9 -0
  10. package/dist/assets/tui-notices/marked-LICENSE +44 -0
  11. package/dist/assets/tui-notices/pi-tui-LICENSE +21 -0
  12. package/dist/{auth-PCV2XQDV.js → auth-X2UJUMOC.js} +24 -24
  13. package/dist/{builtins-PD652MTK.js → builtins-XLXWWSRF.js} +6 -6
  14. package/dist/{chunk-DZK63TZJ.js → chunk-24S3DN22.js} +336 -612
  15. package/dist/{chunk-NTK3WTHM.js → chunk-24TOGHPO.js} +2 -2
  16. package/dist/{chunk-M6TAYK66.js → chunk-2O2LVQQK.js} +11 -4
  17. package/dist/{chunk-OQM5IVJY.js → chunk-34XHRVKG.js} +3 -3
  18. package/dist/{chunk-LY4N4TTL.js → chunk-3LXJOICS.js} +2 -2
  19. package/dist/{chunk-3BJGMT2D.js → chunk-3XE4NRLF.js} +1 -1
  20. package/dist/{chunk-N2OKBREN.js → chunk-4MFBBY2Z.js} +3 -3
  21. package/dist/{chunk-5VTJP36Q.js → chunk-4N2RZ4TO.js} +2 -2
  22. package/dist/{chunk-WNGF5AJX.js → chunk-4QKAITQT.js} +3 -3
  23. package/dist/chunk-4UHVS5T7.js +207 -0
  24. package/dist/{chunk-GLYBJ4RQ.js → chunk-5AJPUR72.js} +6 -6
  25. package/dist/{chunk-5CY4Q6QI.js → chunk-5EQO5NWP.js} +105 -3
  26. package/dist/{chunk-6HAO6X5B.js → chunk-65BGHOUR.js} +8 -5
  27. package/dist/{chunk-6VRRJT7L.js → chunk-6CA2BHOR.js} +2 -2
  28. package/dist/{chunk-HL26ADLH.js → chunk-6CB2IL4N.js} +2 -1
  29. package/dist/{chunk-E7RF4KBO.js → chunk-6LRLOJHQ.js} +3 -3
  30. package/dist/{chunk-HXHFDHB6.js → chunk-6TAATXXH.js} +6 -6
  31. package/dist/{chunk-P6M7RKMI.js → chunk-6YHPAAZR.js} +3 -3
  32. package/dist/{chunk-5QRX7SLS.js → chunk-7EEGBKV4.js} +7 -7
  33. package/dist/{chunk-BS4GAMUB.js → chunk-A67NR5AT.js} +2 -2
  34. package/dist/{chunk-WJIMKGD6.js → chunk-BAU36233.js} +8 -8
  35. package/dist/{chunk-PZN2LQY6.js → chunk-BO4XV5VX.js} +4 -4
  36. package/dist/{chunk-I2K2NCZQ.js → chunk-BQQ5MXUC.js} +6 -6
  37. package/dist/{chunk-X3BI7HTV.js → chunk-C3G5PNUO.js} +21 -21
  38. package/dist/{chunk-SRZOW5L2.js → chunk-C6GEXX4L.js} +1 -1
  39. package/dist/{chunk-6RYDAVQT.js → chunk-CE64C5K5.js} +219 -64
  40. package/dist/chunk-CP3HIR5H.js +2119 -0
  41. package/dist/{chunk-BBV5TKE6.js → chunk-CPXGJI2A.js} +2 -2
  42. package/dist/{chunk-IGLVVNEG.js → chunk-CULVKYTK.js} +4 -4
  43. package/dist/{chunk-DXLUVUD4.js → chunk-D2T66PDV.js} +5 -5
  44. package/dist/{chunk-NF3BK5WR.js → chunk-DACXIVVF.js} +5 -5
  45. package/dist/{chunk-IKRWLEDA.js → chunk-DLIYANB7.js} +20 -15
  46. package/dist/{chunk-RGZNQ5CT.js → chunk-DO7M3LSX.js} +9 -9
  47. package/dist/{chunk-2QPI3TR3.js → chunk-DVJL77SO.js} +2 -2
  48. package/dist/{chunk-ODUTYZIU.js → chunk-EUEXGXXR.js} +5 -5
  49. package/dist/{chunk-WKUYQBCG.js → chunk-EUZRMP4Y.js} +18 -16
  50. package/dist/{chunk-JMPL7NUB.js → chunk-G4LGUTOE.js} +4 -4
  51. package/dist/{chunk-CBSKDFWL.js → chunk-GEVQNST4.js} +2 -2
  52. package/dist/{chunk-NNWJYUNO.js → chunk-GFQ7P2UF.js} +7 -7
  53. package/dist/{chunk-SXQKNKRA.js → chunk-GI5RRMAH.js} +14 -14
  54. package/dist/{chunk-HPTJF6DG.js → chunk-GVZFCJHE.js} +336 -83
  55. package/dist/{chunk-ACCKVSHU.js → chunk-GXIWHXDB.js} +3 -3
  56. package/dist/{chunk-LUL5Z66S.js → chunk-HOX4YZ2K.js} +6 -5
  57. package/dist/chunk-HRAKUPIH.js +57 -0
  58. package/dist/{chunk-F5Z7EWMN.js → chunk-IJMW64DX.js} +50 -50
  59. package/dist/{chunk-QNWRHOMF.js → chunk-IMOD2YPV.js} +16 -9
  60. package/dist/{chunk-HZ2T2YED.js → chunk-IQCNVLO6.js} +28 -8
  61. package/dist/{chunk-HZFBVU5X.js → chunk-ISNCCX42.js} +8 -8
  62. package/dist/{chunk-7JSSKXG2.js → chunk-IZYTT3CD.js} +7 -3
  63. package/dist/chunk-KKEYGFX4.js +915 -0
  64. package/dist/{chunk-HHVJNVUJ.js → chunk-KS7ETA3P.js} +2 -2
  65. package/dist/{chunk-BLTEAUCB.js → chunk-L3Z5ANCV.js} +7 -7
  66. package/dist/{chunk-4VMV6OS6.js → chunk-LBFQMYS3.js} +2 -2
  67. package/dist/{chunk-URBGEOH3.js → chunk-M6Z2V6YU.js} +5 -5
  68. package/dist/{chunk-BT7HGDOX.js → chunk-MBJO5VNZ.js} +12 -12
  69. package/dist/chunk-MNQN3X6Y.js +595 -0
  70. package/dist/{chunk-3QKXHCGS.js → chunk-MZHXENL7.js} +5 -5
  71. package/dist/chunk-MZNWZUJM.js +1801 -0
  72. package/dist/{chunk-7YJWEF2L.js → chunk-N37QC5FV.js} +5 -5
  73. package/dist/{chunk-TJFDL26W.js → chunk-NCCQ6DVS.js} +7 -7
  74. package/dist/{chunk-P5JMBPDJ.js → chunk-NO7J45X6.js} +162 -47
  75. package/dist/chunk-OH3YYA3B.js +15 -0
  76. package/dist/{chunk-22PQ4TX4.js → chunk-P4DL2LM5.js} +16 -77
  77. package/dist/{chunk-LIN2K3EL.js → chunk-PFLOULP3.js} +4 -4
  78. package/dist/{chunk-QXFBABFJ.js → chunk-QKWL7SYE.js} +11 -11
  79. package/dist/chunk-RFCKPS2V.js +26 -0
  80. package/dist/{chunk-ZS43Y2FT.js → chunk-RTLNFZMD.js} +12 -4
  81. package/dist/{chunk-U7H5WRG5.js → chunk-RXFPB32E.js} +8 -6
  82. package/dist/{chunk-Q7NNUHQV.js → chunk-SEDI5K5B.js} +16 -16
  83. package/dist/{chunk-WV6TDAPN.js → chunk-SELG4SUR.js} +7 -7
  84. package/dist/{chunk-3WBALRQH.js → chunk-SER7RRAE.js} +27 -832
  85. package/dist/{chunk-K2HL3GBL.js → chunk-T4TY5GG3.js} +165 -15
  86. package/dist/chunk-T7QQBNLH.js +691 -0
  87. package/dist/{chunk-6OII3LOK.js → chunk-TLTGZTXI.js} +3 -3
  88. package/dist/chunk-TZ6UVP2H.js +637 -0
  89. package/dist/{chunk-3JLFK5MW.js → chunk-TZHN5ITX.js} +13 -41
  90. package/dist/{chunk-VANN3GDP.js → chunk-U3TPUXOQ.js} +399 -234
  91. package/dist/{chunk-VHMX7SXF.js → chunk-UA3W4FGC.js} +6 -6
  92. package/dist/{chunk-3O2ZAUGQ.js → chunk-UA6W4XFJ.js} +2 -2
  93. package/dist/chunk-UWD3JD5X.js +709 -0
  94. package/dist/chunk-V4ZKOKRB.js +13433 -0
  95. package/dist/{chunk-NC4KV7EL.js → chunk-VCRVEDUC.js} +5 -5
  96. package/dist/{chunk-4DU2TVI4.js → chunk-VMATUZB6.js} +12 -10
  97. package/dist/{chunk-J2FYEQ5L.js → chunk-VTYHHQ57.js} +2 -2
  98. package/dist/chunk-WB7POC6M.js +891 -0
  99. package/dist/{chunk-3HQVBIKD.js → chunk-WBVKKTUT.js} +2 -2
  100. package/dist/{chunk-EHOSNVVM.js → chunk-WLHX3MM5.js} +6 -2
  101. package/dist/{chunk-24T2YZ7A.js → chunk-WN552PKN.js} +553 -298
  102. package/dist/{chunk-4U4TKZFR.js → chunk-WT5TRMO4.js} +51 -26
  103. package/dist/{chunk-XWMSPJYN.js → chunk-WURGVOZJ.js} +56 -12
  104. package/dist/{chunk-7WUZEB2M.js → chunk-XR3XJN2M.js} +2 -2
  105. package/dist/chunk-XW2UZICE.js +372 -0
  106. package/dist/{chunk-2AKYFREM.js → chunk-XZ6UFQ52.js} +11 -11
  107. package/dist/chunk-Y3JU5RPK.js +8 -0
  108. package/dist/chunk-YKRJTYNP.js +1143 -0
  109. package/dist/{chunk-PWWSIB2A.js → chunk-ZGIGW4ZG.js} +5 -5
  110. package/dist/cli/index.js +34 -36
  111. package/dist/{clio-QQCMTUZE.js → clio-L2P7S2R2.js} +9 -9
  112. package/dist/{code-nav-GUPM6766.js → code-nav-B5LNX4KU.js} +25 -25
  113. package/dist/{components-TNIKXCBH.js → components-63MMQKUT.js} +6 -6
  114. package/dist/{config-IIM7YOD3.js → config-YXARKGTX.js} +70 -67
  115. package/dist/{configure-4ZM5HWJX.js → configure-LMVQJ46J.js} +47 -35
  116. package/dist/{context-OL5P3HEP.js → context-7HJEWTTP.js} +87 -44
  117. package/dist/{context-44BZLJ3J.js → context-XSZKKFBW.js} +14 -14
  118. package/dist/{context-AIDVQKMW.js → context-YG2LZDYZ.js} +60 -58
  119. package/dist/{context-clear-OQV76MYP.js → context-clear-AC5NXHM2.js} +57 -55
  120. package/dist/{context-index-HP2JFUWA.js → context-index-KKTPRV5G.js} +3 -3
  121. package/dist/{context-map-INTXD54D.js → context-map-T7ROR5D5.js} +4 -4
  122. package/dist/{context-working-set-ZUW3EGLS.js → context-working-set-F4Q4J3NS.js} +12 -10
  123. package/dist/{detail-UXPWRANG.js → detail-H73BEF2N.js} +58 -56
  124. package/dist/{dispatch-runner-P3ZW6G77.js → dispatch-runner-3RY5FSJC.js} +74 -72
  125. package/dist/{doctor-JJVGPZWT.js → doctor-EQYJOGUG.js} +44 -30
  126. package/dist/{eval-V2RTN3UH.js → eval-4P7O6CCE.js} +109 -46
  127. package/dist/{evidence-35PYWGSO.js → evidence-D6GUSYJW.js} +57 -55
  128. package/dist/{evidence-CIGGKI6J.js → evidence-O76QF7TZ.js} +62 -59
  129. package/dist/{evolve-33SM3NJP.js → evolve-H47BCETS.js} +58 -56
  130. package/dist/{extensions-YVRHX6ZI.js → extensions-NNL3ZOCU.js} +98 -20
  131. package/dist/{fleet-LFO7SIPC.js → fleet-KMNS6NOM.js} +106 -99
  132. package/dist/{fleet-commands-RLK72GU3.js → fleet-commands-DOWSYCBX.js} +14 -14
  133. package/dist/{fleet-decisions-3SBSCTCW.js → fleet-decisions-S3PTZV2D.js} +9 -9
  134. package/dist/{fleet-graph-JZIBCGMW.js → fleet-graph-F2DE2TME.js} +26 -24
  135. package/dist/{fleet-inspect-2L5YGGZJ.js → fleet-inspect-EN2Q6IVB.js} +60 -57
  136. package/dist/{fleet-preflight-QRSHIIDE.js → fleet-preflight-FRLETDD3.js} +3 -3
  137. package/dist/{fleet-validate-LIAVKDUU.js → fleet-validate-B2XDLS57.js} +28 -29
  138. package/dist/{fleet-verify-JIK3OQZR.js → fleet-verify-4JKUWGJ7.js} +57 -55
  139. package/dist/{fleet-view-IWHYGQKK.js → fleet-view-BHJFW26B.js} +60 -57
  140. package/dist/{init-NJEDOTQW.js → init-XAT5N5YM.js} +79 -74
  141. package/dist/interop-FVECHFKG.js +246 -0
  142. package/dist/{inventory-74UL7UHU.js → inventory-7KFQGLCV.js} +60 -57
  143. package/dist/library-NY2XOT75.js +492 -0
  144. package/dist/library-QAPAO23R.js +306 -0
  145. package/dist/library-import-5Y6MAS3R.js +183 -0
  146. package/dist/library-inventory-JT6HWITQ.js +56 -0
  147. package/dist/library-validation-EQUH25DC.js +42 -0
  148. package/dist/{memory-I76I5VUH.js → memory-DYVTTCP6.js} +58 -56
  149. package/dist/{models-D4YDIQZQ.js → models-MASFJ6Y2.js} +48 -36
  150. package/dist/{monitor-NKVD55HX.js → monitor-YMP4NXJJ.js} +64 -61
  151. package/dist/{orchestrator-I6OATVPK.js → orchestrator-AFQRRTEI.js} +3685 -1841
  152. package/dist/{panes-7BTYH3XQ.js → panes-D3Y2KFG5.js} +4 -4
  153. package/dist/{panes-WPOMEMRH.js → panes-NICTHQCV.js} +7 -7
  154. package/dist/{paths-J3KN7UAO.js → paths-PSFAUIGO.js} +5 -5
  155. package/dist/{preload-EJAWJEIO.js → preload-5Q7VXRFJ.js} +57 -55
  156. package/dist/{reset-4XMQKDNZ.js → reset-7NKZK7JN.js} +9 -9
  157. package/dist/{resources-TVYVXK3Q.js → resources-NILSIZAT.js} +94 -38
  158. package/dist/{run-OWQNNSJU.js → run-BPZGEBZV.js} +121 -105
  159. package/dist/{share-NPZZMUXG.js → share-EZ6ERBMH.js} +31 -28
  160. package/dist/skills-BTVVNYVM.js +100 -0
  161. package/dist/{skills-eval-J5TCKSJA.js → skills-eval-UY34MNK7.js} +110 -72
  162. package/dist/{skills-inventory-7II4DM57.js → skills-inventory-JDHSIA7I.js} +30 -25
  163. package/dist/{slash-commands-MDSDSWYF.js → slash-commands-K4FNQ2AT.js} +49 -46
  164. package/dist/{steer-S7D7IKPU.js → steer-2B3EQGFH.js} +4 -4
  165. package/dist/{support-5VAEC32W.js → support-L2SOL3IE.js} +7 -7
  166. package/dist/{targets-KILZEOCE.js → targets-44VKGFLN.js} +64 -58
  167. package/dist/{tasks-R6P6OV22.js → tasks-3KODKFU7.js} +12 -12
  168. package/dist/{terminal-lease-LZCG2KN3.js → terminal-lease-LXA7MMPO.js} +32 -19
  169. package/dist/{tools-6OCQ6SVB.js → tools-3UB7TEVR.js} +7 -7
  170. package/dist/{trace-JHLXWUMN.js → trace-TAMIU4OJ.js} +5 -4
  171. package/dist/{tui-primitives-RCY2HN7G.js → tui-primitives-A6MUW32V.js} +3 -2
  172. package/dist/{uninstall-FXYMFFRT.js → uninstall-QYVRPEM4.js} +9 -9
  173. package/dist/{upgrade-D2OZH6IQ.js → upgrade-7PMKM2JH.js} +15 -16
  174. package/dist/{usage-PIASNUS4.js → usage-6EQV7EQK.js} +70 -67
  175. package/dist/{verifiers-LTHUY2PX.js → verifiers-JLITWSHU.js} +15 -15
  176. package/dist/{verify-HYF7KBVE.js → verify-T7NAEVIG.js} +13 -13
  177. package/dist/{web-fetch-MQN4FH3X.js → web-fetch-W4TNW4Q7.js} +4 -4
  178. package/dist/{wiki-generate-RK7JQ5NP.js → wiki-generate-T2TJQJUA.js} +81 -76
  179. package/dist/{with-panes-OFTNAR4Y.js → with-panes-CHFC7HGI.js} +4 -4
  180. package/dist/worker/entry.js +283 -76
  181. package/docs/README.md +43 -0
  182. package/docs/architecture/architecture.md +8 -7
  183. package/docs/architecture/artifact-versions.md +3 -3
  184. package/docs/architecture/context-engine.md +35 -1
  185. package/docs/architecture/library.md +32 -0
  186. package/docs/architecture/middleware-and-components.md +1 -1
  187. package/docs/architecture/model-catalog.md +21 -1
  188. package/docs/architecture/pi-boundary.md +18 -0
  189. package/docs/architecture/prompt-envelope-and-tools.md +5 -5
  190. package/docs/architecture/safety-model.md +21 -2
  191. package/docs/architecture/session-lifecycle.md +12 -1
  192. package/docs/architecture/tui-design.md +108 -9
  193. package/docs/architecture/worker-context.md +106 -0
  194. package/docs/guide/authoring-plugins.md +160 -0
  195. package/docs/guide/built-in-agents.md +5 -5
  196. package/docs/guide/commands-and-modes.md +161 -56
  197. package/docs/guide/configuration-and-targets.md +1 -1
  198. package/docs/guide/configuration-reference.md +27 -34
  199. package/docs/guide/environment-variables.md +2 -2
  200. package/docs/guide/exit-codes-and-output.md +1 -1
  201. package/docs/guide/extensions-and-sharing.md +93 -53
  202. package/docs/guide/fleet-dispatch.md +31 -4
  203. package/docs/guide/glossary.md +1 -1
  204. package/docs/guide/harness-extensions.md +291 -0
  205. package/docs/guide/installation-and-lifecycle.md +9 -9
  206. package/docs/guide/interop.md +243 -0
  207. package/docs/guide/panes-and-files.md +3 -3
  208. package/docs/guide/plugins.md +80 -0
  209. package/docs/guide/resource-library.md +111 -45
  210. package/docs/guide/skills-marketplace.md +35 -72
  211. package/docs/guide/tool-usage.md +19 -7
  212. package/docs/guide/troubleshooting.md +1 -1
  213. package/docs/process/development-pipeline.md +14 -14
  214. package/docs/process/documentation-coverage.md +28 -1
  215. package/docs/process/documentation-guide.md +15 -7
  216. package/docs/process/eval-runner.md +8 -3
  217. package/docs/process/performance-methodology.md +1 -1
  218. package/docs/process/release-cut-checklist.md +4 -0
  219. package/docs/process/scientific-validation.md +23 -0
  220. package/evals/scalar-decision-machinery.ts +1 -1
  221. package/examples/extensions/README.md +67 -0
  222. package/examples/extensions/lab-status/clio-coder-extension.json +14 -0
  223. package/examples/extensions/lab-status/extension.mjs +68 -0
  224. package/examples/extensions/lab-status/jobs.synthetic.json +9 -0
  225. package/examples/extensions/measurements/clio-coder-extension.json +28 -0
  226. package/examples/extensions/measurements/summarize.cjs +23 -0
  227. package/library/README.md +109 -0
  228. package/library/_authoring/templates/agent/README.md +28 -0
  229. package/library/_authoring/templates/agent/agents/benchmark-scout.md +30 -0
  230. package/library/_authoring/templates/agent/plugin.json +23 -0
  231. package/library/_authoring/templates/fleet/README.md +29 -0
  232. package/library/_authoring/templates/fleet/fleets/pipeline-review.md +31 -0
  233. package/library/_authoring/templates/fleet/plugin.json +23 -0
  234. package/library/_authoring/templates/plugin/README.md +37 -0
  235. package/library/_authoring/templates/plugin/agents/data-curator.md +31 -0
  236. package/library/_authoring/templates/plugin/assets/curation-guide.md +22 -0
  237. package/library/_authoring/templates/plugin/plugin.json +42 -0
  238. package/library/_authoring/templates/plugin/prompts/inspect-dataset.md +15 -0
  239. package/library/_authoring/templates/plugin/skills/dataset-curation/SKILL.md +36 -0
  240. package/library/_authoring/templates/plugin/skills/dataset-curation/evals.md +17 -0
  241. package/library/_authoring/templates/prompt/README.md +28 -0
  242. package/library/_authoring/templates/prompt/plugin.json +23 -0
  243. package/library/_authoring/templates/prompt/prompts/paper-summary.md +26 -0
  244. package/library/_authoring/templates/skill/README.md +24 -0
  245. package/library/_authoring/templates/skill/SKILL.md +39 -0
  246. package/library/_authoring/templates/skill/evals.md +30 -0
  247. package/library/_authoring/templates/skill/plugin.json +23 -0
  248. package/library/agents/README.md +7 -0
  249. package/library/fleets/README.md +7 -0
  250. package/library/plugins/materio/README.md +137 -0
  251. package/library/plugins/materio/ai.iowarp.clio/agents/materio-lab-definer.md +208 -0
  252. package/library/plugins/materio/ai.iowarp.clio/agents/materio-literature-reviewer.md +308 -0
  253. package/library/plugins/materio/ai.iowarp.clio/agents/materio-research-explorer.md +249 -0
  254. package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-executor.md +416 -0
  255. package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-verifier.md +60 -0
  256. package/library/plugins/materio/ai.iowarp.clio/agents/materio-workflow-planner.md +238 -0
  257. package/library/plugins/materio/ai.iowarp.clio/fleets/materio-execute-task.md +50 -0
  258. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/add-task.md +66 -0
  259. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/archive-task.md +65 -0
  260. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/checkpoint.md +26 -0
  261. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-research-tasks.md +230 -0
  262. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-virtual-lab.md +181 -0
  263. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/execute-task.md +292 -0
  264. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/help.md +129 -0
  265. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/identify-research.md +206 -0
  266. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/literature-review.md +201 -0
  267. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/pause-research.md +12 -0
  268. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/progress.md +105 -0
  269. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/remove-task.md +63 -0
  270. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/resume-research.md +64 -0
  271. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/settings.md +16 -0
  272. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/status.md +92 -0
  273. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/upload-data.md +104 -0
  274. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/wtfp.md +145 -0
  275. package/library/plugins/materio/ai.iowarp.clio/references/execution.md +56 -0
  276. package/library/plugins/materio/ai.iowarp.portability/provenance.json +9 -0
  277. package/library/plugins/materio/assets/actions/add-task.md +86 -0
  278. package/library/plugins/materio/assets/actions/archive-task.md +84 -0
  279. package/library/plugins/materio/assets/actions/checkpoint.md +47 -0
  280. package/library/plugins/materio/assets/actions/define-research-tasks.md +228 -0
  281. package/library/plugins/materio/assets/actions/define-virtual-lab.md +179 -0
  282. package/library/plugins/materio/assets/actions/execute-task.md +290 -0
  283. package/library/plugins/materio/assets/actions/help.md +140 -0
  284. package/library/plugins/materio/assets/actions/identify-research.md +204 -0
  285. package/library/plugins/materio/assets/actions/literature-review.md +199 -0
  286. package/library/plugins/materio/assets/actions/pause-research.md +34 -0
  287. package/library/plugins/materio/assets/actions/progress.md +125 -0
  288. package/library/plugins/materio/assets/actions/remove-task.md +82 -0
  289. package/library/plugins/materio/assets/actions/resume-research.md +84 -0
  290. package/library/plugins/materio/assets/actions/settings.md +38 -0
  291. package/library/plugins/materio/assets/actions/status.md +112 -0
  292. package/library/plugins/materio/assets/actions/upload-data.md +123 -0
  293. package/library/plugins/materio/assets/actions/wtfp.md +179 -0
  294. package/library/plugins/materio/assets/references/research-domains.md +134 -0
  295. package/library/plugins/materio/assets/references/research-policy.md +77 -0
  296. package/library/plugins/materio/assets/references/traditional-workflows.md +146 -0
  297. package/library/plugins/materio/assets/scripts/check_physics.py +271 -0
  298. package/library/plugins/materio/assets/scripts/check_scripts.py +248 -0
  299. package/library/plugins/materio/assets/scripts/project_plugin.py +165 -0
  300. package/library/plugins/materio/assets/scripts/research_state.py +400 -0
  301. package/library/plugins/materio/assets/scripts/verify_citations.py +616 -0
  302. package/library/plugins/materio/assets/templates/RESEARCH.md +39 -0
  303. package/library/plugins/materio/assets/templates/VIRTUAL-LAB.md +120 -0
  304. package/library/plugins/materio/assets/templates/WORKFLOW.md +42 -0
  305. package/library/plugins/materio/assets/templates/config.json +5 -0
  306. package/library/plugins/materio/evals/scripts.yaml +29 -0
  307. package/library/plugins/materio/plugin.json +530 -0
  308. package/library/plugins/materio/skills/materio-lab-definer/SKILL.md +74 -0
  309. package/library/plugins/materio/skills/materio-literature-reviewer/SKILL.md +64 -0
  310. package/library/plugins/materio/skills/materio-research-explorer/SKILL.md +74 -0
  311. package/library/plugins/materio/skills/materio-task-executor/SKILL.md +214 -0
  312. package/library/plugins/materio/skills/materio-task-verifier/SKILL.md +46 -0
  313. package/library/plugins/materio/skills/materio-workflow-planner/SKILL.md +79 -0
  314. package/library/plugins/materio/tests/test_check_physics.py +139 -0
  315. package/library/plugins/materio/tests/test_check_scripts.py +140 -0
  316. package/library/plugins/materio/tests/test_research_state.py +291 -0
  317. package/library/plugins/materio/tests/test_verify_citations.py +337 -0
  318. package/library/prompts/README.md +7 -0
  319. package/library/registry.yaml +921 -0
  320. package/library/skills/README.md +120 -0
  321. package/{skills → library/skills}/coding/ast-grep/SKILL.md +1 -1
  322. package/{skills → library/skills}/coding/ast-grep/evals.md +1 -1
  323. package/library/skills/coding/ast-grep/plugin.json +23 -0
  324. package/{skills → library/skills}/coding/coding-standards/SKILL.md +1 -1
  325. package/{skills → library/skills}/coding/coding-standards/evals.md +1 -1
  326. package/library/skills/coding/coding-standards/plugin.json +23 -0
  327. package/{skills → library/skills}/coding/prototype/SKILL.md +1 -1
  328. package/{skills → library/skills}/coding/prototype/evals.md +1 -1
  329. package/library/skills/coding/prototype/plugin.json +23 -0
  330. package/{skills → library/skills}/coding/tdd/SKILL.md +1 -1
  331. package/{skills → library/skills}/coding/tdd/evals.md +1 -1
  332. package/library/skills/coding/tdd/plugin.json +23 -0
  333. package/{skills → library/skills}/context/context-handoff/SKILL.md +1 -1
  334. package/{skills → library/skills}/context/context-handoff/evals.md +1 -1
  335. package/library/skills/context/context-handoff/plugin.json +23 -0
  336. package/{skills → library/skills}/context/context-prime/SKILL.md +1 -1
  337. package/{skills → library/skills}/context/context-prime/evals.md +1 -1
  338. package/library/skills/context/context-prime/plugin.json +23 -0
  339. package/{skills → library/skills}/git/branch-closeout/SKILL.md +1 -1
  340. package/library/skills/git/branch-closeout/plugin.json +23 -0
  341. package/{skills → library/skills}/git/file-ticket/SKILL.md +1 -1
  342. package/library/skills/git/file-ticket/plugin.json +23 -0
  343. package/{skills → library/skills}/git/fix-issue/SKILL.md +1 -1
  344. package/library/skills/git/fix-issue/plugin.json +23 -0
  345. package/{skills → library/skills}/git/resolve-merge-conflicts/SKILL.md +1 -1
  346. package/{skills → library/skills}/git/resolve-merge-conflicts/evals.md +1 -1
  347. package/library/skills/git/resolve-merge-conflicts/plugin.json +23 -0
  348. package/{skills → library/skills}/git/ship/SKILL.md +1 -1
  349. package/library/skills/git/ship/plugin.json +23 -0
  350. package/{skills → library/skills}/git/worktree-create/SKILL.md +1 -1
  351. package/library/skills/git/worktree-create/plugin.json +23 -0
  352. package/{skills → library/skills}/git/worktree-merge/SKILL.md +1 -1
  353. package/library/skills/git/worktree-merge/plugin.json +23 -0
  354. package/{skills → library/skills}/meta/clio-coder-dev/SKILL.md +1 -1
  355. package/{skills → library/skills}/meta/clio-coder-dev/evals.md +1 -1
  356. package/library/skills/meta/clio-coder-dev/plugin.json +23 -0
  357. package/{skills → library/skills}/meta/clio-coder-test/SKILL.md +1 -1
  358. package/{skills → library/skills}/meta/clio-coder-test/evals.md +1 -1
  359. package/library/skills/meta/clio-coder-test/plugin.json +23 -0
  360. package/{skills → library/skills}/meta/credentials/SKILL.md +1 -1
  361. package/{skills → library/skills}/meta/credentials/evals.md +1 -1
  362. package/library/skills/meta/credentials/plugin.json +23 -0
  363. package/library/skills/meta/find-skills/SKILL.md +85 -0
  364. package/library/skills/meta/find-skills/evals.md +65 -0
  365. package/library/skills/meta/find-skills/plugin.json +23 -0
  366. package/{skills → library/skills}/meta/herdr/SKILL.md +1 -1
  367. package/{skills → library/skills}/meta/herdr/evals.md +1 -1
  368. package/library/skills/meta/herdr/plugin.json +23 -0
  369. package/{skills → library/skills}/meta/skill-craft/SKILL.md +23 -9
  370. package/{skills → library/skills}/meta/skill-craft/evals.md +11 -3
  371. package/library/skills/meta/skill-craft/plugin.json +23 -0
  372. package/{skills → library/skills}/planning/archify/SKILL.md +13 -13
  373. package/library/skills/planning/archify/plugin.json +23 -0
  374. package/{skills → library/skills}/planning/architecture/SKILL.md +1 -1
  375. package/{skills → library/skills}/planning/architecture/evals.md +1 -1
  376. package/library/skills/planning/architecture/plugin.json +23 -0
  377. package/{skills → library/skills}/planning/backlog/SKILL.md +1 -1
  378. package/{skills → library/skills}/planning/backlog/evals.md +1 -1
  379. package/library/skills/planning/backlog/plugin.json +23 -0
  380. package/{skills → library/skills}/planning/prd/SKILL.md +1 -1
  381. package/{skills → library/skills}/planning/prd/evals.md +1 -1
  382. package/library/skills/planning/prd/plugin.json +23 -0
  383. package/{skills → library/skills}/planning/product-intent/SKILL.md +1 -1
  384. package/{skills → library/skills}/planning/product-intent/evals.md +1 -1
  385. package/library/skills/planning/product-intent/plugin.json +23 -0
  386. package/{skills → library/skills}/planning/tech-spec/SKILL.md +1 -1
  387. package/{skills → library/skills}/planning/tech-spec/evals.md +1 -1
  388. package/library/skills/planning/tech-spec/plugin.json +23 -0
  389. package/{skills → library/skills}/registry.yaml +7 -7
  390. package/{skills → library/skills}/remote.yaml +1 -1
  391. package/{skills → library/skills}/research/arxiv-literature/SKILL.md +1 -1
  392. package/{skills → library/skills}/research/arxiv-literature/evals.md +1 -1
  393. package/library/skills/research/arxiv-literature/plugin.json +23 -0
  394. package/{skills → library/skills}/research/experiment-protocol/SKILL.md +1 -1
  395. package/{skills → library/skills}/research/experiment-protocol/evals.md +1 -1
  396. package/library/skills/research/experiment-protocol/plugin.json +23 -0
  397. package/{skills → library/skills}/research/scientific-debugging/SKILL.md +1 -1
  398. package/{skills → library/skills}/research/scientific-debugging/evals.md +1 -1
  399. package/library/skills/research/scientific-debugging/plugin.json +23 -0
  400. package/{skills → library/skills}/research/scientific-modernization/SKILL.md +1 -1
  401. package/{skills → library/skills}/research/scientific-modernization/evals.md +1 -1
  402. package/library/skills/research/scientific-modernization/plugin.json +23 -0
  403. package/{skills → library/skills}/skill-marketplace.json +37 -37
  404. package/{skills → library/skills}/workflow/cut-it/SKILL.md +1 -1
  405. package/{skills → library/skills}/workflow/cut-it/evals.md +1 -1
  406. package/library/skills/workflow/cut-it/plugin.json +23 -0
  407. package/{skills → library/skills}/workflow/design-council/SKILL.md +1 -1
  408. package/{skills → library/skills}/workflow/design-council/evals.md +1 -1
  409. package/library/skills/workflow/design-council/plugin.json +23 -0
  410. package/{skills → library/skills}/workflow/grill-me/SKILL.md +1 -1
  411. package/{skills → library/skills}/workflow/grill-me/evals.md +1 -1
  412. package/library/skills/workflow/grill-me/plugin.json +23 -0
  413. package/{skills → library/skills}/workflow/workflow-distiller/SKILL.md +14 -11
  414. package/{skills → library/skills}/workflow/workflow-distiller/evals.md +14 -6
  415. package/library/skills/workflow/workflow-distiller/plugin.json +23 -0
  416. package/package.json +12 -5
  417. package/src/cli/agents.ts +1 -1
  418. package/src/cli/config-inspect.ts +1 -1
  419. package/src/cli/configure.ts +2 -2
  420. package/src/cli/eval.ts +40 -6
  421. package/src/cli/extensions.ts +74 -8
  422. package/src/cli/fleet-preflight.ts +2 -0
  423. package/src/cli/fleet.ts +2 -0
  424. package/src/cli/index.ts +1 -3
  425. package/src/cli/interop-inspect.ts +61 -33
  426. package/src/cli/interop.ts +79 -9
  427. package/src/cli/library-import.ts +139 -0
  428. package/src/cli/library.ts +418 -120
  429. package/src/cli/run.ts +26 -9
  430. package/src/cli/skills-eval.ts +43 -6
  431. package/src/cli/skills-inventory.ts +6 -2
  432. package/src/cli/skills.ts +44 -491
  433. package/src/core/bus-events.ts +5 -0
  434. package/src/core/defaults.ts +1 -1
  435. package/src/core/recent-models.ts +2 -2
  436. package/src/core/session-routing.ts +3 -3
  437. package/src/core/state-file-lock.ts +1 -1
  438. package/src/core/tool-names.ts +5 -0
  439. package/src/domains/agents/extension.ts +42 -6
  440. package/src/domains/agents/fleet-commands.ts +92 -1
  441. package/src/domains/agents/fleet-contract.ts +87 -19
  442. package/src/domains/agents/recipe.ts +5 -4
  443. package/src/domains/agents/registry.ts +80 -24
  444. package/src/domains/config/keybindings.ts +155 -95
  445. package/src/domains/context/worker/contract.ts +91 -0
  446. package/src/domains/context/worker/pressure.ts +120 -0
  447. package/src/domains/context/worker/recall.ts +62 -0
  448. package/src/domains/context/worker/select.ts +164 -0
  449. package/src/domains/context/worker/snapshot.ts +35 -0
  450. package/src/domains/context/worker/store.ts +16 -0
  451. package/src/domains/context/working-set/replay/synthetic.ts +2 -1
  452. package/src/domains/dispatch/active-route-planner.ts +2 -0
  453. package/src/domains/dispatch/backoff.ts +1 -0
  454. package/src/domains/dispatch/code-step.ts +12 -2
  455. package/src/domains/dispatch/contract.ts +3 -0
  456. package/src/domains/dispatch/execution-plan.ts +2 -0
  457. package/src/domains/dispatch/extension.ts +109 -27
  458. package/src/domains/dispatch/fleet-plan.ts +10 -0
  459. package/src/domains/dispatch/fleet-run.ts +1 -0
  460. package/src/domains/dispatch/orphan-recovery.ts +1 -0
  461. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  462. package/src/domains/dispatch/state.ts +1 -0
  463. package/src/domains/dispatch/types.ts +5 -0
  464. package/src/domains/dispatch/validation.ts +12 -0
  465. package/src/domains/dispatch/workspace-checkpoint.ts +1 -1
  466. package/src/domains/evidence/failure-attribution.ts +1 -0
  467. package/src/domains/evidence/trust-status.ts +22 -3
  468. package/src/domains/extensions/command-schema.ts +145 -0
  469. package/src/domains/extensions/command-tools.ts +15 -0
  470. package/src/domains/extensions/compatibility.ts +7 -0
  471. package/src/domains/extensions/contract.ts +0 -4
  472. package/src/domains/extensions/discovery.ts +69 -205
  473. package/src/domains/extensions/extension.ts +0 -4
  474. package/src/domains/extensions/index.ts +1 -5
  475. package/src/domains/extensions/manager.ts +1 -6
  476. package/src/domains/extensions/operator-commands.ts +29 -0
  477. package/src/domains/extensions/operator-runtime.ts +483 -0
  478. package/src/domains/extensions/public-api.ts +53 -0
  479. package/src/domains/extensions/runtime-child.mjs +114 -0
  480. package/src/domains/extensions/runtime-process.ts +306 -0
  481. package/src/domains/extensions/runtime-schema.ts +146 -0
  482. package/src/domains/extensions/{resources.ts → snapshot-access.ts} +1 -17
  483. package/src/domains/extensions/snapshot.ts +4 -32
  484. package/src/domains/extensions/state.ts +5 -83
  485. package/src/domains/extensions/types.ts +33 -34
  486. package/src/domains/interop/adopt.ts +546 -0
  487. package/src/domains/interop/detect.ts +50 -12
  488. package/src/domains/interop/foreign.ts +554 -0
  489. package/src/domains/interop/import.ts +277 -0
  490. package/src/domains/interop/index.ts +24 -0
  491. package/src/domains/interop/install.ts +6 -0
  492. package/src/domains/interop/inventory.ts +351 -0
  493. package/src/domains/interop/projection.ts +360 -0
  494. package/src/domains/interop/registry.ts +106 -3
  495. package/src/domains/interop/types.ts +51 -0
  496. package/src/domains/lifecycle/migrations/index.ts +0 -2
  497. package/src/domains/lifecycle/naming-resources.ts +1 -1
  498. package/src/domains/middleware/marketplace-offer.ts +1 -1
  499. package/src/domains/mux/contract.ts +1 -1
  500. package/src/domains/plugins/catalog.ts +204 -0
  501. package/src/domains/plugins/contract.ts +24 -0
  502. package/src/domains/plugins/discovery.ts +316 -0
  503. package/src/domains/plugins/extension.ts +40 -0
  504. package/src/domains/plugins/index.ts +77 -0
  505. package/src/domains/plugins/integrity.ts +6 -0
  506. package/src/domains/plugins/manifest.ts +3 -0
  507. package/src/domains/plugins/resources.ts +102 -0
  508. package/src/domains/plugins/state.ts +753 -0
  509. package/src/domains/plugins/types.ts +217 -0
  510. package/src/domains/prompts/extension.ts +9 -2
  511. package/src/domains/prompts/fragments/operating/skills.md +10 -10
  512. package/src/domains/resources/common-loader.ts +9 -6
  513. package/src/domains/resources/index.ts +67 -0
  514. package/src/domains/resources/library-actions.ts +836 -0
  515. package/src/domains/resources/library-evals.ts +38 -0
  516. package/src/domains/resources/library-inventory.ts +1048 -0
  517. package/src/domains/resources/library-types.ts +50 -0
  518. package/src/domains/resources/library-validation.ts +634 -0
  519. package/src/domains/resources/library.ts +437 -156
  520. package/src/domains/resources/package-references.ts +66 -0
  521. package/src/domains/resources/prompts/loader.ts +75 -41
  522. package/src/domains/resources/skills/install.ts +2 -2
  523. package/src/domains/resources/skills/loader.ts +77 -22
  524. package/src/domains/resources/skills/marketplace.ts +48 -57
  525. package/src/domains/resources/skills/promotion.ts +2 -2
  526. package/src/domains/resources/skills/provenance-pin.ts +17 -4
  527. package/src/domains/safety/action-classifier.ts +2 -2
  528. package/src/domains/safety/default-path-policy.ts +3 -1
  529. package/src/domains/safety/policy-engine.ts +1 -1
  530. package/src/domains/safety/protected-artifacts.ts +21 -5
  531. package/src/domains/safety/skill-authority.ts +5 -2
  532. package/src/domains/share/archive.ts +1 -1
  533. package/src/engine/apis/openai-completions.ts +52 -2
  534. package/src/engine/notices/pi-tui-LICENSE +21 -0
  535. package/src/engine/tui.ts +3 -0
  536. package/src/engine/worker-runtime.ts +58 -14
  537. package/src/engine/worker-tools.ts +5 -0
  538. package/src/entry/orchestrator.ts +26 -5
  539. package/src/entry/plugin-reload.ts +18 -0
  540. package/src/interactive/application-controller.ts +67 -21
  541. package/src/interactive/chat-loop.ts +32 -5
  542. package/src/interactive/chat-panel.ts +5 -1
  543. package/src/interactive/clio-editor.ts +53 -21
  544. package/src/interactive/command-output.ts +56 -1
  545. package/src/interactive/editor-submit.ts +65 -28
  546. package/src/interactive/fleet-run-preview.ts +2 -0
  547. package/src/interactive/follow-up-queue-panel.ts +3 -3
  548. package/src/interactive/footer/dashboard.ts +4 -1
  549. package/src/interactive/footer/notifications.ts +2 -2
  550. package/src/interactive/footer/widgets.ts +2 -2
  551. package/src/interactive/interactive-application.ts +209 -21
  552. package/src/interactive/interactive-input-runtime.ts +254 -7
  553. package/src/interactive/interactive-presentation.ts +41 -12
  554. package/src/interactive/interactive-slash-runtime.ts +37 -8
  555. package/src/interactive/keybinding-manager.ts +156 -79
  556. package/src/interactive/keyboard-owner.ts +37 -0
  557. package/src/interactive/leader-key.ts +49 -102
  558. package/src/interactive/leader-menu.ts +45 -0
  559. package/src/interactive/overlay-ask-user-lifecycle.ts +9 -1
  560. package/src/interactive/overlay-frame.ts +15 -0
  561. package/src/interactive/overlay-key-routing.ts +46 -47
  562. package/src/interactive/overlay-lifecycle.ts +30 -15
  563. package/src/interactive/overlay-resource-openers.ts +56 -46
  564. package/src/interactive/overlays/ask-user.ts +630 -556
  565. package/src/interactive/overlays/extension-panel.ts +70 -0
  566. package/src/interactive/overlays/extensions.ts +28 -5
  567. package/src/interactive/overlays/fleet-run-approval.ts +7 -3
  568. package/src/interactive/overlays/help-reference.ts +89 -40
  569. package/src/interactive/overlays/interop.ts +122 -3
  570. package/src/interactive/overlays/keybinding-detail.ts +2 -2
  571. package/src/interactive/overlays/library-lifecycle.ts +90 -0
  572. package/src/interactive/overlays/library-model.ts +574 -0
  573. package/src/interactive/overlays/library-review.ts +557 -0
  574. package/src/interactive/overlays/library-tabs.ts +3 -15
  575. package/src/interactive/overlays/library.ts +602 -0
  576. package/src/interactive/overlays/list-overlay.ts +218 -39
  577. package/src/interactive/overlays/model-selector.ts +28 -25
  578. package/src/interactive/overlays/session-selector.ts +9 -3
  579. package/src/interactive/overlays/settings.ts +25 -18
  580. package/src/interactive/overlays/tree-selector.ts +16 -11
  581. package/src/interactive/permission-hint.ts +13 -0
  582. package/src/interactive/permission-overlay.ts +77 -28
  583. package/src/interactive/prompt-source-label.ts +21 -0
  584. package/src/interactive/renderers/reference-card.ts +35 -0
  585. package/src/interactive/renderers/worker-entry.ts +35 -3
  586. package/src/interactive/slash-autocomplete.ts +99 -1
  587. package/src/interactive/slash-commands.ts +390 -67
  588. package/src/interactive/slash-spec.ts +0 -1
  589. package/src/interactive/terminal-lease.ts +44 -12
  590. package/src/interactive/turn-queues.ts +8 -7
  591. package/src/interactive/turn-runtime.ts +1 -1
  592. package/src/interactive/view/view-overlay.ts +19 -14
  593. package/src/interactive/welcome-dashboard.ts +525 -408
  594. package/src/tools/bootstrap.ts +8 -0
  595. package/src/tools/builtin-tool-catalog.ts +7 -2
  596. package/src/tools/context/index.ts +58 -5
  597. package/src/tools/context/library.ts +465 -0
  598. package/src/tools/context/surface.ts +20 -6
  599. package/src/tools/core-bootstrap.ts +3 -0
  600. package/src/tools/dispatch-admission.ts +24 -1
  601. package/src/tools/dispatch-arguments.ts +8 -0
  602. package/src/tools/dispatch-plan.ts +32 -0
  603. package/src/tools/dispatch-schema.ts +31 -1
  604. package/src/tools/dispatch-types.ts +3 -0
  605. package/src/tools/dispatch.ts +1 -1
  606. package/src/tools/harness-extensions.ts +169 -0
  607. package/src/tools/observation.ts +4 -0
  608. package/src/tools/policy.ts +7 -1
  609. package/src/tools/registry.ts +19 -1
  610. package/src/tools/worker-evidence.ts +5 -0
  611. package/src/worker/context-seed.ts +192 -0
  612. package/src/worker/entry.ts +1 -0
  613. package/src/worker/spec-contract.ts +8 -1
  614. package/dist/chunk-3UW3KU4A.js +0 -21
  615. package/dist/chunk-536HXRFE.js +0 -1257
  616. package/dist/chunk-B3MOMLJ4.js +0 -433
  617. package/dist/chunk-CXQ37WJH.js +0 -45
  618. package/dist/chunk-KTFSFCVN.js +0 -46
  619. package/dist/chunk-QCOV5DFY.js +0 -911
  620. package/dist/chunk-QRFXEO6Y.js +0 -17
  621. package/dist/chunk-VAHLPXPY.js +0 -399
  622. package/dist/interop-RVCAYECG.js +0 -115
  623. package/dist/library-CTKZA7K3.js +0 -226
  624. package/dist/skills-OXFEAWMT.js +0 -510
  625. package/skills/README.md +0 -418
  626. package/skills/meta/find-skills/SKILL.md +0 -78
  627. package/skills/meta/find-skills/evals.md +0 -47
  628. package/src/domains/extensions/resource-path.ts +0 -27
  629. package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +0 -27
  630. package/src/interactive/overlays/agents.ts +0 -70
  631. package/src/interactive/overlays/library-install-confirm.ts +0 -152
  632. package/src/interactive/overlays/prompts.ts +0 -89
  633. package/src/interactive/overlays/skills-hub.ts +0 -615
  634. /package/{skills → library/skills}/coding/ast-grep/references/rule_reference.md +0 -0
  635. /package/{skills → library/skills}/coding/prototype/references/LOGIC.md +0 -0
  636. /package/{skills → library/skills}/coding/prototype/references/UI.md +0 -0
  637. /package/{skills → library/skills}/coding/tdd/references/mocking.md +0 -0
  638. /package/{skills → library/skills}/coding/tdd/references/tests.md +0 -0
  639. /package/{skills → library/skills}/context/context-handoff/scripts/new-handoff.sh +0 -0
  640. /package/{skills → library/skills}/git/branch-closeout/evals.md +0 -0
  641. /package/{skills → library/skills}/git/branch-closeout/references/closeout-checklist.md +0 -0
  642. /package/{skills → library/skills}/git/file-ticket/assets/issue-template.md +0 -0
  643. /package/{skills → library/skills}/git/file-ticket/evals.md +0 -0
  644. /package/{skills → library/skills}/git/file-ticket/references/issue-discovery.md +0 -0
  645. /package/{skills → library/skills}/git/fix-issue/evals.md +0 -0
  646. /package/{skills → library/skills}/git/fix-issue/references/diagnosis-and-rca.md +0 -0
  647. /package/{skills → library/skills}/git/resolve-merge-conflicts/references/conflict-matrix.md +0 -0
  648. /package/{skills → library/skills}/git/ship/assets/pr-template.md +0 -0
  649. /package/{skills → library/skills}/git/ship/evals.md +0 -0
  650. /package/{skills → library/skills}/git/ship/references/remote-and-branch-policy.md +0 -0
  651. /package/{skills → library/skills}/git/worktree-create/evals.md +0 -0
  652. /package/{skills → library/skills}/git/worktree-create/references/worktree-setup.md +0 -0
  653. /package/{skills → library/skills}/git/worktree-merge/evals.md +0 -0
  654. /package/{skills → library/skills}/git/worktree-merge/references/merge-strategies.md +0 -0
  655. /package/{skills → library/skills}/meta/clio-coder-test/references/harness.md +0 -0
  656. /package/{skills → library/skills}/meta/clio-coder-test/references/test-map.md +0 -0
  657. /package/{skills → library/skills}/planning/archify/evals.md +0 -0
@@ -0,0 +1,753 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import {
3
+ closeSync,
4
+ cpSync,
5
+ existsSync,
6
+ lstatSync,
7
+ mkdirSync,
8
+ openSync,
9
+ readdirSync,
10
+ readFileSync,
11
+ realpathSync,
12
+ renameSync,
13
+ rmSync,
14
+ } from "node:fs";
15
+ import path from "node:path";
16
+ import { canonicalizeExistingPath } from "../../core/path-canonical.js";
17
+ import { safeResourceWrite } from "../../core/safe-resource-write.js";
18
+ import { clioConfigDir } from "../../core/xdg.js";
19
+ import { evaluateClioCompatibility } from "../extensions/compatibility.js";
20
+ import { isLibraryKind, type LibraryRequirementRef } from "../resources/library-types.js";
21
+ import { isPluginId, pluginPathContained, readPluginManifest } from "./discovery.js";
22
+ import { pluginContentDigest } from "./integrity.js";
23
+ import type {
24
+ InstalledPlugin,
25
+ LibraryPackageInstallInput,
26
+ PluginDiagnosticCode,
27
+ PluginExpectedCopy,
28
+ PluginExpectedState,
29
+ PluginInstallOptions,
30
+ PluginInstallRecord,
31
+ PluginListOptions,
32
+ PluginMutationOptions,
33
+ PluginMutationResult,
34
+ PluginScope,
35
+ PluginState,
36
+ } from "./types.js";
37
+ import { isForeignPluginOrigin } from "./types.js";
38
+
39
+ /** sourcePath is a prepared package root containing plugin.json for the declared kind. */
40
+ export function installLibraryPackage(input: LibraryPackageInstallInput): PluginMutationResult {
41
+ const { kind, sourcePath, ...options } = input;
42
+ return installPlugin(sourcePath, { ...options, expectedKind: kind });
43
+ }
44
+
45
+ export function pluginBaseDir(scope: PluginScope, cwd = process.cwd()): string {
46
+ return scope === "user"
47
+ ? path.join(clioConfigDir(), "plugins")
48
+ : path.join(path.resolve(cwd), ".clio-coder", "plugins");
49
+ }
50
+
51
+ export function pluginStatePath(scope: PluginScope, cwd = process.cwd()): string {
52
+ return path.join(pluginBaseDir(scope, cwd), "state.json");
53
+ }
54
+
55
+ function record(value: unknown): value is Record<string, unknown> {
56
+ return value !== null && typeof value === "object" && !Array.isArray(value);
57
+ }
58
+
59
+ function plainFile(file: string): void {
60
+ const stat = lstatSync(file);
61
+ if (!stat.isFile() || stat.isSymbolicLink() || stat.nlink !== 1)
62
+ throw new Error(`plugin state must be a regular unlinked file: ${file}`);
63
+ }
64
+
65
+ function stateBytes(file: string): string | undefined {
66
+ if (!existsSync(file)) return undefined;
67
+ plainFile(file);
68
+ return readFileSync(file, "utf8");
69
+ }
70
+
71
+ function readState(scope: PluginScope, cwd: string): { state: PluginState; bytes?: string } {
72
+ const bytes = stateBytes(pluginStatePath(scope, cwd));
73
+ if (bytes === undefined) return { state: { version: 1, disabled: [], installed: {} } };
74
+ const raw: unknown = JSON.parse(bytes);
75
+ if (
76
+ !record(raw) ||
77
+ raw.version !== 1 ||
78
+ !Array.isArray(raw.disabled) ||
79
+ !raw.disabled.every((id) => typeof id === "string" && isPluginId(id)) ||
80
+ !record(raw.installed)
81
+ )
82
+ throw new Error("plugin install state is malformed");
83
+ for (const [id, entry] of Object.entries(raw.installed)) {
84
+ if (
85
+ !isPluginId(id) ||
86
+ !record(entry) ||
87
+ typeof entry.installedAt !== "string" ||
88
+ typeof entry.source !== "string" ||
89
+ typeof entry.contentDigest !== "string" ||
90
+ !/^[a-f0-9]{64}$/u.test(entry.contentDigest)
91
+ )
92
+ throw new Error(`invalid plugin install record: ${id}`);
93
+ if (entry.origin !== undefined && typeof entry.origin !== "string" && !validOrigin(entry.origin))
94
+ throw new Error(`invalid plugin origin: ${id}`);
95
+ if (entry.kind !== undefined && !isLibraryKind(entry.kind)) throw new Error(`invalid package kind: ${id}`);
96
+ if (entry.trust !== undefined && entry.trust !== "trusted" && entry.trust !== "foreign")
97
+ throw new Error(`invalid package trust: ${id}`);
98
+ }
99
+ return { state: raw as unknown as PluginState, bytes };
100
+ }
101
+
102
+ const FOREIGN_FORMATS = new Set(["portable", "claude-code", "codex"]);
103
+ /** Persisted provenance is validated on every read so a hand-edited record cannot invent an origin. */
104
+ function validOrigin(origin: unknown): boolean {
105
+ if (!record(origin) || typeof origin.source !== "string") return false;
106
+ const optional =
107
+ (origin.marketplace === undefined || typeof origin.marketplace === "string") &&
108
+ (origin.host === undefined || typeof origin.host === "string");
109
+ switch (origin.kind) {
110
+ case "local":
111
+ case "catalog":
112
+ case "github":
113
+ return true;
114
+ case "interop":
115
+ return (
116
+ typeof origin.host === "string" &&
117
+ path.isAbsolute(origin.source) &&
118
+ optional &&
119
+ (origin.format === undefined || FOREIGN_FORMATS.has(String(origin.format)))
120
+ );
121
+ case "import":
122
+ return (
123
+ FOREIGN_FORMATS.has(String(origin.format)) &&
124
+ optional &&
125
+ ((origin.transport === "local" && path.isAbsolute(origin.source)) ||
126
+ (origin.transport === "github" && /^https:\/\/github\.com\//u.test(origin.source)))
127
+ );
128
+ default:
129
+ return false;
130
+ }
131
+ }
132
+
133
+ function assertUnchangedState(file: string, expected: string | undefined): void {
134
+ if (stateBytes(file) !== expected)
135
+ throw new Error("plugin install state changed during the operation; retry after reviewing concurrent edits");
136
+ }
137
+
138
+ function writeState(scope: PluginScope, cwd: string, state: PluginState, expected: string | undefined): void {
139
+ const file = pluginStatePath(scope, cwd);
140
+ assertUnchangedState(file, expected);
141
+ safeResourceWrite(file, `${JSON.stringify(state, null, 2)}\n`, {
142
+ mode: 0o600,
143
+ beforeRename: () => assertUnchangedState(file, expected),
144
+ });
145
+ }
146
+
147
+ /** Reject redirects beneath the operator-selected config or project root. */
148
+ function assertManagedBase(scope: PluginScope, cwd: string): void {
149
+ const boundary = scope === "user" ? path.resolve(clioConfigDir()) : path.resolve(cwd);
150
+ const base = pluginBaseDir(scope, cwd);
151
+ let cursor = boundary;
152
+ for (const part of path.relative(boundary, base).split(path.sep)) {
153
+ cursor = path.join(cursor, part);
154
+ try {
155
+ const stat = lstatSync(cursor);
156
+ if (stat.isSymbolicLink() || !stat.isDirectory())
157
+ throw new Error(`plugin managed path must be a directory without symbolic links: ${cursor}`);
158
+ } catch (error) {
159
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
160
+ }
161
+ }
162
+ }
163
+
164
+ /** A writer refusal with a machine-readable reason; the message is what operators see. */
165
+ export class PluginWriterRefusal extends Error {
166
+ constructor(
167
+ readonly code: PluginDiagnosticCode,
168
+ message: string,
169
+ readonly changed?: {
170
+ scope: PluginScope;
171
+ id: string;
172
+ fact: keyof PluginExpectedCopy;
173
+ expected: unknown;
174
+ observed: unknown;
175
+ },
176
+ ) {
177
+ super(message);
178
+ this.name = "PluginWriterRefusal";
179
+ }
180
+ }
181
+
182
+ function acquireScopeLock(scope: PluginScope, cwd: string): () => void {
183
+ assertManagedBase(scope, cwd);
184
+ mkdirSync(pluginBaseDir(scope, cwd), { recursive: true });
185
+ const lock = path.join(pluginBaseDir(scope, cwd), ".mutation.lock");
186
+ let fd: number;
187
+ try {
188
+ fd = openSync(lock, "wx", 0o600);
189
+ } catch (error) {
190
+ if ((error as NodeJS.ErrnoException).code === "EEXIST")
191
+ throw new PluginWriterRefusal("locked", "another plugin operation holds the installation lock");
192
+ throw error;
193
+ }
194
+ return () => {
195
+ closeSync(fd);
196
+ rmSync(lock, { force: true });
197
+ };
198
+ }
199
+
200
+ /**
201
+ * Hold one scope's cooperative `.mutation.lock` around `fn`. Non-blocking: a
202
+ * held lock throws a `locked` refusal immediately, so two holders can never
203
+ * deadlock. A composer that reviewed peer-scope facts holds the peer lock here
204
+ * and lets the writer take its own; the same scope must never be nested.
205
+ */
206
+ export function withPluginScopeLock<T>(scope: PluginScope, cwd: string, fn: () => T): T {
207
+ const release = acquireScopeLock(scope, cwd);
208
+ try {
209
+ return fn();
210
+ } finally {
211
+ release();
212
+ }
213
+ }
214
+
215
+ function withMutation(scope: PluginScope, cwd: string, work: () => PluginMutationResult): PluginMutationResult {
216
+ try {
217
+ return withPluginScopeLock(scope, cwd, work);
218
+ } catch (error) {
219
+ return {
220
+ diagnostics: [
221
+ {
222
+ type: "error",
223
+ message: error instanceof Error ? error.message : String(error),
224
+ ...(error instanceof PluginWriterRefusal ? { code: error.code } : {}),
225
+ ...(error instanceof PluginWriterRefusal && error.changed ? { changed: error.changed } : {}),
226
+ },
227
+ ],
228
+ };
229
+ }
230
+ }
231
+
232
+ /** Observe the facts a plan reviews for one copy. Throws when that scope's state cannot be read. */
233
+ export function observePluginCopy(scope: PluginScope, id: string, cwd: string): PluginExpectedCopy {
234
+ const saved = readState(scope, cwd).state.installed[id];
235
+ const target = path.join(pluginBaseDir(scope, cwd), id);
236
+ let tree: string = "absent";
237
+ if (existsSync(target)) {
238
+ try {
239
+ tree = pluginContentDigest(target);
240
+ } catch {
241
+ tree = "unreadable";
242
+ }
243
+ }
244
+ return {
245
+ scope,
246
+ id,
247
+ recorded: saved !== undefined,
248
+ tree,
249
+ enabled: !readState(scope, cwd).state.disabled.includes(id),
250
+ ...(saved ? { recordedDigest: saved.contentDigest } : {}),
251
+ ...(saved?.kind ? { kind: saved.kind } : {}),
252
+ ...(saved?.trust ? { trust: saved.trust } : {}),
253
+ ...(saved?.origin !== undefined ? { origin: saved.origin } : {}),
254
+ };
255
+ }
256
+
257
+ /**
258
+ * Recheck reviewed facts. Called inside the mutated scope's lock; peer-scope
259
+ * facts are only as protected as the lock the composer holds for that scope.
260
+ */
261
+ function assertExpectedState(expect: PluginExpectedState | undefined, cwd: string): void {
262
+ for (const expected of expect?.copies ?? []) {
263
+ let observed: PluginExpectedCopy;
264
+ try {
265
+ observed = observePluginCopy(expected.scope, expected.id, cwd);
266
+ } catch (error) {
267
+ throw new PluginWriterRefusal(
268
+ "stale_plan",
269
+ `reviewed state for ${expected.scope}:${expected.id} is no longer readable: ${error instanceof Error ? error.message : String(error)}; review a fresh plan`,
270
+ );
271
+ }
272
+ // A reviewed snapshot is complete: a fact that appears or disappears
273
+ // (absent origin becoming foreign, trust or kind recorded later) is a
274
+ // change, so compare the union of both key sets.
275
+ const facts = new Set(
276
+ expected.partial ? Object.keys(expected) : [...Object.keys(expected), ...Object.keys(observed)],
277
+ ) as Set<keyof PluginExpectedCopy>;
278
+ for (const fact of facts) {
279
+ if (fact === "scope" || fact === "id" || fact === "partial") continue;
280
+ const want = JSON.stringify(expected[fact] ?? null);
281
+ const have = JSON.stringify(observed[fact] ?? null);
282
+ if (want !== have)
283
+ throw new PluginWriterRefusal(
284
+ "stale_plan",
285
+ `reviewed ${fact} changed for ${expected.scope}:${expected.id} (expected ${want}, observed ${have}); review a fresh plan`,
286
+ { scope: expected.scope, id: expected.id, fact, expected: expected[fact], observed: observed[fact] },
287
+ );
288
+ }
289
+ }
290
+ }
291
+
292
+ /** The one precedence rule: valid, compatible copies compete and project wins. */
293
+ export function resolvePluginPrecedence(entries: InstalledPlugin[]): void {
294
+ for (const entry of entries) {
295
+ const winner = entries
296
+ .filter((peer) => peer.id === entry.id && peer.valid && peer.compatible)
297
+ .sort((a, b) => Number(a.scope === "project") - Number(b.scope === "project"))
298
+ .at(-1);
299
+ entry.effective = entry === winner;
300
+ entry.loadable = entry.valid && entry.compatible && entry.enabled && entry.effective;
301
+ delete entry.overriddenBy;
302
+ if (winner && winner !== entry) entry.overriddenBy = winner.scope;
303
+ }
304
+ }
305
+
306
+ export interface PluginDependentBreak {
307
+ ref: LibraryRequirementRef;
308
+ scope: PluginScope;
309
+ missing: LibraryRequirementRef[];
310
+ }
311
+
312
+ function unmetRequirementsOf(entry: InstalledPlugin, entries: ReadonlyArray<InstalledPlugin>): LibraryRequirementRef[] {
313
+ return (entry.manifest?.clio.requires ?? []).filter(
314
+ (requirement) => !entries.some((peer) => peer.loadable && `${peer.kind ?? "plugin"}:${peer.id}` === requirement),
315
+ );
316
+ }
317
+
318
+ /**
319
+ * Project the effective set after exactly one disable or removal and report
320
+ * enabled effective dependents that are satisfied now and would not be.
321
+ * Pre-existing breakage is listed separately and never refuses.
322
+ */
323
+ export function newlyBrokenDependents(
324
+ entries: ReadonlyArray<InstalledPlugin>,
325
+ mutation: { scope: PluginScope; id: string; operation: "disable" | "remove" },
326
+ ): { newlyBroken: PluginDependentBreak[]; preexisting: PluginDependentBreak[]; effectiveAfter?: InstalledPlugin } {
327
+ const before = entries.map((entry) => ({ ...entry }));
328
+ resolvePluginPrecedence(before);
329
+ const after = before
330
+ .filter((entry) => !(mutation.operation === "remove" && entry.id === mutation.id && entry.scope === mutation.scope))
331
+ .map((entry) => ({
332
+ ...entry,
333
+ enabled:
334
+ mutation.operation === "disable" && entry.id === mutation.id && entry.scope === mutation.scope
335
+ ? false
336
+ : entry.enabled,
337
+ }));
338
+ resolvePluginPrecedence(after);
339
+ const newlyBroken: PluginDependentBreak[] = [];
340
+ const preexisting: PluginDependentBreak[] = [];
341
+ for (const entry of before) {
342
+ if (entry.id === mutation.id && entry.scope === mutation.scope) continue;
343
+ const later = after.find((peer) => peer.id === entry.id && peer.scope === entry.scope);
344
+ if (!later?.loadable) continue;
345
+ const missingBefore = entry.loadable ? unmetRequirementsOf(entry, before) : [];
346
+ const missingAfter = unmetRequirementsOf(later, after);
347
+ const ref: LibraryRequirementRef = `${entry.kind ?? "plugin"}:${entry.id}`;
348
+ const fresh = missingAfter.filter((requirement) => !missingBefore.includes(requirement));
349
+ if (fresh.length) newlyBroken.push({ ref, scope: entry.scope, missing: fresh });
350
+ else if (missingAfter.length) preexisting.push({ ref, scope: entry.scope, missing: missingAfter });
351
+ }
352
+ const effectiveAfter = after.find((entry) => entry.id === mutation.id && entry.effective);
353
+ return { newlyBroken, preexisting, ...(effectiveAfter ? { effectiveAfter } : {}) };
354
+ }
355
+
356
+ function refuseBrokenDependents(
357
+ cwd: string,
358
+ mutation: { scope: PluginScope; id: string; operation: "disable" | "remove" },
359
+ ): void {
360
+ const { newlyBroken } = newlyBrokenDependents(listInstalledPlugins(cwd, { all: true }), mutation);
361
+ if (newlyBroken.length)
362
+ throw new PluginWriterRefusal(
363
+ "dependents",
364
+ `${mutation.operation} of ${mutation.scope}:${mutation.id} would break ${newlyBroken
365
+ .map((item) => `${item.scope}:${item.ref} (missing ${item.missing.join(", ")})`)
366
+ .join("; ")}; disable or remove those dependents first`,
367
+ );
368
+ }
369
+
370
+ function scopeEntries(scope: PluginScope, cwd: string): InstalledPlugin[] {
371
+ const base = pluginBaseDir(scope, cwd);
372
+ if (!existsSync(base)) return [];
373
+ let names: string[];
374
+ try {
375
+ assertManagedBase(scope, cwd);
376
+ names = readdirSync(base).sort().filter(isPluginId);
377
+ } catch (error) {
378
+ return [
379
+ {
380
+ id: `invalid-${scope}-plugin-root`,
381
+ name: "Plugin installation directory",
382
+ version: "0.0.0",
383
+ description: "",
384
+ scope,
385
+ rootPath: base,
386
+ manifestPath: pluginStatePath(scope, cwd),
387
+ enabled: false,
388
+ valid: false,
389
+ compatible: true,
390
+ effective: false,
391
+ loadable: false,
392
+ resources: {},
393
+ diagnostics: [
394
+ {
395
+ type: "error",
396
+ message: `plugin directory cannot be read: ${error instanceof Error ? error.message : String(error)}`,
397
+ path: base,
398
+ },
399
+ ],
400
+ },
401
+ ];
402
+ }
403
+ let state: PluginState = { version: 1, disabled: [], installed: {} };
404
+ let stateError: string | undefined;
405
+ try {
406
+ assertManagedBase(scope, cwd);
407
+ state = readState(scope, cwd).state;
408
+ } catch (error) {
409
+ stateError = error instanceof Error ? error.message : String(error);
410
+ }
411
+ const entries: InstalledPlugin[] = [];
412
+ for (const id of names) {
413
+ const rootPath = path.join(base, id);
414
+ const candidate = readPluginManifest(rootPath);
415
+ const manifest = candidate.manifest;
416
+ const diagnostics = [...candidate.diagnostics];
417
+ const saved = state.installed[id];
418
+ if (manifest && manifest.name !== id)
419
+ diagnostics.push({
420
+ type: "error",
421
+ message: `installed directory ${id} does not match plugin identity ${manifest.name}`,
422
+ path: rootPath,
423
+ });
424
+ if (stateError)
425
+ diagnostics.push({
426
+ type: "error",
427
+ message: `plugin install state cannot be read: ${stateError}`,
428
+ path: pluginStatePath(scope, cwd),
429
+ });
430
+ else if (!saved)
431
+ diagnostics.push({
432
+ type: "error",
433
+ message: "plugin is not recorded in install state; install it through plugins install",
434
+ path: rootPath,
435
+ });
436
+ else if (candidate.contentDigest !== saved.contentDigest)
437
+ diagnostics.push({
438
+ type: "error",
439
+ message: `installed plugin content drift detected (expected ${saved.contentDigest}, observed ${candidate.contentDigest ?? "unreadable"})`,
440
+ path: rootPath,
441
+ });
442
+ const range = manifest?.clio.compatibility?.clio;
443
+ const compatible = range === undefined || evaluateClioCompatibility(range).satisfied;
444
+ if (!compatible)
445
+ diagnostics.push({
446
+ type: "error",
447
+ message: `plugin requires Clio ${range}`,
448
+ path: candidate.manifestPath ?? rootPath,
449
+ });
450
+ const valid =
451
+ candidate.valid &&
452
+ !stateError &&
453
+ !!saved &&
454
+ candidate.contentDigest === saved.contentDigest &&
455
+ manifest?.name === id;
456
+ entries.push({
457
+ id,
458
+ kind: saved?.kind ?? manifest?.clio.kind ?? "plugin",
459
+ trust: saved?.trust ?? (isForeignPluginOrigin(saved?.origin) ? "foreign" : "trusted"),
460
+ name: manifest?.name ?? id,
461
+ version: manifest?.version ?? "0.0.0",
462
+ description: manifest?.description ?? "",
463
+ scope,
464
+ rootPath,
465
+ manifestPath: candidate.manifestPath ?? path.join(rootPath, "plugin.json"),
466
+ enabled: !state.disabled.includes(id),
467
+ valid,
468
+ compatible,
469
+ effective: false,
470
+ loadable: false,
471
+ resources: manifest?.clio.resources ?? {},
472
+ ...(manifest ? { manifest } : {}),
473
+ diagnostics,
474
+ ...(candidate.contentDigest ? { observedContentDigest: candidate.contentDigest } : {}),
475
+ ...(valid && candidate.manifestDigest && saved
476
+ ? {
477
+ provenance: {
478
+ id,
479
+ scope,
480
+ sourcePath: saved.source,
481
+ canonicalRoot: realpathSync(rootPath),
482
+ manifestDigest: candidate.manifestDigest,
483
+ contentDigest: saved.contentDigest,
484
+ },
485
+ }
486
+ : {}),
487
+ });
488
+ }
489
+ return entries;
490
+ }
491
+
492
+ export function listInstalledPlugins(cwd = process.cwd(), options: PluginListOptions = {}): InstalledPlugin[] {
493
+ const scopes: PluginScope[] = options.scope ? [options.scope] : ["user", "project"];
494
+ const entries = scopes.flatMap((scope) => scopeEntries(scope, cwd));
495
+ resolvePluginPrecedence(entries);
496
+ return entries
497
+ .filter((entry) => options.all || entry.effective || !entry.valid || !entry.compatible)
498
+ .sort((a, b) => a.id.localeCompare(b.id) || a.scope.localeCompare(b.scope));
499
+ }
500
+
501
+ export function readPluginInstallRecord(id: string, options: PluginListOptions = {}): PluginInstallRecord | undefined {
502
+ if (!isPluginId(id)) return undefined;
503
+ const cwd = options.cwd ?? process.cwd();
504
+ if (options.scope) return readState(options.scope, cwd).state.installed[id];
505
+ return readState("project", cwd).state.installed[id] ?? readState("user", cwd).state.installed[id];
506
+ }
507
+
508
+ function selectedScope(id: string, options: PluginListOptions): PluginScope {
509
+ if (options.scope) return options.scope;
510
+ return existsSync(path.join(pluginBaseDir("project", options.cwd), id)) ? "project" : "user";
511
+ }
512
+
513
+ function uniqueSibling(target: string, purpose: string): string {
514
+ return path.join(
515
+ path.dirname(target),
516
+ `.${path.basename(target)}.${purpose}-${process.pid}-${randomBytes(8).toString("hex")}`,
517
+ );
518
+ }
519
+
520
+ /** Recheck held bytes after publication so edits made during staging survive. */
521
+ function retainRecovery(backup: string, expectedDigest: string | undefined): boolean {
522
+ try {
523
+ if (!expectedDigest || pluginContentDigest(backup) !== expectedDigest) return true;
524
+ rmSync(backup, { recursive: true, force: true });
525
+ return false;
526
+ } catch {
527
+ // Cleanup failure does not undo a committed lifecycle operation.
528
+ return true;
529
+ }
530
+ }
531
+
532
+ export function installPlugin(sourcePath: string, options: PluginInstallOptions = {}): PluginMutationResult {
533
+ const cwd = options.cwd ?? process.cwd();
534
+ const scope = options.scope ?? "user";
535
+ const source = path.resolve(cwd, sourcePath);
536
+ const candidate = readPluginManifest(source);
537
+ if (!candidate.valid || !candidate.manifest || !candidate.contentDigest) return { diagnostics: candidate.diagnostics };
538
+ const manifest = candidate.manifest;
539
+ const digest = candidate.contentDigest;
540
+ const range = manifest.clio.compatibility?.clio;
541
+ if (range && !evaluateClioCompatibility(range).satisfied)
542
+ return { diagnostics: [{ type: "error", message: `plugin requires Clio ${range}` }] };
543
+ if (
544
+ (options.expectedKind !== undefined && options.expectedKind !== (manifest.clio.kind ?? "plugin")) ||
545
+ (options.expectedDigest !== undefined && options.expectedDigest !== digest) ||
546
+ (options.expectedId !== undefined && options.expectedId !== manifest.name) ||
547
+ (options.expectedVersion !== undefined && options.expectedVersion !== manifest.version)
548
+ )
549
+ return {
550
+ diagnostics: [{ type: "error", message: "plugin source does not match the pinned digest, identity, or version" }],
551
+ };
552
+ const target = path.join(pluginBaseDir(scope, cwd), manifest.name);
553
+ const resolvedBase = pluginBaseDir(scope, cwd);
554
+ // Copying a source into its own descendant grows recursively; replacing an
555
+ // ancestor would erase the source. Neither is a meaningful install.
556
+ if (
557
+ pluginPathContained(canonicalizeExistingPath(source), canonicalizeExistingPath(resolvedBase)) ||
558
+ pluginPathContained(canonicalizeExistingPath(target), canonicalizeExistingPath(source))
559
+ )
560
+ return { diagnostics: [{ type: "error", message: "plugin source overlaps its managed installation destination" }] };
561
+ return withMutation(scope, cwd, () => {
562
+ const { state, bytes } = readState(scope, cwd);
563
+ assertExpectedState(options.expect, cwd);
564
+ const previouslyInstalled = Object.hasOwn(state.installed, manifest.name);
565
+ const previousDigest = state.installed[manifest.name]?.contentDigest;
566
+ const previousOrigin = state.installed[manifest.name]?.origin;
567
+ if (isForeignPluginOrigin(previousOrigin))
568
+ throw new Error("interop packages require a new reviewed adoption; remove the installed copy and adopt it again");
569
+ const previousKind = state.installed[manifest.name]?.kind ?? readPluginManifest(target).manifest?.clio.kind;
570
+ if (previousKind && previousKind !== (manifest.clio.kind ?? "plugin"))
571
+ throw new Error("package kind cannot change during replacement; remove it explicitly first");
572
+ if (existsSync(target) && !options.force)
573
+ throw new Error(`plugin ${manifest.name} is already installed; use --force to replace it`);
574
+ if (existsSync(target) && lstatSync(target).isSymbolicLink())
575
+ throw new Error("installed plugin root must not be a symbolic link");
576
+ const staging = uniqueSibling(target, "install");
577
+ const backup = uniqueSibling(target, "backup");
578
+ let moved = false;
579
+ let published = false;
580
+ let preserveBackup = false;
581
+ if (existsSync(target)) {
582
+ try {
583
+ preserveBackup = pluginContentDigest(target) !== state.installed[manifest.name]?.contentDigest;
584
+ } catch {
585
+ preserveBackup = true;
586
+ }
587
+ }
588
+ try {
589
+ cpSync(source, staging, { recursive: true, verbatimSymlinks: true, errorOnExist: true, force: false });
590
+ const staged = readPluginManifest(staging);
591
+ if (!staged.valid || staged.manifest?.name !== manifest.name || staged.contentDigest !== digest)
592
+ throw new Error("staged plugin differs from the verified source tree");
593
+ if (pluginContentDigest(source) !== digest) throw new Error("plugin source changed while staging");
594
+ assertUnchangedState(pluginStatePath(scope, cwd), bytes);
595
+ if (existsSync(target)) {
596
+ renameSync(target, backup);
597
+ moved = true;
598
+ }
599
+ renameSync(staging, target);
600
+ published = true;
601
+ if (pluginContentDigest(target) !== digest) throw new Error("plugin changed during publication");
602
+ const origin = options.origin ?? { kind: "local" as const, source };
603
+ const trust = isForeignPluginOrigin(origin)
604
+ ? "foreign"
605
+ : (options.trust ?? state.installed[manifest.name]?.trust ?? "trusted");
606
+ state.installed[manifest.name] = {
607
+ kind: manifest.clio.kind ?? "plugin",
608
+ installedAt: new Date().toISOString(),
609
+ source: typeof origin === "string" ? origin : origin.source,
610
+ origin,
611
+ contentDigest: digest,
612
+ trust,
613
+ };
614
+ if (!previouslyInstalled) state.disabled = state.disabled.filter((id) => id !== manifest.name);
615
+ writeState(scope, cwd, state, bytes);
616
+ } catch (error) {
617
+ rmSync(staging, { recursive: true, force: true });
618
+ if (published && existsSync(target)) {
619
+ // Preserve concurrent changes instead of deleting someone else's work.
620
+ let unchanged = false;
621
+ try {
622
+ unchanged = pluginContentDigest(target) === digest;
623
+ } catch {
624
+ /* Preserve unreadable replacement. */
625
+ }
626
+ if (!unchanged)
627
+ return {
628
+ recovery: { ...(moved ? { packageBackup: backup } : {}) },
629
+ diagnostics: [
630
+ {
631
+ type: "error",
632
+ message: `plugin installation failed and changed content was preserved: ${String(error)}`,
633
+ path: target,
634
+ },
635
+ ],
636
+ };
637
+ rmSync(target, { recursive: true, force: true });
638
+ }
639
+ if (moved) renameSync(backup, target);
640
+ throw error;
641
+ }
642
+ if (moved && !preserveBackup) preserveBackup = retainRecovery(backup, previousDigest);
643
+ const plugin = listInstalledPlugins(cwd, { scope, all: true }).find((entry) => entry.id === manifest.name);
644
+ return {
645
+ ...(plugin ? { plugin } : {}),
646
+ ...(moved && preserveBackup ? { recovery: { packageBackup: backup } } : {}),
647
+ diagnostics: plugin?.diagnostics ?? [],
648
+ };
649
+ });
650
+ }
651
+
652
+ export function updatePlugin(id: string, options: PluginInstallOptions = {}): PluginMutationResult {
653
+ if (!isPluginId(id)) return { diagnostics: [{ type: "error", message: "invalid plugin id" }] };
654
+ try {
655
+ const scope = selectedScope(id, options);
656
+ const installed = readPluginInstallRecord(id, { ...options, scope });
657
+ if (!installed) throw new Error(`plugin ${id} is not installed`);
658
+ if (isForeignPluginOrigin(installed.origin))
659
+ throw new Error("interop packages require a new reviewed adoption; remove the installed copy and adopt it again");
660
+ const current = listInstalledPlugins(options.cwd ?? process.cwd(), { scope, all: true }).find(
661
+ (entry) => entry.id === id,
662
+ );
663
+ if (!options.force && !current?.valid)
664
+ throw new Error(
665
+ `plugin ${id} has changed or unverifiable content; use --force to preserve a recovery copy and replace it`,
666
+ );
667
+ if (/^[a-z][a-z0-9+.-]*:\/\//iu.test(installed.source))
668
+ throw new Error("remote plugin updates must resolve a verified library catalog source");
669
+ return installPlugin(installed.source, {
670
+ ...options,
671
+ scope,
672
+ force: true,
673
+ expectedId: id,
674
+ origin: installed.origin ?? installed.source,
675
+ });
676
+ } catch (error) {
677
+ return { diagnostics: [{ type: "error", message: error instanceof Error ? error.message : String(error) }] };
678
+ }
679
+ }
680
+
681
+ function setEnabled(id: string, enabled: boolean, options: PluginMutationOptions): PluginMutationResult {
682
+ if (!isPluginId(id)) return { diagnostics: [{ type: "error", message: "invalid plugin id" }] };
683
+ const cwd = options.cwd ?? process.cwd();
684
+ const scope = selectedScope(id, options);
685
+ return withMutation(scope, cwd, () => {
686
+ const { state, bytes } = readState(scope, cwd);
687
+ assertExpectedState(options.expect, cwd);
688
+ const plugin = listInstalledPlugins(cwd, { scope, all: true }).find((entry) => entry.id === id);
689
+ if (!plugin) throw new Error(`plugin ${id} is not installed`);
690
+ if (enabled && (!plugin.valid || !plugin.compatible))
691
+ throw new Error(`plugin ${id} cannot be enabled: ${plugin.diagnostics.map((entry) => entry.message).join("; ")}`);
692
+ if (!enabled && plugin.enabled) refuseBrokenDependents(cwd, { scope, id, operation: "disable" });
693
+ state.disabled = state.disabled.filter((value) => value !== id);
694
+ if (!enabled) state.disabled.push(id);
695
+ writeState(scope, cwd, state, bytes);
696
+ const updated = listInstalledPlugins(cwd, { scope, all: true }).find((entry) => entry.id === id);
697
+ return { ...(updated ? { plugin: updated } : {}), diagnostics: [] };
698
+ });
699
+ }
700
+
701
+ export function enablePlugin(id: string, options: PluginMutationOptions = {}): PluginMutationResult {
702
+ return setEnabled(id, true, options);
703
+ }
704
+ export function disablePlugin(id: string, options: PluginMutationOptions = {}): PluginMutationResult {
705
+ return setEnabled(id, false, options);
706
+ }
707
+
708
+ export function removePlugin(id: string, options: PluginMutationOptions = {}): PluginMutationResult {
709
+ if (!isPluginId(id)) return { diagnostics: [{ type: "error", message: "invalid plugin id" }] };
710
+ const cwd = options.cwd ?? process.cwd();
711
+ const scope = selectedScope(id, options);
712
+ return withMutation(scope, cwd, () => {
713
+ const { state, bytes } = readState(scope, cwd);
714
+ assertExpectedState(options.expect, cwd);
715
+ const target = path.join(pluginBaseDir(scope, cwd), id);
716
+ const previousDigest = state.installed[id]?.contentDigest;
717
+ if (!existsSync(target) && !state.installed[id]) throw new Error(`plugin ${id} is not installed`);
718
+ refuseBrokenDependents(cwd, { scope, id, operation: "remove" });
719
+ const backup = uniqueSibling(target, "removed");
720
+ const moved = existsSync(target);
721
+ let preserve = false;
722
+ if (moved) {
723
+ try {
724
+ preserve = pluginContentDigest(target) !== state.installed[id]?.contentDigest;
725
+ } catch {
726
+ preserve = true;
727
+ }
728
+ renameSync(target, backup);
729
+ }
730
+ try {
731
+ delete state.installed[id];
732
+ state.disabled = state.disabled.filter((value) => value !== id);
733
+ writeState(scope, cwd, state, bytes);
734
+ } catch (error) {
735
+ if (moved) renameSync(backup, target);
736
+ throw error;
737
+ }
738
+ if (moved && !preserve) preserve = retainRecovery(backup, previousDigest);
739
+ return {
740
+ removed: { id, scope, path: target },
741
+ ...(preserve ? { recovery: { packageBackup: backup } } : {}),
742
+ diagnostics: preserve
743
+ ? [
744
+ {
745
+ type: "warning",
746
+ message: "removed plugin contained changed or unverified files; preserved recovery copy",
747
+ path: backup,
748
+ },
749
+ ]
750
+ : [],
751
+ };
752
+ });
753
+ }