@skaile/workspaces 6.0.0 → 6.1.0

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 (320) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/{asset-feeds-PXUWCXVI.js → asset-feeds-HJFV7UPW.js} +26 -18
  3. package/dist/asset-feeds-HJFV7UPW.js.map +1 -0
  4. package/dist/asset-manager/catalog-deployer.js +7 -7
  5. package/dist/asset-manager/index.js +13 -13
  6. package/dist/asset-manager/installer.js +8 -8
  7. package/dist/asset-manager/renderers.js +7 -7
  8. package/dist/asset-manager/src/index.d.ts +192 -5
  9. package/dist/asset-manager/src/index.d.ts.map +1 -1
  10. package/dist/asset-manager/src/installer.d.ts +31 -0
  11. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  12. package/dist/asset-manager/src/mcp-config.d.ts +21 -0
  13. package/dist/asset-manager/src/mcp-config.d.ts.map +1 -1
  14. package/dist/bridge/harnesses/claude-sdk.js +13 -17
  15. package/dist/bridge/harnesses/claude-sdk.js.map +1 -1
  16. package/dist/bridge/harnesses/codex.js +10 -10
  17. package/dist/bridge/harnesses/continue.js +10 -10
  18. package/dist/bridge/harnesses/echo.js +2 -2
  19. package/dist/bridge/harnesses/gemini.js +6 -6
  20. package/dist/bridge/harnesses/goose.js +10 -10
  21. package/dist/bridge/harnesses/omp.js +4 -4
  22. package/dist/bridge/harnesses/opencode.js +10 -10
  23. package/dist/bridge/harnesses/qwen.js +6 -6
  24. package/dist/bridge/index.js +14 -14
  25. package/dist/bridge/src/claude-sdk-surface.d.ts +17 -0
  26. package/dist/bridge/src/claude-sdk-surface.d.ts.map +1 -0
  27. package/dist/bridge/src/harness-model-check.d.ts +15 -0
  28. package/dist/bridge/src/harness-model-check.d.ts.map +1 -1
  29. package/dist/bridge/src/harnesses/claude-sdk.d.ts.map +1 -1
  30. package/dist/bridge/src/index.d.ts +2 -1
  31. package/dist/bridge/src/index.d.ts.map +1 -1
  32. package/dist/bridge/src/normalizer.d.ts +3 -1
  33. package/dist/bridge/src/normalizer.d.ts.map +1 -1
  34. package/dist/{chunk-VJRTDKXS.js → chunk-2LAPHLDH.js} +144 -94
  35. package/dist/chunk-2LAPHLDH.js.map +1 -0
  36. package/dist/{chunk-VXEYX73S.js → chunk-3GMOPFWH.js} +4 -4
  37. package/dist/{chunk-VXEYX73S.js.map → chunk-3GMOPFWH.js.map} +1 -1
  38. package/dist/{chunk-MCUJTNY5.js → chunk-4FVIT5DI.js} +3 -3
  39. package/dist/{chunk-MCUJTNY5.js.map → chunk-4FVIT5DI.js.map} +1 -1
  40. package/dist/{chunk-SZXGRHQQ.js → chunk-4MUDQCBP.js} +4 -4
  41. package/dist/{chunk-SZXGRHQQ.js.map → chunk-4MUDQCBP.js.map} +1 -1
  42. package/dist/{chunk-7CV3HFWJ.js → chunk-5J4NPGFM.js} +3 -3
  43. package/dist/{chunk-7CV3HFWJ.js.map → chunk-5J4NPGFM.js.map} +1 -1
  44. package/dist/{chunk-4XWLB7JB.js → chunk-5Y2KGB4H.js} +69 -34
  45. package/dist/chunk-5Y2KGB4H.js.map +1 -0
  46. package/dist/{chunk-OULSJRXV.js → chunk-6YR4ALVX.js} +6 -6
  47. package/dist/{chunk-OULSJRXV.js.map → chunk-6YR4ALVX.js.map} +1 -1
  48. package/dist/chunk-7HX6FNKL.js +317 -0
  49. package/dist/chunk-7HX6FNKL.js.map +1 -0
  50. package/dist/{chunk-WDAIWDLK.js → chunk-7LP7RCZI.js} +4 -4
  51. package/dist/{chunk-WDAIWDLK.js.map → chunk-7LP7RCZI.js.map} +1 -1
  52. package/dist/{chunk-2UUKCROR.js → chunk-AATHJRKL.js} +4 -4
  53. package/dist/{chunk-2UUKCROR.js.map → chunk-AATHJRKL.js.map} +1 -1
  54. package/dist/{chunk-DUMTLYSO.js → chunk-ABFPSVIS.js} +3 -3
  55. package/dist/{chunk-DUMTLYSO.js.map → chunk-ABFPSVIS.js.map} +1 -1
  56. package/dist/{chunk-TKHJXPSB.js → chunk-AITJ7ELM.js} +140 -26
  57. package/dist/chunk-AITJ7ELM.js.map +1 -0
  58. package/dist/{chunk-Y2TO2U7W.js → chunk-ASWTQQ7E.js} +3 -3
  59. package/dist/{chunk-Y2TO2U7W.js.map → chunk-ASWTQQ7E.js.map} +1 -1
  60. package/dist/{chunk-WYHQUCHR.js → chunk-AZ2H6R5I.js} +51 -25
  61. package/dist/chunk-AZ2H6R5I.js.map +1 -0
  62. package/dist/{chunk-LN6QB7XI.js → chunk-BBBCJSSU.js} +4 -4
  63. package/dist/{chunk-LN6QB7XI.js.map → chunk-BBBCJSSU.js.map} +1 -1
  64. package/dist/{chunk-WEH33JSG.js → chunk-CEKW3KXP.js} +87 -26
  65. package/dist/chunk-CEKW3KXP.js.map +1 -0
  66. package/dist/{chunk-ARWKK325.js → chunk-COYF6IG2.js} +5 -5
  67. package/dist/{chunk-ARWKK325.js.map → chunk-COYF6IG2.js.map} +1 -1
  68. package/dist/{chunk-SNEE6UGY.js → chunk-DGTI65OC.js} +11 -11
  69. package/dist/{chunk-SNEE6UGY.js.map → chunk-DGTI65OC.js.map} +1 -1
  70. package/dist/{chunk-HK7HMEPT.js → chunk-DIGFA7Z5.js} +3 -3
  71. package/dist/{chunk-HK7HMEPT.js.map → chunk-DIGFA7Z5.js.map} +1 -1
  72. package/dist/{chunk-AF432MS3.js → chunk-EJPMNDTP.js} +3 -3
  73. package/dist/{chunk-AF432MS3.js.map → chunk-EJPMNDTP.js.map} +1 -1
  74. package/dist/chunk-EX3GLAL6.js +31 -0
  75. package/dist/chunk-EX3GLAL6.js.map +1 -0
  76. package/dist/{chunk-UVVVR4XO.js → chunk-FKQNBCDW.js} +3 -3
  77. package/dist/{chunk-UVVVR4XO.js.map → chunk-FKQNBCDW.js.map} +1 -1
  78. package/dist/{chunk-GEQSUC6U.js → chunk-GNZBFSRB.js} +3 -3
  79. package/dist/{chunk-GEQSUC6U.js.map → chunk-GNZBFSRB.js.map} +1 -1
  80. package/dist/{chunk-U56GGCC2.js → chunk-HMISULVD.js} +4 -4
  81. package/dist/{chunk-U56GGCC2.js.map → chunk-HMISULVD.js.map} +1 -1
  82. package/dist/{chunk-GN4VVSAA.js → chunk-HPMQRAIF.js} +7 -7
  83. package/dist/{chunk-GN4VVSAA.js.map → chunk-HPMQRAIF.js.map} +1 -1
  84. package/dist/{chunk-OAHVKSQJ.js → chunk-HWNK3F3X.js} +913 -80
  85. package/dist/chunk-HWNK3F3X.js.map +1 -0
  86. package/dist/{chunk-NMI2TWMH.js → chunk-IHFGPHCT.js} +131 -341
  87. package/dist/chunk-IHFGPHCT.js.map +1 -0
  88. package/dist/{chunk-F2GOZMRA.js → chunk-ILLTBKDJ.js} +47 -47
  89. package/dist/chunk-ILLTBKDJ.js.map +1 -0
  90. package/dist/{chunk-FKU57Q5Q.js → chunk-IRYKRKVQ.js} +3 -3
  91. package/dist/{chunk-FKU57Q5Q.js.map → chunk-IRYKRKVQ.js.map} +1 -1
  92. package/dist/{chunk-T2BDID2J.js → chunk-J72MO2WA.js} +8 -8
  93. package/dist/{chunk-T2BDID2J.js.map → chunk-J72MO2WA.js.map} +1 -1
  94. package/dist/{chunk-X3RMRJNR.js → chunk-JRN5QF4C.js} +8 -3
  95. package/dist/chunk-JRN5QF4C.js.map +1 -0
  96. package/dist/{chunk-E3GPGTW3.js → chunk-KUQAJVYT.js} +5 -5
  97. package/dist/{chunk-E3GPGTW3.js.map → chunk-KUQAJVYT.js.map} +1 -1
  98. package/dist/{chunk-WDXZA7QW.js → chunk-LSSYC5IC.js} +2 -2
  99. package/dist/{chunk-WDXZA7QW.js.map → chunk-LSSYC5IC.js.map} +1 -1
  100. package/dist/{chunk-3IXIEHUB.js → chunk-NB7SYQYP.js} +5 -5
  101. package/dist/{chunk-3IXIEHUB.js.map → chunk-NB7SYQYP.js.map} +1 -1
  102. package/dist/{chunk-3JKGY2YC.js → chunk-NUA33BYO.js} +149 -27
  103. package/dist/chunk-NUA33BYO.js.map +1 -0
  104. package/dist/{chunk-VBI7HGHB.js → chunk-QAKUD6QN.js} +2 -2
  105. package/dist/{chunk-VBI7HGHB.js.map → chunk-QAKUD6QN.js.map} +1 -1
  106. package/dist/{chunk-KX2PT5Q4.js → chunk-QEULL4Q3.js} +4 -4
  107. package/dist/{chunk-KX2PT5Q4.js.map → chunk-QEULL4Q3.js.map} +1 -1
  108. package/dist/{chunk-YGRZNFRO.js → chunk-QSYQOTWN.js} +3 -3
  109. package/dist/{chunk-YGRZNFRO.js.map → chunk-QSYQOTWN.js.map} +1 -1
  110. package/dist/{chunk-DHYSUJ3H.js → chunk-RDTLPOPD.js} +4 -4
  111. package/dist/{chunk-DHYSUJ3H.js.map → chunk-RDTLPOPD.js.map} +1 -1
  112. package/dist/{chunk-GOCWM7FN.js → chunk-RHN5MRQO.js} +21 -4
  113. package/dist/chunk-RHN5MRQO.js.map +1 -0
  114. package/dist/{chunk-UL22SDGR.js → chunk-S2XHGWQC.js} +161 -123
  115. package/dist/chunk-S2XHGWQC.js.map +1 -0
  116. package/dist/{chunk-4DWBSTYA.js → chunk-SVTMNSPI.js} +22 -5
  117. package/dist/chunk-SVTMNSPI.js.map +1 -0
  118. package/dist/{chunk-QOM5Z62G.js → chunk-UI745XC3.js} +9 -22
  119. package/dist/chunk-UI745XC3.js.map +1 -0
  120. package/dist/{chunk-L4YKW5AY.js → chunk-VMVDAZLA.js} +20 -8
  121. package/dist/chunk-VMVDAZLA.js.map +1 -0
  122. package/dist/{chunk-H6UVIKQ2.js → chunk-VYVTEMAW.js} +3 -3
  123. package/dist/{chunk-H6UVIKQ2.js.map → chunk-VYVTEMAW.js.map} +1 -1
  124. package/dist/{chunk-SRODW6M2.js → chunk-X3YGUKCG.js} +3 -3
  125. package/dist/{chunk-SRODW6M2.js.map → chunk-X3YGUKCG.js.map} +1 -1
  126. package/dist/{chunk-JDR6ILCW.js → chunk-XGULGQA3.js} +3 -3
  127. package/dist/{chunk-JDR6ILCW.js.map → chunk-XGULGQA3.js.map} +1 -1
  128. package/dist/{chunk-7XSAW5OC.js → chunk-YLLVSR2U.js} +4 -4
  129. package/dist/{chunk-7XSAW5OC.js.map → chunk-YLLVSR2U.js.map} +1 -1
  130. package/dist/{chunk-6Z5KTFJT.js → chunk-Z3VKUWAX.js} +3 -3
  131. package/dist/{chunk-6Z5KTFJT.js.map → chunk-Z3VKUWAX.js.map} +1 -1
  132. package/dist/{chunk-7TPYPVAH.js → chunk-ZAELRYKS.js} +3 -3
  133. package/dist/{chunk-7TPYPVAH.js.map → chunk-ZAELRYKS.js.map} +1 -1
  134. package/dist/{chunk-UQ33Y4DM.js → chunk-ZBHZLWV3.js} +4 -4
  135. package/dist/{chunk-UQ33Y4DM.js.map → chunk-ZBHZLWV3.js.map} +1 -1
  136. package/dist/{chunk-OTIB4D2K.js → chunk-ZDLUQLI6.js} +4 -4
  137. package/dist/{chunk-OTIB4D2K.js.map → chunk-ZDLUQLI6.js.map} +1 -1
  138. package/dist/{chunk-OHNKYHRR.js → chunk-ZHGKAZJ7.js} +214 -16
  139. package/dist/chunk-ZHGKAZJ7.js.map +1 -0
  140. package/dist/{claude-code-VJGYBXQR.js → claude-code-RE46FJXI.js} +4 -4
  141. package/dist/{claude-code-VJGYBXQR.js.map → claude-code-RE46FJXI.js.map} +1 -1
  142. package/dist/cli/index.js +704 -448
  143. package/dist/cli/index.js.map +1 -1
  144. package/dist/cli/src/agent-pins.d.ts +11 -0
  145. package/dist/cli/src/agent-pins.d.ts.map +1 -1
  146. package/dist/cli/src/commands/catalog.d.ts +1 -1
  147. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  148. package/dist/cli/src/commands/config.d.ts.map +1 -1
  149. package/dist/cli/src/commands/diff.d.ts.map +1 -1
  150. package/dist/cli/src/commands/harness.d.ts +24 -0
  151. package/dist/cli/src/commands/harness.d.ts.map +1 -0
  152. package/dist/cli/src/commands/integration.d.ts.map +1 -1
  153. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  154. package/dist/cli/src/commands/library-index.d.ts +20 -2
  155. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  156. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  157. package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
  158. package/dist/cli/src/commands/project.d.ts +19 -1
  159. package/dist/cli/src/commands/project.d.ts.map +1 -1
  160. package/dist/cli/src/commands/run.d.ts.map +1 -1
  161. package/dist/cli/src/commands/serve-preflight.d.ts.map +1 -1
  162. package/dist/cli/src/commands/session-logs/local-query.d.ts +2 -0
  163. package/dist/cli/src/commands/session-logs/local-query.d.ts.map +1 -1
  164. package/dist/cli/src/commands/source.d.ts +9 -2
  165. package/dist/cli/src/commands/source.d.ts.map +1 -1
  166. package/dist/cli/src/commands/store.d.ts.map +1 -1
  167. package/dist/cli/src/commands/update.d.ts.map +1 -1
  168. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  169. package/dist/cli/src/config-checks.d.ts +37 -0
  170. package/dist/cli/src/config-checks.d.ts.map +1 -0
  171. package/dist/cli/src/skill-checks.d.ts +27 -0
  172. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  173. package/dist/cli/src/store-addable.d.ts +11 -0
  174. package/dist/cli/src/store-addable.d.ts.map +1 -1
  175. package/dist/connectors/config.js +5 -5
  176. package/dist/connectors/index.js +18 -18
  177. package/dist/{connectors-CXZLXAFZ.js → connectors-7THEF7YA.js} +21 -21
  178. package/dist/{connectors-CXZLXAFZ.js.map → connectors-7THEF7YA.js.map} +1 -1
  179. package/dist/core/index.js +6 -6
  180. package/dist/core/manifest.js +2 -2
  181. package/dist/core/models.js +1 -1
  182. package/dist/core/publish-manifest.js +3 -3
  183. package/dist/core/ref.js +1 -1
  184. package/dist/core/runtime-assets.js +5 -5
  185. package/dist/core/src/agent-instances.d.ts.map +1 -1
  186. package/dist/core/src/config-key-diagnostics.d.ts +9 -0
  187. package/dist/core/src/config-key-diagnostics.d.ts.map +1 -0
  188. package/dist/core/src/index.d.ts +1 -1
  189. package/dist/core/src/index.d.ts.map +1 -1
  190. package/dist/core/src/manifest.d.ts +10 -0
  191. package/dist/core/src/manifest.d.ts.map +1 -1
  192. package/dist/core/src/models.d.ts +8 -0
  193. package/dist/core/src/models.d.ts.map +1 -1
  194. package/dist/core/src/workspace-config.d.ts +8 -0
  195. package/dist/core/src/workspace-config.d.ts.map +1 -1
  196. package/dist/core/src/workspace-yaml-editor.d.ts +9 -2
  197. package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
  198. package/dist/core/workspace-config.js +4 -4
  199. package/dist/deploy/index.js +6 -6
  200. package/dist/discovery/index.js +4 -4
  201. package/dist/discovery/src/builtin-providers.d.ts.map +1 -1
  202. package/dist/discovery/src/parse-manifest.d.ts.map +1 -1
  203. package/dist/{ensure-sources-UPTHZKGF.js → ensure-sources-IH7CHSJF.js} +16 -16
  204. package/dist/{ensure-sources-UPTHZKGF.js.map → ensure-sources-IH7CHSJF.js.map} +1 -1
  205. package/dist/factory-assets/connectors/box.js +18 -18
  206. package/dist/factory-assets/connectors/deploy.js +18 -18
  207. package/dist/factory-assets/connectors/devserver.js +18 -18
  208. package/dist/factory-assets/connectors/flow/adapter.js +18 -18
  209. package/dist/factory-assets/connectors/flow/contract/normalize.d.ts.map +1 -1
  210. package/dist/factory-assets/connectors/flow/contract.js +1 -1
  211. package/dist/factory-assets/connectors/flow/engine.js +8 -8
  212. package/dist/factory-assets/connectors/flow/run-flow.js +20 -20
  213. package/dist/factory-assets/connectors/flow.js +18 -18
  214. package/dist/factory-assets/connectors/git.js +18 -18
  215. package/dist/factory-assets/connectors/gmail.js +18 -18
  216. package/dist/factory-assets/connectors/googledrive.js +18 -18
  217. package/dist/factory-assets/connectors/local.js +18 -18
  218. package/dist/factory-assets/connectors/mattermost.js +18 -18
  219. package/dist/factory-assets/connectors/memory.js +18 -18
  220. package/dist/factory-assets/connectors/minio.js +18 -18
  221. package/dist/factory-assets/connectors/postgres.js +18 -18
  222. package/dist/factory-assets/connectors/s3.js +18 -18
  223. package/dist/factory-assets/connectors/sharepoint.js +18 -18
  224. package/dist/factory-assets/connectors/sqlite.js +18 -18
  225. package/dist/factory-assets/connectors/static-server.js +18 -18
  226. package/dist/factory-assets/connectors/tunnel.js +18 -18
  227. package/dist/factory-assets/connectors/webdav.js +18 -18
  228. package/dist/factory-assets/connectors/xstate-store.js +18 -18
  229. package/dist/factory-assets/connectors/xstate.js +18 -18
  230. package/dist/factory-assets/skills/authoring-skaile-assets/SKILL.md +1 -1
  231. package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +2 -2
  232. package/dist/factory-assets/skills/authoring-skaile-manifests/references/dependency-standard.md +3 -3
  233. package/dist/{flows-TJQIMGUX.js → flows-4JZQ3XFK.js} +11 -11
  234. package/dist/{flows-TJQIMGUX.js.map → flows-4JZQ3XFK.js.map} +1 -1
  235. package/dist/{helpers-DE53KG3E.js → helpers-JNMK3FC2.js} +16 -16
  236. package/dist/{helpers-DE53KG3E.js.map → helpers-JNMK3FC2.js.map} +1 -1
  237. package/dist/library/index.js +9 -9
  238. package/dist/library/install.js +4 -4
  239. package/dist/library/src/index.d.ts +1 -1
  240. package/dist/library/src/index.d.ts.map +1 -1
  241. package/dist/library/src/local/library-dir.d.ts +22 -5
  242. package/dist/library/src/local/library-dir.d.ts.map +1 -1
  243. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  244. package/dist/library/src/remote/remote-catalog-source.d.ts +6 -0
  245. package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
  246. package/dist/{library-publish-KKQ2ULLX.js → library-publish-I3UWXAHI.js} +52 -50
  247. package/dist/library-publish-I3UWXAHI.js.map +1 -0
  248. package/dist/model-endpoint/index.js +9 -9
  249. package/dist/{open-library-RJGJIW5H.js → open-library-NKKUJLWA.js} +19 -19
  250. package/dist/{open-library-RJGJIW5H.js.map → open-library-NKKUJLWA.js.map} +1 -1
  251. package/dist/{open-registry-3QS3J7KO.js → open-registry-BYAXSHUI.js} +14 -14
  252. package/dist/{open-registry-3QS3J7KO.js.map → open-registry-BYAXSHUI.js.map} +1 -1
  253. package/dist/{paths-QAV4C3KX.js → paths-UKWE35XS.js} +9 -9
  254. package/dist/{paths-QAV4C3KX.js.map → paths-UKWE35XS.js.map} +1 -1
  255. package/dist/{plugin-store-MSH6GK6T.js → plugin-store-ABE35NRX.js} +9 -9
  256. package/dist/{plugin-store-MSH6GK6T.js.map → plugin-store-ABE35NRX.js.map} +1 -1
  257. package/dist/project-BIPK47JK.js +86 -0
  258. package/dist/{project-HZW2MZPA.js.map → project-BIPK47JK.js.map} +1 -1
  259. package/dist/resolver/index.js +7 -7
  260. package/dist/runner/index.js +33 -33
  261. package/dist/runner/src/composition/content-source.d.ts.map +1 -1
  262. package/dist/runner/src/composition/errors.d.ts +16 -1
  263. package/dist/runner/src/composition/errors.d.ts.map +1 -1
  264. package/dist/runner/src/credential-notice.d.ts +3 -3
  265. package/dist/runner/src/credential-notice.d.ts.map +1 -1
  266. package/dist/runner/src/serve.d.ts +14 -2
  267. package/dist/runner/src/serve.d.ts.map +1 -1
  268. package/dist/sdk/asset-manager.js +13 -13
  269. package/dist/sdk/bridge.js +14 -14
  270. package/dist/sdk/core.js +6 -6
  271. package/dist/sdk/flow.js +8 -8
  272. package/dist/sdk/index.js +33 -33
  273. package/dist/sdk/resolver.js +7 -7
  274. package/dist/sdk/runner.js +33 -33
  275. package/dist/sdk/transport/ws/server.js +7 -7
  276. package/dist/sdk/transport/ws.js +7 -7
  277. package/dist/sdk/transport.js +7 -7
  278. package/dist/{serve-preflight-L4POEHNQ.js → serve-preflight-FLTIBTEX.js} +28 -29
  279. package/dist/serve-preflight-FLTIBTEX.js.map +1 -0
  280. package/dist/{setup-AGYB4PKR.js → setup-AG6NFHSN.js} +25 -25
  281. package/dist/{setup-AGYB4PKR.js.map → setup-AG6NFHSN.js.map} +1 -1
  282. package/dist/{skills-2LMQ2IAD.js → skills-UQYUHVKO.js} +12 -12
  283. package/dist/{skills-2LMQ2IAD.js.map → skills-UQYUHVKO.js.map} +1 -1
  284. package/dist/source-ASEHI2XS.js +85 -0
  285. package/dist/{source-GBMYD3RO.js.map → source-ASEHI2XS.js.map} +1 -1
  286. package/dist/{source-manifest-publish-FK22TVQT.js → source-manifest-publish-IEVV3W6J.js} +45 -45
  287. package/dist/{source-manifest-publish-FK22TVQT.js.map → source-manifest-publish-IEVV3W6J.js.map} +1 -1
  288. package/dist/transport/index.js +7 -7
  289. package/dist/transport/ws/server.js +7 -7
  290. package/dist/transport/ws.js +7 -7
  291. package/dist/tui/index.js +33 -33
  292. package/dist/types/src/install-manifest.d.ts +1 -1
  293. package/dist/types/src/install-manifest.d.ts.map +1 -1
  294. package/dist/workspace-plugin/adapters/mcp.js +25 -25
  295. package/dist/workspace-plugin/adapters/omp.js +14 -14
  296. package/dist/workspace-plugin/index.js +1 -1
  297. package/package.json +1 -1
  298. package/dist/asset-feeds-PXUWCXVI.js.map +0 -1
  299. package/dist/chunk-3JKGY2YC.js.map +0 -1
  300. package/dist/chunk-4DWBSTYA.js.map +0 -1
  301. package/dist/chunk-4XWLB7JB.js.map +0 -1
  302. package/dist/chunk-F2GOZMRA.js.map +0 -1
  303. package/dist/chunk-GOCWM7FN.js.map +0 -1
  304. package/dist/chunk-L4YKW5AY.js.map +0 -1
  305. package/dist/chunk-NMI2TWMH.js.map +0 -1
  306. package/dist/chunk-OAHVKSQJ.js.map +0 -1
  307. package/dist/chunk-OHNKYHRR.js.map +0 -1
  308. package/dist/chunk-PUK7TQT4.js +0 -13
  309. package/dist/chunk-PUK7TQT4.js.map +0 -1
  310. package/dist/chunk-QOM5Z62G.js.map +0 -1
  311. package/dist/chunk-TKHJXPSB.js.map +0 -1
  312. package/dist/chunk-UL22SDGR.js.map +0 -1
  313. package/dist/chunk-VJRTDKXS.js.map +0 -1
  314. package/dist/chunk-WEH33JSG.js.map +0 -1
  315. package/dist/chunk-WYHQUCHR.js.map +0 -1
  316. package/dist/chunk-X3RMRJNR.js.map +0 -1
  317. package/dist/library-publish-KKQ2ULLX.js.map +0 -1
  318. package/dist/project-HZW2MZPA.js +0 -84
  319. package/dist/serve-preflight-L4POEHNQ.js.map +0 -1
  320. package/dist/source-GBMYD3RO.js +0 -85
package/dist/cli/index.js CHANGED
@@ -1,91 +1,92 @@
1
1
  #!/usr/bin/env node
2
- import { makeValidateCommand, scanIdentities, isRecord } from '../chunk-NMI2TWMH.js';
3
- import { storeNotInstallableReason } from '../chunk-PUK7TQT4.js';
4
- import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError, removeProviderEntry } from '../chunk-3IXIEHUB.js';
5
- import { makeInstallCommand, makeCheckCommand, makeCleanCommand, pinComposedAgents, reportRewritten, reportReplaced, reportRelocked, reportMoved, reportStoreNotChecked, globalProblems, editedConventionFiles, supportsInstallManifest, REF_HINT, reportInstalledSoftDeps } from '../chunk-WEH33JSG.js';
2
+ import { makeValidateCommand, scanIdentities } from '../chunk-IHFGPHCT.js';
3
+ import { storeNotInstallableReason, mcpNotRunnableHere } from '../chunk-EX3GLAL6.js';
4
+ import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError, removeProviderEntry } from '../chunk-NB7SYQYP.js';
5
+ import { makeInstallCommand, makeCheckCommand, makeCleanCommand, pinComposedAgents, reportRewritten, reportReplaced, reportRelocked, reportMoved, reportStoreNotChecked, globalProblems, editedConventionFiles, supportsInstallManifest, runYamlInstall, REF_HINT, reportInstalledSoftDeps } from '../chunk-CEKW3KXP.js';
6
+ import { unknownHarnessMessage, reportProjectConfig, driverAliasOption, foldDriverFlag, friendlyHarnessError, harnessErrorNotes, isRecord } from '../chunk-7HX6FNKL.js';
6
7
  import { createSpinner } from '../chunk-NESV47MF.js';
