@skaile/workspaces 5.8.0 → 5.10.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 (348) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/{asset-feeds-EYRZR4K5.js → asset-feeds-ELEBTNUS.js} +18 -18
  4. package/dist/{asset-feeds-EYRZR4K5.js.map → asset-feeds-ELEBTNUS.js.map} +1 -1
  5. package/dist/asset-manager/catalog-deployer.js +8 -8
  6. package/dist/asset-manager/index.js +14 -14
  7. package/dist/asset-manager/installer.js +10 -10
  8. package/dist/asset-manager/renderers.js +9 -9
  9. package/dist/asset-manager/src/index.d.ts +300 -36
  10. package/dist/asset-manager/src/index.d.ts.map +1 -1
  11. package/dist/asset-manager/src/install-agent.d.ts +3 -1
  12. package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
  13. package/dist/asset-manager/src/install-instances.d.ts +31 -1
  14. package/dist/asset-manager/src/install-instances.d.ts.map +1 -1
  15. package/dist/asset-manager/src/installer.d.ts +20 -0
  16. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  17. package/dist/asset-manager/src/renderers.d.ts +4 -5
  18. package/dist/asset-manager/src/renderers.d.ts.map +1 -1
  19. package/dist/bridge/drivers/claude-sdk.js +170 -17
  20. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  21. package/dist/bridge/drivers/codex.js +13 -11
  22. package/dist/bridge/drivers/codex.js.map +1 -1
  23. package/dist/bridge/drivers/continue.js +10 -10
  24. package/dist/bridge/drivers/echo.js +4 -4
  25. package/dist/bridge/drivers/gemini.js +7 -7
  26. package/dist/bridge/drivers/goose.js +10 -10
  27. package/dist/bridge/drivers/omp.js +7 -5
  28. package/dist/bridge/drivers/omp.js.map +1 -1
  29. package/dist/bridge/drivers/opencode.js +10 -10
  30. package/dist/bridge/drivers/qwen.js +7 -7
  31. package/dist/bridge/index.js +14 -14
  32. package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
  33. package/dist/bridge/src/drivers/claude-sdk.d.ts +31 -1
  34. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  35. package/dist/bridge/src/drivers/claude-tool-allowlist.d.ts +43 -0
  36. package/dist/bridge/src/drivers/claude-tool-allowlist.d.ts.map +1 -0
  37. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  38. package/dist/bridge/src/types.d.ts +20 -1
  39. package/dist/bridge/src/types.d.ts.map +1 -1
  40. package/dist/{chunk-36AFURKZ.js → chunk-2FMEGSBN.js} +38 -11
  41. package/dist/chunk-2FMEGSBN.js.map +1 -0
  42. package/dist/{chunk-GCICGXDD.js → chunk-2H73V6XR.js} +3 -3
  43. package/dist/{chunk-GCICGXDD.js.map → chunk-2H73V6XR.js.map} +1 -1
  44. package/dist/{chunk-H7QUDDKH.js → chunk-2JMLDZLP.js} +1069 -182
  45. package/dist/chunk-2JMLDZLP.js.map +1 -0
  46. package/dist/{chunk-B6GIW55K.js → chunk-32XKCNCL.js} +6 -3
  47. package/dist/chunk-32XKCNCL.js.map +1 -0
  48. package/dist/{chunk-4MQS7CAF.js → chunk-3BEY4WK3.js} +371 -175
  49. package/dist/chunk-3BEY4WK3.js.map +1 -0
  50. package/dist/{chunk-SH5D7U7N.js → chunk-3KHYGOEY.js} +3 -3
  51. package/dist/{chunk-SH5D7U7N.js.map → chunk-3KHYGOEY.js.map} +1 -1
  52. package/dist/{chunk-CGT45WN7.js → chunk-3MKPZZRE.js} +3 -3
  53. package/dist/{chunk-CGT45WN7.js.map → chunk-3MKPZZRE.js.map} +1 -1
  54. package/dist/{chunk-QVNRCDTV.js → chunk-4OV5DSBB.js} +4 -4
  55. package/dist/chunk-4OV5DSBB.js.map +1 -0
  56. package/dist/{chunk-GXXFLBUQ.js → chunk-4P3KTUZH.js} +33 -33
  57. package/dist/chunk-4P3KTUZH.js.map +1 -0
  58. package/dist/{chunk-I6NLLJHZ.js → chunk-5QI2JYJC.js} +2 -2
  59. package/dist/{chunk-I6NLLJHZ.js.map → chunk-5QI2JYJC.js.map} +1 -1
  60. package/dist/{chunk-EF7NPDDU.js → chunk-6HHE63CO.js} +31 -17
  61. package/dist/chunk-6HHE63CO.js.map +1 -0
  62. package/dist/{chunk-FTJJO3EM.js → chunk-7CR6HT2X.js} +10 -10
  63. package/dist/{chunk-FTJJO3EM.js.map → chunk-7CR6HT2X.js.map} +1 -1
  64. package/dist/{chunk-FZNG4V4J.js → chunk-7I5VRVDP.js} +3 -3
  65. package/dist/{chunk-FZNG4V4J.js.map → chunk-7I5VRVDP.js.map} +1 -1
  66. package/dist/{chunk-HG34RNTK.js → chunk-CLTHEKHR.js} +10 -9
  67. package/dist/chunk-CLTHEKHR.js.map +1 -0
  68. package/dist/{chunk-UMVKJM4Q.js → chunk-DALV4HHP.js} +18 -3
  69. package/dist/chunk-DALV4HHP.js.map +1 -0
  70. package/dist/{chunk-F3RDEH5U.js → chunk-F4NJDSR7.js} +6 -5
  71. package/dist/chunk-F4NJDSR7.js.map +1 -0
  72. package/dist/{chunk-LSXHED6I.js → chunk-FRPBSUFH.js} +6 -6
  73. package/dist/{chunk-LSXHED6I.js.map → chunk-FRPBSUFH.js.map} +1 -1
  74. package/dist/{chunk-W5DWWE4Y.js → chunk-G54USEUP.js} +4 -4
  75. package/dist/{chunk-W5DWWE4Y.js.map → chunk-G54USEUP.js.map} +1 -1
  76. package/dist/{chunk-Y7QA2OLD.js → chunk-GEWAIQZ5.js} +24 -20
  77. package/dist/chunk-GEWAIQZ5.js.map +1 -0
  78. package/dist/{chunk-GB7WDMH2.js → chunk-GFCXNFTW.js} +4 -4
  79. package/dist/{chunk-GB7WDMH2.js.map → chunk-GFCXNFTW.js.map} +1 -1
  80. package/dist/{chunk-AWQYXZVG.js → chunk-HJ5MCB3L.js} +28 -4
  81. package/dist/chunk-HJ5MCB3L.js.map +1 -0
  82. package/dist/{chunk-2LWYNQK7.js → chunk-HOHUEKES.js} +3 -3
  83. package/dist/{chunk-2LWYNQK7.js.map → chunk-HOHUEKES.js.map} +1 -1
  84. package/dist/{chunk-ZKSJMZKD.js → chunk-IJHH4DSW.js} +8 -8
  85. package/dist/{chunk-ZKSJMZKD.js.map → chunk-IJHH4DSW.js.map} +1 -1
  86. package/dist/{chunk-BTE2V4IW.js → chunk-IXWODEED.js} +40 -7
  87. package/dist/chunk-IXWODEED.js.map +1 -0
  88. package/dist/{chunk-OFBIWVCR.js → chunk-JFXQEVLF.js} +3 -3
  89. package/dist/{chunk-OFBIWVCR.js.map → chunk-JFXQEVLF.js.map} +1 -1
  90. package/dist/{chunk-JAKOMFC6.js → chunk-JZCSNEHK.js} +77 -31
  91. package/dist/chunk-JZCSNEHK.js.map +1 -0
  92. package/dist/{chunk-CKQEIY43.js → chunk-MVQ3Q2HM.js} +4 -4
  93. package/dist/{chunk-CKQEIY43.js.map → chunk-MVQ3Q2HM.js.map} +1 -1
  94. package/dist/{chunk-LEMHVDET.js → chunk-NRDSGLCQ.js} +188 -33
  95. package/dist/chunk-NRDSGLCQ.js.map +1 -0
  96. package/dist/{chunk-V2DXZYBB.js → chunk-NWDSLXOX.js} +3 -3
  97. package/dist/{chunk-V2DXZYBB.js.map → chunk-NWDSLXOX.js.map} +1 -1
  98. package/dist/{chunk-6GRX5L6A.js → chunk-OBVJ7RPW.js} +4 -4
  99. package/dist/{chunk-6GRX5L6A.js.map → chunk-OBVJ7RPW.js.map} +1 -1
  100. package/dist/{chunk-PTSGWKHR.js → chunk-OOWHXOK6.js} +4 -4
  101. package/dist/{chunk-PTSGWKHR.js.map → chunk-OOWHXOK6.js.map} +1 -1
  102. package/dist/{chunk-YSHVQGUS.js → chunk-PE36IF2D.js} +119 -30
  103. package/dist/chunk-PE36IF2D.js.map +1 -0
  104. package/dist/{chunk-S53LOR7B.js → chunk-QG3HOJEK.js} +3 -3
  105. package/dist/{chunk-S53LOR7B.js.map → chunk-QG3HOJEK.js.map} +1 -1
  106. package/dist/{chunk-2FRUUDZY.js → chunk-SBFW3CJH.js} +5 -5
  107. package/dist/{chunk-2FRUUDZY.js.map → chunk-SBFW3CJH.js.map} +1 -1
  108. package/dist/{chunk-UAROCOXF.js → chunk-SX5U422E.js} +3 -3
  109. package/dist/{chunk-UAROCOXF.js.map → chunk-SX5U422E.js.map} +1 -1
  110. package/dist/{chunk-QOP6KDFR.js → chunk-TH4CTXHX.js} +6 -6
  111. package/dist/{chunk-QOP6KDFR.js.map → chunk-TH4CTXHX.js.map} +1 -1
  112. package/dist/{chunk-F2EKONM7.js → chunk-TRSQP3JD.js} +3 -3
  113. package/dist/{chunk-F2EKONM7.js.map → chunk-TRSQP3JD.js.map} +1 -1
  114. package/dist/{chunk-FVJK4QWM.js → chunk-V5TZH4GF.js} +4 -4
  115. package/dist/{chunk-FVJK4QWM.js.map → chunk-V5TZH4GF.js.map} +1 -1
  116. package/dist/{chunk-HYDRDNKN.js → chunk-V7PQZOBR.js} +5 -5
  117. package/dist/{chunk-HYDRDNKN.js.map → chunk-V7PQZOBR.js.map} +1 -1
  118. package/dist/{chunk-IONAUNWB.js → chunk-VLXDXRRX.js} +3 -3
  119. package/dist/{chunk-IONAUNWB.js.map → chunk-VLXDXRRX.js.map} +1 -1
  120. package/dist/{chunk-CIFS5K6T.js → chunk-VMKMFS2Q.js} +28 -7
  121. package/dist/chunk-VMKMFS2Q.js.map +1 -0
  122. package/dist/{chunk-Y4N2NUZD.js → chunk-WBYDAL6X.js} +4 -4
  123. package/dist/{chunk-Y4N2NUZD.js.map → chunk-WBYDAL6X.js.map} +1 -1
  124. package/dist/{chunk-WTQ3TATB.js → chunk-X4BAYGMT.js} +3 -3
  125. package/dist/{chunk-WTQ3TATB.js.map → chunk-X4BAYGMT.js.map} +1 -1
  126. package/dist/{chunk-NPLPCRW5.js → chunk-XCNK4UE5.js} +5 -5
  127. package/dist/{chunk-NPLPCRW5.js.map → chunk-XCNK4UE5.js.map} +1 -1
  128. package/dist/{chunk-OJ4N4T4H.js → chunk-XDVR7QIT.js} +20 -6
  129. package/dist/chunk-XDVR7QIT.js.map +1 -0
  130. package/dist/{chunk-GTILM2CI.js → chunk-Y34MSWEZ.js} +43 -12
  131. package/dist/chunk-Y34MSWEZ.js.map +1 -0
  132. package/dist/{chunk-4PTSR4UU.js → chunk-Y63UQZ7P.js} +3 -3
  133. package/dist/{chunk-4PTSR4UU.js.map → chunk-Y63UQZ7P.js.map} +1 -1
  134. package/dist/chunk-YBQONMH2.js +465 -0
  135. package/dist/chunk-YBQONMH2.js.map +1 -0
  136. package/dist/{chunk-P23M65LB.js → chunk-Z2K6BGUR.js} +71 -24
  137. package/dist/chunk-Z2K6BGUR.js.map +1 -0
  138. package/dist/{chunk-BJNUNQAW.js → chunk-ZGQTS3Y4.js} +3 -3
  139. package/dist/{chunk-BJNUNQAW.js.map → chunk-ZGQTS3Y4.js.map} +1 -1
  140. package/dist/cli/index.js +913 -720
  141. package/dist/cli/index.js.map +1 -1
  142. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  143. package/dist/cli/src/commands/catalog.d.ts +8 -5
  144. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  145. package/dist/cli/src/commands/diff.d.ts +3 -1
  146. package/dist/cli/src/commands/diff.d.ts.map +1 -1
  147. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  148. package/dist/cli/src/commands/library-index.d.ts +34 -2
  149. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  150. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  151. package/dist/cli/src/commands/manage.d.ts +6 -5
  152. package/dist/cli/src/commands/manage.d.ts.map +1 -1
  153. package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
  154. package/dist/cli/src/commands/outdated.d.ts +7 -5
  155. package/dist/cli/src/commands/outdated.d.ts.map +1 -1
  156. package/dist/cli/src/commands/project.d.ts +11 -8
  157. package/dist/cli/src/commands/project.d.ts.map +1 -1
  158. package/dist/cli/src/commands/source.d.ts +30 -1
  159. package/dist/cli/src/commands/source.d.ts.map +1 -1
  160. package/dist/cli/src/commands/update.d.ts.map +1 -1
  161. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  162. package/dist/cli/src/commands/why.d.ts.map +1 -1
  163. package/dist/cli/src/skill-checks.d.ts +47 -2
  164. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  165. package/dist/client/index.js +1 -1
  166. package/dist/client/src/client.d.ts +10 -3
  167. package/dist/client/src/client.d.ts.map +1 -1
  168. package/dist/connectors/config.js +5 -5
  169. package/dist/connectors/index.js +18 -18
  170. package/dist/{connectors-O6Y6VESP.js → connectors-OXP2JBGI.js} +21 -21
  171. package/dist/{connectors-O6Y6VESP.js.map → connectors-OXP2JBGI.js.map} +1 -1
  172. package/dist/connectors-shared/index.js +2 -2
  173. package/dist/core/index.js +7 -7
  174. package/dist/core/logging.js +1 -1
  175. package/dist/core/manifest.js +2 -2
  176. package/dist/core/models.js +1 -1
  177. package/dist/core/publish-manifest.js +2 -2
  178. package/dist/core/ref.js +1 -1
  179. package/dist/core/runtime-assets.js +5 -5
  180. package/dist/core/src/index.d.ts +2 -1
  181. package/dist/core/src/index.d.ts.map +1 -1
  182. package/dist/core/src/lock.d.ts +5 -2
  183. package/dist/core/src/lock.d.ts.map +1 -1
  184. package/dist/core/src/logging/sinks/sqlite-runtime.d.ts.map +1 -1
  185. package/dist/core/src/manifest.d.ts.map +1 -1
  186. package/dist/core/src/models.d.ts +21 -5
  187. package/dist/core/src/models.d.ts.map +1 -1
  188. package/dist/core/src/publish-manifest.d.ts +19 -3
  189. package/dist/core/src/publish-manifest.d.ts.map +1 -1
  190. package/dist/core/src/repo-manager.d.ts.map +1 -1
  191. package/dist/core/src/requirements.d.ts +26 -0
  192. package/dist/core/src/requirements.d.ts.map +1 -0
  193. package/dist/core/src/walker.d.ts.map +1 -1
  194. package/dist/core/src/workspace-config.d.ts +18 -0
  195. package/dist/core/src/workspace-config.d.ts.map +1 -1
  196. package/dist/core/src/workspace-yaml-editor.d.ts +4 -1
  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 +7 -7
  200. package/dist/discovery/index.js +5 -5
  201. package/dist/discovery/src/builtin-providers.d.ts.map +1 -1
  202. package/dist/discovery/src/discover-manifest.d.ts.map +1 -1
  203. package/dist/discovery/src/discover.d.ts.map +1 -1
  204. package/dist/discovery/src/source-config.d.ts.map +1 -1
  205. package/dist/discovery/src/tree-entries.d.ts.map +1 -1
  206. package/dist/{ensure-sources-SKLNM4UZ.js → ensure-sources-5ISVIA4T.js} +17 -17
  207. package/dist/{ensure-sources-SKLNM4UZ.js.map → ensure-sources-5ISVIA4T.js.map} +1 -1
  208. package/dist/factory-assets/connectors/box.js +18 -18
  209. package/dist/factory-assets/connectors/deploy.js +18 -18
  210. package/dist/factory-assets/connectors/devserver.js +18 -18
  211. package/dist/factory-assets/connectors/flow/adapter.js +18 -18
  212. package/dist/factory-assets/connectors/flow/engine.js +8 -8
  213. package/dist/factory-assets/connectors/flow/run-flow.js +20 -20
  214. package/dist/factory-assets/connectors/flow.js +18 -18
  215. package/dist/factory-assets/connectors/git.js +18 -18
  216. package/dist/factory-assets/connectors/gmail.js +18 -18
  217. package/dist/factory-assets/connectors/googledrive.js +18 -18
  218. package/dist/factory-assets/connectors/local.js +18 -18
  219. package/dist/factory-assets/connectors/mattermost.js +18 -18
  220. package/dist/factory-assets/connectors/memory.js +18 -18
  221. package/dist/factory-assets/connectors/minio.js +18 -18
  222. package/dist/factory-assets/connectors/postgres.js +18 -18
  223. package/dist/factory-assets/connectors/s3.js +18 -18
  224. package/dist/factory-assets/connectors/sharepoint.js +18 -18
  225. package/dist/factory-assets/connectors/sqlite.js +18 -18
  226. package/dist/factory-assets/connectors/static-server.js +18 -18
  227. package/dist/factory-assets/connectors/tunnel.js +18 -18
  228. package/dist/factory-assets/connectors/webdav.js +18 -18
  229. package/dist/factory-assets/connectors/xstate-store.js +18 -18
  230. package/dist/factory-assets/connectors/xstate.js +18 -18
  231. package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +9 -3
  232. package/dist/{flows-CBYRSAGS.js → flows-HMSE76PO.js} +12 -12
  233. package/dist/{flows-CBYRSAGS.js.map → flows-HMSE76PO.js.map} +1 -1
  234. package/dist/{helpers-MWZDRBLD.js → helpers-X6URBGSF.js} +17 -17
  235. package/dist/{helpers-MWZDRBLD.js.map → helpers-X6URBGSF.js.map} +1 -1
  236. package/dist/library/index.js +11 -11
  237. package/dist/library/install.js +3 -3
  238. package/dist/library/src/index.d.ts +2 -1
  239. package/dist/library/src/index.d.ts.map +1 -1
  240. package/dist/library/src/local/library-dir.d.ts +42 -0
  241. package/dist/library/src/local/library-dir.d.ts.map +1 -0
  242. package/dist/library/src/local/library-manager.d.ts +10 -1
  243. package/dist/library/src/local/library-manager.d.ts.map +1 -1
  244. package/dist/library/src/local/library.d.ts +2 -2
  245. package/dist/library/src/local/library.d.ts.map +1 -1
  246. package/dist/library/src/local/local-catalog-source.d.ts +9 -0
  247. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  248. package/dist/library/src/manifest-writer.d.ts +55 -4
  249. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  250. package/dist/library/src/remote/cache.d.ts +18 -1
  251. package/dist/library/src/remote/cache.d.ts.map +1 -1
  252. package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
  253. package/dist/library/src/remote/rest-catalog-source.d.ts.map +1 -1
  254. package/dist/library/src/sync/git-driver.d.ts +5 -6
  255. package/dist/library/src/sync/git-driver.d.ts.map +1 -1
  256. package/dist/{library-publish-PICMDSB2.js → library-publish-OS3JDW4S.js} +123 -41
  257. package/dist/library-publish-OS3JDW4S.js.map +1 -0
  258. package/dist/open-library-4QSUORI6.js +40 -0
  259. package/dist/{open-library-OG457THY.js.map → open-library-4QSUORI6.js.map} +1 -1
  260. package/dist/open-registry-VCKS3MP5.js +32 -0
  261. package/dist/{open-registry-ZUZJ7MS7.js.map → open-registry-VCKS3MP5.js.map} +1 -1
  262. package/dist/paths-BVO56A25.js +22 -0
  263. package/dist/{paths-FQ64OLJG.js.map → paths-BVO56A25.js.map} +1 -1
  264. package/dist/{plugin-store-MPAMD5OT.js → plugin-store-X7GPWGBG.js} +9 -9
  265. package/dist/{plugin-store-MPAMD5OT.js.map → plugin-store-X7GPWGBG.js.map} +1 -1
  266. package/dist/{project-2GFT5LEZ.js → project-PAXP46RD.js} +20 -20
  267. package/dist/{project-2GFT5LEZ.js.map → project-PAXP46RD.js.map} +1 -1
  268. package/dist/resolver/index.js +8 -8
  269. package/dist/runner/index.js +32 -32
  270. package/dist/runner/src/agent.d.ts.map +1 -1
  271. package/dist/runner/src/context-usage/compose.d.ts.map +1 -1
  272. package/dist/runner/src/platform-blocks.d.ts +55 -0
  273. package/dist/runner/src/platform-blocks.d.ts.map +1 -0
  274. package/dist/runner/src/serve.d.ts.map +1 -1
  275. package/dist/runner/src/session-builder.d.ts.map +1 -1
  276. package/dist/sdk/asset-manager.js +14 -14
  277. package/dist/sdk/bridge.js +14 -14
  278. package/dist/sdk/client.js +1 -1
  279. package/dist/sdk/core.js +7 -7
  280. package/dist/sdk/flow.js +8 -8
  281. package/dist/sdk/index.js +33 -33
  282. package/dist/sdk/resolver.js +8 -8
  283. package/dist/sdk/runner.js +32 -32
  284. package/dist/sdk/session.js +2 -2
  285. package/dist/sdk/types.js +1 -1
  286. package/dist/session/index.js +2 -2
  287. package/dist/session/src/dispatcher.d.ts +25 -4
  288. package/dist/session/src/dispatcher.d.ts.map +1 -1
  289. package/dist/session/src/index.d.ts +1 -1
  290. package/dist/session/src/index.d.ts.map +1 -1
  291. package/dist/{setup-WHMCSIF2.js → setup-BV55VHWC.js} +24 -24
  292. package/dist/{setup-WHMCSIF2.js.map → setup-BV55VHWC.js.map} +1 -1
  293. package/dist/{skills-TVO26Y4V.js → skills-EDFUCJPX.js} +13 -13
  294. package/dist/{skills-TVO26Y4V.js.map → skills-EDFUCJPX.js.map} +1 -1
  295. package/dist/source-E4VAT5RZ.js +41 -0
  296. package/dist/{source-LKOFTOEK.js.map → source-E4VAT5RZ.js.map} +1 -1
  297. package/dist/{source-manifest-publish-L5J3QXER.js → source-manifest-publish-CLEE6TNH.js} +23 -23
  298. package/dist/{source-manifest-publish-L5J3QXER.js.map → source-manifest-publish-CLEE6TNH.js.map} +1 -1
  299. package/dist/tui/index.js +32 -32
  300. package/dist/types/index.js +1 -1
  301. package/dist/types/manifests.js +1 -1
  302. package/dist/types/src/events.d.ts +1 -1
  303. package/dist/types/src/events.d.ts.map +1 -1
  304. package/dist/types/src/index.d.ts +2 -2
  305. package/dist/types/src/index.d.ts.map +1 -1
  306. package/dist/types/src/manifests/agent.d.ts +2 -0
  307. package/dist/types/src/manifests/agent.d.ts.map +1 -1
  308. package/dist/types/src/manifests/contract.d.ts +2 -0
  309. package/dist/types/src/manifests/contract.d.ts.map +1 -1
  310. package/dist/types/src/manifests/index.d.ts +3 -3
  311. package/dist/types/src/manifests/index.d.ts.map +1 -1
  312. package/dist/types/src/manifests/prompt.d.ts +2 -0
  313. package/dist/types/src/manifests/prompt.d.ts.map +1 -1
  314. package/dist/types/src/protocol.d.ts +43 -1
  315. package/dist/types/src/protocol.d.ts.map +1 -1
  316. package/dist/types/src/version.d.ts +17 -1
  317. package/dist/types/src/version.d.ts.map +1 -1
  318. package/dist/workspace-plugin/adapters/mcp.js +25 -25
  319. package/dist/workspace-plugin/adapters/omp.js +14 -14
  320. package/dist/workspace-plugin/index.js +2 -2
  321. package/package.json +1 -1
  322. package/dist/chunk-36AFURKZ.js.map +0 -1
  323. package/dist/chunk-4MQS7CAF.js.map +0 -1
  324. package/dist/chunk-AWQYXZVG.js.map +0 -1
  325. package/dist/chunk-B6GIW55K.js.map +0 -1
  326. package/dist/chunk-BTE2V4IW.js.map +0 -1
  327. package/dist/chunk-CIFS5K6T.js.map +0 -1
  328. package/dist/chunk-EF7NPDDU.js.map +0 -1
  329. package/dist/chunk-F3RDEH5U.js.map +0 -1
  330. package/dist/chunk-GTILM2CI.js.map +0 -1
  331. package/dist/chunk-GXXFLBUQ.js.map +0 -1
  332. package/dist/chunk-H7QUDDKH.js.map +0 -1
  333. package/dist/chunk-HG34RNTK.js.map +0 -1
  334. package/dist/chunk-JAKOMFC6.js.map +0 -1
  335. package/dist/chunk-LEMHVDET.js.map +0 -1
  336. package/dist/chunk-OJ4N4T4H.js.map +0 -1
  337. package/dist/chunk-P23M65LB.js.map +0 -1
  338. package/dist/chunk-QVNRCDTV.js.map +0 -1
  339. package/dist/chunk-UMVKJM4Q.js.map +0 -1
  340. package/dist/chunk-Y7QA2OLD.js.map +0 -1
  341. package/dist/chunk-YSHVQGUS.js.map +0 -1
  342. package/dist/chunk-ZAOGFXDO.js +0 -112
  343. package/dist/chunk-ZAOGFXDO.js.map +0 -1
  344. package/dist/library-publish-PICMDSB2.js.map +0 -1
  345. package/dist/open-library-OG457THY.js +0 -40
  346. package/dist/open-registry-ZUZJ7MS7.js +0 -32
  347. package/dist/paths-FQ64OLJG.js +0 -22
  348. package/dist/source-LKOFTOEK.js +0 -41
package/dist/cli/index.js CHANGED
@@ -1,24 +1,24 @@
1
1
  #!/usr/bin/env node
2
- import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-NPLPCRW5.js';
3
- import { makeSourceCommand, syncProjectSources } from '../chunk-P23M65LB.js';
4
- import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportRelocked, REF_HINT, reportInstalledSoftDeps } from '../chunk-GXXFLBUQ.js';
2
+ import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-XCNK4UE5.js';
3
+ import { makeSourceCommand, syncProjectSources, divergedSourceClones } from '../chunk-Z2K6BGUR.js';
4
+ import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportReplaced, reportRelocked, REF_HINT, reportInstalledSoftDeps } from '../chunk-4P3KTUZH.js';
5
5
  import { createSpinner } from '../chunk-NESV47MF.js';
6
- import { AI_RESOURCES } from '../chunk-Y4N2NUZD.js';
7
- import { findAssetManifestFile, declaredVersion, readAssetBody, checkAssetManifest } from '../chunk-ZAOGFXDO.js';
8
- import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, assetEntryRef, manifestVersionMismatchMessage, refFor } from '../chunk-HYDRDNKN.js';
9
- import { openCatalogSource, LocalCatalogDisabledError, openLibraryManager, openLibrary } from '../chunk-HG34RNTK.js';
10
- import { logErr, S, logOk, logInfo, logWarn, TARGET_DEFAULT_HINT, deferredWarnings, warnLegacyClaudeCopies, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth, KIND_COL_WIDTH } from '../chunk-F2EKONM7.js';
11
- import { getKindRegistry, getKnownKinds } from '../chunk-2FRUUDZY.js';
6
+ import { AI_RESOURCES } from '../chunk-WBYDAL6X.js';
7
+ import { unresolvedManifestDependencies, warnIgnoredDomainFiles, warnLegacyBundleFiles, removedDomainOption, rejectRemovedDomainOption, resolveLibraryPublisherDetailed, warnLibraryNameFallback, indexLibrary, requireValidPublisherOrExit, exitOnManifestPublisherProblems, registerLibraryAsset, DOMAIN_REMOVED_HINT, manifestPublisherProblems, manifestRequiresProblems, findAssetManifestFile, declaredVersion, checkAssetFile, duplicateAssetMessage, readAssetBody, checkAsset, invalidSemverText } from '../chunk-YBQONMH2.js';
8
+ import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, assetEntryRef, manifestVersionMismatchMessage } from '../chunk-V7PQZOBR.js';
9
+ import { openCatalogSource, LocalCatalogDisabledError, openLibraryManager, openLibrary } from '../chunk-CLTHEKHR.js';
10
+ import { logErr, S, logOk, logInfo, logWarn, TARGET_DEFAULT_HINT, deferredWarnings, warnLegacyClaudeCopies, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth, KIND_COL_WIDTH } from '../chunk-TRSQP3JD.js';
11
+ import { getKindRegistry, getKnownKinds } from '../chunk-SBFW3CJH.js';
12
12
  import { LocalSecretsProvider } from '../chunk-ILFGVSTJ.js';
13
- import { runAgentChat, isCompositionError, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, hashAgentFiles, createCompositionContentSource, compileComposition, instanceForSession, resolveAgentInstance, describeComposition, MarkdownStreamer } from '../chunk-LEMHVDET.js';
14
- import { buildClaudePluginFiles } from '../chunk-I6NLLJHZ.js';
15
- import '../chunk-LSXHED6I.js';
16
- import '../chunk-UAROCOXF.js';
13
+ import { runAgentChat, isCompositionError, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, hashAgentFiles, createCompositionContentSource, compileComposition, instanceForSession, resolveAgentInstance, describeComposition, MarkdownStreamer } from '../chunk-NRDSGLCQ.js';
14
+ import { buildClaudePluginFiles } from '../chunk-5QI2JYJC.js';
15
+ import '../chunk-FRPBSUFH.js';
16
+ import '../chunk-SX5U422E.js';
17
17
  import '../chunk-R6O6YWU7.js';
18
- import '../chunk-W5DWWE4Y.js';
19
- import '../chunk-4PTSR4UU.js';
18
+ import '../chunk-G54USEUP.js';
19
+ import '../chunk-Y63UQZ7P.js';
20
20
  import '../chunk-4ZTPYIBE.js';
21
- import '../chunk-IONAUNWB.js';
21
+ import '../chunk-VLXDXRRX.js';
22
22
  import '../chunk-X5YPJV4N.js';
23
23
  import '../chunk-O7SG5PC2.js';
24
24
  import '../chunk-7QBNJTTQ.js';
@@ -26,77 +26,77 @@ import '../chunk-OBYKJB4U.js';
26
26
  import '../chunk-5LKOAX7I.js';
27
27
  import '../chunk-32NA4TVC.js';
28
28
  import '../chunk-W3UDISS2.js';
29
- import '../chunk-V2DXZYBB.js';
30
- import { runFlow, resumeFlow } from '../chunk-ZKSJMZKD.js';
29
+ import '../chunk-NWDSLXOX.js';
30
+ import { runFlow, resumeFlow } from '../chunk-IJHH4DSW.js';
31
31
  import '../chunk-4R6DROGN.js';
