@iowarp/clio-coder 0.4.5 → 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 (700) hide show
  1. package/.claude-plugin/marketplace.json +283 -0
  2. package/CHANGELOG.md +74 -0
  3. package/CONTRIBUTING.md +116 -38
  4. package/NOTICE +24 -0
  5. package/README.md +341 -682
  6. package/dist/{acp-H3CU2HBQ.js → acp-W3Y3TRHD.js} +12 -12
  7. package/dist/{agents-IXQQZ7BD.js → agents-J4ICNLQ3.js} +57 -56
  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-R7KYF7N3.js → auth-X2UJUMOC.js} +25 -25
  13. package/dist/{builtins-CRFDQUVP.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-SE4ZKILO.js → chunk-3XE4NRLF.js} +30 -9
  20. package/dist/{chunk-YYB3MC65.js → chunk-4MFBBY2Z.js} +3 -3
  21. package/dist/{chunk-5VTJP36Q.js → chunk-4N2RZ4TO.js} +2 -2
  22. package/dist/{chunk-FKIOX6DS.js → chunk-4QKAITQT.js} +10 -5
  23. package/dist/chunk-4UHVS5T7.js +207 -0
  24. package/dist/{chunk-VLPTKCKT.js → chunk-5AJPUR72.js} +6 -6
  25. package/dist/{chunk-5CY4Q6QI.js → chunk-5EQO5NWP.js} +105 -3
  26. package/dist/{chunk-RXIOCVBZ.js → chunk-65BGHOUR.js} +8 -5
  27. package/dist/{chunk-T53XI6I7.js → chunk-6CA2BHOR.js} +2 -2
  28. package/dist/{chunk-HL26ADLH.js → chunk-6CB2IL4N.js} +2 -1
  29. package/dist/{chunk-HR3HPQ76.js → chunk-6LRLOJHQ.js} +3 -3
  30. package/dist/{chunk-HXHFDHB6.js → chunk-6TAATXXH.js} +6 -6
  31. package/dist/{chunk-WFKDPU7U.js → chunk-6YHPAAZR.js} +3 -3
  32. package/dist/{chunk-ZMZQEBKI.js → chunk-7EEGBKV4.js} +11 -11
  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-MDU3C27C.js → chunk-BO4XV5VX.js} +8 -8
  36. package/dist/{chunk-KF6GFW6O.js → chunk-BQQ5MXUC.js} +11 -11
  37. package/dist/{chunk-K6RDB7IA.js → chunk-C3G5PNUO.js} +23 -23
  38. package/dist/{chunk-SRZOW5L2.js → chunk-C6GEXX4L.js} +1 -1
  39. package/dist/{chunk-U2JOLB7O.js → chunk-CE64C5K5.js} +227 -72
  40. package/dist/chunk-CP3HIR5H.js +2119 -0
  41. package/dist/{chunk-BBV5TKE6.js → chunk-CPXGJI2A.js} +2 -2
  42. package/dist/{chunk-5DDOTTG4.js → chunk-CULVKYTK.js} +5 -5
  43. package/dist/{chunk-F34AR6O3.js → chunk-D2T66PDV.js} +6 -6
  44. package/dist/{chunk-NF3BK5WR.js → chunk-DACXIVVF.js} +5 -5
  45. package/dist/{chunk-4SVIVOMC.js → chunk-DLIYANB7.js} +20 -15
  46. package/dist/{chunk-E3BQTQUP.js → chunk-DO7M3LSX.js} +9 -9
  47. package/dist/{chunk-2QPI3TR3.js → chunk-DVJL77SO.js} +2 -2
  48. package/dist/chunk-EM2WNQS2.js +93 -0
  49. package/dist/{chunk-ODUTYZIU.js → chunk-EUEXGXXR.js} +5 -5
  50. package/dist/{chunk-UL36QJX6.js → chunk-EUZRMP4Y.js} +18 -16
  51. package/dist/{chunk-R6MAYTMS.js → chunk-G4LGUTOE.js} +4 -4
  52. package/dist/{chunk-CBSKDFWL.js → chunk-GEVQNST4.js} +2 -2
  53. package/dist/{chunk-XXBQKW32.js → chunk-GFQ7P2UF.js} +7 -7
  54. package/dist/{chunk-SBZX6ARC.js → chunk-GI5RRMAH.js} +14 -14
  55. package/dist/{chunk-KDWLXVMN.js → chunk-GVZFCJHE.js} +343 -113
  56. package/dist/{chunk-633EXGZA.js → chunk-GXIWHXDB.js} +3 -3
  57. package/dist/{chunk-LUL5Z66S.js → chunk-HOX4YZ2K.js} +6 -5
  58. package/dist/chunk-HRAKUPIH.js +57 -0
  59. package/dist/{chunk-KYKNBD4Y.js → chunk-IJMW64DX.js} +978 -258
  60. package/dist/{chunk-DIMRLNIC.js → chunk-IMOD2YPV.js} +16 -9
  61. package/dist/{chunk-6CDNRHWH.js → chunk-IQCNVLO6.js} +28 -8
  62. package/dist/{chunk-UTUNT5QL.js → chunk-ISNCCX42.js} +9 -9
  63. package/dist/{chunk-RLTT5GVY.js → chunk-IZYTT3CD.js} +9 -5
  64. package/dist/{chunk-5ZMXGW7P.js → chunk-KAFMW7WM.js} +4 -85
  65. package/dist/chunk-KKEYGFX4.js +915 -0
  66. package/dist/{chunk-HHVJNVUJ.js → chunk-KS7ETA3P.js} +2 -2
  67. package/dist/{chunk-UXAC2FX4.js → chunk-L3Z5ANCV.js} +7 -7
  68. package/dist/{chunk-EHCPSZJF.js → chunk-LBFQMYS3.js} +2 -2
  69. package/dist/{chunk-QEQISF75.js → chunk-LK2FN5JY.js} +1 -1
  70. package/dist/{chunk-URBGEOH3.js → chunk-M6Z2V6YU.js} +5 -5
  71. package/dist/{chunk-DRD2A54W.js → chunk-MBJO5VNZ.js} +18 -18
  72. package/dist/chunk-MNQN3X6Y.js +595 -0
  73. package/dist/{chunk-GXCCHKN6.js → chunk-MZHXENL7.js} +7 -7
  74. package/dist/chunk-MZNWZUJM.js +1801 -0
  75. package/dist/{chunk-7YJWEF2L.js → chunk-N37QC5FV.js} +5 -5
  76. package/dist/{chunk-WLMSOT73.js → chunk-NCCQ6DVS.js} +7 -7
  77. package/dist/{chunk-TZ7MFRG4.js → chunk-NO7J45X6.js} +170 -53
  78. package/dist/chunk-OH3YYA3B.js +15 -0
  79. package/dist/{chunk-22PQ4TX4.js → chunk-P4DL2LM5.js} +16 -77
  80. package/dist/{chunk-R6MICQYU.js → chunk-PFLOULP3.js} +4 -4
  81. package/dist/{chunk-MC3JSVR6.js → chunk-QJMRYTCX.js} +7 -7
  82. package/dist/{chunk-ILJ7DWGE.js → chunk-QKWL7SYE.js} +12 -12
  83. package/dist/chunk-R2CT5YDO.js +66 -0
  84. package/dist/chunk-RFCKPS2V.js +26 -0
  85. package/dist/{chunk-ONRTXOZY.js → chunk-RTLNFZMD.js} +12 -4
  86. package/dist/{chunk-U7H5WRG5.js → chunk-RXFPB32E.js} +8 -6
  87. package/dist/{chunk-S32UQ5GL.js → chunk-SEDI5K5B.js} +18 -18
  88. package/dist/{chunk-ICO4TQ2F.js → chunk-SELG4SUR.js} +41 -25
  89. package/dist/{chunk-YEJIG7LN.js → chunk-SER7RRAE.js} +27 -832
  90. package/dist/{chunk-K2HL3GBL.js → chunk-T4TY5GG3.js} +165 -15
  91. package/dist/chunk-T7QQBNLH.js +691 -0
  92. package/dist/{chunk-HGSLRG33.js → chunk-TLTGZTXI.js} +3 -3
  93. package/dist/chunk-TZ6UVP2H.js +637 -0
  94. package/dist/{chunk-EWD5P3GK.js → chunk-TZHN5ITX.js} +13 -41
  95. package/dist/{chunk-7TKWWPD7.js → chunk-U3TPUXOQ.js} +398 -253
  96. package/dist/{chunk-GNQRWTMY.js → chunk-UA3W4FGC.js} +6 -6
  97. package/dist/{chunk-O2RQ7LCK.js → chunk-UA6W4XFJ.js} +2 -2
  98. package/dist/chunk-UWD3JD5X.js +709 -0
  99. package/dist/chunk-V4ZKOKRB.js +13433 -0
  100. package/dist/{chunk-NC4KV7EL.js → chunk-VCRVEDUC.js} +5 -5
  101. package/dist/{chunk-I7VLWRK2.js → chunk-VMATUZB6.js} +12 -10
  102. package/dist/{chunk-J2FYEQ5L.js → chunk-VTYHHQ57.js} +2 -2
  103. package/dist/chunk-WB7POC6M.js +891 -0
  104. package/dist/{chunk-GVYWZNRK.js → chunk-WBVKKTUT.js} +2 -2
  105. package/dist/{chunk-EHOSNVVM.js → chunk-WLHX3MM5.js} +6 -2
  106. package/dist/{chunk-SDWNDICN.js → chunk-WN552PKN.js} +573 -316
  107. package/dist/{chunk-TEG3RYVZ.js → chunk-WT5TRMO4.js} +51 -26
  108. package/dist/{chunk-NY6IWDVU.js → chunk-WURGVOZJ.js} +56 -12
  109. package/dist/{chunk-7WUZEB2M.js → chunk-XR3XJN2M.js} +2 -2
  110. package/dist/chunk-XW2UZICE.js +372 -0
  111. package/dist/{chunk-FSTIBAGM.js → chunk-XZ6UFQ52.js} +11 -11
  112. package/dist/chunk-Y3JU5RPK.js +8 -0
  113. package/dist/chunk-YKRJTYNP.js +1143 -0
  114. package/dist/{chunk-7HBHHVCK.js → chunk-YPRSNUTC.js} +2 -2
  115. package/dist/{chunk-PWWSIB2A.js → chunk-ZGIGW4ZG.js} +5 -5
  116. package/dist/cli/index.js +34 -36
  117. package/dist/{clio-5I2IBFYL.js → clio-L2P7S2R2.js} +9 -9
  118. package/dist/{code-nav-YXIAEZVS.js → code-nav-B5LNX4KU.js} +25 -25
  119. package/dist/{components-TNIKXCBH.js → components-63MMQKUT.js} +6 -6
  120. package/dist/{config-Y2JDJ3JJ.js → config-YXARKGTX.js} +81 -77
  121. package/dist/configure-LMVQJ46J.js +85 -0
  122. package/dist/{context-QQ53HSGJ.js → context-7HJEWTTP.js} +92 -48
  123. package/dist/{context-S2EEC3EJ.js → context-XSZKKFBW.js} +14 -14
  124. package/dist/{context-P5YSEO55.js → context-YG2LZDYZ.js} +67 -64
  125. package/dist/{context-clear-TMEQCOTH.js → context-clear-AC5NXHM2.js} +64 -61
  126. package/dist/{context-index-HP2JFUWA.js → context-index-KKTPRV5G.js} +3 -3
  127. package/dist/{context-map-INTXD54D.js → context-map-T7ROR5D5.js} +4 -4
  128. package/dist/{context-working-set-CNLSQN5K.js → context-working-set-F4Q4J3NS.js} +15 -12
  129. package/dist/{detail-5572VLBO.js → detail-H73BEF2N.js} +65 -62
  130. package/dist/{dispatch-runner-FRHD6P2O.js → dispatch-runner-3RY5FSJC.js} +83 -80
  131. package/dist/{doctor-N3LCM2LG.js → doctor-EQYJOGUG.js} +47 -32
  132. package/dist/{eval-BUU3ZOUZ.js → eval-4P7O6CCE.js} +114 -50
  133. package/dist/{evidence-DTGEN456.js → evidence-D6GUSYJW.js} +64 -61
  134. package/dist/{evidence-SQ5DNFEN.js → evidence-O76QF7TZ.js} +69 -65
  135. package/dist/{evolve-IJNUFZDS.js → evolve-H47BCETS.js} +65 -62
  136. package/dist/{extensions-YVRHX6ZI.js → extensions-NNL3ZOCU.js} +98 -20
  137. package/dist/{fleet-ZNNVSYFO.js → fleet-KMNS6NOM.js} +115 -107
  138. package/dist/{fleet-commands-5YE7NPJL.js → fleet-commands-DOWSYCBX.js} +15 -15
  139. package/dist/{fleet-decisions-3SBSCTCW.js → fleet-decisions-S3PTZV2D.js} +9 -9
  140. package/dist/{fleet-graph-6HHPWF5T.js → fleet-graph-F2DE2TME.js} +26 -24
  141. package/dist/{fleet-inspect-JEYMGCGC.js → fleet-inspect-EN2Q6IVB.js} +67 -63
  142. package/dist/{fleet-preflight-QRSHIIDE.js → fleet-preflight-FRLETDD3.js} +3 -3
  143. package/dist/{fleet-validate-4PM4GDDL.js → fleet-validate-B2XDLS57.js} +28 -29
  144. package/dist/{fleet-verify-NJDTHTO3.js → fleet-verify-4JKUWGJ7.js} +64 -61
  145. package/dist/{fleet-view-UP2BWQQY.js → fleet-view-BHJFW26B.js} +67 -63
  146. package/dist/{init-S3GZQ5ZF.js → init-XAT5N5YM.js} +86 -80
  147. package/dist/interop-FVECHFKG.js +246 -0
  148. package/dist/{inventory-K2OZ36YJ.js → inventory-7KFQGLCV.js} +67 -63
  149. package/dist/library-NY2XOT75.js +492 -0
  150. package/dist/library-QAPAO23R.js +306 -0
  151. package/dist/library-import-5Y6MAS3R.js +183 -0
  152. package/dist/library-inventory-JT6HWITQ.js +56 -0
  153. package/dist/library-validation-EQUH25DC.js +42 -0
  154. package/dist/{memory-OQOXQGYD.js → memory-DYVTTCP6.js} +65 -62
  155. package/dist/{models-3IK2Y5WE.js → models-MASFJ6Y2.js} +51 -38
  156. package/dist/{monitor-FTJLTKCQ.js → monitor-YMP4NXJJ.js} +73 -69
  157. package/dist/{orchestrator-N47O7SFD.js → orchestrator-AFQRRTEI.js} +4255 -2845
  158. package/dist/{panes-7BTYH3XQ.js → panes-D3Y2KFG5.js} +4 -4
  159. package/dist/{panes-WPOMEMRH.js → panes-NICTHQCV.js} +7 -7
  160. package/dist/{paths-J3KN7UAO.js → paths-PSFAUIGO.js} +5 -5
  161. package/dist/{preload-65U34NG6.js → preload-5Q7VXRFJ.js} +64 -61
  162. package/dist/{reset-MUVQDLNL.js → reset-7NKZK7JN.js} +11 -9
  163. package/dist/{resources-LM76COAO.js → resources-NILSIZAT.js} +94 -38
  164. package/dist/{run-3VFZQ33N.js → run-BPZGEBZV.js} +131 -114
  165. package/dist/{share-4JUB4BL7.js → share-EZ6ERBMH.js} +31 -28
  166. package/dist/skills-BTVVNYVM.js +100 -0
  167. package/dist/{skills-eval-G6T57L7M.js → skills-eval-UY34MNK7.js} +117 -78
  168. package/dist/{skills-inventory-WLM46PJH.js → skills-inventory-JDHSIA7I.js} +30 -25
  169. package/dist/{slash-commands-GBARG3Y7.js → slash-commands-K4FNQ2AT.js} +53 -49
  170. package/dist/{steer-S7D7IKPU.js → steer-2B3EQGFH.js} +4 -4
  171. package/dist/{support-5VAEC32W.js → support-L2SOL3IE.js} +7 -7
  172. package/dist/{targets-N5REUETU.js → targets-44VKGFLN.js} +69 -47
  173. package/dist/{tasks-6BVY5YZF.js → tasks-3KODKFU7.js} +14 -14
  174. package/dist/{terminal-lease-57UEOJKS.js → terminal-lease-LXA7MMPO.js} +32 -19
  175. package/dist/{tools-6OCQ6SVB.js → tools-3UB7TEVR.js} +7 -7
  176. package/dist/{trace-JHLXWUMN.js → trace-TAMIU4OJ.js} +5 -4
  177. package/dist/{tui-primitives-RCY2HN7G.js → tui-primitives-A6MUW32V.js} +3 -2
  178. package/dist/{uninstall-FXYMFFRT.js → uninstall-QYVRPEM4.js} +9 -9
  179. package/dist/{upgrade-4HD5HAIV.js → upgrade-7PMKM2JH.js} +17 -18
  180. package/dist/{usage-4GWM2WWP.js → usage-6EQV7EQK.js} +77 -73
  181. package/dist/{verifiers-GSKWKWVG.js → verifiers-JLITWSHU.js} +16 -16
  182. package/dist/{verify-3AS3ULCY.js → verify-T7NAEVIG.js} +13 -13
  183. package/dist/{web-fetch-MQN4FH3X.js → web-fetch-W4TNW4Q7.js} +4 -4
  184. package/dist/{wiki-generate-7BV7XWIY.js → wiki-generate-T2TJQJUA.js} +90 -84
  185. package/dist/{with-panes-OFTNAR4Y.js → with-panes-CHFC7HGI.js} +4 -4
  186. package/dist/worker/entry.js +297 -88
  187. package/docs/README.md +43 -0
  188. package/docs/architecture/architecture.md +8 -7
  189. package/docs/architecture/artifact-versions.md +3 -3
  190. package/docs/architecture/context-engine.md +36 -2
  191. package/docs/architecture/library.md +32 -0
  192. package/docs/architecture/middleware-and-components.md +1 -1
  193. package/docs/architecture/model-catalog.md +21 -1
  194. package/docs/architecture/pi-boundary.md +18 -0
  195. package/docs/architecture/prompt-envelope-and-tools.md +5 -5
  196. package/docs/architecture/safety-model.md +21 -2
  197. package/docs/architecture/session-lifecycle.md +12 -1
  198. package/docs/architecture/tui-design.md +153 -39
  199. package/docs/architecture/worker-context.md +106 -0
  200. package/docs/guide/authoring-plugins.md +160 -0
  201. package/docs/guide/built-in-agents.md +5 -5
  202. package/docs/guide/commands-and-modes.md +186 -80
  203. package/docs/guide/configuration-and-targets.md +123 -28
  204. package/docs/guide/configuration-reference.md +36 -38
  205. package/docs/guide/environment-variables.md +2 -2
  206. package/docs/guide/exit-codes-and-output.md +1 -1
  207. package/docs/guide/extensions-and-sharing.md +93 -53
  208. package/docs/guide/fleet-dispatch.md +32 -10
  209. package/docs/guide/glossary.md +2 -2
  210. package/docs/guide/harness-extensions.md +291 -0
  211. package/docs/guide/installation-and-lifecycle.md +53 -20
  212. package/docs/guide/interop.md +243 -0
  213. package/docs/guide/panes-and-files.md +3 -3
  214. package/docs/guide/plugins.md +80 -0
  215. package/docs/guide/resource-library.md +111 -45
  216. package/docs/guide/skills-marketplace.md +35 -72
  217. package/docs/guide/tool-usage.md +19 -7
  218. package/docs/guide/troubleshooting.md +1 -1
  219. package/docs/process/development-pipeline.md +15 -15
  220. package/docs/process/documentation-coverage.md +29 -2
  221. package/docs/process/documentation-guide.md +15 -7
  222. package/docs/process/eval-runner.md +8 -3
  223. package/docs/process/performance-methodology.md +1 -1
  224. package/docs/process/release-cut-checklist.md +22 -6
  225. package/docs/process/scientific-validation.md +23 -0
  226. package/evals/scalar-decision-machinery.ts +1 -1
  227. package/examples/extensions/README.md +67 -0
  228. package/examples/extensions/lab-status/clio-coder-extension.json +14 -0
  229. package/examples/extensions/lab-status/extension.mjs +68 -0
  230. package/examples/extensions/lab-status/jobs.synthetic.json +9 -0
  231. package/examples/extensions/measurements/clio-coder-extension.json +28 -0
  232. package/examples/extensions/measurements/summarize.cjs +23 -0
  233. package/library/README.md +109 -0
  234. package/library/_authoring/templates/agent/README.md +28 -0
  235. package/library/_authoring/templates/agent/agents/benchmark-scout.md +30 -0
  236. package/library/_authoring/templates/agent/plugin.json +23 -0
  237. package/library/_authoring/templates/fleet/README.md +29 -0
  238. package/library/_authoring/templates/fleet/fleets/pipeline-review.md +31 -0
  239. package/library/_authoring/templates/fleet/plugin.json +23 -0
  240. package/library/_authoring/templates/plugin/README.md +37 -0
  241. package/library/_authoring/templates/plugin/agents/data-curator.md +31 -0
  242. package/library/_authoring/templates/plugin/assets/curation-guide.md +22 -0
  243. package/library/_authoring/templates/plugin/plugin.json +42 -0
  244. package/library/_authoring/templates/plugin/prompts/inspect-dataset.md +15 -0
  245. package/library/_authoring/templates/plugin/skills/dataset-curation/SKILL.md +36 -0
  246. package/library/_authoring/templates/plugin/skills/dataset-curation/evals.md +17 -0
  247. package/library/_authoring/templates/prompt/README.md +28 -0
  248. package/library/_authoring/templates/prompt/plugin.json +23 -0
  249. package/library/_authoring/templates/prompt/prompts/paper-summary.md +26 -0
  250. package/library/_authoring/templates/skill/README.md +24 -0
  251. package/library/_authoring/templates/skill/SKILL.md +39 -0
  252. package/library/_authoring/templates/skill/evals.md +30 -0
  253. package/library/_authoring/templates/skill/plugin.json +23 -0
  254. package/library/agents/README.md +7 -0
  255. package/library/fleets/README.md +7 -0
  256. package/library/plugins/materio/README.md +137 -0
  257. package/library/plugins/materio/ai.iowarp.clio/agents/materio-lab-definer.md +208 -0
  258. package/library/plugins/materio/ai.iowarp.clio/agents/materio-literature-reviewer.md +308 -0
  259. package/library/plugins/materio/ai.iowarp.clio/agents/materio-research-explorer.md +249 -0
  260. package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-executor.md +416 -0
  261. package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-verifier.md +60 -0
  262. package/library/plugins/materio/ai.iowarp.clio/agents/materio-workflow-planner.md +238 -0
  263. package/library/plugins/materio/ai.iowarp.clio/fleets/materio-execute-task.md +50 -0
  264. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/add-task.md +66 -0
  265. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/archive-task.md +65 -0
  266. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/checkpoint.md +26 -0
  267. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-research-tasks.md +230 -0
  268. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-virtual-lab.md +181 -0
  269. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/execute-task.md +292 -0
  270. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/help.md +129 -0
  271. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/identify-research.md +206 -0
  272. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/literature-review.md +201 -0
  273. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/pause-research.md +12 -0
  274. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/progress.md +105 -0
  275. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/remove-task.md +63 -0
  276. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/resume-research.md +64 -0
  277. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/settings.md +16 -0
  278. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/status.md +92 -0
  279. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/upload-data.md +104 -0
  280. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/wtfp.md +145 -0
  281. package/library/plugins/materio/ai.iowarp.clio/references/execution.md +56 -0
  282. package/library/plugins/materio/ai.iowarp.portability/provenance.json +9 -0
  283. package/library/plugins/materio/assets/actions/add-task.md +86 -0
  284. package/library/plugins/materio/assets/actions/archive-task.md +84 -0
  285. package/library/plugins/materio/assets/actions/checkpoint.md +47 -0
  286. package/library/plugins/materio/assets/actions/define-research-tasks.md +228 -0
  287. package/library/plugins/materio/assets/actions/define-virtual-lab.md +179 -0
  288. package/library/plugins/materio/assets/actions/execute-task.md +290 -0
  289. package/library/plugins/materio/assets/actions/help.md +140 -0
  290. package/library/plugins/materio/assets/actions/identify-research.md +204 -0
  291. package/library/plugins/materio/assets/actions/literature-review.md +199 -0
  292. package/library/plugins/materio/assets/actions/pause-research.md +34 -0
  293. package/library/plugins/materio/assets/actions/progress.md +125 -0
  294. package/library/plugins/materio/assets/actions/remove-task.md +82 -0
  295. package/library/plugins/materio/assets/actions/resume-research.md +84 -0
  296. package/library/plugins/materio/assets/actions/settings.md +38 -0
  297. package/library/plugins/materio/assets/actions/status.md +112 -0
  298. package/library/plugins/materio/assets/actions/upload-data.md +123 -0
  299. package/library/plugins/materio/assets/actions/wtfp.md +179 -0
  300. package/library/plugins/materio/assets/references/research-domains.md +134 -0
  301. package/library/plugins/materio/assets/references/research-policy.md +77 -0
  302. package/library/plugins/materio/assets/references/traditional-workflows.md +146 -0
  303. package/library/plugins/materio/assets/scripts/check_physics.py +271 -0
  304. package/library/plugins/materio/assets/scripts/check_scripts.py +248 -0
  305. package/library/plugins/materio/assets/scripts/project_plugin.py +165 -0
  306. package/library/plugins/materio/assets/scripts/research_state.py +400 -0
  307. package/library/plugins/materio/assets/scripts/verify_citations.py +616 -0
  308. package/library/plugins/materio/assets/templates/RESEARCH.md +39 -0
  309. package/library/plugins/materio/assets/templates/VIRTUAL-LAB.md +120 -0
  310. package/library/plugins/materio/assets/templates/WORKFLOW.md +42 -0
  311. package/library/plugins/materio/assets/templates/config.json +5 -0
  312. package/library/plugins/materio/evals/scripts.yaml +29 -0
  313. package/library/plugins/materio/plugin.json +530 -0
  314. package/library/plugins/materio/skills/materio-lab-definer/SKILL.md +74 -0
  315. package/library/plugins/materio/skills/materio-literature-reviewer/SKILL.md +64 -0
  316. package/library/plugins/materio/skills/materio-research-explorer/SKILL.md +74 -0
  317. package/library/plugins/materio/skills/materio-task-executor/SKILL.md +214 -0
  318. package/library/plugins/materio/skills/materio-task-verifier/SKILL.md +46 -0
  319. package/library/plugins/materio/skills/materio-workflow-planner/SKILL.md +79 -0
  320. package/library/plugins/materio/tests/test_check_physics.py +139 -0
  321. package/library/plugins/materio/tests/test_check_scripts.py +140 -0
  322. package/library/plugins/materio/tests/test_research_state.py +291 -0
  323. package/library/plugins/materio/tests/test_verify_citations.py +337 -0
  324. package/library/prompts/README.md +7 -0
  325. package/library/registry.yaml +921 -0
  326. package/library/skills/README.md +120 -0
  327. package/{skills → library/skills}/coding/ast-grep/SKILL.md +1 -1
  328. package/{skills → library/skills}/coding/ast-grep/evals.md +1 -1
  329. package/library/skills/coding/ast-grep/plugin.json +23 -0
  330. package/{skills → library/skills}/coding/coding-standards/SKILL.md +1 -1
  331. package/{skills → library/skills}/coding/coding-standards/evals.md +1 -1
  332. package/library/skills/coding/coding-standards/plugin.json +23 -0
  333. package/{skills → library/skills}/coding/prototype/SKILL.md +1 -1
  334. package/{skills → library/skills}/coding/prototype/evals.md +1 -1
  335. package/library/skills/coding/prototype/plugin.json +23 -0
  336. package/{skills → library/skills}/coding/tdd/SKILL.md +1 -1
  337. package/{skills → library/skills}/coding/tdd/evals.md +1 -1
  338. package/library/skills/coding/tdd/plugin.json +23 -0
  339. package/{skills → library/skills}/context/context-handoff/SKILL.md +1 -1
  340. package/{skills → library/skills}/context/context-handoff/evals.md +1 -1
  341. package/library/skills/context/context-handoff/plugin.json +23 -0
  342. package/{skills → library/skills}/context/context-prime/SKILL.md +1 -1
  343. package/{skills → library/skills}/context/context-prime/evals.md +1 -1
  344. package/library/skills/context/context-prime/plugin.json +23 -0
  345. package/{skills → library/skills}/git/branch-closeout/SKILL.md +1 -1
  346. package/library/skills/git/branch-closeout/plugin.json +23 -0
  347. package/{skills → library/skills}/git/file-ticket/SKILL.md +1 -1
  348. package/library/skills/git/file-ticket/plugin.json +23 -0
  349. package/{skills → library/skills}/git/fix-issue/SKILL.md +1 -1
  350. package/library/skills/git/fix-issue/plugin.json +23 -0
  351. package/{skills → library/skills}/git/resolve-merge-conflicts/SKILL.md +1 -1
  352. package/{skills → library/skills}/git/resolve-merge-conflicts/evals.md +1 -1
  353. package/library/skills/git/resolve-merge-conflicts/plugin.json +23 -0
  354. package/{skills → library/skills}/git/ship/SKILL.md +1 -1
  355. package/library/skills/git/ship/plugin.json +23 -0
  356. package/{skills → library/skills}/git/worktree-create/SKILL.md +1 -1
  357. package/library/skills/git/worktree-create/plugin.json +23 -0
  358. package/{skills → library/skills}/git/worktree-merge/SKILL.md +1 -1
  359. package/library/skills/git/worktree-merge/plugin.json +23 -0
  360. package/{skills → library/skills}/meta/clio-coder-dev/SKILL.md +1 -1
  361. package/{skills → library/skills}/meta/clio-coder-dev/evals.md +1 -1
  362. package/library/skills/meta/clio-coder-dev/plugin.json +23 -0
  363. package/{skills → library/skills}/meta/clio-coder-test/SKILL.md +1 -1
  364. package/{skills → library/skills}/meta/clio-coder-test/evals.md +1 -1
  365. package/library/skills/meta/clio-coder-test/plugin.json +23 -0
  366. package/{skills → library/skills}/meta/credentials/SKILL.md +1 -1
  367. package/{skills → library/skills}/meta/credentials/evals.md +1 -1
  368. package/library/skills/meta/credentials/plugin.json +23 -0
  369. package/library/skills/meta/find-skills/SKILL.md +85 -0
  370. package/library/skills/meta/find-skills/evals.md +65 -0
  371. package/library/skills/meta/find-skills/plugin.json +23 -0
  372. package/{skills → library/skills}/meta/herdr/SKILL.md +1 -1
  373. package/{skills → library/skills}/meta/herdr/evals.md +1 -1
  374. package/library/skills/meta/herdr/plugin.json +23 -0
  375. package/{skills → library/skills}/meta/skill-craft/SKILL.md +23 -9
  376. package/{skills → library/skills}/meta/skill-craft/evals.md +11 -3
  377. package/library/skills/meta/skill-craft/plugin.json +23 -0
  378. package/{skills → library/skills}/planning/archify/SKILL.md +13 -13
  379. package/library/skills/planning/archify/plugin.json +23 -0
  380. package/{skills → library/skills}/planning/architecture/SKILL.md +1 -1
  381. package/{skills → library/skills}/planning/architecture/evals.md +1 -1
  382. package/library/skills/planning/architecture/plugin.json +23 -0
  383. package/{skills → library/skills}/planning/backlog/SKILL.md +1 -1
  384. package/{skills → library/skills}/planning/backlog/evals.md +1 -1
  385. package/library/skills/planning/backlog/plugin.json +23 -0
  386. package/{skills → library/skills}/planning/prd/SKILL.md +1 -1
  387. package/{skills → library/skills}/planning/prd/evals.md +1 -1
  388. package/library/skills/planning/prd/plugin.json +23 -0
  389. package/{skills → library/skills}/planning/product-intent/SKILL.md +1 -1
  390. package/{skills → library/skills}/planning/product-intent/evals.md +1 -1
  391. package/library/skills/planning/product-intent/plugin.json +23 -0
  392. package/{skills → library/skills}/planning/tech-spec/SKILL.md +1 -1
  393. package/{skills → library/skills}/planning/tech-spec/evals.md +1 -1
  394. package/library/skills/planning/tech-spec/plugin.json +23 -0
  395. package/{skills → library/skills}/registry.yaml +7 -7
  396. package/{skills → library/skills}/remote.yaml +1 -1
  397. package/{skills → library/skills}/research/arxiv-literature/SKILL.md +1 -1
  398. package/{skills → library/skills}/research/arxiv-literature/evals.md +1 -1
  399. package/library/skills/research/arxiv-literature/plugin.json +23 -0
  400. package/{skills → library/skills}/research/experiment-protocol/SKILL.md +1 -1
  401. package/{skills → library/skills}/research/experiment-protocol/evals.md +1 -1
  402. package/library/skills/research/experiment-protocol/plugin.json +23 -0
  403. package/{skills → library/skills}/research/scientific-debugging/SKILL.md +1 -1
  404. package/{skills → library/skills}/research/scientific-debugging/evals.md +1 -1
  405. package/library/skills/research/scientific-debugging/plugin.json +23 -0
  406. package/{skills → library/skills}/research/scientific-modernization/SKILL.md +1 -1
  407. package/{skills → library/skills}/research/scientific-modernization/evals.md +1 -1
  408. package/library/skills/research/scientific-modernization/plugin.json +23 -0
  409. package/{skills → library/skills}/skill-marketplace.json +37 -37
  410. package/{skills → library/skills}/workflow/cut-it/SKILL.md +1 -1
  411. package/{skills → library/skills}/workflow/cut-it/evals.md +1 -1
  412. package/library/skills/workflow/cut-it/plugin.json +23 -0
  413. package/{skills → library/skills}/workflow/design-council/SKILL.md +1 -1
  414. package/{skills → library/skills}/workflow/design-council/evals.md +1 -1
  415. package/library/skills/workflow/design-council/plugin.json +23 -0
  416. package/{skills → library/skills}/workflow/grill-me/SKILL.md +1 -1
  417. package/{skills → library/skills}/workflow/grill-me/evals.md +1 -1
  418. package/library/skills/workflow/grill-me/plugin.json +23 -0
  419. package/{skills → library/skills}/workflow/workflow-distiller/SKILL.md +14 -11
  420. package/{skills → library/skills}/workflow/workflow-distiller/evals.md +14 -6
  421. package/library/skills/workflow/workflow-distiller/plugin.json +23 -0
  422. package/package.json +12 -5
  423. package/src/cli/agents.ts +1 -1
  424. package/src/cli/ask.ts +10 -10
  425. package/src/cli/config-inspect.ts +1 -1
  426. package/src/cli/configure-editor.ts +51 -0
  427. package/src/cli/configure-interop.ts +1 -1
  428. package/src/cli/configure-oauth.ts +1 -1
  429. package/src/cli/configure-onboarding.ts +232 -96
  430. package/src/cli/configure-prompts.ts +76 -0
  431. package/src/cli/configure-quick.ts +274 -0
  432. package/src/cli/configure-target.ts +14 -2
  433. package/src/cli/configure.ts +415 -176
  434. package/src/cli/eval.ts +40 -6
  435. package/src/cli/extensions.ts +74 -8
  436. package/src/cli/fleet-preflight.ts +2 -0
  437. package/src/cli/fleet.ts +2 -0
  438. package/src/cli/index.ts +1 -3
  439. package/src/cli/interop-inspect.ts +61 -33
  440. package/src/cli/interop.ts +79 -9
  441. package/src/cli/library-import.ts +139 -0
  442. package/src/cli/library.ts +418 -120
  443. package/src/cli/oauth-manual-input.ts +1 -1
  444. package/src/cli/reset.ts +2 -0
  445. package/src/cli/run.ts +26 -9
  446. package/src/cli/select.ts +35 -4
  447. package/src/cli/skills-eval.ts +43 -6
  448. package/src/cli/skills-inventory.ts +6 -2
  449. package/src/cli/skills.ts +44 -491
  450. package/src/cli/upgrade.ts +2 -2
  451. package/src/core/bus-events.ts +5 -0
  452. package/src/core/config.ts +6 -1
  453. package/src/core/defaults.ts +34 -12
  454. package/src/{interactive → core}/external-editor.ts +4 -4
  455. package/src/core/recent-models.ts +2 -2
  456. package/src/core/session-routing.ts +3 -3
  457. package/src/core/state-file-lock.ts +1 -1
  458. package/src/core/tool-names.ts +5 -0
  459. package/src/domains/agents/extension.ts +42 -6
  460. package/src/domains/agents/fleet-commands.ts +92 -1
  461. package/src/domains/agents/fleet-contract.ts +87 -19
  462. package/src/domains/agents/recipe.ts +5 -4
  463. package/src/domains/agents/registry.ts +80 -24
  464. package/src/domains/config/classify.ts +1 -1
  465. package/src/domains/config/keybindings.ts +156 -124
  466. package/src/domains/context/worker/contract.ts +91 -0
  467. package/src/domains/context/worker/pressure.ts +120 -0
  468. package/src/domains/context/worker/recall.ts +62 -0
  469. package/src/domains/context/worker/select.ts +164 -0
  470. package/src/domains/context/worker/snapshot.ts +35 -0
  471. package/src/domains/context/worker/store.ts +16 -0
  472. package/src/domains/context/working-set/replay/synthetic.ts +2 -1
  473. package/src/domains/dispatch/active-route-planner.ts +2 -0
  474. package/src/domains/dispatch/backoff.ts +1 -0
  475. package/src/domains/dispatch/code-step.ts +12 -2
  476. package/src/domains/dispatch/contract.ts +3 -0
  477. package/src/domains/dispatch/execution-plan.ts +2 -0
  478. package/src/domains/dispatch/extension.ts +109 -27
  479. package/src/domains/dispatch/fleet-plan.ts +10 -0
  480. package/src/domains/dispatch/fleet-run.ts +1 -0
  481. package/src/domains/dispatch/orphan-recovery.ts +1 -0
  482. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  483. package/src/domains/dispatch/state.ts +1 -0
  484. package/src/domains/dispatch/types.ts +5 -0
  485. package/src/domains/dispatch/validation.ts +12 -0
  486. package/src/domains/dispatch/workspace-checkpoint.ts +1 -1
  487. package/src/domains/evidence/failure-attribution.ts +1 -0
  488. package/src/domains/evidence/trust-status.ts +22 -3
  489. package/src/domains/extensions/command-schema.ts +145 -0
  490. package/src/domains/extensions/command-tools.ts +15 -0
  491. package/src/domains/extensions/compatibility.ts +7 -0
  492. package/src/domains/extensions/contract.ts +0 -4
  493. package/src/domains/extensions/discovery.ts +69 -205
  494. package/src/domains/extensions/extension.ts +0 -4
  495. package/src/domains/extensions/index.ts +1 -5
  496. package/src/domains/extensions/manager.ts +1 -6
  497. package/src/domains/extensions/operator-commands.ts +29 -0
  498. package/src/domains/extensions/operator-runtime.ts +483 -0
  499. package/src/domains/extensions/public-api.ts +53 -0
  500. package/src/domains/extensions/runtime-child.mjs +114 -0
  501. package/src/domains/extensions/runtime-process.ts +306 -0
  502. package/src/domains/extensions/runtime-schema.ts +146 -0
  503. package/src/domains/extensions/{resources.ts → snapshot-access.ts} +1 -17
  504. package/src/domains/extensions/snapshot.ts +4 -32
  505. package/src/domains/extensions/state.ts +5 -83
  506. package/src/domains/extensions/types.ts +33 -34
  507. package/src/domains/interop/adopt.ts +546 -0
  508. package/src/domains/interop/detect.ts +50 -12
  509. package/src/domains/interop/foreign.ts +554 -0
  510. package/src/domains/interop/import.ts +277 -0
  511. package/src/domains/interop/index.ts +24 -0
  512. package/src/domains/interop/install.ts +6 -0
  513. package/src/domains/interop/inventory.ts +351 -0
  514. package/src/domains/interop/projection.ts +360 -0
  515. package/src/domains/interop/registry.ts +106 -3
  516. package/src/domains/interop/types.ts +51 -0
  517. package/src/domains/lifecycle/migrations/index.ts +0 -2
  518. package/src/domains/lifecycle/naming-resources.ts +1 -1
  519. package/src/domains/middleware/marketplace-offer.ts +1 -1
  520. package/src/domains/mux/contract.ts +1 -1
  521. package/src/domains/plugins/catalog.ts +204 -0
  522. package/src/domains/plugins/contract.ts +24 -0
  523. package/src/domains/plugins/discovery.ts +316 -0
  524. package/src/domains/plugins/extension.ts +40 -0
  525. package/src/domains/plugins/index.ts +77 -0
  526. package/src/domains/plugins/integrity.ts +6 -0
  527. package/src/domains/plugins/manifest.ts +3 -0
  528. package/src/domains/plugins/resources.ts +102 -0
  529. package/src/domains/plugins/state.ts +753 -0
  530. package/src/domains/plugins/types.ts +217 -0
  531. package/src/domains/prompts/extension.ts +9 -2
  532. package/src/domains/prompts/fragments/operating/skills.md +10 -10
  533. package/src/domains/providers/probe/fingerprint.ts +13 -6
  534. package/src/domains/providers/probe/reasoning.ts +2 -0
  535. package/src/domains/providers/runtimes/common/probe-helpers.ts +23 -7
  536. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +7 -2
  537. package/src/domains/providers/runtimes/protocol/openai-compat.ts +10 -4
  538. package/src/domains/resources/common-loader.ts +9 -6
  539. package/src/domains/resources/index.ts +67 -0
  540. package/src/domains/resources/library-actions.ts +836 -0
  541. package/src/domains/resources/library-evals.ts +38 -0
  542. package/src/domains/resources/library-inventory.ts +1048 -0
  543. package/src/domains/resources/library-types.ts +50 -0
  544. package/src/domains/resources/library-validation.ts +634 -0
  545. package/src/domains/resources/library.ts +437 -156
  546. package/src/domains/resources/package-references.ts +66 -0
  547. package/src/domains/resources/prompts/loader.ts +75 -41
  548. package/src/domains/resources/skills/install.ts +2 -2
  549. package/src/domains/resources/skills/loader.ts +77 -22
  550. package/src/domains/resources/skills/marketplace.ts +48 -57
  551. package/src/domains/resources/skills/promotion.ts +2 -2
  552. package/src/domains/resources/skills/provenance-pin.ts +17 -4
  553. package/src/domains/safety/action-classifier.ts +2 -2
  554. package/src/domains/safety/default-path-policy.ts +3 -1
  555. package/src/domains/safety/policy-engine.ts +1 -1
  556. package/src/domains/safety/protected-artifacts.ts +21 -5
  557. package/src/domains/safety/skill-authority.ts +5 -2
  558. package/src/domains/share/archive.ts +1 -1
  559. package/src/engine/apis/openai-completions.ts +52 -2
  560. package/src/engine/notices/pi-tui-LICENSE +21 -0
  561. package/src/engine/tui.ts +3 -0
  562. package/src/engine/worker-runtime.ts +58 -14
  563. package/src/engine/worker-tools.ts +5 -0
  564. package/src/entry/orchestrator.ts +26 -5
  565. package/src/entry/plugin-reload.ts +18 -0
  566. package/src/interactive/application-controller.ts +68 -52
  567. package/src/interactive/chat-loop.ts +32 -5
  568. package/src/interactive/chat-panel.ts +168 -638
  569. package/src/interactive/chat-renderer.ts +13 -30
  570. package/src/interactive/clio-editor.ts +53 -21
  571. package/src/interactive/command-output.ts +56 -1
  572. package/src/interactive/dispatch-board.ts +1 -3
  573. package/src/interactive/editor-submit.ts +73 -59
  574. package/src/interactive/fleet-run-preview.ts +2 -0
  575. package/src/interactive/follow-up-queue-panel.ts +3 -3
  576. package/src/interactive/footer/dashboard.ts +12 -4
  577. package/src/interactive/footer/notifications.ts +2 -2
  578. package/src/interactive/footer/widgets.ts +52 -93
  579. package/src/interactive/interactive-application.ts +225 -63
  580. package/src/interactive/interactive-event-projection.ts +2 -44
  581. package/src/interactive/interactive-input-runtime.ts +257 -35
  582. package/src/interactive/interactive-presentation.ts +71 -21
  583. package/src/interactive/interactive-slash-runtime.ts +40 -48
  584. package/src/interactive/keybinding-manager.ts +156 -79
  585. package/src/interactive/keyboard-owner.ts +37 -0
  586. package/src/interactive/layout.ts +29 -4
  587. package/src/interactive/leader-key.ts +49 -102
  588. package/src/interactive/leader-menu.ts +45 -0
  589. package/src/interactive/overlay-ask-user-lifecycle.ts +9 -1
  590. package/src/interactive/overlay-frame.ts +15 -0
  591. package/src/interactive/overlay-general-openers.ts +2 -0
  592. package/src/interactive/overlay-key-routing.ts +46 -47
  593. package/src/interactive/overlay-lifecycle.ts +31 -15
  594. package/src/interactive/overlay-resource-openers.ts +56 -46
  595. package/src/interactive/overlay-session-lifecycle.ts +1 -1
  596. package/src/interactive/overlays/ask-user.ts +630 -556
  597. package/src/interactive/overlays/extension-panel.ts +70 -0
  598. package/src/interactive/overlays/extensions.ts +28 -5
  599. package/src/interactive/overlays/fleet-run-approval.ts +7 -3
  600. package/src/interactive/overlays/help-reference.ts +89 -40
  601. package/src/interactive/overlays/interop.ts +122 -3
  602. package/src/interactive/overlays/keybinding-detail.ts +2 -2
  603. package/src/interactive/overlays/library-lifecycle.ts +90 -0
  604. package/src/interactive/overlays/library-model.ts +574 -0
  605. package/src/interactive/overlays/library-review.ts +557 -0
  606. package/src/interactive/overlays/library-tabs.ts +3 -15
  607. package/src/interactive/overlays/library.ts +602 -0
  608. package/src/interactive/overlays/list-overlay.ts +218 -39
  609. package/src/interactive/overlays/model-selector.ts +28 -25
  610. package/src/interactive/overlays/session-selector.ts +9 -3
  611. package/src/interactive/overlays/settings.ts +34 -26
  612. package/src/interactive/overlays/tree-selector.ts +16 -11
  613. package/src/interactive/permission-hint.ts +13 -0
  614. package/src/interactive/permission-overlay.ts +77 -28
  615. package/src/interactive/prompt-source-label.ts +21 -0
  616. package/src/interactive/renderers/preview.ts +16 -0
  617. package/src/interactive/renderers/reference-card.ts +35 -0
  618. package/src/interactive/renderers/tool-execution.ts +67 -160
  619. package/src/interactive/renderers/worker-entry.ts +90 -42
  620. package/src/interactive/slash-autocomplete.ts +100 -7
  621. package/src/interactive/slash-commands.ts +396 -105
  622. package/src/interactive/slash-spec.ts +0 -1
  623. package/src/interactive/status/controller.ts +0 -5
  624. package/src/interactive/status/state-machine.ts +44 -26
  625. package/src/interactive/status/types.ts +3 -0
  626. package/src/interactive/status/verbs.ts +13 -12
  627. package/src/interactive/terminal-lease.ts +44 -12
  628. package/src/interactive/transcript-detail.ts +50 -112
  629. package/src/interactive/turn-queues.ts +8 -7
  630. package/src/interactive/turn-runtime.ts +1 -1
  631. package/src/interactive/view/artifacts.ts +4 -0
  632. package/src/interactive/view/view-overlay.ts +58 -43
  633. package/src/interactive/welcome-dashboard.ts +525 -408
  634. package/src/tools/bootstrap.ts +8 -0
  635. package/src/tools/builtin-tool-catalog.ts +7 -2
  636. package/src/tools/context/index.ts +58 -5
  637. package/src/tools/context/library.ts +465 -0
  638. package/src/tools/context/surface.ts +20 -6
  639. package/src/tools/core-bootstrap.ts +3 -0
  640. package/src/tools/dispatch-admission.ts +24 -1
  641. package/src/tools/dispatch-arguments.ts +8 -0
  642. package/src/tools/dispatch-plan.ts +32 -0
  643. package/src/tools/dispatch-schema.ts +31 -1
  644. package/src/tools/dispatch-types.ts +3 -0
  645. package/src/tools/dispatch.ts +1 -1
  646. package/src/tools/harness-extensions.ts +169 -0
  647. package/src/tools/observation.ts +4 -0
  648. package/src/tools/policy.ts +7 -1
  649. package/src/tools/presentation.ts +1 -1
  650. package/src/tools/registry.ts +20 -2
  651. package/src/tools/verify/numeric.ts +4 -4
  652. package/src/tools/worker-evidence.ts +5 -0
  653. package/src/worker/context-seed.ts +192 -0
  654. package/src/worker/entry.ts +1 -0
  655. package/src/worker/spec-contract.ts +8 -1
  656. package/dist/chunk-3UW3KU4A.js +0 -21
  657. package/dist/chunk-6SYEGZI3.js +0 -433
  658. package/dist/chunk-CXQ37WJH.js +0 -45
  659. package/dist/chunk-EQEJJ53P.js +0 -399
  660. package/dist/chunk-KTFSFCVN.js +0 -46
  661. package/dist/chunk-QRFXEO6Y.js +0 -17
  662. package/dist/chunk-T7FDXNRU.js +0 -1257
  663. package/dist/chunk-U7VQ4NI4.js +0 -911
  664. package/dist/configure-SML6UBZ5.js +0 -55
  665. package/dist/interop-YOTGXFJM.js +0 -115
  666. package/dist/library-GJI6W6OK.js +0 -226
  667. package/dist/skills-S36AAJHU.js +0 -510
  668. package/skills/README.md +0 -418
  669. package/skills/meta/find-skills/SKILL.md +0 -78
  670. package/skills/meta/find-skills/evals.md +0 -47
  671. package/src/domains/extensions/resource-path.ts +0 -27
  672. package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +0 -27
  673. package/src/interactive/overlays/agents.ts +0 -70
  674. package/src/interactive/overlays/library-install-confirm.ts +0 -152
  675. package/src/interactive/overlays/prompts.ts +0 -89
  676. package/src/interactive/overlays/skills-hub.ts +0 -615
  677. /package/{skills → library/skills}/coding/ast-grep/references/rule_reference.md +0 -0
  678. /package/{skills → library/skills}/coding/prototype/references/LOGIC.md +0 -0
  679. /package/{skills → library/skills}/coding/prototype/references/UI.md +0 -0
  680. /package/{skills → library/skills}/coding/tdd/references/mocking.md +0 -0
  681. /package/{skills → library/skills}/coding/tdd/references/tests.md +0 -0
  682. /package/{skills → library/skills}/context/context-handoff/scripts/new-handoff.sh +0 -0
  683. /package/{skills → library/skills}/git/branch-closeout/evals.md +0 -0
  684. /package/{skills → library/skills}/git/branch-closeout/references/closeout-checklist.md +0 -0
  685. /package/{skills → library/skills}/git/file-ticket/assets/issue-template.md +0 -0
  686. /package/{skills → library/skills}/git/file-ticket/evals.md +0 -0
  687. /package/{skills → library/skills}/git/file-ticket/references/issue-discovery.md +0 -0
  688. /package/{skills → library/skills}/git/fix-issue/evals.md +0 -0
  689. /package/{skills → library/skills}/git/fix-issue/references/diagnosis-and-rca.md +0 -0
  690. /package/{skills → library/skills}/git/resolve-merge-conflicts/references/conflict-matrix.md +0 -0
  691. /package/{skills → library/skills}/git/ship/assets/pr-template.md +0 -0
  692. /package/{skills → library/skills}/git/ship/evals.md +0 -0
  693. /package/{skills → library/skills}/git/ship/references/remote-and-branch-policy.md +0 -0
  694. /package/{skills → library/skills}/git/worktree-create/evals.md +0 -0
  695. /package/{skills → library/skills}/git/worktree-create/references/worktree-setup.md +0 -0
  696. /package/{skills → library/skills}/git/worktree-merge/evals.md +0 -0
  697. /package/{skills → library/skills}/git/worktree-merge/references/merge-strategies.md +0 -0
  698. /package/{skills → library/skills}/meta/clio-coder-test/references/harness.md +0 -0
  699. /package/{skills → library/skills}/meta/clio-coder-test/references/test-map.md +0 -0
  700. /package/{skills → library/skills}/planning/archify/evals.md +0 -0