7
- import { getStoreConfig, storeFetch, isStoreAuthenticated, getStoreToken } from '../chunk-VXEYX73S.js';
8
- import { makeSourceCommand, syncProjectSources, divergedSourceClones } from '../chunk-WYHQUCHR.js';
9
- import { deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, exitOnLibrarySymlinks, resolveLibraryPublisherDetailed, getStoreIdentity, warnLibraryNameFallback, indexLibrary, warnIgnoredDomainFiles, removedDomainOption, rejectRemovedDomainOption, requireValidPublisherOrExit, exitOnManifestPublisherProblems, findAssetManifestFile, checkAssetFile, registerLibraryAsset, DOMAIN_REMOVED_HINT, reportLibrarySymlinks, checkAsset, manifestPublisherProblems, exitOnManifestRootProblems, manifestRequiresProblems, composeRefContext, registeredAssetKeys, assetEntryRef, duplicateAssetMessage, unresolvedManifestDependencies, findEntryManifestFile, unheldRequiresOfFile, warnLegacyBundleFiles, checkComposeKinds } from '../chunk-TKHJXPSB.js';
10
- import { openCatalogSource, LocalCatalogDisabledError, openLibraryManager, openLibrary } from '../chunk-DHYSUJ3H.js';
11
- import { AI_RESOURCES } from '../chunk-2UUKCROR.js';
12
- import { loadDeclaredPlugins } from '../chunk-YGRZNFRO.js';
13
- import { status, enable, disable, install, uninstall } from '../chunk-Y2TO2U7W.js';
14
- import { logErr, S, logOk, logInfo, logWarn, TARGET_DEFAULT_HINT, parseHarnessFilter, requireProjectConfig, deferredWarnings, warnPlaceholderBodies, warnFilesOnlyDelegates, reportLegacyOmpCopies, logNoProject, warnLegacyClaudeCopies, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth, KIND_COL_WIDTH } from '../chunk-KX2PT5Q4.js';
15
- import { getKindRegistry, getKnownKinds } from '../chunk-ARWKK325.js';
8
+ import { loadDeclaredPlugins } from '../chunk-QSYQOTWN.js';
9
+ import { getStoreConfig, storeFetch, isStoreAuthenticated, getStoreToken } from '../chunk-3GMOPFWH.js';
10
+ import { makeSourceCommand, syncProjectSources, divergedSourceClones } from '../chunk-AZ2H6R5I.js';
11
+ import { libraryAssetRefusals, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, exitOnLibrarySymlinks, resolveLibraryPublisherDetailed, getStoreIdentity, warnLibraryNameFallback, indexLibrary, warnIgnoredDomainFiles, removedDomainOption, rejectRemovedDomainOption, requireValidPublisherOrExit, exitOnManifestPublisherProblems, findAssetManifestFile, checkAssetFile, registerLibraryAsset, DOMAIN_REMOVED_HINT, reportLibrarySymlinks, checkAsset, manifestPublisherProblems, exitOnManifestPathProblems, manifestRequiresProblems, composeRefContext, registeredAssetKeys, assetEntryRef, duplicateAssetMessage, manifestParseFailureLine, manifestParseErrorText, unresolvedManifestDependencies, findEntryManifestFile, unheldRequiresOfFile, warnLegacyBundleFiles, checkComposeKinds } from '../chunk-AITJ7ELM.js';
12
+ import { openCatalogSource, LocalCatalogDisabledError, openLibraryManager, openLibrary } from '../chunk-RDTLPOPD.js';
13
+ import { AI_RESOURCES } from '../chunk-AATHJRKL.js';
14
+ import { status, enable, disable, install, uninstall } from '../chunk-ASWTQQ7E.js';
15
+ import { logErr, S, logOk, logInfo, logWarn, TARGET_DEFAULT_HINT, parseHarnessFilter, requireProjectConfig, deferredWarnings, warnPlaceholderBodies, warnFilesOnlyDelegates, reportLegacyOmpCopies, logNoProject, warnLegacyClaudeCopies, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth, KIND_COL_WIDTH } from '../chunk-QEULL4Q3.js';
16
+ import { getKindRegistry, getKnownKinds } from '../chunk-COYF6IG2.js';
16
17
  import { LocalSecretsProvider } from '../chunk-ILFGVSTJ.js';
17
- import { resolveInstanceAgentDir, instanceSessionOverrides, runAgentChat, isCompositionError, resolveSessionId, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, hashAgentFiles, createCompositionContentSource, compileComposition, manifestModelForHarness, instanceForSession, resolveAgentInstance, describeComposition, MarkdownStreamer, createFinalTextFallback } from '../chunk-VJRTDKXS.js';
18
- import '../chunk-VBI7HGHB.js';
19
- import '../chunk-OULSJRXV.js';
20
- import '../chunk-7TPYPVAH.js';
21
- import '../chunk-SRODW6M2.js';
18
+ import { resolveInstanceAgentDir, instanceSessionOverrides, runAgentChat, isCompositionError, resolveSessionId, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, hashAgentFiles, createCompositionContentSource, compileComposition, manifestModelForHarness, instanceForSession, resolveAgentInstance, describeComposition, MarkdownStreamer, createFinalTextFallback } from '../chunk-2LAPHLDH.js';
19
+ import '../chunk-QAKUD6QN.js';
20
+ import '../chunk-6YR4ALVX.js';
21
+ import '../chunk-ZAELRYKS.js';
22
+ import '../chunk-X3YGUKCG.js';
22
23
  import '../chunk-WYZXSJBK.js';
23
- import '../chunk-U56GGCC2.js';
24
- import '../chunk-6Z5KTFJT.js';
24
+ import '../chunk-HMISULVD.js';
25
+ import '../chunk-Z3VKUWAX.js';
25
26
  import '../chunk-KW37WNXY.js';
26
27
  import '../chunk-3MWQKQUB.js';
27
- import '../chunk-E3GPGTW3.js';
28
+ import '../chunk-KUQAJVYT.js';
28
29
  import '../chunk-O7SG5PC2.js';
29
30
  import '../chunk-7QBNJTTQ.js';
30
31
  import '../chunk-O2SYFJWP.js';
31
- import '../chunk-AF432MS3.js';
32
+ import '../chunk-EJPMNDTP.js';
32
33
  import '../chunk-32NA4TVC.js';
33
34
  import '../chunk-W3UDISS2.js';
34
35
  import '../chunk-ZFUZ5AKM.js';
35
- import { runFlow, resumeFlow } from '../chunk-T2BDID2J.js';
36
+ import { runFlow, resumeFlow } from '../chunk-J72MO2WA.js';
36
37
  import '../chunk-4R6DROGN.js';
37
- import { parseSkillRequirements, validateRequirements } from '../chunk-FKU57Q5Q.js';
38
- import '../chunk-H6UVIKQ2.js';
39
- import '../chunk-SNEE6UGY.js';
38
+ import { parseSkillRequirements, validateRequirements } from '../chunk-IRYKRKVQ.js';
39
+ import '../chunk-VYVTEMAW.js';
40
+ import '../chunk-DGTI65OC.js';
40
41
  import '../chunk-6GWSDPBP.js';
41
- import '../chunk-LN6QB7XI.js';
42
- import { checkModelProvider, checkHarnessModel } from '../chunk-4XWLB7JB.js';
43
- import '../chunk-WDAIWDLK.js';
44
- import '../chunk-4DWBSTYA.js';
45
- import '../chunk-JDR6ILCW.js';
42
+ import '../chunk-BBBCJSSU.js';
43
+ import { checkHarnessModel, checkModelProvider } from '../chunk-5Y2KGB4H.js';
44
+ import '../chunk-7LP7RCZI.js';
45
+ import '../chunk-SVTMNSPI.js';
46
+ import '../chunk-XGULGQA3.js';
46
47
  import '../chunk-LOO5CB5M.js';
47
48
  import '../chunk-BIRW3HOG.js';
48
- import '../chunk-7CV3HFWJ.js';
49
- import '../chunk-GEQSUC6U.js';
49
+ import '../chunk-5J4NPGFM.js';
50
+ import '../chunk-GNZBFSRB.js';
50
51
  import '../chunk-XFIEVEU7.js';
51
52
  import '../chunk-7DN6JKP2.js';