32
- import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-CGT45WN7.js';
33
- import '../chunk-2LWYNQK7.js';
32
+ import { validateFlowVersions } from '../chunk-3MKPZZRE.js';
33
+ import '../chunk-HOHUEKES.js';
34
34
  import '../chunk-ISHJITXJ.js';
35
- import '../chunk-FTJJO3EM.js';
36
- import '../chunk-WTQ3TATB.js';
37
- import '../chunk-FVJK4QWM.js';
38
- import '../chunk-6GRX5L6A.js';
39
- import '../chunk-S53LOR7B.js';
35
+ import '../chunk-7CR6HT2X.js';
36
+ import '../chunk-X4BAYGMT.js';
37
+ import '../chunk-V5TZH4GF.js';
38
+ import '../chunk-OBVJ7RPW.js';
39
+ import '../chunk-QG3HOJEK.js';
40
40
  import '../chunk-LOO5CB5M.js';
41
- import '../chunk-GCICGXDD.js';
42
- import '../chunk-PTSGWKHR.js';
41
+ import '../chunk-2H73V6XR.js';
42
+ import '../chunk-OOWHXOK6.js';
43
43
  import '../chunk-B4X2N7JQ.js';
44
44
  import '../chunk-YROR332M.js';
45
- import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-AWQYXZVG.js';
45
+ import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-HJ5MCB3L.js';
46
46
  import '../chunk-6E6PKKAD.js';
47
47
  import '../chunk-IFGTRL2I.js';
48
- import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-FZNG4V4J.js';
48
+ import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-7I5VRVDP.js';
49
49
  import '../chunk-LNFKL23K.js';
50
50
  import '../chunk-MGGFBZWA.js';
51
51
  import '../chunk-M3WPBTGJ.js';
52
52
  import { nodeLabel, nodeSkillAsset, nodeIsInert, nodeIsOptional, nodeRunKind, flowSkillVersionPins } from '../chunk-7RGTAEG6.js';
53
53
  import '../chunk-NUELZWCF.js';