@@ -1,7 +1,9 @@
1
1
  import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
2
2
  import {
3
- getVersionInfo
4
- } from "./chunk-GD55RTIW.js";
3
+ evaluateClioCompatibility,
4
+ extensionContentDigest,
5
+ extensionContentDigestWithCapture
6
+ } from "./chunk-XW2UZICE.js";
5
7
  import {
6
8
  require_dist
7
9
  } from "./chunk-B5GGDIHT.js";
@@ -19,236 +21,277 @@ import {
19
21
  // src/domains/extensions/discovery.ts
20
22
  init_esm_shims();
21
23
  var import_yaml = __toESM(require_dist(), 1);
22
- import { existsSync, lstatSync, readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
23
- import path from "node:path";
24
+ import { existsSync, readdirSync, readFileSync, realpathSync as realpathSync2, statSync } from "node:fs";
25
+ import path2 from "node:path";
24
26
 
25
- // src/domains/extensions/compatibility.ts
27
+ // src/domains/extensions/command-schema.ts
26
28
  init_esm_shims();
27
- var MAX_RANGE_CHARS = 256;
28
- var NUMERIC = "(?:0|[1-9]\\d*)";
29
- var IDENTIFIER = "[0-9A-Za-z-]+";
30
- var VERSION_RE = new RegExp(
31
- `^v?(${NUMERIC})\\.(${NUMERIC})\\.(${NUMERIC})(?:-(${IDENTIFIER}(?:\\.${IDENTIFIER})*))?(?:\\+${IDENTIFIER}(?:\\.${IDENTIFIER})*)?$`
32
- );
33
- var PARTIAL_RE = new RegExp(
34
- `^v?(${NUMERIC}|[xX*])(?:\\.(${NUMERIC}|[xX*]))?(?:\\.(${NUMERIC}|[xX*]))?(?:-(${IDENTIFIER}(?:\\.${IDENTIFIER})*))?(?:\\+${IDENTIFIER}(?:\\.${IDENTIFIER})*)?$`
35
- );
36
- function prerelease(value) {
37
- if (value === void 0) return [];
38
- const out = [];
39
- for (const identifier of value.split(".")) {
40
- if (identifier.length === 0) return null;
41
- if (/^\d+$/u.test(identifier)) {
42
- if (identifier.length > 1 && identifier.startsWith("0")) return null;
43
- const parsed = Number(identifier);
44
- if (!Number.isSafeInteger(parsed)) return null;
45
- out.push(parsed);
46
- } else {
47
- out.push(identifier);
29
+ import { lstatSync, realpathSync } from "node:fs";
30
+ import path from "node:path";
31
+ var TOOL_KEYS = /* @__PURE__ */ new Set([
32
+ "name",
33
+ "description",
34
+ "runtime",
35
+ "entrypoint",
36
+ "inputSchema",
37
+ "timeoutMs",
38
+ "maxOutputBytes"
39
+ ]);
40
+ var SCHEMA_KEYS = /* @__PURE__ */ new Set([
41
+ "type",
42
+ "description",
43
+ "properties",
44
+ "required",
45
+ "additionalProperties",
46
+ "items",
47
+ "enum",
48
+ "minimum",
49
+ "maximum",
50
+ "minLength",
51
+ "maxLength",
52
+ "minItems",
53
+ "maxItems"
54
+ ]);
55
+ var TYPES = /* @__PURE__ */ new Set(["object", "array", "string", "number", "integer", "boolean", "null"]);
56
+ function record(value) {
57
+ return value !== null && typeof value === "object" && !Array.isArray(value);
58
+ }
59
+ function extensionToolName(id, name) {
60
+ return `extension_${id}__${name}`;
61
+ }
62
+ function validateSchema(value, depth = 0) {
63
+ if (depth > 12 || !record(value))
64
+ throw new Error("inputSchema must be a JSON schema object with at most 12 nesting levels");
65
+ for (const key of Object.keys(value)) {
66
+ if (!SCHEMA_KEYS.has(key)) throw new Error(`unsupported inputSchema keyword '${key}'`);
67
+ }
68
+ if (typeof value.type !== "string" || !TYPES.has(value.type))
69
+ throw new Error("inputSchema.type must be a supported JSON type");
70
+ if (value.description !== void 0 && typeof value.description !== "string")
71
+ throw new Error("inputSchema.description must be a string");
72
+ if (value.enum !== void 0 && (!Array.isArray(value.enum) || value.enum.length === 0 || value.enum.some((item) => item !== null && typeof item === "object"))) {
73
+ throw new Error("inputSchema.enum must contain JSON scalar values");
74
+ }
75
+ for (const key of ["minimum", "maximum", "minLength", "maxLength", "minItems", "maxItems"]) {
76
+ if (value[key] !== void 0 && (typeof value[key] !== "number" || !Number.isFinite(value[key])))
77
+ throw new Error(`inputSchema.${key} must be finite`);
78
+ }
79
+ if (value.type === "object") {
80
+ if (!record(value.properties) || value.additionalProperties !== false)
81
+ throw new Error("object inputSchema requires properties and additionalProperties: false");
82
+ for (const [key, child] of Object.entries(value.properties)) {
83
+ if (["__proto__", "constructor", "prototype"].includes(key)) throw new Error("unsafe inputSchema property name");
84
+ validateSchema(child, depth + 1);
48
85
  }
86
+ if (value.required !== void 0 && (!Array.isArray(value.required) || value.required.some((key) => typeof key !== "string" || !Object.hasOwn(value.properties, key)))) {
87
+ throw new Error("inputSchema.required must name declared properties");
88
+ }
89
+ } else if (value.type === "array") {
90
+ validateSchema(value.items, depth + 1);
49
91
  }
50
- return out;
51
92
  }
52
- function parseSemVer(value) {
53
- const match = VERSION_RE.exec(value);
54
- if (match === null) return null;
55
- const parsedPrerelease = prerelease(match[4]);
56
- if (parsedPrerelease === null) return null;
57
- const major = Number(match[1]);
58
- const minor = Number(match[2]);
59
- const patch = Number(match[3]);
60
- if (![major, minor, patch].every(Number.isSafeInteger)) return null;
61
- return { major, minor, patch, prerelease: parsedPrerelease };
93
+ function parseExtensionCapabilities(value, id) {
94
+ if (!record(value) || Object.keys(value).some((key) => key !== "tools") || !Array.isArray(value.tools) || value.tools.length === 0 || value.tools.length > 32) {
95
+ throw new Error("capabilities must contain tools with between 1 and 32 command declarations");
96
+ }
97
+ if (id.includes("__")) throw new Error("v2 extension id cannot contain double underscores");
98
+ const names = /* @__PURE__ */ new Set();
99
+ const tools = value.tools.map((tool) => {
100
+ if (!record(tool)) throw new Error("capabilities.tools entries must be objects");
101
+ for (const key of Object.keys(tool)) if (!TOOL_KEYS.has(key)) throw new Error(`unknown command tool key '${key}'`);
102
+ if (typeof tool.name !== "string" || !/^[a-z][a-z0-9_]*$/.test(tool.name) || tool.name.includes("__"))
103
+ throw new Error("command tool name must use lowercase letters, digits, and single underscores");
104
+ const name = extensionToolName(id, tool.name);
105
+ if (name.length > 64 || !/^[a-zA-Z0-9_-]+$/.test(name))
106
+ throw new Error("qualified command tool name must use provider-safe characters and fit 64 characters");
107
+ if (names.has(name)) throw new Error(`duplicate command tool name '${name}'`);
108
+ names.add(name);
109
+ if (typeof tool.description !== "string" || tool.description.trim().length === 0 || tool.description.length > 2e3)
110
+ throw new Error("command tool description must contain 1 to 2000 characters");
111
+ if (tool.runtime !== "node" && tool.runtime !== "python3")
112
+ throw new Error("command tool runtime must be node or python3");
113
+ if (typeof tool.entrypoint !== "string" || tool.entrypoint.includes("\0") || tool.entrypoint.includes("\\") || path.isAbsolute(tool.entrypoint) || tool.entrypoint.split("/").some((part) => part === ".." || part === "." || part === ""))
114
+ throw new Error("command tool entrypoint must be a contained relative file path");
115
+ validateSchema(tool.inputSchema);
116
+ if (tool.inputSchema.type !== "object") throw new Error("command tool inputSchema root must be object");
117
+ for (const [key, maximum] of [
118
+ ["timeoutMs", 3e5],
119
+ ["maxOutputBytes", 1048576]
120
+ ]) {
121
+ const limit = tool[key];
122
+ if (limit !== void 0 && (typeof limit !== "number" || !Number.isInteger(limit) || limit < 1 || limit > maximum))
123
+ throw new Error(`command tool ${key} must be between 1 and ${maximum}`);
124
+ }
125
+ return structuredClone(tool);
126
+ });
127
+ return { tools };
62
128
  }
63
- function parsePart(value) {
64
- if (value === void 0 || value === "x" || value === "X" || value === "*") return null;
65
- const parsed = Number(value);
66
- return Number.isSafeInteger(parsed) ? parsed : null;
129
+ function resolveExtensionEntrypoint(root, entrypoint) {
130
+ const canonicalRoot = realpathSync(root);
131
+ let cursor = canonicalRoot;
132
+ for (const segment of entrypoint.split("/")) {
133
+ if (segment === ".." || segment === "." || segment.length === 0)
134
+ throw new Error("invalid command entrypoint segment");
135
+ cursor = path.join(cursor, segment);
136
+ if (lstatSync(cursor).isSymbolicLink()) throw new Error("command entrypoint cannot contain symbolic links");
137
+ }
138
+ const stat = lstatSync(cursor);
139
+ if (!stat.isFile() || stat.nlink !== 1) throw new Error("command entrypoint must be an ordinary file with one link");
140
+ const relative = path.relative(canonicalRoot, realpathSync(cursor));
141
+ if (relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative))
142
+ throw new Error("command entrypoint escapes extension root");
143
+ return cursor;
67
144
  }
68
- function parsePartial(value) {
69
- const match = PARTIAL_RE.exec(value);
70
- if (match === null) return null;
71
- for (const part of match.slice(1, 4)) {
72
- if (part === void 0 || part === "x" || part === "X" || part === "*") continue;
73
- if (!Number.isSafeInteger(Number(part))) return null;
74
- }
75
- const major = parsePart(match[1]);
76
- const minor = parsePart(match[2]);
77
- const patch = parsePart(match[3]);
78
- if (major === null && (match[2] !== void 0 || match[3] !== void 0) || minor === null && match[3] !== void 0) {
79
- return null;
80
- }
81
- const parsedPrerelease = prerelease(match[4]);
82
- if (parsedPrerelease === null) return null;
83
- if (parsedPrerelease.length > 0 && (major === null || minor === null || patch === null)) return null;
84
- return { major, minor, patch, prerelease: parsedPrerelease };
145
+
146
+ // src/domains/extensions/runtime-schema.ts
147
+ init_esm_shims();
148
+ import { stripVTControlCharacters } from "node:util";
149
+ var RUNTIME_LIMITS = {
150
+ processes: 4,
151
+ messageBytes: 96 * 1024,
152
+ outputBytes: 64 * 1024,
153
+ argumentBytes: 16 * 1024,
154
+ startupMs: 5e3,
155
+ commandMs: 3e4,
156
+ observationMs: 2e3,
157
+ disposeMs: 250,
158
+ diagnosticsBytes: 64 * 1024
159
+ };
160
+ function record2(value) {
161
+ if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("expected an object");
162
+ return value;
85
163
  }
86
- function compareIdentifiers(left, right) {
87
- if (left === right) return 0;
88
- if (typeof left === "number" && typeof right === "number") return left < right ? -1 : 1;
89
- if (typeof left === "number") return -1;
90
- if (typeof right === "number") return 1;
91
- return left < right ? -1 : 1;
164
+ function keys(value, allowed) {
165
+ for (const key of Object.keys(value)) if (!allowed.includes(key)) throw new Error(`unknown runtime field '${key}'`);
92
166
  }
93
- function compare(left, right) {
94
- for (const key of ["major", "minor", "patch"]) {
95
- if (left[key] !== right[key]) return left[key] < right[key] ? -1 : 1;
96
- }
97
- if (left.prerelease.length === 0 || right.prerelease.length === 0) {
98
- if (left.prerelease.length === right.prerelease.length) return 0;
99
- return left.prerelease.length === 0 ? 1 : -1;
100
- }
101
- const length = Math.max(left.prerelease.length, right.prerelease.length);
102
- for (let index = 0; index < length; index += 1) {
103
- const leftPart = left.prerelease[index];
104
- const rightPart = right.prerelease[index];
105
- if (leftPart === void 0 || rightPart === void 0) {
106
- if (leftPart === rightPart) return 0;
107
- return leftPart === void 0 ? -1 : 1;
108
- }
109
- const order = compareIdentifiers(leftPart, rightPart);
110
- if (order !== 0) return order;
111
- }
112
- return 0;
167
+ function string(value, max) {
168
+ if (typeof value !== "string" || value.length === 0 || value.length > max)
169
+ throw new Error(`expected text of 1-${max} characters`);
170
+ return value;
113
171
  }
114
- function floor(partial) {
115
- return {
116
- major: partial.major ?? 0,
117
- minor: partial.minor ?? 0,
118
- patch: partial.patch ?? 0,
119
- prerelease: partial.prerelease
120
- };
172
+ function array(value, max) {
173
+ if (!Array.isArray(value) || value.length > max) throw new Error(`expected an array of at most ${max} entries`);
174
+ return value;
121
175
  }
122
- function nextWildcard(partial) {
123
- if (partial.major === null) return null;
124
- if (partial.minor === null) return { major: partial.major + 1, minor: 0, patch: 0, prerelease: [] };
125
- if (partial.patch === null) return { major: partial.major, minor: partial.minor + 1, patch: 0, prerelease: [] };
126
- return null;
176
+ function choices(value, allowed) {
177
+ const entries = array(value ?? [], allowed.length).map((item) => {
178
+ if (!allowed.includes(item)) throw new Error(`unsupported runtime capability '${String(item)}'`);
179
+ return item;
180
+ });
181
+ if (new Set(entries).size !== entries.length) throw new Error("duplicate runtime capability");
182
+ return entries;
127
183
  }
128
- function lowerBound(version, inclusive) {
129
- return (candidate) => inclusive ? compare(candidate, version) >= 0 : compare(candidate, version) > 0;
184
+ function parseExtensionRuntime(value) {
185
+ const raw = record2(value);
186
+ keys(raw, ["api", "entrypoint", "commands", "events", "ui"]);
187
+ if (raw.api !== 1) throw new Error("runtime.api must be 1");
188
+ const entrypoint = string(raw.entrypoint, 240);
189
+ if (!entrypoint.endsWith(".mjs")) throw new Error("runtime.entrypoint must be a shipped .mjs file");
190
+ const names = /* @__PURE__ */ new Set();
191
+ const commands = array(raw.commands ?? [], 32).map((value2) => {
192
+ const command = record2(value2);
193
+ keys(command, ["name", "description", "timeoutMs"]);
194
+ const name = string(command.name, 40);
195
+ if (!/^[a-z][a-z0-9_]*$/.test(name) || names.has(name))
196
+ throw new Error(`invalid or duplicate runtime command '${name}'`);
197
+ names.add(name);
198
+ const description = string(command.description, 240);
199
+ const timeoutMs = command.timeoutMs ?? RUNTIME_LIMITS.commandMs;
200
+ if (!Number.isInteger(timeoutMs) || Number(timeoutMs) < 100 || Number(timeoutMs) > 3e5)
201
+ throw new Error("runtime command timeoutMs must be 100-300000");
202
+ return { name, description, timeoutMs: Number(timeoutMs) };
203
+ });
204
+ return {
205
+ api: 1,
206
+ entrypoint,
207
+ commands,
208
+ events: choices(raw.events, ["session_open", "turn_end"]),
209
+ ui: choices(raw.ui, ["status", "panel"])
210
+ };
130
211
  }
131
- function upperBound(version, inclusive) {
132
- return (candidate) => inclusive ? compare(candidate, version) <= 0 : compare(candidate, version) < 0;
212
+ function extensionPlainText(value) {
213
+ return stripVTControlCharacters(value).replace(
214
+ /[\p{Cc}\p{Cf}]/gu,
215
+ (char) => char === "\n" || char === " " ? char : ""
216
+ );
133
217
  }
134
- function core(version) {
135
- return `${version.major}.${version.minor}.${version.patch}`;
218
+ function text(value, max) {
219
+ if (value === "") return "";
220
+ return extensionPlainText(string(value, max));
136
221
  }
137
- function predicatesForToken(token) {
138
- const match = /^(<=|>=|<|>|=|~|\^)?(.+)$/u.exec(token);
139
- if (match === null) return null;
140
- const operator = match[1] ?? "";
141
- const partial = parsePartial(match[2] ?? "");
142
- if (partial === null) return null;
143
- const base = floor(partial);
144
- const wildcardUpper = nextWildcard(partial);
145
- const prereleaseCore = partial.prerelease.length > 0 ? core(base) : null;
146
- if (operator === "" || operator === "=") {
147
- if (partial.major === null) return { predicates: [], prereleaseCore };
148
- if (wildcardUpper !== null) {
149
- return { predicates: [lowerBound(base, true), upperBound(wildcardUpper, false)], prereleaseCore };
222
+ function parseExtensionOutput(value, declaration) {
223
+ if (Buffer.byteLength(JSON.stringify(value) ?? "") > RUNTIME_LIMITS.outputBytes)
224
+ throw new Error("runtime output exceeds 64 KiB");
225
+ const raw = record2(value);
226
+ keys(raw, ["text", "status", "panel"]);
227
+ const output = { text: text(raw.text, 32768) };
228
+ if (raw.status !== void 0) {
229
+ if (!declaration.ui.includes("status")) throw new Error("runtime did not declare status UI");
230
+ if (raw.status === null) output.status = null;
231
+ else {
232
+ const status = record2(raw.status);
233
+ keys(status, ["text", "tone"]);
234
+ const parsed = { text: text(status.text, 160).replaceAll("\n", " ").replaceAll(" ", " ") };
235
+ if (status.tone !== void 0) {
236
+ const [tone] = choices([status.tone], ["neutral", "positive", "warning", "error"]);
237
+ if (tone) parsed.tone = tone;
238
+ }
239
+ output.status = parsed;
150
240
  }
151
- return { predicates: [(candidate) => compare(candidate, base) === 0], prereleaseCore };
152
- }
153
- if (operator === ">=") return { predicates: [lowerBound(base, true)], prereleaseCore };
154
- if (operator === "<") return { predicates: [upperBound(base, false)], prereleaseCore };
155
- if (operator === ">") {
156
- return {
157
- predicates: [wildcardUpper === null ? lowerBound(base, false) : lowerBound(wildcardUpper, true)],
158
- prereleaseCore
159
- };
160
241
  }
161
- if (operator === "<=") {
162
- return {
163
- predicates: [wildcardUpper === null ? upperBound(base, true) : upperBound(wildcardUpper, false)],
164
- prereleaseCore
165
- };
166
- }
167
- if (partial.major === null) return { predicates: [], prereleaseCore };
168
- if (operator === "~") {
169
- const upper2 = partial.minor === null ? { major: partial.major + 1, minor: 0, patch: 0, prerelease: [] } : { major: partial.major, minor: partial.minor + 1, patch: 0, prerelease: [] };
170
- return { predicates: [lowerBound(base, true), upperBound(upper2, false)], prereleaseCore };
171
- }
172
- const upper = partial.major > 0 ? { major: partial.major + 1, minor: 0, patch: 0, prerelease: [] } : partial.minor === null ? { major: 1, minor: 0, patch: 0, prerelease: [] } : (partial.minor ?? 0) > 0 ? { major: 0, minor: (partial.minor ?? 0) + 1, patch: 0, prerelease: [] } : partial.patch === null ? { major: 0, minor: 1, patch: 0, prerelease: [] } : { major: 0, minor: 0, patch: (partial.patch ?? 0) + 1, prerelease: [] };
173
- return { predicates: [lowerBound(base, true), upperBound(upper, false)], prereleaseCore };
174
- }
175
- function predicatesForSet(raw) {
176
- const hyphen = /^(\S+)\s+-\s+(\S+)$/u.exec(raw);
177
- if (hyphen !== null) {
178
- const left = parsePartial(hyphen[1] ?? "");
179
- const right = parsePartial(hyphen[2] ?? "");
180
- if (left === null || right === null || left.major === null || right.major === null) return null;
181
- const rightUpper = nextWildcard(right);
182
- return {
183
- predicates: [
184
- lowerBound(floor(left), true),
185
- rightUpper === null ? upperBound(floor(right), true) : upperBound(rightUpper, false)
186
- ],
187
- prereleaseCores: new Set(
188
- [
189
- left.prerelease.length > 0 ? core(floor(left)) : null,
190
- right.prerelease.length > 0 ? core(floor(right)) : null
191
- ].filter((entry) => entry !== null)
192
- )
193
- };
194
- }
195
- const normalized = raw.replace(/(<=|>=|<|>|=|~|\^)\s+/gu, "$1");
196
- const tokens = normalized.split(/\s+/u).filter((entry) => entry.length > 0);
197
- if (tokens.length === 0) return null;
198
- const predicates = [];
199
- const prereleaseCores = /* @__PURE__ */ new Set();
200
- for (const token of tokens) {
201
- const parsed = predicatesForToken(token);
202
- if (parsed === null) return null;
203
- predicates.push(...parsed.predicates);
204
- if (parsed.prereleaseCore !== null) prereleaseCores.add(parsed.prereleaseCore);
242
+ if (raw.panel !== void 0) {
243
+ if (!declaration.ui.includes("panel")) throw new Error("runtime did not declare panel UI");
244
+ const panel = record2(raw.panel);
245
+ keys(panel, ["title", "sections"]);
246
+ const parsed = { title: text(panel.title, 120), sections: [] };
247
+ for (const value2 of array(panel.sections, 16)) {
248
+ const section = record2(value2);
249
+ if (section.kind === "text") {
250
+ keys(section, ["kind", "text"]);
251
+ parsed.sections.push({ kind: "text", text: text(section.text, 8192) });
252
+ } else if (section.kind === "metrics") {
253
+ keys(section, ["kind", "items"]);
254
+ parsed.sections.push({
255
+ kind: "metrics",
256
+ items: array(section.items, 32).map((value3) => {
257
+ const item = record2(value3);
258
+ keys(item, ["label", "value"]);
259
+ return { label: text(item.label, 120), value: text(item.value, 240) };
260
+ })
261
+ });
262
+ } else if (section.kind === "table") {
263
+ keys(section, ["kind", "columns", "rows"]);
264
+ const columns = array(section.columns, 8).map((value3) => text(value3, 80));
265
+ if (columns.length === 0) throw new Error("table needs columns");
266
+ const rows = array(section.rows, 100).map((row) => {
267
+ const cells = array(row, columns.length);
268
+ if (cells.length !== columns.length) throw new Error("table row width differs from columns");
269
+ return cells.map((value3) => text(value3, 240));
270
+ });
271
+ parsed.sections.push({ kind: "table", columns, rows });
272
+ } else throw new Error("unsupported panel section");
273
+ }
274
+ output.panel = parsed;
205
275
  }
206
- return { predicates, prereleaseCores };
207
- }
208
- function parseRange(range) {
209
- const trimmed = range.trim();
210
- if (trimmed.length === 0 || trimmed.length > MAX_RANGE_CHARS) return null;
211
- const sets = trimmed.split("||");
212
- if (sets.some((set) => set.trim().length === 0)) return null;
213
- const parsed = sets.map((set) => predicatesForSet(set.trim()));
214
- return parsed.every((set) => set !== null) ? parsed : null;
276
+ return output;
215
277
  }
216
- function isValidSemVerRange(range) {
217
- return parseRange(range) !== null;
218
- }
219
- function satisfiesSemVerRange(version, range) {
220
- const candidate = parseSemVer(version);
221
- const sets = parseRange(range);
222
- if (candidate === null || sets === null) return false;
223
- return sets.some((set) => {
224
- if (candidate.prerelease.length > 0 && !set.prereleaseCores.has(core(candidate))) return false;
225
- return set.predicates.every((predicate) => predicate(candidate));
226
- });
227
- }
228
- function evaluateClioCompatibility(range, runningVersion = getVersionInfo().clio) {
229
- const rangeValid = isValidSemVerRange(range);
230
- return {
231
- rangeValid,
232
- satisfied: rangeValid && satisfiesSemVerRange(runningVersion, range),
233
- runningVersion
234
- };
278
+ function extensionPanelText(panel) {
279
+ return [
280
+ panel.title,
281
+ ...panel.sections.flatMap((section) => {
282
+ if (section.kind === "text") return [section.text];
283
+ if (section.kind === "metrics") return section.items.map((item) => `${item.label}: ${item.value}`);
284
+ return [section.columns.join(" | "), ...section.rows.map((row) => row.join(" | "))];
285
+ })
286
+ ].join("\n\n");
235
287
  }
236
288
 
237
289
  // src/domains/extensions/discovery.ts
238
290
  var MANIFEST_NAMES = ["clio-coder-extension.yaml", "clio-coder-extension.yml", "clio-coder-extension.json"];
239
- var MANIFEST_KEYS = /* @__PURE__ */ new Set([
240
- "manifestVersion",
241
- "id",
242
- "name",
243
- "version",
244
- "description",
245
- "resources",
246
- "tools",
247
- "settings",
248
- "compatibility"
249
- ]);
250
- var RESOURCE_KEYS = /* @__PURE__ */ new Set(["skills", "prompts", "agents", "fleets", "themes"]);
291
+ var MANIFEST_KEYS = /* @__PURE__ */ new Set(["id", "name", "version", "description", "compatibility", "capabilities", "runtime"]);
251
292
  var COMPATIBILITY_KEYS = /* @__PURE__ */ new Set(["clio"]);
293
+ var PLUGIN_OWNED_KEYS = /* @__PURE__ */ new Set(["resources", "skills", "prompts", "agents", "fleets", "themes"]);
294
+ var PLUGIN_GUIDANCE = "domain resources belong in a plugin: clio-coder library install <path>";
252
295
  function compareNames(a, b) {
253
296
  return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
254
297
  }
@@ -279,168 +322,22 @@ function rejectUnknownKeys(value, allowed, label, manifestPath, diagnostics) {
279
322
  }
280
323
  }
281
324
  }
282
- function normalizeResources(value, manifestPath, diagnostics) {
283
- if (value === void 0) return {};
284
- if (!isRecord(value)) {
285
- diagnostics.push({ type: "error", message: "resources must be an object", path: manifestPath });
286
- return {};
287
- }
288
- rejectUnknownKeys(value, RESOURCE_KEYS, "resources", manifestPath, diagnostics);
289
- const out = {};
290
- for (const kind of RESOURCE_KEYS) {
291
- if (value[kind] === void 0) continue;
292
- const resourcePath = trimString(value[kind]);
293
- if (!resourcePath) {
294
- diagnostics.push({
295
- type: "error",
296
- message: `resources.${kind} must be a non-empty string`,
297
- path: manifestPath
298
- });
299
- continue;
300
- }
301
- out[kind] = resourcePath;
302
- }
303
- return out;
304
- }
305
- function contained(root, candidate) {
306
- const relative = path.relative(root, candidate);
307
- return relative === "" || !relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative);
308
- }
309
- function validateResourceTree(root, resourcePath, kind, diagnostics) {
310
- if (path.isAbsolute(resourcePath)) {
311
- diagnostics.push({ type: "error", message: `resources.${kind} must be relative`, path: resourcePath });
312
- return;
313
- }
314
- const resolvedRoot = path.resolve(root);
315
- const resolved = path.resolve(resolvedRoot, resourcePath);
316
- if (!contained(resolvedRoot, resolved) || resolved === resolvedRoot) {
317
- diagnostics.push({ type: "error", message: `resources.${kind} escapes the extension root`, path: resourcePath });
318
- return;
319
- }
320
- let canonicalRoot;
321
- let canonicalResource;
322
- try {
323
- canonicalRoot = realpathSync(resolvedRoot);
324
- canonicalResource = realpathSync(resolved);
325
- if (!statSync(resolved).isDirectory()) {
326
- diagnostics.push({ type: "error", message: `resources.${kind} is not a directory`, path: resolved });
327
- return;
328
- }
329
- } catch (error) {
325
+ function rejectManifestKeys(value, manifestPath, diagnostics) {
326
+ for (const key of Object.keys(value).sort()) {
327
+ if (MANIFEST_KEYS.has(key)) continue;
330
328
  diagnostics.push({
331
329
  type: "error",
332
- message: `resources.${kind} cannot be resolved: ${error instanceof Error ? error.message : String(error)}`,
333
- path: resolved
330
+ message: PLUGIN_OWNED_KEYS.has(key) ? `harness extensions cannot declare '${key}'; ${PLUGIN_GUIDANCE}` : `unknown manifest key '${key}'`,
331
+ path: manifestPath
334
332
  });
335
- return;
336
- }
337
- if (!contained(canonicalRoot, canonicalResource)) {
338
- diagnostics.push({ type: "error", message: `resources.${kind} escapes through a symbolic link`, path: resolved });
339
- return;
340
333
  }
341
- const pending = [resolved];
342
- while (pending.length > 0) {
343
- const directory = pending.pop();
344
- if (!directory) continue;
345
- for (const entry of readdirSync(directory, { withFileTypes: true }).sort(compareNames)) {
346
- const candidate = path.join(directory, entry.name);
347
- if (entry.isSymbolicLink()) {
348
- try {
349
- const canonicalTarget = realpathSync(candidate);
350
- if (!contained(canonicalRoot, canonicalTarget)) {
351
- diagnostics.push({
352
- type: "error",
353
- message: `resources.${kind} contains an escaping symbolic link`,
354
- path: candidate
355
- });
356
- continue;
357
- }
358
- const targetStat = statSync(candidate);
359
- if (!targetStat.isDirectory() && !targetStat.isFile()) {
360
- diagnostics.push({
361
- type: "error",
362
- message: `resources.${kind} contains a symbolic link to an unsupported filesystem entry`,
363
- path: candidate
364
- });
365
- } else if (targetStat.isFile() && targetStat.nlink !== 1) {
366
- diagnostics.push({
367
- type: "error",
368
- message: `resources.${kind} contains a symbolic link to a hard-linked file`,
369
- path: candidate
370
- });
371
- }
372
- } catch (error) {
373
- diagnostics.push({
374
- type: "error",
375
- message: `resources.${kind} contains an unresolved symbolic link: ${error instanceof Error ? error.message : String(error)}`,
376
- path: candidate
377
- });
378
- }
379
- } else if (entry.isDirectory()) {
380
- pending.push(candidate);
381
- } else if (entry.isFile()) {
382
- try {
383
- if (lstatSync(candidate).nlink !== 1) {
384
- diagnostics.push({
385
- type: "error",
386
- message: `resources.${kind} contains a hard-linked file`,
387
- path: candidate
388
- });
389
- }
390
- } catch (error) {
391
- diagnostics.push({
392
- type: "error",
393
- message: `resources.${kind} entry could not be inspected: ${error instanceof Error ? error.message : String(error)}`,
394
- path: candidate
395
- });
396
- }
397
- } else {
398
- diagnostics.push({
399
- type: "error",
400
- message: `resources.${kind} contains an unsupported filesystem entry`,
401
- path: candidate
402
- });
403
- }
404
- }
405
- }
406
- }
407
- function validateResourceRoots(root, resources, diagnostics) {
408
- for (const [kind, resourcePath] of Object.entries(resources)) {
409
- if (resourcePath) validateResourceTree(root, resourcePath, kind, diagnostics);
410
- }
411
- }
412
- function stringArray(value, field, manifestPath, diagnostics) {
413
- if (value === void 0) return void 0;
414
- if (!Array.isArray(value)) {
415
- diagnostics.push({ type: "error", message: `${field} must be an array of non-empty strings`, path: manifestPath });
416
- return void 0;
417
- }
418
- const out = [];
419
- const seen = /* @__PURE__ */ new Set();
420
- for (const entry of value) {
421
- const parsed = trimString(entry);
422
- if (!parsed) {
423
- diagnostics.push({ type: "error", message: `${field} must contain only non-empty strings`, path: manifestPath });
424
- continue;
425
- }
426
- if (seen.has(parsed)) {
427
- diagnostics.push({ type: "error", message: `${field} contains duplicate entry '${parsed}'`, path: manifestPath });
428
- continue;
429
- }
430
- seen.add(parsed);
431
- out.push(parsed);
432
- }
433
- return out.length > 0 ? out : void 0;
434
334
  }
435
335
  function parseExtensionManifest(value, manifestPath) {
436
336
  const diagnostics = [];
437
337
  if (!isRecord(value)) {
438
338
  return { diagnostics: [{ type: "error", message: "extension manifest must be an object", path: manifestPath }] };
439
339
  }
440
- rejectUnknownKeys(value, MANIFEST_KEYS, "manifest", manifestPath, diagnostics);
441
- if (value.manifestVersion !== 1) {
442
- diagnostics.push({ type: "error", message: "manifestVersion must be 1", path: manifestPath });
443
- }
340
+ rejectManifestKeys(value, manifestPath, diagnostics);
444
341
  const id = trimString(value.id);
445
342
  const name = trimString(value.name) ?? id;
446
343
  const version = trimString(value.version);
@@ -452,9 +349,30 @@ function parseExtensionManifest(value, manifestPath) {
452
349
  }
453
350
  if (!version) diagnostics.push({ type: "error", message: "version is required", path: manifestPath });
454
351
  if (!description) diagnostics.push({ type: "error", message: "description is required", path: manifestPath });
455
- const resources = normalizeResources(value.resources, manifestPath, diagnostics);
456
- const tools = stringArray(value.tools, "tools", manifestPath, diagnostics);
457
- const settings = stringArray(value.settings, "settings", manifestPath, diagnostics);
352
+ let capabilities;
353
+ let runtime;
354
+ if (value.runtime !== void 0) {
355
+ try {
356
+ runtime = parseExtensionRuntime(value.runtime);
357
+ } catch (error) {
358
+ diagnostics.push({
359
+ type: "error",
360
+ message: error instanceof Error ? error.message : String(error),
361
+ path: manifestPath
362
+ });
363
+ }
364
+ }
365
+ if (value.capabilities !== void 0) {
366
+ try {
367
+ capabilities = parseExtensionCapabilities(value.capabilities, id ?? "");
368
+ } catch (error) {
369
+ diagnostics.push({
370
+ type: "error",
371
+ message: error instanceof Error ? error.message : String(error),
372
+ path: manifestPath
373
+ });
374
+ }
375
+ }
458
376
  let compatibility;
459
377
  if (value.compatibility !== void 0) {
460
378
  if (!isRecord(value.compatibility)) {
@@ -489,16 +407,9 @@ function parseExtensionManifest(value, manifestPath) {
489
407
  if (!id || !name || !version || !description || diagnostics.some((diag) => diag.type === "error")) {
490
408
  return { diagnostics };
491
409
  }
492
- const manifest = {
493
- manifestVersion: 1,
494
- id,
495
- name,
496
- version,
497
- description,
498
- resources
499
- };
500
- if (tools) manifest.tools = tools;
501
- if (settings) manifest.settings = settings;
410
+ const manifest = { id, name, version, description };
411
+ if (runtime) manifest.runtime = runtime;
412
+ if (capabilities) manifest.capabilities = capabilities;
502
413
  if (compatibility && Object.keys(compatibility).length > 0) manifest.compatibility = compatibility;
503
414
  const clioRange = manifest.compatibility?.clio;
504
415
  if (clioRange !== void 0) {
@@ -515,7 +426,7 @@ function parseExtensionManifest(value, manifestPath) {
515
426
  }
516
427
  function findExtensionManifestPath(root) {
517
428
  for (const name of MANIFEST_NAMES) {
518
- const candidate = path.join(root, name);
429
+ const candidate = path2.join(root, name);
519
430
  try {
520
431
  if (statSync(candidate).isFile()) return candidate;
521
432
  } catch {
@@ -534,7 +445,28 @@ function loadManifestFromRoot(root) {
534
445
  }
535
446
  try {
536
447
  const parsed = parseExtensionManifest(readJsonOrYaml(manifestPath), manifestPath);
537
- if (parsed.manifest) validateResourceRoots(root, parsed.manifest.resources, parsed.diagnostics);
448
+ if (parsed.manifest?.runtime) {
449
+ try {
450
+ resolveExtensionEntrypoint(root, parsed.manifest.runtime.entrypoint);
451
+ } catch (error) {
452
+ parsed.diagnostics.push({
453
+ type: "error",
454
+ message: `runtime: ${error instanceof Error ? error.message : String(error)}`,
455
+ path: manifestPath
456
+ });
457
+ }
458
+ }
459
+ for (const tool of parsed.manifest?.capabilities?.tools ?? []) {
460
+ try {
461
+ resolveExtensionEntrypoint(root, tool.entrypoint);
462
+ } catch (error) {
463
+ parsed.diagnostics.push({
464
+ type: "error",
465
+ message: `command tool ${tool.name}: ${error instanceof Error ? error.message : String(error)}`,
466
+ path: manifestPath
467
+ });
468
+ }
469
+ }
538
470
  return {
539
471
  path: root,
540
472
  manifestPath,
@@ -553,7 +485,7 @@ function loadManifestFromRoot(root) {
553
485
  }
554
486
  }
555
487
  function discoverExtensionPackages(root) {
556
- const full = path.resolve(root);
488
+ const full = path2.resolve(root);
557
489
  if (!existsSync(full)) {
558
490
  return [{ path: full, valid: false, diagnostics: [{ type: "error", message: "path does not exist", path: full }] }];
559
491
  }
@@ -586,7 +518,7 @@ function discoverExtensionPackages(root) {
586
518
  }
587
519
  let canonicalFull;
588
520
  try {
589
- canonicalFull = realpathSync(full);
521
+ canonicalFull = realpathSync2(full);
590
522
  } catch (error) {
591
523
  return [
592
524
  {
@@ -627,10 +559,10 @@ function discoverExtensionPackages(root) {
627
559
  }
628
560
  for (const entry of entries.sort(compareNames)) {
629
561
  if (entry.name.startsWith(".")) continue;
630
- const child = path.join(canonicalFull, entry.name);
562
+ const child = path2.join(canonicalFull, entry.name);
631
563
  try {
632
564
  if (!entry.isDirectory() && !(entry.isSymbolicLink() && statSync(child).isDirectory())) continue;
633
- const canonicalChild = realpathSync(child);
565
+ const canonicalChild = realpathSync2(child);
634
566
  const spellings = spellingsByCanonicalRoot.get(canonicalChild) ?? [];
635
567
  spellings.push(child);
636
568
  spellingsByCanonicalRoot.set(canonicalChild, spellings);
@@ -688,163 +620,9 @@ function discoverExtensionPackages(root) {
688
620
 
689
621
  // src/domains/extensions/state.ts
690
622
  init_esm_shims();
691
- import { createHash as createHash2 } from "node:crypto";
692
- import {
693
- cpSync,
694
- existsSync as existsSync2,
695
- lstatSync as lstatSync3,
696
- mkdirSync,
697
- readdirSync as readdirSync3,
698
- readFileSync as readFileSync3,
699
- realpathSync as realpathSync3,
700
- renameSync,
701
- rmSync
702
- } from "node:fs";
703
- import path3 from "node:path";
704
-
705
- // src/domains/extensions/integrity.ts
706
- init_esm_shims();
707
623
  import { createHash } from "node:crypto";
708
- import {
709
- closeSync,
710
- constants,
711
- fstatSync,
712
- lstatSync as lstatSync2,
713
- openSync,
714
- readdirSync as readdirSync2,
715
- readFileSync as readFileSync2,
716
- readlinkSync,
717
- realpathSync as realpathSync2
718
- } from "node:fs";
719
- import path2 from "node:path";
720
- function contained2(root, candidate) {
721
- const relative = path2.relative(root, candidate);
722
- return relative === "" || !relative.startsWith(`..${path2.sep}`) && relative !== ".." && !path2.isAbsolute(relative);
723
- }
724
- function digestFrame(hash, kind, relativePath, payload) {
725
- const header = Buffer.from(
726
- `${kind}\0${relativePath.replaceAll(path2.sep, "/")}\0${payload?.byteLength ?? 0}\0`,
727
- "utf8"
728
- );
729
- hash.update(header);
730
- if (payload) hash.update(payload);
731
- hash.update("\0");
732
- }
733
- function sameFileState(left, right) {
734
- return left.dev === right.dev && left.ino === right.ino && left.mode === right.mode && left.nlink === right.nlink && left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
735
- }
736
- function readStableRegularFile(filePath, inspected) {
737
- const fd = openSync(filePath, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
738
- try {
739
- const opened = fstatSync(fd);
740
- if (!opened.isFile() || opened.nlink !== 1 || !sameFileState(inspected, opened)) {
741
- throw new Error(`extension file changed while being opened: ${filePath}`);
742
- }
743
- const payload = readFileSync2(fd);
744
- if (!sameFileState(opened, fstatSync(fd))) {
745
- throw new Error(`extension file changed while being hashed: ${filePath}`);
746
- }
747
- return payload;
748
- } finally {
749
- closeSync(fd);
750
- }
751
- }
752
- function readStableContainedLink(linkPath, inspected, canonicalRoot) {
753
- const canonicalTarget = realpathSync2(linkPath);
754
- if (!contained2(canonicalRoot, canonicalTarget)) {
755
- throw new Error(`symbolic link escapes the extension root: ${linkPath}`);
756
- }
757
- const target = readlinkSync(linkPath);
758
- const after = lstatSync2(linkPath);
759
- if (!after.isSymbolicLink() || !sameFileState(inspected, after)) {
760
- throw new Error(`symbolic link changed while being hashed: ${linkPath}`);
761
- }
762
- const canonicalAfter = realpathSync2(linkPath);
763
- if (canonicalAfter !== canonicalTarget || !contained2(canonicalRoot, canonicalAfter)) {
764
- throw new Error(`symbolic link changed or escapes the extension root: ${linkPath}`);
765
- }
766
- return Buffer.from(target, "utf8");
767
- }
768
- function assertStableDirectory(directoryPath, inspected, canonicalDirectory, canonicalRoot, expectedEntries) {
769
- const after = lstatSync2(directoryPath);
770
- if (!after.isDirectory() || !sameFileState(inspected, after)) {
771
- throw new Error(`extension directory changed while being hashed: ${directoryPath}`);
772
- }
773
- const canonicalAfter = realpathSync2(directoryPath);
774
- if (canonicalAfter !== canonicalDirectory || !contained2(canonicalRoot, canonicalAfter)) {
775
- throw new Error(`extension directory changed or escapes the extension root: ${directoryPath}`);
776
- }
777
- if (expectedEntries !== void 0) {
778
- const currentEntries = readdirSync2(directoryPath).sort();
779
- if (currentEntries.length !== expectedEntries.length || currentEntries.some((entry, index) => entry !== expectedEntries[index])) {
780
- throw new Error(`extension directory entries changed while being hashed: ${directoryPath}`);
781
- }
782
- }
783
- }
784
- function readStableDirectory(directoryPath, inspected, canonicalRoot) {
785
- const canonicalDirectory = realpathSync2(directoryPath);
786
- if (!contained2(canonicalRoot, canonicalDirectory)) {
787
- throw new Error(`extension directory escapes the extension root: ${directoryPath}`);
788
- }
789
- const entries = readdirSync2(directoryPath).sort();
790
- assertStableDirectory(directoryPath, inspected, canonicalDirectory, canonicalRoot);
791
- return { canonicalDirectory, entries };
792
- }
793
- function extensionContentDigestWithCapture(root, options = {}) {
794
- const resolvedRoot = path2.resolve(root);
795
- const rootStat = lstatSync2(resolvedRoot);
796
- if (rootStat.isSymbolicLink()) {
797
- throw new Error(`extension root must be a directory, not a symbolic link: ${resolvedRoot}`);
798
- }
799
- if (!rootStat.isDirectory()) {
800
- throw new Error(`extension root must be a directory: ${resolvedRoot}`);
801
- }
802
- const canonicalRoot = realpathSync2(resolvedRoot);
803
- const canonicalizedRootStat = lstatSync2(resolvedRoot);
804
- if (!canonicalizedRootStat.isDirectory() || !sameFileState(rootStat, canonicalizedRootStat)) {
805
- throw new Error(`extension root changed while being canonicalized: ${resolvedRoot}`);
806
- }
807
- const hash = createHash("sha256");
808
- const requested = new Set((options.capture ?? []).map((entry) => entry.replaceAll(path2.sep, "/")));
809
- const captured = /* @__PURE__ */ new Map();
810
- const visit = (absolutePath, relativePath) => {
811
- const stat = lstatSync2(absolutePath);
812
- if (stat.isSymbolicLink()) {
813
- if (relativePath === "") {
814
- throw new Error(`extension root changed to a symbolic link while being hashed: ${absolutePath}`);
815
- }
816
- digestFrame(hash, "link", relativePath, readStableContainedLink(absolutePath, stat, canonicalRoot));
817
- return;
818
- }
819
- if (stat.isDirectory()) {
820
- digestFrame(hash, "directory", relativePath);
821
- const { canonicalDirectory, entries } = readStableDirectory(absolutePath, stat, canonicalRoot);
822
- for (const entry of entries) {
823
- visit(path2.join(absolutePath, entry), relativePath ? path2.join(relativePath, entry) : entry);
824
- }
825
- assertStableDirectory(absolutePath, stat, canonicalDirectory, canonicalRoot, entries);
826
- return;
827
- }
828
- if (stat.isFile()) {
829
- if (stat.nlink !== 1) {
830
- throw new Error(`hard-linked file is unsupported in an extension: ${absolutePath}`);
831
- }
832
- const payload = readStableRegularFile(absolutePath, stat);
833
- digestFrame(hash, "file", relativePath, payload);
834
- const key = relativePath.replaceAll(path2.sep, "/");
835
- if (requested.has(key)) captured.set(key, payload);
836
- return;
837
- }
838
- throw new Error(`unsupported filesystem entry in extension: ${absolutePath}`);
839
- };
840
- visit(resolvedRoot, "");
841
- return { digest: hash.digest("hex"), captured };
842
- }
843
- function extensionContentDigest(root) {
844
- return extensionContentDigestWithCapture(root).digest;
845
- }
846
-
847
- // src/domains/extensions/state.ts
624
+ import { cpSync, existsSync as existsSync2, mkdirSync, readdirSync as readdirSync2, readFileSync as readFileSync2, realpathSync as realpathSync3, renameSync, rmSync } from "node:fs";
625
+ import path3 from "node:path";
848
626
  var DEFAULT_STATE = { version: 1, disabled: [], installed: {} };
849
627
  function extensionBaseDir(scope, cwd = process.cwd()) {
850
628
  return scope === "user" ? path3.join(clioConfigDir(), "extensions") : path3.join(path3.resolve(cwd), ".clio-coder", "extensions");
@@ -861,7 +639,7 @@ function packageRecoveryPath(root, label) {
861
639
  function preserveFile(filePath, label) {
862
640
  if (!existsSync2(filePath)) return void 0;
863
641
  const backupPath = recoveryPath(filePath, label);
864
- safeResourceWrite(backupPath, readFileSync3(filePath));
642
+ safeResourceWrite(backupPath, readFileSync2(filePath));
865
643
  return backupPath;
866
644
  }
867
645
  function scopeRank(scope) {
@@ -871,7 +649,7 @@ function readState(scope, cwd = process.cwd()) {
871
649
  const filePath = statePath(scope, cwd);
872
650
  if (!existsSync2(filePath)) return { status: "absent", state: structuredClone(DEFAULT_STATE) };
873
651
  try {
874
- const parsed = JSON.parse(readFileSync3(filePath, "utf8"));
652
+ const parsed = JSON.parse(readFileSync2(filePath, "utf8"));
875
653
  if (!isRecord(parsed) || parsed.version !== 1) throw new Error("state must be a version 1 object");
876
654
  if (!Array.isArray(parsed.disabled) || !parsed.disabled.every((entry) => typeof entry === "string")) {
877
655
  throw new Error("state.disabled must be an array of strings");
@@ -941,7 +719,7 @@ function installedFromRoot(root, scope, stateResult, cwd, fallbackId) {
941
719
  } else if (!expectedDigest) {
942
720
  diagnostics.push({
943
721
  type: "error",
944
- message: `extension ${id} install provenance has no content digest; run clio-coder upgrade, then reinstall with --force if it remains unverifiable`,
722
+ message: `extension ${id} install provenance has no content digest; reinstall with --force`,
945
723
  path: statePath(scope, cwd)
946
724
  });
947
725
  } else {
@@ -977,7 +755,7 @@ function installedFromRoot(root, scope, stateResult, cwd, fallbackId) {
977
755
  scope,
978
756
  ...provenance?.source ? { sourcePath: provenance.source } : {},
979
757
  canonicalRoot: realpathSync3(root),
980
- manifestDigest: createHash2("sha256").update(manifestBytes).digest("hex"),
758
+ manifestDigest: createHash("sha256").update(manifestBytes).digest("hex"),
981
759
  contentDigest: expectedDigest
982
760
  } : void 0;
983
761
  const entry = {
@@ -985,6 +763,8 @@ function installedFromRoot(root, scope, stateResult, cwd, fallbackId) {
985
763
  name: manifest?.name ?? id,
986
764
  version: manifest?.version ?? "unknown",
987
765
  description: manifest?.description ?? "Installed extension has an invalid manifest.",
766
+ ...manifest?.capabilities ? { capabilities: manifest.capabilities } : {},
767
+ ...manifest?.runtime ? { runtime: manifest.runtime } : {},
988
768
  scope,
989
769
  rootPath: root,
990
770
  manifestPath: candidate.manifestPath ?? root,
@@ -995,7 +775,6 @@ function installedFromRoot(root, scope, stateResult, cwd, fallbackId) {
995
775
  loadable: false,
996
776
  ...extensionProvenance ? { provenance: extensionProvenance } : {},
997
777
  ...observedDigest ? { observedContentDigest: observedDigest } : {},
998
- resources: manifest?.resources ?? {},
999
778
  diagnostics
1000
779
  };
1001
780
  return { entry, ...extensionProvenance && captured ? { captured } : {} };
@@ -1005,7 +784,7 @@ function listScope(scope, cwd = process.cwd()) {
1005
784
  if (!existsSync2(base)) return [];
1006
785
  const state = readState(scope, cwd);
1007
786
  const out = [];
1008
- for (const entry of readdirSync3(base, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
787
+ for (const entry of readdirSync2(base, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
1009
788
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
1010
789
  const root = path3.join(base, entry.name);
1011
790
  const installed = installedFromRoot(root, scope, state, cwd, entry.name);
@@ -1013,84 +792,24 @@ function listScope(scope, cwd = process.cwd()) {
1013
792
  }
1014
793
  return out;
1015
794
  }
1016
- function upgradeLegacyExtensionInstallState(cwd = process.cwd(), scopes = ["user", "project"]) {
1017
- const reports = [];
1018
- for (const scope of scopes) {
1019
- const filePath = statePath(scope, cwd);
1020
- const report = { scope, statePath: filePath, upgraded: [], refused: [] };
1021
- const stateResult = readState(scope, cwd);
1022
- if (stateResult.status === "absent") {
1023
- reports.push(report);
1024
- continue;
1025
- }
1026
- if (stateResult.status === "corrupt") {
1027
- report.refused.push({ id: "<state>", reason: `install state is corrupt: ${stateResult.message}` });
1028
- reports.push(report);
1029
- continue;
1030
- }
1031
- const next = structuredClone(stateResult.state);
1032
- const verified = /* @__PURE__ */ new Map();
1033
- for (const [id, record] of Object.entries(next.installed)) {
1034
- if (record.contentDigest) continue;
1035
- const root = path3.join(extensionBaseDir(scope, cwd), id);
1036
- try {
1037
- if (!lstatSync3(root).isDirectory()) throw new Error("installed path is not a directory");
1038
- const candidate = loadManifestFromRoot(root);
1039
- if (!candidate.valid || !candidate.manifest) {
1040
- throw new Error(candidate.diagnostics.map((diagnostic) => diagnostic.message).join("; ") || "manifest is invalid");
1041
- }
1042
- if (candidate.manifest.id !== id) {
1043
- throw new Error(`manifest id ${candidate.manifest.id} does not match install record ${id}`);
1044
- }
1045
- const digest = extensionContentDigest(root);
1046
- record.contentDigest = digest;
1047
- verified.set(id, { root, digest });
1048
- report.upgraded.push(id);
1049
- } catch (error) {
1050
- report.refused.push({ id, reason: error instanceof Error ? error.message : String(error) });
1051
- }
1052
- }
1053
- if (report.upgraded.length > 0) {
1054
- const backupPath = `${filePath}.pre-digest.bak`;
1055
- safeResourceWrite(filePath, `${JSON.stringify(next, null, 2)}
1056
- `, {
1057
- encoding: "utf8",
1058
- backup: { path: backupPath },
1059
- beforeRename: () => {
1060
- for (const [id, expected] of verified) {
1061
- const candidate = loadManifestFromRoot(expected.root);
1062
- if (!candidate.valid || candidate.manifest?.id !== id) {
1063
- throw new Error(`extension ${id} became invalid during digest migration`);
1064
- }
1065
- const observed = extensionContentDigest(expected.root);
1066
- if (observed !== expected.digest) throw new Error(`extension ${id} changed during digest migration`);
1067
- }
1068
- }
1069
- });
1070
- report.backupPath = backupPath;
1071
- }
1072
- reports.push(report);
1073
- }
1074
- return reports;
1075
- }
1076
795
  function listInstalledExtensions(cwd = process.cwd(), options = {}) {
1077
- return listInstalledExtensionRecords(cwd, options).map((record) => record.entry);
796
+ return listInstalledExtensionRecords(cwd, options).map((record3) => record3.entry);
1078
797
  }
1079
798
  function listInstalledExtensionRecords(cwd = process.cwd(), options = {}) {
1080
799
  const scopes = options.scope ? [options.scope] : ["user", "project"];
1081
800
  const records = scopes.flatMap((scope) => listScope(scope, cwd));
1082
801
  const byId = /* @__PURE__ */ new Map();
1083
- for (const record of records) {
1084
- const entry = record.entry;
802
+ for (const record3 of records) {
803
+ const entry = record3.entry;
1085
804
  const list = byId.get(entry.id) ?? [];
1086
- list.push(record);
805
+ list.push(record3);
1087
806
  byId.set(entry.id, list);
1088
807
  }
1089
808
  for (const group of byId.values()) {
1090
- const winner = group.filter((record) => record.entry.valid && record.entry.compatible).sort((a, b) => scopeRank(a.entry.scope) - scopeRank(b.entry.scope)).at(-1);
1091
- for (const record of group) {
1092
- const entry = record.entry;
1093
- entry.effective = record === winner;
809
+ const winner = group.filter((record3) => record3.entry.valid && record3.entry.compatible).sort((a, b) => scopeRank(a.entry.scope) - scopeRank(b.entry.scope)).at(-1);
810
+ for (const record3 of group) {
811
+ const entry = record3.entry;
812
+ entry.effective = record3 === winner;
1094
813
  entry.loadable = entry.valid && entry.compatible && entry.enabled && entry.effective;
1095
814
  if (entry.valid && entry.compatible && !entry.effective && winner) entry.overriddenBy = winner.entry.scope;
1096
815
  }
@@ -1319,11 +1038,16 @@ function removeExtension(id, options = {}) {
1319
1038
  }
1320
1039
 
1321
1040
  export {
1041
+ extensionToolName,
1042
+ resolveExtensionEntrypoint,
1043
+ RUNTIME_LIMITS,
1044
+ extensionPlainText,
1045
+ parseExtensionOutput,
1046
+ extensionPanelText,
1047
+ parseExtensionManifest,
1322
1048
  loadManifestFromRoot,
1323
1049
  discoverExtensionPackages,
1324
- extensionContentDigest,
1325
1050
  extensionBaseDir,
1326
- upgradeLegacyExtensionInstallState,
1327
1051
  listInstalledExtensions,
1328
1052
  listInstalledExtensionRecords,
1329
1053
  installExtension,
@@ -1331,4 +1055,4 @@ export {
1331
1055
  disableExtension,
1332
1056
  removeExtension
1333
1057
  };
1334
- //# sourceMappingURL=chunk-DZK63TZJ.js.map
1058
+ //# sourceMappingURL=chunk-24S3DN22.js.map