52
- import '../chunk-UVVVR4XO.js';
53
- import { listHarnesses, getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-F2GOZMRA.js';
53
+ import '../chunk-FKQNBCDW.js';
54
+ import { listHarnesses, getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-ILLTBKDJ.js';
54
55
  import '../chunk-G5SUWZEU.js';
55
56
  import '../chunk-IFGTRL2I.js';
56
- import { loadFlow, flowLookupRoots, findFlowFileInRoots, loadAllFlowEntries } from '../chunk-SZXGRHQQ.js';
57
+ import { loadFlow, flowLookupRoots, findFlowFileInRoots, loadAllFlowEntries } from '../chunk-4MUDQCBP.js';
57
58
  import '../chunk-WD3L5QSU.js';
58
59
  import { nodeLabel, nodeSkillAsset, nodeIsInert, nodeIsOptional, nodeRunKind } from '../chunk-7RGTAEG6.js';
59
60
  import '../chunk-JCPD4QRM.js';
60
- import { LibraryEntryError, AssetManager, parseRefTolerant, MissingManifestError, parseCanonicalLockKey, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-OAHVKSQJ.js';
61
- import { CatalogHttpError, libraryDirMissing, missingLibraryDirMessage, cloneOrInitGitRepo, trackOriginBranch, stampManifestPublisher, isGitRepo, ensureGitRepo, conflictingAssetRoot, scanUnlistedAssets, setManifestPublisher, LIBRARY_OWNERSHIPS, assertManifestEditable, installLibraryAsset, getStoreManifestsDir, assertValidLibraryName, unparsableAssetFiles, syncManifestWithDisk, renamedLibraryName, storeManifestFile, getDefaultValue, isSecretPlaceholder } from '../chunk-UL22SDGR.js';
62
- import { flowFileNameError, SEMVER_RE } from '../chunk-QOM5Z62G.js';
63
- import '../chunk-7XSAW5OC.js';
61
+ import { setLibraryAssetCheck, LibraryEntryError, AssetManager, parseRefTolerant, MissingManifestError, parseCanonicalLockKey, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-HWNK3F3X.js';
62
+ import { CatalogHttpError, libraryDirMissing, missingLibraryDirMessage, cloneOrInitGitRepo, trackOriginBranch, stampManifestPublisher, isGitRepo, ensureGitRepo, conflictingAssetRoot, scanUnlistedAssets, setManifestPublisher, LIBRARY_OWNERSHIPS, assertManifestEditable, installLibraryAsset, getStoreManifestsDir, assertValidLibraryName, unparsableAssetFiles, syncManifestWithDisk, renamedLibraryName, storeManifestFile, getDefaultValue, isSecretPlaceholder } from '../chunk-S2XHGWQC.js';
63
+ import { flowFileNameError, SEMVER_RE } from '../chunk-UI745XC3.js';
64
+ import '../chunk-YLLVSR2U.js';
64
65
  import '../chunk-BFMYYNDT.js';
65
66
  import '../chunk-3TXEJN4W.js';
66
67
  import '../chunk-ISHJITXJ.js';
67
68
  import '../chunk-LNFKL23K.js';
68
- import '../chunk-X3RMRJNR.js';
69
+ import '../chunk-JRN5QF4C.js';
69
70
  import '../chunk-NUELZWCF.js';
70
- import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-3JKGY2YC.js';
71
+ import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-NUA33BYO.js';
71
72
  import '../chunk-NOA6EJXE.js';
72
73
  import '../chunk-KTBKW2FI.js';
73
74
  import '../chunk-UQ6LFBPZ.js';
74
- import '../chunk-DUMTLYSO.js';
75
+ import '../chunk-ABFPSVIS.js';
75
76
  import { effectiveComposes, validatePreset, validateAgent, composeSlotDiagnostics, agentDeprecationDiagnostics, SLOT_ID_PATTERN } from '../chunk-E572OHGY.js';
76
- import { loadSettings, globalSettingsPath, resolveSettings, projectSettingsPath, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, resolveSettingsWithSources, readLock, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile, aiResourceRoots } from '../chunk-L4YKW5AY.js';
77
+ import { loadSettings, globalSettingsPath, resolveSettings, projectSettingsPath, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, resolveSettingsWithSources, resolveConfiguredHarnessName, readLock, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile, aiResourceRoots } from '../chunk-VMVDAZLA.js';
77
78
  import '../chunk-4GY63JU6.js';
78
- import { factoryAssetRoots } from '../chunk-OTIB4D2K.js';
79
+ import { factoryAssetRoots } from '../chunk-ZDLUQLI6.js';
79
80
  import { deployedDir } from '../chunk-5KRMNUL4.js';
80
81
  import { DEFAULT_HARNESS_ID, HARNESS_DEFAULTS } from '../chunk-Z7ZEZZB6.js';
81
82
  import { findKindDirs } from '../chunk-MWXYN6NY.js';
82
- import { SourceEntryError, LegacyKeyError, resolveSkWorkspaceConfig, sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, effectiveAgentInstances, matchPin, coerceVersion, loadSkWorkspaceConfig, findWorkspaceRoot, isWorkspaceConfigFilename, SKAILE_YAML_DEFAULT, AGENT_PROFILE_FIELDS } from '../chunk-OHNKYHRR.js';
83
+ import { SourceEntryError, LegacyKeyError, resolveSkWorkspaceConfig, sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, effectiveAgentInstances, matchPin, coerceVersion, loadSkWorkspaceConfig, findWorkspaceRoot, isWorkspaceConfigFilename, SKAILE_YAML_DEFAULT, AGENT_PROFILE_FIELDS } from '../chunk-ZHGKAZJ7.js';
83
84
  import { globalCacheRoot, globalSkaileDir, userConfigPath } from '../chunk-L5VSIPQD.js';
84
85
  import { HARNESS_TARGETS, SUPPORTED_HARNESSES, harnessNameForHarnessId } from '../chunk-VTETQCR6.js';
85
- import { SKAILE_MANIFEST_FILENAME, loadSkPublishManifest, decodeSkaileManifest, LIBRARY_GITIGNORE, librarySymlinkMessage, isNonAssetPath, isNonAssetDir, encodeSkaileManifest } from '../chunk-UQ33Y4DM.js';
86
+ import { SKAILE_MANIFEST_FILENAME, loadSkPublishManifest, decodeSkaileManifest, LIBRARY_GITIGNORE, librarySymlinkMessage, isNonAssetPath, isNonAssetDir, encodeSkaileManifest } from '../chunk-ZBHZLWV3.js';
86
87
  import { pluginTitle } from '../chunk-RVRB27AN.js';
87
- import { dedupeRequirements, parseFrontmatter, scanDirectory, parseRequires } from '../chunk-GOCWM7FN.js';
88
- import { parseAssetRef, isValidPublisher, PUBLISHER_HINT, isValidAssetName, ASSET_NAME_HINT, depToStr, assetRefToStr, slugifyAssetName, parseAssetRefLoose } from '../chunk-WDXZA7QW.js';
88
+ import { dedupeRequirements, parseFrontmatter, scanDirectory, parseRequires } from '../chunk-RHN5MRQO.js';
89
+ import { parseAssetRef, isValidPublisher, PUBLISHER_HINT, isValidAssetName, ASSET_NAME_HINT, depToStr, assetRefToStr, slugifyAssetName, parseAssetRefLoose } from '../chunk-LSSYC5IC.js';
89
90
  import { portableSpawn, portableSpawnSync } from '../chunk-ADPM6AYF.js';
90
91
  import { openSqlite } from '../chunk-DKXNKFKP.js';
91
92
  import { parseModelRef, resolveEntryBaseUrl } from '../chunk-LSI2IVFT.js';
@@ -94,8 +95,8 @@ import { registerLogStore, LogStore, StdoutSink } from '../chunk-BOFL7GIF.js';
94
95
  import '../chunk-NSBPE2FW.js';
95
96
  import * as fs8 from 'fs';
96
97
  import fs8__default, { readFileSync, existsSync, mkdirSync, writeFileSync, lstatSync, rmSync, readdirSync, statSync } from 'fs';
97
- import * as path18 from 'path';
98
- import path18__default, { resolve, join } from 'path';
98
+ import * as path19 from 'path';
99
+ import path19__default, { resolve, join } from 'path';
99
100
  import { fileURLToPath } from 'url';
100
101
  import { Help, Command, Option } from 'commander';
101
102
  import { rcompare } from 'semver';
@@ -224,7 +225,7 @@ async function runSearch(kind, query, opts) {
224
225
  const showLocal = !opts.store;
225
226
  const showStore = !opts.local;
226
227
  const { resolveConfig } = await import('../library/index.js');
227
- const airGapped = resolveConfig({ projectDir: path18__default.resolve(opts.projectDir) }).catalog.cache_ttl === 0;
228
+ const airGapped = resolveConfig({ projectDir: path19__default.resolve(opts.projectDir) }).catalog.cache_ttl === 0;
228
229
  if (showLocal) {
229
230
  await searchLocal(query, kind, opts, showStore, airGapped);
230
231
  }
@@ -232,13 +233,19 @@ async function runSearch(kind, query, opts) {
232
233
  await searchStore(query, kind, opts, airGapped);
233
234
  }
234
235
  }
235
- async function searchIndex(query, kind) {
236
- const { openLibrary: openLibrary2 } = await import('../open-library-RJGJIW5H.js');
236
+ async function searchIndex(query, kind, projectDir) {
237
+ const { openLibrary: openLibrary2 } = await import('../open-library-NKKUJLWA.js');
237
238
  const library = await openLibrary2();
238
239
  try {
239
240
  const { libraryDirMissing: libraryDirMissing2 } = await import('../library/index.js');
240
241
  const sources = await library.listSources();
241
242
  const gone = new Set(sources.filter(libraryDirMissing2).map((l) => l.id));
243
+ for (const id of new AssetManager({
244
+ registry: getKindRegistry(),
245
+ projectDir
246
+ }).undeclaredSourceClones(sources)) {
247
+ gone.add(id);
248
+ }
242
249
  const defs = (await library.listAssetDefs(kind ? { kind } : {})).filter((d) => !d.libraryId || !gone.has(d.libraryId));
243
250
  const libraryNames = new Map(sources.map((l) => [l.id, l.name]));
244
251
  let entries = defs.map(
@@ -270,7 +277,7 @@ async function searchIndex(query, kind) {
270
277
  }
271
278
  }
272
279
  async function searchFactory(projectDir, query, kind) {
273
- const prefixes = factoryAssetRoots().map((r) => r.endsWith(path18__default.sep) ? r : r + path18__default.sep);
280
+ const prefixes = factoryAssetRoots().map((r) => r.endsWith(path19__default.sep) ? r : r + path19__default.sep);
274
281
  const isFactoryPath = (p6) => prefixes.some((fp) => p6 === fp.slice(0, -1) || p6.startsWith(fp));
275
282
  try {
276
283
  const entries = await new AssetManager({ registry: getKindRegistry(), projectDir }).search(
@@ -383,18 +390,35 @@ async function expandCompetingOrigins(entries, projectDir) {
383
390
  }
384
391
  return out;
385
392
  }
393
+ async function withAddVersions(entries, projectDir) {
394
+ if (!entries.some((e) => e.library && e.publisher)) return entries;
395
+ let versions;
396
+ try {
397
+ versions = await new AssetManager({
398
+ registry: getKindRegistry(),
399
+ projectDir
400
+ }).sourceAssetVersions();
401
+ } catch {
402
+ return entries;
403
+ }
404
+ if (versions.size === 0) return entries;
405
+ return entries.map((e) => {
406
+ const v = e.library ? versions.get(`${e.library}\0${entryDedupKey(e)}`) : void 0;
407
+ return v && v !== e.version ? { ...e, version: v } : e;
408
+ });
409
+ }
386
410
  async function searchLocal(query, kind, opts, showStore, airGapped) {
387
- const projectDir = path18__default.resolve(opts.projectDir);
388
- const { restoreSourceReaders } = await import('../source-GBMYD3RO.js');
411
+ const projectDir = path19__default.resolve(opts.projectDir);
412
+ const { restoreSourceReaders } = await import('../source-ASEHI2XS.js');
389
413
  for (const name of await restoreSourceReaders(projectDir)) {
390
414
  logInfo(`Re-registered source "${name}" (its library entry was removed elsewhere).`);
391
415
  }
392
416
  const factory = await searchFactory(projectDir, query, kind);
393
- let entries = unionEntries(await searchIndex(query, kind), factory);
417
+ let entries = unionEntries(await searchIndex(query, kind, projectDir), factory);
394
418
  if (entries.length === 0 && !query && !kind && !airGapped) {
395
- const { autoSyncForSearch } = await import('../source-GBMYD3RO.js');
419
+ const { autoSyncForSearch } = await import('../source-ASEHI2XS.js');
396
420
  if (await autoSyncForSearch(projectDir)) {
397
- entries = unionEntries(await searchIndex(query, kind), factory);
421
+ entries = unionEntries(await searchIndex(query, kind, projectDir), factory);
398
422
  }
399
423
  }
400
424
  if (entries.length === 0) {
@@ -410,7 +434,10 @@ async function searchLocal(query, kind, opts, showStore, airGapped) {
410
434
  ${S.heading("Local:")}`);
411
435
  }
412
436
  printLocalEntries(
413
- await expandCompetingOrigins(await expandLibraryCopies(entries, projectDir), projectDir)
437
+ await withAddVersions(
438
+ await expandCompetingOrigins(await expandLibraryCopies(entries, projectDir), projectDir),
439
+ projectDir
440
+ )
414
441
  );
415
442
  }
416
443
  var MIN_LOCAL_DESCRIPTION_WIDTH = 10;
@@ -506,9 +533,9 @@ async function searchStore(query, kind, opts, airGapped) {
506
533
  logInfo("air-gapped (cache_ttl: 0) \u2014 local sources only");
507
534
  return;
508
535
  }
509
- const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-RJGJIW5H.js');
536
+ const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-NKKUJLWA.js');
510
537
  try {
511
- const remote = await openCatalogSource2({ projectDir: path18__default.resolve(opts.projectDir) });
538
+ const remote = await openCatalogSource2({ projectDir: path19__default.resolve(opts.projectDir) });
512
539
  const assets = await remote.listAssets(kind ? { kind } : {});
513
540
  const sel = selectStoreRows(filterCatalogAssets(assets, query), query, Boolean(opts.all));
514
541
  if (sel.shown.length > 0) {
@@ -523,7 +550,7 @@ async function searchStore(query, kind, opts, airGapped) {
523
550
  const local = e instanceof LocalCatalogDisabledError2;
524
551
  if (opts.store) {
525
552
  logErr(
526
- local ? "remote catalog disabled (catalog.url: local) \u2014 set catalog.url: https://skaile.store to search the store" : `Store search failed: ${await describeStoreFailure(e, path18__default.resolve(opts.projectDir))}`
553
+ local ? "remote catalog disabled (catalog.url: local) \u2014 set catalog.url: https://skaile.store to search the store" : `Store search failed: ${await describeStoreFailure(e, path19__default.resolve(opts.projectDir))}`
527
554
  );
528
555
  process.exit(1);
529
556
  } else {
@@ -624,7 +651,10 @@ function makeAddCommand() {
624
651
  ).option("--no-soft-deps", "skip the soft-dep prompt entirely (don't add, don't report)").option(
625
652
  "--force",
626
653
  "overwrite a deployed folder that no lock entry owns (a hand-made skill of the same name)"
627
- ).option("--verbose", "print the full `exists in N libraries` warning for every asset").action(async (ref, opts) => {
654
+ ).option("--verbose", "print the full `exists in N libraries` warning for every asset").option(
655
+ "--dry-run",
656
+ "show the library, version, dependencies and folders the add would use; change nothing"
657
+ ).action(async (ref, opts) => {
628
658
  if (opts.withSoftDeps && opts.softDeps === false) {
629
659
  logErr("--with-soft-deps and --no-soft-deps are mutually exclusive.");
630
660
  process.exit(1);
@@ -635,7 +665,7 @@ function makeAddCommand() {
635
665
  const collisionKeys = [];
636
666
  const am2 = new AssetManager({
637
667
  registry: getKindRegistry(),
638
- projectDir: path18__default.resolve(opts.projectDir),
668
+ projectDir: path19__default.resolve(opts.projectDir),
639
669
  global: opts.global || harnesses !== void 0,
640
670
  harnesses,
641
671
  harness: opts.target,
@@ -653,6 +683,7 @@ function makeAddCommand() {
653
683
  const placeholderDescriptions = [];
654
684
  let presets = [];
655
685
  const skippedSecrets = /* @__PURE__ */ new Set();
686
+ let plan = [];
656
687
  const added = await am2.add(ref, {
657
688
  link: opts.link,
658
689
  force: opts.force,
@@ -671,9 +702,18 @@ function makeAddCommand() {
671
702
  warnings.push(
672
703
  `${secretPath} looks like a secret: it is not deployed or hashed with the asset. Keep secrets out of an asset root`
673
704
  );
705
+ },
706
+ dryRun: opts.dryRun === true,
707
+ onPlan: (items) => {
708
+ plan = items;
674
709
  }
675
710
  });
676
- spinner.stop("Done");
711
+ spinner.stop(opts.dryRun ? "Planned" : "Done");
712
+ if (opts.dryRun) {
713
+ warnings.flush();
714
+ printAddPlan(plan);
715
+ return;
716
+ }
677
717
  warnings.flush();
678
718
  if (!am2.global) await pinComposedAgents(am2.projectDir);
679
719
  await promptSoftDepAdds(am2, ref, {
@@ -754,6 +794,18 @@ function makeAddCommand() {
754
794
  }
755
795
  });
756
796
  }
797
+ function printAddPlan(plan) {
798
+ const line = (item, label) => {
799
+ logInfo(
800
+ `${label} ${colorRef(item.ref)}${item.version ? `#${item.version}` : ""} (${item.origin})`
801
+ );
802
+ for (const folder of item.folders) console.log(` folder: ${S.dim(folder)}`);
803
+ if (item.files.length > 0) console.log(` files: ${S.dim(item.files.join(", "))}`);
804
+ };
805
+ for (const item of plan.filter((i) => i.requested)) line(item, "Would add");
806
+ for (const item of plan.filter((i) => !i.requested)) line(item, "Would also add");
807
+ logInfo("Dry run: nothing was changed.");
808
+ }
757
809
  function readableError(err) {
758
810
  if (err instanceof Error && err.code === "unknown_asset_kind") {
759
811
  return `Error: ${err.message.replace(/^unknown_asset_kind: /, "")}`;
@@ -773,7 +825,7 @@ function makeRemoveCommand() {
773
825
  requireProjectConfig(opts.projectDir, { allowMissing: true });
774
826
  const am2 = new AssetManager({
775
827
  registry: getKindRegistry(),
776
- projectDir: path18__default.resolve(opts.projectDir),
828
+ projectDir: path19__default.resolve(opts.projectDir),
777
829
  global: opts.global || harnesses !== void 0,
778
830
  harnesses,
779
831
  harness: opts.target
@@ -813,6 +865,9 @@ function makeRemoveCommand() {
813
865
  for (const dep of result.pruned) {
814
866
  logOk(`Removed ${dep} (no longer required by anything declared in skaile.yaml)`);
815
867
  }
868
+ for (const setting of result.droppedSettings ?? []) {
869
+ logOk(`Removed ${setting} from skaile.yaml (it only set values for ${ref})`);
870
+ }
816
871
  await promptSoftDepRemovals(am2, ref, {
817
872
  isTTY: !!process.stdin.isTTY,
818
873
  noSoftDeps: opts.softDeps === false,
@@ -845,7 +900,7 @@ function makeListCommand() {
845
900
  }
846
901
  const am2 = new AssetManager({
847
902
  registry: getKindRegistry(),
848
- projectDir: path18__default.resolve(opts.projectDir),
903
+ projectDir: path19__default.resolve(opts.projectDir),
849
904
  harness: opts.target
850
905
  });
851
906
  let declared;
@@ -895,7 +950,7 @@ function makeListCommand() {
895
950
  function runGlobalList(kind, opts, harnesses) {
896
951
  const am2 = new AssetManager({
897
952
  registry: getKindRegistry(),
898
- projectDir: path18__default.resolve(opts.projectDir),
953
+ projectDir: path19__default.resolve(opts.projectDir),
899
954
  global: true,
900
955
  harnesses
901
956
  });
@@ -974,7 +1029,7 @@ function infoVersionLine(locked, latest) {
974
1029
  }
975
1030
  function lockedVersionOf(projectDir, kind, name, publisher) {
976
1031
  try {
977
- const lock = readLock(path18__default.join(projectDir, "skaile.lock.yaml"));
1032
+ const lock = readLock(path19__default.join(projectDir, "skaile.lock.yaml"));
978
1033
  for (const key of Object.keys(lock?.assets ?? {})) {
979
1034
  const id = parseCanonicalLockKey(key);
980
1035
  if (id.kind !== kind || id.name !== name || !id.version) continue;
@@ -1014,7 +1069,7 @@ async function resolveInfoEntry(am2, ref, opts) {
1014
1069
  return { entry: match ?? deployed };
1015
1070
  }
1016
1071
  const lookup = opts.storeLookup ?? (async (filter) => {
1017
- const { resolveCatalogSource } = await import('../open-library-RJGJIW5H.js');
1072
+ const { resolveCatalogSource } = await import('../open-library-NKKUJLWA.js');
1018
1073
  const { source, close } = await resolveCatalogSource({ projectDir: opts.projectDir });
1019
1074
  try {
1020
1075
  return await source.listAssets(filter);
@@ -1030,7 +1085,7 @@ async function resolveInfoEntry(am2, ref, opts) {
1030
1085
  );
1031
1086
  return { entry: hit ? catalogAssetToEntry(hit) : null };
1032
1087
  } catch (err) {
1033
- const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-RJGJIW5H.js');
1088
+ const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-NKKUJLWA.js');
1034
1089
  const storeNote = err instanceof Error ? err.message : String(err);
1035
1090
  const disabled = err instanceof LocalCatalogDisabledError2 || /catalog\.url/i.test(storeNote);
1036
1091
  return { entry: null, storeNote, ...disabled ? { storeDisabled: true } : {} };
@@ -1046,7 +1101,7 @@ function infoNotFoundHint(ref, lookup) {
1046
1101
  }
1047
1102
  function makeInfoCommand() {
1048
1103
  return new Command("info").description("Show asset metadata, deps, deploy status").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
1049
- const projectDir = path18__default.resolve(opts.projectDir);
1104
+ const projectDir = path19__default.resolve(opts.projectDir);
1050
1105
  requireProjectConfig(projectDir, { allowMissing: true });
1051
1106
  const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
1052
1107
  let lookup;
@@ -1079,6 +1134,12 @@ function makeInfoCommand() {
1079
1134
  if (entry.publisher) console.log(` repository: ${S.dim(entry.publisher)}`);
1080
1135
  const infoSource = showLocked && entry.source.endsWith(`#${entry.version}`) ? `${entry.source.slice(0, -`#${entry.version}`.length)}#${infoLocked}` : entry.source;
1081
1136
  console.log(` source: ${S.dim(infoSource)}`);
1137
+ const infoLibrary = await am2.lockedLibraryOf(
1138
+ entry.kind,
1139
+ entry.name,
1140
+ parseRefTolerant(ref)?.publisher ?? entry.publisher
1141
+ );
1142
+ if (infoLibrary) console.log(` library: ${S.dim(infoLibrary)}`);
1082
1143
  if (entry.kind === "mcp-server") {
1083
1144
  const skipped = (await am2.mcpNotices()).find(
1084
1145
  (n) => n.kind === "skipped" && (n.id === entry.name || n.id.endsWith(`/${entry.name}`))
@@ -1117,7 +1178,7 @@ function makeCreateCommand() {
1117
1178
  new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...SCAFFOLD_KINDS])
1118
1179
  ).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
1119
1180
  const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
1120
- const destDir = opts.dir ? path18__default.resolve(opts.dir) : process.cwd();
1181
+ const destDir = opts.dir ? path19__default.resolve(opts.dir) : process.cwd();
1121
1182
  const result = am2.create(name, opts.kind, destDir);
1122
1183
  if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
1123
1184
  else {
@@ -1132,7 +1193,7 @@ function makeDoctorCommand() {
1132
1193
  const problems = globalProblems(
1133
1194
  new AssetManager({
1134
1195
  registry: getKindRegistry(),
1135
- projectDir: path18__default.resolve(opts.projectDir),
1196
+ projectDir: path19__default.resolve(opts.projectDir),
1136
1197
  global: true,
1137
1198
  harnesses: parseHarnessFilter(opts.harness)
1138
1199
  })
@@ -1146,19 +1207,24 @@ function makeDoctorCommand() {
1146
1207
  return;
1147
1208
  }
1148
1209
  requireProjectConfig(opts.projectDir);
1210
+ const configErrors = await reportProjectConfig(path19__default.resolve(opts.projectDir), {
1211
+ harness: true,
1212
+ instances: true
1213
+ });
1214
+ if (configErrors > 0) process.exitCode = 1;
1149
1215
  const am2 = new AssetManager({
1150
1216
  registry: getKindRegistry(),
1151
- projectDir: path18__default.resolve(opts.projectDir)
1217
+ projectDir: path19__default.resolve(opts.projectDir)
1152
1218
  });
1153
1219
  const { gaps } = await am2.projectState();
1154
- const edited = await editedConventionFiles(path18__default.resolve(opts.projectDir));
1220
+ const edited = await editedConventionFiles(path19__default.resolve(opts.projectDir));
1155
1221
  const notices = [
1156
1222
  ...(await am2.mcpNotices()).map((n) => n.text),
1157
1223
  // A library that went back past the lock is no drift either (p1257).
1158
1224
  ...await am2.libraryOlderNotices()
1159
1225
  ];
1160
1226
  if (gaps.length === 0 && edited.length === 0) {
1161
- logOk("No missing dependencies.");
1227
+ if (configErrors === 0) logOk("No missing dependencies.");
1162
1228
  for (const n of notices) logWarn(n);
1163
1229
  return;
1164
1230
  }
@@ -1189,20 +1255,20 @@ function claudeSkillRoots() {
1189
1255
  const roots = [];
1190
1256
  const override = process.env.SKAILE_CLAUDE_SKILLS_DIR;
1191
1257
  if (override) roots.push(override);
1192
- roots.push(path18.join(os.homedir(), ".claude", "skills"));
1258
+ roots.push(path19.join(os.homedir(), ".claude", "skills"));
1193
1259
  return roots;
1194
1260
  }
1195
1261
  function resolveImportSource(nameOrPath) {
1196
- const asPath = path18.resolve(nameOrPath);
1262
+ const asPath = path19.resolve(nameOrPath);
1197
1263
  if (fs8.existsSync(asPath)) {
1198
- const dir = fs8.statSync(asPath).isDirectory() ? asPath : path18.dirname(asPath);
1199
- const skillFile = path18.join(dir, "SKILL.md");
1264
+ const dir = fs8.statSync(asPath).isDirectory() ? asPath : path19.dirname(asPath);
1265
+ const skillFile = path19.join(dir, "SKILL.md");
1200
1266
  if (fs8.existsSync(skillFile)) return { dir, skillFile, via: "path" };
1201
1267
  }
1202
- if (!nameOrPath.includes(path18.sep) && !nameOrPath.startsWith(".")) {
1268
+ if (!nameOrPath.includes(path19.sep) && !nameOrPath.startsWith(".")) {
1203
1269
  for (const root of claudeSkillRoots()) {
1204
- const dir = path18.join(root, nameOrPath);
1205
- const skillFile = path18.join(dir, "SKILL.md");
1270
+ const dir = path19.join(root, nameOrPath);
1271
+ const skillFile = path19.join(dir, "SKILL.md");
1206
1272
  if (fs8.existsSync(skillFile)) return { dir, skillFile, via: "claude-skills" };
1207
1273
  }
1208
1274
  }
@@ -1260,8 +1326,8 @@ ${body}
1260
1326
  // cli/src/commands/asset-cmd.ts
1261
1327
  function copyFilter(root) {
1262
1328
  return (src) => {
1263
- const rel = path18.relative(root, src).split(path18.sep).join("/");
1264
- return rel === "" || !(isNonAssetPath(rel) || isNonAssetDir(path18.basename(src)));
1329
+ const rel = path19.relative(root, src).split(path19.sep).join("/");
1330
+ return rel === "" || !(isNonAssetPath(rel) || isNonAssetDir(path19.basename(src)));
1265
1331
  };
1266
1332
  }
1267
1333
  async function resolveDefByRef(library, ref, opts) {
@@ -1344,16 +1410,16 @@ function makeAssetCommand() {
1344
1410
  }
1345
1411
  const rawSkill = fs8.readFileSync(src.skillFile, "utf8");
1346
1412
  const norm = opts.normalize ? normalizeSkillContent(rawSkill, {
1347
- fallbackName: path18.basename(src.dir),
1413
+ fallbackName: path19.basename(src.dir),
1348
1414
  version: opts.version,
1349
1415
  stage: opts.stage
1350
- }) : { content: rawSkill, name: path18.basename(src.dir), changed: false, notes: [] };
1416
+ }) : { content: rawSkill, name: path19.basename(src.dir), changed: false, notes: [] };
1351
1417
  if (!opts.normalize && !isValidAssetName(norm.name)) {
1352
1418
  logWarn(
1353
1419
  `Name "${norm.name}" is not canonical (kebab-case); \`skaile validate\` will reject this manifest entry. Drop --no-normalize to slugify it.`
1354
1420
  );
1355
1421
  }
1356
- const destDir = path18.join(target.path, norm.name);
1422
+ const destDir = path19.join(target.path, norm.name);
1357
1423
  if (fs8.existsSync(destDir)) {
1358
1424
  logErr(`Destination already exists: ${destDir}`);
1359
1425
  process.exit(1);
@@ -1385,7 +1451,7 @@ function makeAssetCommand() {
1385
1451
  logWarn(`${norm.name}/SKILL.md [${f.tag}] \u2014 ${f.text}`);
1386
1452
  }
1387
1453
  fs8.cpSync(src.dir, destDir, { recursive: true, filter: copyFilter(src.dir) });
1388
- fs8.writeFileSync(path18.join(destDir, "SKILL.md"), norm.content, "utf8");
1454
+ fs8.writeFileSync(path19.join(destDir, "SKILL.md"), norm.content, "utf8");
1389
1455
  for (const note of norm.notes) logInfo(` \u2022 ${note}`);
1390
1456
  const fm = parseFrontmatter(norm.content).data;
1391
1457
  for (const f of checkAgentSkillConformance(fm, { dirName: norm.name })) {
@@ -1451,10 +1517,10 @@ function makeAssetCommand() {
1451
1517
  );
1452
1518
  process.exit(1);
1453
1519
  }
1454
- const basename3 = path18.basename(srcPath);
1520
+ const basename3 = path19.basename(srcPath);
1455
1521
  const destDir = target.path;
1456
1522
  fs8.mkdirSync(destDir, { recursive: true });
1457
- const destPath = path18.join(destDir, basename3);
1523
+ const destPath = path19.join(destDir, basename3);
1458
1524
  if (fs8.existsSync(destPath)) {
1459
1525
  logErr(`Destination already exists: ${destPath}`);
1460
1526
  process.exit(1);
@@ -1486,7 +1552,7 @@ function makeAssetCommand() {
1486
1552
  }
1487
1553
  logOk(`Migrated ${basename3} \u2192 ${target.name} (${opts.mode})`);
1488
1554
  const publisher = loadSkPublishManifest(target.path)?.publisher ?? "<publisher>";
1489
- const migratedKind = fs8.existsSync(path18.join(destPath, "SKILL.md")) ? "skill" : "<kind>";
1555
+ const migratedKind = fs8.existsSync(path19.join(destPath, "SKILL.md")) ? "skill" : "<kind>";
1490
1556
  logInfo(
1491
1557
  `Not addable yet: run ${S.cmd(`skaile library index ${target.name}`)}, then ${S.cmd(`skaile add ${migratedKind}:@${publisher.replace(/^@/, "")}/${basename3}`)}`
1492
1558
  );
@@ -1612,14 +1678,14 @@ function makeAuthCommand() {
1612
1678
  }
1613
1679
  function collectCacheTargets(scope) {
1614
1680
  const out = [];
1615
- out.push(path18__default.join(scope.projectDir, ".skaile", "cache"));
1616
- out.push(path18__default.join(scope.projectDir, ".skaile", "store-cache"));
1617
- out.push(path18__default.join(scope.projectDir, ".skaile", "repos"));
1681
+ out.push(path19__default.join(scope.projectDir, ".skaile", "cache"));
1682
+ out.push(path19__default.join(scope.projectDir, ".skaile", "store-cache"));
1683
+ out.push(path19__default.join(scope.projectDir, ".skaile", "repos"));
1618
1684
  if (scope.global) {
1619
1685
  out.push(globalCacheRoot());
1620
1686
  const home = globalSkaileDir();
1621
- out.push(path18__default.join(home, "repos"));
1622
- out.push(path18__default.join(home, "catalog-cache"));
1687
+ out.push(path19__default.join(home, "repos"));
1688
+ out.push(path19__default.join(home, "catalog-cache"));
1623
1689
  }
1624
1690
  return out;
1625
1691
  }
@@ -1633,7 +1699,7 @@ function dirSize(target) {
1633
1699
  function dirSizeOfDir(dir) {
1634
1700
  let total = 0;
1635
1701
  for (const ent of readdirSync(dir, { withFileTypes: true })) {
1636
- const child = path18__default.join(dir, ent.name);
1702
+ const child = path19__default.join(dir, ent.name);
1637
1703
  if (ent.isSymbolicLink()) continue;
1638
1704
  if (ent.isDirectory()) total += dirSizeOfDir(child);
1639
1705
  else if (ent.isFile()) total += statSync(child).size;
@@ -1659,7 +1725,7 @@ function makeCacheCommand() {
1659
1725
  const cmd = new Command("cache").description("Inspect and reclaim the re-derivable cache");
1660
1726
  cmd.command("clean").description("Remove the project cache (.skaile/cache); --global also clears ~/.skaile/cache").option("--global", "Also clear the global cache (sources + catalog) and legacy dirs").option("--dry-run", "Show what would be removed without doing it").option("-y, --yes", "Skip confirmation prompt").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
1661
1727
  const targets = collectCacheTargets({
1662
- projectDir: path18__default.resolve(opts.projectDir),
1728
+ projectDir: path19__default.resolve(opts.projectDir),
1663
1729
  global: opts.global
1664
1730
  }).filter((t) => existsSync(t));
1665
1731
  if (targets.length === 0) {
@@ -1689,12 +1755,12 @@ function makeCacheCommand() {
1689
1755
  for (const r of removed) logOk(`Removed ${r}`);
1690
1756
  });
1691
1757
  cmd.command("dir").description("Print the resolved cache roots").option("--global", "Include the global cache root").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
1692
- console.log(path18__default.join(path18__default.resolve(opts.projectDir), ".skaile", "cache"));
1758
+ console.log(path19__default.join(path19__default.resolve(opts.projectDir), ".skaile", "cache"));
1693
1759
  if (opts.global) console.log(globalCacheRoot());
1694
1760
  });
1695
1761
  cmd.command("size").description("Show cache disk usage per directory").option("--global", "Include the global cache").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
1696
1762
  const targets = collectCacheTargets({
1697
- projectDir: path18__default.resolve(opts.projectDir),
1763
+ projectDir: path19__default.resolve(opts.projectDir),
1698
1764
  global: opts.global
1699
1765
  });
1700
1766
  console.log();
@@ -1710,7 +1776,7 @@ function makeCatalogCommand() {
1710
1776
  const catalog = new Command("catalog").description("Catalog source health and configuration");
1711
1777
  catalog.command("test").description("Probe the configured catalog source and report status").option("--project-dir <path>", "Project directory (for project-level config overlay)").option("--url <url>", "Override the catalog URL for this probe").option("--force", "Probe the network even in air-gapped mode (cache_ttl: 0)").action(async (opts) => {
1712
1778
  const { resolveConfig, isLocalCatalogUrl, trpcGetUrl } = await import('../library/index.js');
1713
- const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : void 0;
1779
+ const projectDir = opts.projectDir ? path19__default.resolve(opts.projectDir) : void 0;
1714
1780
  const cfg = resolveConfig({ projectDir });
1715
1781
  const baseUrl = opts.url ?? cfg.catalog.url;
1716
1782
  if (isLocalCatalogUrl(baseUrl)) {
@@ -1732,7 +1798,7 @@ function makeCatalogCommand() {
1732
1798
  });
1733
1799
  catalog.command("info").description("Print the resolved catalog configuration (url, framing, cacheTtlMs)").option("--project-dir <path>", "Project directory (for project-level config overlay)").action(async (opts) => {
1734
1800
  const { resolveConfig } = await import('../library/index.js');
1735
- const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : void 0;
1801
+ const projectDir = opts.projectDir ? path19__default.resolve(opts.projectDir) : void 0;
1736
1802
  const cfg = resolveConfig({ projectDir });
1737
1803
  console.log(`url: ${cfg.catalog.url}`);
1738
1804
  console.log(`framing: ${cfg.catalog.framing}`);
@@ -1741,7 +1807,7 @@ function makeCatalogCommand() {
1741
1807
  return catalog;
1742
1808
  }
1743
1809
  async function runLocalCatalogTest(projectDir) {
1744
- const { resolveCatalogSource } = await import('../open-library-RJGJIW5H.js');
1810
+ const { resolveCatalogSource } = await import('../open-library-NKKUJLWA.js');
1745
1811
  let resolved;
1746
1812
  try {
1747
1813
  resolved = await resolveCatalogSource({ projectDir });
@@ -1917,13 +1983,13 @@ async function scanLibraryFlowEntries() {
1917
1983
  const { LocalIndex, resolveIndexPath, scanAuthoringLibraries } = await import('../library/index.js');
1918
1984
  const indexPath = resolveIndexPath();
1919
1985
  if (!existsSync(indexPath)) return entries;
1920
- const { getKindRegistry: getKindRegistry2 } = await import('../open-registry-3QS3J7KO.js');
1986
+ const { getKindRegistry: getKindRegistry2 } = await import('../open-registry-BYAXSHUI.js');
1921
1987
  const index = new LocalIndex({ indexPath });
1922
1988
  try {
1923
1989
  for (const { library, assets } of await scanAuthoringLibraries(index, getKindRegistry2())) {
1924
1990
  for (const asset of assets) {
1925
1991
  if (asset.kind !== "flow") continue;
1926
- if (flowFileNameError(asset.manifest, path18__default.basename(asset.manifestPath))) continue;
1992
+ if (flowFileNameError(asset.manifest, path19__default.basename(asset.manifestPath))) continue;
1927
1993
  try {
1928
1994
  const flow = loadFlow(asset.manifestPath);
1929
1995
  if (flow.id) {
@@ -1991,9 +2057,9 @@ function findSkills() {
1991
2057
  }
1992
2058
  function walkSkills(dir, out) {
1993
2059
  for (const entry of fs8__default.readdirSync(dir, { withFileTypes: true })) {
1994
- const full = path18__default.join(dir, entry.name);
2060
+ const full = path19__default.join(dir, entry.name);
1995
2061
  if (entry.isDirectory()) {
1996
- const skillMd = path18__default.join(full, "SKILL.md");
2062
+ const skillMd = path19__default.join(full, "SKILL.md");
1997
2063
  if (fs8__default.existsSync(skillMd)) {
1998
2064
  out.push({ name: entry.name, path: full, skillPath: skillMd });
1999
2065
  } else {
@@ -2015,7 +2081,7 @@ function resolveFlowIds() {
2015
2081
  }
2016
2082
  }
2017
2083
  function resolveSessionIds(projectDir) {
2018
- const sessionsDir = path18__default.join(projectDir, ".skaile", "sessions");
2084
+ const sessionsDir = path19__default.join(projectDir, ".skaile", "sessions");
2019
2085
  if (!fs8__default.existsSync(sessionsDir)) return [];
2020
2086
  try {
2021
2087
  return fs8__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
@@ -2070,50 +2136,6 @@ function resolveDynamic(words, cword) {
2070
2136
  if (cmd === "config" && ["get", "set"].includes(sub) && isLast(3)) return CONFIG_KEYS;
2071
2137
  return null;
2072
2138
  }
2073
- function unknownHarnessMessage(harness) {
2074
- const known = listHarnesses().map((d) => d.id);
2075
- if (known.includes(harness)) return void 0;
2076
- return `Unknown agent harness: "${harness}". Available: ${known.join(", ")}`;
2077
- }
2078
- var warnedDriverFlag = false;
2079
- function warnDriverFlagDeprecated() {
2080
- if (warnedDriverFlag) return;
2081
- warnedDriverFlag = true;
2082
- console.error("--driver is deprecated; use --harness");
2083
- }
2084
- function driverAliasOption() {
2085
- return new Option("--driver <name>", "Deprecated alias of --harness").hideHelp();
2086
- }
2087
- function foldDriverFlag(opts, fallback) {
2088
- const { driver, ...rest } = opts;
2089
- if (driver !== void 0) warnDriverFlagDeprecated();
2090
- return { ...rest, harness: rest.harness ?? driver ?? fallback };
2091
- }
2092
- function friendlyHarnessError(err) {
2093
- const e = err;
2094
- if (!e) return null;
2095
- const isSpawnEnoent = e.code === "ENOENT" && (e.syscall?.startsWith("spawn") === true || /^spawn .*ENOENT/.test(e.message ?? ""));
2096
- const isConfig = e.category === "config" || e.detail?.category === "config";
2097
- if (!isSpawnEnoent && !isConfig) return null;
2098
- const hint = e.hint ?? e.detail?.hint;
2099
- const base = hint ?? "The configured agent binary is not installed or not on your PATH.";
2100
- return `${base}
2101
- Try a different harness with \`--harness claude-sdk\`.`;
2102
- }
2103
- function harnessErrorNotes(err) {
2104
- const e = err;
2105
- const notes = [];
2106
- const category = e?.category ?? e?.detail?.category;
2107
- const hint = e?.hint ?? e?.detail?.hint;
2108
- if (hint && category !== "config") notes.push(hint);
2109
- else if (category === "auth") notes.push("Check your API key or login.");
2110
- if (e?.logSessionId) {
2111
- notes.push(`Full records: .skaile/logs.db (skaile session logs ${e.logSessionId}).`);
2112
- }
2113
- return notes;
2114
- }
2115
-
2116
- // cli/src/commands/config.ts
2117
2139
  var PERSONAL_KEYS = /* @__PURE__ */ new Set(["harness", "model"]);
2118
2140
  function resolveDriverKeyAlias(key) {
2119
2141
  if (key !== "driver") return key;
@@ -2261,7 +2283,7 @@ function printResolvedPathsSection(config) {
2261
2283
  console.log(` ${S.label("prompts:".padEnd(16))} ${config.promptsDir ?? paths.promptsDir}`);
2262
2284
  }
2263
2285
  async function showConfig(opts) {
2264
- const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
2286
+ const projectDir = opts.projectDir ? path19__default.resolve(opts.projectDir) : process.cwd();
2265
2287
  let config;
2266
2288
  let sources;
2267
2289
  let wsDefaults;
@@ -2328,7 +2350,7 @@ function makeConfigCommand() {
2328
2350
  cmd.command("show").description("Show effective config with sources").option("--project-dir <path>", "Project directory").action((opts) => showConfig(opts));
2329
2351
  cmd.command("get <key>").description("Get an effective config value").option("--project-dir <path>", "Project directory").option("--global", "Read ~/.skaile/settings.json only, not the project's value").action(async (rawKey, opts) => {
2330
2352
  const key = resolveDriverKeyAlias(rawKey);
2331
- const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
2353
+ const projectDir = opts.projectDir ? path19__default.resolve(opts.projectDir) : process.cwd();
2332
2354
  if (CATALOG_KEYS.has(key)) {
2333
2355
  const { resolveConfig } = await import('../library/index.js');
2334
2356
  const field = key.slice("catalog.".length);
@@ -2344,7 +2366,7 @@ function makeConfigCommand() {
2344
2366
  ).option("--project-dir <path>", "Project directory").option("--global", "Write to ~/.skaile/settings.json instead of project-local").action(
2345
2367
  async (rawKey, value, opts) => {
2346
2368
  const key = resolveDriverKeyAlias(rawKey);
2347
- const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
2369
+ const projectDir = opts.projectDir ? path19__default.resolve(opts.projectDir) : process.cwd();
2348
2370
  if (CATALOG_KEYS.has(key)) {
2349
2371
  await setCatalogKey(key, value);
2350
2372
  return;
@@ -2378,6 +2400,19 @@ function makeConfigCommand() {
2378
2400
  process.exit(1);
2379
2401
  }
2380
2402
  }
2403
+ if (key === "model") {
2404
+ await loadDeclaredPlugins(projectDir);
2405
+ const harness = (await resolveSettings(projectDir)).harness ?? DEFAULT_HARNESS_ID;
2406
+ const refusal = checkHarnessModel(harness, {
2407
+ registry: loadRegistryView({ projectDir }).merged,
2408
+ model: value,
2409
+ roles: resolveSkWorkspaceConfig(projectDir).roles
2410
+ });
2411
+ if (refusal) {
2412
+ logErr(`${refusal} (the project's harness is ${harness})`);
2413
+ process.exit(1);
2414
+ }
2415
+ }
2381
2416
  const projectHarness = key === "harness" ? resolveSkWorkspaceConfig(projectDir).agent_config?.default?.harness : void 0;
2382
2417
  const filePath = opts.global ? globalSettingsPath() : projectSettingsPath(projectDir);
2383
2418
  const existing = await loadSettings(filePath);
@@ -2412,7 +2447,7 @@ function makeConfigCommand() {
2412
2447
  "Remove a value that `config set` wrote: harness, model, apiKey.<provider> (removes the provider entry) or catalog.url, catalog.cache_ttl, catalog.framing (the default applies again)"
2413
2448
  ).option("--project-dir <path>", "Project directory").option("--global", "Remove from ~/.skaile/settings.json instead of project-local").action(async (rawKey, opts) => {
2414
2449
  const key = resolveDriverKeyAlias(rawKey);
2415
- const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
2450
+ const projectDir = opts.projectDir ? path19__default.resolve(opts.projectDir) : process.cwd();
2416
2451
  if (CATALOG_KEYS.has(key)) {
2417
2452
  await unsetCatalogKey(key);
2418
2453
  return;
@@ -2735,8 +2770,8 @@ function makeConnectorCommand() {
2735
2770
  async (driver, opts) => {
2736
2771
  const { installNpmPackages } = await import('../connectors/index.js');
2737
2772
  const { scanDirectory: scanDirectory2, factoryAssetRoots: factoryAssetRoots2, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
2738
- const projectDir = path18__default.resolve(opts.projectDir);
2739
- const yamlPath = path18__default.join(projectDir, "skaile.yaml");
2773
+ const projectDir = path19__default.resolve(opts.projectDir);
2774
+ const yamlPath = path19__default.join(projectDir, "skaile.yaml");
2740
2775
  if (!existsSync(yamlPath)) {
2741
2776
  logErr("No skaile.yaml found in current directory. Run 'skaile init' first.");
2742
2777
  process.exit(1);
@@ -2796,8 +2831,8 @@ ${installResult.output}`);
2796
2831
  );
2797
2832
  cmd.command("remove <id>").option("--project-dir <path>", "Workspace directory", process.cwd()).description("Remove a connector from skaile.yaml by its instance ID").action(async (id, opts) => {
2798
2833
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
2799
- const projectDir = path18__default.resolve(opts.projectDir);
2800
- const yamlPath = path18__default.join(projectDir, "skaile.yaml");
2834
+ const projectDir = path19__default.resolve(opts.projectDir);
2835
+ const yamlPath = path19__default.join(projectDir, "skaile.yaml");
2801
2836
  if (!existsSync(yamlPath)) {
2802
2837
  logErr("No skaile.yaml found in current directory.");
2803
2838
  process.exit(1);
@@ -2814,7 +2849,7 @@ ${installResult.output}`);
2814
2849
  cmd.command("status [id]").option("--project-dir <path>", "Workspace directory", process.cwd()).description("Connect and report health status for one or all connectors").action(async (id, opts) => {
2815
2850
  const res = await import('../connectors/index.js');
2816
2851
  res.registerBuiltinConnectors();
2817
- const projectDir = path18__default.resolve(opts.projectDir);
2852
+ const projectDir = path19__default.resolve(opts.projectDir);
2818
2853
  const declarations = res.loadConnectorDeclarations(projectDir);
2819
2854
  if (declarations.length === 0) {
2820
2855
  console.log("No connectors configured in skaile.yaml.");
@@ -2838,7 +2873,7 @@ ${installResult.output}`);
2838
2873
  await manager.disconnectAll();
2839
2874
  });
2840
2875
  cmd.command("list").description("List all configured connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
2841
- const projectDir = path18__default.resolve(opts.projectDir);
2876
+ const projectDir = path19__default.resolve(opts.projectDir);
2842
2877
  const manager = await connectConnectors(projectDir);
2843
2878
  try {
2844
2879
  console.log(JSON.stringify(manager.listConnectors(), null, 2));
@@ -2847,7 +2882,7 @@ ${installResult.output}`);
2847
2882
  }
2848
2883
  });
2849
2884
  cmd.command("sync [id]").description("Re-sync a filesystem-face connector or all of them (git pull, S3 refresh, etc.)").option("--all", "Sync all connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
2850
- const projectDir = path18__default.resolve(opts.projectDir);
2885
+ const projectDir = path19__default.resolve(opts.projectDir);
2851
2886
  const manager = await connectConnectors(projectDir);
2852
2887
  try {
2853
2888
  if (opts.all) {
@@ -2871,7 +2906,7 @@ ${installResult.output}`);
2871
2906
  }
2872
2907
  });
2873
2908
  cmd.command("ops <id>").description("List available operations for a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
2874
- const projectDir = path18__default.resolve(opts.projectDir);
2909
+ const projectDir = path19__default.resolve(opts.projectDir);
2875
2910
  const manager = await connectConnectors(projectDir);
2876
2911
  try {
2877
2912
  if (!manager.has(id)) {
@@ -2886,7 +2921,7 @@ ${installResult.output}`);
2886
2921
  }
2887
2922
  });
2888
2923
  cmd.command("read <id> <resource-path>").description("Read content from a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, opts) => {
2889
- const projectDir = path18__default.resolve(opts.projectDir);
2924
+ const projectDir = path19__default.resolve(opts.projectDir);
2890
2925
  const manager = await connectConnectors(projectDir);
2891
2926
  try {
2892
2927
  const content = await manager.read(id, resourcePath);
@@ -2896,7 +2931,7 @@ ${installResult.output}`);
2896
2931
  }
2897
2932
  });
2898
2933
  cmd.command("write <id> <resource-path> <content>").description("Write content to a connector at a path").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, content, opts) => {
2899
- const projectDir = path18__default.resolve(opts.projectDir);
2934
+ const projectDir = path19__default.resolve(opts.projectDir);
2900
2935
  const manager = await connectConnectors(projectDir);
2901
2936
  try {
2902
2937
  await manager.write(id, resourcePath, { data: content });
@@ -2906,7 +2941,7 @@ ${installResult.output}`);
2906
2941
  }
2907
2942
  });
2908
2943
  cmd.command("entries <id> [resource-path]").description("List entries in a connector (files, keys, rows, etc)").option("--project-dir <path>", "Workspace directory", process.cwd()).option("--recursive", "Include nested entries").option("--limit <n>", "Maximum entries to return", parsePositiveIntOption).action(async (id, resourcePath, opts) => {
2909
- const projectDir = path18__default.resolve(opts.projectDir);
2944
+ const projectDir = path19__default.resolve(opts.projectDir);
2910
2945
  const manager = await connectConnectors(projectDir);
2911
2946
  try {
2912
2947
  const entries = await manager.list(id, resourcePath, {
@@ -2919,7 +2954,7 @@ ${installResult.output}`);
2919
2954
  }
2920
2955
  });
2921
2956
  cmd.command("search <id> <query>").description("Search within a connector for matching content").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, query, opts) => {
2922
- const projectDir = path18__default.resolve(opts.projectDir);
2957
+ const projectDir = path19__default.resolve(opts.projectDir);
2923
2958
  const manager = await connectConnectors(projectDir);
2924
2959
  try {
2925
2960
  const results = await manager.search(id, query);
@@ -2929,7 +2964,7 @@ ${installResult.output}`);
2929
2964
  }
2930
2965
  });
2931
2966
  cmd.command("delete <id> <resource-path>").description("Delete an entry from a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, opts) => {
2932
- const projectDir = path18__default.resolve(opts.projectDir);
2967
+ const projectDir = path19__default.resolve(opts.projectDir);
2933
2968
  const manager = await connectConnectors(projectDir);
2934
2969
  try {
2935
2970
  const ok = await manager.delete(id, resourcePath);
@@ -2939,7 +2974,7 @@ ${installResult.output}`);
2939
2974
  }
2940
2975
  });
2941
2976
  cmd.command("run <id> <op> [args...]").description("Run a custom adapter operation (e.g. git log, sqlite query)").option("--project-dir <path>", "Workspace directory", process.cwd()).allowUnknownOption().action(async (id, op, args, opts) => {
2942
- const projectDir = path18__default.resolve(opts.projectDir);
2977
+ const projectDir = path19__default.resolve(opts.projectDir);
2943
2978
  const manager = await connectConnectors(projectDir);
2944
2979
  try {
2945
2980
  if (!manager.has(id)) {
@@ -3048,7 +3083,7 @@ function envRecord() {
3048
3083
  async function buildDeployContext(projectDir) {
3049
3084
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
3050
3085
  const config = resolveSkWorkspaceConfig2(projectDir);
3051
- const workspaceId = config.name ?? path18__default.basename(projectDir);
3086
+ const workspaceId = config.name ?? path19__default.basename(projectDir);
3052
3087
  let log;
3053
3088
  try {
3054
3089
  const { createLogger } = await import('../core/logging.js');
@@ -3080,13 +3115,13 @@ async function ensureTargetsRegistered(projectDir) {
3080
3115
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
3081
3116
  const config = resolveSkWorkspaceConfig2(projectDir);
3082
3117
  if (config.plugins && config.plugins.length > 0) {
3083
- const { ensurePluginsLoaded } = await import('../plugin-store-MSH6GK6T.js');
3118
+ const { ensurePluginsLoaded } = await import('../plugin-store-ABE35NRX.js');
3084
3119
  const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
3085
3120
  for (const f of result.failed) logWarn(f.error);
3086
3121
  }
3087
3122
  }
3088
3123
  async function runUp(opts) {
3089
- const projectDir = path18__default.resolve(opts.projectDir);
3124
+ const projectDir = path19__default.resolve(opts.projectDir);
3090
3125
  await ensureTargetsRegistered(projectDir);
3091
3126
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
3092
3127
  const { resolveDeployTarget, pluginRegistry } = await import('../plugin-registry/index.js');
@@ -3154,7 +3189,7 @@ async function restoreFromHandle(projectDir) {
3154
3189
  return { target, handle, ctx };
3155
3190
  }
3156
3191
  async function runDown(opts) {
3157
- const projectDir = path18__default.resolve(opts.projectDir);
3192
+ const projectDir = path19__default.resolve(opts.projectDir);
3158
3193
  const restored = await restoreFromHandle(projectDir);
3159
3194
  if (!restored) return;
3160
3195
  await restored.handle.stop();
@@ -3163,7 +3198,7 @@ async function runDown(opts) {
3163
3198
  logOk(`Stopped ${S.cmd(restored.target.id)} and cleared the handle.`);
3164
3199
  }
3165
3200
  async function runStatus(opts) {
3166
- const projectDir = path18__default.resolve(opts.projectDir);
3201
+ const projectDir = path19__default.resolve(opts.projectDir);
3167
3202
  const restored = await restoreFromHandle(projectDir);
3168
3203
  if (!restored) return;
3169
3204
  const health = await restored.handle.health();
@@ -3177,7 +3212,7 @@ async function runStatus(opts) {
3177
3212
  console.log();
3178
3213
  }
3179
3214
  async function runLogs(opts) {
3180
- const projectDir = path18__default.resolve(opts.projectDir);
3215
+ const projectDir = path19__default.resolve(opts.projectDir);
3181
3216
  const restored = await restoreFromHandle(projectDir);
3182
3217
  if (!restored) return;
3183
3218
  if (!restored.handle.logs) {
@@ -3200,12 +3235,15 @@ function makeDeployCommand() {
3200
3235
  return cmd;
3201
3236
  }
3202
3237
  var DIFF_SHOWS = { content: true, modified: true, incomplete: true };
3238
+ function uniqueMessages(gaps) {
3239
+ return [...new Set(gaps.map((g) => g.message))];
3240
+ }
3203
3241
  function makeDiffCommand() {
3204
3242
  return new Command("diff").description("Show changes between deployed and source versions").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
3205
3243
  requireProjectConfig(opts.projectDir);
3206
3244
  const am2 = new AssetManager({
3207
3245
  registry: getKindRegistry(),
3208
- projectDir: path18__default.resolve(opts.projectDir)
3246
+ projectDir: path19__default.resolve(opts.projectDir)
3209
3247
  });
3210
3248
  try {
3211
3249
  parseAssetRef(ref);
@@ -3226,7 +3264,7 @@ function makeDiffCommand() {
3226
3264
  const requirementGaps = await am2.requirementGapsOf(ref);
3227
3265
  const blocking = gaps.filter((g) => !DIFF_SHOWS[g.type]);
3228
3266
  if (blocking.length > 0) {
3229
- for (const g of [...blocking, ...requirementGaps]) logErr(g.message);
3267
+ for (const line of uniqueMessages([...blocking, ...requirementGaps])) logErr(line);
3230
3268
  process.exitCode = 1;
3231
3269
  return;
3232
3270
  }
@@ -3257,7 +3295,7 @@ function makeDiffCommand() {
3257
3295
  console.log(result.diff);
3258
3296
  break;
3259
3297
  }
3260
- for (const g of [...problems, ...requirementGaps]) logErr(g.message);
3298
+ for (const line of uniqueMessages([...problems, ...requirementGaps])) logErr(line);
3261
3299
  if (result.status === "not-found" || problems.length > 0 || requirementGaps.length > 0)
3262
3300
  process.exitCode = 1;
3263
3301
  });
@@ -3265,7 +3303,7 @@ function makeDiffCommand() {
3265
3303
  function makeFlowCommand() {
3266
3304
  const cmd = new Command("flow").description("Manage flows");
3267
3305
  cmd.command("list").description("List the flows of this project").option("--project-dir <path>", "Project directory", process.cwd()).option("--all", "Also list the flows of registered libraries and cached sources").action(async (opts) => {
3268
- const projectDir = path18__default.resolve(opts.projectDir);
3306
+ const projectDir = path19__default.resolve(opts.projectDir);
3269
3307
  const flows = discoverProjectFlows(projectDir);
3270
3308
  const others = opts.all ? await discoverOtherFlows(projectDir) : [];
3271
3309
  if (flows.length === 0 && others.length === 0) {
@@ -3301,7 +3339,7 @@ function makeFlowCommand() {
3301
3339
  }
3302
3340
  });
3303
3341
  cmd.command("show <id>").description("Show flow details and node graph").option("--project-dir <path>", "Project directory", process.cwd()).option("--all", "Also look in registered libraries and cached sources").action(async (id, opts) => {
3304
- const projectDir = path18__default.resolve(opts.projectDir);
3342
+ const projectDir = path19__default.resolve(opts.projectDir);
3305
3343
  const flow = discoverProjectFlows(projectDir).find((f) => f.id === id) ?? (opts.all ? (await discoverOtherFlows(projectDir)).find((o) => o.flow.id === id)?.flow : void 0);
3306
3344
  if (!flow) {
3307
3345
  logErr(`Flow not found: ${id}`);
@@ -3335,12 +3373,68 @@ function makeFlowCommand() {
3335
3373
  cmd.action(() => cmd.help());
3336
3374
  return cmd;
3337
3375
  }
3376
+ var HARNESS_ID_OF_TARGET = {
3377
+ "claude-code": "claude-sdk",
3378
+ omp: "omp",
3379
+ codex: "codex"
3380
+ };
3381
+ function parseHarnessTarget(name) {
3382
+ if (name === "claude-sdk") return "claude-code";
3383
+ return SUPPORTED_HARNESSES.includes(name) ? name : void 0;
3384
+ }
3385
+ function makeHarnessCommand() {
3386
+ const cmd = new Command("harness").description("Choose the coding-agent harness of a project");
3387
+ cmd.command("set <name>").description(
3388
+ `Switch the project to a harness (${SUPPORTED_HARNESSES.join(" | ")}): rewrite skaile.yaml and install for it`
3389
+ ).option("--project-dir <path>", "Project directory", process.cwd()).action(async (name, opts) => {
3390
+ await runHarnessSet(name, path19__default.resolve(opts.projectDir));
3391
+ });
3392
+ cmd.action(() => cmd.help());
3393
+ return cmd;
3394
+ }
3395
+ async function runHarnessSet(name, projectDir) {
3396
+ const target = parseHarnessTarget(name);
3397
+ if (!target) {
3398
+ logErr(`Unknown harness "${name}". Supported: ${SUPPORTED_HARNESSES.join(", ")}`);
3399
+ process.exit(1);
3400
+ }
3401
+ requireProjectConfig(projectDir);
3402
+ const file = path19__default.join(projectDir, "skaile.yaml");
3403
+ const before = resolveConfiguredHarnessName(projectDir);
3404
+ let editor;
3405
+ try {
3406
+ editor = WorkspaceYamlEditor.load(file);
3407
+ } catch (err) {
3408
+ logErr(err instanceof Error ? err.message : String(err));
3409
+ process.exit(1);
3410
+ }
3411
+ const profile = editor.getAgentConfig("default");
3412
+ editor.setAgentConfig("default", {
3413
+ agent: target,
3414
+ harness: HARNESS_ID_OF_TARGET[target]
3415
+ });
3416
+ editor.save();
3417
+ if (before === target) {
3418
+ logInfo(`Project is already on ${S.cmd(target)}; installing for it.`);
3419
+ } else {
3420
+ logOk(
3421
+ `Set ${S.cmd("agent-config.default")} to ${S.cmd(`agent: ${target}`)}, ${S.cmd(`harness: ${HARNESS_ID_OF_TARGET[target]}`)} in skaile.yaml`
3422
+ );
3423
+ }
3424
+ if (profile?.model) {
3425
+ logInfo(
3426
+ `model ${profile.model} is kept. Check it fits ${target}: skaile run "hi there" --dry-run`
3427
+ );
3428
+ }
3429
+ logInfo(`Installing for ${target} (${HARNESS_TARGETS[target].local.skill})`);
3430
+ await runYamlInstall({ projectDir });
3431
+ }
3338
3432
  function makeHistoryCommand() {
3339
3433
  const cmd = new Command("history").description("Show recent add/remove/update actions");
3340
3434
  cmd.argument("[limit]", "Number of entries to show", "20").option("--project-dir <path>", "Project directory", process.cwd()).action((limitStr, opts) => {
3341
3435
  const am2 = new AssetManager({
3342
3436
  registry: getKindRegistry(),
3343
- projectDir: path18__default.resolve(opts.projectDir)
3437
+ projectDir: path19__default.resolve(opts.projectDir)
3344
3438
  });
3345
3439
  const limit = parseInt(limitStr, 10) || 20;
3346
3440
  const entries = am2.history(limit);
@@ -3363,7 +3457,7 @@ function makeHistoryCommand() {
3363
3457
  cmd.command("clear").description("Clear action history").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
3364
3458
  const am2 = new AssetManager({
3365
3459
  registry: getKindRegistry(),
3366
- projectDir: path18__default.resolve(opts.projectDir)
3460
+ projectDir: path19__default.resolve(opts.projectDir)
3367
3461
  });
3368
3462
  am2.clearHistory();
3369
3463
  logOk("History cleared.");
@@ -3394,7 +3488,7 @@ async function readConfig(p6) {
3394
3488
  }
3395
3489
  }
3396
3490
  async function writeConfig(p6, value) {
3397
- await fs5.mkdir(path18__default.dirname(p6), { recursive: true });
3491
+ await fs5.mkdir(path19__default.dirname(p6), { recursive: true });
3398
3492
  const cleaned = {};
3399
3493
  for (const [k, v] of Object.entries(value)) {
3400
3494
  if (v === void 0) continue;
@@ -3403,7 +3497,7 @@ async function writeConfig(p6, value) {
3403
3497
  await fs5.writeFile(p6, stringify$1(cleaned));
3404
3498
  }
3405
3499
  function configPath(projectDir) {
3406
- return path18__default.join(projectDir, ".codex", "config.toml");
3500
+ return path19__default.join(projectDir, ".codex", "config.toml");
3407
3501
  }
3408
3502
  async function install2(projectDir) {
3409
3503
  const p6 = configPath(projectDir);
@@ -3414,7 +3508,7 @@ async function install2(projectDir) {
3414
3508
  const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
3415
3509
  let warning;
3416
3510
  if (previous && !matches) {
3417
- warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path18__default.relative(projectDir, p6)}`;
3511
+ warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path19__default.relative(projectDir, p6)}`;
3418
3512
  }
3419
3513
  if (matches) return { changed: false, method: "toml" };
3420
3514
  servers[SKAILE_MCP_NAME] = next;
@@ -3422,7 +3516,7 @@ async function install2(projectDir) {
3422
3516
  return { changed: true, method: "toml", warning };
3423
3517
  }
3424
3518
  function userConfigPath2() {
3425
- return path18__default.join(process.env.CODEX_HOME || path18__default.join(homedir(), ".codex"), "config.toml");
3519
+ return path19__default.join(process.env.CODEX_HOME || path19__default.join(homedir(), ".codex"), "config.toml");
3426
3520
  }
3427
3521
  async function readUserConfig() {
3428
3522
  const p6 = userConfigPath2();
@@ -3464,7 +3558,7 @@ async function trustProject(projectDir) {
3464
3558
  } catch {
3465
3559
  return "refused";
3466
3560
  }
3467
- await fs5.mkdir(path18__default.dirname(p6), { recursive: true });
3561
+ await fs5.mkdir(path19__default.dirname(p6), { recursive: true });
3468
3562
  await fs5.writeFile(p6, next);
3469
3563
  await writeTrustMark(projectDir, [
3470
3564
  .../* @__PURE__ */ new Set([
@@ -3476,7 +3570,7 @@ async function trustProject(projectDir) {
3476
3570
  }
3477
3571
  var TRUST_MARK = "codexTrustAdded";
3478
3572
  function stateFilePath(projectDir) {
3479
- return path18__default.join(projectDir, ".skaile", "plugin-state.json");
3573
+ return path19__default.join(projectDir, ".skaile", "plugin-state.json");
3480
3574
  }
3481
3575
  async function readState(projectDir) {
3482
3576
  try {
@@ -3500,7 +3594,7 @@ async function writeTrustMark(projectDir, roots) {
3500
3594
  const state2 = await readState(projectDir);
3501
3595
  if (roots.length > 0) state2[TRUST_MARK] = roots;
3502
3596
  else delete state2[TRUST_MARK];
3503
- await fs5.mkdir(path18__default.dirname(stateFilePath(projectDir)), { recursive: true });
3597
+ await fs5.mkdir(path19__default.dirname(stateFilePath(projectDir)), { recursive: true });
3504
3598
  await fs5.writeFile(stateFilePath(projectDir), JSON.stringify(state2, null, 2));
3505
3599
  }
3506
3600
  async function untrustProject(projectDir) {
@@ -3598,12 +3692,12 @@ async function status2(projectDir) {
3598
3692
  installed: "yes",
3599
3693
  enabled: trusted ? "n/a" : "untrusted",
3600
3694
  method: "mcp",
3601
- location: path18__default.relative(projectDir, p6)
3695
+ location: path19__default.relative(projectDir, p6)
3602
3696
  };
3603
3697
  }
3604
3698
  async function install3(projectDir) {
3605
- const extDir = path18__default.join(projectDir, ".omp", "extensions");
3606
- const extPath = path18__default.join(extDir, "skaile.ts");
3699
+ const extDir = path19__default.join(projectDir, ".omp", "extensions");
3700
+ const extPath = path19__default.join(extDir, "skaile.ts");
3607
3701
  await fs5.mkdir(extDir, { recursive: true });
3608
3702
  const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
3609
3703
  const plugin = new WorkspacePlugin({ projectDir });
@@ -3618,7 +3712,7 @@ async function install3(projectDir) {
3618
3712
  return { changed: true, method: "generated" };
3619
3713
  }
3620
3714
  async function uninstall3(projectDir) {
3621
- const extPath = path18__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3715
+ const extPath = path19__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3622
3716
  try {
3623
3717
  await fs5.unlink(extPath);
3624
3718
  return { changed: true };
@@ -3627,14 +3721,14 @@ async function uninstall3(projectDir) {
3627
3721
  }
3628
3722
  }
3629
3723
  async function status3(projectDir) {
3630
- const extPath = path18__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3724
+ const extPath = path19__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3631
3725
  if (existsSync(extPath)) {
3632
3726
  return {
3633
3727
  harness: "omp",
3634
3728
  installed: "yes",
3635
3729
  enabled: "n/a",
3636
3730
  method: "extension",
3637
- location: path18__default.relative(projectDir, extPath)
3731
+ location: path19__default.relative(projectDir, extPath)
3638
3732
  };
3639
3733
  }
3640
3734
  return {
@@ -3689,15 +3783,27 @@ async function installOmp(projectDir) {
3689
3783
  logInfo(`omp: already installed (${r.method})`);
3690
3784
  }
3691
3785
  await unignoreOmpExtension(projectDir);
3692
- if (isGitIgnored(projectDir, OMP_EXTENSION)) {
3786
+ const rule = ompExtensionIgnoreRule(projectDir, OMP_EXTENSION);
3787
+ if (rule) {
3693
3788
  logWarn(
3694
- `git ignores ${OMP_EXTENSION} (a global ignore file or .git/info/exclude); omp does not load an ignored extension. Remove that rule.`
3789
+ `git ignores ${OMP_EXTENSION} (${rule}); omp does not load an ignored extension. Remove that rule.`
3695
3790
  );
3696
3791
  }
3697
3792
  console.log(` ${S.dim("\u2192")} OMP auto-discovers extensions on next startup.`);
3698
3793
  }
3699
- function isGitIgnored(projectDir, file) {
3700
- return spawnSync("git", ["check-ignore", "-q", file], { cwd: projectDir, stdio: "ignore" }).status === 0;
3794
+ function ompExtensionIgnoreRule(projectDir, file) {
3795
+ const verbose = (p6) => {
3796
+ const r = spawnSync("git", ["check-ignore", "-v", p6], { cwd: projectDir, encoding: "utf-8" });
3797
+ return r.status === 0 ? r.stdout.trim() || void 0 : void 0;
3798
+ };
3799
+ const hit = verbose(file);
3800
+ if (!hit) return void 0;
3801
+ const dirs = [];
3802
+ for (let d = path19__default.posix.dirname(file); d !== "."; d = path19__default.posix.dirname(d)) dirs.push(d);
3803
+ if (dirs.some((d) => verbose(d) !== void 0)) return void 0;
3804
+ const [rule] = hit.split(" ");
3805
+ const m = /^(.*?):(\d+):(.*)$/.exec(rule ?? "");
3806
+ return m ? `${m[1]}:${m[2]}: ${m[3]}` : rule;
3701
3807
  }
3702
3808
  async function installCodex(projectDir) {
3703
3809
  const r = await install2(projectDir);
@@ -3722,7 +3828,7 @@ ${await trustEntry(projectDir)}`
3722
3828
  console.log(` ${S.dim("\u2192")} Restart Codex CLI to pick up the change.`);
3723
3829
  }
3724
3830
  async function runInstall(opts) {
3725
- const projectDir = path18__default.resolve(opts.projectDir);
3831
+ const projectDir = path19__default.resolve(opts.projectDir);
3726
3832
  const targets = resolveHarness(opts.harness);
3727
3833
  if (!targets) return 1;
3728
3834
  let exitCode = 0;
@@ -3785,7 +3891,7 @@ async function uninstallCodex(projectDir) {
3785
3891
  }
3786
3892
  }
3787
3893
  async function runUninstall(opts) {
3788
- const projectDir = path18__default.resolve(opts.projectDir);
3894
+ const projectDir = path19__default.resolve(opts.projectDir);
3789
3895
  const targets = resolveHarness(opts.harness);
3790
3896
  if (!targets) return 1;
3791
3897
  let exitCode = 0;
@@ -3808,12 +3914,12 @@ async function runUninstall(opts) {
3808
3914
  return exitCode;
3809
3915
  }
3810
3916
  async function removeEmptyPluginState(projectDir) {
3811
- const stateFile = path18__default.join(projectDir, ".skaile", "plugin-state.json");
3917
+ const stateFile = path19__default.join(projectDir, ".skaile", "plugin-state.json");
3812
3918
  try {
3813
3919
  const parsed = JSON.parse(await fs5.readFile(stateFile, "utf-8"));
3814
3920
  if (typeof parsed !== "object" || parsed === null || Object.keys(parsed).length > 0) return;
3815
3921
  await fs5.unlink(stateFile);
3816
- await fs5.rmdir(path18__default.dirname(stateFile)).catch(() => void 0);
3922
+ await fs5.rmdir(path19__default.dirname(stateFile)).catch(() => void 0);
3817
3923
  } catch {
3818
3924
  }
3819
3925
  }
@@ -3824,7 +3930,7 @@ var PER_MACHINE_FILES = {
3824
3930
  };
3825
3931
  var OMP_EXTENSION = ".omp/extensions/skaile.ts";
3826
3932
  async function unignoreOmpExtension(projectDir) {
3827
- const gitignore = path18__default.join(projectDir, ".gitignore");
3933
+ const gitignore = path19__default.join(projectDir, ".gitignore");
3828
3934
  let text;
3829
3935
  try {
3830
3936
  text = await fs5.readFile(gitignore, "utf-8");
@@ -3841,12 +3947,12 @@ async function unignoreOmpExtension(projectDir) {
3841
3947
  }
3842
3948
  var CLAUDE_FULL_FILES = [".claude/settings.json", ".claude/plugins/skaile/"];
3843
3949
  async function ignorePerMachineFiles(projectDir, targets, full) {
3844
- const gitignore = path18__default.join(projectDir, ".gitignore");
3950
+ const gitignore = path19__default.join(projectDir, ".gitignore");
3845
3951
  let existing = null;
3846
3952
  try {
3847
3953
  existing = await fs5.readFile(gitignore, "utf-8");
3848
3954
  } catch {
3849
- if (!existsSync(path18__default.join(projectDir, ".git"))) return;
3955
+ if (!existsSync(path19__default.join(projectDir, ".git"))) return;
3850
3956
  }
3851
3957
  const have = new Set((existing ?? "").split("\n").map((l) => l.trim()));
3852
3958
  const wanted = [
@@ -3890,7 +3996,7 @@ async function toggleTarget(t, projectDir, action3) {
3890
3996
  });
3891
3997
  }
3892
3998
  async function runToggle(opts, action3) {
3893
- const projectDir = path18__default.resolve(opts.projectDir);
3999
+ const projectDir = path19__default.resolve(opts.projectDir);
3894
4000
  const requestedAll = opts.harness === "all";
3895
4001
  const targets = resolveHarness(opts.harness);
3896
4002
  if (!targets) return 1;
@@ -3903,7 +4009,7 @@ async function runToggle(opts, action3) {
3903
4009
  return exitCode;
3904
4010
  }
3905
4011
  async function runStatus2(opts) {
3906
- const projectDir = path18__default.resolve(opts.projectDir);
4012
+ const projectDir = path19__default.resolve(opts.projectDir);
3907
4013
  const targets = resolveHarness(opts.harness);
3908
4014
  if (!targets) return 1;
3909
4015
  const rows = [];
@@ -3975,7 +4081,7 @@ async function runHook(event) {
3975
4081
  await plugin.shutdown();
3976
4082
  return;
3977
4083
  }
3978
- const store = new PluginStore(path18__default.join(projectDir, ".skaile", "plugin-state.json"));
4084
+ const store = new PluginStore(path19__default.join(projectDir, ".skaile", "plugin-state.json"));
3979
4085
  await store.load();
3980
4086
  const status4 = store.get("connector:status");
3981
4087
  if (status4 && typeof status4 === "object" && Object.keys(status4).length > 0) {
@@ -4054,7 +4160,7 @@ function makeIntegrationCommand() {
4054
4160
  cmd.command("omp-exec <kind> <name>").description(
4055
4161
  "Run one tool or slash command of the omp extension (used by .omp/extensions/skaile.ts)"
4056
4162
  ).option("--project-dir <path>", "Project directory", process.cwd()).action(async (kind, name, opts) => {
4057
- process.exitCode = await runOmpExec(kind, name, path18__default.resolve(opts.projectDir));
4163
+ process.exitCode = await runOmpExec(kind, name, path19__default.resolve(opts.projectDir));
4058
4164
  });
4059
4165
  cmd.command("hook <event>").description(
4060
4166
  "Run a Claude Code lifecycle hook (session-start | session-end | user-prompt-submit)"
@@ -4097,7 +4203,7 @@ function unfinishedGitState(dir) {
4097
4203
  for (const [entry, state2] of Object.entries(UNFINISHED_GIT_ENTRIES)) {
4098
4204
  const p6 = spawnSync("git", ["rev-parse", "--git-path", entry], { cwd: dir, encoding: "utf-8" });
4099
4205
  if (p6.status !== 0) return "the git directory could not be read";
4100
- if (fs8.existsSync(path18.resolve(dir, p6.stdout.trim()))) return state2;
4206
+ if (fs8.existsSync(path19.resolve(dir, p6.stdout.trim()))) return state2;
4101
4207
  }
4102
4208
  return null;
4103
4209
  }
@@ -4105,7 +4211,7 @@ async function reindexLibrary(lib, library, name) {
4105
4211
  assertManifestEditableOrExit(lib.path);
4106
4212
  exitOnManifestPublisherProblems(lib.path, name);
4107
4213
  exitOnLibrarySymlinks(lib.path, `skaile library index ${name}`);
4108
- exitOnManifestRootProblems(lib.path, `skaile library index ${name}`);
4214
+ exitOnManifestPathProblems(lib.path, `skaile library index ${name}`);
4109
4215
  const badRequires = manifestRequiresProblems(lib.path);
4110
4216
  const resolved = resolveLibraryPublisherDetailed(lib, {}, getStoreIdentity());
4111
4217
  warnLibraryNameFallback(name, resolved);
@@ -4122,7 +4228,7 @@ async function reindexLibrary(lib, library, name) {
4122
4228
  {
4123
4229
  check: (e) => checkAssetFile(e.source, e.kind, registry, lib.path, composeRefs),
4124
4230
  // A flow the engine would never load under its id (p871): keep it out of the manifest and the index.
4125
- refuse: (e) => e.kind === "flow" && flowFileNameError({ id: e.name }, path18.basename(e.source)) !== void 0
4231
+ refuse: (e) => e.kind === "flow" && flowFileNameError({ id: e.name }, path19.basename(e.source)) !== void 0
4126
4232
  }
4127
4233
  );
4128
4234
  const manifest = loadSkPublishManifest(lib.path);
@@ -4143,7 +4249,7 @@ async function reindexLibrary(lib, library, name) {
4143
4249
  }
4144
4250
  const invalidVersion = skipped.filter((x) => x.reason === "invalid-version");
4145
4251
  for (const s of invalidVersion) {
4146
- const found = checkAssetFile(path18.join(lib.path, s.file), s.kind, registry).find(
4252
+ const found = checkAssetFile(path19.join(lib.path, s.file), s.kind, registry).find(
4147
4253
  (f) => f.text.startsWith("version ")
4148
4254
  );
4149
4255
  const detail = found?.text ?? s.detail;
@@ -4154,28 +4260,36 @@ async function reindexLibrary(lib, library, name) {
4154
4260
  }
4155
4261
  const duplicates = skipped.filter((x) => x.reason === "duplicate");
4156
4262
  for (const s of duplicates) {
4157
- logErr(duplicateAssetMessage(s.kind, s.name, path18.dirname(s.file), s.detail, name));
4263
+ logErr(duplicateAssetMessage(s.kind, s.name, path19.dirname(s.file), s.detail, name));
4158
4264
  }
4159
4265
  for (const s of failed) {
4160
4266
  for (const f of s.findings) logErr(`${s.file} [${f.tag}] \u2014 ${f.text}`);
4161
4267
  }
4162
- const duplicateFiles = new Set(duplicates.map((s) => path18.resolve(lib.path, s.file)));
4268
+ const duplicateFiles = new Set(duplicates.map((s) => path19.resolve(lib.path, s.file)));
4163
4269
  const skippedKeys = new Set(
4164
4270
  [
4165
4271
  ...skipped.filter((s) => s.reason !== "duplicate"),
4166
4272
  ...failed.filter((s) => !s.inManifest)
4167
4273
  ].map((s) => `${s.kind}:${s.name}`)
4168
4274
  );
4275
+ const refusedFiles = new Set(
4276
+ [
4277
+ ...skipped.filter((s) => s.reason !== "duplicate"),
4278
+ ...failed.filter((s) => !s.inManifest)
4279
+ ].map((s) => path19.resolve(lib.path, s.file))
4280
+ );
4169
4281
  const res = await indexLibrary(lib, library, {
4170
- exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`) || duplicateFiles.has(path18.resolve(a.manifestPath))
4282
+ exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`) || duplicateFiles.has(path19.resolve(a.manifestPath)) || refusedFiles.has(path19.resolve(a.manifestPath))
4171
4283
  });
4172
4284
  const unparsable = res.unparsable;
4173
4285
  for (const e of res.errors) (unparsable.includes(e) ? logErr : logWarn)(e);
4174
4286
  const syncUnparsable = skipped.filter(
4175
- (s) => s.reason === "unparsable" && !unparsable.some((e) => e.includes(s.file))
4287
+ (s) => s.reason === "unparsable" && !unparsable.some((e) => e.startsWith(`${s.file} `))
4176
4288
  );
4177
4289
  for (const s of syncUnparsable) {
4178
- logErr(`${s.kind}:${s.name} skipped: manifest file ${s.file} could not be parsed.`);
4290
+ logErr(
4291
+ manifestParseFailureLine(lib.path, s.file) ?? `${s.file} [${s.kind}] \u2014 ${manifestParseErrorText("the manifest file could not be read")}`
4292
+ );
4179
4293
  }
4180
4294
  for (const p6 of badRequires) logErr(`${p6.asset}: ${p6.message}`);
4181
4295
  for (const w of await unresolvedManifestDependencies(lib.path)) logWarn(w);
@@ -4185,7 +4299,7 @@ async function reindexLibrary(lib, library, name) {
4185
4299
  const file = findEntryManifestFile(lib.path, a);
4186
4300
  if (!file) continue;
4187
4301
  for (const f of unheldRequiresOfFile(file, a.kind, composeRefs)) {
4188
- logWarn(`${path18.relative(lib.path, file)} [${f.tag}] \u2014 ${f.text}`);
4302
+ logWarn(`${path19.relative(lib.path, file)} [${f.tag}] \u2014 ${f.text}`);
4189
4303
  }
4190
4304
  }
4191
4305
  const skippedUnparsable = unparsable.length + syncUnparsable.length;
@@ -4250,18 +4364,55 @@ var DEPLOYED_COPY_DIRS = [
4250
4364
  )
4251
4365
  )
4252
4366
  ];
4367
+ var DEPLOY_ROOT_FOLDERS = new Set(
4368
+ DEPLOYED_COPY_DIRS.map((d) => d.split("/")[0])
4369
+ );
4370
+ function deployFolderBelowProject(dir) {
4371
+ const real = canonicalDir(dir);
4372
+ const home = (() => {
4373
+ try {
4374
+ return fs8.realpathSync(os.homedir());
4375
+ } catch {
4376
+ return void 0;
4377
+ }
4378
+ })();
4379
+ for (let cur = real; path19.dirname(cur) !== cur; cur = path19.dirname(cur)) {
4380
+ const project = path19.dirname(cur);
4381
+ const folder = path19.basename(cur);
4382
+ if (!DEPLOY_ROOT_FOLDERS.has(folder) || project === home) continue;
4383
+ const isProject = fs8.existsSync(path19.join(project, "skaile.yaml")) || DEPLOYED_COPY_DIRS.some((d) => {
4384
+ const full = path19.join(project, d);
4385
+ try {
4386
+ return fs8.statSync(full).isDirectory() && fs8.readdirSync(full).length > 0;
4387
+ } catch {
4388
+ return false;
4389
+ }
4390
+ });
4391
+ if (isProject) return { folder, project };
4392
+ }
4393
+ return void 0;
4394
+ }
4395
+ function refuseDeployFolder(dir, force = false) {
4396
+ const deployFolder = force ? void 0 : deployFolderBelowProject(dir);
4397
+ if (!deployFolder) return;
4398
+ logErr(
4399
+ `${dir} is inside the deploy folder ${deployFolder.folder}/ of the project ${deployFolder.project}: a library holds asset sources, not the copies \`skaile add\` deployed. Pick another --path for the library, or pass --force when the sources live in that folder.`
4400
+ );
4401
+ process.exit(1);
4402
+ }
4253
4403
  async function refuseUnusableLibraryDir(dir, force = false) {
4254
4404
  const deployed = DEPLOYED_COPY_DIRS.filter((d) => {
4255
- const full = path18.join(dir, d);
4405
+ const full = path19.join(dir, d);
4256
4406
  return fs8.existsSync(full) && fs8.statSync(full).isDirectory() && fs8.readdirSync(full).length > 0;
4257
4407
  });
4258
4408
  if (deployed.length > 0 && !force) {
4259
- const where = fs8.existsSync(path18.join(dir, "skaile.yaml")) ? "skaile.yaml with deployed copies" : "deployed copies";
4409
+ const where = fs8.existsSync(path19.join(dir, "skaile.yaml")) ? "skaile.yaml with deployed copies" : "deployed copies";
4260
4410
  logErr(
4261
4411
  `${dir} is a project folder (${where} in ${deployed.map((d) => `${d}/`).join(", ")}): a library holds asset sources, not the copies \`skaile add\` deployed. Pick another --path for the library, or pass --force when the sources live in those folders.`
4262
4412
  );
4263
4413
  process.exit(1);
4264
4414
  }
4415
+ refuseDeployFolder(dir, force);
4265
4416
  assertManifestEditableOrExit(dir);
4266
4417
  const unparsable = await unparsableAssetFiles(dir, getKindRegistry());
4267
4418
  if (unparsable.length > 0) {
@@ -4273,26 +4424,26 @@ async function refuseUnusableLibraryDir(dir, force = false) {
4273
4424
  }
4274
4425
  async function assertLibraryPathFree(manager, dir, exceptId) {
4275
4426
  const clash = (await manager.listLibraries()).find(
4276
- (l) => l.id !== exceptId && path18.resolve(l.path) === dir
4427
+ (l) => l.id !== exceptId && path19.resolve(l.path) === dir
4277
4428
  );
4278
4429
  if (clash) throw new Error(`${dir} is already registered as library "${clash.name}".`);
4279
4430
  }
4280
4431
  function canonicalDir(dir) {
4281
- const abs = path18.resolve(dir);
4432
+ const abs = path19.resolve(dir);
4282
4433
  const missing = [];
4283
4434
  let existing = abs;
4284
4435
  while (!fs8.existsSync(existing)) {
4285
- const parent = path18.dirname(existing);
4436
+ const parent = path19.dirname(existing);
4286
4437
  if (parent === existing) return abs;
4287
- missing.unshift(path18.basename(existing));
4438
+ missing.unshift(path19.basename(existing));
4288
4439
  existing = parent;
4289
4440
  }
4290
- return path18.join(fs8.realpathSync(existing), ...missing);
4441
+ return path19.join(fs8.realpathSync(existing), ...missing);
4291
4442
  }
4292
4443
  function refuseGlobalInstallFolder(name, dir) {
4293
4444
  const reserved = globalInstallDir();
4294
- const rel = path18.relative(canonicalDir(reserved).toLowerCase(), canonicalDir(dir).toLowerCase());
4295
- const inside = rel === "" || !rel.startsWith("..") && !path18.isAbsolute(rel);
4445
+ const rel = path19.relative(canonicalDir(reserved).toLowerCase(), canonicalDir(dir).toLowerCase());
4446
+ const inside = rel === "" || !rel.startsWith("..") && !path19.isAbsolute(rel);
4296
4447
  if (name?.toLowerCase() === GLOBAL_INSTALL_DIR_NAME || inside) {
4297
4448
  logErr(
4298
4449
  `"${GLOBAL_INSTALL_DIR_NAME}" is reserved: ${reserved} holds assets from \`skaile install\`, not a library you author.`
@@ -4302,8 +4453,8 @@ function refuseGlobalInstallFolder(name, dir) {
4302
4453
  }
4303
4454
  async function refuseNestedLibraryPath(manager, dir, exceptId) {
4304
4455
  const within = (parent, child) => {
4305
- const rel = path18.relative(parent, child);
4306
- return rel === "" || !rel.startsWith("..") && !path18.isAbsolute(rel);
4456
+ const rel = path19.relative(parent, child);
4457
+ return rel === "" || !rel.startsWith("..") && !path19.isAbsolute(rel);
4307
4458
  };
4308
4459
  const target = canonicalDir(dir).toLowerCase();
4309
4460
  const librariesDir = resolveLibraryDir();
@@ -4340,7 +4491,7 @@ function assertCreateDirInsideLibrary(libRoot, destDir, given) {
4340
4491
  }
4341
4492
  };
4342
4493
  let probe = destDir;
4343
- while (!exists(probe)) probe = path18.dirname(probe);
4494
+ while (!exists(probe)) probe = path19.dirname(probe);
4344
4495
  let realProbe;
4345
4496
  try {
4346
4497
  realProbe = fs8.realpathSync(probe);
@@ -4353,19 +4504,19 @@ function assertCreateDirInsideLibrary(libRoot, destDir, given) {
4353
4504
  process.exit(1);
4354
4505
  }
4355
4506
  const realRoot = canonicalDir(libRoot);
4356
- const realDest = path18.join(realProbe, path18.relative(probe, destDir));
4357
- const rel = path18.relative(realRoot, realDest);
4358
- if (rel === ".." || rel.startsWith(`..${path18.sep}`) || path18.isAbsolute(rel)) {
4507
+ const realDest = path19.join(realProbe, path19.relative(probe, destDir));
4508
+ const rel = path19.relative(realRoot, realDest);
4509
+ if (rel === ".." || rel.startsWith(`..${path19.sep}`) || path19.isAbsolute(rel)) {
4359
4510
  logErr(
4360
4511
  `--dir "${given}" must stay inside the library (${realRoot}): it resolves to ${realDest}.`
4361
4512
  );
4362
4513
  process.exit(1);
4363
4514
  }
4364
- const relParts = path18.relative(path18.resolve(libRoot), path18.resolve(destDir)).split(path18.sep);
4365
- let walked = path18.resolve(libRoot);
4515
+ const relParts = path19.relative(path19.resolve(libRoot), path19.resolve(destDir)).split(path19.sep);
4516
+ let walked = path19.resolve(libRoot);
4366
4517
  for (const [i, part] of relParts.entries()) {
4367
4518
  if (part === "" || part === ".") continue;
4368
- walked = path18.join(walked, part);
4519
+ walked = path19.join(walked, part);
4369
4520
  if (!exists(walked)) break;
4370
4521
  if (fs8.lstatSync(walked).isSymbolicLink()) {
4371
4522
  logErr(
@@ -4379,7 +4530,7 @@ function assertCreateDirInsideLibrary(libRoot, destDir, given) {
4379
4530
  }
4380
4531
  }
4381
4532
  function adoptWritesManifest(libPath) {
4382
- if (!fs8.existsSync(path18.join(libPath, SKAILE_MANIFEST_FILENAME))) return true;
4533
+ if (!fs8.existsSync(path19.join(libPath, SKAILE_MANIFEST_FILENAME))) return true;
4383
4534
  const manifest = loadSkPublishManifest(libPath);
4384
4535
  if (!manifest || manifest.source || (manifest.assets ?? []).length > 0) return false;
4385
4536
  return manifestPublisherProblems(libPath).length === 0;
@@ -4433,13 +4584,13 @@ function requireValidLibraryName(name) {
4433
4584
  var LOCAL_OWNERSHIP_REASON = "ownership only governs sync with a git remote, and a local library is always owned by you.";
4434
4585
  function pruneEmptyLibraryParents(libPath) {
4435
4586
  const root = canonicalDir(resolveLibraryDir());
4436
- let dir = path18.dirname(path18.resolve(libPath));
4587
+ let dir = path19.dirname(path19.resolve(libPath));
4437
4588
  for (; ; ) {
4438
- const rel = path18.relative(root, canonicalDir(dir));
4439
- if (rel === "" || rel.startsWith("..") || path18.isAbsolute(rel)) return;
4589
+ const rel = path19.relative(root, canonicalDir(dir));
4590
+ if (rel === "" || rel.startsWith("..") || path19.isAbsolute(rel)) return;
4440
4591
  if (!fs8.existsSync(dir) || fs8.readdirSync(dir).length > 0) return;
4441
4592
  fs8.rmdirSync(dir);
4442
- dir = path18.dirname(dir);
4593
+ dir = path19.dirname(dir);
4443
4594
  }
4444
4595
  }
4445
4596
  function remoteBranches(url) {
@@ -4452,7 +4603,7 @@ function remoteBranches(url) {
4452
4603
  return r.stdout.split("\n").map((line) => line.split(" ")[1]?.replace(/^refs\/heads\//, "")).filter((b) => !!b);
4453
4604
  }
4454
4605
  async function warnIfNotGithubRemote(name, url) {
4455
- const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-KKQ2ULLX.js');
4606
+ const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-I3UWXAHI.js');
4456
4607
  if (!isGithubRemote(url)) logWarn(notGithubRemoteMessage(name, url));
4457
4608
  }
4458
4609
  function scaffoldLibraryFiles(dir, name) {
@@ -4484,7 +4635,7 @@ by the same ref.
4484
4635
  ];
4485
4636
  const written = [];
4486
4637
  for (const [file, content] of files) {
4487
- const target = path18.join(dir, file);
4638
+ const target = path19.join(dir, file);
4488
4639
  if (fs8.existsSync(target)) continue;
4489
4640
  fs8.writeFileSync(target, content, "utf8");
4490
4641
  written.push(file);
@@ -4519,7 +4670,7 @@ function makeLibraryCommand() {
4519
4670
  for (const l of ls) {
4520
4671
  const def = l.isDefault ? pc5.green("\u25B8 ") : " ";
4521
4672
  console.log(
4522
- `${def}${S.cmd(l.name.padEnd(nameW))} ${pc5.dim(l.backend.padEnd(backendW))} ${pc5.dim(l.ownership.padEnd(ownerW))} ${pc5.dim(l.path)}`
4673
+ `${def}${S.cmd(l.name.padEnd(nameW))} ${pc5.dim(l.backend.padEnd(backendW))} ${pc5.dim(l.ownership.padEnd(ownerW))} ${pc5.dim(l.path)}${libraryDirMissing(l) ? ` ${pc5.red("(directory missing)")}` : ""}`
4523
4674
  );
4524
4675
  }
4525
4676
  console.log(`
@@ -4541,6 +4692,11 @@ function makeLibraryCommand() {
4541
4692
  const { manager, close } = await openLibraryManager();
4542
4693
  try {
4543
4694
  const l = await manager.requireLibrary(name);
4695
+ if (libraryDirMissing(l)) {
4696
+ logErr(missingLibraryDirMessage(l));
4697
+ process.exitCode = 1;
4698
+ return;
4699
+ }
4544
4700
  console.log();
4545
4701
  console.log(S.heading(` ${l.name}`));
4546
4702
  console.log(` ${S.rule(50)}`);
@@ -4552,10 +4708,6 @@ function makeLibraryCommand() {
4552
4708
  console.log(` ${S.label("manifestGen")} ${l.manifestGenerated}`);
4553
4709
  console.log(` ${S.label("backendConfig")} ${JSON.stringify(l.backendConfig)}`);
4554
4710
  console.log();
4555
- if (libraryDirMissing(l)) {
4556
- logErr(missingLibraryDirMessage(l));
4557
- process.exitCode = 1;
4558
- }
4559
4711
  } finally {
4560
4712
  close();
4561
4713
  }
@@ -4577,7 +4729,7 @@ function makeLibraryCommand() {
4577
4729
  opts.path ??= gone.path;
4578
4730
  }
4579
4731
  const ownership = flagged[0] ?? gone?.ownership ?? "owner";
4580
- const libPath = opts.path ? path18.resolve(opts.path) : path18.join(resolveLibraryDir(), name);
4732
+ const libPath = opts.path ? path19.resolve(opts.path) : path19.join(resolveLibraryDir(), name);
4581
4733
  refuseGlobalInstallFolder(name, libPath);
4582
4734
  if (fs8.existsSync(libPath) && !fs8.statSync(libPath).isDirectory()) {
4583
4735
  logErr(`${libPath} exists and is not a directory.`);
@@ -4603,6 +4755,8 @@ function makeLibraryCommand() {
4603
4755
  if (fs8.existsSync(libPath)) {
4604
4756
  exitOnLibrarySymlinks(libPath, `skaile library init ${name} --path ${libPath}`);
4605
4757
  await refuseUnusableLibraryDir(libPath, opts.force);
4758
+ } else {
4759
+ refuseDeployFolder(libPath, opts.force);
4606
4760
  }
4607
4761
  const hasDefault = (await manager.listLibraries()).some((l) => l.isDefault);
4608
4762
  let backend = "local";
@@ -4769,10 +4923,10 @@ function makeLibraryCommand() {
4769
4923
  exitOnManifestPublisherProblems(target.path, target.name);
4770
4924
  const effectiveKind = opts.kind ?? kind;
4771
4925
  const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
4772
- const libRoot = path18.resolve(target.path);
4773
- const destDir = opts.dir ? path18.resolve(libRoot, opts.dir) : libRoot;
4774
- const relDest = path18.relative(libRoot, destDir);
4775
- if (relDest === ".." || relDest.startsWith(`..${path18.sep}`) || path18.isAbsolute(relDest)) {
4926
+ const libRoot = path19.resolve(target.path);
4927
+ const destDir = opts.dir ? path19.resolve(libRoot, opts.dir) : libRoot;
4928
+ const relDest = path19.relative(libRoot, destDir);
4929
+ if (relDest === ".." || relDest.startsWith(`..${path19.sep}`) || path19.isAbsolute(relDest)) {
4776
4930
  logErr(`--dir "${opts.dir}" must stay inside the library (${libRoot}).`);
4777
4931
  process.exit(1);
4778
4932
  }
@@ -4781,21 +4935,21 @@ function makeLibraryCommand() {
4781
4935
  libRoot,
4782
4936
  effectiveKind,
4783
4937
  name,
4784
- path18.relative(libRoot, path18.join(destDir, name))
4938
+ path19.relative(libRoot, path19.join(destDir, name))
4785
4939
  );
4786
4940
  if (taken) {
4787
4941
  logErr(
4788
- `${effectiveKind}:${name} already exists at "${taken}" \u2014 creating it again under "${path18.relative(libRoot, destDir) || "."}" would re-point the manifest entry. Pick another name.`
4942
+ `${effectiveKind}:${name} already exists at "${taken}" \u2014 creating it again under "${path19.relative(libRoot, destDir) || "."}" would re-point the manifest entry. Pick another name.`
4789
4943
  );
4790
4944
  process.exit(1);
4791
4945
  }
4792
- const wanted = path18.relative(libRoot, path18.join(destDir, name));
4946
+ const wanted = path19.relative(libRoot, path19.join(destDir, name));
4793
4947
  const onDisk = (await scanUnlistedAssets(libRoot, target.name, getKindRegistry())).find(
4794
4948
  (u) => u.entry.kind === effectiveKind && u.entry.name === name && u.root !== wanted
4795
4949
  );
4796
4950
  if (onDisk) {
4797
4951
  logErr(
4798
- `${effectiveKind}:${name} already exists at "${onDisk.root}" (not in the manifest yet) \u2014 creating it again under "${path18.relative(libRoot, destDir) || "."}" would be a duplicate. Run \`skaile library index ${target.name}\` first or pick another name.`
4952
+ `${effectiveKind}:${name} already exists at "${onDisk.root}" (not in the manifest yet) \u2014 creating it again under "${path19.relative(libRoot, destDir) || "."}" would be a duplicate. Run \`skaile library index ${target.name}\` first or pick another name.`
4799
4953
  );
4800
4954
  process.exit(1);
4801
4955
  }
@@ -4845,6 +4999,12 @@ function makeLibraryCommand() {
4845
4999
  cmd.command("default <name>").description("Set <name> as the default library").action(async (name) => {
4846
5000
  const { manager, close } = await openLibraryManager();
4847
5001
  try {
5002
+ const lib = await manager.requireLibrary(name);
5003
+ if (libraryDirMissing(lib)) {
5004
+ logErr(missingLibraryDirMessage(lib));
5005
+ process.exitCode = 1;
5006
+ return;
5007
+ }
4848
5008
  const updated = await manager.setDefault(name);
4849
5009
  logOk(`Default \u2192 ${updated.name}`);
4850
5010
  } finally {
@@ -4861,7 +5021,7 @@ function makeLibraryCommand() {
4861
5021
  logErr(`A library named "${newName}" is already registered.`);
4862
5022
  process.exit(1);
4863
5023
  }
4864
- const newPath = path18.join(path18.dirname(lib.path), newName);
5024
+ const newPath = path19.join(path19.dirname(lib.path), newName);
4865
5025
  refuseGlobalInstallFolder(newName, newPath);
4866
5026
  if (fs8.existsSync(newPath)) {
4867
5027
  logErr(`Target directory already exists: ${newPath}`);
@@ -4954,7 +5114,7 @@ function makeLibraryCommand() {
4954
5114
  }
4955
5115
  patch.isDefault = false;
4956
5116
  } else if (field === "path") {
4957
- const dir = path18.resolve(value);
5117
+ const dir = path19.resolve(value);
4958
5118
  if (!fs8.existsSync(dir) || !fs8.statSync(dir).isDirectory()) {
4959
5119
  logErr(`Directory does not exist: ${dir}. \`library set path=\` does not move files.`);
4960
5120
  process.exit(1);
@@ -5174,16 +5334,16 @@ function makeLibraryCommand() {
5174
5334
  "With --create-repo: create the repo private (the store only accepts public repos)"
5175
5335
  ).option("--ref <gitref>", "Git ref to ingest (default: the library branch or main)").option("--dry-run", "Print the plan; push nothing and call no store endpoint").action(
5176
5336
  async (lib, opts) => {
5177
- const { runLibraryPublish } = await import('../library-publish-KKQ2ULLX.js');
5337
+ const { runLibraryPublish } = await import('../library-publish-I3UWXAHI.js');
5178
5338
  await withStoreErrorHandling(() => runLibraryPublish(lib, opts));
5179
5339
  }
5180
5340
  );
5181
5341
  cmd.command("register <lib>").description("Register the library's manifest without pushing (bytes already on github)").option("--asset <ref>", "Publish only the single asset matching this ref/name").option("--ref <gitref>", "Git ref to ingest (default: the library branch or main)").option("--dry-run", "Print the plan; call no store endpoint").action(async (lib, opts) => {
5182
- const { runLibraryRegister } = await import('../library-publish-KKQ2ULLX.js');
5342
+ const { runLibraryRegister } = await import('../library-publish-I3UWXAHI.js');
5183
5343
  await withStoreErrorHandling(() => runLibraryRegister(lib, opts));
5184
5344
  });
5185
5345
  cmd.command("yank <lib>").description("Retract the library's published assets from the store").option("--asset <ref>", "Yank only the single asset matching this ref/name").action(async (lib, opts) => {
5186
- const { runLibraryYank } = await import('../library-publish-KKQ2ULLX.js');
5346
+ const { runLibraryYank } = await import('../library-publish-I3UWXAHI.js');
5187
5347
  await withStoreErrorHandling(() => runLibraryYank(lib, opts));
5188
5348
  });
5189
5349
  return cmd;
@@ -5234,9 +5394,9 @@ async function printOverallStatus(projectDir, asJson) {
5234
5394
  } catch {
5235
5395
  secretsStrategy = "unavailable";
5236
5396
  }
5237
- const resolvedProjectDir = path18.resolve(projectDir);
5238
- const hasWorkspaceConfig = existsSync(path18.join(resolvedProjectDir, "skaile.yaml"));
5239
- const hasLockFile = existsSync(path18.join(resolvedProjectDir, "skaile.lock.yaml"));
5397
+ const resolvedProjectDir = path19.resolve(projectDir);
5398
+ const hasWorkspaceConfig = existsSync(path19.join(resolvedProjectDir, "skaile.yaml"));
5399
+ const hasLockFile = existsSync(path19.join(resolvedProjectDir, "skaile.lock.yaml"));
5240
5400
  let assignments = [];
5241
5401
  if (hasWorkspaceConfig) {
5242
5402
  try {
@@ -5843,7 +6003,7 @@ function scheduleSoftDepPreview() {
5843
6003
  }
5844
6004
  async function loadAssets() {
5845
6005
  softDepPreviewCache.clear();
5846
- const { gatherAssetFeeds } = await import('../asset-feeds-PXUWCXVI.js');
6006
+ const { gatherAssetFeeds } = await import('../asset-feeds-HJFV7UPW.js');
5847
6007
  const { entries, notes } = await gatherAssetFeeds(am, am.projectDir);
5848
6008
  if (notes.length > 0) {
5849
6009
  state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
@@ -5851,7 +6011,7 @@ async function loadAssets() {
5851
6011
  const installed = new Set(am.listDeployed().map((e) => `${e.kind}:${e.name}`));
5852
6012
  let lock = null;
5853
6013
  try {
5854
- lock = readLock(path18__default.join(am.projectDir, "skaile.lock.yaml"));
6014
+ lock = readLock(path19__default.join(am.projectDir, "skaile.lock.yaml"));
5855
6015
  } catch {
5856
6016
  }
5857
6017
  const rows = buildAssetRows(
@@ -5873,7 +6033,7 @@ function rebuildSourceTree() {
5873
6033
  rebuildVisibleSources();
5874
6034
  }
5875
6035
  function sourceOrgRepo(s) {
5876
- const parts = s.path.split(path18__default.sep).filter(Boolean);
6036
+ const parts = s.path.split(path19__default.sep).filter(Boolean);
5877
6037
  if (parts.length < 2) return null;
5878
6038
  return { org: parts[parts.length - 2], repo: parts[parts.length - 1] };
5879
6039
  }
@@ -6047,13 +6207,13 @@ function reconcileCollapsedSets(rows) {
6047
6207
  async function loadSourcesAndLibraries() {
6048
6208
  try {
6049
6209
  const [{ openLibraryManager: openLibraryManager2 }, { getGlobalCacheDir: getGlobalCacheDir2, globalSkaileDir: globalSkaileDir2 }] = await Promise.all([
6050
- import('../open-library-RJGJIW5H.js'),
6210
+ import('../open-library-NKKUJLWA.js'),
6051
6211
  import('../core/index.js')
6052
6212
  ]);
6053
6213
  const { manager, library, close } = await openLibraryManager2();
6054
6214
  try {
6055
6215
  const newRoot = getGlobalCacheDir2();
6056
- const legacyRoot = path18__default.join(globalSkaileDir2(), "sources");
6216
+ const legacyRoot = path19__default.join(globalSkaileDir2(), "sources");
6057
6217
  const isSourceRow = (l) => l.path.startsWith(newRoot) || l.path.startsWith(legacyRoot);
6058
6218
  const libs = await manager.listLibraries();
6059
6219
  const defs = await library.listAssetDefs();
@@ -7013,13 +7173,13 @@ async function run(projectDir) {
7013
7173
  }
7014
7174
  function makeManageCommand() {
7015
7175
  return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
7016
- await run(path18__default.resolve(opts.projectDir));
7176
+ await run(path19__default.resolve(opts.projectDir));
7017
7177
  });
7018
7178
  }
7019
7179
  function makeMcpServerCommand() {
7020
7180
  return new Command("mcp-server").description("Start skaile workspace MCP server (stdio transport)").option("--project-dir <path>", "Project directory (default: cwd)", process.cwd()).action(async (opts) => {
7021
- const path42 = await import('path');
7022
- const projectDir = path42.default.resolve(opts.projectDir);
7181
+ const path43 = await import('path');
7182
+ const projectDir = path43.default.resolve(opts.projectDir);
7023
7183
  const { LogStore: LogStore2, StdoutSink: StdoutSink2, registerLogStore: registerLogStore2 } = await import('../core/logging.js');
7024
7184
  registerLogStore2(
7025
7185
  new LogStore2({
@@ -7061,10 +7221,10 @@ function walkFiles(root, match) {
7061
7221
  return;
7062
7222
  }
7063
7223
  for (const entry of entries) {
7064
- const full = path18__default.join(dir, entry.name);
7224
+ const full = path19__default.join(dir, entry.name);
7065
7225
  if (entry.isDirectory()) {
7066
7226
  if (SKIPPED_DIRS.has(entry.name)) continue;
7067
- if (entry.name === "cache" && path18__default.basename(dir) === ".skaile") continue;
7227
+ if (entry.name === "cache" && path19__default.basename(dir) === ".skaile") continue;
7068
7228
  visit(full);
7069
7229
  } else if (entry.isFile() && match(entry.name)) {
7070
7230
  out.push(full);
@@ -7082,14 +7242,14 @@ function applyChanges2(changes) {
7082
7242
  switch (change.type) {
7083
7243
  case "write":
7084
7244
  case "create":
7085
- mkdirSync(path18__default.dirname(change.path), { recursive: true });
7245
+ mkdirSync(path19__default.dirname(change.path), { recursive: true });
7086
7246
  writeFileSync(change.path, change.after, "utf-8");
7087
7247
  break;
7088
7248
  case "delete":
7089
7249
  rmSync(change.path, { force: true });
7090
7250
  break;
7091
7251
  case "move":
7092
- mkdirSync(path18__default.dirname(change.to), { recursive: true });
7252
+ mkdirSync(path19__default.dirname(change.to), { recursive: true });
7093
7253
  writeFileSync(change.to, change.after, "utf-8");
7094
7254
  rmSync(change.from, { force: true });
7095
7255
  break;
@@ -7182,7 +7342,7 @@ function unifiedDiff(before, after, oldLabel, newLabel, context = 3) {
7182
7342
  return `${out.join("\n")}
7183
7343
  `;
7184
7344
  }
7185
- var posix = (p6) => p6.split(path18__default.sep).join("/");
7345
+ var posix = (p6) => p6.split(path19__default.sep).join("/");
7186
7346
  function colorizeDiff(diff) {
7187
7347
  return diff.split("\n").map((line) => {
7188
7348
  if (line.startsWith("+++") || line.startsWith("---")) return S.bold(line);
@@ -7193,7 +7353,7 @@ function colorizeDiff(diff) {
7193
7353
  }).join("\n");
7194
7354
  }
7195
7355
  function renderChange(change, base) {
7196
- const rel = (p6) => posix(path18__default.relative(base, p6) || path18__default.basename(p6));
7356
+ const rel = (p6) => posix(path19__default.relative(base, p6) || path19__default.basename(p6));
7197
7357
  switch (change.type) {
7198
7358
  case "write":
7199
7359
  return unifiedDiff(
@@ -7220,7 +7380,7 @@ ${diff}`;
7220
7380
  }
7221
7381
  }
7222
7382
  function changeLabel(change, base) {
7223
- const rel = (p6) => posix(path18__default.relative(base, p6) || path18__default.basename(p6));
7383
+ const rel = (p6) => posix(path19__default.relative(base, p6) || path19__default.basename(p6));
7224
7384
  switch (change.type) {
7225
7385
  case "write":
7226
7386
  return `modify ${rel(change.path)}`;
@@ -7291,7 +7451,7 @@ function itemFromRef(raw, defaultKind, ctx) {
7291
7451
  return { kind: prefixed[1], ref: value };
7292
7452
  }
7293
7453
  if (PATH_LIKE.test(value)) return { kind: defaultKind, ref: value };
7294
- if (defaultKind === "skill" && !value.includes("/") && existsSync(path18__default.join(ctx.agentDir, "skills", value, "SKILL.md"))) {
7454
+ if (defaultKind === "skill" && !value.includes("/") && existsSync(path19__default.join(ctx.agentDir, "skills", value, "SKILL.md"))) {
7295
7455
  return { kind: "skill", ref: `./skills/${value}` };
7296
7456
  }
7297
7457
  return { kind: defaultKind, ref: `${defaultKind}:${value}` };
@@ -7427,7 +7587,7 @@ function migrateAgentYaml(source, options) {
7427
7587
  manual.push("metadata.soul: not a string; left unchanged");
7428
7588
  continue;
7429
7589
  }
7430
- if (path18__default.posix.basename(soul.replace(/\\/g, "/")).toLowerCase() === "soul.md") {
7590
+ if (path19__default.posix.basename(soul.replace(/\\/g, "/")).toLowerCase() === "soul.md") {
7431
7591
  notes.push("metadata.soul \u2192 dropped (SOUL.md is a convention file)");
7432
7592
  } else {
7433
7593
  derived.push({ kind: "persona", ref: soul });
@@ -7661,7 +7821,7 @@ function migrateSubagents(skaileYamlPath, source) {
7661
7821
  if (!isMap(agentNode)) return void 0;
7662
7822
  const subNode = agentNode.get("subagents", true);
7663
7823
  if (!isMap(subNode)) return void 0;
7664
- const dir = path18__default.dirname(skaileYamlPath);
7824
+ const dir = path19__default.dirname(skaileYamlPath);
7665
7825
  const notes = [];
7666
7826
  const manual = [];
7667
7827
  const changes = [];
@@ -7679,10 +7839,10 @@ function migrateSubagents(skaileYamlPath, source) {
7679
7839
  continue;
7680
7840
  }
7681
7841
  const id = instanceId(name);
7682
- const assetDir = path18__default.join(dir, ".skaile", "agents", id);
7842
+ const assetDir = path19__default.join(dir, ".skaile", "agents", id);
7683
7843
  if (takenIds.has(id) || existsSync(assetDir)) {
7684
7844
  manual.push(
7685
- `agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${path18__default.relative(dir, assetDir)} already exists`}; left in place`
7845
+ `agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${path19__default.relative(dir, assetDir)} already exists`}; left in place`
7686
7846
  );
7687
7847
  continue;
7688
7848
  }
@@ -7706,13 +7866,13 @@ function migrateSubagents(skaileYamlPath, source) {
7706
7866
  manifest.tools = { ...allowed ? { allowed } : {}, ...denied ? { denied } : {} };
7707
7867
  }
7708
7868
  const text = stringify(manifest, { lineWidth: 0 });
7709
- const manifestPath = path18__default.join(assetDir, "agent.yaml");
7869
+ const manifestPath = path19__default.join(assetDir, "agent.yaml");
7710
7870
  changes.push({ type: "create", path: manifestPath, after: text });
7711
7871
  assetManifests.push({ file: manifestPath, text });
7712
7872
  if (typeof spec.prompt === "string" && spec.prompt.trim() !== "") {
7713
7873
  changes.push({
7714
7874
  type: "create",
7715
- path: path18__default.join(assetDir, "SOUL.md"),
7875
+ path: path19__default.join(assetDir, "SOUL.md"),
7716
7876
  after: `${spec.prompt.replace(/\s+$/, "")}
7717
7877
  `
7718
7878
  });
@@ -7771,7 +7931,7 @@ function validateMigratedAgent(text, registry) {
7771
7931
  function collectAgentFiles(paths) {
7772
7932
  const files = /* @__PURE__ */ new Set();
7773
7933
  for (const input of paths) {
7774
- const abs = path18__default.resolve(input);
7934
+ const abs = path19__default.resolve(input);
7775
7935
  if (!existsSync(abs)) continue;
7776
7936
  if (statSync(abs).isDirectory()) {
7777
7937
  for (const f of walkFiles(abs, (b) => b === "agent.yaml" || b === "skaile.yaml"))
@@ -7788,7 +7948,7 @@ function planAgentMigration(options) {
7788
7948
  const reports = [];
7789
7949
  for (const file of collectAgentFiles(options.paths)) {
7790
7950
  const source = readText(file);
7791
- const base = path18__default.basename(file);
7951
+ const base = path19__default.basename(file);
7792
7952
  if (base === "skaile.yaml") {
7793
7953
  const result = migrateSubagents(file, source);
7794
7954
  if (!result) continue;
@@ -7796,7 +7956,7 @@ function planAgentMigration(options) {
7796
7956
  for (const asset of result.assetManifests) {
7797
7957
  const v = validateMigratedAgent(asset.text, options.registry);
7798
7958
  validation2.errors.push(
7799
- ...v.errors.map((e) => `${path18__default.basename(path18__default.dirname(asset.file))}: ${e}`)
7959
+ ...v.errors.map((e) => `${path19__default.basename(path19__default.dirname(asset.file))}: ${e}`)
7800
7960
  );
7801
7961
  validation2.warnings.push(...v.warnings);
7802
7962
  }
@@ -7824,7 +7984,7 @@ function planAgentMigration(options) {
7824
7984
  });
7825
7985
  continue;
7826
7986
  }
7827
- migration = migrateAgentYaml(source, { agentDir: path18__default.dirname(file), knownKinds });
7987
+ migration = migrateAgentYaml(source, { agentDir: path19__default.dirname(file), knownKinds });
7828
7988
  } catch (error) {
7829
7989
  reports.push({
7830
7990
  file,
@@ -7854,7 +8014,7 @@ function planAgentMigration(options) {
7854
8014
  var DEFAULT_PUBLISHER = "skaile-ai";
7855
8015
  var PRESET_DEFAULT_VERSION = "1.0.0";
7856
8016
  var FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
7857
- var posix2 = (p6) => p6.split(path18__default.sep).join("/");
8017
+ var posix2 = (p6) => p6.split(path19__default.sep).join("/");
7858
8018
  var MOVED_KINDS = { persona: "PERSONA.md", ruleset: "RULESET.md" };
7859
8019
  var KIND_MANIFEST_FILES = /* @__PURE__ */ new Set(["PERSONA.md", "RULESET.md", "SKILL.md"]);
7860
8020
  function readFrontmatterType(text) {
@@ -7876,7 +8036,14 @@ ${kept.join("\n")}
7876
8036
  ${rest}`;
7877
8037
  return { type: parsed.type, withoutType };
7878
8038
  }
7879
- function planMarkdownMoves(root, knownKinds, manual, unknownTypes) {
8039
+ function finalIdentity(kind, name) {
8040
+ try {
8041
+ return `${kind}:${slugifyAssetName(name)}`;
8042
+ } catch {
8043
+ return `${kind}:${name}`;
8044
+ }
8045
+ }
8046
+ function planMarkdownMoves(root, knownKinds, manual, unknownTypes, identities, conflicts) {
7880
8047
  const moves = [];
7881
8048
  const changes = [];
7882
8049
  const targets = /* @__PURE__ */ new Set();
@@ -7885,17 +8052,26 @@ function planMarkdownMoves(root, knownKinds, manual, unknownTypes) {
7885
8052
  if (!text.startsWith("---")) continue;
7886
8053
  const found = readFrontmatterType(text);
7887
8054
  if (!found) continue;
7888
- const base = path18__default.basename(file);
7889
- const inAgentParts = file.split(path18__default.sep).includes("_agent-parts");
8055
+ const base = path19__default.basename(file);
8056
+ const inAgentParts = file.split(path19__default.sep).includes("_agent-parts");
7890
8057
  const targetName = MOVED_KINDS[found.type];
7891
8058
  if (targetName !== void 0 && !KIND_MANIFEST_FILES.has(base)) {
7892
- const to = path18__default.join(path18__default.dirname(file), base.replace(/\.md$/i, ""), targetName);
8059
+ const to = path19__default.join(path19__default.dirname(file), base.replace(/\.md$/i, ""), targetName);
7893
8060
  if (existsSync(to) || targets.has(to)) {
7894
8061
  manual.push(
7895
- `${posix2(path18__default.relative(root, file))}: ${posix2(path18__default.relative(root, to))} already exists; not moved`
8062
+ `${posix2(path19__default.relative(root, file))}: ${posix2(path19__default.relative(root, to))} already exists; not moved`
8063
+ );
8064
+ continue;
8065
+ }
8066
+ const identity = finalIdentity(found.type, base.replace(/\.md$/i, ""));
8067
+ const earlier = identities.get(identity);
8068
+ if (earlier !== void 0) {
8069
+ conflicts.push(
8070
+ `${earlier} and ${posix2(path19__default.relative(root, file))} both become ${identity}: rename one bundle first. Nothing was changed.`
7896
8071
  );
7897
8072
  continue;
7898
8073
  }
8074
+ identities.set(identity, posix2(path19__default.relative(root, file)));
7899
8075
  targets.add(to);
7900
8076
  moves.push({ from: file, to, kind: found.type });
7901
8077
  changes.push({ type: "move", from: file, to, before: text, after: found.withoutType });
@@ -7913,13 +8089,13 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
7913
8089
  const changes = [];
7914
8090
  for (const file of walkFiles(root, (b) => b === "agent.yaml")) {
7915
8091
  const source = readText(file);
7916
- const agentDir = path18__default.dirname(file);
8092
+ const agentDir = path19__default.dirname(file);
7917
8093
  let hits = 0;
7918
8094
  const refRewrite = (_kind, ref) => {
7919
- const moved = byOldPath.get(path18__default.resolve(agentDir, ref));
8095
+ const moved = byOldPath.get(path19__default.resolve(agentDir, ref));
7920
8096
  if (moved === void 0) return ref;
7921
8097
  hits++;
7922
- const rel = posix2(path18__default.relative(agentDir, moved));
8098
+ const rel = posix2(path19__default.relative(agentDir, moved));
7923
8099
  return rel.startsWith(".") ? rel : `./${rel}`;
7924
8100
  };
7925
8101
  let output;
@@ -7936,7 +8112,7 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
7936
8112
  if (hits === 0 || output === source) continue;
7937
8113
  changes.push({ type: "write", path: file, before: source, after: output });
7938
8114
  notes.push(
7939
- `${posix2(path18__default.relative(root, file))}: persona/ruleset refs \u2192 composes items at the new paths`
8115
+ `${posix2(path19__default.relative(root, file))}: persona/ruleset refs \u2192 composes items at the new paths`
7940
8116
  );
7941
8117
  }
7942
8118
  return changes;
@@ -7960,14 +8136,14 @@ function presetText(name, description, refs, version) {
7960
8136
  }
7961
8137
  function skillDirs(dir) {
7962
8138
  try {
7963
- return readdirSync(path18__default.join(dir, "skills"), { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync(path18__default.join(dir, "skills", e.name, "SKILL.md"))).map((e) => e.name).sort();
8139
+ return readdirSync(path19__default.join(dir, "skills"), { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync(path19__default.join(dir, "skills", e.name, "SKILL.md"))).map((e) => e.name).sort();
7964
8140
  } catch {
7965
8141
  return [];
7966
8142
  }
7967
8143
  }
7968
8144
  function repoPublisher(root) {
7969
8145
  for (const name of ["skaile.manifest.yaml", "skaile.yaml"]) {
7970
- const file = path18__default.join(root, name);
8146
+ const file = path19__default.join(root, name);
7971
8147
  if (!existsSync(file)) continue;
7972
8148
  try {
7973
8149
  const parsed = parse(readText(file));
@@ -7979,15 +8155,15 @@ function repoPublisher(root) {
7979
8155
  }
7980
8156
  return DEFAULT_PUBLISHER;
7981
8157
  }
7982
- function planBundles(root, skaileYamls, publisher, notes, manual, conflicts) {
8158
+ function planBundles(root, skaileYamls, publisher, notes, manual, conflicts, identities) {
7983
8159
  const changes = [];
7984
8160
  const presets = [];
7985
8161
  const handled = /* @__PURE__ */ new Set();
7986
8162
  const claimed = /* @__PURE__ */ new Map();
7987
- const rel = (p6) => posix2(path18__default.relative(root, p6));
8163
+ const rel = (p6) => posix2(path19__default.relative(root, p6));
7988
8164
  const convert = (name, bundleFile, dir) => {
7989
- const target = path18__default.join(dir === root ? path18__default.join(dir, name) : dir, `${name}.preset.yaml`);
7990
- const origin = bundleFile ? rel(bundleFile) : `${rel(path18__default.join(dir, "skills")) || "skills"}/`;
8165
+ const target = path19__default.join(dir === root ? path19__default.join(dir, name) : dir, `${name}.preset.yaml`);
8166
+ const origin = bundleFile ? rel(bundleFile) : `${rel(path19__default.join(dir, "skills")) || "skills"}/`;
7991
8167
  const earlier = claimed.get(target);
7992
8168
  if (earlier !== void 0) {
7993
8169
  conflicts.push(
@@ -7995,6 +8171,14 @@ function planBundles(root, skaileYamls, publisher, notes, manual, conflicts) {
7995
8171
  );
7996
8172
  return;
7997
8173
  }
8174
+ const identity = finalIdentity("preset", name);
8175
+ const sameName = identities.get(identity);
8176
+ if (sameName !== void 0) {
8177
+ conflicts.push(
8178
+ `${sameName} and ${origin} both become ${identity}: rename one bundle first. Nothing was changed.`
8179
+ );
8180
+ return;
8181
+ }
7998
8182
  if (existsSync(target)) {
7999
8183
  manual.push(`${rel(target)} already exists; bundle ${name} not converted`);
8000
8184
  return;
@@ -8026,11 +8210,12 @@ function planBundles(root, skaileYamls, publisher, notes, manual, conflicts) {
8026
8210
  }
8027
8211
  if (refs.length === 0) {
8028
8212
  manual.push(
8029
- `bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(path18__default.join(dir, "skills"))}`}; no preset generated`
8213
+ `bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(path19__default.join(dir, "skills"))}`}; no preset generated`
8030
8214
  );
8031
8215
  return;
8032
8216
  }
8033
8217
  claimed.set(target, origin);
8218
+ identities.set(identity, origin);
8034
8219
  const after = presetText(name, description, refs, version);
8035
8220
  if (before !== void 0 && bundleFile) {
8036
8221
  changes.push({ type: "move", from: bundleFile, to: target, before, after });
@@ -8051,18 +8236,18 @@ function planBundles(root, skaileYamls, publisher, notes, manual, conflicts) {
8051
8236
  const assets = Array.isArray(raw.assets) ? raw.assets : [];
8052
8237
  for (const entry of assets) {
8053
8238
  if (!isRecord(entry) || entry.kind !== "bundle" || typeof entry.name !== "string") continue;
8054
- const baseDir = path18__default.dirname(file);
8055
- const entryRoot = typeof entry.root === "string" ? path18__default.join(baseDir, entry.root) : baseDir;
8239
+ const baseDir = path19__default.dirname(file);
8240
+ const entryRoot = typeof entry.root === "string" ? path19__default.join(baseDir, entry.root) : baseDir;
8056
8241
  const files = Array.isArray(entry.files) ? entry.files : [];
8057
8242
  const bundleName = files.find(
8058
8243
  (f) => typeof f === "string" && f.endsWith(".bundle.yaml")
8059
8244
  );
8060
- convert(entry.name, bundleName ? path18__default.join(entryRoot, bundleName) : void 0, entryRoot);
8245
+ convert(entry.name, bundleName ? path19__default.join(entryRoot, bundleName) : void 0, entryRoot);
8061
8246
  }
8062
8247
  }
8063
8248
  for (const bundleFile of walkFiles(root, (b) => b.endsWith(".bundle.yaml"))) {
8064
8249
  if (handled.has(bundleFile)) continue;
8065
- const base = path18__default.basename(bundleFile);
8250
+ const base = path19__default.basename(bundleFile);
8066
8251
  let name = base.replace(/\.bundle\.yaml$/, "");
8067
8252
  try {
8068
8253
  const parsed = parse(readText(bundleFile));
@@ -8071,7 +8256,7 @@ function planBundles(root, skaileYamls, publisher, notes, manual, conflicts) {
8071
8256
  } catch {
8072
8257
  }
8073
8258
  if (presets.some((p6) => p6.bundleFile === bundleFile)) continue;
8074
- convert(name, bundleFile, path18__default.dirname(bundleFile));
8259
+ convert(name, bundleFile, path19__default.dirname(bundleFile));
8075
8260
  }
8076
8261
  return changes;
8077
8262
  }
@@ -8081,8 +8266,8 @@ function planSkaileYaml(root, file, source, notes, manual) {
8081
8266
  if (doc.errors.length > 0 || !isMap(doc.contents)) return [];
8082
8267
  const map = doc.contents;
8083
8268
  const raw = doc.toJS();
8084
- const dir = path18__default.dirname(file);
8085
- const rel = (p6) => posix2(path18__default.relative(root, p6));
8269
+ const dir = path19__default.dirname(file);
8270
+ const rel = (p6) => posix2(path19__default.relative(root, p6));
8086
8271
  const changes = [];
8087
8272
  let changed = false;
8088
8273
  const deps = map.get("dependencies", true);
@@ -8099,7 +8284,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
8099
8284
  const hasPublication = PUBLICATION_KEYS.some((k) => raw[k] !== void 0);
8100
8285
  let remove = false;
8101
8286
  if (hasPublication) {
8102
- const manifestPath = path18__default.join(dir, "skaile.manifest.yaml");
8287
+ const manifestPath = path19__default.join(dir, "skaile.manifest.yaml");
8103
8288
  if (existsSync(manifestPath)) {
8104
8289
  manual.push(
8105
8290
  `${rel(file)}: publisher/version/assets left in place \u2014 ${rel(manifestPath)} already exists; merge by hand`
@@ -8156,16 +8341,24 @@ function planSkaileYaml(root, file, source, notes, manual) {
8156
8341
  return changes;
8157
8342
  }
8158
8343
  function planAssetMigration(options) {
8159
- const root = path18__default.resolve(options.root);
8344
+ const root = path19__default.resolve(options.root);
8160
8345
  const knownKinds = new Set(options.registry.getAllKinds());
8161
8346
  const notes = [];
8162
8347
  const manual = [];
8163
8348
  const conflicts = [];
8164
8349
  const unknownTypes = [];
8165
- const { moves, changes: moveChanges } = planMarkdownMoves(root, knownKinds, manual, unknownTypes);
8350
+ const identities = /* @__PURE__ */ new Map();
8351
+ const { moves, changes: moveChanges } = planMarkdownMoves(
8352
+ root,
8353
+ knownKinds,
8354
+ manual,
8355
+ unknownTypes,
8356
+ identities,
8357
+ conflicts
8358
+ );
8166
8359
  for (const move of moves) {
8167
8360
  notes.push(
8168
- `${posix2(path18__default.relative(root, move.from))} \u2192 ${posix2(path18__default.relative(root, move.to))} (${move.kind})`
8361
+ `${posix2(path19__default.relative(root, move.from))} \u2192 ${posix2(path19__default.relative(root, move.to))} (${move.kind})`
8169
8362
  );
8170
8363
  }
8171
8364
  const agentChanges = planAgentRefRewrites(root, moves, knownKinds, notes);
@@ -8177,11 +8370,19 @@ function planAssetMigration(options) {
8177
8370
  const raw = parse(source);
8178
8371
  if (isRecord(raw)) skaileYamls.push({ file, source, raw });
8179
8372
  } catch {
8180
- manual.push(`${posix2(path18__default.relative(root, file))}: invalid YAML; skipped`);
8373
+ manual.push(`${posix2(path19__default.relative(root, file))}: invalid YAML; skipped`);
8181
8374
  }
8182
8375
  }
8183
8376
  const publisher = repoPublisher(root);
8184
- const bundleChanges = planBundles(root, skaileYamls, publisher, notes, manual, conflicts);
8377
+ const bundleChanges = planBundles(
8378
+ root,
8379
+ skaileYamls,
8380
+ publisher,
8381
+ notes,
8382
+ manual,
8383
+ conflicts,
8384
+ identities
8385
+ );
8185
8386
  const skaileChanges = skaileYamls.flatMap(
8186
8387
  ({ file, source }) => planSkaileYaml(root, file, source, notes, manual)
8187
8388
  );
@@ -8266,12 +8467,12 @@ function migrateHarnessSettings(text, label = "settings.json") {
8266
8467
  }
8267
8468
  function workspaceYamlFiles(projectDir) {
8268
8469
  const files = [];
8269
- if (existsSync(path18__default.join(projectDir, SKAILE_YAML_DEFAULT))) {
8270
- files.push(path18__default.join(projectDir, SKAILE_YAML_DEFAULT));
8470
+ if (existsSync(path19__default.join(projectDir, SKAILE_YAML_DEFAULT))) {
8471
+ files.push(path19__default.join(projectDir, SKAILE_YAML_DEFAULT));
8271
8472
  }
8272
8473
  try {
8273
8474
  for (const entry of readdirSync(projectDir).sort()) {
8274
- if (entry.endsWith(SKAILE_YAML_SUFFIX)) files.push(path18__default.join(projectDir, entry));
8475
+ if (entry.endsWith(SKAILE_YAML_SUFFIX)) files.push(path19__default.join(projectDir, entry));
8275
8476
  }
8276
8477
  } catch {
8277
8478
  }
@@ -8285,7 +8486,7 @@ function planHarnessMigration(opts) {
8285
8486
  if (seen.has(file) || !existsSync(file)) return;
8286
8487
  seen.add(file);
8287
8488
  const before = readText(file);
8288
- const label = path18__default.basename(file);
8489
+ const label = path19__default.basename(file);
8289
8490
  let result;
8290
8491
  try {
8291
8492
  result = rewrite(before, label);
@@ -8308,7 +8509,7 @@ function runMigrateHarness(opts) {
8308
8509
  "--apply"
8309
8510
  );
8310
8511
  const cwd = process.cwd();
8311
- const projectDir = path18__default.resolve(opts.projectDir ?? findWorkspaceRoot(cwd) ?? cwd);
8512
+ const projectDir = path19__default.resolve(opts.projectDir ?? findWorkspaceRoot(cwd) ?? cwd);
8312
8513
  const plan = planHarnessMigration({ projectDir });
8313
8514
  for (const note of plan.notes) console.log(` ${note}`);
8314
8515
  printChanges(plan.changes, projectDir);
@@ -8468,7 +8669,7 @@ function workspaceConfigFiles(dir) {
8468
8669
  } catch {
8469
8670
  return [];
8470
8671
  }
8471
- return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) => path18__default.join(dir, name));
8672
+ return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) => path19__default.join(dir, name));
8472
8673
  }
8473
8674
  function readAgentConfigBlock(raw) {
8474
8675
  const key = AGENT_CONFIG_KEYS2.find((candidate) => raw[candidate] !== void 0);
@@ -8480,7 +8681,7 @@ function readAgentConfigBlock(raw) {
8480
8681
  return flat ? { key, profiles: { default: profiles }, flat } : { key, profiles, flat };
8481
8682
  }
8482
8683
  function planProviderMigration(options) {
8483
- const projectDir = path18__default.resolve(options.projectDir);
8684
+ const projectDir = path19__default.resolve(options.projectDir);
8484
8685
  const registryPath = options.workspace ? workspaceProviderRegistryPath(projectDir) : userProviderRegistryPath();
8485
8686
  const plan = {
8486
8687
  registryPath,
@@ -8496,7 +8697,7 @@ function planProviderMigration(options) {
8496
8697
  raw = parseDocument(readFileSync(file, "utf-8")).toJS() ?? {};
8497
8698
  } catch (error) {
8498
8699
  plan.warnings.push(
8499
- `${path18__default.basename(file)}: not valid YAML (${error instanceof Error ? error.message : String(error)}) \u2014 skipped`
8700
+ `${path19__default.basename(file)}: not valid YAML (${error instanceof Error ? error.message : String(error)}) \u2014 skipped`
8500
8701
  );
8501
8702
  continue;
8502
8703
  }
@@ -8545,7 +8746,7 @@ function planProviderMigration(options) {
8545
8746
  });
8546
8747
  if (!model) {
8547
8748
  plan.warnings.push(
8548
- `${path18__default.basename(file)}: profile '${profile}' had no model: \u2014 it now resolves against registry order. Pin it with 'model: ${providerId}/<modelId>'.`
8749
+ `${path19__default.basename(file)}: profile '${profile}' had no model: \u2014 it now resolves against registry order. Pin it with 'model: ${providerId}/<modelId>'.`
8549
8750
  );
8550
8751
  }
8551
8752
  touched = true;
@@ -8612,7 +8813,7 @@ function printPlan(plan) {
8612
8813
  for (const entry of plan.entries) {
8613
8814
  const base = entry.entry.base_url ?? S.dim("(transport-derived)");
8614
8815
  console.log(
8615
- ` ${S.label(`${path18__default.basename(entry.file)} ${entry.profile}`)} provider: ${entry.legacy.provider}, cloud: ${entry.legacy.cloud}`
8816
+ ` ${S.label(`${path19__default.basename(entry.file)} ${entry.profile}`)} provider: ${entry.legacy.provider}, cloud: ${entry.legacy.cloud}`
8616
8817
  );
8617
8818
  console.log(` \u2192 providers.yml ${S.bold(entry.providerId)} ${base}`);
8618
8819
  console.log(
@@ -8628,7 +8829,7 @@ function printPlan(plan) {
8628
8829
  console.log();
8629
8830
  }
8630
8831
  async function runMigrateProviders(opts) {
8631
- const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
8832
+ const projectDir = opts.projectDir ? path19__default.resolve(opts.projectDir) : process.cwd();
8632
8833
  const plan = planProviderMigration({ projectDir, workspace: opts.workspace });
8633
8834
  for (const warning of plan.warnings) logWarn(warning);
8634
8835
  if (plan.entries.length === 0 && Object.keys(plan.providers).length === 0) {
@@ -8732,7 +8933,7 @@ async function runMigrateAgents(paths, opts) {
8732
8933
  let failures = 0;
8733
8934
  let manualCount = 0;
8734
8935
  for (const report of plan.reports) {
8735
- const rel = path18__default.relative(base, report.file) || report.file;
8936
+ const rel = path19__default.relative(base, report.file) || report.file;
8736
8937
  for (const note of report.notes) console.log(` ${S.label(rel)} ${note}`);
8737
8938
  for (const note of report.manual) {
8738
8939
  manualCount++;
@@ -8759,7 +8960,7 @@ async function runMigrateAssets(root, opts) {
8759
8960
  const write = resolveMode(opts);
8760
8961
  const base = process.cwd();
8761
8962
  const plan = planAssetMigration({
8762
- root: path18__default.resolve(root ?? base),
8963
+ root: path19__default.resolve(root ?? base),
8763
8964
  registry: getKindRegistry()
8764
8965
  });
8765
8966
  if (plan.conflicts.length > 0) {
@@ -8771,7 +8972,7 @@ async function runMigrateAssets(root, opts) {
8771
8972
  for (const note of plan.manual) logWarn(note);
8772
8973
  for (const { file, type } of plan.unknownTypes) {
8773
8974
  logWarn(
8774
- `${path18__default.relative(base, file) || file}: frontmatter type "${type}" is not a registered asset kind (reported, not rewritten)`
8975
+ `${path19__default.relative(base, file) || file}: frontmatter type "${type}" is not a registered asset kind (reported, not rewritten)`
8775
8976
  );
8776
8977
  }
8777
8978
  printChanges(plan.changes, base);
@@ -8795,8 +8996,8 @@ function makeNpxCommand() {
8795
8996
  skills.command("add <url>").description(
8796
8997
  "Clone a repo, register it in the project's skaile.yaml sources[], and install a skill from it"
8797
8998
  ).requiredOption("--skill <name>", "Skill name to install from the repo").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", `Agent framework (${TARGET_DEFAULT_HINT})`).option("--global", "Deploy globally").action(async (url, opts) => {
8798
- const projectDir = path18__default.resolve(opts.projectDir);
8799
- const projYaml = path18__default.join(projectDir, "skaile.yaml");
8999
+ const projectDir = path19__default.resolve(opts.projectDir);
9000
+ const projYaml = path19__default.join(projectDir, "skaile.yaml");
8800
9001
  if (!existsSync(projYaml)) {
8801
9002
  logErr(`No skaile.yaml in ${projectDir} \u2014 run \`skaile init\` first.`);
8802
9003
  process.exit(1);
@@ -8809,11 +9010,11 @@ function makeNpxCommand() {
8809
9010
  }
8810
9011
  const spinner = createSpinner();
8811
9012
  const key = sourceCacheKey(url);
8812
- const clonePath = path18__default.join(getGlobalCacheDir(), key);
9013
+ const clonePath = path19__default.join(getGlobalCacheDir(), key);
8813
9014
  spinner.start(`Cloning ${url}`);
8814
9015
  try {
8815
9016
  if (!existsSync(clonePath)) {
8816
- mkdirSync(path18__default.dirname(clonePath), { recursive: true });
9017
+ mkdirSync(path19__default.dirname(clonePath), { recursive: true });
8817
9018
  execSync(`git clone ${url} ${clonePath}`, { stdio: "ignore" });
8818
9019
  }
8819
9020
  spinner.stop(`Cloned to ${key}`);
@@ -8868,7 +9069,7 @@ function makeNpxCommand() {
8868
9069
  return npx;
8869
9070
  }
8870
9071
  function resolvePublisher(clonePath, url) {
8871
- const manifestPath = path18__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
9072
+ const manifestPath = path19__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
8872
9073
  if (existsSync(manifestPath)) {
8873
9074
  try {
8874
9075
  const { manifest } = decodeSkaileManifest(readFileSync(manifestPath, "utf8"));
@@ -8881,12 +9082,12 @@ function resolvePublisher(clonePath, url) {
8881
9082
  return url.match(/github\.com[/:]([^/]+)\/[^/]+/)?.[1];
8882
9083
  }
8883
9084
  function resolveSkillName(clonePath, requested) {
8884
- const skillsDir = path18__default.join(clonePath, "skills");
8885
- if (existsSync(path18__default.join(skillsDir, requested, "SKILL.md"))) return requested;
9085
+ const skillsDir = path19__default.join(clonePath, "skills");
9086
+ if (existsSync(path19__default.join(skillsDir, requested, "SKILL.md"))) return requested;
8886
9087
  if (!existsSync(skillsDir)) return requested;
8887
9088
  for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
8888
9089
  if (!entry.isDirectory()) continue;
8889
- const md = path18__default.join(skillsDir, entry.name, "SKILL.md");
9090
+ const md = path19__default.join(skillsDir, entry.name, "SKILL.md");
8890
9091
  if (!existsSync(md)) continue;
8891
9092
  try {
8892
9093
  const { data } = parseFrontmatter(readFileSync(md, "utf8"));
@@ -8940,7 +9141,7 @@ function makeOutdatedCommand() {
8940
9141
  requireProjectConfig(opts.projectDir);
8941
9142
  const am2 = new AssetManager({
8942
9143
  registry: getKindRegistry(),
8943
- projectDir: path18__default.resolve(opts.projectDir),
9144
+ projectDir: path19__default.resolve(opts.projectDir),
8944
9145
  harness: opts.target
8945
9146
  });
8946
9147
  const entries = await am2.outdated();
@@ -8983,7 +9184,7 @@ function makePatchCommand() {
8983
9184
  cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
8984
9185
  const am2 = new AssetManager({
8985
9186
  registry: getKindRegistry(),
8986
- projectDir: path18__default.resolve(opts.projectDir)
9187
+ projectDir: path19__default.resolve(opts.projectDir)
8987
9188
  });
8988
9189
  try {
8989
9190
  const dest = await am2.patch(ref);
@@ -8997,7 +9198,7 @@ function makePatchCommand() {
8997
9198
  cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
8998
9199
  const am2 = new AssetManager({
8999
9200
  registry: getKindRegistry(),
9000
- projectDir: path18__default.resolve(opts.projectDir)
9201
+ projectDir: path19__default.resolve(opts.projectDir)
9001
9202
  });
9002
9203
  try {
9003
9204
  const patchFile = await am2.patchCommit(ref);
@@ -9011,7 +9212,7 @@ function makePatchCommand() {
9011
9212
  cmd.command("submit <ref>").description("Apply patch to repo clone and prepare for PR").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
9012
9213
  const am2 = new AssetManager({
9013
9214
  registry: getKindRegistry(),
9014
- projectDir: path18__default.resolve(opts.projectDir)
9215
+ projectDir: path19__default.resolve(opts.projectDir)
9015
9216
  });
9016
9217
  try {
9017
9218
  await am2.patchSubmit(ref);
@@ -9027,7 +9228,7 @@ function makePatchCommand() {
9027
9228
  cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
9028
9229
  const am2 = new AssetManager({
9029
9230
  registry: getKindRegistry(),
9030
- projectDir: path18__default.resolve(opts.projectDir)
9231
+ projectDir: path19__default.resolve(opts.projectDir)
9031
9232
  });
9032
9233
  am2.patchRemove(ref);
9033
9234
  logOk(`Patch removed for ${ref}`);
@@ -9046,7 +9247,7 @@ function action2(fn) {
9046
9247
  };
9047
9248
  }
9048
9249
  async function reconcileAndReport(projectDir, plugins, opts = {}) {
9049
- const { reconcilePlugins } = await import('../plugin-store-MSH6GK6T.js');
9250
+ const { reconcilePlugins } = await import('../plugin-store-ABE35NRX.js');
9050
9251
  if (plugins.length === 0) {
9051
9252
  logInfo("No plugins declared \u2014 nothing to reconcile.");
9052
9253
  return;
@@ -9061,7 +9262,7 @@ async function reconcileAndReport(projectDir, plugins, opts = {}) {
9061
9262
  }
9062
9263
  }
9063
9264
  async function verifyPluginLoads(projectDir, spec) {
9064
- const { loadPlugins } = await import('../plugin-store-MSH6GK6T.js');
9265
+ const { loadPlugins } = await import('../plugin-store-ABE35NRX.js');
9065
9266
  const { createPluginRegistry } = await import('../plugin-registry/index.js');
9066
9267
  const registry = createPluginRegistry();
9067
9268
  const result = await loadPlugins(projectDir, [spec], registry);
@@ -9073,10 +9274,10 @@ async function verifyPluginLoads(projectDir, spec) {
9073
9274
  logOk(`Loaded ${S.cmd(spec)}${contributed.length > 0 ? ` (${contributed.join(", ")})` : ""}`);
9074
9275
  }
9075
9276
  async function runInstall2(spec, opts) {
9076
- const projectDir = path18__default.resolve(opts.projectDir);
9277
+ const projectDir = path19__default.resolve(opts.projectDir);
9077
9278
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
9078
- const { specName, rollbackPluginStore } = await import('../plugin-store-MSH6GK6T.js');
9079
- const yamlPath = path18__default.join(projectDir, "skaile.yaml");
9279
+ const { specName, rollbackPluginStore } = await import('../plugin-store-ABE35NRX.js');
9280
+ const yamlPath = path19__default.join(projectDir, "skaile.yaml");
9080
9281
  if (!existsSync(yamlPath)) {
9081
9282
  throw new Error(`no skaile.yaml in ${projectDir}; run \`skaile init\` first`);
9082
9283
  }
@@ -9102,10 +9303,10 @@ async function runInstall2(spec, opts) {
9102
9303
  }
9103
9304
  }
9104
9305
  async function runRemove(name, opts) {
9105
- const projectDir = path18__default.resolve(opts.projectDir);
9306
+ const projectDir = path19__default.resolve(opts.projectDir);
9106
9307
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
9107
- const { specName } = await import('../plugin-store-MSH6GK6T.js');
9108
- const yamlPath = path18__default.join(projectDir, "skaile.yaml");
9308
+ const { specName } = await import('../plugin-store-ABE35NRX.js');
9309
+ const yamlPath = path19__default.join(projectDir, "skaile.yaml");
9109
9310
  if (!existsSync(yamlPath)) {
9110
9311
  logInfo(`No plugin matching ${S.cmd(name)}: there is no skaile.yaml in ${projectDir}.`);
9111
9312
  return;
@@ -9121,7 +9322,7 @@ async function runRemove(name, opts) {
9121
9322
  await reconcileAndReport(projectDir, editor.getPlugins());
9122
9323
  }
9123
9324
  async function runList(opts) {
9124
- const projectDir = path18__default.resolve(opts.projectDir);
9325
+ const projectDir = path19__default.resolve(opts.projectDir);
9125
9326
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
9126
9327
  const config = resolveSkWorkspaceConfig2(projectDir);
9127
9328
  const declared = config.plugins ?? [];
@@ -9136,7 +9337,7 @@ async function runList(opts) {
9136
9337
  const registry = createPluginRegistry();
9137
9338
  if (declared.length > 0) {
9138
9339
  try {
9139
- const { loadPlugins } = await import('../plugin-store-MSH6GK6T.js');
9340
+ const { loadPlugins } = await import('../plugin-store-ABE35NRX.js');
9140
9341
  const result = await loadPlugins(projectDir, declared, registry);
9141
9342
  for (const f of result.failed) logWarn(f.error);
9142
9343
  } catch (err) {
@@ -9404,8 +9605,8 @@ function redactSecrets(preset, findings) {
9404
9605
  }
9405
9606
  return { preset: next, keys };
9406
9607
  }
9407
- function placeholderKey(itemId, path42) {
9408
- return `${itemId}_${path42}`.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
9608
+ function placeholderKey(itemId, path43) {
9609
+ return `${itemId}_${path43}`.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
9409
9610
  }
9410
9611
  function setAtPath(root, segments, value) {
9411
9612
  let node = root;
@@ -9428,7 +9629,7 @@ function makePresetCommand() {
9428
9629
  cmd.command("init [name]").description("Scaffold a new .preset.yaml file").option("--dir <path>", "Output directory", process.cwd()).action(async (name, opts) => {
9429
9630
  const presetName = name ?? "my-preset";
9430
9631
  const filename = `${presetName}.preset.yaml`;
9431
- const outPath = path18__default.join(path18__default.resolve(opts.dir), filename);
9632
+ const outPath = path19__default.join(path19__default.resolve(opts.dir), filename);
9432
9633
  if (existsSync(outPath)) {
9433
9634
  logErr(`File already exists: ${outPath}`);
9434
9635
  logInfo("Choose a different name or remove the existing file.");
@@ -9461,7 +9662,7 @@ function makePresetCommand() {
9461
9662
  return cmd;
9462
9663
  }
9463
9664
  async function runPresetExport(name, opts) {
9464
- const projectDir = path18__default.resolve(opts.projectDir);
9665
+ const projectDir = path19__default.resolve(opts.projectDir);
9465
9666
  const file = loadSkWorkspaceConfig(projectDir);
9466
9667
  if (!file) {
9467
9668
  logErr(`No skaile.yaml found in ${projectDir}`);
@@ -9471,7 +9672,7 @@ async function runPresetExport(name, opts) {
9471
9672
  const presetName = name ?? file.config.name ?? "my-preset";
9472
9673
  let lock = null;
9473
9674
  try {
9474
- lock = readLock(path18__default.join(projectDir, "skaile.lock.yaml"));
9675
+ lock = readLock(path19__default.join(projectDir, "skaile.lock.yaml"));
9475
9676
  } catch {
9476
9677
  lock = null;
9477
9678
  }
@@ -9512,7 +9713,7 @@ async function runPresetExport(name, opts) {
9512
9713
  const contents = header ? `${header}
9513
9714
  ${body}` : body;
9514
9715
  if (opts.out && opts.dir !== process.cwd()) logWarn("--dir is ignored when --out is set.");
9515
- const outPath = opts.out ? path18__default.resolve(opts.out) : path18__default.join(path18__default.resolve(opts.dir), `${presetName}.preset.yaml`);
9716
+ const outPath = opts.out ? path19__default.resolve(opts.out) : path19__default.join(path19__default.resolve(opts.dir), `${presetName}.preset.yaml`);
9516
9717
  if (existsSync(outPath) && !opts.force) {
9517
9718
  logErr(`File already exists: ${outPath}`);
9518
9719
  logInfo("Pass --force to overwrite, or choose a different --out/--dir.");
@@ -9524,7 +9725,7 @@ ${body}` : body;
9524
9725
  logErr(`Failed to write ${outPath}: ${e.message}`);
9525
9726
  process.exit(1);
9526
9727
  }
9527
- logOk(`Exported ${S.brand(path18__default.basename(outPath))}`);
9728
+ logOk(`Exported ${S.brand(path19__default.basename(outPath))}`);
9528
9729
  logInfo(`Path: ${outPath}`);
9529
9730
  if (unresolved.length > 0) {
9530
9731
  console.error(S.err("This file is NOT safe to share."));
@@ -9565,13 +9766,13 @@ function collectInput(value, acc) {
9565
9766
  return acc;
9566
9767
  }
9567
9768
  async function runPresetApply(filePath, opts) {
9568
- const projectDir = path18__default.resolve(opts.projectDir);
9769
+ const projectDir = path19__default.resolve(opts.projectDir);
9569
9770
  const file = loadSkWorkspaceConfig(projectDir);
9570
9771
  if (!file) {
9571
9772
  logErr("No skaile.yaml \u2014 run `skaile init` first");
9572
9773
  process.exit(1);
9573
9774
  }
9574
- const resolved = path18__default.resolve(filePath);
9775
+ const resolved = path19__default.resolve(filePath);
9575
9776
  if (!existsSync(resolved)) {
9576
9777
  logErr(`File not found: ${resolved}`);
9577
9778
  process.exit(1);
@@ -9789,7 +9990,7 @@ async function reportNestedPresetRefs(preset) {
9789
9990
  }
9790
9991
  async function checkPresetCycles(preset, resolved) {
9791
9992
  const { detectCycles } = await import('../discovery/index.js');
9792
- const presetRef = path18__default.basename(resolved, ".preset.yaml");
9993
+ const presetRef = path19__default.basename(resolved, ".preset.yaml");
9793
9994
  const edges = [];
9794
9995
  for (const item of preset.items) {
9795
9996
  if (item.ref) {
@@ -9841,7 +10042,7 @@ function printPresetSummary(preset, placeholderCount, hasWarnings) {
9841
10042
  }
9842
10043
  }
9843
10044
  async function runPresetValidate(filePath) {
9844
- const resolved = path18__default.resolve(filePath);
10045
+ const resolved = path19__default.resolve(filePath);
9845
10046
  const preset = await loadPresetForValidation(resolved);
9846
10047
  await reportNestedPresetRefs(preset);
9847
10048
  await checkPresetCycles(preset, resolved);
@@ -9894,7 +10095,7 @@ function resolveNamedAgent(projectDir, arg) {
9894
10095
  logErr(message);
9895
10096
  process.exit(1);
9896
10097
  };
9897
- const asPath = path18__default.resolve(projectDir, arg);
10098
+ const asPath = path19__default.resolve(projectDir, arg);
9898
10099
  const isPath = arg.includes("/") || arg.includes("\\");
9899
10100
  const viaRef = (ref) => {
9900
10101
  try {
@@ -9919,7 +10120,7 @@ function resolveNamedAgent(projectDir, arg) {
9919
10120
  if (!(err instanceof AgentRefResolutionError)) throw err;
9920
10121
  if (err.code === "ambiguous") return fail(err.message);
9921
10122
  }
9922
- if (existsSync(path18__default.join(asPath, "agent.yaml"))) return asPath;
10123
+ if (existsSync(path19__default.join(asPath, "agent.yaml"))) return asPath;
9923
10124
  const known = Object.keys(instances);
9924
10125
  return fail(
9925
10126
  `No agent "${arg}" found. Give an agent name, an agent: ref or a path` + (known.length > 0 ? ` (agent instances of this project: ${known.join(", ")})` : "") + "."
@@ -9930,7 +10131,7 @@ function makeRebuildCommand() {
9930
10131
  "[agent]",
9931
10132
  "Agent name, agent: ref, instance id or path (defaults to the project agent)"
9932
10133
  ).option("--project-dir <dir>", "Project directory", process.cwd()).action(async (agentArg, opts) => {
9933
- const projectDir = path18__default.resolve(opts.projectDir);
10134
+ const projectDir = path19__default.resolve(opts.projectDir);
9934
10135
  requireProjectConfig(projectDir, { allowMissing: true });
9935
10136
  let agentDir;
9936
10137
  if (agentArg) {
@@ -9988,9 +10189,9 @@ function makeRebuildCommand() {
9988
10189
  }
9989
10190
  function resolveSingleShotAgentDir(projectDir, agentDefinition) {
9990
10191
  if (!agentDefinition) return resolveAgentDir(projectDir);
9991
- const asPath = agentDefinition.endsWith("agent.yaml") ? path18__default.dirname(path18__default.resolve(projectDir, agentDefinition)) : agentDefinition;
10192
+ const asPath = agentDefinition.endsWith("agent.yaml") ? path19__default.dirname(path19__default.resolve(projectDir, agentDefinition)) : agentDefinition;
9992
10193
  const dir = resolveAgentDefinitionDir(projectDir, asPath);
9993
- if (!dir || !fs8__default.existsSync(path18__default.join(dir, "agent.yaml"))) {
10194
+ if (!dir || !fs8__default.existsSync(path19__default.join(dir, "agent.yaml"))) {
9994
10195
  throw new Error(
9995
10196
  `--agent-definition "${agentDefinition}" does not resolve to an agent directory with agent.yaml${dir ? ` (looked in ${dir})` : ""}`
9996
10197
  );
@@ -10049,7 +10250,7 @@ async function printCompositionDryRun(projectDir, agentDir, harness, model, inst
10049
10250
  async function findSkillFile(projectDir, skill) {
10050
10251
  const name = skill.trim().replace(/^skill:/, "").replace(/^@[^/]+\//, "").replace(/#.*$/, "");
10051
10252
  for (const target of SUPPORTED_HARNESSES) {
10052
- const file = path18__default.join(deployedDir("skill", name, target, false, projectDir), "SKILL.md");
10253
+ const file = path19__default.join(deployedDir("skill", name, target, false, projectDir), "SKILL.md");
10053
10254
  if (fs8__default.existsSync(file)) return file;
10054
10255
  }
10055
10256
  const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
@@ -10065,6 +10266,14 @@ async function printSkillDryRun(projectDir, skill) {
10065
10266
  return false;
10066
10267
  }
10067
10268
  const content = fs8__default.readFileSync(file, "utf-8");
10269
+ const prerequisiteErrors = checkAssetFile(file, "skill", getKindRegistry()).filter(
10270
+ (f) => f.text.startsWith("metadata.prerequisites")
10271
+ );
10272
+ if (prerequisiteErrors.length > 0) {
10273
+ for (const f of prerequisiteErrors) logErr(`${file} [${f.tag}] - ${f.text}`);
10274
+ logErr(`Fix the skill's metadata.prerequisites (see \`skaile validate\`), then run it again.`);
10275
+ return false;
10276
+ }
10068
10277
  const { data } = parseFrontmatter(content);
10069
10278
  const meta = data.metadata ?? {};
10070
10279
  console.log(` ${S.label("Skill:")} ${S.heading(String(data.name ?? skill))}`);
@@ -10172,8 +10381,9 @@ function makeRunCommand() {
10172
10381
  "--instance <id>",
10173
10382
  "Run the skaile.yaml `agents:` instance <id> (`default` is the primary `agent:`) with its overrides; single-shot prompts only"
10174
10383
  ).option("--skill <name>", "Skill name (for single-shot mode)").action(async (positional, opts) => {
10175
- const projectDir = path18__default.resolve(opts.projectDir);
10384
+ const projectDir = path19__default.resolve(opts.projectDir);
10176
10385
  await loadDeclaredPlugins(projectDir);
10386
+ await reportProjectConfig(projectDir, { harness: false });
10177
10387
  const cliHarness = foldDriverFlag(opts).harness;
10178
10388
  const dryRun = opts.dryRun ?? false;
10179
10389
  const agentDefinition = opts.agentDefinition?.trim() || void 0;
@@ -10342,7 +10552,7 @@ function makeResumeCommand() {
10342
10552
  "--session <run-id>",
10343
10553
  "Target session by runId (full ID or the prefix `session list` prints)"
10344
10554
  ).option("--dry-run", "Print plan without executing").action(async (opts) => {
10345
- const projectDir = path18__default.resolve(opts.projectDir);
10555
+ const projectDir = path19__default.resolve(opts.projectDir);
10346
10556
  let sessionId = opts.session;
10347
10557
  const dryRun = opts.dryRun ?? false;
10348
10558
  if (sessionId) {
@@ -10383,7 +10593,7 @@ function makeResumeCommand() {
10383
10593
  }
10384
10594
  function makeStatusCommand() {
10385
10595
  return new Command("status").description("Show current session state").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
10386
- const projectDir = path18__default.resolve(opts.projectDir);
10596
+ const projectDir = path19__default.resolve(opts.projectDir);
10387
10597
  const session = await loadSession(projectDir);
10388
10598
  if (!session) {
10389
10599
  logInfo("No active session.");
@@ -10409,7 +10619,7 @@ function makeStatusCommand() {
10409
10619
  }
10410
10620
  function makeClearCommand() {
10411
10621
  return new Command("clear").description("Unset current session pointer").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
10412
- const projectDir = path18__default.resolve(opts.projectDir);
10622
+ const projectDir = path19__default.resolve(opts.projectDir);
10413
10623
  await clearSession(projectDir);
10414
10624
  logOk("Session cleared.");
10415
10625
  });
@@ -10421,8 +10631,8 @@ function makeReplCommand() {
10421
10631
  ).action(async (opts) => {
10422
10632
  const { findWorkspaceRoot: findWorkspaceRoot2 } = await import('../core/index.js');
10423
10633
  const { startRepl } = await import('../tui/index.js');
10424
- const os2 = await import('os');
10425
- const userCwd = path18__default.resolve(opts.projectDir ?? process.cwd());
10634
+ const os3 = await import('os');
10635
+ const userCwd = path19__default.resolve(opts.projectDir ?? process.cwd());
10426
10636
  const workspaceRoot = findWorkspaceRoot2(userCwd);
10427
10637
  const instanceId2 = opts.instance?.trim() || void 0;
10428
10638
  let projectDir;
@@ -10451,12 +10661,12 @@ function makeReplCommand() {
10451
10661
  p4.cancel("Cancelled.");
10452
10662
  process.exit(0);
10453
10663
  }
10454
- const tmpDir = fs8__default.mkdtempSync(path18__default.join(os2.tmpdir(), "skaile-repl-"));
10664
+ const tmpDir = fs8__default.mkdtempSync(path19__default.join(os3.tmpdir(), "skaile-repl-"));
10455
10665
  projectDir = tmpDir;
10456
10666
  agentCwd = userCwd;
10457
10667
  logOk(`Temporary workspace: ${S.cmd(tmpDir)}`);
10458
10668
  if (!harnessOverride) {
10459
- const claudeDir = path18__default.join(os2.homedir(), ".claude");
10669
+ const claudeDir = path19__default.join(os3.homedir(), ".claude");
10460
10670
  if (fs8__default.existsSync(claudeDir)) {
10461
10671
  harnessOverride = "claude-sdk";
10462
10672
  logInfo(`Detected ${S.cmd("~/.claude")} \u2192 using ${S.cmd("claude-sdk")} harness`);
@@ -10468,6 +10678,7 @@ function makeReplCommand() {
10468
10678
  console.log();
10469
10679
  }
10470
10680
  await loadDeclaredPlugins(projectDir);
10681
+ await reportProjectConfig(projectDir, { harness: false });
10471
10682
  const effective = await resolveSettings(projectDir, {
10472
10683
  harness: harnessOverride,
10473
10684
  model: opts.model
@@ -10618,7 +10829,7 @@ function makeServeCommand() {
10618
10829
  }
10619
10830
  const providers = parseProviderIds(opts.providers);
10620
10831
  const modelEndpoint = parseModelEndpointFlag(opts.modelEndpoint);
10621
- const { checkHarnessSdk, checkModelEndpointPeer, checkServeModel } = await import('../serve-preflight-L4POEHNQ.js');
10832
+ const { checkHarnessSdk, checkModelEndpointPeer, checkServeModel } = await import('../serve-preflight-FLTIBTEX.js');
10622
10833
  const harnessProblem = managedCodex ? null : await checkHarnessSdk(opts.projectDir, opts.harness);
10623
10834
  if (harnessProblem) {
10624
10835
  logErr(harnessProblem);
@@ -10679,12 +10890,12 @@ function makeServeCommand() {
10679
10890
  );
10680
10891
  }
10681
10892
  async function ensurePluginsLoadedForServe(projectDir) {
10682
- const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-DE53KG3E.js');
10893
+ const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-JNMK3FC2.js');
10683
10894
  try {
10684
10895
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
10685
10896
  const config = resolveSkWorkspaceConfig2(projectDir);
10686
10897
  if (!config.plugins || config.plugins.length === 0) return;
10687
- const { ensurePluginsLoaded } = await import('../plugin-store-MSH6GK6T.js');
10898
+ const { ensurePluginsLoaded } = await import('../plugin-store-ABE35NRX.js');
10688
10899
  const { pluginRegistry } = await import('../plugin-registry/index.js');
10689
10900
  const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
10690
10901
  if (result.loaded.length > 0) {
@@ -10698,14 +10909,14 @@ async function ensurePluginsLoadedForServe(projectDir) {
10698
10909
  }
10699
10910
  }
10700
10911
  async function runCompileTest(opts) {
10701
- const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-DE53KG3E.js');
10912
+ const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-JNMK3FC2.js');
10702
10913
  const { tmpdir } = await import('os');
10703
10914
  const { dirname: dirname3, join: join6, resolve: resolve4 } = await import('path');
10704
10915
  const { fileURLToPath: fileURLToPath2 } = await import('url');
10705
10916
  const { unlinkSync, existsSync: existsSync22 } = await import('fs');
10706
10917
  const { spawn } = await import('child_process');
10707
10918
  const { portableSpawnSync: portableSpawnSync2 } = await import('../core/index.js');
10708
- const { MONOREPO_ROOT } = await import('../paths-QAV4C3KX.js');
10919
+ const { MONOREPO_ROOT } = await import('../paths-UKWE35XS.js');
10709
10920
  if (MONOREPO_ROOT === null) {
10710
10921
  logErr2("--compile-test is only available inside the skaile-dev workspace.");
10711
10922
  logInfo2("Run it from a checkout of skaile-ai/skaile-dev (the monorepo shell).");
@@ -10898,6 +11109,15 @@ function localQuery(dbPath, q) {
10898
11109
  db.close();
10899
11110
  }
10900
11111
  }
11112
+ function localSessionExists(dbPath, sessionId) {
11113
+ const db = openSqlite(dbPath, { readonly: true });
11114
+ try {
11115
+ db.exec("PRAGMA query_only=1;");
11116
+ return db.prepare("SELECT 1 AS found FROM log_entries WHERE session_id = $sid LIMIT 1").get({ $sid: sessionId }) != null;
11117
+ } finally {
11118
+ db.close();
11119
+ }
11120
+ }
10901
11121
  function buildSelect(q) {
10902
11122
  const where = ["session_id = $sid"];
10903
11123
  const params = { $sid: q.sessionId };
@@ -11188,7 +11408,7 @@ function resolveMode2(opts) {
11188
11408
  if (opts.forceLocal && opts.forceRemote) {
11189
11409
  throw new Error("Cannot use both --local and --remote");
11190
11410
  }
11191
- const startDir = path18__default.resolve(opts.projectDir ?? process.cwd());
11411
+ const startDir = path19__default.resolve(opts.projectDir ?? process.cwd());
11192
11412
  const localDb = findLogsDb(startDir);
11193
11413
  if (opts.forceLocal) {
11194
11414
  if (!localDb) {
@@ -11221,14 +11441,14 @@ function resolveMode2(opts) {
11221
11441
  function findLogsDb(startDir) {
11222
11442
  let dir = startDir;
11223
11443
  for (let i = 0; i < MAX_WALK_LEVELS; i++) {
11224
- const candidate = path18__default.join(dir, ".skaile", "logs.db");
11444
+ const candidate = path19__default.join(dir, ".skaile", "logs.db");
11225
11445
  if (existsSync(candidate)) {
11226
11446
  try {
11227
11447
  if (statSync(candidate).isFile()) return candidate;
11228
11448
  } catch {
11229
11449
  }
11230
11450
  }
11231
- const parent = path18__default.dirname(dir);
11451
+ const parent = path19__default.dirname(dir);
11232
11452
  if (parent === dir) return void 0;
11233
11453
  dir = parent;
11234
11454
  }
@@ -11327,6 +11547,9 @@ function buildLogQuery(opts) {
11327
11547
  async function fetchEntries(sessionId, opts, resolved, query) {
11328
11548
  if (resolved.mode === "local") {
11329
11549
  const result2 = localQuery(resolved.dbPath, { ...query, sessionId });
11550
+ if (result2.entries.length === 0 && !localSessionExists(resolved.dbPath, sessionId)) {
11551
+ throw new Error(`No session ${sessionId} in this project's log database.`);
11552
+ }
11330
11553
  return { entries: result2.entries, nextCursor: result2.nextCursor };
11331
11554
  }
11332
11555
  if (!opts.projectId) {
@@ -11418,7 +11641,7 @@ async function requireSession(projectDir, idOrPrefix) {
11418
11641
  function makeSessionCommand() {
11419
11642
  const cmd = new Command("session").description("Manage sessions");
11420
11643
  cmd.command("list").description("List all sessions for a project").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
11421
- const projectDir = path18__default.resolve(opts.projectDir);
11644
+ const projectDir = path19__default.resolve(opts.projectDir);
11422
11645
  const sessions = await listSessions(projectDir);
11423
11646
  const current = await loadSession(projectDir);
11424
11647
  if (sessions.length === 0) {
@@ -11446,18 +11669,18 @@ function makeSessionCommand() {
11446
11669
  console.log();
11447
11670
  });
11448
11671
  cmd.command("show <run-id>").description("Show a specific session (full run ID or the prefix `session list` prints)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (idOrPrefix, opts) => {
11449
- const projectDir = path18__default.resolve(opts.projectDir);
11672
+ const projectDir = path19__default.resolve(opts.projectDir);
11450
11673
  const { session } = await requireSession(projectDir, idOrPrefix);
11451
11674
  console.log(JSON.stringify(session, null, 2));
11452
11675
  });
11453
11676
  cmd.command("switch <run-id>").description("Switch the current session (full run ID or the prefix `session list` prints)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (idOrPrefix, opts) => {
11454
- const projectDir = path18__default.resolve(opts.projectDir);
11677
+ const projectDir = path19__default.resolve(opts.projectDir);
11455
11678
  const { runId } = await requireSession(projectDir, idOrPrefix);
11456
11679
  await setCurrentSession(projectDir, runId);
11457
11680
  logOk(`Switched to session: ${S.dim(runId.slice(0, 8))}`);
11458
11681
  });
11459
11682
  cmd.command("delete <run-id>").description("Delete a session (full run ID or the prefix `session list` prints)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (idOrPrefix, opts) => {
11460
- const projectDir = path18__default.resolve(opts.projectDir);
11683
+ const projectDir = path19__default.resolve(opts.projectDir);
11461
11684
  const { runId } = await requireSession(projectDir, idOrPrefix);
11462
11685
  await deleteSession(projectDir, runId);
11463
11686
  logOk(`Deleted session: ${S.dim(runId.slice(0, 8))}`);
@@ -11534,7 +11757,7 @@ function makeShowCommand() {
11534
11757
  requireProjectConfig(opts.projectDir, { allowMissing: true });
11535
11758
  const am2 = new AssetManager({
11536
11759
  registry: getKindRegistry(),
11537
- projectDir: path18__default.resolve(opts.projectDir),
11760
+ projectDir: path19__default.resolve(opts.projectDir),
11538
11761
  harness: opts.target
11539
11762
  });
11540
11763
  if (!kind) {
@@ -11562,7 +11785,7 @@ function searchCuratedManifests(query) {
11562
11785
  const slug = file.slice(0, -".yaml".length);
11563
11786
  let manifest;
11564
11787
  try {
11565
- manifest = decodeSkaileManifest(readFileSync(path18.join(dir, file), "utf-8")).manifest;
11788
+ manifest = decodeSkaileManifest(readFileSync(path19.join(dir, file), "utf-8")).manifest;
11566
11789
  } catch {
11567
11790
  continue;
11568
11791
  }
@@ -11582,6 +11805,13 @@ async function fetchIdentity() {
11582
11805
  const jwt = await getStoreToken();
11583
11806
  return storeFetch({ ...getStoreConfig(), jwt }, "/api/v1/me");
11584
11807
  }
11808
+ function storeRefProblem(ref, err) {
11809
+ const message = err instanceof Error ? err.message : String(err);
11810
+ const plain = message.replace(/ Run the `migrate-skaile-manifest`.*$/, "");
11811
+ if (!plain.startsWith("publisher required")) return message;
11812
+ const name = /^(?:[^:@/#\s]+:)?([^@/#\s]+)/.exec(ref.trim())?.[1];
11813
+ return name ? `${plain} Find the publisher with \`skaile store search ${name}\`.` : plain;
11814
+ }
11585
11815
  async function storeNotFoundMessage(remote, ref) {
11586
11816
  const parsed = parseAssetRef(ref);
11587
11817
  let versions = [];
@@ -11636,7 +11866,7 @@ function makeStoreCommand() {
11636
11866
  });
11637
11867
  store.command("mode <auto|local|remote>").description("Set the catalog resolution mode (not yet wired)").action((_mode) => {
11638
11868
  logErr(
11639
- `\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${path18__default.join(globalSkaileDir(), "store", "config.yaml")}.`
11869
+ `\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${path19__default.join(globalSkaileDir(), "store", "config.yaml")}.`
11640
11870
  );
11641
11871
  process.exit(2);
11642
11872
  });
@@ -11644,9 +11874,9 @@ function makeStoreCommand() {
11644
11874
  "--all",
11645
11875
  `List every match (default: ${STORE_ROW_LIMIT} rows, only what \`skaile add\` can install)`
11646
11876
  ).option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (query, opts) => {
11647
- const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-RJGJIW5H.js');
11648
- const { getKnownKinds: getKnownKinds2 } = await import('../open-registry-3QS3J7KO.js');
11649
- const projectDir = path18__default.resolve(opts.projectDir);
11877
+ const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-NKKUJLWA.js');
11878
+ const { getKnownKinds: getKnownKinds2 } = await import('../open-registry-BYAXSHUI.js');
11879
+ const projectDir = path19__default.resolve(opts.projectDir);
11650
11880
  if (opts.kind && !getKnownKinds2().has(opts.kind)) {
11651
11881
  logErr(
11652
11882
  `Unknown kind "${opts.kind}". Valid kinds: ${[...getKnownKinds2()].sort().join(", ")}`
@@ -11703,16 +11933,16 @@ function makeStoreCommand() {
11703
11933
  }
11704
11934
  });
11705
11935
  store.command("show <ref>").description("Show a store asset's details + provenance (source, files, integrity)").option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (ref, opts) => {
11706
- const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-RJGJIW5H.js');
11707
- const { supportsInstallManifest: supportsInstallManifest2 } = await import('../project-HZW2MZPA.js');
11936
+ const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-NKKUJLWA.js');
11937
+ const { supportsInstallManifest: supportsInstallManifest2 } = await import('../project-BIPK47JK.js');
11708
11938
  try {
11709
11939
  parseAssetRef(ref);
11710
11940
  } catch (e) {
11711
- logErr(`Invalid asset ref "${ref}": ${e instanceof Error ? e.message : String(e)}`);
11941
+ logErr(`Invalid asset ref "${ref}": ${storeRefProblem(ref, e)}`);
11712
11942
  process.exit(1);
11713
11943
  }
11714
11944
  try {
11715
- const remote = await openCatalogSource2({ projectDir: path18__default.resolve(opts.projectDir) });
11945
+ const remote = await openCatalogSource2({ projectDir: path19__default.resolve(opts.projectDir) });
11716
11946
  const asset = await remote.resolve(ref);
11717
11947
  if (!asset) {
11718
11948
  logErr(await storeNotFoundMessage(remote, ref));
@@ -11723,7 +11953,7 @@ function makeStoreCommand() {
11723
11953
  const manifestFailure = {};
11724
11954
  if (supportsInstallManifest2(remote)) {
11725
11955
  manifest = await remote.getInstallManifest(canonical).catch(async (err) => {
11726
- manifestFailure.text = await describeStoreFailure(err, path18__default.resolve(opts.projectDir));
11956
+ manifestFailure.text = await describeStoreFailure(err, path19__default.resolve(opts.projectDir));
11727
11957
  return null;
11728
11958
  });
11729
11959
  }
@@ -11771,9 +12001,14 @@ function makeStoreCommand() {
11771
12001
  }
11772
12002
  console.log();
11773
12003
  const notInstallable = storeNotInstallableReason(asset);
11774
- console.log(
11775
- notInstallable ? ` ${S.dim(`Not installable: ${notInstallable}`)}` : ` ${S.dim(`Install: skaile add ${canonical}`)}`
11776
- );
12004
+ const notRunnable = !notInstallable && asset.kind === "mcp-server" && manifest ? await mcpNotRunnableHere(manifest, asset.name) : void 0;
12005
+ if (notInstallable) console.log(` ${S.dim(`Not installable: ${notInstallable}`)}`);
12006
+ else if (notRunnable) {
12007
+ console.log(` ${S.dim(`Not runnable here: ${notRunnable}`)}`);
12008
+ console.log(
12009
+ ` ${S.dim(`skaile add ${canonical} still records it in the lock, but writes no .mcp.json entry.`)}`
12010
+ );
12011
+ } else console.log(` ${S.dim(`Install: skaile add ${canonical}`)}`);
11777
12012
  console.log();
11778
12013
  } catch (e) {
11779
12014
  if (e instanceof LocalCatalogDisabledError2) {
@@ -11782,7 +12017,7 @@ function makeStoreCommand() {
11782
12017
  );
11783
12018
  } else {
11784
12019
  logErr(
11785
- `Store show failed: ${await describeStoreFailure(e, path18__default.resolve(opts.projectDir))}`
12020
+ `Store show failed: ${await describeStoreFailure(e, path19__default.resolve(opts.projectDir))}`
11786
12021
  );
11787
12022
  }
11788
12023
  process.exit(1);
@@ -11856,7 +12091,7 @@ function makeTreeCommand() {
11856
12091
  requireProjectConfig(opts.projectDir);
11857
12092
  const am2 = new AssetManager({
11858
12093
  registry: getKindRegistry(),
11859
- projectDir: path18__default.resolve(opts.projectDir)
12094
+ projectDir: path19__default.resolve(opts.projectDir)
11860
12095
  });
11861
12096
  const root = await am2.tree();
11862
12097
  if (root.children.length === 0) {
@@ -11882,9 +12117,12 @@ function makeUpdateCommand() {
11882
12117
  return new Command("update").description("Refresh the Catalog cache and re-deploy outdated assets in the current project").argument(
11883
12118
  "[name]",
11884
12119
  "Update only this declared asset (kind:@publisher/name, kind:name or name); exits 1 when none matches"
11885
- ).option("--project-dir <path>", "Project directory", process.cwd()).option("--no-catalog", "Skip refreshing the catalog cache").option("--catalog-only", "Refresh the catalog cache only; do not re-deploy assets").option("--no-sync", "Skip syncing sources from upstream before re-deploying").option("-y, --yes", "Sync sources without the confirmation prompt").action(
12120
+ ).option("--project-dir <path>", "Project directory", process.cwd()).option("--no-catalog", "Skip refreshing the catalog cache").option("--catalog-only", "Refresh the catalog cache only; do not re-deploy assets").option("--no-sync", "Skip syncing sources from upstream before re-deploying").option("-y, --yes", "Sync sources without the confirmation prompt").option(
12121
+ "--force",
12122
+ "Delete files the new content does not ship, and overwrite hand-edited agent files"
12123
+ ).action(
11886
12124
  async (name, opts) => {
11887
- const projectDir = path18__default.resolve(opts.projectDir);
12125
+ const projectDir = path19__default.resolve(opts.projectDir);
11888
12126
  if (!opts.catalogOnly) requireProjectConfig(projectDir);
11889
12127
  const am2 = new AssetManager({
11890
12128
  registry: getKindRegistry(),
@@ -11904,7 +12142,7 @@ function makeUpdateCommand() {
11904
12142
  const catalogSpinner = createSpinner();
11905
12143
  catalogSpinner.start("Refreshing catalog cache");
11906
12144
  try {
11907
- const remote = await openCatalogSource({ projectDir: path18__default.resolve(opts.projectDir) });
12145
+ const remote = await openCatalogSource({ projectDir: path19__default.resolve(opts.projectDir) });
11908
12146
  const result2 = await remote.refresh({ timeoutMs: CATALOG_REFRESH_TIMEOUT_MS });
11909
12147
  catalogSpinner.stop(
11910
12148
  `Catalog refreshed: ${S.heading(String(result2.assetsCached))} assets cached`
@@ -11945,7 +12183,7 @@ function makeUpdateCommand() {
11945
12183
  spinner.start("Re-deploying assets");
11946
12184
  let result;
11947
12185
  try {
11948
- result = await am2.install({ moveLibraries: true });
12186
+ result = await am2.install({ moveLibraries: true, force: opts.force });
11949
12187
  } catch (err) {
11950
12188
  spinner.stop("Failed");
11951
12189
  logErr(String(err));
@@ -12039,13 +12277,13 @@ async function resolveUpdateTarget(am2, name) {
12039
12277
  async function needsCatalog(am2, projectDir) {
12040
12278
  let lock = null;
12041
12279
  try {
12042
- lock = readLock(path18__default.join(projectDir, "skaile.lock.yaml"));
12280
+ lock = readLock(path19__default.join(projectDir, "skaile.lock.yaml"));
12043
12281
  } catch {
12044
12282
  lock = null;
12045
12283
  }
12046
12284
  let declaredUrls = /* @__PURE__ */ new Set();
12047
12285
  try {
12048
- const yamlPath = path18__default.join(projectDir, "skaile.yaml");
12286
+ const yamlPath = path19__default.join(projectDir, "skaile.yaml");
12049
12287
  declaredUrls = new Set(
12050
12288
  WorkspaceYamlEditor.load(yamlPath).getSources().map((s) => normalizeRepoUrl(s.url))
12051
12289
  );
@@ -12081,7 +12319,7 @@ function readText2(file) {
12081
12319
  }
12082
12320
  }
12083
12321
  async function updateOne(am2, projectDir, target) {
12084
- const lockPath = path18__default.join(projectDir, "skaile.lock.yaml");
12322
+ const lockPath = path19__default.join(projectDir, "skaile.lock.yaml");
12085
12323
  const before = readText2(lockPath);
12086
12324
  const spinner = createSpinner();
12087
12325
  spinner.start(`Updating ${target.ref}`);
@@ -12277,7 +12515,7 @@ function makeWhyCommand() {
12277
12515
  requireProjectConfig(opts.projectDir);
12278
12516
  const am2 = new AssetManager({
12279
12517
  registry: getKindRegistry(),
12280
- projectDir: path18__default.resolve(opts.projectDir)
12518
+ projectDir: path19__default.resolve(opts.projectDir)
12281
12519
  });
12282
12520
  const chain = await am2.why(ref);
12283
12521
  if (chain.length === 0) {
@@ -12349,7 +12587,7 @@ function isIndexBusyError(err) {
12349
12587
  var _defaultFormatHelp = Help.prototype.formatHelp;
12350
12588
  var pkg = JSON.parse(
12351
12589
  readFileSync(
12352
- path18__default.resolve(path18__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
12590
+ path19__default.resolve(path19__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
12353
12591
  "utf-8"
12354
12592
  )
12355
12593
  );
@@ -12360,7 +12598,7 @@ for (const key of [
12360
12598
  "SKAILE_CACHE_DIR"
12361
12599
  ]) {
12362
12600
  const value = process.env[key];
12363
- if (value) process.env[key] = path18__default.resolve(value);
12601
+ if (value) process.env[key] = path19__default.resolve(value);
12364
12602
  }
12365
12603
  var program = new Command("skaile").description("AI asset manager").version(pkg.version, "-v, --version", "Show the skaile CLI version").enablePositionalOptions().configureHelp({
12366
12604
  formatHelp(cmd, helper) {
@@ -12375,6 +12613,7 @@ Project:
12375
12613
  clean [--all] [--dry-run] Remove skaile-managed assets
12376
12614
  setup Interactive provider setup wizard
12377
12615
  config show|get|set Personal settings
12616
+ harness set <name> Switch the project to claude-code | omp | codex and install
12378
12617
 
12379
12618
  Assets (skill, agent, prompt, flow, preset, contract):
12380
12619
  add <ref> [--global] Add to skaile.yaml + deploy
@@ -12472,48 +12711,61 @@ Advanced:
12472
12711
  }
12473
12712
  });
12474
12713
  var INIT_HARNESS_DEFAULTS = {
12475
- "claude-code": { harness: "claude-sdk" },
12476
- omp: { harness: "omp" },
12477
- codex: { harness: "codex" }
12714
+ "claude-code": { harness: HARNESS_ID_OF_TARGET["claude-code"] },
12715
+ omp: { harness: HARNESS_ID_OF_TARGET.omp },
12716
+ codex: { harness: HARNESS_ID_OF_TARGET.codex }
12478
12717
  };
12479
- program.command("init [project-dir]").description("Initialize a project directory (defaults to current directory)").option("--harness <name>", "Coding-agent harness (claude-code | omp | codex)", "claude-code").option("--no-git", "Skip git init and .gitignore").action(
12718
+ program.command("init [project-dir]").description("Initialize a project directory (defaults to current directory)").option(
12719
+ "--harness <name>",
12720
+ "Coding-agent harness of a new project (claude-code | omp | codex; default claude-code)"
12721
+ ).option("--no-git", "Skip git init and .gitignore").action(
12480
12722
  (projectDir, opts) => runInit(projectDir, opts)
12481
12723
  );
12482
12724
  async function runInit(projectDir, opts) {
12483
12725
  const { mkdirSync: mkdirSync5, writeFileSync: writeFileSync7 } = await import('fs');
12484
12726
  const { stringify: stringify2 } = await import('yaml');
12485
- const { HARNESS_TARGETS: HARNESS_TARGETS2, SUPPORTED_HARNESSES: SUPPORTED_HARNESSES2 } = await import('../core/index.js');
12486
- const harness = opts.harness;
12727
+ const { HARNESS_TARGETS: HARNESS_TARGETS2, SUPPORTED_HARNESSES: SUPPORTED_HARNESSES2, resolveConfiguredHarnessName: resolveConfiguredHarnessName2 } = await import('../core/index.js');
12728
+ const harness = opts.harness ?? "claude-code";
12487
12729
  if (!SUPPORTED_HARNESSES2.includes(harness)) {
12488
12730
  logErr(`Unknown harness "${opts.harness}". Supported: ${SUPPORTED_HARNESSES2.join(", ")}`);
12489
12731
  process.exitCode = 1;
12490
12732
  return;
12491
12733
  }
12492
- const resolved = path18__default.resolve(projectDir ?? ".");
12493
- const projectName = path18__default.basename(resolved);
12734
+ const resolved = path19__default.resolve(projectDir ?? ".");
12735
+ if (opts.harness && (await import('fs')).existsSync(path19__default.join(resolved, "skaile.yaml"))) {
12736
+ const current = resolveConfiguredHarnessName2(resolved);
12737
+ if (current !== harness) {
12738
+ logErr(
12739
+ `${resolved} is already a skaile project${current ? ` on ${current}` : ""}. To switch it to ${harness}, run: skaile harness set ${harness}`
12740
+ );
12741
+ process.exitCode = 1;
12742
+ return;
12743
+ }
12744
+ }
12745
+ const projectName = path19__default.basename(resolved);
12494
12746
  const created = [];
12495
12747
  const { existsSync: existsSync22 } = await import('fs');
12496
12748
  if (!existsSync22(resolved)) {
12497
12749
  mkdirSync5(resolved, { recursive: true });
12498
12750
  created.push(".");
12499
12751
  }
12500
- const skaileDir = path18__default.join(resolved, ".skaile");
12752
+ const skaileDir = path19__default.join(resolved, ".skaile");
12501
12753
  if (!existsSync22(skaileDir)) {
12502
- mkdirSync5(path18__default.join(skaileDir, "sessions"), { recursive: true });
12754
+ mkdirSync5(path19__default.join(skaileDir, "sessions"), { recursive: true });
12503
12755
  created.push(".skaile/");
12504
12756
  }
12505
- const settingsPath = path18__default.join(skaileDir, "settings.json");
12757
+ const settingsPath = path19__default.join(skaileDir, "settings.json");
12506
12758
  if (!existsSync22(settingsPath)) {
12507
12759
  writeFileSync7(settingsPath, "{}\n");
12508
12760
  created.push(".skaile/settings.json");
12509
12761
  }
12510
- const wsConfigPath = path18__default.join(resolved, "skaile.yaml");
12762
+ const wsConfigPath = path19__default.join(resolved, "skaile.yaml");
12511
12763
  if (!existsSync22(wsConfigPath)) {
12512
12764
  writeFileSync7(wsConfigPath, stringify2(buildInitWorkspaceConfig(projectName, harness)));
12513
12765
  created.push("skaile.yaml");
12514
12766
  }
12515
12767
  for (const dir of new Set(Object.values(HARNESS_TARGETS2[harness].local))) {
12516
- const full = path18__default.join(resolved, dir);
12768
+ const full = path19__default.join(resolved, dir);
12517
12769
  if (!existsSync22(full)) {
12518
12770
  mkdirSync5(full, { recursive: true });
12519
12771
  created.push(`${dir}/`);
@@ -12545,7 +12797,7 @@ function buildInitWorkspaceConfig(projectName, harness) {
12545
12797
  async function initGitScaffold(resolved, created) {
12546
12798
  const { execSync: execSync2 } = await import('child_process');
12547
12799
  const { existsSync: existsSync22, readFileSync: readFileSync13, writeFileSync: writeFileSync7 } = await import('fs');
12548
- const gitignorePath = path18__default.join(resolved, ".gitignore");
12800
+ const gitignorePath = path19__default.join(resolved, ".gitignore");
12549
12801
  const entries = [
12550
12802
  "node_modules/",
12551
12803
  // Python bytecode a deployed skill script leaves inside `.claude/skills` and friends.
@@ -12589,7 +12841,7 @@ async function initGitScaffold(resolved, created) {
12589
12841
  `);
12590
12842
  if (!existing) created.push(".gitignore");
12591
12843
  }
12592
- if (!existsSync22(path18__default.join(resolved, ".git"))) {
12844
+ if (!existsSync22(path19__default.join(resolved, ".git"))) {
12593
12845
  try {
12594
12846
  execSync2("git init", { cwd: resolved, stdio: "pipe" });
12595
12847
  created.push(".git/");
@@ -12619,7 +12871,7 @@ async function bootstrapUserConfig() {
12619
12871
  }
12620
12872
  async function hydrateInitSources(resolved, created) {
12621
12873
  try {
12622
- const { ensureSourcesCloned } = await import('../ensure-sources-UPTHZKGF.js');
12874
+ const { ensureSourcesCloned } = await import('../ensure-sources-IH7CHSJF.js');
12623
12875
  const hydrate = ensureSourcesCloned(resolved, { quiet: true });
12624
12876
  for (const n of hydrate.cloned) created.push(`~/.skaile/cache/sources/${n}/`);
12625
12877
  if (hydrate.failed.length > 0) {
@@ -12635,7 +12887,7 @@ function printInitSummary(resolved, projectDir, created) {
12635
12887
  logOk(`Initialized project at ${S.heading(resolved)}`);
12636
12888
  console.log();
12637
12889
  console.log(S.heading(" Next steps:"));
12638
- const isCurrentDir = resolved === path18__default.resolve(".");
12890
+ const isCurrentDir = resolved === path19__default.resolve(".");
12639
12891
  let step = 1;
12640
12892
  if (!isCurrentDir) {
12641
12893
  console.log(` ${S.dim(`${step}.`)} ${S.cmd(`cd ${projectDir}`)}`);
@@ -12659,7 +12911,7 @@ function printInitSummary(resolved, projectDir, created) {
12659
12911
  console.log();
12660
12912
  }
12661
12913
  program.command("setup").description("Interactive provider setup wizard").action(async () => {
12662
- const { cmdSetup } = await import('../setup-AGYB4PKR.js');
12914
+ const { cmdSetup } = await import('../setup-AG6NFHSN.js');
12663
12915
  await cmdSetup([], { projectDir: process.cwd() });
12664
12916
  });
12665
12917
  program.addCommand(makeInstallCommand());
@@ -12667,6 +12919,7 @@ program.addCommand(makeCheckCommand());
12667
12919
  program.addCommand(makeCleanCommand());
12668
12920
  program.addCommand(makeCacheCommand());
12669
12921
  program.addCommand(makeConfigCommand());
12922
+ program.addCommand(makeHarnessCommand());
12670
12923
  program.addCommand(makeProvidersCommand());
12671
12924
  program.addCommand(makeMigrateCommand());
12672
12925
  program.addCommand(makeAddCommand());
@@ -12738,8 +12991,8 @@ program.hook("postAction", async (_thisCommand, actionCommand) => {
12738
12991
  if (!["add", "remove", "install", "update"].includes(actionCommand.name())) return;
12739
12992
  const opts = actionCommand.opts();
12740
12993
  if (opts.global || opts.dryRun) return;
12741
- const projectDir = path18__default.resolve(opts.projectDir ?? process.cwd());
12742
- const { refreshPluginSkills } = await import('../claude-code-VJGYBXQR.js');
12994
+ const projectDir = path19__default.resolve(opts.projectDir ?? process.cwd());
12995
+ const { refreshPluginSkills } = await import('../claude-code-RE46FJXI.js');
12743
12996
  try {
12744
12997
  if (await refreshPluginSkills(projectDir)) {
12745
12998
  logInfo(`Updated ${S.cmd(".claude/plugins/skaile/skills")} (the --full plugin copy)`);
@@ -12757,6 +13010,9 @@ process.once("beforeExit", () => {
12757
13010
  logErr("The command ended before it finished (nothing left to wait for).");
12758
13011
  process.exit(1);
12759
13012
  });
13013
+ setLibraryAssetCheck(
13014
+ (asset, libraryPath) => libraryAssetRefusals(asset, libraryPath, getKindRegistry())
13015
+ );
12760
13016
  try {
12761
13017
  await program.parseAsync();
12762
13018
  commandSettled = true;