54
- import '../chunk-F3RDEH5U.js';
55
- import { AssetManager, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-H7QUDDKH.js';
56
- import { cloneOrInitGitRepo, trackOriginBranch, stampManifestPublisher, ensureGitRepo, conflictingAssetRoot, setManifestPublisher, LIBRARY_OWNERSHIPS, isGitRepo, assertManifestEditable, installLibraryAsset, missingRootAssets, assertValidLibraryName, upsertManifestAsset, syncManifestWithDisk, getStoreManifestsDir, getDefaultValue, isSecretPlaceholder } from '../chunk-4MQS7CAF.js';
57
- import { parseManifestFile, requiresSyntaxErrors, SEMVER_RE } from '../chunk-Y7QA2OLD.js';
58
- import '../chunk-CKQEIY43.js';
54
+ import '../chunk-F4NJDSR7.js';
55
+ import { AssetManager, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-2JMLDZLP.js';
56
+ import { libraryDirMissing, missingLibraryDirMessage, cloneOrInitGitRepo, trackOriginBranch, stampManifestPublisher, ensureGitRepo, conflictingAssetRoot, setManifestPublisher, LIBRARY_OWNERSHIPS, isGitRepo, assertManifestEditable, installLibraryAsset, missingRootAssets, assertValidLibraryName, syncManifestWithDisk, getStoreManifestsDir, getDefaultValue, isSecretPlaceholder } from '../chunk-3BEY4WK3.js';
57
+ import { parseManifestFile, SEMVER_RE } from '../chunk-GEWAIQZ5.js';
58
+ import '../chunk-MVQ3Q2HM.js';
59
59
  import '../chunk-R7FOF242.js';
60
60
  import '../chunk-3TXEJN4W.js';
61
- import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-YSHVQGUS.js';
61
+ import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-PE36IF2D.js';
62
62
  import '../chunk-CGYEHQOX.js';
63
63
  import '../chunk-KTBKW2FI.js';
64
64
  import '../chunk-UQ6LFBPZ.js';
65
- import '../chunk-EF7NPDDU.js';
66
- import { effectiveComposes, validatePreset, composeSlotDiagnostics, agentDeprecationDiagnostics, validateAgent, SLOT_ID_PATTERN } from '../chunk-B6GIW55K.js';
67
- import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, readLock, aiResourceRoots, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-36AFURKZ.js';
65
+ import '../chunk-6HHE63CO.js';
66
+ import { effectiveComposes, validatePreset, composeSlotDiagnostics, agentDeprecationDiagnostics, validateAgent, SLOT_ID_PATTERN } from '../chunk-32XKCNCL.js';
67
+ import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, readLock, aiResourceRoots, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-2FMEGSBN.js';
68
68
  import '../chunk-4GY63JU6.js';
69
- import { factoryAssetRoots } from '../chunk-GB7WDMH2.js';
69
+ import { factoryAssetRoots } from '../chunk-GFCXNFTW.js';
70
70
  import '../chunk-PMECEZK3.js';
71
71
  import { DEFAULT_DRIVER_ID, DRIVER_DEFAULTS } from '../chunk-5BEFNLOR.js';
72
72
  import { findKindDirs } from '../chunk-A2ULN3KX.js';
73
- import { sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, resolveSkWorkspaceConfig, matchPin, coerceVersion, loadSkWorkspaceConfig, normalizeAgentInstances, agentInstanceDiagnostics, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-JAKOMFC6.js';
73
+ import { SourceEntryError, SKAILE_YAML_DEFAULT, sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, resolveSkWorkspaceConfig, matchPin, coerceVersion, loadSkWorkspaceConfig, normalizeAgentInstances, agentInstanceDiagnostics, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-JZCSNEHK.js';
74
74
  import { globalCacheRoot, globalSkaileDir, userConfigPath } from '../chunk-L5VSIPQD.js';
75
75
  import { SUPPORTED_DRIVER_TARGETS, driverTargetForDriver } from '../chunk-CPSIPIX7.js';
76
- import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest, loadSkPublishManifest, encodeSkaileManifest } from '../chunk-BTE2V4IW.js';
76
+ import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest, loadSkPublishManifest, encodeSkaileManifest } from '../chunk-IXWODEED.js';
77
77
  import { pluginTitle } from '../chunk-RVRB27AN.js';
78
- import { parseFrontmatter, scanDirectory } from '../chunk-GTILM2CI.js';
79
- import { parseAssetRef, isValidPublisher, PUBLISHER_HINT, isValidAssetName, ASSET_NAME_HINT, slugifyAssetName, parseAssetRefLoose, assetRefToStr } from '../chunk-QVNRCDTV.js';
78
+ import { dedupeRequirements, parseFrontmatter, scanDirectory } from '../chunk-Y34MSWEZ.js';
79
+ import { parseAssetRef, isValidPublisher, PUBLISHER_HINT, isValidAssetName, ASSET_NAME_HINT, slugifyAssetName, parseAssetRefLoose, assetRefToStr } from '../chunk-4OV5DSBB.js';
80
80
  import { portableSpawn, portableSpawnSync } from '../chunk-ICSCSM5D.js';
81
- import { openSqlite } from '../chunk-UMVKJM4Q.js';
81
+ import { openSqlite } from '../chunk-DALV4HHP.js';
82
82
  import { parseModelRef, resolveEntryBaseUrl } from '../chunk-MJHSLODD.js';
83
83
  import '../chunk-C3CAXQMA.js';
84
84
  import '../chunk-BOFL7GIF.js';
85
85
  import '../chunk-NSBPE2FW.js';
86
- import * as fs9 from 'fs';
87
- import fs9__default, { readFileSync, existsSync, mkdirSync, writeFileSync, lstatSync, rmSync, readdirSync, statSync } from 'fs';
88
- import * as path23 from 'path';
89
- import path23__default, { resolve, join } from 'path';
86
+ import * as fs8 from 'fs';
87
+ import fs8__default, { readFileSync, existsSync, mkdirSync, writeFileSync, lstatSync, rmSync, readdirSync, statSync } from 'fs';
88
+ import * as path18 from 'path';
89
+ import path18__default, { resolve, join } from 'path';
90
90
  import { fileURLToPath } from 'url';
91
91
  import { Help, Command, Option } from 'commander';
92
92
  import { rcompare } from 'semver';
93
93
  import * as p4 from '@clack/prompts';
94
94
  import pc5 from 'picocolors';
95
- import { parse, stringify, parseDocument, isMap, isScalar, isSeq } from 'yaml';
96
95
  import * as os from 'os';
96
+ import { parse, stringify, parseDocument, isMap, isScalar, isSeq } from 'yaml';
97
97
  import * as readline from 'readline';
98
98
  import { createInterface } from 'readline';
99
- import fs6 from 'fs/promises';
99
+ import fs5 from 'fs/promises';
100
100
  import { parse as parse$1, stringify as stringify$1 } from 'smol-toml';
101
101
  import { execSync, spawnSync, execFileSync } from 'child_process';
102
102
  import * as readline2 from 'readline/promises';
@@ -175,7 +175,7 @@ async function runSearch(kind, query, opts) {
175
175
  const showLocal = !opts.store;
176
176
  const showStore = !opts.local;
177
177
  const { resolveConfig } = await import('../library/index.js');
178
- const airGapped = resolveConfig({ projectDir: path23__default.resolve(opts.projectDir) }).catalog.cache_ttl === 0;
178
+ const airGapped = resolveConfig({ projectDir: path18__default.resolve(opts.projectDir) }).catalog.cache_ttl === 0;
179
179
  if (showLocal) {
180
180
  await searchLocal(query, kind, opts, showStore, airGapped);
181
181
  }
@@ -184,11 +184,14 @@ async function runSearch(kind, query, opts) {
184
184
  }
185
185
  }
186
186
  async function searchIndex(query, kind) {
187
- const { openLibrary: openLibrary2 } = await import('../open-library-OG457THY.js');
187
+ const { openLibrary: openLibrary2 } = await import('../open-library-4QSUORI6.js');
188
188
  const library = await openLibrary2();
189
189
  try {
190
- const defs = await library.listAssetDefs(kind ? { kind } : {});
191
- const libraryNames = new Map((await library.listSources()).map((l) => [l.id, l.name]));
190
+ const { libraryDirMissing: libraryDirMissing2 } = await import('../library/index.js');
191
+ const sources = await library.listSources();
192
+ const gone = new Set(sources.filter(libraryDirMissing2).map((l) => l.id));
193
+ const defs = (await library.listAssetDefs(kind ? { kind } : {})).filter((d) => !d.libraryId || !gone.has(d.libraryId));
194
+ const libraryNames = new Map(sources.map((l) => [l.id, l.name]));
192
195
  let entries = defs.map(
193
196
  (d) => ({
194
197
  name: d.name,
@@ -218,7 +221,7 @@ async function searchIndex(query, kind) {
218
221
  }
219
222
  }
220
223
  async function searchFactory(projectDir, query, kind) {
221
- const prefixes = factoryAssetRoots().map((r) => r.endsWith(path23__default.sep) ? r : r + path23__default.sep);
224
+ const prefixes = factoryAssetRoots().map((r) => r.endsWith(path18__default.sep) ? r : r + path18__default.sep);
222
225
  const isFactoryPath = (p6) => prefixes.some((fp) => p6 === fp.slice(0, -1) || p6.startsWith(fp));
223
226
  try {
224
227
  const entries = await new AssetManager({ registry: getKindRegistry(), projectDir }).search(
@@ -269,12 +272,70 @@ async function expandLibraryCopies(entries, projectDir) {
269
272
  }
270
273
  return out;
271
274
  }
275
+ function originAtVersion(o) {
276
+ return `${describeOrigin(o)}${o.version ? ` v${o.version}` : ""}`;
277
+ }
278
+ async function competingOriginsOf(am2, target) {
279
+ let ref;
280
+ if (typeof target === "string") {
281
+ if (target.includes("#")) return void 0;
282
+ ref = target;
283
+ } else {
284
+ const publisher = (target.canonicalRef ? parseRefTolerant(target.canonicalRef)?.publisher : void 0) ?? target.publisher;
285
+ if (!publisher) return void 0;
286
+ ref = `${target.kind}:@${publisher}/${target.name}`;
287
+ }
288
+ try {
289
+ const origins = await am2.refOrigins(ref);
290
+ return new Set(origins.map((o) => o.version)).size > 1 ? origins : void 0;
291
+ } catch {
292
+ return void 0;
293
+ }
294
+ }
295
+ function describeOrigin(o) {
296
+ return o.kind === "factory" ? "factory" : `${o.kind} ${o.label}`;
297
+ }
298
+ async function expandCompetingOrigins(entries, projectDir) {
299
+ if (entries.length === 0) return entries;
300
+ let competing;
301
+ try {
302
+ competing = await new AssetManager({
303
+ registry: getKindRegistry(),
304
+ projectDir
305
+ }).competingOrigins();
306
+ } catch {
307
+ return entries;
308
+ }
309
+ if (competing.size === 0) return entries;
310
+ const out = [];
311
+ const expanded = /* @__PURE__ */ new Set();
312
+ for (const e of entries) {
313
+ const key = entryDedupKey(e);
314
+ const origins = competing.get(key);
315
+ if (!origins) {
316
+ out.push(e);
317
+ continue;
318
+ }
319
+ if (expanded.has(key)) continue;
320
+ expanded.add(key);
321
+ origins.forEach((o, i) => {
322
+ out.push({
323
+ ...e,
324
+ version: o.version,
325
+ description: o.description || e.description,
326
+ library: describeOrigin(o),
327
+ usedByAdd: i === 0
328
+ });
329
+ });
330
+ }
331
+ return out;
332
+ }
272
333
  async function searchLocal(query, kind, opts, showStore, airGapped) {
273
- const projectDir = path23__default.resolve(opts.projectDir);
334
+ const projectDir = path18__default.resolve(opts.projectDir);
274
335
  const factory = await searchFactory(projectDir, query, kind);
275
336
  let entries = unionEntries(await searchIndex(query, kind), factory);
276
337
  if (entries.length === 0 && !query && !kind && !airGapped) {
277
- const { autoSyncForSearch } = await import('../source-LKOFTOEK.js');
338
+ const { autoSyncForSearch } = await import('../source-E4VAT5RZ.js');
278
339
  if (await autoSyncForSearch(projectDir)) {
279
340
  entries = unionEntries(await searchIndex(query, kind), factory);
280
341
  }
@@ -291,7 +352,9 @@ async function searchLocal(query, kind, opts, showStore, airGapped) {
291
352
  console.log(`
292
353
  ${S.heading("Local:")}`);
293
354
  }
294
- printLocalEntries(await expandLibraryCopies(entries, projectDir));
355
+ printLocalEntries(
356
+ await expandCompetingOrigins(await expandLibraryCopies(entries, projectDir), projectDir)
357
+ );
295
358
  }
296
359
  var MIN_LOCAL_DESCRIPTION_WIDTH = 10;
297
360
  function layoutLocalTable(rows, width, style = {}) {
@@ -392,9 +455,9 @@ async function searchStore(query, kind, opts, airGapped) {
392
455
  logInfo("air-gapped (cache_ttl: 0) \u2014 local sources only");
393
456
  return;
394
457
  }
395
- const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-OG457THY.js');
458
+ const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-4QSUORI6.js');
396
459
  try {
397
- const remote = await openCatalogSource2({ projectDir: path23__default.resolve(opts.projectDir) });
460
+ const remote = await openCatalogSource2({ projectDir: path18__default.resolve(opts.projectDir) });
398
461
  const assets = await remote.listAssets(kind ? { kind } : {});
399
462
  const results = filterCatalogAssets(assets, query);
400
463
  if (results.length > 0) {
@@ -515,10 +578,17 @@ function makeAddCommand() {
515
578
  process.exit(1);
516
579
  }
517
580
  const harnesses = parseHarnessFilter(opts.harness);
581
+ if (!opts.global && harnesses === void 0) {
582
+ const projectDir = path18__default.resolve(opts.projectDir);
583
+ if (!existsSync(path18__default.join(projectDir, SKAILE_YAML_DEFAULT))) {
584
+ logErr(`No ${S.cmd("skaile.yaml")} found. Run ${S.cmd("skaile init")} to create one.`);
585
+ process.exit(1);
586
+ }
587
+ }
518
588
  const warnings = deferredWarnings();
519
589
  const am2 = new AssetManager({
520
590
  registry: getKindRegistry(),
521
- projectDir: path23__default.resolve(opts.projectDir),
591
+ projectDir: path18__default.resolve(opts.projectDir),
522
592
  global: opts.global || harnesses !== void 0,
523
593
  harnesses,
524
594
  driverTarget: opts.target,
@@ -529,11 +599,18 @@ function makeAddCommand() {
529
599
  try {
530
600
  const libraryOf = /* @__PURE__ */ new Map();
531
601
  let presets = [];
602
+ const skippedLinks = /* @__PURE__ */ new Set();
532
603
  const added = await am2.add(ref, {
533
604
  link: opts.link,
534
605
  onLibraryOrigin: (deployedRef, library) => libraryOf.set(deployedRef, library),
535
606
  onPresets: (expanded) => {
536
607
  presets = expanded;
608
+ },
609
+ // One line per dropped link, however many harnesses the asset is deployed into.
610
+ onSkippedSymlink: (_assetRef, linkPath) => {
611
+ if (skippedLinks.has(linkPath)) return;
612
+ skippedLinks.add(linkPath);
613
+ warnings.push(`skipped symlink ${linkPath}`);
537
614
  }
538
615
  });
539
616
  spinner.stop("Done");
@@ -564,6 +641,15 @@ function makeAddCommand() {
564
641
  logOk(library ? `${a} (library ${library})` : a);
565
642
  }
566
643
  }
644
+ const addOrigins = await competingOriginsOf(am2, ref);
645
+ if (addOrigins) {
646
+ const [first, ...rest] = addOrigins;
647
+ logInfo(
648
+ S.dim(
649
+ `${ref} is held at different versions; used ${originAtVersion(first)} (also ${rest.map(originAtVersion).join(", ")})`
650
+ )
651
+ );
652
+ }
567
653
  await reportPresetMembership(am2, ref, (line) => logInfo(S.dim(line)));
568
654
  } catch (err2) {
569
655
  spinner.stop("Failed");
@@ -577,23 +663,31 @@ function makeRemoveCommand() {
577
663
  return new Command("remove").description("Remove from skaile.yaml + undeploy").argument("<ref>", "Asset reference (kind:@publisher/name, or kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Remove from ~/.skaile/skaile.yaml + undeploy from every global harness").option(
578
664
  "--harness <ids>",
579
665
  "Comma-separated global harnesses to undeploy from (default: all resolved); implies --global"
580
- ).option("--target <agent>", `Driver target (${TARGET_DEFAULT_HINT})`).option("--no-soft-deps", "skip the orphaned-soft-dep prompt (don't remove, don't report)").action(async (ref, opts) => {
666
+ ).option("--target <agent>", `Driver target (${TARGET_DEFAULT_HINT})`).option("--force", "Remove even when another installed asset requires it").option("--no-soft-deps", "skip the orphaned-soft-dep prompt (don't remove, don't report)").action(async (ref, opts) => {
581
667
  const harnesses = parseHarnessFilter(opts.harness);
582
668
  const am2 = new AssetManager({
583
669
  registry: getKindRegistry(),
584
- projectDir: path23__default.resolve(opts.projectDir),
670
+ projectDir: path18__default.resolve(opts.projectDir),
585
671
  global: opts.global || harnesses !== void 0,
586
672
  harnesses,
587
673
  driverTarget: opts.target
588
674
  });
589
675
  let result;
590
676
  try {
591
- result = await am2.removeWithDependencies(ref);
677
+ result = await am2.removeWithDependencies(ref, { force: opts.force === true });
592
678
  } catch (err2) {
593
679
  logErr(err2 instanceof Error ? err2.message : String(err2));
594
680
  process.exitCode = 1;
595
681
  return;
596
682
  }
683
+ if (result.blocked) {
684
+ logWarn(`${result.blocked.ref} is required by ${result.blocked.requiredBy.join(", ")}`);
685
+ logInfo(
686
+ `Nothing removed. Remove ${result.blocked.requiredBy.length === 1 ? "that asset" : "those assets"} first, or run \`skaile remove ${ref} --force\`.`
687
+ );
688
+ process.exitCode = 1;
689
+ return;
690
+ }
597
691
  if (!result.changed) {
598
692
  logErr(`Not deployed or declared: ${ref}`);
599
693
  process.exitCode = 1;
@@ -635,7 +729,7 @@ function makeListCommand() {
635
729
  }
636
730
  const am2 = new AssetManager({
637
731
  registry: getKindRegistry(),
638
- projectDir: path23__default.resolve(opts.projectDir),
732
+ projectDir: path18__default.resolve(opts.projectDir),
639
733
  driverTarget: opts.target
640
734
  });
641
735
  let declared;
@@ -683,7 +777,7 @@ function makeListCommand() {
683
777
  function runGlobalList(kind, opts, harnesses) {
684
778
  const am2 = new AssetManager({
685
779
  registry: getKindRegistry(),
686
- projectDir: path23__default.resolve(opts.projectDir),
780
+ projectDir: path18__default.resolve(opts.projectDir),
687
781
  global: true,
688
782
  harnesses
689
783
  });
@@ -756,7 +850,7 @@ async function resolveInfoEntry(am2, ref, opts) {
756
850
  return { entry: match ?? deployed };
757
851
  }
758
852
  const lookup = opts.storeLookup ?? (async (filter) => {
759
- const { resolveCatalogSource } = await import('../open-library-OG457THY.js');
853
+ const { resolveCatalogSource } = await import('../open-library-4QSUORI6.js');
760
854
  const { source, close } = await resolveCatalogSource({ projectDir: opts.projectDir });
761
855
  try {
762
856
  return await source.listAssets(filter);
@@ -772,7 +866,7 @@ async function resolveInfoEntry(am2, ref, opts) {
772
866
  );
773
867
  return { entry: hit ? catalogAssetToEntry(hit) : null };
774
868
  } catch (err2) {
775
- const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-OG457THY.js');
869
+ const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-4QSUORI6.js');
776
870
  const storeNote = err2 instanceof Error ? err2.message : String(err2);
777
871
  const disabled = err2 instanceof LocalCatalogDisabledError2 || /catalog\.url/i.test(storeNote);
778
872
  return { entry: null, storeNote, ...disabled ? { storeDisabled: true } : {} };
@@ -788,7 +882,7 @@ function infoNotFoundHint(ref, lookup) {
788
882
  }
789
883
  function makeInfoCommand() {
790
884
  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) => {
791
- const projectDir = path23__default.resolve(opts.projectDir);
885
+ const projectDir = path18__default.resolve(opts.projectDir);
792
886
  const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
793
887
  const lookup = await resolveInfoEntry(am2, ref, { projectDir });
794
888
  const entry = lookup.entry;
@@ -805,9 +899,20 @@ function makeInfoCommand() {
805
899
  if (entry.description) console.log(` description: ${entry.description}`);
806
900
  if (entry.publisher) console.log(` repository: ${S.dim(entry.publisher)}`);
807
901
  console.log(` source: ${S.dim(entry.source)}`);
808
- if (entry.requires.length) {
902
+ const infoOrigins = await competingOriginsOf(am2, entry);
903
+ if (infoOrigins) {
904
+ const [first, ...rest] = infoOrigins;
905
+ console.log(
906
+ ` origin: ${describeOrigin(first)} (used by add; also ${rest.map(originAtVersion).join(", ")})`
907
+ );
908
+ }
909
+ const ownPublisher = (entry.canonicalRef ? parseRefTolerant(entry.canonicalRef)?.publisher : void 0) ?? entry.publisher;
910
+ const requirements = dedupeRequirements(entry.requires, ownPublisher).map(
911
+ (d) => d.publisher || !ownPublisher ? d : { ...d, publisher: ownPublisher }
912
+ );
913
+ if (requirements.length) {
809
914
  console.log(` requires:`);
810
- for (const d of entry.requires) {
915
+ for (const d of requirements) {
811
916
  const scope = d.publisher ? `@${d.publisher}/` : "";
812
917
  console.log(` ${S.dim("\xB7")} ${kindColor(d.kind)}:${scope}${d.name}`);
813
918
  }
@@ -826,7 +931,7 @@ function makeCreateCommand() {
826
931
  new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...SCAFFOLD_KINDS])
827
932
  ).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
828
933
  const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
829
- const destDir = opts.dir ? path23__default.resolve(opts.dir) : process.cwd();
934
+ const destDir = opts.dir ? path18__default.resolve(opts.dir) : process.cwd();
830
935
  const result = am2.create(name, opts.kind, destDir);
831
936
  if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
832
937
  else {
@@ -839,20 +944,16 @@ function makeDoctorCommand() {
839
944
  return new Command("doctor").description("Scan for missing dependency chains").argument("[name]", "Check a specific asset (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (name, opts) => {
840
945
  const am2 = new AssetManager({
841
946
  registry: getKindRegistry(),
842
- projectDir: path23__default.resolve(opts.projectDir)
947
+ projectDir: path18__default.resolve(opts.projectDir)
843
948
  });
844
- const issues = await am2.doctor();
845
- if (issues.length === 0) {
949
+ const { gaps, requirements } = await am2.projectState();
950
+ if (gaps.length === 0) {
846
951
  logOk("No missing dependencies.");
847
952
  return;
848
953
  }
849
- const unresolved = issues.filter((i) => i.unresolved);
850
- const missing = issues.filter((i) => !i.unresolved);
851
- for (const i of unresolved) {
852
- logErr(
853
- `${i.assetKind}:${i.assetName}: locked, but no source or library provides it \u2014 ${i.fix ?? "run skaile install"}`
854
- );
855
- }
954
+ process.exitCode = 1;
955
+ for (const g of gaps) if (g.type !== "requires") logErr(g.message);
956
+ const missing = requirements.filter((i) => !i.unresolved);
856
957
  if (missing.length === 0) return;
857
958
  const assetW = Math.max(5, ...missing.map((i) => `${i.assetKind}:${i.assetName}`.length));
858
959
  const depW = Math.max(11, ...missing.map((i) => `${i.depKind}:${i.depName}`.length));
@@ -870,180 +971,27 @@ function makeDoctorCommand() {
870
971
  console.log();
871
972
  });
872
973
  }
873
- function manifestRequiresProblems(dir) {
874
- const file = path23.join(dir, "skaile.manifest.yaml");
875
- let doc;
876
- try {
877
- doc = parse(fs9.readFileSync(file, "utf-8"));
878
- } catch {
879
- return [];
880
- }
881
- const assets = doc?.assets;
882
- if (!Array.isArray(assets)) return [];
883
- const problems = [];
884
- for (const a of assets) {
885
- if (!a || typeof a !== "object") continue;
886
- const { kind, name, dependencies } = a;
887
- if (!Array.isArray(dependencies)) continue;
888
- const entries = dependencies.map((d) => typeof d === "string" ? d : String(d));
889
- for (const message of requiresSyntaxErrors(entries)) {
890
- problems.push({
891
- asset: `${String(kind)}:${String(name)}`,
892
- message: `ManifestRequiresError: ${message}`
893
- });
894
- }
895
- }
896
- return problems;
897
- }
898
- async function indexLibrary(lib, index, opts = {}) {
899
- const { LocalCatalogSource } = await import('../library/index.js');
900
- const own = index ?? await openLibrary();
901
- try {
902
- const source = new LocalCatalogSource(own, lib.id, lib.path, getKindRegistry());
903
- const res = await source.sync({ exclude: opts.exclude });
904
- return {
905
- assetsFound: res.assetsFound,
906
- assetsUpdated: res.assetsUpdated,
907
- errors: res.errors
908
- };
909
- } finally {
910
- if (!index) own.close();
911
- }
912
- }
913
- function resolveLibraryPublisherDetailed(lib, opts, storeIdentity) {
914
- const bare = (p6) => p6.startsWith("@") ? p6.slice(1) : p6;
915
- if (opts.publisher?.trim()) return { publisher: bare(opts.publisher.trim()), source: "flag" };
916
- const declared = loadSkPublishManifest(lib.path)?.publisher?.trim();
917
- if (declared) return { publisher: bare(declared), source: "manifest" };
918
- const identity = (storeIdentity?.githubLogin ?? storeIdentity?.username)?.trim();
919
- if (identity) return { publisher: identity, source: "identity" };
920
- try {
921
- return { publisher: slugifyAssetName(lib.name), source: "library-name" };
922
- } catch {
923
- return { publisher: "library", source: "library-name" };
924
- }
925
- }
926
- function warnLibraryNameFallback(libName, resolved) {
927
- if (resolved.source !== "library-name") return;
928
- logWarn(
929
- `No publisher given and not signed in \u2014 using the library name "${resolved.publisher}" as the publisher. Pass --publisher <name> or run \`skaile store login\`; change it later with \`skaile library set ${libName} publisher=<name>\`.`
930
- );
931
- }
932
- function normalizeAssetFrontmatter(assetDir) {
933
- let markerFile = ["SKILL.md", "AGENT.md", "CONTRACT.md"].map((m) => path23.join(assetDir, m)).find((f) => fs9.existsSync(f));
934
- if (!markerFile) {
935
- const promptMd = fs9.readdirSync(assetDir).find((f) => f.endsWith(".prompt.md"));
936
- if (promptMd) markerFile = path23.join(assetDir, promptMd);
937
- }
938
- if (!markerFile) return;
939
- try {
940
- const { data, body } = parseFrontmatter(fs9.readFileSync(markerFile, "utf8"));
941
- const fm = stringify(data).trimEnd();
942
- fs9.writeFileSync(markerFile, `---
943
- ${fm}
944
- ---
945
-
946
- ${body}
947
- `, "utf8");
948
- } catch {
949
- }
950
- }
951
- async function registerLibraryAsset(lib, index, input) {
952
- const { publisher, source } = resolveLibraryPublisherDetailed(
953
- lib,
954
- { publisher: input.publisher },
955
- getStoreIdentity()
956
- );
957
- warnLibraryNameFallback(lib.name, { publisher, source });
958
- normalizeAssetFrontmatter(input.assetDir);
959
- stampManifestPublisher(lib.path, publisher);
960
- upsertManifestAsset(lib.path, {
961
- kind: input.kind,
962
- name: input.name,
963
- root: path23.relative(lib.path, input.assetDir) || input.name,
964
- version: input.version,
965
- publisher
966
- });
967
- const idx = await indexLibrary(lib, index);
968
- for (const e of idx.errors) logWarn(e);
969
- return { publisher, ref: refFor(input.kind, publisher, input.name, input.version) };
970
- }
971
- var LIBRARY_UPGRADE_DOCS = "https://github.com/skaile-ai/workspaces/blob/main/docs/sections/cli/commands/library.md#upgrading-a-4x-library";
972
- var DOMAIN_REMOVED_HINT = `Domains were removed in 5.0 \u2014 delete DOMAIN.md files; group assets with .claude-plugin/marketplace.json. See ${LIBRARY_UPGRADE_DOCS}`;
973
- function removedDomainOption() {
974
- return new Option("--domain <domain>", "Removed in 5.0").hideHelp();
975
- }
976
- function rejectRemovedDomainOption(opts) {
977
- if (opts.domain === void 0) return;
978
- logErr(DOMAIN_REMOVED_HINT);
979
- process.exit(1);
980
- }
981
- function findFiles(root, match) {
982
- const found = [];
983
- const walk = (dir) => {
984
- let entries;
985
- try {
986
- entries = fs9.readdirSync(dir, { withFileTypes: true });
987
- } catch {
988
- return;
989
- }
990
- for (const entry of entries) {
991
- if (entry.isDirectory()) {
992
- if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
993
- walk(path23.join(dir, entry.name));
994
- }
995
- } else if (match(entry.name)) {
996
- found.push(path23.join(dir, entry.name));
997
- }
998
- }
999
- };
1000
- walk(root);
1001
- return found;
1002
- }
1003
- function countDomainFiles(root) {
1004
- return findFiles(root, (name) => name === "DOMAIN.md").length;
1005
- }
1006
- function warnIgnoredDomainFiles(root) {
1007
- const count = countDomainFiles(root);
1008
- if (count > 0) {
1009
- logWarn(
1010
- `${count} DOMAIN.md file(s) are ignored since 5.0 (domains were removed) \u2014 delete them; group assets with .claude-plugin/marketplace.json. See ${LIBRARY_UPGRADE_DOCS}`
1011
- );
1012
- }
1013
- return count;
1014
- }
1015
- function warnLegacyBundleFiles(root) {
1016
- const files = findFiles(root, (name) => name.endsWith(".bundle.yaml"));
1017
- if (files.length > 0) {
1018
- const shown = files.slice(0, 5).map((f) => path23.relative(root, f) || f);
1019
- const more = files.length > shown.length ? `, +${files.length - shown.length} more` : "";
1020
- logWarn(
1021
- `${files.length} *.bundle.yaml file(s) are not scanned (the bundle kind became preset): ${shown.join(", ")}${more}. Run \`skaile migrate assets ${root} --write\` to rename them to *.preset.yaml. See ${LIBRARY_UPGRADE_DOCS}`
1022
- );
1023
- }
1024
- return files.length;
1025
- }
1026
974
  var DEFAULT_IMPORT_VERSION = "0.1.0";
1027
975
  var DEFAULT_IMPORT_STAGE = "alpha";
1028
976
  function claudeSkillRoots() {
1029
977
  const roots = [];
1030
978
  const override = process.env.SKAILE_CLAUDE_SKILLS_DIR;
1031
979
  if (override) roots.push(override);
1032
- roots.push(path23.join(os.homedir(), ".claude", "skills"));
980
+ roots.push(path18.join(os.homedir(), ".claude", "skills"));
1033
981
  return roots;
1034
982
  }
1035
983
  function resolveImportSource(nameOrPath) {
1036
- const asPath = path23.resolve(nameOrPath);
1037
- if (fs9.existsSync(asPath)) {
1038
- const dir = fs9.statSync(asPath).isDirectory() ? asPath : path23.dirname(asPath);
1039
- const skillFile = path23.join(dir, "SKILL.md");
1040
- if (fs9.existsSync(skillFile)) return { dir, skillFile, via: "path" };
984
+ const asPath = path18.resolve(nameOrPath);
985
+ if (fs8.existsSync(asPath)) {
986
+ const dir = fs8.statSync(asPath).isDirectory() ? asPath : path18.dirname(asPath);
987
+ const skillFile = path18.join(dir, "SKILL.md");
988
+ if (fs8.existsSync(skillFile)) return { dir, skillFile, via: "path" };
1041
989
  }
1042
- if (!nameOrPath.includes(path23.sep) && !nameOrPath.startsWith(".")) {
990
+ if (!nameOrPath.includes(path18.sep) && !nameOrPath.startsWith(".")) {
1043
991
  for (const root of claudeSkillRoots()) {
1044
- const dir = path23.join(root, nameOrPath);
1045
- const skillFile = path23.join(dir, "SKILL.md");
1046
- if (fs9.existsSync(skillFile)) return { dir, skillFile, via: "claude-skills" };
992
+ const dir = path18.join(root, nameOrPath);
993
+ const skillFile = path18.join(dir, "SKILL.md");
994
+ if (fs8.existsSync(skillFile)) return { dir, skillFile, via: "claude-skills" };
1047
995
  }
1048
996
  }
1049
997
  return null;
@@ -1139,13 +1087,7 @@ function makeAssetCommand() {
1139
1087
  ).option("--commit", "Auto-commit in git-backed libraries", false).action(
1140
1088
  async (nameOrPath, opts) => {
1141
1089
  rejectRemovedDomainOption(opts);
1142
- if (opts.publisher !== void 0) {
1143
- const bare = opts.publisher.trim().replace(/^@/, "");
1144
- if (!isValidPublisher(bare)) {
1145
- logErr(`Invalid publisher "${opts.publisher}": ${PUBLISHER_HINT}.`);
1146
- process.exit(1);
1147
- }
1148
- }
1090
+ if (opts.publisher !== void 0) requireValidPublisherOrExit(opts.publisher);
1149
1091
  const src = resolveImportSource(nameOrPath);
1150
1092
  if (!src) {
1151
1093
  logErr(
@@ -1175,19 +1117,20 @@ function makeAssetCommand() {
1175
1117
  logErr(err2 instanceof Error ? err2.message : String(err2));
1176
1118
  process.exit(1);
1177
1119
  }
1178
- const rawSkill = fs9.readFileSync(src.skillFile, "utf8");
1120
+ exitOnManifestPublisherProblems(target.path, target.name);
1121
+ const rawSkill = fs8.readFileSync(src.skillFile, "utf8");
1179
1122
  const norm = opts.normalize ? normalizeSkillContent(rawSkill, {
1180
- fallbackName: path23.basename(src.dir),
1123
+ fallbackName: path18.basename(src.dir),
1181
1124
  version: opts.version,
1182
1125
  stage: opts.stage
1183
- }) : { content: rawSkill, name: path23.basename(src.dir), changed: false, notes: [] };
1126
+ }) : { content: rawSkill, name: path18.basename(src.dir), changed: false, notes: [] };
1184
1127
  if (!opts.normalize && !isValidAssetName(norm.name)) {
1185
1128
  logWarn(
1186
1129
  `Name "${norm.name}" is not canonical (kebab-case); \`skaile validate\` will reject this manifest entry. Drop --no-normalize to slugify it.`
1187
1130
  );
1188
1131
  }
1189
- const destDir = path23.join(target.path, norm.name);
1190
- if (fs9.existsSync(destDir)) {
1132
+ const destDir = path18.join(target.path, norm.name);
1133
+ if (fs8.existsSync(destDir)) {
1191
1134
  logErr(`Destination already exists: ${destDir}`);
1192
1135
  process.exit(1);
1193
1136
  }
@@ -1198,8 +1141,8 @@ function makeAssetCommand() {
1198
1141
  );
1199
1142
  process.exit(1);
1200
1143
  }
1201
- fs9.cpSync(src.dir, destDir, { recursive: true });
1202
- fs9.writeFileSync(path23.join(destDir, "SKILL.md"), norm.content, "utf8");
1144
+ fs8.cpSync(src.dir, destDir, { recursive: true });
1145
+ fs8.writeFileSync(path18.join(destDir, "SKILL.md"), norm.content, "utf8");
1203
1146
  for (const note of norm.notes) logInfo(` \u2022 ${note}`);
1204
1147
  const fm = parseFrontmatter(norm.content).data;
1205
1148
  for (const f of checkAgentSkillConformance(fm, { dirName: norm.name })) {
@@ -1239,7 +1182,7 @@ function makeAssetCommand() {
1239
1182
  logErr(`Invalid --mode "${opts.mode}". Expected: copy | move | link.`);
1240
1183
  process.exit(1);
1241
1184
  }
1242
- if (!fs9.existsSync(srcPath)) {
1185
+ if (!fs8.existsSync(srcPath)) {
1243
1186
  logErr(`Source path does not exist: ${srcPath}`);
1244
1187
  process.exit(1);
1245
1188
  }
@@ -1265,23 +1208,23 @@ function makeAssetCommand() {
1265
1208
  );
1266
1209
  process.exit(1);
1267
1210
  }
1268
- const basename3 = path23.basename(srcPath);
1211
+ const basename3 = path18.basename(srcPath);
1269
1212
  const destDir = target.path;
1270
- fs9.mkdirSync(destDir, { recursive: true });
1271
- const destPath = path23.join(destDir, basename3);
1272
- if (fs9.existsSync(destPath)) {
1213
+ fs8.mkdirSync(destDir, { recursive: true });
1214
+ const destPath = path18.join(destDir, basename3);
1215
+ if (fs8.existsSync(destPath)) {
1273
1216
  logErr(`Destination already exists: ${destPath}`);
1274
1217
  process.exit(1);
1275
1218
  }
1276
1219
  switch (opts.mode) {
1277
1220
  case "copy":
1278
- fs9.cpSync(srcPath, destPath, { recursive: true });
1221
+ fs8.cpSync(srcPath, destPath, { recursive: true });
1279
1222
  break;
1280
1223
  case "move":
1281
- fs9.renameSync(srcPath, destPath);
1224
+ fs8.renameSync(srcPath, destPath);
1282
1225
  break;
1283
1226
  case "link":
1284
- fs9.symlinkSync(path23.resolve(srcPath), destPath);
1227
+ fs8.symlinkSync(path18.resolve(srcPath), destPath);
1285
1228
  break;
1286
1229
  }
1287
1230
  if (target.backend === "git" && opts.commit) {
@@ -1411,14 +1354,14 @@ function makeAuthCommand() {
1411
1354
  }
1412
1355
  function collectCacheTargets(scope) {
1413
1356
  const out = [];
1414
- out.push(path23__default.join(scope.projectDir, ".skaile", "cache"));
1415
- out.push(path23__default.join(scope.projectDir, ".skaile", "store-cache"));
1416
- out.push(path23__default.join(scope.projectDir, ".skaile", "repos"));
1357
+ out.push(path18__default.join(scope.projectDir, ".skaile", "cache"));
1358
+ out.push(path18__default.join(scope.projectDir, ".skaile", "store-cache"));
1359
+ out.push(path18__default.join(scope.projectDir, ".skaile", "repos"));
1417
1360
  if (scope.global) {
1418
1361
  out.push(globalCacheRoot());
1419
1362
  const home = globalSkaileDir();
1420
- out.push(path23__default.join(home, "repos"));
1421
- out.push(path23__default.join(home, "catalog-cache"));
1363
+ out.push(path18__default.join(home, "repos"));
1364
+ out.push(path18__default.join(home, "catalog-cache"));
1422
1365
  }
1423
1366
  return out;
1424
1367
  }
@@ -1432,7 +1375,7 @@ function dirSize(target) {
1432
1375
  function dirSizeOfDir(dir) {
1433
1376
  let total = 0;
1434
1377
  for (const ent of readdirSync(dir, { withFileTypes: true })) {
1435
- const child = path23__default.join(dir, ent.name);
1378
+ const child = path18__default.join(dir, ent.name);
1436
1379
  if (ent.isSymbolicLink()) continue;
1437
1380
  if (ent.isDirectory()) total += dirSizeOfDir(child);
1438
1381
  else if (ent.isFile()) total += statSync(child).size;
@@ -1458,7 +1401,7 @@ function makeCacheCommand() {
1458
1401
  const cmd = new Command("cache").description("Inspect and reclaim the re-derivable cache");
1459
1402
  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) => {
1460
1403
  const targets = collectCacheTargets({
1461
- projectDir: path23__default.resolve(opts.projectDir),
1404
+ projectDir: path18__default.resolve(opts.projectDir),
1462
1405
  global: opts.global
1463
1406
  }).filter((t) => existsSync(t));
1464
1407
  if (targets.length === 0) {
@@ -1488,12 +1431,12 @@ function makeCacheCommand() {
1488
1431
  for (const r of removed) logOk(`Removed ${r}`);
1489
1432
  });
1490
1433
  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) => {
1491
- console.log(path23__default.join(path23__default.resolve(opts.projectDir), ".skaile", "cache"));
1434
+ console.log(path18__default.join(path18__default.resolve(opts.projectDir), ".skaile", "cache"));
1492
1435
  if (opts.global) console.log(globalCacheRoot());
1493
1436
  });
1494
1437
  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) => {
1495
1438
  const targets = collectCacheTargets({
1496
- projectDir: path23__default.resolve(opts.projectDir),
1439
+ projectDir: path18__default.resolve(opts.projectDir),
1497
1440
  global: opts.global
1498
1441
  });
1499
1442
  console.log();
@@ -1509,7 +1452,7 @@ function makeCatalogCommand() {
1509
1452
  const catalog = new Command("catalog").description("Catalog source health and configuration");
1510
1453
  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) => {
1511
1454
  const { resolveConfig, isLocalCatalogUrl, trpcGetUrl } = await import('../library/index.js');
1512
- const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : void 0;
1455
+ const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : void 0;
1513
1456
  const cfg = resolveConfig({ projectDir });
1514
1457
  const baseUrl = opts.url ?? cfg.catalog.url;
1515
1458
  if (isLocalCatalogUrl(baseUrl)) {
@@ -1527,7 +1470,7 @@ function makeCatalogCommand() {
1527
1470
  });
1528
1471
  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) => {
1529
1472
  const { resolveConfig } = await import('../library/index.js');
1530
- const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : void 0;
1473
+ const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : void 0;
1531
1474
  const cfg = resolveConfig({ projectDir });
1532
1475
  console.log(`url: ${cfg.catalog.url}`);
1533
1476
  console.log(`framing: ${cfg.catalog.framing}`);
@@ -1536,7 +1479,7 @@ function makeCatalogCommand() {
1536
1479
  return catalog;
1537
1480
  }
1538
1481
  async function runLocalCatalogTest(projectDir) {
1539
- const { resolveCatalogSource } = await import('../open-library-OG457THY.js');
1482
+ const { resolveCatalogSource } = await import('../open-library-4QSUORI6.js');
1540
1483
  let resolved;
1541
1484
  try {
1542
1485
  resolved = await resolveCatalogSource({ projectDir });
@@ -1679,7 +1622,7 @@ async function scanLibraryFlowEntries() {
1679
1622
  const { LocalIndex, resolveIndexPath, scanAuthoringLibraries } = await import('../library/index.js');
1680
1623
  const indexPath = resolveIndexPath();
1681
1624
  if (!existsSync(indexPath)) return entries;
1682
- const { getKindRegistry: getKindRegistry2 } = await import('../open-registry-ZUZJ7MS7.js');
1625
+ const { getKindRegistry: getKindRegistry2 } = await import('../open-registry-VCKS3MP5.js');
1683
1626
  const index = new LocalIndex({ indexPath });
1684
1627
  try {
1685
1628
  for (const { assets } of await scanAuthoringLibraries(index, getKindRegistry2())) {
@@ -1729,11 +1672,11 @@ function findSkills() {
1729
1672
  return deduped;
1730
1673
  }
1731
1674
  function walkSkills(dir, out) {
1732
- for (const entry of fs9__default.readdirSync(dir, { withFileTypes: true })) {
1733
- const full = path23__default.join(dir, entry.name);
1675
+ for (const entry of fs8__default.readdirSync(dir, { withFileTypes: true })) {
1676
+ const full = path18__default.join(dir, entry.name);
1734
1677
  if (entry.isDirectory()) {
1735
- const skillMd = path23__default.join(full, "SKILL.md");
1736
- if (fs9__default.existsSync(skillMd)) {
1678
+ const skillMd = path18__default.join(full, "SKILL.md");
1679
+ if (fs8__default.existsSync(skillMd)) {
1737
1680
  out.push({ name: entry.name, path: full, skillPath: skillMd });
1738
1681
  } else {
1739
1682
  walkSkills(full, out);
@@ -1754,10 +1697,10 @@ function resolveFlowIds() {
1754
1697
  }
1755
1698
  }
1756
1699
  function resolveSessionIds(projectDir) {
1757
- const sessionsDir = path23__default.join(projectDir, ".skaile", "sessions");
1758
- if (!fs9__default.existsSync(sessionsDir)) return [];
1700
+ const sessionsDir = path18__default.join(projectDir, ".skaile", "sessions");
1701
+ if (!fs8__default.existsSync(sessionsDir)) return [];
1759
1702
  try {
1760
- return fs9__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
1703
+ return fs8__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
1761
1704
  } catch {
1762
1705
  return [];
1763
1706
  }
@@ -1896,7 +1839,7 @@ function printResolvedPathsSection(config) {
1896
1839
  console.log(` ${S.label("prompts:".padEnd(16))} ${config.promptsDir ?? paths.promptsDir}`);
1897
1840
  }
1898
1841
  async function showConfig(opts) {
1899
- const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
1842
+ const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
1900
1843
  let config;
1901
1844
  let wsDefaults;
1902
1845
  try {
@@ -1941,13 +1884,13 @@ function makeConfigCommand() {
1941
1884
  const cmd = new Command("config").description("Manage personal config (.skaile/settings.json)");
1942
1885
  cmd.command("show").description("Show effective config with sources").option("--project-dir <path>", "Project directory").action((opts) => showConfig(opts));
1943
1886
  cmd.command("get <key>").description("Get an effective config value").option("--project-dir <path>", "Project directory").action(async (key, opts) => {
1944
- const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
1887
+ const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
1945
1888
  const config = await resolveSettings(projectDir);
1946
1889
  const value = config[key];
1947
1890
  console.log(value ?? S.dim("(not set)"));
1948
1891
  });
1949
1892
  cmd.command("set <key> <value>").description("Set a personal config value (driver, model, apiKey.<provider>)").option("--project-dir <path>", "Project directory").option("--global", "Write to ~/.skaile/settings.json instead of project-local").action(async (key, value, opts) => {
1950
- const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
1893
+ const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
1951
1894
  if (key === "provider" || key === "cloud" || key === "cloudConfig") {
1952
1895
  logErr(
1953
1896
  `'${key}' is no longer a setting \u2014 an endpoint is an AI provider registry entry and a session selects one with a model reference.
@@ -2287,8 +2230,8 @@ function makeConnectorCommand() {
2287
2230
  async (driver, opts) => {
2288
2231
  const { installNpmPackages } = await import('../connectors/index.js');
2289
2232
  const { scanDirectory: scanDirectory2, factoryAssetRoots: factoryAssetRoots2, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
2290
- const projectDir = path23__default.resolve(opts.projectDir);
2291
- const yamlPath = path23__default.join(projectDir, "skaile.yaml");
2233
+ const projectDir = path18__default.resolve(opts.projectDir);
2234
+ const yamlPath = path18__default.join(projectDir, "skaile.yaml");
2292
2235
  if (!existsSync(yamlPath)) {
2293
2236
  logErr("No skaile.yaml found in current directory. Run 'skaile init' first.");
2294
2237
  process.exit(1);
@@ -2348,8 +2291,8 @@ ${installResult.output}`);
2348
2291
  );
2349
2292
  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) => {
2350
2293
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
2351
- const projectDir = path23__default.resolve(opts.projectDir);
2352
- const yamlPath = path23__default.join(projectDir, "skaile.yaml");
2294
+ const projectDir = path18__default.resolve(opts.projectDir);
2295
+ const yamlPath = path18__default.join(projectDir, "skaile.yaml");
2353
2296
  if (!existsSync(yamlPath)) {
2354
2297
  logErr("No skaile.yaml found in current directory.");
2355
2298
  process.exit(1);
@@ -2366,7 +2309,7 @@ ${installResult.output}`);
2366
2309
  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) => {
2367
2310
  const res = await import('../connectors/index.js');
2368
2311
  res.registerBuiltinConnectors();
2369
- const projectDir = path23__default.resolve(opts.projectDir);
2312
+ const projectDir = path18__default.resolve(opts.projectDir);
2370
2313
  const declarations = res.loadConnectorDeclarations(projectDir);
2371
2314
  if (declarations.length === 0) {
2372
2315
  console.log("No connectors configured in skaile.yaml.");
@@ -2390,7 +2333,7 @@ ${installResult.output}`);
2390
2333
  await manager.disconnectAll();
2391
2334
  });
2392
2335
  cmd.command("list").description("List all configured connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
2393
- const projectDir = path23__default.resolve(opts.projectDir);
2336
+ const projectDir = path18__default.resolve(opts.projectDir);
2394
2337
  const manager = await connectConnectors(projectDir);
2395
2338
  try {
2396
2339
  console.log(JSON.stringify(manager.listConnectors(), null, 2));
@@ -2399,7 +2342,7 @@ ${installResult.output}`);
2399
2342
  }
2400
2343
  });
2401
2344
  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) => {
2402
- const projectDir = path23__default.resolve(opts.projectDir);
2345
+ const projectDir = path18__default.resolve(opts.projectDir);
2403
2346
  const manager = await connectConnectors(projectDir);
2404
2347
  try {
2405
2348
  if (opts.all) {
@@ -2423,7 +2366,7 @@ ${installResult.output}`);
2423
2366
  }
2424
2367
  });
2425
2368
  cmd.command("ops <id>").description("List available operations for a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
2426
- const projectDir = path23__default.resolve(opts.projectDir);
2369
+ const projectDir = path18__default.resolve(opts.projectDir);
2427
2370
  const manager = await connectConnectors(projectDir);
2428
2371
  try {
2429
2372
  if (!manager.has(id)) {
@@ -2438,7 +2381,7 @@ ${installResult.output}`);
2438
2381
  }
2439
2382
  });
2440
2383
  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) => {
2441
- const projectDir = path23__default.resolve(opts.projectDir);
2384
+ const projectDir = path18__default.resolve(opts.projectDir);
2442
2385
  const manager = await connectConnectors(projectDir);
2443
2386
  try {
2444
2387
  const content = await manager.read(id, resourcePath);
@@ -2448,7 +2391,7 @@ ${installResult.output}`);
2448
2391
  }
2449
2392
  });
2450
2393
  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) => {
2451
- const projectDir = path23__default.resolve(opts.projectDir);
2394
+ const projectDir = path18__default.resolve(opts.projectDir);
2452
2395
  const manager = await connectConnectors(projectDir);
2453
2396
  try {
2454
2397
  await manager.write(id, resourcePath, { data: content });
@@ -2458,7 +2401,7 @@ ${installResult.output}`);
2458
2401
  }
2459
2402
  });
2460
2403
  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) => {
2461
- const projectDir = path23__default.resolve(opts.projectDir);
2404
+ const projectDir = path18__default.resolve(opts.projectDir);
2462
2405
  const manager = await connectConnectors(projectDir);
2463
2406
  try {
2464
2407
  const entries = await manager.list(id, resourcePath, {
@@ -2471,7 +2414,7 @@ ${installResult.output}`);
2471
2414
  }
2472
2415
  });
2473
2416
  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) => {
2474
- const projectDir = path23__default.resolve(opts.projectDir);
2417
+ const projectDir = path18__default.resolve(opts.projectDir);
2475
2418
  const manager = await connectConnectors(projectDir);
2476
2419
  try {
2477
2420
  const results = await manager.search(id, query);
@@ -2481,7 +2424,7 @@ ${installResult.output}`);
2481
2424
  }
2482
2425
  });
2483
2426
  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) => {
2484
- const projectDir = path23__default.resolve(opts.projectDir);
2427
+ const projectDir = path18__default.resolve(opts.projectDir);
2485
2428
  const manager = await connectConnectors(projectDir);
2486
2429
  try {
2487
2430
  const ok = await manager.delete(id, resourcePath);
@@ -2491,7 +2434,7 @@ ${installResult.output}`);
2491
2434
  }
2492
2435
  });
2493
2436
  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) => {
2494
- const projectDir = path23__default.resolve(opts.projectDir);
2437
+ const projectDir = path18__default.resolve(opts.projectDir);
2495
2438
  const manager = await connectConnectors(projectDir);
2496
2439
  try {
2497
2440
  if (!manager.has(id)) {
@@ -2600,7 +2543,7 @@ function envRecord() {
2600
2543
  async function buildDeployContext(projectDir) {
2601
2544
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
2602
2545
  const config = resolveSkWorkspaceConfig2(projectDir);
2603
- const workspaceId = config.name ?? path23__default.basename(projectDir);
2546
+ const workspaceId = config.name ?? path18__default.basename(projectDir);
2604
2547
  let log;
2605
2548
  try {
2606
2549
  const { createLogger } = await import('../core/logging.js');
@@ -2632,13 +2575,13 @@ async function ensureTargetsRegistered(projectDir) {
2632
2575
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
2633
2576
  const config = resolveSkWorkspaceConfig2(projectDir);
2634
2577
  if (config.plugins && config.plugins.length > 0) {
2635
- const { ensurePluginsLoaded } = await import('../plugin-store-MPAMD5OT.js');
2578
+ const { ensurePluginsLoaded } = await import('../plugin-store-X7GPWGBG.js');
2636
2579
  const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
2637
2580
  for (const f of result.failed) logWarn(f.error);
2638
2581
  }
2639
2582
  }
2640
2583
  async function runUp(opts) {
2641
- const projectDir = path23__default.resolve(opts.projectDir);
2584
+ const projectDir = path18__default.resolve(opts.projectDir);
2642
2585
  await ensureTargetsRegistered(projectDir);
2643
2586
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
2644
2587
  const { resolveDeployTarget, pluginRegistry } = await import('../plugin-registry/index.js');
@@ -2706,7 +2649,7 @@ async function restoreFromHandle(projectDir) {
2706
2649
  return { target, handle, ctx };
2707
2650
  }
2708
2651
  async function runDown(opts) {
2709
- const projectDir = path23__default.resolve(opts.projectDir);
2652
+ const projectDir = path18__default.resolve(opts.projectDir);
2710
2653
  const restored = await restoreFromHandle(projectDir);
2711
2654
  if (!restored) return;
2712
2655
  await restored.handle.stop();
@@ -2715,7 +2658,7 @@ async function runDown(opts) {
2715
2658
  logOk(`Stopped ${S.cmd(restored.target.id)} and cleared the handle.`);
2716
2659
  }
2717
2660
  async function runStatus(opts) {
2718
- const projectDir = path23__default.resolve(opts.projectDir);
2661
+ const projectDir = path18__default.resolve(opts.projectDir);
2719
2662
  const restored = await restoreFromHandle(projectDir);
2720
2663
  if (!restored) return;
2721
2664
  const health = await restored.handle.health();
@@ -2729,7 +2672,7 @@ async function runStatus(opts) {
2729
2672
  console.log();
2730
2673
  }
2731
2674
  async function runLogs(opts) {
2732
- const projectDir = path23__default.resolve(opts.projectDir);
2675
+ const projectDir = path18__default.resolve(opts.projectDir);
2733
2676
  const restored = await restoreFromHandle(projectDir);
2734
2677
  if (!restored) return;
2735
2678
  if (!restored.handle.logs) {
@@ -2755,30 +2698,34 @@ function makeDiffCommand() {
2755
2698
  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) => {
2756
2699
  const am2 = new AssetManager({
2757
2700
  registry: getKindRegistry(),
2758
- projectDir: path23__default.resolve(opts.projectDir)
2701
+ projectDir: path18__default.resolve(opts.projectDir)
2759
2702
  });
2760
2703
  const result = await am2.diff(ref);
2704
+ const problems = (await am2.gapsOf(ref)).filter(
2705
+ (g) => !(g.type === "content" && result.status === "differs")
2706
+ );
2761
2707
  switch (result.status) {
2762
2708
  case "not-found":
2763
- logErr(`Asset not found: ${ref}`);
2764
- process.exitCode = 1;
2765
- return;
2709
+ if (problems.length === 0) logErr(`Asset not found: ${ref}`);
2710
+ break;
2766
2711
  case "not-deployed":
2767
- logWarn(`${ref} is not deployed \u2014 run skaile install`);
2768
- return;
2712
+ if (problems.length === 0) logWarn(`${ref} is not deployed \u2014 run skaile install`);
2713
+ break;
2769
2714
  case "identical":
2770
2715
  logInfo("No differences.");
2771
- return;
2716
+ break;
2772
2717
  case "differs":
2773
2718
  console.log(result.diff);
2774
- return;
2719
+ break;
2775
2720
  }
2721
+ for (const g of problems) logErr(g.message);
2722
+ if (result.status === "not-found" || problems.length > 0) process.exitCode = 1;
2776
2723
  });
2777
2724
  }
2778
2725
  function makeFlowCommand() {
2779
2726
  const cmd = new Command("flow").description("Manage flows");
2780
2727
  cmd.command("list").description("List available flows").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
2781
- const flows = await discoverFlowsWithLibraries(path23__default.resolve(opts.projectDir));
2728
+ const flows = await discoverFlowsWithLibraries(path18__default.resolve(opts.projectDir));
2782
2729
  if (flows.length === 0) {
2783
2730
  logInfo("No flows found.");
2784
2731
  return;
@@ -2793,7 +2740,7 @@ function makeFlowCommand() {
2793
2740
  console.log();
2794
2741
  });
2795
2742
  cmd.command("show <id>").description("Show flow details and node graph").option("--project-dir <path>", "Project directory", process.cwd()).action(async (id, opts) => {
2796
- const flows = await discoverFlowsWithLibraries(path23__default.resolve(opts.projectDir));
2743
+ const flows = await discoverFlowsWithLibraries(path18__default.resolve(opts.projectDir));
2797
2744
  const flow = flows.find((f) => f.id === id);
2798
2745
  if (!flow) {
2799
2746
  logErr(`Flow not found: ${id}`);
@@ -2827,7 +2774,7 @@ function makeHistoryCommand() {
2827
2774
  cmd.argument("[limit]", "Number of entries to show", "20").option("--project-dir <path>", "Project directory", process.cwd()).action((limitStr, opts) => {
2828
2775
  const am2 = new AssetManager({
2829
2776
  registry: getKindRegistry(),
2830
- projectDir: path23__default.resolve(opts.projectDir)
2777
+ projectDir: path18__default.resolve(opts.projectDir)
2831
2778
  });
2832
2779
  const limit = parseInt(limitStr, 10) || 20;
2833
2780
  const entries = am2.history(limit);
@@ -2850,7 +2797,7 @@ function makeHistoryCommand() {
2850
2797
  cmd.command("clear").description("Clear action history").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
2851
2798
  const am2 = new AssetManager({
2852
2799
  registry: getKindRegistry(),
2853
- projectDir: path23__default.resolve(opts.projectDir)
2800
+ projectDir: path18__default.resolve(opts.projectDir)
2854
2801
  });
2855
2802
  am2.clearHistory();
2856
2803
  logOk("History cleared.");
@@ -2864,12 +2811,12 @@ var MCP_SERVER_ENTRY = {
2864
2811
  env: {}
2865
2812
  };
2866
2813
  function pluginDir(projectDir) {
2867
- return path23__default.join(projectDir, ".claude", "plugins", "skaile");
2814
+ return path18__default.join(projectDir, ".claude", "plugins", "skaile");
2868
2815
  }
2869
2816
  async function readJsonStrict(p6) {
2870
2817
  let raw;
2871
2818
  try {
2872
- raw = await fs6.readFile(p6, "utf-8");
2819
+ raw = await fs5.readFile(p6, "utf-8");
2873
2820
  } catch {
2874
2821
  return null;
2875
2822
  }
@@ -2882,32 +2829,32 @@ async function readJsonStrict(p6) {
2882
2829
  }
2883
2830
  }
2884
2831
  async function writeJson(p6, value) {
2885
- await fs6.mkdir(path23__default.dirname(p6), { recursive: true });
2886
- await fs6.writeFile(p6, `${JSON.stringify(value, null, 2)}
2832
+ await fs5.mkdir(path18__default.dirname(p6), { recursive: true });
2833
+ await fs5.writeFile(p6, `${JSON.stringify(value, null, 2)}
2887
2834
  `);
2888
2835
  }
2889
2836
  async function copyDir(src, dest) {
2890
- await fs6.mkdir(dest, { recursive: true });
2891
- const entries = await fs6.readdir(src, { withFileTypes: true });
2837
+ await fs5.mkdir(dest, { recursive: true });
2838
+ const entries = await fs5.readdir(src, { withFileTypes: true });
2892
2839
  for (const entry of entries) {
2893
- const srcPath = path23__default.join(src, entry.name);
2894
- const destPath = path23__default.join(dest, entry.name);
2840
+ const srcPath = path18__default.join(src, entry.name);
2841
+ const destPath = path18__default.join(dest, entry.name);
2895
2842
  if (entry.isDirectory()) await copyDir(srcPath, destPath);
2896
- else await fs6.copyFile(srcPath, destPath);
2843
+ else await fs5.copyFile(srcPath, destPath);
2897
2844
  }
2898
2845
  }
2899
2846
  async function install(projectDir, opts) {
2900
2847
  return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);
2901
2848
  }
2902
2849
  async function installMcp(projectDir) {
2903
- const mcpPath = path23__default.join(projectDir, ".claude", "mcp.json");
2850
+ const mcpPath = path18__default.join(projectDir, ".claude", "mcp.json");
2904
2851
  const existing = await readJsonStrict(mcpPath) ?? {};
2905
2852
  const mcpServers = { ...existing.mcpServers ?? {} };
2906
2853
  const previous = mcpServers[SKAILE_MCP_NAME];
2907
2854
  const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);
2908
2855
  let warning;
2909
2856
  if (previous && !matches) {
2910
- warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path23__default.relative(projectDir, mcpPath)}`;
2857
+ warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path18__default.relative(projectDir, mcpPath)}`;
2911
2858
  }
2912
2859
  mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;
2913
2860
  await writeJson(mcpPath, { ...existing, mcpServers });
@@ -2916,15 +2863,15 @@ async function installMcp(projectDir) {
2916
2863
  async function installFullPlugin(projectDir) {
2917
2864
  const dir = pluginDir(projectDir);
2918
2865
  for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {
2919
- const dest = path23__default.join(dir, rel);
2920
- await fs6.mkdir(path23__default.dirname(dest), { recursive: true });
2921
- await fs6.writeFile(dest, content);
2866
+ const dest = path18__default.join(dir, rel);
2867
+ await fs5.mkdir(path18__default.dirname(dest), { recursive: true });
2868
+ await fs5.writeFile(dest, content);
2922
2869
  }
2923
- const projectSkillsDir = path23__default.join(projectDir, ".skaile", "skills");
2870
+ const projectSkillsDir = path18__default.join(projectDir, ".skaile", "skills");
2924
2871
  if (existsSync(projectSkillsDir)) {
2925
- await copyDir(projectSkillsDir, path23__default.join(dir, "skills"));
2872
+ await copyDir(projectSkillsDir, path18__default.join(dir, "skills"));
2926
2873
  }
2927
- const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
2874
+ const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
2928
2875
  const settings = await readJsonStrict(settingsPath) ?? {};
2929
2876
  const plugins = settings.plugins ?? [];
2930
2877
  if (!plugins.includes(dir)) plugins.push(dir);
@@ -2932,8 +2879,8 @@ async function installFullPlugin(projectDir) {
2932
2879
  return { changed: true, method: "plugin" };
2933
2880
  }
2934
2881
  async function uninstall(projectDir) {
2935
- const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
2936
- const mcpPath = path23__default.join(projectDir, ".claude", "mcp.json");
2882
+ const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
2883
+ const mcpPath = path18__default.join(projectDir, ".claude", "mcp.json");
2937
2884
  const dir = pluginDir(projectDir);
2938
2885
  let changed = false;
2939
2886
  const settings = await readJsonStrict(settingsPath);
@@ -2947,7 +2894,7 @@ async function uninstall(projectDir) {
2947
2894
  }
2948
2895
  }
2949
2896
  if (existsSync(dir)) {
2950
- await fs6.rm(dir, { recursive: true, force: true });
2897
+ await fs5.rm(dir, { recursive: true, force: true });
2951
2898
  changed = true;
2952
2899
  }
2953
2900
  const mcp = await readJsonStrict(mcpPath);
@@ -2957,7 +2904,7 @@ async function uninstall(projectDir) {
2957
2904
  const updated = { ...mcp, mcpServers: rest };
2958
2905
  if (Object.keys(rest).length === 0) delete updated.mcpServers;
2959
2906
  if (Object.keys(updated).length === 0) {
2960
- await fs6.unlink(mcpPath);
2907
+ await fs5.unlink(mcpPath);
2961
2908
  } else {
2962
2909
  await writeJson(mcpPath, updated);
2963
2910
  }
@@ -2967,12 +2914,12 @@ async function uninstall(projectDir) {
2967
2914
  async function detectInstall(projectDir) {
2968
2915
  const dir = pluginDir(projectDir);
2969
2916
  const settings = await readJsonStrict(
2970
- path23__default.join(projectDir, ".claude", "settings.json")
2917
+ path18__default.join(projectDir, ".claude", "settings.json")
2971
2918
  );
2972
- if (existsSync(path23__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
2919
+ if (existsSync(path18__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
2973
2920
  return { method: "plugin", pluginPath: dir };
2974
2921
  }
2975
- const mcp = await readJsonStrict(path23__default.join(projectDir, ".claude", "mcp.json"));
2922
+ const mcp = await readJsonStrict(path18__default.join(projectDir, ".claude", "mcp.json"));
2976
2923
  if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {
2977
2924
  return { method: "mcp" };
2978
2925
  }
@@ -2981,7 +2928,7 @@ async function detectInstall(projectDir) {
2981
2928
  async function enable(projectDir) {
2982
2929
  const detected = await detectInstall(projectDir);
2983
2930
  if (!detected) throw new Error("plugin not installed for claude-code");
2984
- const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
2931
+ const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
2985
2932
  const settings = await readJsonStrict(settingsPath) ?? {};
2986
2933
  if (detected.method === "plugin") {
2987
2934
  const disabled2 = settings.disabledPlugins ?? [];
@@ -3003,7 +2950,7 @@ async function enable(projectDir) {
3003
2950
  async function disable(projectDir) {
3004
2951
  const detected = await detectInstall(projectDir);
3005
2952
  if (!detected) throw new Error("plugin not installed for claude-code");
3006
- const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
2953
+ const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
3007
2954
  const settings = await readJsonStrict(settingsPath) ?? {};
3008
2955
  if (detected.method === "plugin") {
3009
2956
  const list2 = settings.disabledPlugins ?? [];
@@ -3023,12 +2970,12 @@ async function disable(projectDir) {
3023
2970
  return { changed: true };
3024
2971
  }
3025
2972
  async function status(projectDir) {
3026
- const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
3027
- const mcpPath = path23__default.join(projectDir, ".claude", "mcp.json");
2973
+ const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
2974
+ const mcpPath = path18__default.join(projectDir, ".claude", "mcp.json");
3028
2975
  const dir = pluginDir(projectDir);
3029
2976
  const settings = await readJsonStrict(settingsPath);
3030
2977
  const mcp = await readJsonStrict(mcpPath);
3031
- const pluginInstalled = !!(existsSync(path23__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
2978
+ const pluginInstalled = !!(existsSync(path18__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
3032
2979
  const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);
3033
2980
  if (!pluginInstalled && !mcpInstalled) {
3034
2981
  return {
@@ -3046,7 +2993,7 @@ async function status(projectDir) {
3046
2993
  installed: "yes",
3047
2994
  enabled: disabled2 ? "no" : "yes",
3048
2995
  method: "plugin",
3049
- location: path23__default.relative(projectDir, dir)
2996
+ location: path18__default.relative(projectDir, dir)
3050
2997
  };
3051
2998
  }
3052
2999
  const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;
@@ -3055,7 +3002,7 @@ async function status(projectDir) {
3055
3002
  installed: "yes",
3056
3003
  enabled: disabled ? "no" : "yes",
3057
3004
  method: "mcp",
3058
- location: path23__default.relative(projectDir, mcpPath)
3005
+ location: path18__default.relative(projectDir, mcpPath)
3059
3006
  };
3060
3007
  }
3061
3008
  var SKAILE_MCP_NAME2 = "skaile-workspace";
@@ -3069,7 +3016,7 @@ function buildEntry(projectDir) {
3069
3016
  async function readConfig(p6) {
3070
3017
  let raw;
3071
3018
  try {
3072
- raw = await fs6.readFile(p6, "utf-8");
3019
+ raw = await fs5.readFile(p6, "utf-8");
3073
3020
  } catch {
3074
3021
  return null;
3075
3022
  }
@@ -3082,16 +3029,16 @@ async function readConfig(p6) {
3082
3029
  }
3083
3030
  }
3084
3031
  async function writeConfig(p6, value) {
3085
- await fs6.mkdir(path23__default.dirname(p6), { recursive: true });
3032
+ await fs5.mkdir(path18__default.dirname(p6), { recursive: true });
3086
3033
  const cleaned = {};
3087
3034
  for (const [k, v] of Object.entries(value)) {
3088
3035
  if (v === void 0) continue;
3089
3036
  cleaned[k] = v;
3090
3037
  }
3091
- await fs6.writeFile(p6, stringify$1(cleaned));
3038
+ await fs5.writeFile(p6, stringify$1(cleaned));
3092
3039
  }
3093
3040
  function configPath(projectDir) {
3094
- return path23__default.join(projectDir, ".codex", "config.toml");
3041
+ return path18__default.join(projectDir, ".codex", "config.toml");
3095
3042
  }
3096
3043
  async function install2(projectDir) {
3097
3044
  const p6 = configPath(projectDir);
@@ -3102,7 +3049,7 @@ async function install2(projectDir) {
3102
3049
  const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
3103
3050
  let warning;
3104
3051
  if (previous && !matches) {
3105
- warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path23__default.relative(projectDir, p6)}`;
3052
+ warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path18__default.relative(projectDir, p6)}`;
3106
3053
  }
3107
3054
  if (matches) return { changed: false, method: "toml" };
3108
3055
  servers[SKAILE_MCP_NAME2] = next;
@@ -3119,7 +3066,7 @@ async function uninstall2(projectDir) {
3119
3066
  const updated = { ...cfg, mcp_servers: rest };
3120
3067
  if (Object.keys(rest).length === 0) delete updated.mcp_servers;
3121
3068
  if (Object.keys(updated).length === 0) {
3122
- await fs6.unlink(p6);
3069
+ await fs5.unlink(p6);
3123
3070
  } else {
3124
3071
  await writeConfig(p6, updated);
3125
3072
  }
@@ -3143,43 +3090,43 @@ async function status2(projectDir) {
3143
3090
  installed: "yes",
3144
3091
  enabled: "n/a",
3145
3092
  method: "mcp",
3146
- location: path23__default.relative(projectDir, p6)
3093
+ location: path18__default.relative(projectDir, p6)
3147
3094
  };
3148
3095
  }
3149
3096
  async function install3(projectDir) {
3150
- const extDir = path23__default.join(projectDir, ".omp", "extensions");
3151
- const extPath = path23__default.join(extDir, "skaile.ts");
3152
- await fs6.mkdir(extDir, { recursive: true });
3097
+ const extDir = path18__default.join(projectDir, ".omp", "extensions");
3098
+ const extPath = path18__default.join(extDir, "skaile.ts");
3099
+ await fs5.mkdir(extDir, { recursive: true });
3153
3100
  const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
3154
3101
  const plugin = new WorkspacePlugin({ projectDir });
3155
3102
  const nextSrc = await plugin.buildOmpExtensionSource();
3156
3103
  let prevSrc = null;
3157
3104
  try {
3158
- prevSrc = await fs6.readFile(extPath, "utf-8");
3105
+ prevSrc = await fs5.readFile(extPath, "utf-8");
3159
3106
  } catch {
3160
3107
  }
3161
3108
  if (prevSrc === nextSrc) return { changed: false, method: "generated" };
3162
- await fs6.writeFile(extPath, nextSrc);
3109
+ await fs5.writeFile(extPath, nextSrc);
3163
3110
  return { changed: true, method: "generated" };
3164
3111
  }
3165
3112
  async function uninstall3(projectDir) {
3166
- const extPath = path23__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3113
+ const extPath = path18__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3167
3114
  try {
3168
- await fs6.unlink(extPath);
3115
+ await fs5.unlink(extPath);
3169
3116
  return { changed: true };
3170
3117
  } catch {
3171
3118
  return { changed: false };
3172
3119
  }
3173
3120
  }
3174
3121
  async function status3(projectDir) {
3175
- const extPath = path23__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3122
+ const extPath = path18__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3176
3123
  if (existsSync(extPath)) {
3177
3124
  return {
3178
3125
  harness: "omp",
3179
3126
  installed: "yes",
3180
3127
  enabled: "n/a",
3181
3128
  method: "extension",
3182
- location: path23__default.relative(projectDir, extPath)
3129
+ location: path18__default.relative(projectDir, extPath)
3183
3130
  };
3184
3131
  }
3185
3132
  return {
@@ -3242,7 +3189,7 @@ async function installCodex(projectDir) {
3242
3189
  console.log(` ${S.dim("\u2192")} Restart Codex CLI to pick up the change.`);
3243
3190
  }
3244
3191
  async function runInstall(opts) {
3245
- const projectDir = path23__default.resolve(opts.projectDir);
3192
+ const projectDir = path18__default.resolve(opts.projectDir);
3246
3193
  const targets = resolveDriver(opts.driver);
3247
3194
  let exitCode = 0;
3248
3195
  if (targets.includes("claude-code")) {
@@ -3276,7 +3223,7 @@ async function uninstallCodex(projectDir) {
3276
3223
  else logInfo(`codex: not installed`);
3277
3224
  }
3278
3225
  async function runUninstall(opts) {
3279
- const projectDir = path23__default.resolve(opts.projectDir);
3226
+ const projectDir = path18__default.resolve(opts.projectDir);
3280
3227
  const targets = resolveDriver(opts.driver);
3281
3228
  let exitCode = 0;
3282
3229
  if (targets.includes("claude-code")) {
@@ -3319,7 +3266,7 @@ async function toggleTarget(t, projectDir, action3) {
3319
3266
  });
3320
3267
  }
3321
3268
  async function runToggle(opts, action3) {
3322
- const projectDir = path23__default.resolve(opts.projectDir);
3269
+ const projectDir = path18__default.resolve(opts.projectDir);
3323
3270
  const requestedAll = opts.driver === "all";
3324
3271
  const targets = resolveDriver(opts.driver);
3325
3272
  const usageError = checkToggleSupported(targets, requestedAll, action3);
@@ -3331,7 +3278,7 @@ async function runToggle(opts, action3) {
3331
3278
  return exitCode;
3332
3279
  }
3333
3280
  async function runStatus2(opts) {
3334
- const projectDir = path23__default.resolve(opts.projectDir);
3281
+ const projectDir = path18__default.resolve(opts.projectDir);
3335
3282
  const targets = resolveDriver(opts.driver);
3336
3283
  const rows = [];
3337
3284
  let exitCode = 0;
@@ -3402,7 +3349,7 @@ async function runHook(event) {
3402
3349
  await plugin.shutdown();
3403
3350
  return;
3404
3351
  }
3405
- const store = new PluginStore(path23__default.join(projectDir, ".skaile", "plugin-state.json"));
3352
+ const store = new PluginStore(path18__default.join(projectDir, ".skaile", "plugin-state.json"));
3406
3353
  await store.load();
3407
3354
  const status4 = store.get("connector:status");
3408
3355
  if (status4 && typeof status4 === "object" && Object.keys(status4).length > 0) {
@@ -3480,19 +3427,22 @@ function unfinishedGitState(dir) {
3480
3427
  for (const [entry, state2] of Object.entries(UNFINISHED_GIT_ENTRIES)) {
3481
3428
  const p6 = spawnSync("git", ["rev-parse", "--git-path", entry], { cwd: dir, encoding: "utf-8" });
3482
3429
  if (p6.status !== 0) return "the git directory could not be read";
3483
- if (fs9.existsSync(path23.resolve(dir, p6.stdout.trim()))) return state2;
3430
+ if (fs8.existsSync(path18.resolve(dir, p6.stdout.trim()))) return state2;
3484
3431
  }
3485
3432
  return null;
3486
3433
  }
3487
3434
  async function reindexLibrary(lib, library, name) {
3488
3435
  assertManifestEditableOrExit(lib.path);
3436
+ exitOnManifestPublisherProblems(lib.path, name);
3489
3437
  const badRequires = manifestRequiresProblems(lib.path);
3490
3438
  const resolved = resolveLibraryPublisherDetailed(lib, {}, getStoreIdentity());
3491
3439
  warnLibraryNameFallback(name, resolved);
3492
- const { removed, unknownKind, skipped } = await syncManifestWithDisk(
3440
+ const registry = getKindRegistry();
3441
+ const { removed, unknownKind, skipped, failed } = await syncManifestWithDisk(
3493
3442
  lib.path,
3494
3443
  resolved.publisher,
3495
- getKindRegistry()
3444
+ registry,
3445
+ { check: (e) => checkAssetFile(e.source, e.kind, registry) }
3496
3446
  );
3497
3447
  const manifest = loadSkPublishManifest(lib.path);
3498
3448
  for (const a of unknownKind) {
@@ -3511,16 +3461,20 @@ async function reindexLibrary(lib, library, name) {
3511
3461
  }
3512
3462
  const duplicates = skipped.filter((x) => x.reason === "duplicate");
3513
3463
  for (const s of duplicates) {
3514
- logErr(
3515
- `${s.kind}:${s.name} found in ${path23.dirname(s.file)} but ${s.detail}. Rename or delete one of the two directories, then re-run \`skaile library index ${name}\`.`
3516
- );
3464
+ logErr(duplicateAssetMessage(s.kind, s.name, path18.dirname(s.file), s.detail, name));
3465
+ }
3466
+ for (const s of failed) {
3467
+ for (const f of s.findings) logErr(`${s.file} [${f.tag}] \u2014 ${f.text}`);
3517
3468
  }
3518
- const duplicateFiles = new Set(duplicates.map((s) => path23.resolve(lib.path, s.file)));
3469
+ const duplicateFiles = new Set(duplicates.map((s) => path18.resolve(lib.path, s.file)));
3519
3470
  const skippedKeys = new Set(
3520
- skipped.filter((s) => s.reason !== "duplicate").map((s) => `${s.kind}:${s.name}`)
3471
+ [
3472
+ ...skipped.filter((s) => s.reason !== "duplicate"),
3473
+ ...failed.filter((s) => !s.inManifest)
3474
+ ].map((s) => `${s.kind}:${s.name}`)
3521
3475
  );
3522
3476
  const res = await indexLibrary(lib, library, {
3523
- exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`) || duplicateFiles.has(path23.resolve(a.manifestPath))
3477
+ exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`) || duplicateFiles.has(path18.resolve(a.manifestPath))
3524
3478
  });
3525
3479
  const unparsable = res.errors.filter((e) => e.includes("ManifestSchemaError:"));
3526
3480
  for (const e of res.errors) (unparsable.includes(e) ? logErr : logWarn)(e);
@@ -3531,6 +3485,7 @@ async function reindexLibrary(lib, library, name) {
3531
3485
  logErr(`${s.kind}:${s.name} skipped: manifest file ${s.file} could not be parsed.`);
3532
3486
  }
3533
3487
  for (const p6 of badRequires) logErr(`${p6.asset}: ${p6.message}`);
3488
+ for (const w of await unresolvedManifestDependencies(lib.path)) logWarn(w);
3534
3489
  logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
3535
3490
  warnIgnoredDomainFiles(lib.path);
3536
3491
  warnLegacyBundleFiles(lib.path);
@@ -3545,6 +3500,12 @@ async function reindexLibrary(lib, library, name) {
3545
3500
  );
3546
3501
  process.exitCode = 1;
3547
3502
  }
3503
+ if (failed.length > 0) {
3504
+ logErr(
3505
+ `${failed.length} asset(s) fail the checks of \`skaile validate\` (listed above); fix them and re-run \`skaile library index ${name}\`.`
3506
+ );
3507
+ process.exitCode = 1;
3508
+ }
3548
3509
  if (duplicates.length > 0) {
3549
3510
  logErr(
3550
3511
  `${duplicates.length} asset(s) skipped: kind + name already registered in another directory.`
@@ -3567,26 +3528,26 @@ function assertManifestEditableOrExit(libraryPath) {
3567
3528
  }
3568
3529
  async function assertLibraryPathFree(manager, dir, exceptId) {
3569
3530
  const clash = (await manager.listLibraries()).find(
3570
- (l) => l.id !== exceptId && path23.resolve(l.path) === dir
3531
+ (l) => l.id !== exceptId && path18.resolve(l.path) === dir
3571
3532
  );
3572
3533
  if (clash) throw new Error(`${dir} is already registered as library "${clash.name}".`);
3573
3534
  }
3574
3535
  function canonicalDir(dir) {
3575
- const abs = path23.resolve(dir);
3536
+ const abs = path18.resolve(dir);
3576
3537
  const missing = [];
3577
3538
  let existing = abs;
3578
- while (!fs9.existsSync(existing)) {
3579
- const parent = path23.dirname(existing);
3539
+ while (!fs8.existsSync(existing)) {
3540
+ const parent = path18.dirname(existing);
3580
3541
  if (parent === existing) return abs;
3581
- missing.unshift(path23.basename(existing));
3542
+ missing.unshift(path18.basename(existing));
3582
3543
  existing = parent;
3583
3544
  }
3584
- return path23.join(fs9.realpathSync(existing), ...missing);
3545
+ return path18.join(fs8.realpathSync(existing), ...missing);
3585
3546
  }
3586
3547
  function refuseGlobalInstallFolder(name, dir) {
3587
3548
  const reserved = globalInstallDir();
3588
- const rel = path23.relative(canonicalDir(reserved).toLowerCase(), canonicalDir(dir).toLowerCase());
3589
- const inside = rel === "" || !rel.startsWith("..") && !path23.isAbsolute(rel);
3549
+ const rel = path18.relative(canonicalDir(reserved).toLowerCase(), canonicalDir(dir).toLowerCase());
3550
+ const inside = rel === "" || !rel.startsWith("..") && !path18.isAbsolute(rel);
3590
3551
  if (name?.toLowerCase() === GLOBAL_INSTALL_DIR_NAME || inside) {
3591
3552
  logErr(
3592
3553
  `"${GLOBAL_INSTALL_DIR_NAME}" is reserved: ${reserved} holds assets from \`skaile install\`, not a library you author.`
@@ -3594,6 +3555,85 @@ function refuseGlobalInstallFolder(name, dir) {
3594
3555
  process.exit(1);
3595
3556
  }
3596
3557
  }
3558
+ async function refuseNestedLibraryPath(manager, dir, exceptId) {
3559
+ const within = (parent, child) => {
3560
+ const rel = path18.relative(parent, child);
3561
+ return rel === "" || !rel.startsWith("..") && !path18.isAbsolute(rel);
3562
+ };
3563
+ const target = canonicalDir(dir).toLowerCase();
3564
+ const librariesDir = resolveLibraryDir();
3565
+ if (within(target, canonicalDir(librariesDir).toLowerCase())) {
3566
+ logErr(
3567
+ `"libraries" is reserved: ${librariesDir} holds every library and the global installs, not a library you author.`
3568
+ );
3569
+ process.exit(1);
3570
+ }
3571
+ for (const other of await manager.listLibraries()) {
3572
+ if (other.id === exceptId) continue;
3573
+ const otherDir = canonicalDir(other.path).toLowerCase();
3574
+ if (within(otherDir, target)) {
3575
+ logErr(
3576
+ `${dir} is inside the library "${other.name}" (${other.path}): a library cannot live inside another library.`
3577
+ );
3578
+ process.exit(1);
3579
+ }
3580
+ if (within(target, otherDir)) {
3581
+ logErr(
3582
+ `${dir} contains the library "${other.name}" (${other.path}): a library cannot contain another library.`
3583
+ );
3584
+ process.exit(1);
3585
+ }
3586
+ }
3587
+ }
3588
+ function assertCreateDirInsideLibrary(libRoot, destDir, given) {
3589
+ const exists = (p6) => {
3590
+ try {
3591
+ fs8.lstatSync(p6);
3592
+ return true;
3593
+ } catch {
3594
+ return false;
3595
+ }
3596
+ };
3597
+ let probe = destDir;
3598
+ while (!exists(probe)) probe = path18.dirname(probe);
3599
+ let realProbe;
3600
+ try {
3601
+ realProbe = fs8.realpathSync(probe);
3602
+ } catch {
3603
+ logErr(`--dir "${given}" passes through a broken symlink (${probe}).`);
3604
+ process.exit(1);
3605
+ }
3606
+ if (!fs8.statSync(realProbe).isDirectory()) {
3607
+ logErr(`--dir "${given}": ${probe} is not a directory.`);
3608
+ process.exit(1);
3609
+ }
3610
+ const realRoot = canonicalDir(libRoot);
3611
+ const realDest = path18.join(realProbe, path18.relative(probe, destDir));
3612
+ const rel = path18.relative(realRoot, realDest);
3613
+ if (rel === ".." || rel.startsWith(`..${path18.sep}`) || path18.isAbsolute(rel)) {
3614
+ logErr(
3615
+ `--dir "${given}" must stay inside the library (${realRoot}): it resolves to ${realDest}.`
3616
+ );
3617
+ process.exit(1);
3618
+ }
3619
+ }
3620
+ function adoptWritesManifest(libPath) {
3621
+ if (!fs8.existsSync(path18.join(libPath, SKAILE_MANIFEST_FILENAME))) return true;
3622
+ const manifest = loadSkPublishManifest(libPath);
3623
+ if (!manifest || manifest.source || (manifest.assets ?? []).length > 0) return false;
3624
+ return manifestPublisherProblems(libPath).length === 0;
3625
+ }
3626
+ async function countUnlistedAssets(libPath) {
3627
+ const manifest = loadSkPublishManifest(libPath);
3628
+ const listed = manifest?.assets ?? [];
3629
+ if (!manifest || manifest.source || listed.length === 0) return 0;
3630
+ const keys = new Set(listed.map((a) => `${a.kind}:${a.name}`));
3631
+ const onDisk = await scanDirectory(libPath, "unlisted", {
3632
+ knownKinds: new Set(getKindRegistry().getAllKinds()),
3633
+ keepDuplicates: true
3634
+ });
3635
+ return new Set(onDisk.map((e) => `${e.kind}:${e.name}`).filter((k) => !keys.has(k))).size;
3636
+ }
3597
3637
  function readOriginTracking(dir) {
3598
3638
  if (!isGitRepo(dir)) return null;
3599
3639
  const origin = spawnSync("git", ["remote", "get-url", "origin"], { cwd: dir, encoding: "utf-8" });
@@ -3613,6 +3653,15 @@ function requireGitBackend(lib, verb) {
3613
3653
  process.exit(1);
3614
3654
  }
3615
3655
  }
3656
+ async function findLibraryWithMissingDir(name) {
3657
+ const { manager, close } = await openLibraryManager();
3658
+ try {
3659
+ const lib = await manager.getLibrary(name);
3660
+ return lib && libraryDirMissing(lib) ? lib : null;
3661
+ } finally {
3662
+ close();
3663
+ }
3664
+ }
3616
3665
  function requireValidLibraryName(name) {
3617
3666
  try {
3618
3667
  assertValidLibraryName(name);
@@ -3623,17 +3672,17 @@ function requireValidLibraryName(name) {
3623
3672
  var LOCAL_OWNERSHIP_REASON = "ownership only governs sync with a git remote, and a local library is always owned by you.";
3624
3673
  function pruneEmptyLibraryParents(libPath) {
3625
3674
  const root = canonicalDir(resolveLibraryDir());
3626
- let dir = path23.dirname(path23.resolve(libPath));
3675
+ let dir = path18.dirname(path18.resolve(libPath));
3627
3676
  for (; ; ) {
3628
- const rel = path23.relative(root, canonicalDir(dir));
3629
- if (rel === "" || rel.startsWith("..") || path23.isAbsolute(rel)) return;
3630
- if (!fs9.existsSync(dir) || fs9.readdirSync(dir).length > 0) return;
3631
- fs9.rmdirSync(dir);
3632
- dir = path23.dirname(dir);
3677
+ const rel = path18.relative(root, canonicalDir(dir));
3678
+ if (rel === "" || rel.startsWith("..") || path18.isAbsolute(rel)) return;
3679
+ if (!fs8.existsSync(dir) || fs8.readdirSync(dir).length > 0) return;
3680
+ fs8.rmdirSync(dir);
3681
+ dir = path18.dirname(dir);
3633
3682
  }
3634
3683
  }
3635
3684
  async function warnIfNotGithubRemote(name, url) {
3636
- const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-PICMDSB2.js');
3685
+ const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-OS3JDW4S.js');
3637
3686
  if (!isGithubRemote(url)) logWarn(notGithubRemoteMessage(name, url));
3638
3687
  }
3639
3688
  function scaffoldLibraryFiles(dir, name) {
@@ -3665,9 +3714,9 @@ by the same ref.
3665
3714
  ];
3666
3715
  const written = [];
3667
3716
  for (const [file, content] of files) {
3668
- const target = path23.join(dir, file);
3669
- if (fs9.existsSync(target)) continue;
3670
- fs9.writeFileSync(target, content, "utf8");
3717
+ const target = path18.join(dir, file);
3718
+ if (fs8.existsSync(target)) continue;
3719
+ fs8.writeFileSync(target, content, "utf8");
3671
3720
  written.push(file);
3672
3721
  }
3673
3722
  return written;
@@ -3678,7 +3727,15 @@ function makeLibraryCommand() {
3678
3727
  const { manager, close } = await openLibraryManager();
3679
3728
  try {
3680
3729
  const ls = await manager.listLibraries();
3681
- if (opts.json) return console.log(JSON.stringify(ls, null, 2));
3730
+ if (opts.json) {
3731
+ return console.log(
3732
+ JSON.stringify(
3733
+ ls.map((l) => libraryDirMissing(l) ? { ...l, directoryMissing: true } : l),
3734
+ null,
3735
+ 2
3736
+ )
3737
+ );
3738
+ }
3682
3739
  if (ls.length === 0) {
3683
3740
  logInfo("No libraries registered. Run `skaile library init personal` to start.");
3684
3741
  return;
@@ -3698,6 +3755,7 @@ function makeLibraryCommand() {
3698
3755
  console.log(`
3699
3756
  ${S.dim(`${ls.length} library(s)`)}
3700
3757
  `);
3758
+ for (const l of ls) if (libraryDirMissing(l)) logWarn(missingLibraryDirMessage(l));
3701
3759
  } finally {
3702
3760
  close();
3703
3761
  }
@@ -3724,6 +3782,7 @@ function makeLibraryCommand() {
3724
3782
  console.log(` ${S.label("manifestGen")} ${l.manifestGenerated}`);
3725
3783
  console.log(` ${S.label("backendConfig")} ${JSON.stringify(l.backendConfig)}`);
3726
3784
  console.log();
3785
+ if (libraryDirMissing(l)) logWarn(missingLibraryDirMessage(l));
3727
3786
  } finally {
3728
3787
  close();
3729
3788
  }
@@ -3736,10 +3795,15 @@ function makeLibraryCommand() {
3736
3795
  logErr("Pick one of --owner, --contributor, --reader.");
3737
3796
  process.exit(1);
3738
3797
  }
3739
- const ownership = flagged[0] ?? "owner";
3740
- const libPath = opts.path ? path23.resolve(opts.path) : path23.join(resolveLibraryDir(), name);
3798
+ const gone = await findLibraryWithMissingDir(name);
3799
+ if (gone) {
3800
+ if (gone.backend === "git") opts.git ??= gone.backendConfig.url;
3801
+ opts.path ??= gone.path;
3802
+ }
3803
+ const ownership = flagged[0] ?? gone?.ownership ?? "owner";
3804
+ const libPath = opts.path ? path18.resolve(opts.path) : path18.join(resolveLibraryDir(), name);
3741
3805
  refuseGlobalInstallFolder(name, libPath);
3742
- if (fs9.existsSync(libPath) && !fs9.statSync(libPath).isDirectory()) {
3806
+ if (fs8.existsSync(libPath) && !fs8.statSync(libPath).isDirectory()) {
3743
3807
  logErr(`${libPath} exists and is not a directory.`);
3744
3808
  process.exit(1);
3745
3809
  }
@@ -3752,11 +3816,14 @@ function makeLibraryCommand() {
3752
3816
  }
3753
3817
  const { manager, library, close } = await openLibraryManager();
3754
3818
  try {
3755
- if (await manager.getLibrary(name)) {
3819
+ const existing = await manager.getLibrary(name);
3820
+ if (existing && !gone) {
3756
3821
  logErr(`A library named "${name}" is already registered.`);
3757
3822
  process.exit(1);
3758
3823
  }
3824
+ if (existing) await manager.removeLibrary(name);
3759
3825
  await assertLibraryPathFree(manager, libPath);
3826
+ await refuseNestedLibraryPath(manager, libPath);
3760
3827
  const hasDefault = (await manager.listLibraries()).some((l) => l.isDefault);
3761
3828
  let backend = "local";
3762
3829
  let backendConfig;
@@ -3775,9 +3842,9 @@ function makeLibraryCommand() {
3775
3842
  backend = "git";
3776
3843
  backendConfig = { url: adopted.url, branch: adopted.branch, authHint: "ssh" };
3777
3844
  } else {
3778
- fs9.mkdirSync(libPath, { recursive: true });
3845
+ fs8.mkdirSync(libPath, { recursive: true });
3779
3846
  }
3780
- const blank = fs9.readdirSync(libPath).every((entry) => entry === ".git");
3847
+ const blank = fs8.readdirSync(libPath).every((entry) => entry === ".git");
3781
3848
  const isDefault = !hasDefault && ownership !== "reader";
3782
3849
  await manager.addLibrary({
3783
3850
  name,
@@ -3804,6 +3871,11 @@ function makeLibraryCommand() {
3804
3871
  }
3805
3872
  if (!blank) {
3806
3873
  const lib = await manager.requireLibrary(name);
3874
+ if (adoptWritesManifest(libPath)) {
3875
+ await reindexLibrary(lib, library, name);
3876
+ return;
3877
+ }
3878
+ const unlisted = await countUnlistedAssets(libPath);
3807
3879
  const resolved = resolveLibraryPublisherDetailed(lib, {}, getStoreIdentity());
3808
3880
  if (resolved.source === "manifest" && !isValidPublisher(resolved.publisher)) {
3809
3881
  logWarn(
@@ -3817,6 +3889,11 @@ function makeLibraryCommand() {
3817
3889
  const res = await indexLibrary(lib, library);
3818
3890
  for (const e of res.errors) logWarn(e);
3819
3891
  logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
3892
+ if (unlisted > 0) {
3893
+ logWarn(
3894
+ `${unlisted} asset(s) on disk are not in the manifest; run \`skaile library index ${name}\`.`
3895
+ );
3896
+ }
3820
3897
  warnIgnoredDomainFiles(libPath);
3821
3898
  }
3822
3899
  } catch (err2) {
@@ -3829,7 +3906,7 @@ function makeLibraryCommand() {
3829
3906
  cmd.command("link <name> <git-url>").description("Attach a github remote to a local library (makes it store-publishable)").option("--branch <name>", "Default branch", "main").action(async (name, url, opts) => {
3830
3907
  const { manager, close } = await openLibraryManager();
3831
3908
  try {
3832
- const lib = await manager.requireLibrary(name);
3909
+ const lib = await manager.requireLibraryDir(name);
3833
3910
  if (lib.backend === "git") {
3834
3911
  logErr(
3835
3912
  `Library "${name}" is already git-backed. Use \`skaile library set ${name} backendConfig.url=${url}\` to change its remote.`
@@ -3866,13 +3943,7 @@ function makeLibraryCommand() {
3866
3943
  logErr(`Invalid asset name "${name}": ${ASSET_NAME_HINT}.`);
3867
3944
  process.exit(1);
3868
3945
  }
3869
- if (opts.publisher !== void 0) {
3870
- const bare = opts.publisher.trim().replace(/^@/, "");
3871
- if (!isValidPublisher(bare)) {
3872
- logErr(`Invalid publisher "${opts.publisher}": ${PUBLISHER_HINT}.`);
3873
- process.exit(1);
3874
- }
3875
- }
3946
+ if (opts.publisher !== void 0) requireValidPublisherOrExit(opts.publisher);
3876
3947
  if (opts.description !== void 0) {
3877
3948
  const len = opts.description.trim().length;
3878
3949
  if (len === 0 || len > 1024) {
@@ -3884,24 +3955,26 @@ function makeLibraryCommand() {
3884
3955
  try {
3885
3956
  const target = await resolveTargetLibrary(manager, opts.library);
3886
3957
  assertManifestEditableOrExit(target.path);
3958
+ exitOnManifestPublisherProblems(target.path, target.name);
3887
3959
  const effectiveKind = opts.kind ?? kind;
3888
3960
  const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
3889
- const libRoot = path23.resolve(target.path);
3890
- const destDir = opts.dir ? path23.resolve(libRoot, opts.dir) : libRoot;
3891
- const relDest = path23.relative(libRoot, destDir);
3892
- if (relDest === ".." || relDest.startsWith(`..${path23.sep}`) || path23.isAbsolute(relDest)) {
3961
+ const libRoot = path18.resolve(target.path);
3962
+ const destDir = opts.dir ? path18.resolve(libRoot, opts.dir) : libRoot;
3963
+ const relDest = path18.relative(libRoot, destDir);
3964
+ if (relDest === ".." || relDest.startsWith(`..${path18.sep}`) || path18.isAbsolute(relDest)) {
3893
3965
  logErr(`--dir "${opts.dir}" must stay inside the library (${libRoot}).`);
3894
3966
  process.exit(1);
3895
3967
  }
3968
+ if (opts.dir) assertCreateDirInsideLibrary(libRoot, destDir, opts.dir);
3896
3969
  const taken = conflictingAssetRoot(
3897
3970
  libRoot,
3898
3971
  effectiveKind,
3899
3972
  name,
3900
- path23.relative(libRoot, path23.join(destDir, name))
3973
+ path18.relative(libRoot, path18.join(destDir, name))
3901
3974
  );
3902
3975
  if (taken) {
3903
3976
  logErr(
3904
- `${effectiveKind}:${name} already exists at "${taken}" \u2014 creating it again under "${path23.relative(libRoot, destDir) || "."}" would re-point the manifest entry. Pick another name.`
3977
+ `${effectiveKind}:${name} already exists at "${taken}" \u2014 creating it again under "${path18.relative(libRoot, destDir) || "."}" would re-point the manifest entry. Pick another name.`
3905
3978
  );
3906
3979
  process.exit(1);
3907
3980
  }
@@ -3911,9 +3984,9 @@ function makeLibraryCommand() {
3911
3984
  process.exit(1);
3912
3985
  }
3913
3986
  logOk(`Created ${effectiveKind}: ${pc5.dim(res.path)}`);
3914
- if (opts.description === void 0 && effectiveKind === "skill") {
3987
+ if (opts.description === void 0 && ["skill", "agent", "prompt", "contract"].includes(effectiveKind)) {
3915
3988
  logWarn(
3916
- "Description is a TODO placeholder \u2014 edit it (what the skill does and when to use it) or `skaile validate` will fail."
3989
+ `Description is a TODO placeholder \u2014 edit it (what the ${effectiveKind} does and when to use it) or \`skaile validate\` will fail.`
3917
3990
  );
3918
3991
  }
3919
3992
  const { ref } = await registerLibraryAsset(target, library, {
@@ -3930,9 +4003,9 @@ function makeLibraryCommand() {
3930
4003
  }
3931
4004
  );
3932
4005
  async function resolveTargetLibrary(manager, libraryName) {
3933
- if (libraryName) return manager.requireLibrary(libraryName);
4006
+ if (libraryName) return manager.requireLibraryDir(libraryName);
3934
4007
  const def = await manager.findDefaultLibrary();
3935
- if (def) return def;
4008
+ if (def) return manager.requireLibraryDir(def.name);
3936
4009
  if ((await manager.listLibraries()).length === 0) {
3937
4010
  logErr("No libraries registered. Run `skaile library init <name>` first.");
3938
4011
  process.exit(1);
@@ -3955,13 +4028,13 @@ function makeLibraryCommand() {
3955
4028
  logErr(`A library named "${newName}" is already registered.`);
3956
4029
  process.exit(1);
3957
4030
  }
3958
- const newPath = path23.join(path23.dirname(lib.path), newName);
4031
+ const newPath = path18.join(path18.dirname(lib.path), newName);
3959
4032
  refuseGlobalInstallFolder(newName, newPath);
3960
- if (fs9.existsSync(newPath)) {
4033
+ if (fs8.existsSync(newPath)) {
3961
4034
  logErr(`Target directory already exists: ${newPath}`);
3962
4035
  process.exit(1);
3963
4036
  }
3964
- fs9.renameSync(lib.path, newPath);
4037
+ fs8.renameSync(lib.path, newPath);
3965
4038
  await manager.updateLibrary(lib.id, { name: newName, path: newPath });
3966
4039
  logOk(`Renamed ${lib.name} \u2192 ${newName}`);
3967
4040
  }
@@ -3988,17 +4061,17 @@ function makeLibraryCommand() {
3988
4061
  try {
3989
4062
  const lib = await manager.requireLibrary(name);
3990
4063
  if (field === "publisher") {
3991
- const publisher = value.trim().replace(/^@/, "");
3992
- if (!isValidPublisher(publisher)) {
3993
- logErr(`Invalid publisher "${value}": ${PUBLISHER_HINT}.`);
3994
- process.exit(1);
3995
- }
4064
+ const publisher = requireValidPublisherOrExit(value);
3996
4065
  if (lib.ownership === "reader") {
3997
4066
  logErr(
3998
4067
  `Library "${lib.name}" is read-only (ownership=reader); its publisher is not yours to set.`
3999
4068
  );
4000
4069
  process.exit(1);
4001
4070
  }
4071
+ if (libraryDirMissing(lib)) {
4072
+ logErr(missingLibraryDirMessage(lib));
4073
+ process.exit(1);
4074
+ }
4002
4075
  assertManifestEditableOrExit(lib.path);
4003
4076
  setManifestPublisher(lib.path, publisher);
4004
4077
  const res = await indexLibrary(lib, library);
@@ -4041,13 +4114,14 @@ function makeLibraryCommand() {
4041
4114
  }
4042
4115
  patch.isDefault = false;
4043
4116
  } else if (field === "path") {
4044
- const dir = path23.resolve(value);
4045
- if (!fs9.existsSync(dir) || !fs9.statSync(dir).isDirectory()) {
4117
+ const dir = path18.resolve(value);
4118
+ if (!fs8.existsSync(dir) || !fs8.statSync(dir).isDirectory()) {
4046
4119
  logErr(`Directory does not exist: ${dir}. \`library set path=\` does not move files.`);
4047
4120
  process.exit(1);
4048
4121
  }
4049
4122
  refuseGlobalInstallFolder(null, dir);
4050
4123
  await assertLibraryPathFree(manager, dir, lib.id);
4124
+ await refuseNestedLibraryPath(manager, dir, lib.id);
4051
4125
  patch.path = dir;
4052
4126
  } else if (field.startsWith("backendConfig.")) {
4053
4127
  const key = field.split(".")[1];
@@ -4105,7 +4179,7 @@ function makeLibraryCommand() {
4105
4179
  cmd.command("sync <name>").description("Pull then push (as backend permits)").action(async (name) => {
4106
4180
  const { manager, library, close } = await openLibraryManager();
4107
4181
  try {
4108
- const lib = await manager.requireLibrary(name);
4182
+ const lib = await manager.requireLibraryDir(name);
4109
4183
  requireGitBackend(lib, "sync");
4110
4184
  const drv = manager.driverFor(lib.backend);
4111
4185
  const pull = await drv.pull(lib);
@@ -4127,8 +4201,10 @@ function makeLibraryCommand() {
4127
4201
  cmd.command("index <name>").description("(Re)index a library's assets into the local index").action(async (name) => {
4128
4202
  const { manager, library, close } = await openLibraryManager();
4129
4203
  try {
4130
- const lib = await manager.requireLibrary(name);
4204
+ const lib = await manager.requireLibraryDir(name);
4131
4205
  await reindexLibrary(lib, library, name);
4206
+ } catch (err2) {
4207
+ exitOnSyncError(err2);
4132
4208
  } finally {
4133
4209
  close();
4134
4210
  }
@@ -4136,7 +4212,7 @@ function makeLibraryCommand() {
4136
4212
  cmd.command("pull <name>").description("Pull from remote").action(async (name) => {
4137
4213
  const { manager, library, close } = await openLibraryManager();
4138
4214
  try {
4139
- const lib = await manager.requireLibrary(name);
4215
+ const lib = await manager.requireLibraryDir(name);
4140
4216
  requireGitBackend(lib, "pull");
4141
4217
  const res = await manager.driverFor(lib.backend).pull(lib);
4142
4218
  if (res.conflicts.length > 0) {
@@ -4154,7 +4230,7 @@ function makeLibraryCommand() {
4154
4230
  cmd.command("push <name>").description("Push local commits (owner only)").option("--force", "Force-with-lease push", false).action(async (name, opts) => {
4155
4231
  const { manager, close } = await openLibraryManager();
4156
4232
  try {
4157
- const lib = await manager.requireLibrary(name);
4233
+ const lib = await manager.requireLibraryDir(name);
4158
4234
  requireGitBackend(lib, "push");
4159
4235
  const res = await manager.driverFor(lib.backend).push(lib, { force: opts.force });
4160
4236
  logOk(`Pushed (${res.pushed}).`);
@@ -4167,7 +4243,7 @@ function makeLibraryCommand() {
4167
4243
  cmd.command("propose <name>").description("Open a pull request on the upstream repo (contributor only)").option("--title <title>", "PR title").option("--body <body>", "PR body").option("--branch <name>", "Branch name (default: skaile/<timestamp>)").action(async (name, opts) => {
4168
4244
  const { manager, close } = await openLibraryManager();
4169
4245
  try {
4170
- const lib = await manager.requireLibrary(name);
4246
+ const lib = await manager.requireLibraryDir(name);
4171
4247
  const res = await manager.driverFor(lib.backend).propose(lib, opts);
4172
4248
  logOk(`PR opened: ${res.prUrl}`);
4173
4249
  } catch (err2) {
@@ -4179,7 +4255,7 @@ function makeLibraryCommand() {
4179
4255
  cmd.command("commit <name>").description("Git-commit local changes inside the library (git only)").option("-m, --message <msg>", "Commit message", "skaile: update assets").action(async (name, opts) => {
4180
4256
  const { manager, close } = await openLibraryManager();
4181
4257
  try {
4182
- const lib = await manager.requireLibrary(name);
4258
+ const lib = await manager.requireLibraryDir(name);
4183
4259
  requireGitBackend(lib, "commit");
4184
4260
  if (!isGitRepo(lib.path)) {
4185
4261
  logErr(
@@ -4232,13 +4308,15 @@ function makeLibraryCommand() {
4232
4308
  const args = rawArgs[0] === "--" ? rawArgs.slice(1) : rawArgs;
4233
4309
  const { manager, close } = await openLibraryManager();
4234
4310
  try {
4235
- const lib = await manager.requireLibrary(name);
4311
+ const lib = await manager.requireLibraryDir(name);
4236
4312
  const r = spawnSync("git", args, { cwd: lib.path, stdio: "inherit" });
4237
4313
  if (r.error) {
4238
4314
  logErr(`Could not run git: ${r.error.message}`);
4239
4315
  process.exit(1);
4240
4316
  }
4241
4317
  process.exit(r.status ?? 1);
4318
+ } catch (err2) {
4319
+ exitOnSyncError(err2);
4242
4320
  } finally {
4243
4321
  close();
4244
4322
  }
@@ -4248,16 +4326,16 @@ function makeLibraryCommand() {
4248
4326
  "With --create-repo: create the repo private (the store only accepts public repos)"
4249
4327
  ).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(
4250
4328
  async (lib, opts) => {
4251
- const { runLibraryPublish } = await import('../library-publish-PICMDSB2.js');
4329
+ const { runLibraryPublish } = await import('../library-publish-OS3JDW4S.js');
4252
4330
  await withStoreErrorHandling(() => runLibraryPublish(lib, opts));
4253
4331
  }
4254
4332
  );
4255
4333
  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) => {
4256
- const { runLibraryRegister } = await import('../library-publish-PICMDSB2.js');
4334
+ const { runLibraryRegister } = await import('../library-publish-OS3JDW4S.js');
4257
4335
  await withStoreErrorHandling(() => runLibraryRegister(lib, opts));
4258
4336
  });
4259
4337
  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) => {
4260
- const { runLibraryYank } = await import('../library-publish-PICMDSB2.js');
4338
+ const { runLibraryYank } = await import('../library-publish-OS3JDW4S.js');
4261
4339
  await withStoreErrorHandling(() => runLibraryYank(lib, opts));
4262
4340
  });
4263
4341
  return cmd;
@@ -4273,7 +4351,7 @@ async function withStoreErrorHandling(fn) {
4273
4351
  async function printPerLibraryStatus(name, asJson) {
4274
4352
  const { manager, close } = await openLibraryManager();
4275
4353
  try {
4276
- const lib = await manager.requireLibrary(name);
4354
+ const lib = await manager.requireLibraryDir(name);
4277
4355
  const status4 = await manager.driverFor(lib.backend).status(lib);
4278
4356
  if (asJson) return console.log(JSON.stringify({ library: lib.name, status: status4 }, null, 2));
4279
4357
  console.log(`
@@ -4308,9 +4386,9 @@ async function printOverallStatus(projectDir, asJson) {
4308
4386
  } catch {
4309
4387
  secretsStrategy = "unavailable";
4310
4388
  }
4311
- const resolvedProjectDir = path23.resolve(projectDir);
4312
- const hasWorkspaceConfig = existsSync(path23.join(resolvedProjectDir, "skaile.yaml"));
4313
- const hasLockFile = existsSync(path23.join(resolvedProjectDir, "skaile.lock.yaml"));
4389
+ const resolvedProjectDir = path18.resolve(projectDir);
4390
+ const hasWorkspaceConfig = existsSync(path18.join(resolvedProjectDir, "skaile.yaml"));
4391
+ const hasLockFile = existsSync(path18.join(resolvedProjectDir, "skaile.lock.yaml"));
4314
4392
  let assignments = [];
4315
4393
  if (hasWorkspaceConfig) {
4316
4394
  try {
@@ -4917,7 +4995,7 @@ function scheduleSoftDepPreview() {
4917
4995
  }
4918
4996
  async function loadAssets() {
4919
4997
  softDepPreviewCache.clear();
4920
- const { gatherAssetFeeds } = await import('../asset-feeds-EYRZR4K5.js');
4998
+ const { gatherAssetFeeds } = await import('../asset-feeds-ELEBTNUS.js');
4921
4999
  const { entries, notes } = await gatherAssetFeeds(am, am.projectDir);
4922
5000
  if (notes.length > 0) {
4923
5001
  state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
@@ -4925,10 +5003,15 @@ async function loadAssets() {
4925
5003
  const installed = new Set(am.listDeployed().map((e) => `${e.kind}:${e.name}`));
4926
5004
  let lock = null;
4927
5005
  try {
4928
- lock = readLock(path23__default.join(am.projectDir, "skaile.lock.yaml"));
5006
+ lock = readLock(path18__default.join(am.projectDir, "skaile.lock.yaml"));
4929
5007
  } catch {
4930
5008
  }
4931
- const rows = buildAssetRows(entries, installed, lockedLibraryByIdentity(lock));
5009
+ const rows = buildAssetRows(
5010
+ entries,
5011
+ installed,
5012
+ await am.lockedLibraryNames(),
5013
+ lockedPublishersByName(lock)
5014
+ );
4932
5015
  state.assetRows = rows;
4933
5016
  reconcileCollapsedSets(rows);
4934
5017
  rebuildVisible();
@@ -4942,7 +5025,7 @@ function rebuildSourceTree() {
4942
5025
  rebuildVisibleSources();
4943
5026
  }
4944
5027
  function sourceOrgRepo(s) {
4945
- const parts = s.path.split(path23__default.sep).filter(Boolean);
5028
+ const parts = s.path.split(path18__default.sep).filter(Boolean);
4946
5029
  if (parts.length < 2) return null;
4947
5030
  return { org: parts[parts.length - 2], repo: parts[parts.length - 1] };
4948
5031
  }
@@ -5015,22 +5098,27 @@ function rebuildVisibleLibraries() {
5015
5098
  );
5016
5099
  clampCursor();
5017
5100
  }
5018
- function lockedLibraryByIdentity(lock) {
5101
+ function lockedPublishersByName(lock) {
5019
5102
  const out = /* @__PURE__ */ new Map();
5020
- for (const [key, locked] of Object.entries(lock?.assets ?? {})) {
5021
- if (!locked.library) continue;
5103
+ for (const key of Object.keys(lock?.assets ?? {})) {
5022
5104
  const ref = parseAssetRefLoose(key);
5023
- if (ref?.publisher) out.set(`${ref.kind}:${ref.publisher}/${ref.name}`, locked.library.name);
5105
+ if (!ref?.publisher) continue;
5106
+ const id = `${ref.kind}:${ref.name}`;
5107
+ const publishers = out.get(id) ?? /* @__PURE__ */ new Set();
5108
+ publishers.add(ref.publisher);
5109
+ out.set(id, publishers);
5024
5110
  }
5025
5111
  return out;
5026
5112
  }
5027
- function isRowInstalled(origin, group, entry, installed, lockedLibrary) {
5113
+ function isRowInstalled(origin, group, entry, installed, lockedLibrary, lockedPublishers) {
5028
5114
  if (!installed.has(`${entry.kind}:${entry.name}`)) return false;
5029
5115
  const publisher = entry.publisher?.replace(/^@/, "");
5116
+ const lockedFor = lockedPublishers.get(`${entry.kind}:${entry.name}`);
5117
+ if (publisher && lockedFor && !lockedFor.has(publisher)) return false;
5030
5118
  const locked = publisher ? lockedLibrary.get(`${entry.kind}:${publisher}/${entry.name}`) : void 0;
5031
- return locked === void 0 || origin === "library" && group === locked;
5119
+ return locked === void 0 || origin === "library" && locked !== null && group === locked;
5032
5120
  }
5033
- function buildAssetRows(entries, installed, lockedLibrary = /* @__PURE__ */ new Map()) {
5121
+ function buildAssetRows(entries, installed, lockedLibrary = /* @__PURE__ */ new Map(), lockedPublishers = /* @__PURE__ */ new Map()) {
5034
5122
  const byOrigin = /* @__PURE__ */ new Map();
5035
5123
  for (const { origin, entry, group } of entries) {
5036
5124
  const publisher = group || entry.publisher || "other";
@@ -5058,7 +5146,14 @@ function buildAssetRows(entries, installed, lockedLibrary = /* @__PURE__ */ new
5058
5146
  source: group,
5059
5147
  org: entry.repo?.includes("/") ? entry.repo.slice(0, entry.repo.indexOf("/")) : void 0,
5060
5148
  entry,
5061
- installed: isRowInstalled(origin, group, entry, installed, lockedLibrary),
5149
+ installed: isRowInstalled(
5150
+ origin,
5151
+ group,
5152
+ entry,
5153
+ installed,
5154
+ lockedLibrary,
5155
+ lockedPublishers
5156
+ ),
5062
5157
  plugin
5063
5158
  });
5064
5159
  }
@@ -5104,13 +5199,13 @@ function reconcileCollapsedSets(rows) {
5104
5199
  async function loadSourcesAndLibraries() {
5105
5200
  try {
5106
5201
  const [{ openLibraryManager: openLibraryManager2 }, { getGlobalCacheDir: getGlobalCacheDir2, globalSkaileDir: globalSkaileDir2 }] = await Promise.all([
5107
- import('../open-library-OG457THY.js'),
5202
+ import('../open-library-4QSUORI6.js'),
5108
5203
  import('../core/index.js')
5109
5204
  ]);
5110
5205
  const { manager, library, close } = await openLibraryManager2();
5111
5206
  try {
5112
5207
  const newRoot = getGlobalCacheDir2();
5113
- const legacyRoot = path23__default.join(globalSkaileDir2(), "sources");
5208
+ const legacyRoot = path18__default.join(globalSkaileDir2(), "sources");
5114
5209
  const isSourceRow = (l) => l.path.startsWith(newRoot) || l.path.startsWith(legacyRoot);
5115
5210
  const libs = await manager.listLibraries();
5116
5211
  const defs = await library.listAssetDefs();
@@ -5480,10 +5575,15 @@ async function applyChanges() {
5480
5575
  let pruned = 0;
5481
5576
  const appliedAdds = [];
5482
5577
  const appliedRemoves = [];
5578
+ const blockedRemovals = [];
5483
5579
  for (const ref of state.pendingRemoves) {
5484
5580
  try {
5485
5581
  const result = await am.removeWithDependencies(ref);
5486
- if (result.changed) {
5582
+ if (result.blocked) {
5583
+ blockedRemovals.push(
5584
+ `kept ${result.blocked.ref}: required by ${result.blocked.requiredBy.join(", ")} (skaile remove --force overrides)`
5585
+ );
5586
+ } else if (result.changed) {
5487
5587
  removed++;
5488
5588
  pruned += result.pruned.length;
5489
5589
  appliedRemoves.push(ref);
@@ -5510,6 +5610,7 @@ async function applyChanges() {
5510
5610
  if (added > 0) parts.push(pc5.green(`+${added} added`));
5511
5611
  if (removed > 0) parts.push(pc5.red(`-${removed} removed`));
5512
5612
  if (pruned > 0) parts.push(pc5.red(`-${pruned} no longer required`));
5613
+ for (const b of blockedRemovals) parts.push(pc5.yellow(b));
5513
5614
  const softDeps = appliedAdds.length > 0 ? await am.reportSoftDeps(appliedAdds) : [];
5514
5615
  if (softDeps.length > 0) {
5515
5616
  parts.push(pc5.dim(`${softDeps.length} soft dep${softDeps.length === 1 ? "" : "s"} referenced`));
@@ -6059,13 +6160,13 @@ async function run(projectDir) {
6059
6160
  }
6060
6161
  function makeManageCommand() {
6061
6162
  return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
6062
- await run(path23__default.resolve(opts.projectDir));
6163
+ await run(path18__default.resolve(opts.projectDir));
6063
6164
  });
6064
6165
  }
6065
6166
  function makeMcpServerCommand() {
6066
6167
  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) => {
6067
- const path44 = await import('path');
6068
- const projectDir = path44.default.resolve(opts.projectDir);
6168
+ const path43 = await import('path');
6169
+ const projectDir = path43.default.resolve(opts.projectDir);
6069
6170
  const { LogStore, StdoutSink, registerLogStore } = await import('../core/logging.js');
6070
6171
  registerLogStore(
6071
6172
  new LogStore({
@@ -6112,10 +6213,10 @@ function walkFiles(root, match) {
6112
6213
  return;
6113
6214
  }
6114
6215
  for (const entry of entries) {
6115
- const full = path23__default.join(dir, entry.name);
6216
+ const full = path18__default.join(dir, entry.name);
6116
6217
  if (entry.isDirectory()) {
6117
6218
  if (SKIPPED_DIRS.has(entry.name)) continue;
6118
- if (entry.name === "cache" && path23__default.basename(dir) === ".skaile") continue;
6219
+ if (entry.name === "cache" && path18__default.basename(dir) === ".skaile") continue;
6119
6220
  visit(full);
6120
6221
  } else if (entry.isFile() && match(entry.name)) {
6121
6222
  out.push(full);
@@ -6133,14 +6234,14 @@ function applyChanges2(changes) {
6133
6234
  switch (change.type) {
6134
6235
  case "write":
6135
6236
  case "create":
6136
- mkdirSync(path23__default.dirname(change.path), { recursive: true });
6237
+ mkdirSync(path18__default.dirname(change.path), { recursive: true });
6137
6238
  writeFileSync(change.path, change.after, "utf-8");
6138
6239
  break;
6139
6240
  case "delete":
6140
6241
  rmSync(change.path, { force: true });
6141
6242
  break;
6142
6243
  case "move":
6143
- mkdirSync(path23__default.dirname(change.to), { recursive: true });
6244
+ mkdirSync(path18__default.dirname(change.to), { recursive: true });
6144
6245
  writeFileSync(change.to, change.after, "utf-8");
6145
6246
  rmSync(change.from, { force: true });
6146
6247
  break;
@@ -6233,7 +6334,7 @@ function unifiedDiff(before, after, oldLabel, newLabel, context = 3) {
6233
6334
  return `${out.join("\n")}
6234
6335
  `;
6235
6336
  }
6236
- var posix = (p6) => p6.split(path23__default.sep).join("/");
6337
+ var posix = (p6) => p6.split(path18__default.sep).join("/");
6237
6338
  function colorizeDiff(diff) {
6238
6339
  return diff.split("\n").map((line) => {
6239
6340
  if (line.startsWith("+++") || line.startsWith("---")) return S.bold(line);
@@ -6244,7 +6345,7 @@ function colorizeDiff(diff) {
6244
6345
  }).join("\n");
6245
6346
  }
6246
6347
  function renderChange(change, base) {
6247
- const rel = (p6) => posix(path23__default.relative(base, p6) || path23__default.basename(p6));
6348
+ const rel = (p6) => posix(path18__default.relative(base, p6) || path18__default.basename(p6));
6248
6349
  switch (change.type) {
6249
6350
  case "write":
6250
6351
  return unifiedDiff(
@@ -6271,7 +6372,7 @@ ${diff}`;
6271
6372
  }
6272
6373
  }
6273
6374
  function changeLabel(change, base) {
6274
- const rel = (p6) => posix(path23__default.relative(base, p6) || path23__default.basename(p6));
6375
+ const rel = (p6) => posix(path18__default.relative(base, p6) || path18__default.basename(p6));
6275
6376
  switch (change.type) {
6276
6377
  case "write":
6277
6378
  return `modify ${rel(change.path)}`;
@@ -6331,10 +6432,10 @@ function loadAsset(projectDir, id, ref) {
6331
6432
  )
6332
6433
  };
6333
6434
  }
6334
- const manifestPath = path23__default.join(dir, AGENT_MANIFEST_FILE);
6435
+ const manifestPath = path18__default.join(dir, AGENT_MANIFEST_FILE);
6335
6436
  let text;
6336
6437
  try {
6337
- text = fs9__default.readFileSync(manifestPath, "utf-8");
6438
+ text = fs8__default.readFileSync(manifestPath, "utf-8");
6338
6439
  } catch {
6339
6440
  return {
6340
6441
  diagnostic: err(
@@ -6513,12 +6614,12 @@ function findManifestCandidates(rootPath) {
6513
6614
  function walk(dir) {
6514
6615
  let entries;
6515
6616
  try {
6516
- entries = fs9__default.readdirSync(dir, { withFileTypes: true });
6617
+ entries = fs8__default.readdirSync(dir, { withFileTypes: true });
6517
6618
  } catch {
6518
6619
  return;
6519
6620
  }
6520
6621
  for (const entry of entries) {
6521
- const fullPath = path23__default.join(dir, entry.name);
6622
+ const fullPath = path18__default.join(dir, entry.name);
6522
6623
  if (entry.isDirectory()) {
6523
6624
  if (!SKIP_DIRS.has(entry.name)) walk(fullPath);
6524
6625
  } else if (entry.isFile()) {
@@ -6554,10 +6655,10 @@ function checkManifestIdentity(kind, parsed) {
6554
6655
  return null;
6555
6656
  }
6556
6657
  function parseManifestCandidate(c, absRoot) {
6557
- const content = fs9__default.readFileSync(c.filePath, "utf-8");
6658
+ const content = fs8__default.readFileSync(c.filePath, "utf-8");
6558
6659
  const res = parseManifestFile(c.filePath, content);
6559
6660
  if (!res.ok) {
6560
- logErr(`${path23__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 parse error: ${res.reason}`);
6661
+ logErr(`${path18__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 parse error: ${res.reason}`);
6561
6662
  return { kind: "error" };
6562
6663
  }
6563
6664
  return {
@@ -6587,7 +6688,7 @@ function checkComposeKinds(parsed, registry) {
6587
6688
  return diagnostics;
6588
6689
  }
6589
6690
  function validateManifestCandidate(c, parsed, body, absRoot, registry, strictConformance) {
6590
- const relPath = path23__default.relative(absRoot, c.filePath);
6691
+ const relPath = path18__default.relative(absRoot, c.filePath);
6591
6692
  let errors = 0;
6592
6693
  let warnings = 0;
6593
6694
  const identityError = checkManifestIdentity(c.kind, parsed);
@@ -6595,26 +6696,29 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
6595
6696
  logErr(`${relPath} [${c.kind}] \u2014 ${identityError}`);
6596
6697
  errors++;
6597
6698
  }
6598
- if (parsed && typeof parsed === "object") {
6599
- const manifest = parsed;
6600
- const version = declaredVersion(manifest);
6601
- if (version !== void 0 && !isValidSemver(version)) {
6602
- logErr(`${relPath} [${c.kind}] \u2014 version "${version}" is not valid semver`);
6699
+ const dirName = path18__default.basename(path18__default.dirname(c.filePath));
6700
+ const checked = checkAsset(
6701
+ c.kind,
6702
+ parsed ?? {},
6703
+ body,
6704
+ dirName,
6705
+ registry
6706
+ );
6707
+ for (const f of checked.errors) {
6708
+ logErr(`${relPath} [${f.tag}] \u2014 ${f.text}`);
6709
+ errors++;
6710
+ }
6711
+ for (const f of checked.advisories) {
6712
+ const line = `${relPath} [${f.tag}] \u2014 ${f.text}`;
6713
+ if (f.conformance && strictConformance) {
6714
+ logErr(line);
6603
6715
  errors++;
6604
- }
6605
- const dirName = path23__default.basename(path23__default.dirname(c.filePath));
6606
- for (const f of checkAssetManifest(c.kind, manifest, body, dirName)) {
6607
- const line = `${relPath} [${f.tag}] \u2014 ${f.text}`;
6608
- if (f.conformance && strictConformance) {
6609
- logErr(line);
6610
- errors++;
6611
- } else {
6612
- logWarn(line);
6613
- warnings++;
6614
- }
6716
+ } else {
6717
+ logWarn(line);
6718
+ warnings++;
6615
6719
  }
6616
6720
  }
6617
- if (c.kind === "agent" && path23__default.basename(c.filePath) === "agent.yaml") {
6721
+ if (c.kind === "agent" && path18__default.basename(c.filePath) === "agent.yaml") {
6618
6722
  for (const d of [
6619
6723
  ...checkComposeKinds(parsed, registry),
6620
6724
  ...composeSlotDiagnostics(parsed),
@@ -6630,23 +6734,11 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
6630
6734
  }
6631
6735
  }
6632
6736
  }
6633
- const provider = registry.getProvider(c.kind);
6634
- if (!provider) {
6635
- logErr(`${relPath} [${c.kind}] \u2014 unknown_asset_kind: kind "${c.kind}" is not registered`);
6636
- return { errors: errors + 1, warnings };
6637
- }
6638
- const result = provider.validateManifest(parsed);
6639
- if (!result.ok) {
6640
- for (const err2 of result.errors) {
6641
- logErr(`${relPath} [${c.kind}] \u2014 ${err2.path ? `${err2.path}: ` : ""}${err2.message}`);
6642
- }
6643
- errors += result.errors.length;
6644
- }
6645
6737
  return { errors, warnings };
6646
6738
  }
6647
6739
  function validateManifests(rootPath, strictConformance) {
6648
- const absRoot = path23__default.resolve(rootPath);
6649
- if (!fs9__default.existsSync(absRoot)) {
6740
+ const absRoot = path18__default.resolve(rootPath);
6741
+ if (!fs8__default.existsSync(absRoot)) {
6650
6742
  logErr(`Path does not exist: ${absRoot}`);
6651
6743
  return { total: 0, errors: 1, warnings: 0 };
6652
6744
  }
@@ -6674,14 +6766,14 @@ function validateManifests(rootPath, strictConformance) {
6674
6766
  const obj = parseResult.parsed;
6675
6767
  const identity = obj && typeof obj === "object" ? obj[c.kind === "flow" ? "id" : "name"] : null;
6676
6768
  if (typeof identity === "string" && identity.length > 0) {
6677
- const dir = path23__default.dirname(c.filePath);
6769
+ const dir = path18__default.dirname(c.filePath);
6678
6770
  const key = `${c.kind}:${identity}`;
6679
6771
  const first = seenIdentity.get(key);
6680
6772
  if (first === void 0) {
6681
6773
  seenIdentity.set(key, dir);
6682
6774
  } else if (first !== dir) {
6683
6775
  logErr(
6684
- `${path23__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 ${key} is also defined in ${path23__default.relative(absRoot, first) || "."}; two directories cannot share a kind and name (\`skaile library index\` keeps only the first).`
6776
+ `${path18__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 ${key} is also defined in ${path18__default.relative(absRoot, first) || "."}; two directories cannot share a kind and name (\`skaile library index\` keeps only the first).`
6685
6777
  );
6686
6778
  errors++;
6687
6779
  }
@@ -6694,12 +6786,12 @@ function findWorkspaceManifests(rootPath) {
6694
6786
  function walk(dir) {
6695
6787
  let entries;
6696
6788
  try {
6697
- entries = fs9__default.readdirSync(dir, { withFileTypes: true });
6789
+ entries = fs8__default.readdirSync(dir, { withFileTypes: true });
6698
6790
  } catch {
6699
6791
  return;
6700
6792
  }
6701
6793
  for (const entry of entries) {
6702
- const full = path23__default.join(dir, entry.name);
6794
+ const full = path18__default.join(dir, entry.name);
6703
6795
  if (entry.isDirectory()) {
6704
6796
  if (!SKIP_DIRS.has(entry.name)) walk(full);
6705
6797
  } else if (entry.isFile() && /(^|\.)skaile\.yaml$/.test(entry.name)) {
@@ -6762,14 +6854,14 @@ function validateWorkspaceAssets(parsed, relPath) {
6762
6854
  return errors;
6763
6855
  }
6764
6856
  function validateWorkspaceManifests(rootPath) {
6765
- const absRoot = path23__default.resolve(rootPath);
6857
+ const absRoot = path18__default.resolve(rootPath);
6766
6858
  const files = findWorkspaceManifests(absRoot);
6767
6859
  let errors = 0;
6768
6860
  for (const file of files) {
6769
- const relPath = path23__default.relative(absRoot, file);
6861
+ const relPath = path18__default.relative(absRoot, file);
6770
6862
  let parsed;
6771
6863
  try {
6772
- parsed = parse(fs9__default.readFileSync(file, "utf-8")) ?? {};
6864
+ parsed = parse(fs8__default.readFileSync(file, "utf-8")) ?? {};
6773
6865
  } catch (e) {
6774
6866
  logErr(`${relPath} \u2014 parse error: ${e instanceof Error ? e.message : String(e)}`);
6775
6867
  errors++;
@@ -6777,7 +6869,7 @@ function validateWorkspaceManifests(rootPath) {
6777
6869
  }
6778
6870
  errors += validateWorkspaceRefs(collectWorkspaceRefFields(parsed), relPath);
6779
6871
  errors += validateWorkspaceAssets(parsed, relPath);
6780
- for (const d of checkAgentInstances(path23__default.dirname(file), parsed)) {
6872
+ for (const d of checkAgentInstances(path18__default.dirname(file), parsed)) {
6781
6873
  const line = `${relPath} [agents] \u2014 ${d.code}: ${d.path ? `${d.path}: ` : ""}${d.message}`;
6782
6874
  if (d.severity === "error") {
6783
6875
  logErr(line);
@@ -6790,7 +6882,7 @@ function validateWorkspaceManifests(rootPath) {
6790
6882
  return { total: files.length, errors };
6791
6883
  }
6792
6884
  function validatePublishManifestRoots(rootPath) {
6793
- const absRoot = path23__default.resolve(rootPath);
6885
+ const absRoot = path18__default.resolve(rootPath);
6794
6886
  const manifest = loadSkPublishManifest(absRoot);
6795
6887
  if (!manifest) return 0;
6796
6888
  const missing = missingRootAssets(absRoot, manifest);
@@ -6802,7 +6894,7 @@ function validatePublishManifestRoots(rootPath) {
6802
6894
  return missing.length;
6803
6895
  }
6804
6896
  function validatePublishManifestRequires(rootPath) {
6805
- const problems = manifestRequiresProblems(path23__default.resolve(rootPath));
6897
+ const problems = manifestRequiresProblems(path18__default.resolve(rootPath));
6806
6898
  for (const p6 of problems) {
6807
6899
  logErr(
6808
6900
  `${SKAILE_MANIFEST_FILENAME} [assets] \u2014 ${p6.asset}: ${p6.message}. Use the \`kind:@<publisher>/name[#version]\` form.`
@@ -6810,16 +6902,21 @@ function validatePublishManifestRequires(rootPath) {
6810
6902
  }
6811
6903
  return problems.length;
6812
6904
  }
6905
+ function validatePublishManifestPublisherSlugs(rootPath) {
6906
+ const problems = manifestPublisherProblems(path18__default.resolve(rootPath));
6907
+ for (const message of problems) logErr(message);
6908
+ return problems.length;
6909
+ }
6813
6910
  function validatePublishManifestVersions(rootPath) {
6814
- const absRoot = path23__default.resolve(rootPath);
6911
+ const absRoot = path18__default.resolve(rootPath);
6815
6912
  const manifest = loadSkPublishManifest(absRoot);
6816
6913
  if (!manifest || manifest.source) return 0;
6817
6914
  let warnings = 0;
6818
6915
  for (const a of manifest.assets ?? []) {
6819
6916
  if (!a.root || a.source || !a.version) continue;
6820
- const file = findAssetManifestFile(path23__default.join(absRoot, a.root), a.kind, a.name);
6917
+ const file = findAssetManifestFile(path18__default.join(absRoot, a.root), a.kind, a.name);
6821
6918
  if (!file) continue;
6822
- const res = parseManifestFile(file, fs9__default.readFileSync(file, "utf-8"));
6919
+ const res = parseManifestFile(file, fs8__default.readFileSync(file, "utf-8"));
6823
6920
  if (!res.ok) continue;
6824
6921
  const fileVersion = declaredVersion(res.data);
6825
6922
  if (fileVersion === void 0 || fileVersion === a.version) continue;
@@ -6827,7 +6924,7 @@ function validatePublishManifestVersions(rootPath) {
6827
6924
  manifestVersionMismatchMessage(
6828
6925
  assetEntryRef(a, manifest),
6829
6926
  a.version,
6830
- toPosix(path23__default.relative(absRoot, file)),
6927
+ toPosix(path18__default.relative(absRoot, file)),
6831
6928
  fileVersion
6832
6929
  )
6833
6930
  );
@@ -6836,7 +6933,7 @@ function validatePublishManifestVersions(rootPath) {
6836
6933
  return warnings;
6837
6934
  }
6838
6935
  function validatePublishManifestPublishers(rootPath) {
6839
- const absRoot = path23__default.resolve(rootPath);
6936
+ const absRoot = path18__default.resolve(rootPath);
6840
6937
  const manifest = loadSkPublishManifest(absRoot);
6841
6938
  if (!manifest || manifest.source) return 0;
6842
6939
  const bare = (p6) => p6.trim().replace(/^@/, "");
@@ -6844,15 +6941,15 @@ function validatePublishManifestPublishers(rootPath) {
6844
6941
  for (const a of manifest.assets ?? []) {
6845
6942
  const resolved = a.publisher ?? manifest.publisher;
6846
6943
  if (!a.root || a.source || !resolved) continue;
6847
- const file = findAssetManifestFile(path23__default.join(absRoot, a.root), a.kind, a.name);
6944
+ const file = findAssetManifestFile(path18__default.join(absRoot, a.root), a.kind, a.name);
6848
6945
  if (!file) continue;
6849
- const res = parseManifestFile(file, fs9__default.readFileSync(file, "utf-8"));
6946
+ const res = parseManifestFile(file, fs8__default.readFileSync(file, "utf-8"));
6850
6947
  if (!res.ok) continue;
6851
6948
  const meta = res.data.metadata;
6852
6949
  const declared = meta !== null && typeof meta === "object" ? meta.publisher : null;
6853
6950
  if (typeof declared !== "string" || bare(declared) === bare(resolved)) continue;
6854
6951
  logWarn(
6855
- `${toPosix(path23__default.relative(absRoot, file))} [publisher] \u2014 metadata.publisher "${bare(declared)}" differs from the manifest publisher "${bare(resolved)}" for ${assetEntryRef(a, manifest)}. The manifest wins and the file value is ignored: delete \`metadata.publisher\` from the file, or set the publisher in ${SKAILE_MANIFEST_FILENAME}.`
6952
+ `${toPosix(path18__default.relative(absRoot, file))} [publisher] \u2014 metadata.publisher "${bare(declared)}" differs from the manifest publisher "${bare(resolved)}" for ${assetEntryRef(a, manifest)}. The manifest wins and the file value is ignored: delete \`metadata.publisher\` from the file, or set the publisher in ${SKAILE_MANIFEST_FILENAME}.`
6856
6953
  );
6857
6954
  warnings++;
6858
6955
  }
@@ -6860,7 +6957,7 @@ function validatePublishManifestPublishers(rootPath) {
6860
6957
  }
6861
6958
  var EXCLUDED_PATHS = ["skaileup-shared/", "external/", "docs/"];
6862
6959
  function toPosix(p6) {
6863
- return p6.split(path23__default.sep).join("/");
6960
+ return p6.split(path18__default.sep).join("/");
6864
6961
  }
6865
6962
  function isExcludedPath(relPath) {
6866
6963
  const rel = toPosix(relPath);
@@ -6870,20 +6967,23 @@ var VERSIONED_KINDS = {
6870
6967
  skill: true,
6871
6968
  agent: true,
6872
6969
  flow: true,
6873
- prompt: true
6970
+ prompt: true,
6971
+ preset: true,
6972
+ contract: true
6874
6973
  };
6875
6974
  function readAssetVersion(c) {
6876
6975
  const kind = c.kind;
6877
- const fileName = path23__default.basename(c.filePath);
6878
- const dirName = path23__default.basename(path23__default.dirname(c.filePath));
6879
- const content = fs9__default.readFileSync(c.filePath, "utf-8");
6976
+ const fileName = path18__default.basename(c.filePath);
6977
+ const dirName = path18__default.basename(path18__default.dirname(c.filePath));
6978
+ const content = fs8__default.readFileSync(c.filePath, "utf-8");
6880
6979
  if (c.filePath.endsWith(".md")) {
6881
- const fm = parseSkillFrontmatter(content);
6980
+ const res = parseManifestFile(c.filePath, content);
6981
+ const data = res.ok ? res.data : {};
6882
6982
  const stem = fileName.replace(/\.prompt\.md$/, "");
6883
6983
  return {
6884
6984
  kind,
6885
- name: fm?.name ?? (kind === "prompt" ? stem : dirName),
6886
- version: fm?.metadata?.version ?? "",
6985
+ name: typeof data.name === "string" ? data.name : kind === "prompt" ? stem : dirName,
6986
+ version: declaredVersion(data) ?? "",
6887
6987
  filePath: c.filePath
6888
6988
  };
6889
6989
  }
@@ -6908,26 +7008,26 @@ function readAssetVersion(c) {
6908
7008
  };
6909
7009
  }
6910
7010
  function collectAssetVersions(root) {
6911
- if (!fs9__default.existsSync(root)) return [];
7011
+ if (!fs8__default.existsSync(root)) return [];
6912
7012
  const assets = [];
6913
7013
  for (const c of findManifestCandidates(root)) {
6914
7014
  if (!VERSIONED_KINDS[c.kind]) continue;
6915
7015
  if (c.filePath.endsWith(".flow.json")) continue;
6916
- if (isExcludedPath(path23__default.relative(root, c.filePath))) continue;
7016
+ if (isExcludedPath(path18__default.relative(root, c.filePath))) continue;
6917
7017
  assets.push(readAssetVersion(c));
6918
7018
  }
6919
7019
  return assets;
6920
7020
  }
6921
7021
  function assetLocation(a, root) {
6922
- return toPosix(path23__default.relative(root, a.filePath));
7022
+ return toPosix(path18__default.relative(root, a.filePath));
6923
7023
  }
6924
7024
  function findChangelogUnit(assetRelPath, root) {
6925
- let dir = path23__default.posix.dirname(toPosix(assetRelPath));
7025
+ let dir = path18__default.posix.dirname(toPosix(assetRelPath));
6926
7026
  for (; ; ) {
6927
7027
  const candidate = dir === "." ? "CHANGELOG.md" : `${dir}/CHANGELOG.md`;
6928
- if (fs9__default.existsSync(path23__default.join(root, candidate))) return candidate;
7028
+ if (fs8__default.existsSync(path18__default.join(root, candidate))) return candidate;
6929
7029
  if (dir === ".") return null;
6930
- dir = path23__default.posix.dirname(dir);
7030
+ dir = path18__default.posix.dirname(dir);
6931
7031
  }
6932
7032
  }
6933
7033
  function checkChangelogUnits(modifiedFiles, root) {
@@ -6945,9 +7045,6 @@ function checkChangelogUnits(modifiedFiles, root) {
6945
7045
  const stale = [...units].filter((u) => !modified.has(u));
6946
7046
  return { updated, stale, orphans };
6947
7047
  }
6948
- function isValidSemver(v) {
6949
- return SEMVER_RE.test(v);
6950
- }
6951
7048
  function extractVersionFromContent(filePath, content) {
6952
7049
  if (filePath.endsWith(".yaml")) {
6953
7050
  const parsed2 = parse(content);
@@ -6962,13 +7059,15 @@ function checkAssetVersions(assets, root) {
6962
7059
  let errors = 0;
6963
7060
  const warnings = 0;
6964
7061
  for (const a of assets) {
7062
+ const location = assetLocation(a, root);
6965
7063
  if (!a.version) {
6966
- logErr(`${a.kind}:${a.name} (${assetLocation(a, root)}) \u2014 missing version`);
7064
+ logErr(`${a.kind}:${a.name} (${location}) \u2014 missing version`);
6967
7065
  errors++;
6968
- } else if (!isValidSemver(a.version)) {
6969
- logErr(
6970
- `${a.kind}:${a.name} (${assetLocation(a, root)}) \u2014 version "${a.version}" is not valid semver`
6971
- );
7066
+ continue;
7067
+ }
7068
+ const invalid = invalidSemverText(a.version);
7069
+ if (invalid) {
7070
+ logErr(`${a.kind}:${a.name} (${location}) \u2014 ${invalid}`);
6972
7071
  errors++;
6973
7072
  }
6974
7073
  }
@@ -6978,7 +7077,7 @@ function checkVersionBumps(assets, root) {
6978
7077
  let warnings = 0;
6979
7078
  for (const a of assets) {
6980
7079
  if (!a.version) continue;
6981
- const relPath = toPosix(path23__default.relative(root, a.filePath));
7080
+ const relPath = toPosix(path18__default.relative(root, a.filePath));
6982
7081
  try {
6983
7082
  const headContent = execFileSync("git", ["show", `HEAD:./${relPath}`], {
6984
7083
  cwd: root,
@@ -7011,7 +7110,7 @@ function checkFlowVersionPins(assets, root) {
7011
7110
  pins = flowSkillVersionPins(loadFlow(f.filePath));
7012
7111
  } catch (err2) {
7013
7112
  logWarn(
7014
- `flow:${f.name} (${path23__default.relative(root, f.filePath)}) \u2014 could not be read: ${err2 instanceof Error ? err2.message : err2}`
7113
+ `flow:${f.name} (${path18__default.relative(root, f.filePath)}) \u2014 could not be read: ${err2 instanceof Error ? err2.message : err2}`
7015
7114
  );
7016
7115
  warnings++;
7017
7116
  continue;
@@ -7029,16 +7128,16 @@ function checkFlowVersionPins(assets, root) {
7029
7128
  }
7030
7129
  function resolveCheckRoot(pathArg) {
7031
7130
  if (pathArg) {
7032
- const abs = path23__default.resolve(pathArg);
7033
- if (!fs9__default.existsSync(abs)) {
7131
+ const abs = path18__default.resolve(pathArg);
7132
+ if (!fs8__default.existsSync(abs)) {
7034
7133
  logErr(`Path does not exist: ${abs}`);
7035
7134
  return null;
7036
7135
  }
7037
7136
  return abs;
7038
7137
  }
7039
- for (let dir = process.cwd(); ; dir = path23__default.dirname(dir)) {
7040
- if (fs9__default.existsSync(path23__default.join(dir, SKAILE_MANIFEST_FILENAME))) return dir;
7041
- if (path23__default.dirname(dir) === dir) return AI_RESOURCES;
7138
+ for (let dir = process.cwd(); ; dir = path18__default.dirname(dir)) {
7139
+ if (fs8__default.existsSync(path18__default.join(dir, SKAILE_MANIFEST_FILENAME))) return dir;
7140
+ if (path18__default.dirname(dir) === dir) return AI_RESOURCES;
7042
7141
  }
7043
7142
  }
7044
7143
  function changedFiles(root, ref) {
@@ -7073,7 +7172,7 @@ function runVersionsCheck(pathArg, opts) {
7073
7172
  process.exit(1);
7074
7173
  return;
7075
7174
  }
7076
- const changedAbs = new Set(changed.map((f) => path23__default.resolve(root, f)));
7175
+ const changedAbs = new Set(changed.map((f) => path18__default.resolve(root, f)));
7077
7176
  assets = assets.filter((a) => changedAbs.has(a.filePath));
7078
7177
  }
7079
7178
  logInfo(`Checking versions in ${root}`);
@@ -7105,8 +7204,8 @@ function makeValidateCommand() {
7105
7204
  cmd.argument("[path]", "Path to asset repo or directory to validate", ".").option(
7106
7205
  "--strict-conformance",
7107
7206
  "Treat Agent Skills (agentskills.io) standard findings as errors"
7108
- ).action((targetPath, opts) => {
7109
- const absPath = path23__default.resolve(targetPath);
7207
+ ).action(async (targetPath, opts) => {
7208
+ const absPath = path18__default.resolve(targetPath);
7110
7209
  logInfo(`Validating manifests in ${absPath}`);
7111
7210
  const { total, errors, warnings } = validateManifests(
7112
7211
  absPath,
@@ -7114,15 +7213,19 @@ function makeValidateCommand() {
7114
7213
  );
7115
7214
  const ws = validateWorkspaceManifests(absPath);
7116
7215
  const rootErrors = validatePublishManifestRoots(absPath);
7216
+ const slugErrors = validatePublishManifestPublisherSlugs(absPath);
7117
7217
  const requiresErrors = validatePublishManifestRequires(absPath);
7118
7218
  const versionWarnings = validatePublishManifestVersions(absPath);
7119
7219
  const publisherWarnings = validatePublishManifestPublishers(absPath);
7120
- const totalErrors = errors + ws.errors + rootErrors + requiresErrors;
7220
+ const dependencyProblems = await unresolvedManifestDependencies(absPath);
7221
+ for (const w of dependencyProblems) logWarn(w);
7222
+ const dependencyWarnings = dependencyProblems.length;
7223
+ const totalErrors = errors + ws.errors + rootErrors + slugErrors + requiresErrors;
7121
7224
  console.log();
7122
7225
  warnIgnoredDomainFiles(absPath);
7123
7226
  warnLegacyBundleFiles(absPath);
7124
7227
  logInfo(`Scanned ${total} asset manifest(s) and ${ws.total} skaile.yaml file(s)`);
7125
- const totalWarnings = warnings + versionWarnings + publisherWarnings;
7228
+ const totalWarnings = warnings + versionWarnings + publisherWarnings + dependencyWarnings;
7126
7229
  if (totalWarnings > 0) logWarn(`${totalWarnings} warning(s)`);
7127
7230
  if (totalErrors === 0) {
7128
7231
  logOk("All manifests valid");
@@ -7192,7 +7295,7 @@ function itemFromRef(raw, defaultKind, ctx) {
7192
7295
  return { kind: prefixed[1], ref: value };
7193
7296
  }
7194
7297
  if (PATH_LIKE.test(value)) return { kind: defaultKind, ref: value };
7195
- if (defaultKind === "skill" && !value.includes("/") && existsSync(path23__default.join(ctx.agentDir, "skills", value, "SKILL.md"))) {
7298
+ if (defaultKind === "skill" && !value.includes("/") && existsSync(path18__default.join(ctx.agentDir, "skills", value, "SKILL.md"))) {
7196
7299
  return { kind: "skill", ref: `./skills/${value}` };
7197
7300
  }
7198
7301
  return { kind: defaultKind, ref: `${defaultKind}:${value}` };
@@ -7328,7 +7431,7 @@ function migrateAgentYaml(source, options) {
7328
7431
  manual.push("metadata.soul: not a string; left unchanged");
7329
7432
  continue;
7330
7433
  }
7331
- if (path23__default.posix.basename(soul.replace(/\\/g, "/")).toLowerCase() === "soul.md") {
7434
+ if (path18__default.posix.basename(soul.replace(/\\/g, "/")).toLowerCase() === "soul.md") {
7332
7435
  notes.push("metadata.soul \u2192 dropped (SOUL.md is a convention file)");
7333
7436
  } else {
7334
7437
  derived.push({ kind: "persona", ref: soul });
@@ -7562,7 +7665,7 @@ function migrateSubagents(skaileYamlPath, source) {
7562
7665
  if (!isMap(agentNode)) return void 0;
7563
7666
  const subNode = agentNode.get("subagents", true);
7564
7667
  if (!isMap(subNode)) return void 0;
7565
- const dir = path23__default.dirname(skaileYamlPath);
7668
+ const dir = path18__default.dirname(skaileYamlPath);
7566
7669
  const notes = [];
7567
7670
  const manual = [];
7568
7671
  const changes = [];
@@ -7580,10 +7683,10 @@ function migrateSubagents(skaileYamlPath, source) {
7580
7683
  continue;
7581
7684
  }
7582
7685
  const id = instanceId(name);
7583
- const assetDir = path23__default.join(dir, ".skaile", "agents", id);
7686
+ const assetDir = path18__default.join(dir, ".skaile", "agents", id);
7584
7687
  if (takenIds.has(id) || existsSync(assetDir)) {
7585
7688
  manual.push(
7586
- `agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${path23__default.relative(dir, assetDir)} already exists`}; left in place`
7689
+ `agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${path18__default.relative(dir, assetDir)} already exists`}; left in place`
7587
7690
  );
7588
7691
  continue;
7589
7692
  }
@@ -7607,13 +7710,13 @@ function migrateSubagents(skaileYamlPath, source) {
7607
7710
  manifest.tools = { ...allowed ? { allowed } : {}, ...denied ? { denied } : {} };
7608
7711
  }
7609
7712
  const text = stringify(manifest, { lineWidth: 0 });
7610
- const manifestPath = path23__default.join(assetDir, "agent.yaml");
7713
+ const manifestPath = path18__default.join(assetDir, "agent.yaml");
7611
7714
  changes.push({ type: "create", path: manifestPath, after: text });
7612
7715
  assetManifests.push({ file: manifestPath, text });
7613
7716
  if (typeof spec.prompt === "string" && spec.prompt.trim() !== "") {
7614
7717
  changes.push({
7615
7718
  type: "create",
7616
- path: path23__default.join(assetDir, "SOUL.md"),
7719
+ path: path18__default.join(assetDir, "SOUL.md"),
7617
7720
  after: `${spec.prompt.replace(/\s+$/, "")}
7618
7721
  `
7619
7722
  });
@@ -7672,7 +7775,7 @@ function validateMigratedAgent(text, registry) {
7672
7775
  function collectAgentFiles(paths) {
7673
7776
  const files = /* @__PURE__ */ new Set();
7674
7777
  for (const input of paths) {
7675
- const abs = path23__default.resolve(input);
7778
+ const abs = path18__default.resolve(input);
7676
7779
  if (!existsSync(abs)) continue;
7677
7780
  if (statSync(abs).isDirectory()) {
7678
7781
  for (const f of walkFiles(abs, (b) => b === "agent.yaml" || b === "skaile.yaml"))
@@ -7689,7 +7792,7 @@ function planAgentMigration(options) {
7689
7792
  const reports = [];
7690
7793
  for (const file of collectAgentFiles(options.paths)) {
7691
7794
  const source = readText(file);
7692
- const base = path23__default.basename(file);
7795
+ const base = path18__default.basename(file);
7693
7796
  if (base === "skaile.yaml") {
7694
7797
  const result = migrateSubagents(file, source);
7695
7798
  if (!result) continue;
@@ -7697,7 +7800,7 @@ function planAgentMigration(options) {
7697
7800
  for (const asset of result.assetManifests) {
7698
7801
  const v = validateMigratedAgent(asset.text, options.registry);
7699
7802
  validation2.errors.push(
7700
- ...v.errors.map((e) => `${path23__default.basename(path23__default.dirname(asset.file))}: ${e}`)
7803
+ ...v.errors.map((e) => `${path18__default.basename(path18__default.dirname(asset.file))}: ${e}`)
7701
7804
  );
7702
7805
  validation2.warnings.push(...v.warnings);
7703
7806
  }
@@ -7725,7 +7828,7 @@ function planAgentMigration(options) {
7725
7828
  });
7726
7829
  continue;
7727
7830
  }
7728
- migration = migrateAgentYaml(source, { agentDir: path23__default.dirname(file), knownKinds });
7831
+ migration = migrateAgentYaml(source, { agentDir: path18__default.dirname(file), knownKinds });
7729
7832
  } catch (error) {
7730
7833
  reports.push({
7731
7834
  file,
@@ -7753,8 +7856,9 @@ function planAgentMigration(options) {
7753
7856
  return { changes, reports };
7754
7857
  }
7755
7858
  var DEFAULT_PUBLISHER = "skaile-ai";
7859
+ var PRESET_DEFAULT_VERSION = "1.0.0";
7756
7860
  var FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
7757
- var posix2 = (p6) => p6.split(path23__default.sep).join("/");
7861
+ var posix2 = (p6) => p6.split(path18__default.sep).join("/");
7758
7862
  var MOVED_KINDS = { persona: "PERSONA.md", ruleset: "RULESET.md" };
7759
7863
  var KIND_MANIFEST_FILES = /* @__PURE__ */ new Set(["PERSONA.md", "RULESET.md", "SKILL.md"]);
7760
7864
  function readFrontmatterType(text) {
@@ -7785,14 +7889,14 @@ function planMarkdownMoves(root, knownKinds, manual, unknownTypes) {
7785
7889
  if (!text.startsWith("---")) continue;
7786
7890
  const found = readFrontmatterType(text);
7787
7891
  if (!found) continue;
7788
- const base = path23__default.basename(file);
7789
- const inAgentParts = file.split(path23__default.sep).includes("_agent-parts");
7892
+ const base = path18__default.basename(file);
7893
+ const inAgentParts = file.split(path18__default.sep).includes("_agent-parts");
7790
7894
  const targetName = MOVED_KINDS[found.type];
7791
7895
  if (targetName !== void 0 && !KIND_MANIFEST_FILES.has(base)) {
7792
- const to = path23__default.join(path23__default.dirname(file), base.replace(/\.md$/i, ""), targetName);
7896
+ const to = path18__default.join(path18__default.dirname(file), base.replace(/\.md$/i, ""), targetName);
7793
7897
  if (existsSync(to) || targets.has(to)) {
7794
7898
  manual.push(
7795
- `${posix2(path23__default.relative(root, file))}: ${posix2(path23__default.relative(root, to))} already exists; not moved`
7899
+ `${posix2(path18__default.relative(root, file))}: ${posix2(path18__default.relative(root, to))} already exists; not moved`
7796
7900
  );
7797
7901
  continue;
7798
7902
  }
@@ -7813,13 +7917,13 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
7813
7917
  const changes = [];
7814
7918
  for (const file of walkFiles(root, (b) => b === "agent.yaml")) {
7815
7919
  const source = readText(file);
7816
- const agentDir = path23__default.dirname(file);
7920
+ const agentDir = path18__default.dirname(file);
7817
7921
  let hits = 0;
7818
7922
  const refRewrite = (_kind, ref) => {
7819
- const moved = byOldPath.get(path23__default.resolve(agentDir, ref));
7923
+ const moved = byOldPath.get(path18__default.resolve(agentDir, ref));
7820
7924
  if (moved === void 0) return ref;
7821
7925
  hits++;
7822
- const rel = posix2(path23__default.relative(agentDir, moved));
7926
+ const rel = posix2(path18__default.relative(agentDir, moved));
7823
7927
  return rel.startsWith(".") ? rel : `./${rel}`;
7824
7928
  };
7825
7929
  let output;
@@ -7836,7 +7940,7 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
7836
7940
  if (hits === 0 || output === source) continue;
7837
7941
  changes.push({ type: "write", path: file, before: source, after: output });
7838
7942
  notes.push(
7839
- `${posix2(path23__default.relative(root, file))}: persona/ruleset refs \u2192 composes items at the new paths`
7943
+ `${posix2(path18__default.relative(root, file))}: persona/ruleset refs \u2192 composes items at the new paths`
7840
7944
  );
7841
7945
  }
7842
7946
  return changes;
@@ -7847,12 +7951,12 @@ function presetItemRef(dep, publisher) {
7847
7951
  const [, kind, rest] = match;
7848
7952
  return rest.startsWith("@") ? dep.trim() : `${kind}:@${publisher}/${rest}`;
7849
7953
  }
7850
- function presetText(name, description, refs, publisher) {
7954
+ function presetText(name, description, refs, publisher, version) {
7851
7955
  return stringify(
7852
7956
  {
7853
7957
  publisher,
7854
7958
  name,
7855
- version: "1.0.0",
7959
+ version,
7856
7960
  description: description && description.trim() !== "" ? description : `Preset ${name}`,
7857
7961
  items: refs.map((ref) => ({ ref }))
7858
7962
  },
@@ -7861,14 +7965,14 @@ function presetText(name, description, refs, publisher) {
7861
7965
  }
7862
7966
  function skillDirs(dir) {
7863
7967
  try {
7864
- return readdirSync(path23__default.join(dir, "skills"), { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync(path23__default.join(dir, "skills", e.name, "SKILL.md"))).map((e) => e.name).sort();
7968
+ 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();
7865
7969
  } catch {
7866
7970
  return [];
7867
7971
  }
7868
7972
  }
7869
7973
  function repoPublisher(root) {
7870
7974
  for (const name of ["skaile.manifest.yaml", "skaile.yaml"]) {
7871
- const file = path23__default.join(root, name);
7975
+ const file = path18__default.join(root, name);
7872
7976
  if (!existsSync(file)) continue;
7873
7977
  try {
7874
7978
  const parsed = parse(readText(file));
@@ -7884,9 +7988,9 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
7884
7988
  const changes = [];
7885
7989
  const presets = [];
7886
7990
  const handled = /* @__PURE__ */ new Set();
7887
- const rel = (p6) => posix2(path23__default.relative(root, p6));
7991
+ const rel = (p6) => posix2(path18__default.relative(root, p6));
7888
7992
  const convert = (name, bundleFile, dir) => {
7889
- const target = path23__default.join(dir, `${name}.preset.yaml`);
7993
+ const target = path18__default.join(dir, `${name}.preset.yaml`);
7890
7994
  if (existsSync(target)) {
7891
7995
  manual.push(`${rel(target)} already exists; bundle ${name} not converted`);
7892
7996
  return;
@@ -7894,11 +7998,16 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
7894
7998
  let description;
7895
7999
  let refs = [];
7896
8000
  let before;
8001
+ let version = PRESET_DEFAULT_VERSION;
8002
+ let versionNote;
7897
8003
  if (bundleFile && existsSync(bundleFile)) {
7898
8004
  before = readText(bundleFile);
7899
8005
  const parsed = parse(before);
7900
8006
  if (isRecord(parsed)) {
7901
8007
  if (typeof parsed.description === "string") description = parsed.description;
8008
+ const declared = typeof parsed.version === "string" || typeof parsed.version === "number" ? String(parsed.version) : void 0;
8009
+ if (declared !== void 0 && SEMVER_RE.test(declared)) version = declared;
8010
+ else if (declared !== void 0) versionNote = `version ${declared} \u2192 ${version}`;
7902
8011
  const deps = Array.isArray(parsed.dependencies) ? parsed.dependencies : [];
7903
8012
  refs = deps.filter((d) => typeof d === "string").map((d) => presetItemRef(d, publisher));
7904
8013
  if (refs.length !== deps.length) {
@@ -7912,11 +8021,11 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
7912
8021
  }
7913
8022
  if (refs.length === 0) {
7914
8023
  manual.push(
7915
- `bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(path23__default.join(dir, "skills"))}`}; no preset generated`
8024
+ `bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(path18__default.join(dir, "skills"))}`}; no preset generated`
7916
8025
  );
7917
8026
  return;
7918
8027
  }
7919
- const after = presetText(name, description, refs, publisher);
8028
+ const after = presetText(name, description, refs, publisher, version);
7920
8029
  if (before !== void 0 && bundleFile) {
7921
8030
  changes.push({ type: "move", from: bundleFile, to: target, before, after });
7922
8031
  handled.add(bundleFile);
@@ -7928,24 +8037,26 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
7928
8037
  file: target,
7929
8038
  ...bundleFile && before !== void 0 ? { bundleFile } : {}
7930
8039
  });
7931
- notes.push(`bundle ${name} \u2192 ${rel(target)} (${refs.length} items)`);
8040
+ notes.push(
8041
+ `bundle ${name} \u2192 ${rel(target)} (${refs.length} items${versionNote ? `, ${versionNote}` : ""})`
8042
+ );
7932
8043
  };
7933
8044
  for (const { file, raw } of skaileYamls) {
7934
8045
  const assets = Array.isArray(raw.assets) ? raw.assets : [];
7935
8046
  for (const entry of assets) {
7936
8047
  if (!isRecord(entry) || entry.kind !== "bundle" || typeof entry.name !== "string") continue;
7937
- const baseDir = path23__default.dirname(file);
7938
- const entryRoot = typeof entry.root === "string" ? path23__default.join(baseDir, entry.root) : baseDir;
8048
+ const baseDir = path18__default.dirname(file);
8049
+ const entryRoot = typeof entry.root === "string" ? path18__default.join(baseDir, entry.root) : baseDir;
7939
8050
  const files = Array.isArray(entry.files) ? entry.files : [];
7940
8051
  const bundleName = files.find(
7941
8052
  (f) => typeof f === "string" && f.endsWith(".bundle.yaml")
7942
8053
  );
7943
- convert(entry.name, bundleName ? path23__default.join(entryRoot, bundleName) : void 0, entryRoot);
8054
+ convert(entry.name, bundleName ? path18__default.join(entryRoot, bundleName) : void 0, entryRoot);
7944
8055
  }
7945
8056
  }
7946
8057
  for (const bundleFile of walkFiles(root, (b) => b.endsWith(".bundle.yaml"))) {
7947
8058
  if (handled.has(bundleFile)) continue;
7948
- const base = path23__default.basename(bundleFile);
8059
+ const base = path18__default.basename(bundleFile);
7949
8060
  let name = base.replace(/\.bundle\.yaml$/, "");
7950
8061
  try {
7951
8062
  const parsed = parse(readText(bundleFile));
@@ -7954,7 +8065,7 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
7954
8065
  } catch {
7955
8066
  }
7956
8067
  if (presets.some((p6) => p6.bundleFile === bundleFile)) continue;
7957
- convert(name, bundleFile, path23__default.dirname(bundleFile));
8068
+ convert(name, bundleFile, path18__default.dirname(bundleFile));
7958
8069
  }
7959
8070
  return changes;
7960
8071
  }
@@ -7964,8 +8075,8 @@ function planSkaileYaml(root, file, source, notes, manual) {
7964
8075
  if (doc.errors.length > 0 || !isMap(doc.contents)) return [];
7965
8076
  const map = doc.contents;
7966
8077
  const raw = doc.toJS();
7967
- const dir = path23__default.dirname(file);
7968
- const rel = (p6) => posix2(path23__default.relative(root, p6));
8078
+ const dir = path18__default.dirname(file);
8079
+ const rel = (p6) => posix2(path18__default.relative(root, p6));
7969
8080
  const changes = [];
7970
8081
  let changed = false;
7971
8082
  const deps = map.get("dependencies", true);
@@ -7982,7 +8093,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
7982
8093
  const hasPublication = PUBLICATION_KEYS.some((k) => raw[k] !== void 0);
7983
8094
  let remove = false;
7984
8095
  if (hasPublication) {
7985
- const manifestPath = path23__default.join(dir, "skaile.manifest.yaml");
8096
+ const manifestPath = path18__default.join(dir, "skaile.manifest.yaml");
7986
8097
  if (existsSync(manifestPath)) {
7987
8098
  manual.push(
7988
8099
  `${rel(file)}: publisher/version/assets left in place \u2014 ${rel(manifestPath)} already exists; merge by hand`
@@ -8039,7 +8150,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
8039
8150
  return changes;
8040
8151
  }
8041
8152
  function planAssetMigration(options) {
8042
- const root = path23__default.resolve(options.root);
8153
+ const root = path18__default.resolve(options.root);
8043
8154
  const knownKinds = new Set(options.registry.getAllKinds());
8044
8155
  const notes = [];
8045
8156
  const manual = [];
@@ -8047,7 +8158,7 @@ function planAssetMigration(options) {
8047
8158
  const { moves, changes: moveChanges } = planMarkdownMoves(root, knownKinds, manual, unknownTypes);
8048
8159
  for (const move of moves) {
8049
8160
  notes.push(
8050
- `${posix2(path23__default.relative(root, move.from))} \u2192 ${posix2(path23__default.relative(root, move.to))} (${move.kind})`
8161
+ `${posix2(path18__default.relative(root, move.from))} \u2192 ${posix2(path18__default.relative(root, move.to))} (${move.kind})`
8051
8162
  );
8052
8163
  }
8053
8164
  const agentChanges = planAgentRefRewrites(root, moves, knownKinds, notes);
@@ -8059,7 +8170,7 @@ function planAssetMigration(options) {
8059
8170
  const raw = parse(source);
8060
8171
  if (isRecord(raw)) skaileYamls.push({ file, source, raw });
8061
8172
  } catch {
8062
- manual.push(`${posix2(path23__default.relative(root, file))}: invalid YAML; skipped`);
8173
+ manual.push(`${posix2(path18__default.relative(root, file))}: invalid YAML; skipped`);
8063
8174
  }
8064
8175
  }
8065
8176
  const publisher = repoPublisher(root);
@@ -8213,7 +8324,7 @@ function workspaceConfigFiles(dir) {
8213
8324
  } catch {
8214
8325
  return [];
8215
8326
  }
8216
- return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) => path23__default.join(dir, name));
8327
+ return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) => path18__default.join(dir, name));
8217
8328
  }
8218
8329
  function readAgentConfigBlock(raw) {
8219
8330
  const key = AGENT_CONFIG_KEYS.find((candidate) => raw[candidate] !== void 0);
@@ -8225,7 +8336,7 @@ function readAgentConfigBlock(raw) {
8225
8336
  return flat ? { key, profiles: { default: profiles }, flat } : { key, profiles, flat };
8226
8337
  }
8227
8338
  function planProviderMigration(options) {
8228
- const projectDir = path23__default.resolve(options.projectDir);
8339
+ const projectDir = path18__default.resolve(options.projectDir);
8229
8340
  const registryPath = options.workspace ? workspaceProviderRegistryPath(projectDir) : userProviderRegistryPath();
8230
8341
  const plan = {
8231
8342
  registryPath,
@@ -8241,7 +8352,7 @@ function planProviderMigration(options) {
8241
8352
  raw = parseDocument(readFileSync(file, "utf-8")).toJS() ?? {};
8242
8353
  } catch (error) {
8243
8354
  plan.warnings.push(
8244
- `${path23__default.basename(file)}: not valid YAML (${error instanceof Error ? error.message : String(error)}) \u2014 skipped`
8355
+ `${path18__default.basename(file)}: not valid YAML (${error instanceof Error ? error.message : String(error)}) \u2014 skipped`
8245
8356
  );
8246
8357
  continue;
8247
8358
  }
@@ -8290,7 +8401,7 @@ function planProviderMigration(options) {
8290
8401
  });
8291
8402
  if (!model) {
8292
8403
  plan.warnings.push(
8293
- `${path23__default.basename(file)}: profile '${profile}' had no model: \u2014 it now resolves against registry order. Pin it with 'model: ${providerId}/<modelId>'.`
8404
+ `${path18__default.basename(file)}: profile '${profile}' had no model: \u2014 it now resolves against registry order. Pin it with 'model: ${providerId}/<modelId>'.`
8294
8405
  );
8295
8406
  }
8296
8407
  touched = true;
@@ -8357,7 +8468,7 @@ function printPlan(plan) {
8357
8468
  for (const entry of plan.entries) {
8358
8469
  const base = entry.entry.base_url ?? S.dim("(transport-derived)");
8359
8470
  console.log(
8360
- ` ${S.label(`${path23__default.basename(entry.file)} ${entry.profile}`)} provider: ${entry.legacy.provider}, cloud: ${entry.legacy.cloud}`
8471
+ ` ${S.label(`${path18__default.basename(entry.file)} ${entry.profile}`)} provider: ${entry.legacy.provider}, cloud: ${entry.legacy.cloud}`
8361
8472
  );
8362
8473
  console.log(` \u2192 providers.yml ${S.bold(entry.providerId)} ${base}`);
8363
8474
  console.log(
@@ -8373,7 +8484,7 @@ function printPlan(plan) {
8373
8484
  console.log();
8374
8485
  }
8375
8486
  async function runMigrateProviders(opts) {
8376
- const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
8487
+ const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
8377
8488
  const plan = planProviderMigration({ projectDir, workspace: opts.workspace });
8378
8489
  for (const warning of plan.warnings) logWarn(warning);
8379
8490
  if (plan.entries.length === 0 && Object.keys(plan.providers).length === 0) {
@@ -8504,7 +8615,7 @@ async function runMigrateAgents(paths, opts) {
8504
8615
  let failures = 0;
8505
8616
  let manualCount = 0;
8506
8617
  for (const report of plan.reports) {
8507
- const rel = path23__default.relative(base, report.file) || report.file;
8618
+ const rel = path18__default.relative(base, report.file) || report.file;
8508
8619
  for (const note of report.notes) console.log(` ${S.label(rel)} ${note}`);
8509
8620
  for (const note of report.manual) {
8510
8621
  manualCount++;
@@ -8531,14 +8642,14 @@ async function runMigrateAssets(root, opts) {
8531
8642
  const write = resolveMode(opts);
8532
8643
  const base = process.cwd();
8533
8644
  const plan = planAssetMigration({
8534
- root: path23__default.resolve(root ?? base),
8645
+ root: path18__default.resolve(root ?? base),
8535
8646
  registry: getKindRegistry()
8536
8647
  });
8537
8648
  for (const note of plan.notes) console.log(` ${note}`);
8538
8649
  for (const note of plan.manual) logWarn(note);
8539
8650
  for (const { file, type } of plan.unknownTypes) {
8540
8651
  logWarn(
8541
- `${path23__default.relative(base, file) || file}: frontmatter type "${type}" is not a registered asset kind (reported, not rewritten)`
8652
+ `${path18__default.relative(base, file) || file}: frontmatter type "${type}" is not a registered asset kind (reported, not rewritten)`
8542
8653
  );
8543
8654
  }
8544
8655
  printChanges(plan.changes, base);
@@ -8561,8 +8672,8 @@ function makeNpxCommand() {
8561
8672
  skills.command("add <url>").description(
8562
8673
  "Clone a repo, register it in the project's skaile.yaml sources[], and install a skill from it"
8563
8674
  ).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) => {
8564
- const projectDir = path23__default.resolve(opts.projectDir);
8565
- const projYaml = path23__default.join(projectDir, "skaile.yaml");
8675
+ const projectDir = path18__default.resolve(opts.projectDir);
8676
+ const projYaml = path18__default.join(projectDir, "skaile.yaml");
8566
8677
  if (!existsSync(projYaml)) {
8567
8678
  logErr(`No skaile.yaml in ${projectDir} \u2014 run \`skaile init\` first.`);
8568
8679
  process.exit(1);
@@ -8575,11 +8686,11 @@ function makeNpxCommand() {
8575
8686
  }
8576
8687
  const spinner = createSpinner();
8577
8688
  const key = sourceCacheKey(url);
8578
- const clonePath = path23__default.join(getGlobalCacheDir(), key);
8689
+ const clonePath = path18__default.join(getGlobalCacheDir(), key);
8579
8690
  spinner.start(`Cloning ${url}`);
8580
8691
  try {
8581
8692
  if (!existsSync(clonePath)) {
8582
- mkdirSync(path23__default.dirname(clonePath), { recursive: true });
8693
+ mkdirSync(path18__default.dirname(clonePath), { recursive: true });
8583
8694
  execSync(`git clone ${url} ${clonePath}`, { stdio: "ignore" });
8584
8695
  }
8585
8696
  spinner.stop(`Cloned to ${key}`);
@@ -8634,7 +8745,7 @@ function makeNpxCommand() {
8634
8745
  return npx;
8635
8746
  }
8636
8747
  function resolvePublisher(clonePath, url) {
8637
- const manifestPath = path23__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
8748
+ const manifestPath = path18__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
8638
8749
  if (existsSync(manifestPath)) {
8639
8750
  try {
8640
8751
  const { manifest } = decodeSkaileManifest(readFileSync(manifestPath, "utf8"));
@@ -8647,12 +8758,12 @@ function resolvePublisher(clonePath, url) {
8647
8758
  return url.match(/github\.com[/:]([^/]+)\/[^/]+/)?.[1];
8648
8759
  }
8649
8760
  function resolveSkillName(clonePath, requested) {
8650
- const skillsDir = path23__default.join(clonePath, "skills");
8651
- if (existsSync(path23__default.join(skillsDir, requested, "SKILL.md"))) return requested;
8761
+ const skillsDir = path18__default.join(clonePath, "skills");
8762
+ if (existsSync(path18__default.join(skillsDir, requested, "SKILL.md"))) return requested;
8652
8763
  if (!existsSync(skillsDir)) return requested;
8653
8764
  for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
8654
8765
  if (!entry.isDirectory()) continue;
8655
- const md = path23__default.join(skillsDir, entry.name, "SKILL.md");
8766
+ const md = path18__default.join(skillsDir, entry.name, "SKILL.md");
8656
8767
  if (!existsSync(md)) continue;
8657
8768
  try {
8658
8769
  const { data } = parseFrontmatter(readFileSync(md, "utf8"));
@@ -8684,7 +8795,7 @@ function makeOutdatedCommand() {
8684
8795
  ).action(async (filter, opts) => {
8685
8796
  const am2 = new AssetManager({
8686
8797
  registry: getKindRegistry(),
8687
- projectDir: path23__default.resolve(opts.projectDir),
8798
+ projectDir: path18__default.resolve(opts.projectDir),
8688
8799
  driverTarget: opts.target
8689
8800
  });
8690
8801
  const entries = await am2.outdated();
@@ -8714,6 +8825,12 @@ function makeOutdatedCommand() {
8714
8825
  if (filtered.some((e) => e.problem !== void 0 && !e.manualFix)) {
8715
8826
  logWarn(`Run ${S.cmd("skaile install")} to restore or re-lock the broken assets.`);
8716
8827
  }
8828
+ for (const e of filtered) {
8829
+ if (e.problem !== void 0 || (await am2.gapsOf(outdatedRef(e))).length > 0) {
8830
+ process.exitCode = 1;
8831
+ break;
8832
+ }
8833
+ }
8717
8834
  });
8718
8835
  }
8719
8836
  function makePatchCommand() {
@@ -8721,7 +8838,7 @@ function makePatchCommand() {
8721
8838
  cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
8722
8839
  const am2 = new AssetManager({
8723
8840
  registry: getKindRegistry(),
8724
- projectDir: path23__default.resolve(opts.projectDir)
8841
+ projectDir: path18__default.resolve(opts.projectDir)
8725
8842
  });
8726
8843
  try {
8727
8844
  const dest = await am2.patch(ref);
@@ -8735,7 +8852,7 @@ function makePatchCommand() {
8735
8852
  cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
8736
8853
  const am2 = new AssetManager({
8737
8854
  registry: getKindRegistry(),
8738
- projectDir: path23__default.resolve(opts.projectDir)
8855
+ projectDir: path18__default.resolve(opts.projectDir)
8739
8856
  });
8740
8857
  try {
8741
8858
  const patchFile = await am2.patchCommit(ref);
@@ -8749,7 +8866,7 @@ function makePatchCommand() {
8749
8866
  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) => {
8750
8867
  const am2 = new AssetManager({
8751
8868
  registry: getKindRegistry(),
8752
- projectDir: path23__default.resolve(opts.projectDir)
8869
+ projectDir: path18__default.resolve(opts.projectDir)
8753
8870
  });
8754
8871
  try {
8755
8872
  await am2.patchSubmit(ref);
@@ -8765,7 +8882,7 @@ function makePatchCommand() {
8765
8882
  cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
8766
8883
  const am2 = new AssetManager({
8767
8884
  registry: getKindRegistry(),
8768
- projectDir: path23__default.resolve(opts.projectDir)
8885
+ projectDir: path18__default.resolve(opts.projectDir)
8769
8886
  });
8770
8887
  am2.patchRemove(ref);
8771
8888
  logOk(`Patch removed for ${ref}`);
@@ -8784,7 +8901,7 @@ function action2(fn) {
8784
8901
  };
8785
8902
  }
8786
8903
  async function reconcileAndReport(projectDir, plugins) {
8787
- const { reconcilePlugins } = await import('../plugin-store-MPAMD5OT.js');
8904
+ const { reconcilePlugins } = await import('../plugin-store-X7GPWGBG.js');
8788
8905
  if (plugins.length === 0) {
8789
8906
  logInfo("No plugins declared \u2014 nothing to reconcile.");
8790
8907
  return;
@@ -8798,10 +8915,10 @@ async function reconcileAndReport(projectDir, plugins) {
8798
8915
  }
8799
8916
  }
8800
8917
  async function runInstall2(spec, opts) {
8801
- const projectDir = path23__default.resolve(opts.projectDir);
8918
+ const projectDir = path18__default.resolve(opts.projectDir);
8802
8919
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
8803
- const { specName } = await import('../plugin-store-MPAMD5OT.js');
8804
- const yamlPath = path23__default.join(projectDir, "skaile.yaml");
8920
+ const { specName } = await import('../plugin-store-X7GPWGBG.js');
8921
+ const yamlPath = path18__default.join(projectDir, "skaile.yaml");
8805
8922
  const editor = WorkspaceYamlEditor2.load(yamlPath);
8806
8923
  const replaced = editor.addPlugin(spec, specName);
8807
8924
  editor.save();
@@ -8810,10 +8927,10 @@ async function runInstall2(spec, opts) {
8810
8927
  await reconcileAndReport(projectDir, editor.getPlugins());
8811
8928
  }
8812
8929
  async function runRemove(name, opts) {
8813
- const projectDir = path23__default.resolve(opts.projectDir);
8930
+ const projectDir = path18__default.resolve(opts.projectDir);
8814
8931
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
8815
- const { specName } = await import('../plugin-store-MPAMD5OT.js');
8816
- const yamlPath = path23__default.join(projectDir, "skaile.yaml");
8932
+ const { specName } = await import('../plugin-store-X7GPWGBG.js');
8933
+ const yamlPath = path18__default.join(projectDir, "skaile.yaml");
8817
8934
  const editor = WorkspaceYamlEditor2.load(yamlPath);
8818
8935
  const removed = editor.removePlugin(name, specName);
8819
8936
  if (!removed) {
@@ -8825,7 +8942,7 @@ async function runRemove(name, opts) {
8825
8942
  await reconcileAndReport(projectDir, editor.getPlugins());
8826
8943
  }
8827
8944
  async function runList(opts) {
8828
- const projectDir = path23__default.resolve(opts.projectDir);
8945
+ const projectDir = path18__default.resolve(opts.projectDir);
8829
8946
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
8830
8947
  const config = resolveSkWorkspaceConfig2(projectDir);
8831
8948
  const declared = config.plugins ?? [];
@@ -8840,7 +8957,7 @@ async function runList(opts) {
8840
8957
  const registry = createPluginRegistry();
8841
8958
  if (declared.length > 0) {
8842
8959
  try {
8843
- const { loadPlugins } = await import('../plugin-store-MPAMD5OT.js');
8960
+ const { loadPlugins } = await import('../plugin-store-X7GPWGBG.js');
8844
8961
  const result = await loadPlugins(projectDir, declared, registry);
8845
8962
  for (const f of result.failed) logWarn(f.error);
8846
8963
  } catch (err2) {
@@ -9015,7 +9132,7 @@ function neededSources(config, lock) {
9015
9132
  }
9016
9133
  function sourcesWithSidecar(sources) {
9017
9134
  const dir = getStoreManifestsDir();
9018
- return sources.filter((s) => existsSync(path23.join(dir, `${storeManifestSlug(s.url)}.yaml`))).map((s) => s.url);
9135
+ return sources.filter((s) => existsSync(path18.join(dir, `${storeManifestSlug(s.url)}.yaml`))).map((s) => s.url);
9019
9136
  }
9020
9137
  function compact(obj) {
9021
9138
  const out = {};
@@ -9107,8 +9224,8 @@ function redactSecrets(preset, findings) {
9107
9224
  }
9108
9225
  return { preset: next, keys };
9109
9226
  }
9110
- function placeholderKey(itemId, path44) {
9111
- return `${itemId}_${path44}`.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
9227
+ function placeholderKey(itemId, path43) {
9228
+ return `${itemId}_${path43}`.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
9112
9229
  }
9113
9230
  function setAtPath(root, segments, value) {
9114
9231
  let node = root;
@@ -9131,7 +9248,7 @@ function makePresetCommand() {
9131
9248
  cmd.command("init [name]").description("Scaffold a new .preset.yaml file").option("--dir <path>", "Output directory", process.cwd()).action(async (name, opts) => {
9132
9249
  const presetName = name ?? "my-preset";
9133
9250
  const filename = `${presetName}.preset.yaml`;
9134
- const outPath = path23__default.join(path23__default.resolve(opts.dir), filename);
9251
+ const outPath = path18__default.join(path18__default.resolve(opts.dir), filename);
9135
9252
  if (existsSync(outPath)) {
9136
9253
  logErr(`File already exists: ${outPath}`);
9137
9254
  logInfo("Choose a different name or remove the existing file.");
@@ -9164,7 +9281,7 @@ function makePresetCommand() {
9164
9281
  return cmd;
9165
9282
  }
9166
9283
  async function runPresetExport(name, opts) {
9167
- const projectDir = path23__default.resolve(opts.projectDir);
9284
+ const projectDir = path18__default.resolve(opts.projectDir);
9168
9285
  const file = loadSkWorkspaceConfig(projectDir);
9169
9286
  if (!file) {
9170
9287
  logErr(`No skaile.yaml found in ${projectDir}`);
@@ -9174,7 +9291,7 @@ async function runPresetExport(name, opts) {
9174
9291
  const presetName = name ?? file.config.name ?? "my-preset";
9175
9292
  let lock = null;
9176
9293
  try {
9177
- lock = readLock(path23__default.join(projectDir, "skaile.lock.yaml"));
9294
+ lock = readLock(path18__default.join(projectDir, "skaile.lock.yaml"));
9178
9295
  } catch {
9179
9296
  lock = null;
9180
9297
  }
@@ -9215,7 +9332,7 @@ async function runPresetExport(name, opts) {
9215
9332
  const contents = header ? `${header}
9216
9333
  ${body}` : body;
9217
9334
  if (opts.out && opts.dir !== process.cwd()) logWarn("--dir is ignored when --out is set.");
9218
- const outPath = opts.out ? path23__default.resolve(opts.out) : path23__default.join(path23__default.resolve(opts.dir), `${presetName}.preset.yaml`);
9335
+ const outPath = opts.out ? path18__default.resolve(opts.out) : path18__default.join(path18__default.resolve(opts.dir), `${presetName}.preset.yaml`);
9219
9336
  if (existsSync(outPath) && !opts.force) {
9220
9337
  logErr(`File already exists: ${outPath}`);
9221
9338
  logInfo("Pass --force to overwrite, or choose a different --out/--dir.");
@@ -9227,7 +9344,7 @@ ${body}` : body;
9227
9344
  logErr(`Failed to write ${outPath}: ${e.message}`);
9228
9345
  process.exit(1);
9229
9346
  }
9230
- logOk(`Exported ${S.brand(path23__default.basename(outPath))}`);
9347
+ logOk(`Exported ${S.brand(path18__default.basename(outPath))}`);
9231
9348
  logInfo(`Path: ${outPath}`);
9232
9349
  if (unresolved.length > 0) {
9233
9350
  console.error(S.err("This file is NOT safe to share."));
@@ -9268,13 +9385,13 @@ function collectInput(value, acc) {
9268
9385
  return acc;
9269
9386
  }
9270
9387
  async function runPresetApply(filePath, opts) {
9271
- const projectDir = path23__default.resolve(opts.projectDir);
9388
+ const projectDir = path18__default.resolve(opts.projectDir);
9272
9389
  const file = loadSkWorkspaceConfig(projectDir);
9273
9390
  if (!file) {
9274
9391
  logErr("No skaile.yaml \u2014 run `skaile init` first");
9275
9392
  process.exit(1);
9276
9393
  }
9277
- const resolved = path23__default.resolve(filePath);
9394
+ const resolved = path18__default.resolve(filePath);
9278
9395
  if (!existsSync(resolved)) {
9279
9396
  logErr(`File not found: ${resolved}`);
9280
9397
  process.exit(1);
@@ -9490,7 +9607,7 @@ async function reportNestedPresetRefs(preset) {
9490
9607
  }
9491
9608
  async function checkPresetCycles(preset, resolved) {
9492
9609
  const { detectCycles } = await import('../discovery/index.js');
9493
- const presetRef = path23__default.basename(resolved, ".preset.yaml");
9610
+ const presetRef = path18__default.basename(resolved, ".preset.yaml");
9494
9611
  const edges = [];
9495
9612
  for (const item of preset.items) {
9496
9613
  if (item.ref) {
@@ -9542,7 +9659,7 @@ function printPresetSummary(preset, placeholderCount, hasWarnings) {
9542
9659
  }
9543
9660
  }
9544
9661
  async function runPresetValidate(filePath) {
9545
- const resolved = path23__default.resolve(filePath);
9662
+ const resolved = path18__default.resolve(filePath);
9546
9663
  const preset = await loadPresetForValidation(resolved);
9547
9664
  await reportNestedPresetRefs(preset);
9548
9665
  await checkPresetCycles(preset, resolved);
@@ -9592,11 +9709,11 @@ items:
9592
9709
  }
9593
9710
  function makeRebuildCommand() {
9594
9711
  return new Command("rebuild").description("Re-snapshot inline-snapshot composition items and bump prompt version").argument("[agent]", "Agent name or path (defaults to current project agent)").option("--project-dir <dir>", "Project directory", process.cwd()).action(async (agentArg, opts) => {
9595
- const projectDir = path23__default.resolve(opts.projectDir);
9712
+ const projectDir = path18__default.resolve(opts.projectDir);
9596
9713
  let agentDir;
9597
9714
  if (agentArg) {
9598
9715
  if (agentArg.includes("/") || agentArg.includes("\\")) {
9599
- agentDir = path23__default.resolve(projectDir, agentArg);
9716
+ agentDir = path18__default.resolve(projectDir, agentArg);
9600
9717
  } else {
9601
9718
  let resolved;
9602
9719
  try {
@@ -9605,7 +9722,7 @@ function makeRebuildCommand() {
9605
9722
  if (!(err2 instanceof AgentRefResolutionError)) throw err2;
9606
9723
  logWarn(`${err2.message} \u2014 using "${agentArg}"`);
9607
9724
  }
9608
- agentDir = resolved ?? path23__default.resolve(projectDir, agentArg);
9725
+ agentDir = resolved ?? path18__default.resolve(projectDir, agentArg);
9609
9726
  }
9610
9727
  } else {
9611
9728
  let resolved;
@@ -9675,9 +9792,9 @@ Try a different harness with \`--driver claude-sdk\`.`;
9675
9792
  // cli/src/commands/run.ts
9676
9793
  function resolveSingleShotAgentDir(projectDir, agentDefinition) {
9677
9794
  if (!agentDefinition) return resolveAgentDir(projectDir);
9678
- const asPath = agentDefinition.endsWith("agent.yaml") ? path23__default.dirname(path23__default.resolve(projectDir, agentDefinition)) : agentDefinition;
9795
+ const asPath = agentDefinition.endsWith("agent.yaml") ? path18__default.dirname(path18__default.resolve(projectDir, agentDefinition)) : agentDefinition;
9679
9796
  const dir = resolveAgentDefinitionDir(projectDir, asPath);
9680
- if (!dir || !fs9__default.existsSync(path23__default.join(dir, "agent.yaml"))) {
9797
+ if (!dir || !fs8__default.existsSync(path18__default.join(dir, "agent.yaml"))) {
9681
9798
  throw new Error(
9682
9799
  `--agent-definition "${agentDefinition}" does not resolve to an agent directory with agent.yaml${dir ? ` (looked in ${dir})` : ""}`
9683
9800
  );
@@ -9776,7 +9893,7 @@ function makeRunCommand() {
9776
9893
  "--agent-definition <ref|path>",
9777
9894
  "Agent asset for this one invocation (agent:@pub/name, ai-assets://\u2026, or a directory with agent.yaml); single-shot prompts only"
9778
9895
  ).option("--skill <name>", "Skill name (for single-shot mode)").action(async (positional, opts) => {
9779
- const projectDir = path23__default.resolve(opts.projectDir);
9896
+ const projectDir = path18__default.resolve(opts.projectDir);
9780
9897
  const cliDriver = opts.driver;
9781
9898
  const dryRun = opts.dryRun ?? false;
9782
9899
  const agentDefinition = opts.agentDefinition?.trim() || void 0;
@@ -9895,7 +10012,7 @@ function makeRunCommand() {
9895
10012
  }
9896
10013
  function makeResumeCommand() {
9897
10014
  const cmd = new Command("resume").description("Resume current session").option("--project-dir <path>", "Project directory", process.cwd()).option("--session <run-id>", "Target session by runId").option("--dry-run", "Print plan without executing").action(async (opts) => {
9898
- const projectDir = path23__default.resolve(opts.projectDir);
10015
+ const projectDir = path18__default.resolve(opts.projectDir);
9899
10016
  const sessionId = opts.session;
9900
10017
  const dryRun = opts.dryRun ?? false;
9901
10018
  const session = sessionId ? await loadSessionById(projectDir, sessionId) : await loadSession(projectDir);
@@ -9922,7 +10039,7 @@ function makeResumeCommand() {
9922
10039
  }
9923
10040
  function makeStatusCommand() {
9924
10041
  return new Command("status").description("Show current session state").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
9925
- const projectDir = path23__default.resolve(opts.projectDir);
10042
+ const projectDir = path18__default.resolve(opts.projectDir);
9926
10043
  const session = await loadSession(projectDir);
9927
10044
  if (!session) {
9928
10045
  logInfo("No active session.");
@@ -9947,7 +10064,7 @@ function makeStatusCommand() {
9947
10064
  }
9948
10065
  function makeClearCommand() {
9949
10066
  return new Command("clear").description("Unset current session pointer").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
9950
- const projectDir = path23__default.resolve(opts.projectDir);
10067
+ const projectDir = path18__default.resolve(opts.projectDir);
9951
10068
  await clearSession(projectDir);
9952
10069
  logOk("Session cleared.");
9953
10070
  });
@@ -9957,7 +10074,7 @@ function makeReplCommand() {
9957
10074
  const { findWorkspaceRoot } = await import('../core/index.js');
9958
10075
  const { startRepl } = await import('../tui/index.js');
9959
10076
  const os2 = await import('os');
9960
- const userCwd = path23__default.resolve(opts.projectDir ?? process.cwd());
10077
+ const userCwd = path18__default.resolve(opts.projectDir ?? process.cwd());
9961
10078
  const workspaceRoot = findWorkspaceRoot(userCwd);
9962
10079
  let projectDir;
9963
10080
  let agentCwd;
@@ -9979,13 +10096,13 @@ function makeReplCommand() {
9979
10096
  p4.cancel("Cancelled.");
9980
10097
  process.exit(0);
9981
10098
  }
9982
- const tmpDir = fs9__default.mkdtempSync(path23__default.join(os2.tmpdir(), "skaile-repl-"));
10099
+ const tmpDir = fs8__default.mkdtempSync(path18__default.join(os2.tmpdir(), "skaile-repl-"));
9983
10100
  projectDir = tmpDir;
9984
10101
  agentCwd = userCwd;
9985
10102
  logOk(`Temporary workspace: ${S.cmd(tmpDir)}`);
9986
10103
  if (!driverOverride) {
9987
- const claudeDir = path23__default.join(os2.homedir(), ".claude");
9988
- if (fs9__default.existsSync(claudeDir)) {
10104
+ const claudeDir = path18__default.join(os2.homedir(), ".claude");
10105
+ if (fs8__default.existsSync(claudeDir)) {
9989
10106
  driverOverride = "claude-sdk";
9990
10107
  logInfo(`Detected ${S.cmd("~/.claude")} \u2192 using ${S.cmd("claude-sdk")} harness`);
9991
10108
  } else {
@@ -10057,12 +10174,12 @@ function makeServeCommand() {
10057
10174
  );
10058
10175
  }
10059
10176
  async function ensurePluginsLoadedForServe(projectDir) {
10060
- const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-MWZDRBLD.js');
10177
+ const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-X6URBGSF.js');
10061
10178
  try {
10062
10179
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
10063
10180
  const config = resolveSkWorkspaceConfig2(projectDir);
10064
10181
  if (!config.plugins || config.plugins.length === 0) return;
10065
- const { ensurePluginsLoaded } = await import('../plugin-store-MPAMD5OT.js');
10182
+ const { ensurePluginsLoaded } = await import('../plugin-store-X7GPWGBG.js');
10066
10183
  const { pluginRegistry } = await import('../plugin-registry/index.js');
10067
10184
  const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
10068
10185
  if (result.loaded.length > 0) {
@@ -10076,21 +10193,21 @@ async function ensurePluginsLoadedForServe(projectDir) {
10076
10193
  }
10077
10194
  }
10078
10195
  async function runCompileTest(opts) {
10079
- const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-MWZDRBLD.js');
10196
+ const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-X6URBGSF.js');
10080
10197
  const { tmpdir } = await import('os');
10081
- const { dirname: dirname3, join: join7, resolve: resolve5 } = await import('path');
10198
+ const { dirname: dirname3, join: join6, resolve: resolve5 } = await import('path');
10082
10199
  const { fileURLToPath: fileURLToPath2 } = await import('url');
10083
10200
  const { unlinkSync, existsSync: existsSync18 } = await import('fs');
10084
10201
  const { spawn } = await import('child_process');
10085
10202
  const { portableSpawnSync: portableSpawnSync2 } = await import('../core/index.js');
10086
- const { MONOREPO_ROOT } = await import('../paths-FQ64OLJG.js');
10203
+ const { MONOREPO_ROOT } = await import('../paths-BVO56A25.js');
10087
10204
  if (MONOREPO_ROOT === null) {
10088
10205
  logErr2("--compile-test is only available inside the skaile-dev workspace.");
10089
10206
  logInfo2("Run it from a checkout of skaile-ai/skaile-dev (the monorepo shell).");
10090
10207
  process.exitCode = 2;
10091
10208
  return;
10092
10209
  }
10093
- const outfile = join7(tmpdir(), `skaile-compile-test-${Date.now()}`);
10210
+ const outfile = join6(tmpdir(), `skaile-compile-test-${Date.now()}`);
10094
10211
  const __thisFile = fileURLToPath2(import.meta.url);
10095
10212
  const entryPoint = resolve5(dirname3(__thisFile), "..", "index.ts");
10096
10213
  logInfo2(`Building compiled binary...`);
@@ -10566,7 +10683,7 @@ function resolveMode2(opts) {
10566
10683
  if (opts.forceLocal && opts.forceRemote) {
10567
10684
  throw new Error("Cannot use both --local and --remote");
10568
10685
  }
10569
- const startDir = path23__default.resolve(opts.projectDir ?? process.cwd());
10686
+ const startDir = path18__default.resolve(opts.projectDir ?? process.cwd());
10570
10687
  const localDb = findLogsDb(startDir);
10571
10688
  if (opts.forceLocal) {
10572
10689
  if (!localDb) {
@@ -10599,14 +10716,14 @@ function resolveMode2(opts) {
10599
10716
  function findLogsDb(startDir) {
10600
10717
  let dir = startDir;
10601
10718
  for (let i = 0; i < MAX_WALK_LEVELS; i++) {
10602
- const candidate = path23__default.join(dir, ".skaile", "logs.db");
10719
+ const candidate = path18__default.join(dir, ".skaile", "logs.db");
10603
10720
  if (existsSync(candidate)) {
10604
10721
  try {
10605
10722
  if (statSync(candidate).isFile()) return candidate;
10606
10723
  } catch {
10607
10724
  }
10608
10725
  }
10609
- const parent = path23__default.dirname(dir);
10726
+ const parent = path18__default.dirname(dir);
10610
10727
  if (parent === dir) return void 0;
10611
10728
  dir = parent;
10612
10729
  }
@@ -10781,7 +10898,7 @@ function parsePositiveInt(value, flag) {
10781
10898
  function makeSessionCommand() {
10782
10899
  const cmd = new Command("session").description("Manage sessions");
10783
10900
  cmd.command("list").description("List all sessions for a project").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
10784
- const projectDir = path23__default.resolve(opts.projectDir);
10901
+ const projectDir = path18__default.resolve(opts.projectDir);
10785
10902
  const sessions = await listSessions(projectDir);
10786
10903
  const current = await loadSession(projectDir);
10787
10904
  if (sessions.length === 0) {
@@ -10809,7 +10926,7 @@ function makeSessionCommand() {
10809
10926
  console.log();
10810
10927
  });
10811
10928
  cmd.command("show <run-id>").description("Show a specific session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
10812
- const projectDir = path23__default.resolve(opts.projectDir);
10929
+ const projectDir = path18__default.resolve(opts.projectDir);
10813
10930
  const session = await loadSessionById(projectDir, runId);
10814
10931
  if (!session) {
10815
10932
  logErr(`Session not found: ${runId}`);
@@ -10818,7 +10935,7 @@ function makeSessionCommand() {
10818
10935
  console.log(JSON.stringify(session, null, 2));
10819
10936
  });
10820
10937
  cmd.command("switch <run-id>").description("Switch the current session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
10821
- const projectDir = path23__default.resolve(opts.projectDir);
10938
+ const projectDir = path18__default.resolve(opts.projectDir);
10822
10939
  if (!await loadSessionById(projectDir, runId)) {
10823
10940
  logErr(`Session not found: ${runId}`);
10824
10941
  process.exit(1);
@@ -10827,7 +10944,7 @@ function makeSessionCommand() {
10827
10944
  logOk(`Switched to session: ${S.dim(runId.slice(0, 8))}`);
10828
10945
  });
10829
10946
  cmd.command("delete <run-id>").description("Delete a session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
10830
- const projectDir = path23__default.resolve(opts.projectDir);
10947
+ const projectDir = path18__default.resolve(opts.projectDir);
10831
10948
  if (!await loadSessionById(projectDir, runId)) {
10832
10949
  logErr(`Session not found: ${runId}`);
10833
10950
  process.exit(1);
@@ -10885,12 +11002,12 @@ function showOverview(am2) {
10885
11002
  }
10886
11003
  async function showAsset(am2, kind, name) {
10887
11004
  const entry = await am2.info(`${kind}:${name}`);
10888
- if (entry?.source && fs9__default.existsSync(entry.source)) {
11005
+ if (entry?.source && fs8__default.existsSync(entry.source)) {
10889
11006
  console.log();
10890
11007
  console.log(` ${kindColor(entry.kind)} ${S.heading(entry.name)}`);
10891
11008
  console.log(` ${S.rule(40)}`);
10892
11009
  console.log();
10893
- console.log(fs9__default.readFileSync(entry.source, "utf-8"));
11010
+ console.log(fs8__default.readFileSync(entry.source, "utf-8"));
10894
11011
  return;
10895
11012
  }
10896
11013
  logErr(`Asset not found: ${kind}:${name}`);
@@ -10900,7 +11017,7 @@ function makeShowCommand() {
10900
11017
  return new Command("show").description("Show deployed assets overview, or print asset content").argument("[kind]", "Asset kind (skill, agent, prompt, flow, preset, contract)").argument("[name]", "Asset name").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", `Agent framework (${TARGET_DEFAULT_HINT})`).action(async (kind, name, opts) => {
10901
11018
  const am2 = new AssetManager({
10902
11019
  registry: getKindRegistry(),
10903
- projectDir: path23__default.resolve(opts.projectDir),
11020
+ projectDir: path18__default.resolve(opts.projectDir),
10904
11021
  driverTarget: opts.target
10905
11022
  });
10906
11023
  if (!kind) {
@@ -10963,14 +11080,14 @@ function makeStoreCommand() {
10963
11080
  });
10964
11081
  store.command("mode <auto|local|remote>").description("Set the catalog resolution mode (not yet wired)").action((_mode) => {
10965
11082
  logErr(
10966
- `\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${path23__default.join(globalSkaileDir(), "store", "config.yaml")}.`
11083
+ `\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${path18__default.join(globalSkaileDir(), "store", "config.yaml")}.`
10967
11084
  );
10968
11085
  process.exit(2);
10969
11086
  });
10970
11087
  store.command("search <query>").description("Search the AI Asset Store catalog by name, description, or publisher").option("--kind <kind>", "Filter by asset kind (skill, agent, prompt, flow, \u2026)").option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (query, opts) => {
10971
- const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-OG457THY.js');
11088
+ const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-4QSUORI6.js');
10972
11089
  try {
10973
- const remote = await openCatalogSource2({ projectDir: path23__default.resolve(opts.projectDir) });
11090
+ const remote = await openCatalogSource2({ projectDir: path18__default.resolve(opts.projectDir) });
10974
11091
  const assets = await remote.listAssets(opts.kind ? { kind: opts.kind } : {});
10975
11092
  const results = filterCatalogAssets(assets, query);
10976
11093
  if (results.length === 0) {
@@ -10996,10 +11113,10 @@ function makeStoreCommand() {
10996
11113
  }
10997
11114
  });
10998
11115
  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) => {
10999
- const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-OG457THY.js');
11000
- const { supportsInstallManifest } = await import('../project-2GFT5LEZ.js');
11116
+ const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-4QSUORI6.js');
11117
+ const { supportsInstallManifest } = await import('../project-PAXP46RD.js');
11001
11118
  try {
11002
- const remote = await openCatalogSource2({ projectDir: path23__default.resolve(opts.projectDir) });
11119
+ const remote = await openCatalogSource2({ projectDir: path18__default.resolve(opts.projectDir) });
11003
11120
  const asset = await remote.resolve(ref);
11004
11121
  if (!asset) {
11005
11122
  logErr(`Not found in store: ${ref} (try a full ref, e.g. skill:@publisher/name#version)`);
@@ -11124,7 +11241,7 @@ function makeTreeCommand() {
11124
11241
  return new Command("tree").description("Show full dependency tree").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
11125
11242
  const am2 = new AssetManager({
11126
11243
  registry: getKindRegistry(),
11127
- projectDir: path23__default.resolve(opts.projectDir)
11244
+ projectDir: path18__default.resolve(opts.projectDir)
11128
11245
  });
11129
11246
  const root = await am2.tree();
11130
11247
  if (root.children.length === 0) {
@@ -11146,13 +11263,19 @@ function makeTreeCommand() {
11146
11263
  });
11147
11264
  }
11148
11265
  function makeUpdateCommand() {
11149
- return new Command("update").description("Refresh the Catalog cache and re-deploy outdated assets in the current project").argument("[name]", "Update a specific asset (kind:name)").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(
11150
- async (_name, opts) => {
11266
+ return new Command("update").description("Refresh the Catalog cache and re-deploy outdated assets in the current project").argument(
11267
+ "[name]",
11268
+ "Update only this declared asset (kind:@publisher/name, kind:name or name); exits 1 when none matches"
11269
+ ).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(
11270
+ async (name, opts) => {
11271
+ const projectDir = path18__default.resolve(opts.projectDir);
11272
+ const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
11273
+ const target = name !== void 0 && !opts.catalogOnly ? await resolveUpdateTarget(am2, name) : void 0;
11151
11274
  if (opts.catalog !== false) {
11152
11275
  const catalogSpinner = createSpinner();
11153
11276
  catalogSpinner.start("Refreshing catalog cache");
11154
11277
  try {
11155
- const remote = await openCatalogSource({ projectDir: path23__default.resolve(opts.projectDir) });
11278
+ const remote = await openCatalogSource({ projectDir: path18__default.resolve(opts.projectDir) });
11156
11279
  const result2 = await remote.refresh();
11157
11280
  catalogSpinner.stop(
11158
11281
  `Catalog refreshed: ${S.heading(String(result2.assetsCached))} assets cached`
@@ -11169,7 +11292,6 @@ function makeUpdateCommand() {
11169
11292
  }
11170
11293
  }
11171
11294
  if (opts.catalogOnly) return;
11172
- const projectDir = path23__default.resolve(opts.projectDir);
11173
11295
  if (await shouldSyncSources(opts)) {
11174
11296
  const syncSpinner = createSpinner();
11175
11297
  syncSpinner.start("Syncing sources");
@@ -11178,13 +11300,16 @@ function makeUpdateCommand() {
11178
11300
  total === 0 ? "No sources to sync." : `Synced ${S.heading(`${synced}/${total}`)} source(s)` + (failed ? ` (${failed} failed)` : "")
11179
11301
  );
11180
11302
  if (failed > 0) process.exitCode = 1;
11303
+ } else {
11304
+ for (const slug of divergedSourceClones(projectDir)) {
11305
+ logErr(`${slug}: git pull failed: Not possible to fast-forward, aborting.`);
11306
+ process.exitCode = 1;
11307
+ }
11308
+ }
11309
+ if (target) {
11310
+ await updateOne(am2, projectDir, target);
11311
+ return;
11181
11312
  }
11182
- const warnings = deferredWarnings();
11183
- const am2 = new AssetManager({
11184
- registry: getKindRegistry(),
11185
- projectDir,
11186
- onLibraryCollision: warnings.push
11187
- });
11188
11313
  const spinner = createSpinner();
11189
11314
  spinner.start("Re-deploying assets");
11190
11315
  let result;
@@ -11192,18 +11317,17 @@ function makeUpdateCommand() {
11192
11317
  result = await am2.install();
11193
11318
  } catch (err2) {
11194
11319
  spinner.stop("Failed");
11195
- warnings.flush();
11196
11320
  logErr(String(err2));
11197
11321
  process.exit(1);
11198
11322
  }
11199
11323
  spinner.stop("Done");
11200
- warnings.flush();
11201
11324
  if (result.deployed.length > 0) {
11202
11325
  for (const d of result.deployed) logOk(`Updated ${d}`);
11203
11326
  }
11204
11327
  for (const r of result.removed) logWarn(`Removed: ${r}`);
11328
+ reportReplaced(result.replaced);
11205
11329
  reportRelocked(result.relocked);
11206
- const changed = result.deployed.length > 0 || result.removed.length > 0 || !!result.relocked?.length;
11330
+ const changed = result.deployed.length > 0 || result.removed.length > 0 || !!result.replaced?.length || !!result.relocked?.length;
11207
11331
  if (result.lockWritten && changed) {
11208
11332
  logInfo(`Lock file written: ${S.dim("skaile.lock.yaml")}`);
11209
11333
  }
@@ -11216,6 +11340,73 @@ function makeUpdateCommand() {
11216
11340
  }
11217
11341
  );
11218
11342
  }
11343
+ function declaredMatches(d, arg) {
11344
+ const declared = parseAssetRefLoose(d.ref);
11345
+ if (!declared) return false;
11346
+ const spec = arg.trim().replace(/#.*$/, "");
11347
+ const colon = spec.indexOf(":");
11348
+ const kindRaw = colon >= 0 ? spec.slice(0, colon) : void 0;
11349
+ const rest = colon >= 0 ? spec.slice(colon + 1) : spec;
11350
+ const kind = kindRaw === "mcp" ? "mcp-server" : kindRaw;
11351
+ let publisher;
11352
+ let name = rest;
11353
+ if (rest.startsWith("@")) {
11354
+ const slash = rest.indexOf("/");
11355
+ publisher = rest.slice(1, slash < 0 ? void 0 : slash);
11356
+ name = slash < 0 ? "" : rest.slice(slash + 1);
11357
+ }
11358
+ return (kind === void 0 || kind === declared.kind) && (publisher === void 0 || publisher === declared.publisher?.replace(/^@/, "")) && name === declared.name;
11359
+ }
11360
+ async function resolveUpdateTarget(am2, name) {
11361
+ let declared;
11362
+ try {
11363
+ declared = (await am2.listDeclared()).filter((d) => d.state !== "invalid");
11364
+ } catch (err2) {
11365
+ if (err2 instanceof MissingManifestError) {
11366
+ logErr("No skaile.yaml found in this directory. Run `skaile init` first.");
11367
+ } else {
11368
+ logErr(err2 instanceof Error ? err2.message : String(err2));
11369
+ }
11370
+ process.exit(1);
11371
+ }
11372
+ const hits = declared.filter((d) => declaredMatches(d, name));
11373
+ if (hits.length === 1) return hits[0];
11374
+ if (hits.length > 1) {
11375
+ logErr(`"${name}" matches ${hits.length} declared assets; name the one you mean:`);
11376
+ for (const h of hits) console.error(` ${h.ref}`);
11377
+ process.exit(1);
11378
+ }
11379
+ logErr(`No declared asset matches "${name}".`);
11380
+ if (declared.length > 0) logInfo(`Declared: ${declared.map((d) => d.ref).join(", ")}`);
11381
+ process.exit(1);
11382
+ }
11383
+ function readText2(file) {
11384
+ try {
11385
+ return readFileSync(file, "utf8");
11386
+ } catch {
11387
+ return "";
11388
+ }
11389
+ }
11390
+ async function updateOne(am2, projectDir, target) {
11391
+ const lockPath = path18__default.join(projectDir, "skaile.lock.yaml");
11392
+ const before = readText2(lockPath);
11393
+ const spinner = createSpinner();
11394
+ spinner.start(`Updating ${target.ref}`);
11395
+ let deployed;
11396
+ try {
11397
+ deployed = await am2.add(target.ref);
11398
+ } catch (err2) {
11399
+ spinner.stop("Failed");
11400
+ logErr(err2 instanceof Error ? err2.message : String(err2));
11401
+ process.exitCode = 1;
11402
+ return;
11403
+ }
11404
+ spinner.stop("Done");
11405
+ for (const d of deployed) logOk(`Updated ${d}`);
11406
+ if (deployed.length > 0) return;
11407
+ if (readText2(lockPath) !== before) logInfo(`Re-locked ${target.ref}`);
11408
+ else logInfo(`${target.ref} is up to date.`);
11409
+ }
11219
11410
  async function shouldSyncSources(opts) {
11220
11411
  if (opts.sync === false) return false;
11221
11412
  if (opts.yes || !process.stdin.isTTY) return true;
@@ -11324,7 +11515,7 @@ function makeWhyCommand() {
11324
11515
  return new Command("why").description("Show why an asset is installed (dependency chain)").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
11325
11516
  const am2 = new AssetManager({
11326
11517
  registry: getKindRegistry(),
11327
- projectDir: path23__default.resolve(opts.projectDir)
11518
+ projectDir: path18__default.resolve(opts.projectDir)
11328
11519
  });
11329
11520
  const chain = await am2.why(ref);
11330
11521
  if (chain.length === 0) {
@@ -11333,9 +11524,11 @@ function makeWhyCommand() {
11333
11524
  declared = await am2.listDeclared();
11334
11525
  } catch {
11335
11526
  logErr(`${ref} not found in lock file. Run \`skaile install\` first.`);
11527
+ process.exitCode = 1;
11336
11528
  return;
11337
11529
  }
11338
11530
  logErr(whyEmptyMessage(ref, declared));
11531
+ process.exitCode = 1;
11339
11532
  return;
11340
11533
  }
11341
11534
  console.log();
@@ -11359,7 +11552,7 @@ function makeWhyCommand() {
11359
11552
  var _defaultFormatHelp = Help.prototype.formatHelp;
11360
11553
  var pkg = JSON.parse(
11361
11554
  readFileSync(
11362
- path23__default.resolve(path23__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
11555
+ path18__default.resolve(path18__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
11363
11556
  "utf-8"
11364
11557
  )
11365
11558
  );
@@ -11370,7 +11563,7 @@ for (const key of [
11370
11563
  "SKAILE_CACHE_DIR"
11371
11564
  ]) {
11372
11565
  const value = process.env[key];
11373
- if (value) process.env[key] = path23__default.resolve(value);
11566
+ if (value) process.env[key] = path18__default.resolve(value);
11374
11567
  }
11375
11568
  var program = new Command("skaile").description("AI asset manager").version(pkg.version, "-v, --version", "Show the skaile CLI version").enablePositionalOptions().configureHelp({
11376
11569
  formatHelp(cmd, helper) {
@@ -11490,7 +11683,7 @@ program.command("init [project-dir]").description("Initialize a project director
11490
11683
  (projectDir, opts) => runInit(projectDir, opts)
11491
11684
  );
11492
11685
  async function runInit(projectDir, opts) {
11493
- const { mkdirSync: mkdirSync5, writeFileSync: writeFileSync7 } = await import('fs');
11686
+ const { mkdirSync: mkdirSync5, writeFileSync: writeFileSync6 } = await import('fs');
11494
11687
  const { stringify: stringify2 } = await import('yaml');
11495
11688
  const { DRIVER_TARGETS, SUPPORTED_DRIVER_TARGETS: SUPPORTED_DRIVER_TARGETS2 } = await import('../core/index.js');
11496
11689
  const harness = opts.harness;
@@ -11499,31 +11692,31 @@ async function runInit(projectDir, opts) {
11499
11692
  process.exitCode = 1;
11500
11693
  return;
11501
11694
  }
11502
- const resolved = path23__default.resolve(projectDir ?? ".");
11503
- const projectName = path23__default.basename(resolved);
11695
+ const resolved = path18__default.resolve(projectDir ?? ".");
11696
+ const projectName = path18__default.basename(resolved);
11504
11697
  const created = [];
11505
11698
  const { existsSync: existsSync18 } = await import('fs');
11506
11699
  if (!existsSync18(resolved)) {
11507
11700
  mkdirSync5(resolved, { recursive: true });
11508
11701
  created.push(".");
11509
11702
  }
11510
- const skaileDir = path23__default.join(resolved, ".skaile");
11703
+ const skaileDir = path18__default.join(resolved, ".skaile");
11511
11704
  if (!existsSync18(skaileDir)) {
11512
- mkdirSync5(path23__default.join(skaileDir, "sessions"), { recursive: true });
11705
+ mkdirSync5(path18__default.join(skaileDir, "sessions"), { recursive: true });
11513
11706
  created.push(".skaile/");
11514
11707
  }
11515
- const settingsPath = path23__default.join(skaileDir, "settings.json");
11708
+ const settingsPath = path18__default.join(skaileDir, "settings.json");
11516
11709
  if (!existsSync18(settingsPath)) {
11517
- writeFileSync7(settingsPath, "{}\n");
11710
+ writeFileSync6(settingsPath, "{}\n");
11518
11711
  created.push(".skaile/settings.json");
11519
11712
  }
11520
- const wsConfigPath = path23__default.join(resolved, "skaile.yaml");
11713
+ const wsConfigPath = path18__default.join(resolved, "skaile.yaml");
11521
11714
  if (!existsSync18(wsConfigPath)) {
11522
- writeFileSync7(wsConfigPath, stringify2(buildInitWorkspaceConfig(projectName, harness)));
11715
+ writeFileSync6(wsConfigPath, stringify2(buildInitWorkspaceConfig(projectName, harness)));
11523
11716
  created.push("skaile.yaml");
11524
11717
  }
11525
11718
  for (const dir of new Set(Object.values(DRIVER_TARGETS[harness].local))) {
11526
- const full = path23__default.join(resolved, dir);
11719
+ const full = path18__default.join(resolved, dir);
11527
11720
  if (!existsSync18(full)) {
11528
11721
  mkdirSync5(full, { recursive: true });
11529
11722
  created.push(`${dir}/`);
@@ -11554,8 +11747,8 @@ function buildInitWorkspaceConfig(projectName, harness) {
11554
11747
  }
11555
11748
  async function initGitScaffold(resolved, created) {
11556
11749
  const { execSync: execSync2 } = await import('child_process');
11557
- const { existsSync: existsSync18, readFileSync: readFileSync10, writeFileSync: writeFileSync7 } = await import('fs');
11558
- const gitignorePath = path23__default.join(resolved, ".gitignore");
11750
+ const { existsSync: existsSync18, readFileSync: readFileSync10, writeFileSync: writeFileSync6 } = await import('fs');
11751
+ const gitignorePath = path18__default.join(resolved, ".gitignore");
11559
11752
  const entries = [
11560
11753
  "node_modules/",
11561
11754
  ".skaile/sessions/",
@@ -11577,11 +11770,11 @@ async function initGitScaffold(resolved, created) {
11577
11770
  const append = entries.filter((e) => !have.has(e));
11578
11771
  if (append.length > 0) {
11579
11772
  const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
11580
- writeFileSync7(gitignorePath, `${existing + prefix}${append.join("\n")}
11773
+ writeFileSync6(gitignorePath, `${existing + prefix}${append.join("\n")}
11581
11774
  `);
11582
11775
  if (!existing) created.push(".gitignore");
11583
11776
  }
11584
- if (!existsSync18(path23__default.join(resolved, ".git"))) {
11777
+ if (!existsSync18(path18__default.join(resolved, ".git"))) {
11585
11778
  try {
11586
11779
  execSync2("git init", { cwd: resolved, stdio: "pipe" });
11587
11780
  created.push(".git/");
@@ -11593,10 +11786,10 @@ async function initGitScaffold(resolved, created) {
11593
11786
  }
11594
11787
  async function bootstrapUserConfig() {
11595
11788
  try {
11596
- const fs14 = await import('fs');
11789
+ const fs13 = await import('fs');
11597
11790
  const { userConfigPath: userConfigPath2, saveConfig, getConfigDefaults } = await import('../library/index.js');
11598
11791
  const userCfgPath = userConfigPath2();
11599
- if (!fs14.existsSync(userCfgPath)) {
11792
+ if (!fs13.existsSync(userCfgPath)) {
11600
11793
  const defaults = getConfigDefaults();
11601
11794
  saveConfig(userCfgPath, {
11602
11795
  catalog: { url: defaults.catalog.url, cache_ttl: defaults.catalog.cache_ttl }
@@ -11611,7 +11804,7 @@ async function bootstrapUserConfig() {
11611
11804
  }
11612
11805
  async function hydrateInitSources(resolved, created) {
11613
11806
  try {
11614
- const { ensureSourcesCloned } = await import('../ensure-sources-SKLNM4UZ.js');
11807
+ const { ensureSourcesCloned } = await import('../ensure-sources-5ISVIA4T.js');
11615
11808
  const hydrate = ensureSourcesCloned(resolved, { quiet: true });
11616
11809
  for (const n of hydrate.cloned) created.push(`~/.skaile/cache/sources/${n}/`);
11617
11810
  if (hydrate.failed.length > 0) {
@@ -11627,7 +11820,7 @@ function printInitSummary(resolved, projectDir, created) {
11627
11820
  logOk(`Initialized project at ${S.heading(resolved)}`);
11628
11821
  console.log();
11629
11822
  console.log(S.heading(" Next steps:"));
11630
- const isCurrentDir = resolved === path23__default.resolve(".");
11823
+ const isCurrentDir = resolved === path18__default.resolve(".");
11631
11824
  let step = 1;
11632
11825
  if (!isCurrentDir) {
11633
11826
  console.log(` ${S.dim(`${step}.`)} ${S.cmd(`cd ${projectDir}`)}`);
@@ -11651,7 +11844,7 @@ function printInitSummary(resolved, projectDir, created) {
11651
11844
  console.log();
11652
11845
  }
11653
11846
  program.command("setup").description("Interactive provider setup wizard").action(async () => {
11654
- const { cmdSetup } = await import('../setup-WHMCSIF2.js');
11847
+ const { cmdSetup } = await import('../setup-BV55VHWC.js');
11655
11848
  await cmdSetup([], { projectDir: process.cwd() });
11656
11849
  });
11657
11850
  program.addCommand(makeInstallCommand());
@@ -11733,7 +11926,7 @@ try {
11733
11926
  await program.parseAsync();
11734
11927
  } catch (err2) {
11735
11928
  const { LibrarySyncError } = await import('../library/index.js');
11736
- if (!(err2 instanceof LibrarySyncError)) throw err2;
11929
+ if (!(err2 instanceof LibrarySyncError || err2 instanceof SourceEntryError)) throw err2;
11737
11930
  logErr(err2.message);
11738
11931
  process.exit(1);
11739
11932
  }