@skaile/workspaces 5.6.1 → 5.8.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 (428) hide show
  1. package/CHANGELOG.md +176 -0
  2. package/README.md +4 -2
  3. package/dist/app-sdk/index.js +1 -1
  4. package/dist/{asset-feeds-LU7NHOAP.js → asset-feeds-EYRZR4K5.js} +55 -31
  5. package/dist/asset-feeds-EYRZR4K5.js.map +1 -0
  6. package/dist/asset-manager/catalog-deployer.js +10 -10
  7. package/dist/asset-manager/index.js +16 -16
  8. package/dist/asset-manager/installer.js +12 -12
  9. package/dist/asset-manager/renderers.js +11 -11
  10. package/dist/asset-manager/src/index.d.ts +364 -30
  11. package/dist/asset-manager/src/index.d.ts.map +1 -1
  12. package/dist/asset-manager/src/install-agent.d.ts +11 -0
  13. package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
  14. package/dist/asset-manager/src/installer.d.ts +6 -3
  15. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  16. package/dist/bridge/drivers/claude-sdk.js +148 -212
  17. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  18. package/dist/bridge/drivers/codex.js +91 -67
  19. package/dist/bridge/drivers/codex.js.map +1 -1
  20. package/dist/bridge/drivers/continue.js +16 -17
  21. package/dist/bridge/drivers/continue.js.map +1 -1
  22. package/dist/bridge/drivers/echo.js +4 -4
  23. package/dist/bridge/drivers/gemini.js +8 -8
  24. package/dist/bridge/drivers/goose.js +16 -17
  25. package/dist/bridge/drivers/goose.js.map +1 -1
  26. package/dist/bridge/drivers/omp.js +68 -104
  27. package/dist/bridge/drivers/omp.js.map +1 -1
  28. package/dist/bridge/drivers/opencode.js +16 -17
  29. package/dist/bridge/drivers/opencode.js.map +1 -1
  30. package/dist/bridge/drivers/qwen.js +8 -8
  31. package/dist/bridge/index.js +17 -18
  32. package/dist/bridge/src/codex/managed-driver.d.ts +13 -10
  33. package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
  34. package/dist/bridge/src/drivers/_subprocess-cli.d.ts +12 -2
  35. package/dist/bridge/src/drivers/_subprocess-cli.d.ts.map +1 -1
  36. package/dist/bridge/src/drivers/claude-sdk.d.ts +37 -62
  37. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  38. package/dist/bridge/src/drivers/codex.d.ts +26 -10
  39. package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
  40. package/dist/bridge/src/drivers/continue.d.ts +2 -2
  41. package/dist/bridge/src/drivers/continue.d.ts.map +1 -1
  42. package/dist/bridge/src/drivers/gemini.d.ts +2 -2
  43. package/dist/bridge/src/drivers/gemini.d.ts.map +1 -1
  44. package/dist/bridge/src/drivers/goose.d.ts +2 -2
  45. package/dist/bridge/src/drivers/goose.d.ts.map +1 -1
  46. package/dist/bridge/src/drivers/omp.d.ts +24 -35
  47. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  48. package/dist/bridge/src/drivers/opencode.d.ts +2 -2
  49. package/dist/bridge/src/drivers/opencode.d.ts.map +1 -1
  50. package/dist/bridge/src/drivers/recovery-policy.d.ts +79 -0
  51. package/dist/bridge/src/drivers/recovery-policy.d.ts.map +1 -0
  52. package/dist/bridge/src/index.d.ts +1 -0
  53. package/dist/bridge/src/index.d.ts.map +1 -1
  54. package/dist/bridge/src/reconfigure-ledger.d.ts +117 -0
  55. package/dist/bridge/src/reconfigure-ledger.d.ts.map +1 -0
  56. package/dist/bridge/src/types.d.ts +57 -6
  57. package/dist/bridge/src/types.d.ts.map +1 -1
  58. package/dist/{chunk-OLLAQLFJ.js → chunk-2FRUUDZY.js} +5 -5
  59. package/dist/{chunk-OLLAQLFJ.js.map → chunk-2FRUUDZY.js.map} +1 -1
  60. package/dist/{chunk-SDFROXSA.js → chunk-2LWYNQK7.js} +3 -3
  61. package/dist/{chunk-SDFROXSA.js.map → chunk-2LWYNQK7.js.map} +1 -1
  62. package/dist/{chunk-TZCQ7ZWQ.js → chunk-36AFURKZ.js} +10 -11
  63. package/dist/chunk-36AFURKZ.js.map +1 -0
  64. package/dist/{chunk-MX3UQXLU.js → chunk-4MQS7CAF.js} +256 -92
  65. package/dist/chunk-4MQS7CAF.js.map +1 -0
  66. package/dist/{chunk-45VFGT7A.js → chunk-4PTSR4UU.js} +3 -3
  67. package/dist/{chunk-45VFGT7A.js.map → chunk-4PTSR4UU.js.map} +1 -1
  68. package/dist/{chunk-VX3INFBA.js → chunk-6GRX5L6A.js} +5 -5
  69. package/dist/{chunk-VX3INFBA.js.map → chunk-6GRX5L6A.js.map} +1 -1
  70. package/dist/{chunk-NFGRW3L7.js → chunk-7RGTAEG6.js} +3 -3
  71. package/dist/{chunk-NFGRW3L7.js.map → chunk-7RGTAEG6.js.map} +1 -1
  72. package/dist/{chunk-5B5IZVEP.js → chunk-AWQYXZVG.js} +15 -6
  73. package/dist/chunk-AWQYXZVG.js.map +1 -0
  74. package/dist/{chunk-XBSQ4KMC.js → chunk-B4X2N7JQ.js} +205 -3
  75. package/dist/chunk-B4X2N7JQ.js.map +1 -0
  76. package/dist/{chunk-FRHE7FFB.js → chunk-B6GIW55K.js} +5 -3
  77. package/dist/chunk-B6GIW55K.js.map +1 -0
  78. package/dist/{chunk-LLKKLKZJ.js → chunk-BJNUNQAW.js} +3 -3
  79. package/dist/{chunk-LLKKLKZJ.js.map → chunk-BJNUNQAW.js.map} +1 -1
  80. package/dist/{chunk-7ZHLYXTI.js → chunk-BTE2V4IW.js} +3 -3
  81. package/dist/{chunk-7ZHLYXTI.js.map → chunk-BTE2V4IW.js.map} +1 -1
  82. package/dist/{chunk-ZBBM6O6P.js → chunk-CGT45WN7.js} +3 -3
  83. package/dist/{chunk-ZBBM6O6P.js.map → chunk-CGT45WN7.js.map} +1 -1
  84. package/dist/{chunk-47ZD34KB.js → chunk-CIFS5K6T.js} +3 -3
  85. package/dist/{chunk-47ZD34KB.js.map → chunk-CIFS5K6T.js.map} +1 -1
  86. package/dist/{chunk-BTISGSK4.js → chunk-CKQEIY43.js} +4 -4
  87. package/dist/{chunk-BTISGSK4.js.map → chunk-CKQEIY43.js.map} +1 -1
  88. package/dist/{chunk-KXTO7HON.js → chunk-EAZECHPM.js} +3 -3
  89. package/dist/{chunk-KXTO7HON.js.map → chunk-EAZECHPM.js.map} +1 -1
  90. package/dist/{chunk-VKSXST23.js → chunk-EF7NPDDU.js} +4 -4
  91. package/dist/{chunk-VKSXST23.js.map → chunk-EF7NPDDU.js.map} +1 -1
  92. package/dist/chunk-EPBKISS5.js +84 -0
  93. package/dist/chunk-EPBKISS5.js.map +1 -0
  94. package/dist/{chunk-VJENKWXF.js → chunk-F2EKONM7.js} +3 -3
  95. package/dist/{chunk-VJENKWXF.js.map → chunk-F2EKONM7.js.map} +1 -1
  96. package/dist/{chunk-DMLDYFDS.js → chunk-F3RDEH5U.js} +7 -4
  97. package/dist/chunk-F3RDEH5U.js.map +1 -0
  98. package/dist/{chunk-UAP2XHRF.js → chunk-FTJJO3EM.js} +39 -29
  99. package/dist/chunk-FTJJO3EM.js.map +1 -0
  100. package/dist/{chunk-2GRB5ITE.js → chunk-FVJK4QWM.js} +4 -4
  101. package/dist/{chunk-2GRB5ITE.js.map → chunk-FVJK4QWM.js.map} +1 -1
  102. package/dist/{chunk-AOAZCSDI.js → chunk-FZNG4V4J.js} +16 -30
  103. package/dist/chunk-FZNG4V4J.js.map +1 -0
  104. package/dist/{chunk-BF33SCLY.js → chunk-GB7WDMH2.js} +4 -4
  105. package/dist/{chunk-BF33SCLY.js.map → chunk-GB7WDMH2.js.map} +1 -1
  106. package/dist/{chunk-NARITJS2.js → chunk-GCICGXDD.js} +3 -3
  107. package/dist/{chunk-NARITJS2.js.map → chunk-GCICGXDD.js.map} +1 -1
  108. package/dist/{chunk-PA7WLID3.js → chunk-GTILM2CI.js} +56 -5
  109. package/dist/chunk-GTILM2CI.js.map +1 -0
  110. package/dist/{chunk-WIHQWVWL.js → chunk-GXXFLBUQ.js} +26 -27
  111. package/dist/chunk-GXXFLBUQ.js.map +1 -0
  112. package/dist/{chunk-PTO2YDDG.js → chunk-H7QUDDKH.js} +1337 -168
  113. package/dist/chunk-H7QUDDKH.js.map +1 -0
  114. package/dist/{chunk-I4QBZLOR.js → chunk-HG34RNTK.js} +7 -13
  115. package/dist/chunk-HG34RNTK.js.map +1 -0
  116. package/dist/{chunk-65EYRFZJ.js → chunk-HYDRDNKN.js} +10 -6
  117. package/dist/chunk-HYDRDNKN.js.map +1 -0
  118. package/dist/{chunk-4GNJELPH.js → chunk-I6NLLJHZ.js} +2 -2
  119. package/dist/{chunk-4GNJELPH.js.map → chunk-I6NLLJHZ.js.map} +1 -1
  120. package/dist/{chunk-VSQFGU5D.js → chunk-ILFGVSTJ.js} +3 -3
  121. package/dist/{chunk-VSQFGU5D.js.map → chunk-ILFGVSTJ.js.map} +1 -1
  122. package/dist/{chunk-2XFUXGV6.js → chunk-IONAUNWB.js} +3 -3
  123. package/dist/{chunk-2XFUXGV6.js.map → chunk-IONAUNWB.js.map} +1 -1
  124. package/dist/{chunk-CT6NQSA4.js → chunk-ISHJITXJ.js} +3 -3
  125. package/dist/{chunk-CT6NQSA4.js.map → chunk-ISHJITXJ.js.map} +1 -1
  126. package/dist/chunk-IZCR27MU.js +60 -0
  127. package/dist/chunk-IZCR27MU.js.map +1 -0
  128. package/dist/{chunk-2W4LBLIN.js → chunk-JAKOMFC6.js} +68 -20
  129. package/dist/chunk-JAKOMFC6.js.map +1 -0
  130. package/dist/{chunk-MFHKHXDE.js → chunk-L5VSIPQD.js} +5 -5
  131. package/dist/chunk-L5VSIPQD.js.map +1 -0
  132. package/dist/{chunk-RGXVQZOV.js → chunk-LEMHVDET.js} +89 -67
  133. package/dist/chunk-LEMHVDET.js.map +1 -0
  134. package/dist/{chunk-37FTLYFP.js → chunk-LNFKL23K.js} +3 -3
  135. package/dist/{chunk-37FTLYFP.js.map → chunk-LNFKL23K.js.map} +1 -1
  136. package/dist/{chunk-6NPINANG.js → chunk-LSXHED6I.js} +6 -6
  137. package/dist/{chunk-6NPINANG.js.map → chunk-LSXHED6I.js.map} +1 -1
  138. package/dist/{chunk-XUUYAS3Z.js → chunk-M3WPBTGJ.js} +3 -3
  139. package/dist/{chunk-XUUYAS3Z.js.map → chunk-M3WPBTGJ.js.map} +1 -1
  140. package/dist/{chunk-QZLWJETK.js → chunk-MGGFBZWA.js} +3 -3
  141. package/dist/{chunk-QZLWJETK.js.map → chunk-MGGFBZWA.js.map} +1 -1
  142. package/dist/{chunk-QD772CGQ.js → chunk-NPLPCRW5.js} +5 -5
  143. package/dist/{chunk-QD772CGQ.js.map → chunk-NPLPCRW5.js.map} +1 -1
  144. package/dist/{chunk-QCI6D7E4.js → chunk-NUELZWCF.js} +266 -170
  145. package/dist/chunk-NUELZWCF.js.map +1 -0
  146. package/dist/{chunk-GP6ZL7PE.js → chunk-OFBIWVCR.js} +3 -3
  147. package/dist/{chunk-GP6ZL7PE.js.map → chunk-OFBIWVCR.js.map} +1 -1
  148. package/dist/{chunk-D2V42LUE.js → chunk-P23M65LB.js} +93 -52
  149. package/dist/chunk-P23M65LB.js.map +1 -0
  150. package/dist/{chunk-46OVMT76.js → chunk-PMECEZK3.js} +16 -10
  151. package/dist/chunk-PMECEZK3.js.map +1 -0
  152. package/dist/{chunk-27HS2DHB.js → chunk-PTSGWKHR.js} +4 -4
  153. package/dist/{chunk-27HS2DHB.js.map → chunk-PTSGWKHR.js.map} +1 -1
  154. package/dist/{chunk-OKGUDNDT.js → chunk-Q6E6FM7P.js} +35 -33
  155. package/dist/chunk-Q6E6FM7P.js.map +1 -0
  156. package/dist/{chunk-PJS2YWGG.js → chunk-QOP6KDFR.js} +8 -9
  157. package/dist/chunk-QOP6KDFR.js.map +1 -0
  158. package/dist/{chunk-AO7VJ6G6.js → chunk-QVNRCDTV.js} +29 -8
  159. package/dist/chunk-QVNRCDTV.js.map +1 -0
  160. package/dist/{chunk-VBBBZDI7.js → chunk-S53LOR7B.js} +3 -3
  161. package/dist/{chunk-VBBBZDI7.js.map → chunk-S53LOR7B.js.map} +1 -1
  162. package/dist/{chunk-KUFNKVBM.js → chunk-SH5D7U7N.js} +20 -7
  163. package/dist/{chunk-KUFNKVBM.js.map → chunk-SH5D7U7N.js.map} +1 -1
  164. package/dist/{chunk-SX4UIDKT.js → chunk-UAROCOXF.js} +3 -3
  165. package/dist/{chunk-SX4UIDKT.js.map → chunk-UAROCOXF.js.map} +1 -1
  166. package/dist/{chunk-JMKB7IB4.js → chunk-UMVKJM4Q.js} +4 -4
  167. package/dist/chunk-UMVKJM4Q.js.map +1 -0
  168. package/dist/{chunk-HCYS7GFP.js → chunk-V2DXZYBB.js} +3 -3
  169. package/dist/{chunk-HCYS7GFP.js.map → chunk-V2DXZYBB.js.map} +1 -1
  170. package/dist/{chunk-KYXOGHY6.js → chunk-W5DWWE4Y.js} +4 -4
  171. package/dist/{chunk-KYXOGHY6.js.map → chunk-W5DWWE4Y.js.map} +1 -1
  172. package/dist/{chunk-FK6HPLQA.js → chunk-WTQ3TATB.js} +3 -3
  173. package/dist/{chunk-FK6HPLQA.js.map → chunk-WTQ3TATB.js.map} +1 -1
  174. package/dist/{chunk-OGLDAJFL.js → chunk-Y4N2NUZD.js} +4 -4
  175. package/dist/{chunk-OGLDAJFL.js.map → chunk-Y4N2NUZD.js.map} +1 -1
  176. package/dist/{chunk-XOGG7VDZ.js → chunk-Y7QA2OLD.js} +17 -25
  177. package/dist/chunk-Y7QA2OLD.js.map +1 -0
  178. package/dist/{chunk-2KOKBTR4.js → chunk-YSHVQGUS.js} +123 -28
  179. package/dist/chunk-YSHVQGUS.js.map +1 -0
  180. package/dist/chunk-ZAOGFXDO.js +112 -0
  181. package/dist/chunk-ZAOGFXDO.js.map +1 -0
  182. package/dist/{chunk-7KLC4LZO.js → chunk-ZKSJMZKD.js} +17 -13
  183. package/dist/chunk-ZKSJMZKD.js.map +1 -0
  184. package/dist/cli/index.js +1169 -672
  185. package/dist/cli/index.js.map +1 -1
  186. package/dist/cli/src/asset-feeds.d.ts +5 -2
  187. package/dist/cli/src/asset-feeds.d.ts.map +1 -1
  188. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  189. package/dist/cli/src/commands/catalog.d.ts +27 -5
  190. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  191. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  192. package/dist/cli/src/commands/library-index.d.ts +49 -4
  193. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  194. package/dist/cli/src/commands/library-publish.d.ts +9 -0
  195. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  196. package/dist/cli/src/commands/manage.d.ts +8 -2
  197. package/dist/cli/src/commands/manage.d.ts.map +1 -1
  198. package/dist/cli/src/commands/outdated.d.ts +10 -4
  199. package/dist/cli/src/commands/outdated.d.ts.map +1 -1
  200. package/dist/cli/src/commands/project.d.ts +15 -4
  201. package/dist/cli/src/commands/project.d.ts.map +1 -1
  202. package/dist/cli/src/commands/publish-core.d.ts +10 -1
  203. package/dist/cli/src/commands/publish-core.d.ts.map +1 -1
  204. package/dist/cli/src/commands/session.d.ts.map +1 -1
  205. package/dist/cli/src/commands/source.d.ts +18 -3
  206. package/dist/cli/src/commands/source.d.ts.map +1 -1
  207. package/dist/cli/src/commands/tree.d.ts.map +1 -1
  208. package/dist/cli/src/commands/update.d.ts +1 -1
  209. package/dist/cli/src/commands/update.d.ts.map +1 -1
  210. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  211. package/dist/cli/src/flow-discovery.d.ts +8 -5
  212. package/dist/cli/src/flow-discovery.d.ts.map +1 -1
  213. package/dist/cli/src/open-library.d.ts +0 -11
  214. package/dist/cli/src/open-library.d.ts.map +1 -1
  215. package/dist/cli/src/skill-checks.d.ts +30 -10
  216. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  217. package/dist/connectors/config.js +6 -6
  218. package/dist/connectors/index.js +26 -27
  219. package/dist/connectors/src/access-policy.d.ts +33 -0
  220. package/dist/connectors/src/access-policy.d.ts.map +1 -0
  221. package/dist/connectors/src/connector-manager.d.ts.map +1 -1
  222. package/dist/connectors/src/index.d.ts +2 -0
  223. package/dist/connectors/src/index.d.ts.map +1 -1
  224. package/dist/connectors-O6Y6VESP.js +44 -0
  225. package/dist/{connectors-HWENZFKW.js.map → connectors-O6Y6VESP.js.map} +1 -1
  226. package/dist/connectors-shared/index.js +2 -2
  227. package/dist/core/index.js +9 -9
  228. package/dist/core/logging.js +1 -1
  229. package/dist/core/manifest.js +2 -2
  230. package/dist/core/models.js +1 -1
  231. package/dist/core/publish-manifest.js +2 -2
  232. package/dist/core/ref.js +1 -1
  233. package/dist/core/runtime-assets.js +6 -6
  234. package/dist/core/src/cache-paths.d.ts.map +1 -1
  235. package/dist/core/src/index.d.ts +4 -4
  236. package/dist/core/src/index.d.ts.map +1 -1
  237. package/dist/core/src/lock.d.ts +3 -3
  238. package/dist/core/src/lock.d.ts.map +1 -1
  239. package/dist/core/src/logging/config.d.ts +9 -1
  240. package/dist/core/src/logging/config.d.ts.map +1 -1
  241. package/dist/core/src/manifest.d.ts +17 -2
  242. package/dist/core/src/manifest.d.ts.map +1 -1
  243. package/dist/core/src/models.d.ts +22 -6
  244. package/dist/core/src/models.d.ts.map +1 -1
  245. package/dist/core/src/repo-manager.d.ts +41 -6
  246. package/dist/core/src/repo-manager.d.ts.map +1 -1
  247. package/dist/core/src/store.d.ts +16 -2
  248. package/dist/core/src/store.d.ts.map +1 -1
  249. package/dist/core/src/workspace-config.d.ts +10 -1
  250. package/dist/core/src/workspace-config.d.ts.map +1 -1
  251. package/dist/core/store.js +2 -2
  252. package/dist/core/workspace-config.js +5 -5
  253. package/dist/deploy/index.js +9 -9
  254. package/dist/discovery/index.js +5 -5
  255. package/dist/discovery/src/index.d.ts +1 -1
  256. package/dist/discovery/src/index.d.ts.map +1 -1
  257. package/dist/discovery/src/source-config.d.ts +12 -0
  258. package/dist/discovery/src/source-config.d.ts.map +1 -1
  259. package/dist/discovery/src/tree-entries.d.ts.map +1 -1
  260. package/dist/{ensure-sources-DSTSXJWK.js → ensure-sources-SKLNM4UZ.js} +19 -19
  261. package/dist/{ensure-sources-DSTSXJWK.js.map → ensure-sources-SKLNM4UZ.js.map} +1 -1
  262. package/dist/factory-assets/connectors/box.js +26 -27
  263. package/dist/factory-assets/connectors/deploy.js +26 -27
  264. package/dist/factory-assets/connectors/devserver.js +26 -27
  265. package/dist/factory-assets/connectors/flow/adapter.d.ts +6 -0
  266. package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
  267. package/dist/factory-assets/connectors/flow/adapter.js +26 -27
  268. package/dist/factory-assets/connectors/flow/contract/expression.d.ts +3 -0
  269. package/dist/factory-assets/connectors/flow/contract/expression.d.ts.map +1 -1
  270. package/dist/factory-assets/connectors/flow/contract/output-fields.d.ts +1 -1
  271. package/dist/factory-assets/connectors/flow/contract/output-fields.d.ts.map +1 -1
  272. package/dist/factory-assets/connectors/flow/contract/schema.d.ts.map +1 -1
  273. package/dist/factory-assets/connectors/flow/contract.js +4 -4
  274. package/dist/factory-assets/connectors/flow/engine/flow-output.d.ts +4 -3
  275. package/dist/factory-assets/connectors/flow/engine/flow-output.d.ts.map +1 -1
  276. package/dist/factory-assets/connectors/flow/engine/output-schema.d.ts +6 -1
  277. package/dist/factory-assets/connectors/flow/engine/output-schema.d.ts.map +1 -1
  278. package/dist/factory-assets/connectors/flow/engine.js +13 -13
  279. package/dist/factory-assets/connectors/flow/inline-sub-flow-host.d.ts.map +1 -1
  280. package/dist/factory-assets/connectors/flow/prompt-fragments.js +3 -3
  281. package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
  282. package/dist/factory-assets/connectors/flow/run-flow.js +28 -29
  283. package/dist/factory-assets/connectors/flow.js +26 -27
  284. package/dist/factory-assets/connectors/git/config.d.ts.map +1 -1
  285. package/dist/factory-assets/connectors/git.js +26 -27
  286. package/dist/factory-assets/connectors/gmail.js +26 -27
  287. package/dist/factory-assets/connectors/googledrive.js +26 -27
  288. package/dist/factory-assets/connectors/local.js +26 -27
  289. package/dist/factory-assets/connectors/mattermost.js +26 -27
  290. package/dist/factory-assets/connectors/memory.js +26 -27
  291. package/dist/factory-assets/connectors/minio.js +26 -27
  292. package/dist/factory-assets/connectors/postgres.js +26 -27
  293. package/dist/factory-assets/connectors/s3.js +26 -27
  294. package/dist/factory-assets/connectors/sharepoint.js +26 -27
  295. package/dist/factory-assets/connectors/sqlite.js +26 -27
  296. package/dist/factory-assets/connectors/static-server.js +26 -27
  297. package/dist/factory-assets/connectors/tunnel.js +26 -27
  298. package/dist/factory-assets/connectors/webdav.js +26 -27
  299. package/dist/factory-assets/connectors/xstate-store.js +26 -27
  300. package/dist/factory-assets/connectors/xstate.js +26 -27
  301. package/dist/factory-assets/skills/skaile-author-asset/SKILL.md +10 -7
  302. package/dist/flows-CBYRSAGS.js +26 -0
  303. package/dist/{flows-ENQY2DV7.js.map → flows-CBYRSAGS.js.map} +1 -1
  304. package/dist/{helpers-R44RUTDY.js → helpers-MWZDRBLD.js} +19 -19
  305. package/dist/{helpers-R44RUTDY.js.map → helpers-MWZDRBLD.js.map} +1 -1
  306. package/dist/library/index.js +13 -13
  307. package/dist/library/install.js +3 -3
  308. package/dist/library/src/index.d.ts +5 -3
  309. package/dist/library/src/index.d.ts.map +1 -1
  310. package/dist/library/src/local/library-manager.d.ts +6 -0
  311. package/dist/library/src/local/library-manager.d.ts.map +1 -1
  312. package/dist/library/src/local/local-catalog-source.d.ts +5 -2
  313. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  314. package/dist/library/src/local/scan-authoring-libraries.d.ts +43 -0
  315. package/dist/library/src/local/scan-authoring-libraries.d.ts.map +1 -0
  316. package/dist/library/src/manifest-writer.d.ts +46 -1
  317. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  318. package/dist/library/src/sync/git-driver.d.ts +12 -0
  319. package/dist/library/src/sync/git-driver.d.ts.map +1 -1
  320. package/dist/{library-publish-LFOJJVMK.js → library-publish-PICMDSB2.js} +129 -49
  321. package/dist/library-publish-PICMDSB2.js.map +1 -0
  322. package/dist/open-library-OG457THY.js +40 -0
  323. package/dist/{open-library-4WUMQHES.js.map → open-library-OG457THY.js.map} +1 -1
  324. package/dist/open-registry-ZUZJ7MS7.js +32 -0
  325. package/dist/{open-registry-NVPCQPND.js.map → open-registry-ZUZJ7MS7.js.map} +1 -1
  326. package/dist/paths-FQ64OLJG.js +22 -0
  327. package/dist/{paths-YUCP7K6U.js.map → paths-FQ64OLJG.js.map} +1 -1
  328. package/dist/{plugin-store-66QFBNEO.js → plugin-store-MPAMD5OT.js} +11 -11
  329. package/dist/{plugin-store-66QFBNEO.js.map → plugin-store-MPAMD5OT.js.map} +1 -1
  330. package/dist/project-2GFT5LEZ.js +41 -0
  331. package/dist/{project-VMOHUXBD.js.map → project-2GFT5LEZ.js.map} +1 -1
  332. package/dist/resolver/index.js +10 -10
  333. package/dist/runner/index.js +41 -42
  334. package/dist/runner/src/logging-bootstrap.d.ts +6 -0
  335. package/dist/runner/src/logging-bootstrap.d.ts.map +1 -1
  336. package/dist/runner/src/reconfigure-handler.d.ts +38 -17
  337. package/dist/runner/src/reconfigure-handler.d.ts.map +1 -1
  338. package/dist/runner/src/serve.d.ts.map +1 -1
  339. package/dist/runner/src/session-capability-wiring.d.ts +0 -2
  340. package/dist/runner/src/session-capability-wiring.d.ts.map +1 -1
  341. package/dist/sdk/asset-manager.js +16 -16
  342. package/dist/sdk/bridge.js +17 -18
  343. package/dist/sdk/core.js +9 -9
  344. package/dist/sdk/flow.js +13 -13
  345. package/dist/sdk/index.js +69 -46
  346. package/dist/sdk/index.js.map +1 -1
  347. package/dist/sdk/resolver.js +10 -10
  348. package/dist/sdk/runner.js +41 -42
  349. package/dist/sdk/session.js +2 -2
  350. package/dist/sdk/src/agent-session.d.ts +8 -0
  351. package/dist/sdk/src/agent-session.d.ts.map +1 -1
  352. package/dist/sdk/store.js +2 -1
  353. package/dist/sdk/types.js +1 -1
  354. package/dist/secrets/index.js +2 -2
  355. package/dist/session/index.js +2 -2
  356. package/dist/{setup-PYY23HGZ.js → setup-WHMCSIF2.js} +27 -28
  357. package/dist/setup-WHMCSIF2.js.map +1 -0
  358. package/dist/skills-TVO26Y4V.js +26 -0
  359. package/dist/{skills-CS7NE5TT.js.map → skills-TVO26Y4V.js.map} +1 -1
  360. package/dist/source-LKOFTOEK.js +41 -0
  361. package/dist/{source-JCF6KSQN.js.map → source-LKOFTOEK.js.map} +1 -1
  362. package/dist/{source-manifest-publish-O6P7G2M7.js → source-manifest-publish-L5J3QXER.js} +28 -28
  363. package/dist/{source-manifest-publish-O6P7G2M7.js.map → source-manifest-publish-L5J3QXER.js.map} +1 -1
  364. package/dist/store/index.js +2 -1
  365. package/dist/store/src/store.d.ts +8 -5
  366. package/dist/store/src/store.d.ts.map +1 -1
  367. package/dist/tui/index.js +41 -42
  368. package/dist/tui/index.js.map +1 -1
  369. package/dist/types/index.js +1 -1
  370. package/dist/types/manifests.js +1 -1
  371. package/dist/types/src/ask-slots.d.ts +68 -0
  372. package/dist/types/src/ask-slots.d.ts.map +1 -0
  373. package/dist/types/src/delivery.d.ts.map +1 -1
  374. package/dist/types/src/events.d.ts +29 -1
  375. package/dist/types/src/events.d.ts.map +1 -1
  376. package/dist/types/src/index.d.ts +1 -1
  377. package/dist/types/src/index.d.ts.map +1 -1
  378. package/dist/types/src/manifests/index.d.ts +1 -1
  379. package/dist/types/src/manifests/index.d.ts.map +1 -1
  380. package/dist/types/src/manifests/preset.d.ts +4 -0
  381. package/dist/types/src/manifests/preset.d.ts.map +1 -1
  382. package/dist/types/src/version.d.ts +12 -1
  383. package/dist/types/src/version.d.ts.map +1 -1
  384. package/dist/workspace-plugin/adapters/mcp.js +33 -34
  385. package/dist/workspace-plugin/adapters/omp.js +14 -14
  386. package/dist/workspace-plugin/index.js +2 -2
  387. package/package.json +1 -1
  388. package/dist/asset-feeds-LU7NHOAP.js.map +0 -1
  389. package/dist/chunk-2KOKBTR4.js.map +0 -1
  390. package/dist/chunk-2NYXQYHN.js +0 -22
  391. package/dist/chunk-2NYXQYHN.js.map +0 -1
  392. package/dist/chunk-2W4LBLIN.js.map +0 -1
  393. package/dist/chunk-46OVMT76.js.map +0 -1
  394. package/dist/chunk-5B5IZVEP.js.map +0 -1
  395. package/dist/chunk-65EYRFZJ.js.map +0 -1
  396. package/dist/chunk-7KLC4LZO.js.map +0 -1
  397. package/dist/chunk-AO7VJ6G6.js.map +0 -1
  398. package/dist/chunk-AOAZCSDI.js.map +0 -1
  399. package/dist/chunk-D2V42LUE.js.map +0 -1
  400. package/dist/chunk-DMLDYFDS.js.map +0 -1
  401. package/dist/chunk-EINLFFP6.js +0 -59
  402. package/dist/chunk-EINLFFP6.js.map +0 -1
  403. package/dist/chunk-FRHE7FFB.js.map +0 -1
  404. package/dist/chunk-I4QBZLOR.js.map +0 -1
  405. package/dist/chunk-JMKB7IB4.js.map +0 -1
  406. package/dist/chunk-MFHKHXDE.js.map +0 -1
  407. package/dist/chunk-MX3UQXLU.js.map +0 -1
  408. package/dist/chunk-OKGUDNDT.js.map +0 -1
  409. package/dist/chunk-PA7WLID3.js.map +0 -1
  410. package/dist/chunk-PJS2YWGG.js.map +0 -1
  411. package/dist/chunk-PTO2YDDG.js.map +0 -1
  412. package/dist/chunk-QCI6D7E4.js.map +0 -1
  413. package/dist/chunk-RGXVQZOV.js.map +0 -1
  414. package/dist/chunk-TZCQ7ZWQ.js.map +0 -1
  415. package/dist/chunk-UAP2XHRF.js.map +0 -1
  416. package/dist/chunk-WIHQWVWL.js.map +0 -1
  417. package/dist/chunk-XBSQ4KMC.js.map +0 -1
  418. package/dist/chunk-XOGG7VDZ.js.map +0 -1
  419. package/dist/connectors-HWENZFKW.js +0 -45
  420. package/dist/flows-ENQY2DV7.js +0 -26
  421. package/dist/library-publish-LFOJJVMK.js.map +0 -1
  422. package/dist/open-library-4WUMQHES.js +0 -40
  423. package/dist/open-registry-NVPCQPND.js +0 -32
  424. package/dist/paths-YUCP7K6U.js +0 -22
  425. package/dist/project-VMOHUXBD.js +0 -41
  426. package/dist/setup-PYY23HGZ.js.map +0 -1
  427. package/dist/skills-CS7NE5TT.js +0 -26
  428. package/dist/source-JCF6KSQN.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-QD772CGQ.js';
3
- import { makeSourceCommand, syncProjectSources } from '../chunk-D2V42LUE.js';
4
- import { AI_RESOURCES } from '../chunk-OGLDAJFL.js';
5
- import { checkSkillManifest } from '../chunk-2NYXQYHN.js';
6
- import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, assetEntryRef, refFor } from '../chunk-65EYRFZJ.js';
7
- import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportInstalledSoftDeps } from '../chunk-WIHQWVWL.js';
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';
8
5
  import { createSpinner } from '../chunk-NESV47MF.js';
9
- import { openCatalogSource, openLibraryManager, openLibrary } from '../chunk-I4QBZLOR.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-VJENKWXF.js';
11
- import { getKindRegistry, getKnownKinds } from '../chunk-OLLAQLFJ.js';
12
- import { LocalSecretsProvider } from '../chunk-VSQFGU5D.js';
13
- import { runAgentChat, isCompositionError, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, hashAgentFiles, createCompositionContentSource, compileComposition, instanceForSession, resolveAgentInstance, describeComposition, MarkdownStreamer } from '../chunk-RGXVQZOV.js';
14
- import { buildClaudePluginFiles } from '../chunk-4GNJELPH.js';
15
- import '../chunk-6NPINANG.js';
16
- import '../chunk-SX4UIDKT.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';
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';
17
17
  import '../chunk-R6O6YWU7.js';
18
- import '../chunk-KYXOGHY6.js';
19
- import '../chunk-45VFGT7A.js';
18
+ import '../chunk-W5DWWE4Y.js';
19
+ import '../chunk-4PTSR4UU.js';
20
20
  import '../chunk-4ZTPYIBE.js';
21
- import '../chunk-2XFUXGV6.js';
21
+ import '../chunk-IONAUNWB.js';
22
22
  import '../chunk-X5YPJV4N.js';
23
23
  import '../chunk-O7SG5PC2.js';
24
24
  import '../chunk-7QBNJTTQ.js';
@@ -26,68 +26,67 @@ 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-HCYS7GFP.js';
30
- import { runFlow, resumeFlow } from '../chunk-7KLC4LZO.js';
29
+ import '../chunk-V2DXZYBB.js';
30
+ import { runFlow, resumeFlow } from '../chunk-ZKSJMZKD.js';
31
31
  import '../chunk-4R6DROGN.js';
32
- import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-ZBBM6O6P.js';
33
- import '../chunk-SDFROXSA.js';
34
- import '../chunk-CT6NQSA4.js';
35
- import '../chunk-UAP2XHRF.js';
36
- import '../chunk-FK6HPLQA.js';
37
- import '../chunk-2GRB5ITE.js';
38
- import '../chunk-VX3INFBA.js';
39
- import '../chunk-VBBBZDI7.js';
40
- import '../chunk-EINLFFP6.js';
32
+ import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-CGT45WN7.js';
33
+ import '../chunk-2LWYNQK7.js';
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';
41
40
  import '../chunk-LOO5CB5M.js';
42
- import '../chunk-NARITJS2.js';
43
- import '../chunk-27HS2DHB.js';
44
- import '../chunk-XBSQ4KMC.js';
41
+ import '../chunk-GCICGXDD.js';
42
+ import '../chunk-PTSGWKHR.js';
43
+ import '../chunk-B4X2N7JQ.js';
45
44
  import '../chunk-YROR332M.js';
46
- import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-5B5IZVEP.js';
45
+ import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-AWQYXZVG.js';
47
46
  import '../chunk-6E6PKKAD.js';
48
47
  import '../chunk-IFGTRL2I.js';
49
- import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-AOAZCSDI.js';
50
- import '../chunk-37FTLYFP.js';
51
- import '../chunk-QZLWJETK.js';
52
- import '../chunk-XUUYAS3Z.js';
53
- import { nodeLabel, nodeSkillAsset, nodeIsInert, nodeIsOptional, nodeRunKind, flowSkillVersionPins } from '../chunk-NFGRW3L7.js';
54
- import '../chunk-QCI6D7E4.js';
55
- import '../chunk-DMLDYFDS.js';
56
- import { AssetManager, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-PTO2YDDG.js';
57
- import { cloneOrInitGitRepo, ensureGitRepo, setManifestPublisher, syncManifestWithDisk, isGitRepo, assertManifestEditable, installLibraryAsset, missingRootAssets, stampManifestPublisher, upsertManifestAsset, getStoreManifestsDir, getDefaultValue, isSecretPlaceholder } from '../chunk-MX3UQXLU.js';
58
- import { parseManifestFile } from '../chunk-XOGG7VDZ.js';
59
- import '../chunk-BTISGSK4.js';
48
+ import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-FZNG4V4J.js';
49
+ import '../chunk-LNFKL23K.js';
50
+ import '../chunk-MGGFBZWA.js';
51
+ import '../chunk-M3WPBTGJ.js';
52
+ import { nodeLabel, nodeSkillAsset, nodeIsInert, nodeIsOptional, nodeRunKind, flowSkillVersionPins } from '../chunk-7RGTAEG6.js';
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';
60
59
  import '../chunk-R7FOF242.js';
61
60
  import '../chunk-3TXEJN4W.js';
62
- import { installTargetOf } from '../chunk-2KOKBTR4.js';
61
+ import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-YSHVQGUS.js';
63
62
  import '../chunk-CGYEHQOX.js';
64
63
  import '../chunk-KTBKW2FI.js';
65
64
  import '../chunk-UQ6LFBPZ.js';
66
- import '../chunk-VKSXST23.js';
67
- import { effectiveComposes, validatePreset, composeSlotDiagnostics, agentDeprecationDiagnostics, validateAgent, SLOT_ID_PATTERN } from '../chunk-FRHE7FFB.js';
68
- import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, readLock, aiResourceRoots, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-TZCQ7ZWQ.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';
69
68
  import '../chunk-4GY63JU6.js';
70
- import { factoryAssetRoots } from '../chunk-BF33SCLY.js';
71
- import '../chunk-46OVMT76.js';
69
+ import { factoryAssetRoots } from '../chunk-GB7WDMH2.js';
70
+ import '../chunk-PMECEZK3.js';
72
71
  import { DEFAULT_DRIVER_ID, DRIVER_DEFAULTS } from '../chunk-5BEFNLOR.js';
73
72
  import { findKindDirs } from '../chunk-A2ULN3KX.js';
74
- import { sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, resolveSkWorkspaceConfig, matchPin, coerceVersion, loadSkWorkspaceConfig, normalizeAgentInstances, agentInstanceDiagnostics, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-2W4LBLIN.js';
75
- import { globalCacheRoot, globalSkaileDir, userConfigPath } from '../chunk-MFHKHXDE.js';
73
+ import { sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, resolveSkWorkspaceConfig, matchPin, coerceVersion, loadSkWorkspaceConfig, normalizeAgentInstances, agentInstanceDiagnostics, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-JAKOMFC6.js';
74
+ import { globalCacheRoot, globalSkaileDir, userConfigPath } from '../chunk-L5VSIPQD.js';
76
75
  import { SUPPORTED_DRIVER_TARGETS, driverTargetForDriver } from '../chunk-CPSIPIX7.js';
77
- import { loadSkPublishManifest, SKAILE_MANIFEST_FILENAME, decodeSkaileManifest, encodeSkaileManifest } from '../chunk-7ZHLYXTI.js';
76
+ import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest, loadSkPublishManifest, encodeSkaileManifest } from '../chunk-BTE2V4IW.js';
78
77
  import { pluginTitle } from '../chunk-RVRB27AN.js';
79
- import { parseFrontmatter, scanDirectory } from '../chunk-PA7WLID3.js';
80
- import { parseAssetRef, isValidAssetName, slugifyAssetName, ASSET_NAME_HINT, assetRefToStr } from '../chunk-AO7VJ6G6.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';
81
80
  import { portableSpawn, portableSpawnSync } from '../chunk-ICSCSM5D.js';
82
- import { openSqlite } from '../chunk-JMKB7IB4.js';
81
+ import { openSqlite } from '../chunk-UMVKJM4Q.js';
83
82
  import { parseModelRef, resolveEntryBaseUrl } from '../chunk-MJHSLODD.js';
84
83
  import '../chunk-C3CAXQMA.js';
85
84
  import '../chunk-BOFL7GIF.js';
86
85
  import '../chunk-NSBPE2FW.js';
87
- import * as fs11 from 'fs';
88
- import fs11__default, { readFileSync, existsSync, mkdirSync, writeFileSync, lstatSync, rmSync, readdirSync, statSync } from 'fs';
89
- import * as path25 from 'path';
90
- import path25__default, { resolve, join } from 'path';
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';
91
90
  import { fileURLToPath } from 'url';
92
91
  import { Help, Command, Option } from 'commander';
93
92
  import { rcompare } from 'semver';
@@ -99,7 +98,7 @@ import * as readline from 'readline';
99
98
  import { createInterface } from 'readline';
100
99
  import fs6 from 'fs/promises';
101
100
  import { parse as parse$1, stringify as stringify$1 } from 'smol-toml';
102
- import { execSync, spawnSync } from 'child_process';
101
+ import { execSync, spawnSync, execFileSync } from 'child_process';
103
102
  import * as readline2 from 'readline/promises';
104
103
  import { createTRPCUntypedClient, httpLink, httpSubscriptionLink } from '@trpc/client';
105
104
 
@@ -176,7 +175,7 @@ async function runSearch(kind, query, opts) {
176
175
  const showLocal = !opts.store;
177
176
  const showStore = !opts.local;
178
177
  const { resolveConfig } = await import('../library/index.js');
179
- const airGapped = resolveConfig({ projectDir: path25__default.resolve(opts.projectDir) }).catalog.cache_ttl === 0;
178
+ const airGapped = resolveConfig({ projectDir: path23__default.resolve(opts.projectDir) }).catalog.cache_ttl === 0;
180
179
  if (showLocal) {
181
180
  await searchLocal(query, kind, opts, showStore, airGapped);
182
181
  }
@@ -185,10 +184,11 @@ async function runSearch(kind, query, opts) {
185
184
  }
186
185
  }
187
186
  async function searchIndex(query, kind) {
188
- const { openLibrary: openLibrary2 } = await import('../open-library-4WUMQHES.js');
187
+ const { openLibrary: openLibrary2 } = await import('../open-library-OG457THY.js');
189
188
  const library = await openLibrary2();
190
189
  try {
191
190
  const defs = await library.listAssetDefs(kind ? { kind } : {});
191
+ const libraryNames = new Map((await library.listSources()).map((l) => [l.id, l.name]));
192
192
  let entries = defs.map(
193
193
  (d) => ({
194
194
  name: d.name,
@@ -202,7 +202,8 @@ async function searchIndex(query, kind) {
202
202
  requires: [],
203
203
  dependencies: [],
204
204
  license: d.license,
205
- category: d.category
205
+ category: d.category,
206
+ library: d.libraryId ? libraryNames.get(d.libraryId) : void 0
206
207
  })
207
208
  );
208
209
  if (query) {
@@ -217,7 +218,7 @@ async function searchIndex(query, kind) {
217
218
  }
218
219
  }
219
220
  async function searchFactory(projectDir, query, kind) {
220
- const prefixes = factoryAssetRoots().map((r) => r.endsWith(path25__default.sep) ? r : r + path25__default.sep);
221
+ const prefixes = factoryAssetRoots().map((r) => r.endsWith(path23__default.sep) ? r : r + path23__default.sep);
221
222
  const isFactoryPath = (p6) => prefixes.some((fp) => p6 === fp.slice(0, -1) || p6.startsWith(fp));
222
223
  try {
223
224
  const entries = await new AssetManager({ registry: getKindRegistry(), projectDir }).search(
@@ -236,12 +237,44 @@ function unionEntries(indexed, factory) {
236
237
  const seen = new Set(indexed.map(entryDedupKey));
237
238
  return [...indexed, ...factory.filter((e) => !seen.has(entryDedupKey(e)))];
238
239
  }
240
+ async function expandLibraryCopies(entries, projectDir) {
241
+ if (entries.length === 0) return entries;
242
+ let holders;
243
+ try {
244
+ holders = await new AssetManager({ registry: getKindRegistry(), projectDir }).libraryHolders();
245
+ } catch {
246
+ return entries;
247
+ }
248
+ if (holders.size === 0) return entries;
249
+ const out = [];
250
+ const expanded = /* @__PURE__ */ new Set();
251
+ for (const e of entries) {
252
+ const key = e.publisher ? `${e.kind}:@${e.publisher}/${e.name}` : void 0;
253
+ const group = key ? holders.get(key) : void 0;
254
+ if (!key || !group) {
255
+ out.push(e);
256
+ continue;
257
+ }
258
+ if (expanded.has(key)) continue;
259
+ expanded.add(key);
260
+ for (const h of group) {
261
+ out.push({
262
+ ...e,
263
+ version: h.version,
264
+ description: h.description || e.description,
265
+ library: h.library,
266
+ usedByAdd: h.picked
267
+ });
268
+ }
269
+ }
270
+ return out;
271
+ }
239
272
  async function searchLocal(query, kind, opts, showStore, airGapped) {
240
- const projectDir = path25__default.resolve(opts.projectDir);
273
+ const projectDir = path23__default.resolve(opts.projectDir);
241
274
  const factory = await searchFactory(projectDir, query, kind);
242
275
  let entries = unionEntries(await searchIndex(query, kind), factory);
243
276
  if (entries.length === 0 && !query && !kind && !airGapped) {
244
- const { autoSyncForSearch } = await import('../source-JCF6KSQN.js');
277
+ const { autoSyncForSearch } = await import('../source-LKOFTOEK.js');
245
278
  if (await autoSyncForSearch(projectDir)) {
246
279
  entries = unionEntries(await searchIndex(query, kind), factory);
247
280
  }
@@ -258,46 +291,54 @@ async function searchLocal(query, kind, opts, showStore, airGapped) {
258
291
  console.log(`
259
292
  ${S.heading("Local:")}`);
260
293
  }
261
- printLocalEntries(entries);
294
+ printLocalEntries(await expandLibraryCopies(entries, projectDir));
262
295
  }
263
296
  var MIN_LOCAL_DESCRIPTION_WIDTH = 10;
264
297
  function layoutLocalTable(rows, width, style = {}) {
265
298
  const styleRef = style.ref ?? ((s) => s);
266
299
  const styleVer = style.version ?? ((s) => s);
300
+ const styleLib = style.library ?? ((s) => s);
267
301
  const gap = COLUMN_GAP.length;
268
302
  const indent = 2;
269
303
  const pad = " ".repeat(indent);
270
304
  const nameW = Math.max(4, ...rows.map((r) => r.ref.length));
271
305
  const verW = Math.max(0, ...rows.map((r) => r.version.length));
272
- const verSpan = verW > 0 ? gap + verW : 0;
306
+ const libW = Math.max(0, ...rows.map((r) => (r.library ?? "").length));
307
+ const tailSpan = (verW > 0 ? gap + verW : 0) + (libW > 0 ? gap + libW : 0);
273
308
  const refCell = (ref) => styleRef(ref) + " ".repeat(nameW - ref.length);
309
+ const tail = (r) => {
310
+ if (libW === 0) return r.version ? `${COLUMN_GAP}${styleVer(r.version)}` : "";
311
+ const verCell = `${COLUMN_GAP}${styleVer(r.version)}${" ".repeat(verW - r.version.length)}`;
312
+ const ver = verW > 0 ? verCell : "";
313
+ return `${ver}${COLUMN_GAP}${r.library ? styleLib(r.library) : ""}`;
314
+ };
274
315
  const lines = [];
275
- const descW = width - (indent + nameW + gap + verSpan);
316
+ const descW = width - (indent + nameW + gap + tailSpan);
276
317
  if (descW >= MIN_LOCAL_DESCRIPTION_WIDTH) {
277
318
  for (const r of rows) {
278
319
  const desc = truncateText(r.description, descW);
279
- const descCell = verW > 0 ? desc.padEnd(descW) : desc;
280
- lines.push(
281
- `${pad}${refCell(r.ref)}${COLUMN_GAP}${descCell}${r.version ? `${COLUMN_GAP}${styleVer(r.version)}` : ""}`
282
- );
320
+ const descCell = tailSpan > 0 ? desc.padEnd(descW) : desc;
321
+ lines.push(`${pad}${refCell(r.ref)}${COLUMN_GAP}${descCell}${tail(r)}`);
283
322
  }
284
- return { ruleWidth: nameW + gap + descW + verSpan, lines };
323
+ return { ruleWidth: nameW + gap + descW + tailSpan, lines };
285
324
  }
286
- if (indent + nameW + verSpan <= width) {
325
+ if (indent + nameW + tailSpan <= width) {
287
326
  for (const r of rows) {
288
- lines.push(
289
- verW > 0 ? `${pad}${refCell(r.ref)}${r.version ? `${COLUMN_GAP}${styleVer(r.version)}` : ""}` : `${pad}${styleRef(r.ref)}`
290
- );
327
+ lines.push(tailSpan > 0 ? `${pad}${refCell(r.ref)}${tail(r)}` : `${pad}${styleRef(r.ref)}`);
291
328
  }
292
- return { ruleWidth: nameW + verSpan, lines };
329
+ return { ruleWidth: nameW + tailSpan, lines };
293
330
  }
294
331
  const subPad = " ".repeat(indent + 2);
295
- const subDescW = width - (indent + 2) - verSpan;
332
+ const subDescW = width - (indent + 2) - tailSpan;
296
333
  for (const r of rows) {
297
334
  lines.push(`${pad}${styleRef(r.ref)}`);
298
335
  const desc = subDescW >= MIN_LOCAL_DESCRIPTION_WIDTH ? truncateText(r.description, subDescW) : "";
299
- const descCell = r.version && desc ? desc.padEnd(subDescW) : desc;
300
- const parts = [descCell, r.version ? styleVer(r.version) : ""].filter((s) => s !== "");
336
+ const descCell = (r.version || r.library) && desc ? desc.padEnd(subDescW) : desc;
337
+ const parts = [
338
+ descCell,
339
+ r.version ? styleVer(r.version) : "",
340
+ r.library ? styleLib(r.library) : ""
341
+ ].filter((s) => s !== "");
301
342
  if (parts.length > 0) lines.push(`${subPad}${parts.join(COLUMN_GAP)}`);
302
343
  }
303
344
  return { ruleWidth: Math.max(1, Math.min(nameW, width - indent)), lines };
@@ -313,10 +354,11 @@ function printLocalEntries(entries, width = terminalWidth()) {
313
354
  items.map((e) => ({
314
355
  ref: localEntryRef(e),
315
356
  description: e.description,
316
- version: e.version ? `v${e.version}` : ""
357
+ version: e.version ? `v${e.version}` : "",
358
+ library: e.usedByAdd ? `${e.library} (used by add)` : e.library
317
359
  })),
318
360
  width,
319
- { ref: S.cmd, version: S.dim }
361
+ { ref: S.cmd, version: S.dim, library: S.dim }
320
362
  );
321
363
  console.log();
322
364
  console.log(
@@ -350,9 +392,9 @@ async function searchStore(query, kind, opts, airGapped) {
350
392
  logInfo("air-gapped (cache_ttl: 0) \u2014 local sources only");
351
393
  return;
352
394
  }
353
- const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-4WUMQHES.js');
395
+ const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-OG457THY.js');
354
396
  try {
355
- const remote = await openCatalogSource2({ projectDir: path25__default.resolve(opts.projectDir) });
397
+ const remote = await openCatalogSource2({ projectDir: path23__default.resolve(opts.projectDir) });
356
398
  const assets = await remote.listAssets(kind ? { kind } : {});
357
399
  const results = filterCatalogAssets(assets, query);
358
400
  if (results.length > 0) {
@@ -363,7 +405,7 @@ async function searchStore(query, kind, opts, airGapped) {
363
405
  logInfo("No results in store");
364
406
  }
365
407
  } catch (e) {
366
- const local = e instanceof LocalCatalogDisabledError;
408
+ const local = e instanceof LocalCatalogDisabledError2;
367
409
  if (opts.store) {
368
410
  logErr(
369
411
  local ? "remote catalog disabled (catalog.url: local) \u2014 set catalog.url: https://skaile.store to search the store" : `Store search failed: ${e.message}`
@@ -424,6 +466,12 @@ async function promptSoftDepAdds(am2, ref, io) {
424
466
  if (yes === true) await addEdge(edge.toRef);
425
467
  }
426
468
  }
469
+ function presetAddNote(ref, presets) {
470
+ const own = presets.find((p6) => p6.ref.split("#")[0] === ref.split("#")[0]);
471
+ if (!own) return void 0;
472
+ const origin = own.library ? `library ${own.library}` : "a source or store";
473
+ return `Recorded in skaile.yaml (preset from ${origin}). ${own.assets} assets, ${own.skipped} instance items skipped (apply with skaile preset apply).`;
474
+ }
427
475
  async function reportPresetMembership(am2, ref, onHint) {
428
476
  for (const preset of await am2.presetsContaining(ref)) {
429
477
  onHint(
@@ -470,7 +518,7 @@ function makeAddCommand() {
470
518
  const warnings = deferredWarnings();
471
519
  const am2 = new AssetManager({
472
520
  registry: getKindRegistry(),
473
- projectDir: path25__default.resolve(opts.projectDir),
521
+ projectDir: path23__default.resolve(opts.projectDir),
474
522
  global: opts.global || harnesses !== void 0,
475
523
  harnesses,
476
524
  driverTarget: opts.target,
@@ -480,9 +528,13 @@ function makeAddCommand() {
480
528
  spinner.start(`Adding ${ref}`);
481
529
  try {
482
530
  const libraryOf = /* @__PURE__ */ new Map();
531
+ let presets = [];
483
532
  const added = await am2.add(ref, {
484
533
  link: opts.link,
485
- onLibraryOrigin: (deployedRef, library) => libraryOf.set(deployedRef, library)
534
+ onLibraryOrigin: (deployedRef, library) => libraryOf.set(deployedRef, library),
535
+ onPresets: (expanded) => {
536
+ presets = expanded;
537
+ }
486
538
  });
487
539
  spinner.stop("Done");
488
540
  warnings.flush();
@@ -499,7 +551,9 @@ function makeAddCommand() {
499
551
  });
500
552
  if (added.length === 0) {
501
553
  const kind = parseAssetRef(ref).kind;
502
- if (!installTargetOf(getKindRegistry(), kind))
554
+ const presetNote = presetAddNote(ref, presets);
555
+ if (presetNote) logInfo(presetNote);
556
+ else if (!installTargetOf(getKindRegistry(), kind))
503
557
  logInfo(
504
558
  `Recorded in skaile.yaml (store bytes are fetched + verified into .skaile/cache/store). ${kind} assets are not deployed into the driver target \u2014 they are composed when skaile runs the agent.`
505
559
  );
@@ -520,24 +574,35 @@ function makeAddCommand() {
520
574
  });
521
575
  }
522
576
  function makeRemoveCommand() {
523
- return new Command("remove").description("Remove from skaile.yaml + undeploy").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Remove from ~/.skaile/skaile.yaml + undeploy from every global harness").option(
577
+ 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(
524
578
  "--harness <ids>",
525
579
  "Comma-separated global harnesses to undeploy from (default: all resolved); implies --global"
526
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) => {
527
581
  const harnesses = parseHarnessFilter(opts.harness);
528
582
  const am2 = new AssetManager({
529
583
  registry: getKindRegistry(),
530
- projectDir: path25__default.resolve(opts.projectDir),
584
+ projectDir: path23__default.resolve(opts.projectDir),
531
585
  global: opts.global || harnesses !== void 0,
532
586
  harnesses,
533
587
  driverTarget: opts.target
534
588
  });
535
- const ok = am2.remove(ref);
536
- if (!ok) {
537
- logErr(`Not deployed: ${ref}`);
589
+ let result;
590
+ try {
591
+ result = await am2.removeWithDependencies(ref);
592
+ } catch (err2) {
593
+ logErr(err2 instanceof Error ? err2.message : String(err2));
594
+ process.exitCode = 1;
595
+ return;
596
+ }
597
+ if (!result.changed) {
598
+ logErr(`Not deployed or declared: ${ref}`);
599
+ process.exitCode = 1;
538
600
  return;
539
601
  }
540
602
  logOk(`Removed ${ref}`);
603
+ for (const dep of result.pruned) {
604
+ logOk(`Removed ${dep} (no longer required by anything declared in skaile.yaml)`);
605
+ }
541
606
  await promptSoftDepRemovals(am2, ref, {
542
607
  isTTY: !!process.stdin.isTTY,
543
608
  noSoftDeps: opts.softDeps === false,
@@ -570,7 +635,7 @@ function makeListCommand() {
570
635
  }
571
636
  const am2 = new AssetManager({
572
637
  registry: getKindRegistry(),
573
- projectDir: path25__default.resolve(opts.projectDir),
638
+ projectDir: path23__default.resolve(opts.projectDir),
574
639
  driverTarget: opts.target
575
640
  });
576
641
  let declared;
@@ -618,7 +683,7 @@ function makeListCommand() {
618
683
  function runGlobalList(kind, opts, harnesses) {
619
684
  const am2 = new AssetManager({
620
685
  registry: getKindRegistry(),
621
- projectDir: path25__default.resolve(opts.projectDir),
686
+ projectDir: path23__default.resolve(opts.projectDir),
622
687
  global: true,
623
688
  harnesses
624
689
  });
@@ -691,7 +756,7 @@ async function resolveInfoEntry(am2, ref, opts) {
691
756
  return { entry: match ?? deployed };
692
757
  }
693
758
  const lookup = opts.storeLookup ?? (async (filter) => {
694
- const { resolveCatalogSource } = await import('../open-library-4WUMQHES.js');
759
+ const { resolveCatalogSource } = await import('../open-library-OG457THY.js');
695
760
  const { source, close } = await resolveCatalogSource({ projectDir: opts.projectDir });
696
761
  try {
697
762
  return await source.listAssets(filter);
@@ -707,9 +772,9 @@ async function resolveInfoEntry(am2, ref, opts) {
707
772
  );
708
773
  return { entry: hit ? catalogAssetToEntry(hit) : null };
709
774
  } catch (err2) {
710
- const { LocalCatalogDisabledError } = await import('../open-library-4WUMQHES.js');
775
+ const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-OG457THY.js');
711
776
  const storeNote = err2 instanceof Error ? err2.message : String(err2);
712
- const disabled = err2 instanceof LocalCatalogDisabledError || /catalog\.url/i.test(storeNote);
777
+ const disabled = err2 instanceof LocalCatalogDisabledError2 || /catalog\.url/i.test(storeNote);
713
778
  return { entry: null, storeNote, ...disabled ? { storeDisabled: true } : {} };
714
779
  }
715
780
  }
@@ -723,7 +788,7 @@ function infoNotFoundHint(ref, lookup) {
723
788
  }
724
789
  function makeInfoCommand() {
725
790
  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) => {
726
- const projectDir = path25__default.resolve(opts.projectDir);
791
+ const projectDir = path23__default.resolve(opts.projectDir);
727
792
  const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
728
793
  const lookup = await resolveInfoEntry(am2, ref, { projectDir });
729
794
  const entry = lookup.entry;
@@ -742,8 +807,10 @@ function makeInfoCommand() {
742
807
  console.log(` source: ${S.dim(entry.source)}`);
743
808
  if (entry.requires.length) {
744
809
  console.log(` requires:`);
745
- for (const d of entry.requires)
746
- console.log(` ${S.dim("\xB7")} ${kindColor(d.kind)}:${d.name}`);
810
+ for (const d of entry.requires) {
811
+ const scope = d.publisher ? `@${d.publisher}/` : "";
812
+ console.log(` ${S.dim("\xB7")} ${kindColor(d.kind)}:${scope}${d.name}`);
813
+ }
747
814
  }
748
815
  if (entry.dependencies.length) {
749
816
  console.log(` dependencies:`);
@@ -756,10 +823,10 @@ function makeInfoCommand() {
756
823
  }
757
824
  function makeCreateCommand() {
758
825
  return new Command("create").description("Scaffold a new asset").argument("<name>", "Asset name").addOption(
759
- new Option("-k, --kind <kind>", "Asset kind").default("skill").choices(getKindRegistry().getAllKinds())
826
+ new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...SCAFFOLD_KINDS])
760
827
  ).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
761
828
  const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
762
- const destDir = opts.dir ? path25__default.resolve(opts.dir) : process.cwd();
829
+ const destDir = opts.dir ? path23__default.resolve(opts.dir) : process.cwd();
763
830
  const result = am2.create(name, opts.kind, destDir);
764
831
  if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
765
832
  else {
@@ -772,21 +839,29 @@ function makeDoctorCommand() {
772
839
  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) => {
773
840
  const am2 = new AssetManager({
774
841
  registry: getKindRegistry(),
775
- projectDir: path25__default.resolve(opts.projectDir)
842
+ projectDir: path23__default.resolve(opts.projectDir)
776
843
  });
777
844
  const issues = await am2.doctor();
778
845
  if (issues.length === 0) {
779
846
  logOk("No missing dependencies.");
780
847
  return;
781
848
  }
782
- const assetW = Math.max(5, ...issues.map((i) => `${i.assetKind}:${i.assetName}`.length));
783
- const depW = Math.max(11, ...issues.map((i) => `${i.depKind}:${i.depName}`.length));
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
+ }
856
+ if (missing.length === 0) return;
857
+ const assetW = Math.max(5, ...missing.map((i) => `${i.assetKind}:${i.assetName}`.length));
858
+ const depW = Math.max(11, ...missing.map((i) => `${i.depKind}:${i.depName}`.length));
784
859
  console.log();
785
860
  console.log(
786
861
  ` ${S.dim("ASSET".padEnd(assetW))} ${S.dim("MISSING DEP".padEnd(depW))} ${S.dim("IN REPOS")}`
787
862
  );
788
863
  console.log(` ${S.rule(assetW + depW + 15)}`);
789
- for (const i of issues) {
864
+ for (const i of missing) {
790
865
  const asset = `${i.assetKind}:${i.assetName}`;
791
866
  const dep = `${i.depKind}:${i.depName}`;
792
867
  const status4 = i.inRepos ? S.warn("fixable") : S.err("not found");
@@ -795,12 +870,37 @@ function makeDoctorCommand() {
795
870
  console.log();
796
871
  });
797
872
  }
798
- async function indexLibrary(lib, index) {
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 = {}) {
799
899
  const { LocalCatalogSource } = await import('../library/index.js');
800
900
  const own = index ?? await openLibrary();
801
901
  try {
802
902
  const source = new LocalCatalogSource(own, lib.id, lib.path, getKindRegistry());
803
- const res = await source.sync();
903
+ const res = await source.sync({ exclude: opts.exclude });
804
904
  return {
805
905
  assetsFound: res.assetsFound,
806
906
  assetsUpdated: res.assetsUpdated,
@@ -823,31 +923,23 @@ function resolveLibraryPublisherDetailed(lib, opts, storeIdentity) {
823
923
  return { publisher: "library", source: "library-name" };
824
924
  }
825
925
  }
826
- function resolveLibraryPublisher(lib, opts, storeIdentity) {
827
- return resolveLibraryPublisherDetailed(lib, opts, storeIdentity).publisher;
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
+ );
828
931
  }
829
- function stampAssetPublisher(assetDir, publisher) {
830
- const markers = ["SKILL.md", "AGENT.md", "CONTRACT.md"];
831
- let markerFile;
832
- for (const m of markers) {
833
- if (fs11.existsSync(path25.join(assetDir, m))) {
834
- markerFile = path25.join(assetDir, m);
835
- break;
836
- }
837
- }
932
+ function normalizeAssetFrontmatter(assetDir) {
933
+ let markerFile = ["SKILL.md", "AGENT.md", "CONTRACT.md"].map((m) => path23.join(assetDir, m)).find((f) => fs9.existsSync(f));
838
934
  if (!markerFile) {
839
- const promptMd = fs11.readdirSync(assetDir).find((f) => f.endsWith(".prompt.md"));
840
- if (promptMd) markerFile = path25.join(assetDir, promptMd);
935
+ const promptMd = fs9.readdirSync(assetDir).find((f) => f.endsWith(".prompt.md"));
936
+ if (promptMd) markerFile = path23.join(assetDir, promptMd);
841
937
  }
842
938
  if (!markerFile) return;
843
939
  try {
844
- const { data, body } = parseFrontmatter(fs11.readFileSync(markerFile, "utf8"));
845
- const meta = data.metadata && typeof data.metadata === "object" && !Array.isArray(data.metadata) ? { ...data.metadata } : {};
846
- if (meta.publisher != null) return;
847
- meta.publisher = publisher;
848
- data.metadata = meta;
940
+ const { data, body } = parseFrontmatter(fs9.readFileSync(markerFile, "utf8"));
849
941
  const fm = stringify(data).trimEnd();
850
- fs11.writeFileSync(markerFile, `---
942
+ fs9.writeFileSync(markerFile, `---
851
943
  ${fm}
852
944
  ---
853
945
 
@@ -862,17 +954,13 @@ async function registerLibraryAsset(lib, index, input) {
862
954
  { publisher: input.publisher },
863
955
  getStoreIdentity()
864
956
  );
865
- if (source === "library-name") {
866
- logWarn(
867
- `No publisher given and not signed in \u2014 using the library name "${publisher}" as the publisher. Pass --publisher <name> or run \`skaile store login\`; change it later with \`skaile library set ${lib.name} publisher=<name>\`.`
868
- );
869
- }
870
- stampAssetPublisher(input.assetDir, publisher);
957
+ warnLibraryNameFallback(lib.name, { publisher, source });
958
+ normalizeAssetFrontmatter(input.assetDir);
871
959
  stampManifestPublisher(lib.path, publisher);
872
960
  upsertManifestAsset(lib.path, {
873
961
  kind: input.kind,
874
962
  name: input.name,
875
- root: path25.relative(lib.path, input.assetDir) || input.name,
963
+ root: path23.relative(lib.path, input.assetDir) || input.name,
876
964
  version: input.version,
877
965
  publisher
878
966
  });
@@ -882,27 +970,38 @@ async function registerLibraryAsset(lib, index, input) {
882
970
  }
883
971
  var LIBRARY_UPGRADE_DOCS = "https://github.com/skaile-ai/workspaces/blob/main/docs/sections/cli/commands/library.md#upgrading-a-4x-library";
884
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}`;
885
- function countDomainFiles(root) {
886
- let count = 0;
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 = [];
887
983
  const walk = (dir) => {
888
984
  let entries;
889
985
  try {
890
- entries = fs11.readdirSync(dir, { withFileTypes: true });
986
+ entries = fs9.readdirSync(dir, { withFileTypes: true });
891
987
  } catch {
892
988
  return;
893
989
  }
894
990
  for (const entry of entries) {
895
991
  if (entry.isDirectory()) {
896
992
  if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
897
- walk(path25.join(dir, entry.name));
993
+ walk(path23.join(dir, entry.name));
898
994
  }
899
- } else if (entry.name === "DOMAIN.md") {
900
- count++;
995
+ } else if (match(entry.name)) {
996
+ found.push(path23.join(dir, entry.name));
901
997
  }
902
998
  }
903
999
  };
904
1000
  walk(root);
905
- return count;
1001
+ return found;
1002
+ }
1003
+ function countDomainFiles(root) {
1004
+ return findFiles(root, (name) => name === "DOMAIN.md").length;
906
1005
  }
907
1006
  function warnIgnoredDomainFiles(root) {
908
1007
  const count = countDomainFiles(root);
@@ -913,27 +1012,38 @@ function warnIgnoredDomainFiles(root) {
913
1012
  }
914
1013
  return count;
915
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
+ }
916
1026
  var DEFAULT_IMPORT_VERSION = "0.1.0";
917
1027
  var DEFAULT_IMPORT_STAGE = "alpha";
918
1028
  function claudeSkillRoots() {
919
1029
  const roots = [];
920
1030
  const override = process.env.SKAILE_CLAUDE_SKILLS_DIR;
921
1031
  if (override) roots.push(override);
922
- roots.push(path25.join(os.homedir(), ".claude", "skills"));
1032
+ roots.push(path23.join(os.homedir(), ".claude", "skills"));
923
1033
  return roots;
924
1034
  }
925
1035
  function resolveImportSource(nameOrPath) {
926
- const asPath = path25.resolve(nameOrPath);
927
- if (fs11.existsSync(asPath)) {
928
- const dir = fs11.statSync(asPath).isDirectory() ? asPath : path25.dirname(asPath);
929
- const skillFile = path25.join(dir, "SKILL.md");
930
- if (fs11.existsSync(skillFile)) return { dir, skillFile, via: "path" };
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" };
931
1041
  }
932
- if (!nameOrPath.includes(path25.sep) && !nameOrPath.startsWith(".")) {
1042
+ if (!nameOrPath.includes(path23.sep) && !nameOrPath.startsWith(".")) {
933
1043
  for (const root of claudeSkillRoots()) {
934
- const dir = path25.join(root, nameOrPath);
935
- const skillFile = path25.join(dir, "SKILL.md");
936
- if (fs11.existsSync(skillFile)) return { dir, skillFile, via: "claude-skills" };
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" };
937
1047
  }
938
1048
  }
939
1049
  return null;
@@ -989,15 +1099,16 @@ ${body}
989
1099
 
990
1100
  // cli/src/commands/asset-cmd.ts
991
1101
  async function resolveDefByRef(library, ref, opts) {
992
- const inScope = (d) => !opts?.fromLibraryId || d.libraryId === opts.fromLibraryId;
993
- const direct = await library.getAssetDef(ref);
994
- if (direct && inScope(direct)) return direct;
995
1102
  let parsed;
996
1103
  try {
997
1104
  parsed = parseAssetRef(ref);
998
- } catch {
999
- return null;
1105
+ } catch (err2) {
1106
+ logErr(
1107
+ `malformed asset ref '${ref}' \u2014 expected ${REF_HINT}: ${err2 instanceof Error ? err2.message : String(err2)}`
1108
+ );
1109
+ process.exit(1);
1000
1110
  }
1111
+ const inScope = (d) => !opts?.fromLibraryId || d.libraryId === opts.fromLibraryId;
1001
1112
  const wantPublisher = parsed.publisher?.replace(/^@/, "");
1002
1113
  const defs = await library.listAssetDefs({ kind: parsed.kind });
1003
1114
  const matches = defs.filter(
@@ -1008,7 +1119,8 @@ async function resolveDefByRef(library, ref, opts) {
1008
1119
  return matches[0];
1009
1120
  }
1010
1121
  function withCanonicalRef(def) {
1011
- return { ref: catalogAssetRef(def), ...def };
1122
+ const { id: _storageId, ...rest } = def;
1123
+ return { ref: catalogAssetRef(def), ...rest };
1012
1124
  }
1013
1125
  function resolveLibraryOption(opts) {
1014
1126
  if (opts.library && opts.to && opts.library !== opts.to) {
@@ -1021,11 +1133,19 @@ function resolveLibraryOption(opts) {
1021
1133
  }
1022
1134
  function makeAssetCommand() {
1023
1135
  const cmd = new Command("asset").description("Author and install AI assets");
1024
- cmd.command("import <name-or-path>").description("Import + skailify an existing coding-agent skill into a library").option("--library <library>", "Target library (default: auto / personal)").addOption(new Option("--to <library>", "Alias for --library").hideHelp()).option("--version <semver>", "Version to stamp when the skill ships none").option("--stage <stage>", "Lifecycle stage to stamp (default: alpha)").option("--no-normalize", "Copy verbatim \u2014 skip frontmatter normalization").option(
1136
+ cmd.command("import <name-or-path>").description("Import + skailify an existing coding-agent skill into a library").option("--library <library>", "Target library (default: auto / personal)").addOption(new Option("--to <library>", "Alias for --library").hideHelp()).addOption(removedDomainOption()).option("--version <semver>", "Version to stamp when the skill ships none").option("--stage <stage>", "Lifecycle stage to stamp (default: alpha)").option("--no-normalize", "Copy verbatim \u2014 skip frontmatter normalization").option(
1025
1137
  "--publisher <name>",
1026
1138
  "Publisher for the imported skill (default: the library's, else your store login)"
1027
1139
  ).option("--commit", "Auto-commit in git-backed libraries", false).action(
1028
1140
  async (nameOrPath, opts) => {
1141
+ 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
+ }
1029
1149
  const src = resolveImportSource(nameOrPath);
1030
1150
  if (!src) {
1031
1151
  logErr(
@@ -1055,24 +1175,31 @@ function makeAssetCommand() {
1055
1175
  logErr(err2 instanceof Error ? err2.message : String(err2));
1056
1176
  process.exit(1);
1057
1177
  }
1058
- const rawSkill = fs11.readFileSync(src.skillFile, "utf8");
1178
+ const rawSkill = fs9.readFileSync(src.skillFile, "utf8");
1059
1179
  const norm = opts.normalize ? normalizeSkillContent(rawSkill, {
1060
- fallbackName: path25.basename(src.dir),
1180
+ fallbackName: path23.basename(src.dir),
1061
1181
  version: opts.version,
1062
1182
  stage: opts.stage
1063
- }) : { content: rawSkill, name: path25.basename(src.dir), changed: false, notes: [] };
1183
+ }) : { content: rawSkill, name: path23.basename(src.dir), changed: false, notes: [] };
1064
1184
  if (!opts.normalize && !isValidAssetName(norm.name)) {
1065
1185
  logWarn(
1066
1186
  `Name "${norm.name}" is not canonical (kebab-case); \`skaile validate\` will reject this manifest entry. Drop --no-normalize to slugify it.`
1067
1187
  );
1068
1188
  }
1069
- const destDir = path25.join(target.path, norm.name);
1070
- if (fs11.existsSync(destDir)) {
1189
+ const destDir = path23.join(target.path, norm.name);
1190
+ if (fs9.existsSync(destDir)) {
1071
1191
  logErr(`Destination already exists: ${destDir}`);
1072
1192
  process.exit(1);
1073
1193
  }
1074
- fs11.cpSync(src.dir, destDir, { recursive: true });
1075
- fs11.writeFileSync(path25.join(destDir, "SKILL.md"), norm.content, "utf8");
1194
+ const taken = conflictingAssetRoot(target.path, "skill", norm.name, norm.name);
1195
+ if (taken) {
1196
+ logErr(
1197
+ `skill:${norm.name} already exists at "${taken}" \u2014 importing it again would re-point the manifest entry. Rename the skill first.`
1198
+ );
1199
+ process.exit(1);
1200
+ }
1201
+ fs9.cpSync(src.dir, destDir, { recursive: true });
1202
+ fs9.writeFileSync(path23.join(destDir, "SKILL.md"), norm.content, "utf8");
1076
1203
  for (const note of norm.notes) logInfo(` \u2022 ${note}`);
1077
1204
  const fm = parseFrontmatter(norm.content).data;
1078
1205
  for (const f of checkAgentSkillConformance(fm, { dirName: norm.name })) {
@@ -1105,13 +1232,14 @@ function makeAssetCommand() {
1105
1232
  }
1106
1233
  }
1107
1234
  );
1108
- cmd.command("migrate <path>").description("Move/copy/link a workspace asset into a library").option("--library <library>", "Target library (default: auto)").addOption(new Option("--to <library>", "Alias for --library").hideHelp()).option("--mode <mode>", "copy | move | link", "copy").option("--commit", "Auto-commit in git-backed libraries", false).action(
1235
+ cmd.command("migrate <path>").description("Move/copy/link a workspace asset into a library").option("--library <library>", "Target library (default: auto)").addOption(new Option("--to <library>", "Alias for --library").hideHelp()).addOption(removedDomainOption()).option("--mode <mode>", "copy | move | link", "copy").option("--commit", "Auto-commit in git-backed libraries", false).action(
1109
1236
  async (srcPath, opts) => {
1237
+ rejectRemovedDomainOption(opts);
1110
1238
  if (!["copy", "move", "link"].includes(opts.mode)) {
1111
1239
  logErr(`Invalid --mode "${opts.mode}". Expected: copy | move | link.`);
1112
1240
  process.exit(1);
1113
1241
  }
1114
- if (!fs11.existsSync(srcPath)) {
1242
+ if (!fs9.existsSync(srcPath)) {
1115
1243
  logErr(`Source path does not exist: ${srcPath}`);
1116
1244
  process.exit(1);
1117
1245
  }
@@ -1137,29 +1265,29 @@ function makeAssetCommand() {
1137
1265
  );
1138
1266
  process.exit(1);
1139
1267
  }
1140
- const basename2 = path25.basename(srcPath);
1268
+ const basename3 = path23.basename(srcPath);
1141
1269
  const destDir = target.path;
1142
- fs11.mkdirSync(destDir, { recursive: true });
1143
- const destPath = path25.join(destDir, basename2);
1144
- if (fs11.existsSync(destPath)) {
1270
+ fs9.mkdirSync(destDir, { recursive: true });
1271
+ const destPath = path23.join(destDir, basename3);
1272
+ if (fs9.existsSync(destPath)) {
1145
1273
  logErr(`Destination already exists: ${destPath}`);
1146
1274
  process.exit(1);
1147
1275
  }
1148
1276
  switch (opts.mode) {
1149
1277
  case "copy":
1150
- fs11.cpSync(srcPath, destPath, { recursive: true });
1278
+ fs9.cpSync(srcPath, destPath, { recursive: true });
1151
1279
  break;
1152
1280
  case "move":
1153
- fs11.renameSync(srcPath, destPath);
1281
+ fs9.renameSync(srcPath, destPath);
1154
1282
  break;
1155
1283
  case "link":
1156
- fs11.symlinkSync(path25.resolve(srcPath), destPath);
1284
+ fs9.symlinkSync(path23.resolve(srcPath), destPath);
1157
1285
  break;
1158
1286
  }
1159
1287
  if (target.backend === "git" && opts.commit) {
1160
1288
  const { spawnSync: spawnSync2 } = await import('child_process');
1161
1289
  spawnSync2("git", ["add", "--", destPath], { cwd: target.path, stdio: "inherit" });
1162
- const r = spawnSync2("git", ["commit", "-m", `skaile: migrate ${basename2}`], {
1290
+ const r = spawnSync2("git", ["commit", "-m", `skaile: migrate ${basename3}`], {
1163
1291
  cwd: target.path,
1164
1292
  stdio: "inherit"
1165
1293
  });
@@ -1167,7 +1295,7 @@ function makeAssetCommand() {
1167
1295
  logWarn("Nothing committed (working tree clean or commit aborted).");
1168
1296
  }
1169
1297
  }
1170
- logOk(`Migrated ${basename2} \u2192 ${target.name} (${opts.mode})`);
1298
+ logOk(`Migrated ${basename3} \u2192 ${target.name} (${opts.mode})`);
1171
1299
  if (opts.mode === "move") {
1172
1300
  logInfo("Source moved into the library \u2014 future edits modify the library copy.");
1173
1301
  } else if (opts.mode === "copy") {
@@ -1283,14 +1411,14 @@ function makeAuthCommand() {
1283
1411
  }
1284
1412
  function collectCacheTargets(scope) {
1285
1413
  const out = [];
1286
- out.push(path25__default.join(scope.projectDir, ".skaile", "cache"));
1287
- out.push(path25__default.join(scope.projectDir, ".skaile", "store-cache"));
1288
- out.push(path25__default.join(scope.projectDir, ".skaile", "repos"));
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"));
1289
1417
  if (scope.global) {
1290
1418
  out.push(globalCacheRoot());
1291
1419
  const home = globalSkaileDir();
1292
- out.push(path25__default.join(home, "repos"));
1293
- out.push(path25__default.join(home, "catalog-cache"));
1420
+ out.push(path23__default.join(home, "repos"));
1421
+ out.push(path23__default.join(home, "catalog-cache"));
1294
1422
  }
1295
1423
  return out;
1296
1424
  }
@@ -1304,7 +1432,7 @@ function dirSize(target) {
1304
1432
  function dirSizeOfDir(dir) {
1305
1433
  let total = 0;
1306
1434
  for (const ent of readdirSync(dir, { withFileTypes: true })) {
1307
- const child = path25__default.join(dir, ent.name);
1435
+ const child = path23__default.join(dir, ent.name);
1308
1436
  if (ent.isSymbolicLink()) continue;
1309
1437
  if (ent.isDirectory()) total += dirSizeOfDir(child);
1310
1438
  else if (ent.isFile()) total += statSync(child).size;
@@ -1330,7 +1458,7 @@ function makeCacheCommand() {
1330
1458
  const cmd = new Command("cache").description("Inspect and reclaim the re-derivable cache");
1331
1459
  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) => {
1332
1460
  const targets = collectCacheTargets({
1333
- projectDir: path25__default.resolve(opts.projectDir),
1461
+ projectDir: path23__default.resolve(opts.projectDir),
1334
1462
  global: opts.global
1335
1463
  }).filter((t) => existsSync(t));
1336
1464
  if (targets.length === 0) {
@@ -1360,12 +1488,12 @@ function makeCacheCommand() {
1360
1488
  for (const r of removed) logOk(`Removed ${r}`);
1361
1489
  });
1362
1490
  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) => {
1363
- console.log(path25__default.join(path25__default.resolve(opts.projectDir), ".skaile", "cache"));
1491
+ console.log(path23__default.join(path23__default.resolve(opts.projectDir), ".skaile", "cache"));
1364
1492
  if (opts.global) console.log(globalCacheRoot());
1365
1493
  });
1366
1494
  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) => {
1367
1495
  const targets = collectCacheTargets({
1368
- projectDir: path25__default.resolve(opts.projectDir),
1496
+ projectDir: path23__default.resolve(opts.projectDir),
1369
1497
  global: opts.global
1370
1498
  });
1371
1499
  console.log();
@@ -1381,7 +1509,7 @@ function makeCatalogCommand() {
1381
1509
  const catalog = new Command("catalog").description("Catalog source health and configuration");
1382
1510
  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) => {
1383
1511
  const { resolveConfig, isLocalCatalogUrl, trpcGetUrl } = await import('../library/index.js');
1384
- const projectDir = opts.projectDir ? path25__default.resolve(opts.projectDir) : void 0;
1512
+ const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : void 0;
1385
1513
  const cfg = resolveConfig({ projectDir });
1386
1514
  const baseUrl = opts.url ?? cfg.catalog.url;
1387
1515
  if (isLocalCatalogUrl(baseUrl)) {
@@ -1399,7 +1527,7 @@ function makeCatalogCommand() {
1399
1527
  });
1400
1528
  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) => {
1401
1529
  const { resolveConfig } = await import('../library/index.js');
1402
- const projectDir = opts.projectDir ? path25__default.resolve(opts.projectDir) : void 0;
1530
+ const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : void 0;
1403
1531
  const cfg = resolveConfig({ projectDir });
1404
1532
  console.log(`url: ${cfg.catalog.url}`);
1405
1533
  console.log(`framing: ${cfg.catalog.framing}`);
@@ -1408,7 +1536,7 @@ function makeCatalogCommand() {
1408
1536
  return catalog;
1409
1537
  }
1410
1538
  async function runLocalCatalogTest(projectDir) {
1411
- const { resolveCatalogSource } = await import('../open-library-4WUMQHES.js');
1539
+ const { resolveCatalogSource } = await import('../open-library-OG457THY.js');
1412
1540
  let resolved;
1413
1541
  try {
1414
1542
  resolved = await resolveCatalogSource({ projectDir });
@@ -1548,29 +1676,20 @@ function libraryFlowEntries() {
1548
1676
  async function scanLibraryFlowEntries() {
1549
1677
  const entries = [];
1550
1678
  try {
1551
- const { LocalCatalogSource, LocalIndex, resolveIndexPath } = await import('../library/index.js');
1679
+ const { LocalIndex, resolveIndexPath, scanAuthoringLibraries } = await import('../library/index.js');
1552
1680
  const indexPath = resolveIndexPath();
1553
1681
  if (!existsSync(indexPath)) return entries;
1554
- const [{ authoringLibraries }, { getKindRegistry: getKindRegistry2 }] = await Promise.all([
1555
- import('../open-library-4WUMQHES.js'),
1556
- import('../open-registry-NVPCQPND.js')
1557
- ]);
1682
+ const { getKindRegistry: getKindRegistry2 } = await import('../open-registry-ZUZJ7MS7.js');
1558
1683
  const index = new LocalIndex({ indexPath });
1559
1684
  try {
1560
- const registry = getKindRegistry2();
1561
- for (const lib of authoringLibraries(await index.listSources())) {
1562
- if (!existsSync(lib.path)) continue;
1563
- try {
1564
- const { assets } = new LocalCatalogSource(index, lib.id, lib.path, registry).scan();
1565
- for (const asset of assets) {
1566
- if (asset.kind !== "flow") continue;
1567
- try {
1568
- const flow = loadFlow(asset.manifestPath);
1569
- if (flow.id) entries.push({ flow, path: asset.manifestPath });
1570
- } catch {
1571
- }
1685
+ for (const { assets } of await scanAuthoringLibraries(index, getKindRegistry2())) {
1686
+ for (const asset of assets) {
1687
+ if (asset.kind !== "flow") continue;
1688
+ try {
1689
+ const flow = loadFlow(asset.manifestPath);
1690
+ if (flow.id) entries.push({ flow, path: asset.manifestPath });
1691
+ } catch {
1572
1692
  }
1573
- } catch {
1574
1693
  }
1575
1694
  }
1576
1695
  } finally {
@@ -1610,11 +1729,11 @@ function findSkills() {
1610
1729
  return deduped;
1611
1730
  }
1612
1731
  function walkSkills(dir, out) {
1613
- for (const entry of fs11__default.readdirSync(dir, { withFileTypes: true })) {
1614
- const full = path25__default.join(dir, entry.name);
1732
+ for (const entry of fs9__default.readdirSync(dir, { withFileTypes: true })) {
1733
+ const full = path23__default.join(dir, entry.name);
1615
1734
  if (entry.isDirectory()) {
1616
- const skillMd = path25__default.join(full, "SKILL.md");
1617
- if (fs11__default.existsSync(skillMd)) {
1735
+ const skillMd = path23__default.join(full, "SKILL.md");
1736
+ if (fs9__default.existsSync(skillMd)) {
1618
1737
  out.push({ name: entry.name, path: full, skillPath: skillMd });
1619
1738
  } else {
1620
1739
  walkSkills(full, out);
@@ -1635,10 +1754,10 @@ function resolveFlowIds() {
1635
1754
  }
1636
1755
  }
1637
1756
  function resolveSessionIds(projectDir) {
1638
- const sessionsDir = path25__default.join(projectDir, ".skaile", "sessions");
1639
- if (!fs11__default.existsSync(sessionsDir)) return [];
1757
+ const sessionsDir = path23__default.join(projectDir, ".skaile", "sessions");
1758
+ if (!fs9__default.existsSync(sessionsDir)) return [];
1640
1759
  try {
1641
- return fs11__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
1760
+ return fs9__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
1642
1761
  } catch {
1643
1762
  return [];
1644
1763
  }
@@ -1777,7 +1896,7 @@ function printResolvedPathsSection(config) {
1777
1896
  console.log(` ${S.label("prompts:".padEnd(16))} ${config.promptsDir ?? paths.promptsDir}`);
1778
1897
  }
1779
1898
  async function showConfig(opts) {
1780
- const projectDir = opts.projectDir ? path25__default.resolve(opts.projectDir) : process.cwd();
1899
+ const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
1781
1900
  let config;
1782
1901
  let wsDefaults;
1783
1902
  try {
@@ -1822,13 +1941,13 @@ function makeConfigCommand() {
1822
1941
  const cmd = new Command("config").description("Manage personal config (.skaile/settings.json)");
1823
1942
  cmd.command("show").description("Show effective config with sources").option("--project-dir <path>", "Project directory").action((opts) => showConfig(opts));
1824
1943
  cmd.command("get <key>").description("Get an effective config value").option("--project-dir <path>", "Project directory").action(async (key, opts) => {
1825
- const projectDir = opts.projectDir ? path25__default.resolve(opts.projectDir) : process.cwd();
1944
+ const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
1826
1945
  const config = await resolveSettings(projectDir);
1827
1946
  const value = config[key];
1828
1947
  console.log(value ?? S.dim("(not set)"));
1829
1948
  });
1830
1949
  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) => {
1831
- const projectDir = opts.projectDir ? path25__default.resolve(opts.projectDir) : process.cwd();
1950
+ const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
1832
1951
  if (key === "provider" || key === "cloud" || key === "cloudConfig") {
1833
1952
  logErr(
1834
1953
  `'${key}' is no longer a setting \u2014 an endpoint is an AI provider registry entry and a session selects one with a model reference.
@@ -2168,8 +2287,8 @@ function makeConnectorCommand() {
2168
2287
  async (driver, opts) => {
2169
2288
  const { installNpmPackages } = await import('../connectors/index.js');
2170
2289
  const { scanDirectory: scanDirectory2, factoryAssetRoots: factoryAssetRoots2, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
2171
- const projectDir = path25__default.resolve(opts.projectDir);
2172
- const yamlPath = path25__default.join(projectDir, "skaile.yaml");
2290
+ const projectDir = path23__default.resolve(opts.projectDir);
2291
+ const yamlPath = path23__default.join(projectDir, "skaile.yaml");
2173
2292
  if (!existsSync(yamlPath)) {
2174
2293
  logErr("No skaile.yaml found in current directory. Run 'skaile init' first.");
2175
2294
  process.exit(1);
@@ -2229,8 +2348,8 @@ ${installResult.output}`);
2229
2348
  );
2230
2349
  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) => {
2231
2350
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
2232
- const projectDir = path25__default.resolve(opts.projectDir);
2233
- const yamlPath = path25__default.join(projectDir, "skaile.yaml");
2351
+ const projectDir = path23__default.resolve(opts.projectDir);
2352
+ const yamlPath = path23__default.join(projectDir, "skaile.yaml");
2234
2353
  if (!existsSync(yamlPath)) {
2235
2354
  logErr("No skaile.yaml found in current directory.");
2236
2355
  process.exit(1);
@@ -2247,7 +2366,7 @@ ${installResult.output}`);
2247
2366
  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) => {
2248
2367
  const res = await import('../connectors/index.js');
2249
2368
  res.registerBuiltinConnectors();
2250
- const projectDir = path25__default.resolve(opts.projectDir);
2369
+ const projectDir = path23__default.resolve(opts.projectDir);
2251
2370
  const declarations = res.loadConnectorDeclarations(projectDir);
2252
2371
  if (declarations.length === 0) {
2253
2372
  console.log("No connectors configured in skaile.yaml.");
@@ -2271,7 +2390,7 @@ ${installResult.output}`);
2271
2390
  await manager.disconnectAll();
2272
2391
  });
2273
2392
  cmd.command("list").description("List all configured connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
2274
- const projectDir = path25__default.resolve(opts.projectDir);
2393
+ const projectDir = path23__default.resolve(opts.projectDir);
2275
2394
  const manager = await connectConnectors(projectDir);
2276
2395
  try {
2277
2396
  console.log(JSON.stringify(manager.listConnectors(), null, 2));
@@ -2280,7 +2399,7 @@ ${installResult.output}`);
2280
2399
  }
2281
2400
  });
2282
2401
  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) => {
2283
- const projectDir = path25__default.resolve(opts.projectDir);
2402
+ const projectDir = path23__default.resolve(opts.projectDir);
2284
2403
  const manager = await connectConnectors(projectDir);
2285
2404
  try {
2286
2405
  if (opts.all) {
@@ -2304,7 +2423,7 @@ ${installResult.output}`);
2304
2423
  }
2305
2424
  });
2306
2425
  cmd.command("ops <id>").description("List available operations for a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
2307
- const projectDir = path25__default.resolve(opts.projectDir);
2426
+ const projectDir = path23__default.resolve(opts.projectDir);
2308
2427
  const manager = await connectConnectors(projectDir);
2309
2428
  try {
2310
2429
  if (!manager.has(id)) {
@@ -2319,7 +2438,7 @@ ${installResult.output}`);
2319
2438
  }
2320
2439
  });
2321
2440
  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) => {
2322
- const projectDir = path25__default.resolve(opts.projectDir);
2441
+ const projectDir = path23__default.resolve(opts.projectDir);
2323
2442
  const manager = await connectConnectors(projectDir);
2324
2443
  try {
2325
2444
  const content = await manager.read(id, resourcePath);
@@ -2329,7 +2448,7 @@ ${installResult.output}`);
2329
2448
  }
2330
2449
  });
2331
2450
  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) => {
2332
- const projectDir = path25__default.resolve(opts.projectDir);
2451
+ const projectDir = path23__default.resolve(opts.projectDir);
2333
2452
  const manager = await connectConnectors(projectDir);
2334
2453
  try {
2335
2454
  await manager.write(id, resourcePath, { data: content });
@@ -2339,7 +2458,7 @@ ${installResult.output}`);
2339
2458
  }
2340
2459
  });
2341
2460
  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) => {
2342
- const projectDir = path25__default.resolve(opts.projectDir);
2461
+ const projectDir = path23__default.resolve(opts.projectDir);
2343
2462
  const manager = await connectConnectors(projectDir);
2344
2463
  try {
2345
2464
  const entries = await manager.list(id, resourcePath, {
@@ -2352,7 +2471,7 @@ ${installResult.output}`);
2352
2471
  }
2353
2472
  });
2354
2473
  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) => {
2355
- const projectDir = path25__default.resolve(opts.projectDir);
2474
+ const projectDir = path23__default.resolve(opts.projectDir);
2356
2475
  const manager = await connectConnectors(projectDir);
2357
2476
  try {
2358
2477
  const results = await manager.search(id, query);
@@ -2362,7 +2481,7 @@ ${installResult.output}`);
2362
2481
  }
2363
2482
  });
2364
2483
  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) => {
2365
- const projectDir = path25__default.resolve(opts.projectDir);
2484
+ const projectDir = path23__default.resolve(opts.projectDir);
2366
2485
  const manager = await connectConnectors(projectDir);
2367
2486
  try {
2368
2487
  const ok = await manager.delete(id, resourcePath);
@@ -2372,7 +2491,7 @@ ${installResult.output}`);
2372
2491
  }
2373
2492
  });
2374
2493
  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) => {
2375
- const projectDir = path25__default.resolve(opts.projectDir);
2494
+ const projectDir = path23__default.resolve(opts.projectDir);
2376
2495
  const manager = await connectConnectors(projectDir);
2377
2496
  try {
2378
2497
  if (!manager.has(id)) {
@@ -2481,7 +2600,7 @@ function envRecord() {
2481
2600
  async function buildDeployContext(projectDir) {
2482
2601
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
2483
2602
  const config = resolveSkWorkspaceConfig2(projectDir);
2484
- const workspaceId = config.name ?? path25__default.basename(projectDir);
2603
+ const workspaceId = config.name ?? path23__default.basename(projectDir);
2485
2604
  let log;
2486
2605
  try {
2487
2606
  const { createLogger } = await import('../core/logging.js');
@@ -2513,13 +2632,13 @@ async function ensureTargetsRegistered(projectDir) {
2513
2632
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
2514
2633
  const config = resolveSkWorkspaceConfig2(projectDir);
2515
2634
  if (config.plugins && config.plugins.length > 0) {
2516
- const { ensurePluginsLoaded } = await import('../plugin-store-66QFBNEO.js');
2635
+ const { ensurePluginsLoaded } = await import('../plugin-store-MPAMD5OT.js');
2517
2636
  const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
2518
2637
  for (const f of result.failed) logWarn(f.error);
2519
2638
  }
2520
2639
  }
2521
2640
  async function runUp(opts) {
2522
- const projectDir = path25__default.resolve(opts.projectDir);
2641
+ const projectDir = path23__default.resolve(opts.projectDir);
2523
2642
  await ensureTargetsRegistered(projectDir);
2524
2643
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
2525
2644
  const { resolveDeployTarget, pluginRegistry } = await import('../plugin-registry/index.js');
@@ -2587,7 +2706,7 @@ async function restoreFromHandle(projectDir) {
2587
2706
  return { target, handle, ctx };
2588
2707
  }
2589
2708
  async function runDown(opts) {
2590
- const projectDir = path25__default.resolve(opts.projectDir);
2709
+ const projectDir = path23__default.resolve(opts.projectDir);
2591
2710
  const restored = await restoreFromHandle(projectDir);
2592
2711
  if (!restored) return;
2593
2712
  await restored.handle.stop();
@@ -2596,7 +2715,7 @@ async function runDown(opts) {
2596
2715
  logOk(`Stopped ${S.cmd(restored.target.id)} and cleared the handle.`);
2597
2716
  }
2598
2717
  async function runStatus(opts) {
2599
- const projectDir = path25__default.resolve(opts.projectDir);
2718
+ const projectDir = path23__default.resolve(opts.projectDir);
2600
2719
  const restored = await restoreFromHandle(projectDir);
2601
2720
  if (!restored) return;
2602
2721
  const health = await restored.handle.health();
@@ -2610,7 +2729,7 @@ async function runStatus(opts) {
2610
2729
  console.log();
2611
2730
  }
2612
2731
  async function runLogs(opts) {
2613
- const projectDir = path25__default.resolve(opts.projectDir);
2732
+ const projectDir = path23__default.resolve(opts.projectDir);
2614
2733
  const restored = await restoreFromHandle(projectDir);
2615
2734
  if (!restored) return;
2616
2735
  if (!restored.handle.logs) {
@@ -2636,7 +2755,7 @@ function makeDiffCommand() {
2636
2755
  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) => {
2637
2756
  const am2 = new AssetManager({
2638
2757
  registry: getKindRegistry(),
2639
- projectDir: path25__default.resolve(opts.projectDir)
2758
+ projectDir: path23__default.resolve(opts.projectDir)
2640
2759
  });
2641
2760
  const result = await am2.diff(ref);
2642
2761
  switch (result.status) {
@@ -2659,7 +2778,7 @@ function makeDiffCommand() {
2659
2778
  function makeFlowCommand() {
2660
2779
  const cmd = new Command("flow").description("Manage flows");
2661
2780
  cmd.command("list").description("List available flows").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
2662
- const flows = await discoverFlowsWithLibraries(path25__default.resolve(opts.projectDir));
2781
+ const flows = await discoverFlowsWithLibraries(path23__default.resolve(opts.projectDir));
2663
2782
  if (flows.length === 0) {
2664
2783
  logInfo("No flows found.");
2665
2784
  return;
@@ -2674,7 +2793,7 @@ function makeFlowCommand() {
2674
2793
  console.log();
2675
2794
  });
2676
2795
  cmd.command("show <id>").description("Show flow details and node graph").option("--project-dir <path>", "Project directory", process.cwd()).action(async (id, opts) => {
2677
- const flows = await discoverFlowsWithLibraries(path25__default.resolve(opts.projectDir));
2796
+ const flows = await discoverFlowsWithLibraries(path23__default.resolve(opts.projectDir));
2678
2797
  const flow = flows.find((f) => f.id === id);
2679
2798
  if (!flow) {
2680
2799
  logErr(`Flow not found: ${id}`);
@@ -2708,7 +2827,7 @@ function makeHistoryCommand() {
2708
2827
  cmd.argument("[limit]", "Number of entries to show", "20").option("--project-dir <path>", "Project directory", process.cwd()).action((limitStr, opts) => {
2709
2828
  const am2 = new AssetManager({
2710
2829
  registry: getKindRegistry(),
2711
- projectDir: path25__default.resolve(opts.projectDir)
2830
+ projectDir: path23__default.resolve(opts.projectDir)
2712
2831
  });
2713
2832
  const limit = parseInt(limitStr, 10) || 20;
2714
2833
  const entries = am2.history(limit);
@@ -2731,7 +2850,7 @@ function makeHistoryCommand() {
2731
2850
  cmd.command("clear").description("Clear action history").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
2732
2851
  const am2 = new AssetManager({
2733
2852
  registry: getKindRegistry(),
2734
- projectDir: path25__default.resolve(opts.projectDir)
2853
+ projectDir: path23__default.resolve(opts.projectDir)
2735
2854
  });
2736
2855
  am2.clearHistory();
2737
2856
  logOk("History cleared.");
@@ -2745,7 +2864,7 @@ var MCP_SERVER_ENTRY = {
2745
2864
  env: {}
2746
2865
  };
2747
2866
  function pluginDir(projectDir) {
2748
- return path25__default.join(projectDir, ".claude", "plugins", "skaile");
2867
+ return path23__default.join(projectDir, ".claude", "plugins", "skaile");
2749
2868
  }
2750
2869
  async function readJsonStrict(p6) {
2751
2870
  let raw;
@@ -2763,7 +2882,7 @@ async function readJsonStrict(p6) {
2763
2882
  }
2764
2883
  }
2765
2884
  async function writeJson(p6, value) {
2766
- await fs6.mkdir(path25__default.dirname(p6), { recursive: true });
2885
+ await fs6.mkdir(path23__default.dirname(p6), { recursive: true });
2767
2886
  await fs6.writeFile(p6, `${JSON.stringify(value, null, 2)}
2768
2887
  `);
2769
2888
  }
@@ -2771,8 +2890,8 @@ async function copyDir(src, dest) {
2771
2890
  await fs6.mkdir(dest, { recursive: true });
2772
2891
  const entries = await fs6.readdir(src, { withFileTypes: true });
2773
2892
  for (const entry of entries) {
2774
- const srcPath = path25__default.join(src, entry.name);
2775
- const destPath = path25__default.join(dest, entry.name);
2893
+ const srcPath = path23__default.join(src, entry.name);
2894
+ const destPath = path23__default.join(dest, entry.name);
2776
2895
  if (entry.isDirectory()) await copyDir(srcPath, destPath);
2777
2896
  else await fs6.copyFile(srcPath, destPath);
2778
2897
  }
@@ -2781,14 +2900,14 @@ async function install(projectDir, opts) {
2781
2900
  return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);
2782
2901
  }
2783
2902
  async function installMcp(projectDir) {
2784
- const mcpPath = path25__default.join(projectDir, ".claude", "mcp.json");
2903
+ const mcpPath = path23__default.join(projectDir, ".claude", "mcp.json");
2785
2904
  const existing = await readJsonStrict(mcpPath) ?? {};
2786
2905
  const mcpServers = { ...existing.mcpServers ?? {} };
2787
2906
  const previous = mcpServers[SKAILE_MCP_NAME];
2788
2907
  const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);
2789
2908
  let warning;
2790
2909
  if (previous && !matches) {
2791
- warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path25__default.relative(projectDir, mcpPath)}`;
2910
+ warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path23__default.relative(projectDir, mcpPath)}`;
2792
2911
  }
2793
2912
  mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;
2794
2913
  await writeJson(mcpPath, { ...existing, mcpServers });
@@ -2797,15 +2916,15 @@ async function installMcp(projectDir) {
2797
2916
  async function installFullPlugin(projectDir) {
2798
2917
  const dir = pluginDir(projectDir);
2799
2918
  for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {
2800
- const dest = path25__default.join(dir, rel);
2801
- await fs6.mkdir(path25__default.dirname(dest), { recursive: true });
2919
+ const dest = path23__default.join(dir, rel);
2920
+ await fs6.mkdir(path23__default.dirname(dest), { recursive: true });
2802
2921
  await fs6.writeFile(dest, content);
2803
2922
  }
2804
- const projectSkillsDir = path25__default.join(projectDir, ".skaile", "skills");
2923
+ const projectSkillsDir = path23__default.join(projectDir, ".skaile", "skills");
2805
2924
  if (existsSync(projectSkillsDir)) {
2806
- await copyDir(projectSkillsDir, path25__default.join(dir, "skills"));
2925
+ await copyDir(projectSkillsDir, path23__default.join(dir, "skills"));
2807
2926
  }
2808
- const settingsPath = path25__default.join(projectDir, ".claude", "settings.json");
2927
+ const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
2809
2928
  const settings = await readJsonStrict(settingsPath) ?? {};
2810
2929
  const plugins = settings.plugins ?? [];
2811
2930
  if (!plugins.includes(dir)) plugins.push(dir);
@@ -2813,8 +2932,8 @@ async function installFullPlugin(projectDir) {
2813
2932
  return { changed: true, method: "plugin" };
2814
2933
  }
2815
2934
  async function uninstall(projectDir) {
2816
- const settingsPath = path25__default.join(projectDir, ".claude", "settings.json");
2817
- const mcpPath = path25__default.join(projectDir, ".claude", "mcp.json");
2935
+ const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
2936
+ const mcpPath = path23__default.join(projectDir, ".claude", "mcp.json");
2818
2937
  const dir = pluginDir(projectDir);
2819
2938
  let changed = false;
2820
2939
  const settings = await readJsonStrict(settingsPath);
@@ -2848,12 +2967,12 @@ async function uninstall(projectDir) {
2848
2967
  async function detectInstall(projectDir) {
2849
2968
  const dir = pluginDir(projectDir);
2850
2969
  const settings = await readJsonStrict(
2851
- path25__default.join(projectDir, ".claude", "settings.json")
2970
+ path23__default.join(projectDir, ".claude", "settings.json")
2852
2971
  );
2853
- if (existsSync(path25__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
2972
+ if (existsSync(path23__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
2854
2973
  return { method: "plugin", pluginPath: dir };
2855
2974
  }
2856
- const mcp = await readJsonStrict(path25__default.join(projectDir, ".claude", "mcp.json"));
2975
+ const mcp = await readJsonStrict(path23__default.join(projectDir, ".claude", "mcp.json"));
2857
2976
  if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {
2858
2977
  return { method: "mcp" };
2859
2978
  }
@@ -2862,7 +2981,7 @@ async function detectInstall(projectDir) {
2862
2981
  async function enable(projectDir) {
2863
2982
  const detected = await detectInstall(projectDir);
2864
2983
  if (!detected) throw new Error("plugin not installed for claude-code");
2865
- const settingsPath = path25__default.join(projectDir, ".claude", "settings.json");
2984
+ const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
2866
2985
  const settings = await readJsonStrict(settingsPath) ?? {};
2867
2986
  if (detected.method === "plugin") {
2868
2987
  const disabled2 = settings.disabledPlugins ?? [];
@@ -2884,7 +3003,7 @@ async function enable(projectDir) {
2884
3003
  async function disable(projectDir) {
2885
3004
  const detected = await detectInstall(projectDir);
2886
3005
  if (!detected) throw new Error("plugin not installed for claude-code");
2887
- const settingsPath = path25__default.join(projectDir, ".claude", "settings.json");
3006
+ const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
2888
3007
  const settings = await readJsonStrict(settingsPath) ?? {};
2889
3008
  if (detected.method === "plugin") {
2890
3009
  const list2 = settings.disabledPlugins ?? [];
@@ -2904,12 +3023,12 @@ async function disable(projectDir) {
2904
3023
  return { changed: true };
2905
3024
  }
2906
3025
  async function status(projectDir) {
2907
- const settingsPath = path25__default.join(projectDir, ".claude", "settings.json");
2908
- const mcpPath = path25__default.join(projectDir, ".claude", "mcp.json");
3026
+ const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
3027
+ const mcpPath = path23__default.join(projectDir, ".claude", "mcp.json");
2909
3028
  const dir = pluginDir(projectDir);
2910
3029
  const settings = await readJsonStrict(settingsPath);
2911
3030
  const mcp = await readJsonStrict(mcpPath);
2912
- const pluginInstalled = !!(existsSync(path25__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
3031
+ const pluginInstalled = !!(existsSync(path23__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
2913
3032
  const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);
2914
3033
  if (!pluginInstalled && !mcpInstalled) {
2915
3034
  return {
@@ -2927,7 +3046,7 @@ async function status(projectDir) {
2927
3046
  installed: "yes",
2928
3047
  enabled: disabled2 ? "no" : "yes",
2929
3048
  method: "plugin",
2930
- location: path25__default.relative(projectDir, dir)
3049
+ location: path23__default.relative(projectDir, dir)
2931
3050
  };
2932
3051
  }
2933
3052
  const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;
@@ -2936,7 +3055,7 @@ async function status(projectDir) {
2936
3055
  installed: "yes",
2937
3056
  enabled: disabled ? "no" : "yes",
2938
3057
  method: "mcp",
2939
- location: path25__default.relative(projectDir, mcpPath)
3058
+ location: path23__default.relative(projectDir, mcpPath)
2940
3059
  };
2941
3060
  }
2942
3061
  var SKAILE_MCP_NAME2 = "skaile-workspace";
@@ -2963,7 +3082,7 @@ async function readConfig(p6) {
2963
3082
  }
2964
3083
  }
2965
3084
  async function writeConfig(p6, value) {
2966
- await fs6.mkdir(path25__default.dirname(p6), { recursive: true });
3085
+ await fs6.mkdir(path23__default.dirname(p6), { recursive: true });
2967
3086
  const cleaned = {};
2968
3087
  for (const [k, v] of Object.entries(value)) {
2969
3088
  if (v === void 0) continue;
@@ -2972,7 +3091,7 @@ async function writeConfig(p6, value) {
2972
3091
  await fs6.writeFile(p6, stringify$1(cleaned));
2973
3092
  }
2974
3093
  function configPath(projectDir) {
2975
- return path25__default.join(projectDir, ".codex", "config.toml");
3094
+ return path23__default.join(projectDir, ".codex", "config.toml");
2976
3095
  }
2977
3096
  async function install2(projectDir) {
2978
3097
  const p6 = configPath(projectDir);
@@ -2983,7 +3102,7 @@ async function install2(projectDir) {
2983
3102
  const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
2984
3103
  let warning;
2985
3104
  if (previous && !matches) {
2986
- warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path25__default.relative(projectDir, p6)}`;
3105
+ warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path23__default.relative(projectDir, p6)}`;
2987
3106
  }
2988
3107
  if (matches) return { changed: false, method: "toml" };
2989
3108
  servers[SKAILE_MCP_NAME2] = next;
@@ -3024,12 +3143,12 @@ async function status2(projectDir) {
3024
3143
  installed: "yes",
3025
3144
  enabled: "n/a",
3026
3145
  method: "mcp",
3027
- location: path25__default.relative(projectDir, p6)
3146
+ location: path23__default.relative(projectDir, p6)
3028
3147
  };
3029
3148
  }
3030
3149
  async function install3(projectDir) {
3031
- const extDir = path25__default.join(projectDir, ".omp", "extensions");
3032
- const extPath = path25__default.join(extDir, "skaile.ts");
3150
+ const extDir = path23__default.join(projectDir, ".omp", "extensions");
3151
+ const extPath = path23__default.join(extDir, "skaile.ts");
3033
3152
  await fs6.mkdir(extDir, { recursive: true });
3034
3153
  const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
3035
3154
  const plugin = new WorkspacePlugin({ projectDir });
@@ -3044,7 +3163,7 @@ async function install3(projectDir) {
3044
3163
  return { changed: true, method: "generated" };
3045
3164
  }
3046
3165
  async function uninstall3(projectDir) {
3047
- const extPath = path25__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3166
+ const extPath = path23__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3048
3167
  try {
3049
3168
  await fs6.unlink(extPath);
3050
3169
  return { changed: true };
@@ -3053,14 +3172,14 @@ async function uninstall3(projectDir) {
3053
3172
  }
3054
3173
  }
3055
3174
  async function status3(projectDir) {
3056
- const extPath = path25__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3175
+ const extPath = path23__default.join(projectDir, ".omp", "extensions", "skaile.ts");
3057
3176
  if (existsSync(extPath)) {
3058
3177
  return {
3059
3178
  harness: "omp",
3060
3179
  installed: "yes",
3061
3180
  enabled: "n/a",
3062
3181
  method: "extension",
3063
- location: path25__default.relative(projectDir, extPath)
3182
+ location: path23__default.relative(projectDir, extPath)
3064
3183
  };
3065
3184
  }
3066
3185
  return {
@@ -3123,7 +3242,7 @@ async function installCodex(projectDir) {
3123
3242
  console.log(` ${S.dim("\u2192")} Restart Codex CLI to pick up the change.`);
3124
3243
  }
3125
3244
  async function runInstall(opts) {
3126
- const projectDir = path25__default.resolve(opts.projectDir);
3245
+ const projectDir = path23__default.resolve(opts.projectDir);
3127
3246
  const targets = resolveDriver(opts.driver);
3128
3247
  let exitCode = 0;
3129
3248
  if (targets.includes("claude-code")) {
@@ -3157,7 +3276,7 @@ async function uninstallCodex(projectDir) {
3157
3276
  else logInfo(`codex: not installed`);
3158
3277
  }
3159
3278
  async function runUninstall(opts) {
3160
- const projectDir = path25__default.resolve(opts.projectDir);
3279
+ const projectDir = path23__default.resolve(opts.projectDir);
3161
3280
  const targets = resolveDriver(opts.driver);
3162
3281
  let exitCode = 0;
3163
3282
  if (targets.includes("claude-code")) {
@@ -3200,7 +3319,7 @@ async function toggleTarget(t, projectDir, action3) {
3200
3319
  });
3201
3320
  }
3202
3321
  async function runToggle(opts, action3) {
3203
- const projectDir = path25__default.resolve(opts.projectDir);
3322
+ const projectDir = path23__default.resolve(opts.projectDir);
3204
3323
  const requestedAll = opts.driver === "all";
3205
3324
  const targets = resolveDriver(opts.driver);
3206
3325
  const usageError = checkToggleSupported(targets, requestedAll, action3);
@@ -3212,7 +3331,7 @@ async function runToggle(opts, action3) {
3212
3331
  return exitCode;
3213
3332
  }
3214
3333
  async function runStatus2(opts) {
3215
- const projectDir = path25__default.resolve(opts.projectDir);
3334
+ const projectDir = path23__default.resolve(opts.projectDir);
3216
3335
  const targets = resolveDriver(opts.driver);
3217
3336
  const rows = [];
3218
3337
  let exitCode = 0;
@@ -3283,7 +3402,7 @@ async function runHook(event) {
3283
3402
  await plugin.shutdown();
3284
3403
  return;
3285
3404
  }
3286
- const store = new PluginStore(path25__default.join(projectDir, ".skaile", "plugin-state.json"));
3405
+ const store = new PluginStore(path23__default.join(projectDir, ".skaile", "plugin-state.json"));
3287
3406
  await store.load();
3288
3407
  const status4 = store.get("connector:status");
3289
3408
  if (status4 && typeof status4 === "object" && Object.keys(status4).length > 0) {
@@ -3347,6 +3466,98 @@ function exitOnSyncError(err2) {
3347
3466
  logErr(err2 instanceof Error ? err2.message : String(err2));
3348
3467
  process.exit(1);
3349
3468
  }
3469
+ var UNFINISHED_GIT_ENTRIES = {
3470
+ MERGE_HEAD: "a merge in progress",
3471
+ "rebase-merge": "a rebase in progress",
3472
+ "rebase-apply": "a rebase in progress",
3473
+ CHERRY_PICK_HEAD: "a cherry-pick in progress",
3474
+ REVERT_HEAD: "a revert in progress"
3475
+ };
3476
+ function unfinishedGitState(dir) {
3477
+ const unmerged = spawnSync("git", ["ls-files", "-u"], { cwd: dir, encoding: "utf-8" });
3478
+ if (unmerged.status !== 0) return "the git index could not be read";
3479
+ if (unmerged.stdout.trim() !== "") return "unmerged files";
3480
+ for (const [entry, state2] of Object.entries(UNFINISHED_GIT_ENTRIES)) {
3481
+ const p6 = spawnSync("git", ["rev-parse", "--git-path", entry], { cwd: dir, encoding: "utf-8" });
3482
+ if (p6.status !== 0) return "the git directory could not be read";
3483
+ if (fs9.existsSync(path23.resolve(dir, p6.stdout.trim()))) return state2;
3484
+ }
3485
+ return null;
3486
+ }
3487
+ async function reindexLibrary(lib, library, name) {
3488
+ assertManifestEditableOrExit(lib.path);
3489
+ const badRequires = manifestRequiresProblems(lib.path);
3490
+ const resolved = resolveLibraryPublisherDetailed(lib, {}, getStoreIdentity());
3491
+ warnLibraryNameFallback(name, resolved);
3492
+ const { removed, unknownKind, skipped } = await syncManifestWithDisk(
3493
+ lib.path,
3494
+ resolved.publisher,
3495
+ getKindRegistry()
3496
+ );
3497
+ const manifest = loadSkPublishManifest(lib.path);
3498
+ for (const a of unknownKind) {
3499
+ logWarn(
3500
+ `Removed manifest entry ${a.kind}:${a.name}: the kind "${a.kind}" is not registered (removed or renamed in a newer release).`
3501
+ );
3502
+ }
3503
+ for (const a of removed) {
3504
+ const ref = manifest ? assetEntryRef(a, manifest) : `${a.kind}:${a.name}`;
3505
+ logInfo(`Removed manifest entry ${ref} (root ${a.root} is gone)`);
3506
+ }
3507
+ for (const s of skipped.filter((x) => x.reason === "invalid-version")) {
3508
+ logWarn(
3509
+ `${s.kind}:${s.name} skipped: ${s.detail}. Set a valid \`metadata.version\` (e.g. 0.1.0) and re-run \`skaile library index ${name}\`.`
3510
+ );
3511
+ }
3512
+ const duplicates = skipped.filter((x) => x.reason === "duplicate");
3513
+ 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
+ );
3517
+ }
3518
+ const duplicateFiles = new Set(duplicates.map((s) => path23.resolve(lib.path, s.file)));
3519
+ const skippedKeys = new Set(
3520
+ skipped.filter((s) => s.reason !== "duplicate").map((s) => `${s.kind}:${s.name}`)
3521
+ );
3522
+ const res = await indexLibrary(lib, library, {
3523
+ exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`) || duplicateFiles.has(path23.resolve(a.manifestPath))
3524
+ });
3525
+ const unparsable = res.errors.filter((e) => e.includes("ManifestSchemaError:"));
3526
+ for (const e of res.errors) (unparsable.includes(e) ? logErr : logWarn)(e);
3527
+ const syncUnparsable = skipped.filter(
3528
+ (s) => s.reason === "unparsable" && !unparsable.some((e) => e.includes(s.file))
3529
+ );
3530
+ for (const s of syncUnparsable) {
3531
+ logErr(`${s.kind}:${s.name} skipped: manifest file ${s.file} could not be parsed.`);
3532
+ }
3533
+ for (const p6 of badRequires) logErr(`${p6.asset}: ${p6.message}`);
3534
+ logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
3535
+ warnIgnoredDomainFiles(lib.path);
3536
+ warnLegacyBundleFiles(lib.path);
3537
+ const skippedUnparsable = unparsable.length + syncUnparsable.length;
3538
+ if (skippedUnparsable > 0) {
3539
+ logErr(`${skippedUnparsable} asset(s) skipped: manifest could not be parsed.`);
3540
+ process.exitCode = 1;
3541
+ }
3542
+ if (badRequires.length > 0) {
3543
+ logErr(
3544
+ `${badRequires.length} invalid requires entr${badRequires.length === 1 ? "y" : "ies"} ignored: use the \`kind:@<publisher>/name[#version]\` form.`
3545
+ );
3546
+ process.exitCode = 1;
3547
+ }
3548
+ if (duplicates.length > 0) {
3549
+ logErr(
3550
+ `${duplicates.length} asset(s) skipped: kind + name already registered in another directory.`
3551
+ );
3552
+ process.exitCode = 1;
3553
+ }
3554
+ }
3555
+ async function indexPulledLibrary(lib, library, name) {
3556
+ const res = await indexLibrary(lib, library);
3557
+ for (const e of res.errors) logWarn(e);
3558
+ logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
3559
+ warnIgnoredDomainFiles(lib.path);
3560
+ }
3350
3561
  function assertManifestEditableOrExit(libraryPath) {
3351
3562
  try {
3352
3563
  assertManifestEditable(libraryPath);
@@ -3356,19 +3567,27 @@ function assertManifestEditableOrExit(libraryPath) {
3356
3567
  }
3357
3568
  async function assertLibraryPathFree(manager, dir, exceptId) {
3358
3569
  const clash = (await manager.listLibraries()).find(
3359
- (l) => l.id !== exceptId && path25.resolve(l.path) === dir
3570
+ (l) => l.id !== exceptId && path23.resolve(l.path) === dir
3360
3571
  );
3361
3572
  if (clash) throw new Error(`${dir} is already registered as library "${clash.name}".`);
3362
3573
  }
3363
3574
  function canonicalDir(dir) {
3364
- const abs = path25.resolve(dir);
3365
- return fs11.existsSync(abs) ? fs11.realpathSync(abs) : abs;
3575
+ const abs = path23.resolve(dir);
3576
+ const missing = [];
3577
+ let existing = abs;
3578
+ while (!fs9.existsSync(existing)) {
3579
+ const parent = path23.dirname(existing);
3580
+ if (parent === existing) return abs;
3581
+ missing.unshift(path23.basename(existing));
3582
+ existing = parent;
3583
+ }
3584
+ return path23.join(fs9.realpathSync(existing), ...missing);
3366
3585
  }
3367
3586
  function refuseGlobalInstallFolder(name, dir) {
3368
3587
  const reserved = globalInstallDir();
3369
- const rel = path25.relative(canonicalDir(reserved), canonicalDir(dir));
3370
- const inside = rel === "" || !rel.startsWith("..") && !path25.isAbsolute(rel);
3371
- if (name === GLOBAL_INSTALL_DIR_NAME || inside) {
3588
+ const rel = path23.relative(canonicalDir(reserved).toLowerCase(), canonicalDir(dir).toLowerCase());
3589
+ const inside = rel === "" || !rel.startsWith("..") && !path23.isAbsolute(rel);
3590
+ if (name?.toLowerCase() === GLOBAL_INSTALL_DIR_NAME || inside) {
3372
3591
  logErr(
3373
3592
  `"${GLOBAL_INSTALL_DIR_NAME}" is reserved: ${reserved} holds assets from \`skaile install\`, not a library you author.`
3374
3593
  );
@@ -3388,10 +3607,35 @@ function readOriginTracking(dir) {
3388
3607
  }
3389
3608
  function requireGitBackend(lib, verb) {
3390
3609
  if (lib.backend !== "git") {
3391
- logErr(`\`library ${verb}\` only applies to git-backed libraries.`);
3610
+ logErr(
3611
+ `\`library ${verb}\` only applies to git-backed libraries. Run \`skaile library link ${lib.name} <url>\` to attach a remote first.`
3612
+ );
3392
3613
  process.exit(1);
3393
3614
  }
3394
3615
  }
3616
+ function requireValidLibraryName(name) {
3617
+ try {
3618
+ assertValidLibraryName(name);
3619
+ } catch (err2) {
3620
+ exitOnSyncError(err2);
3621
+ }
3622
+ }
3623
+ var LOCAL_OWNERSHIP_REASON = "ownership only governs sync with a git remote, and a local library is always owned by you.";
3624
+ function pruneEmptyLibraryParents(libPath) {
3625
+ const root = canonicalDir(resolveLibraryDir());
3626
+ let dir = path23.dirname(path23.resolve(libPath));
3627
+ 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);
3633
+ }
3634
+ }
3635
+ async function warnIfNotGithubRemote(name, url) {
3636
+ const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-PICMDSB2.js');
3637
+ if (!isGithubRemote(url)) logWarn(notGithubRemoteMessage(name, url));
3638
+ }
3395
3639
  function scaffoldLibraryFiles(dir, name) {
3396
3640
  const readme = `# ${name}
3397
3641
 
@@ -3421,9 +3665,9 @@ by the same ref.
3421
3665
  ];
3422
3666
  const written = [];
3423
3667
  for (const [file, content] of files) {
3424
- const target = path25.join(dir, file);
3425
- if (fs11.existsSync(target)) continue;
3426
- fs11.writeFileSync(target, content, "utf8");
3668
+ const target = path23.join(dir, file);
3669
+ if (fs9.existsSync(target)) continue;
3670
+ fs9.writeFileSync(target, content, "utf8");
3427
3671
  written.push(file);
3428
3672
  }
3429
3673
  return written;
@@ -3486,22 +3730,23 @@ function makeLibraryCommand() {
3486
3730
  });
3487
3731
  cmd.command("init <name>").description("Create (or adopt) a library \u2014 default location ~/.skaile/libraries/<name>").option("--git <url>", "Initialize as a git library tracking <url>").option("--path <dir>", "Register the library at <dir> (created if missing) instead").option("--owner", "Mark as owner (the default)").option("--contributor", "Mark as contributor (needs --git or an existing git clone)").option("--reader", "Mark as reader (needs --git or an existing git clone)").action(
3488
3732
  async (name, opts) => {
3733
+ requireValidLibraryName(name);
3489
3734
  const flagged = ["owner", "contributor", "reader"].filter((o) => opts[o]);
3490
3735
  if (flagged.length > 1) {
3491
3736
  logErr("Pick one of --owner, --contributor, --reader.");
3492
3737
  process.exit(1);
3493
3738
  }
3494
3739
  const ownership = flagged[0] ?? "owner";
3495
- const libPath = opts.path ? path25.resolve(opts.path) : path25.join(resolveLibraryDir(), name);
3740
+ const libPath = opts.path ? path23.resolve(opts.path) : path23.join(resolveLibraryDir(), name);
3496
3741
  refuseGlobalInstallFolder(name, libPath);
3497
- if (fs11.existsSync(libPath) && !fs11.statSync(libPath).isDirectory()) {
3742
+ if (fs9.existsSync(libPath) && !fs9.statSync(libPath).isDirectory()) {
3498
3743
  logErr(`${libPath} exists and is not a directory.`);
3499
3744
  process.exit(1);
3500
3745
  }
3501
3746
  const adopted = opts.git ? null : readOriginTracking(libPath);
3502
3747
  if (ownership !== "owner" && !opts.git && !adopted) {
3503
3748
  logErr(
3504
- `--${ownership} needs --git <url> or an existing git clone: ownership only governs sync with a git remote, and a local library is always owned by you.`
3749
+ `--${ownership} needs --git <url> or an existing git clone: ${LOCAL_OWNERSHIP_REASON}`
3505
3750
  );
3506
3751
  process.exit(1);
3507
3752
  }
@@ -3522,15 +3767,17 @@ function makeLibraryCommand() {
3522
3767
  `Could not clone ${opts.git}; initialised an empty repo with that origin instead. git said: ${reason}`
3523
3768
  );
3524
3769
  }
3770
+ await warnIfNotGithubRemote(name, opts.git);
3771
+ trackOriginBranch(libPath, branch);
3525
3772
  backend = "git";
3526
3773
  backendConfig = { url: opts.git, branch, authHint: "ssh" };
3527
3774
  } else if (adopted) {
3528
3775
  backend = "git";
3529
3776
  backendConfig = { url: adopted.url, branch: adopted.branch, authHint: "ssh" };
3530
3777
  } else {
3531
- fs11.mkdirSync(libPath, { recursive: true });
3778
+ fs9.mkdirSync(libPath, { recursive: true });
3532
3779
  }
3533
- const blank = fs11.readdirSync(libPath).every((entry) => entry === ".git");
3780
+ const blank = fs9.readdirSync(libPath).every((entry) => entry === ".git");
3534
3781
  const isDefault = !hasDefault && ownership !== "reader";
3535
3782
  await manager.addLibrary({
3536
3783
  name,
@@ -3557,6 +3804,16 @@ function makeLibraryCommand() {
3557
3804
  }
3558
3805
  if (!blank) {
3559
3806
  const lib = await manager.requireLibrary(name);
3807
+ const resolved = resolveLibraryPublisherDetailed(lib, {}, getStoreIdentity());
3808
+ if (resolved.source === "manifest" && !isValidPublisher(resolved.publisher)) {
3809
+ logWarn(
3810
+ `${SKAILE_MANIFEST_FILENAME} declares publisher "${resolved.publisher}": ${PUBLISHER_HINT}. Fix it with \`skaile library set ${name} publisher=<name>\`.`
3811
+ );
3812
+ }
3813
+ warnLibraryNameFallback(name, resolved);
3814
+ if (resolved.source !== "manifest") {
3815
+ stampManifestPublisher(lib.path, resolved.publisher);
3816
+ }
3560
3817
  const res = await indexLibrary(lib, library);
3561
3818
  for (const e of res.errors) logWarn(e);
3562
3819
  logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
@@ -3580,29 +3837,42 @@ function makeLibraryCommand() {
3580
3837
  process.exit(1);
3581
3838
  }
3582
3839
  ensureGitRepo(lib.path, url, opts.branch);
3840
+ trackOriginBranch(lib.path, opts.branch, { fetch: true });
3583
3841
  await manager.updateLibrary(name, {
3584
3842
  backend: "git",
3585
3843
  backendConfig: { url, branch: opts.branch, authHint: "ssh" }
3586
3844
  });
3587
3845
  logOk(`Library "${name}" linked to ${url}.`);
3846
+ await warnIfNotGithubRemote(name, url);
3588
3847
  } catch (err2) {
3589
3848
  exitOnSyncError(err2);
3590
3849
  } finally {
3591
3850
  close();
3592
3851
  }
3593
3852
  });
3594
- cmd.command("create <kind> <name>").description("Scaffold a new asset inside the default (or named) library").addOption(
3595
- new Option("--kind <kind>", "Asset kind override").choices(getKindRegistry().getAllKinds())
3596
- ).option("--library <name>", "Target library (default: the default-marked one)").option("--dir <dir>", "Target directory inside the library (default: library root)").option("--publisher <name>", "Publisher for the new asset (default: the library's default)").option(
3853
+ cmd.command("create <kind> <name>").description("Scaffold a new asset inside the default (or named) library").addOption(new Option("--kind <kind>", "Asset kind override").choices([...SCAFFOLD_KINDS])).addOption(removedDomainOption()).option("--library <name>", "Target library (default: the default-marked one)").option("--dir <dir>", "Target directory inside the library (default: library root)").option("--publisher <name>", "Publisher for the new asset (default: the library's default)").option(
3597
3854
  "--description <text>",
3598
3855
  "Description for the asset's frontmatter \u2014 say what it does and when to use it (default: a TODO placeholder `skaile validate` rejects)"
3599
3856
  ).action(
3600
3857
  async (kind, name, opts) => {
3601
- const registeredKinds = getKindRegistry().getAllKinds();
3602
- if (!registeredKinds.includes(kind)) {
3603
- logErr(`Unknown asset kind "${kind}". Expected: ${registeredKinds.join(", ")}.`);
3858
+ rejectRemovedDomainOption(opts);
3859
+ for (const k of [kind, opts.kind]) {
3860
+ if (k !== void 0 && !SCAFFOLD_KINDS.includes(k)) {
3861
+ logErr(`Cannot scaffold kind "${k}". Expected: ${SCAFFOLD_KINDS.join(", ")}.`);
3862
+ process.exit(1);
3863
+ }
3864
+ }
3865
+ if (!isValidAssetName(name)) {
3866
+ logErr(`Invalid asset name "${name}": ${ASSET_NAME_HINT}.`);
3604
3867
  process.exit(1);
3605
3868
  }
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
+ }
3606
3876
  if (opts.description !== void 0) {
3607
3877
  const len = opts.description.trim().length;
3608
3878
  if (len === 0 || len > 1024) {
@@ -3616,7 +3886,25 @@ function makeLibraryCommand() {
3616
3886
  assertManifestEditableOrExit(target.path);
3617
3887
  const effectiveKind = opts.kind ?? kind;
3618
3888
  const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
3619
- const destDir = opts.dir ? path25.join(target.path, opts.dir) : target.path;
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)) {
3893
+ logErr(`--dir "${opts.dir}" must stay inside the library (${libRoot}).`);
3894
+ process.exit(1);
3895
+ }
3896
+ const taken = conflictingAssetRoot(
3897
+ libRoot,
3898
+ effectiveKind,
3899
+ name,
3900
+ path23.relative(libRoot, path23.join(destDir, name))
3901
+ );
3902
+ if (taken) {
3903
+ 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.`
3905
+ );
3906
+ process.exit(1);
3907
+ }
3620
3908
  const res = am2.create(name, effectiveKind, destDir, { description: opts.description });
3621
3909
  if (!res.ok) {
3622
3910
  logErr(res.path);
@@ -3661,38 +3949,48 @@ function makeLibraryCommand() {
3661
3949
  close();
3662
3950
  }
3663
3951
  });
3952
+ async function renameLibrary(manager, lib, newName) {
3953
+ requireValidLibraryName(newName);
3954
+ if (await manager.getLibrary(newName)) {
3955
+ logErr(`A library named "${newName}" is already registered.`);
3956
+ process.exit(1);
3957
+ }
3958
+ const newPath = path23.join(path23.dirname(lib.path), newName);
3959
+ refuseGlobalInstallFolder(newName, newPath);
3960
+ if (fs9.existsSync(newPath)) {
3961
+ logErr(`Target directory already exists: ${newPath}`);
3962
+ process.exit(1);
3963
+ }
3964
+ fs9.renameSync(lib.path, newPath);
3965
+ await manager.updateLibrary(lib.id, { name: newName, path: newPath });
3966
+ logOk(`Renamed ${lib.name} \u2192 ${newName}`);
3967
+ }
3664
3968
  cmd.command("rename <old> <new>").description("Rename a library (also moves the directory)").action(async (oldName, newName) => {
3665
3969
  const { manager, close } = await openLibraryManager();
3666
3970
  try {
3667
- const lib = await manager.requireLibrary(oldName);
3668
- const parent = path25.dirname(lib.path);
3669
- const newPath = path25.join(parent, newName);
3670
- refuseGlobalInstallFolder(newName, newPath);
3671
- if (fs11.existsSync(newPath)) {
3672
- logErr(`Target directory already exists: ${newPath}`);
3673
- process.exit(1);
3674
- }
3675
- fs11.renameSync(lib.path, newPath);
3676
- await manager.updateLibrary(lib.id, { name: newName, path: newPath });
3677
- logOk(`Renamed ${oldName} \u2192 ${newName}`);
3971
+ await renameLibrary(manager, await manager.requireLibrary(oldName), newName);
3972
+ } catch (err2) {
3973
+ exitOnSyncError(err2);
3678
3974
  } finally {
3679
3975
  close();
3680
3976
  }
3681
3977
  });
3682
3978
  cmd.command("set <name> <field=value>").description(
3683
- "Update a single library field (ownership, isDefault, path, publisher, backendConfig.<key>)"
3979
+ "Update a single library field (name, ownership, isDefault, path, publisher, backendConfig.<key>)"
3684
3980
  ).action(async (name, expr) => {
3685
3981
  const [field, ...rest] = expr.split("=");
3982
+ if (field === "structure") {
3983
+ logErr(DOMAIN_REMOVED_HINT);
3984
+ process.exit(1);
3985
+ }
3686
3986
  const value = rest.join("=");
3687
3987
  const { manager, library, close } = await openLibraryManager();
3688
3988
  try {
3689
3989
  const lib = await manager.requireLibrary(name);
3690
3990
  if (field === "publisher") {
3691
3991
  const publisher = value.trim().replace(/^@/, "");
3692
- if (!/^[^\s/#@]+$/.test(publisher)) {
3693
- logErr(
3694
- `Invalid publisher "${value}": expected a bare name like "acme" (no @, /, # or spaces).`
3695
- );
3992
+ if (!isValidPublisher(publisher)) {
3993
+ logErr(`Invalid publisher "${value}": ${PUBLISHER_HINT}.`);
3696
3994
  process.exit(1);
3697
3995
  }
3698
3996
  if (lib.ownership === "reader") {
@@ -3709,11 +4007,42 @@ function makeLibraryCommand() {
3709
4007
  return;
3710
4008
  }
3711
4009
  const patch = {};
3712
- if (field === "ownership") patch.ownership = value;
3713
- else if (field === "isDefault") patch.isDefault = value === "true";
3714
- else if (field === "path") {
3715
- const dir = path25.resolve(value);
3716
- if (!fs11.existsSync(dir) || !fs11.statSync(dir).isDirectory()) {
4010
+ if (field === "name") {
4011
+ await renameLibrary(manager, lib, value);
4012
+ return;
4013
+ }
4014
+ if (field === "ownership") {
4015
+ if (!LIBRARY_OWNERSHIPS.includes(value)) {
4016
+ logErr(
4017
+ `Invalid ownership "${value}": expected one of ${LIBRARY_OWNERSHIPS.join(", ")}.`
4018
+ );
4019
+ process.exit(1);
4020
+ }
4021
+ if (value !== "owner" && lib.backend !== "git") {
4022
+ logErr(`ownership=${value} needs a git-backed library: ${LOCAL_OWNERSHIP_REASON}`);
4023
+ process.exit(1);
4024
+ }
4025
+ patch.ownership = value;
4026
+ } else if (field === "isDefault") {
4027
+ if (value !== "true" && value !== "false") {
4028
+ logErr(`Invalid isDefault "${value}": expected true or false.`);
4029
+ process.exit(1);
4030
+ }
4031
+ if (value === "true") {
4032
+ await manager.setDefault(lib.id);
4033
+ logOk(`Updated ${name}.isDefault`);
4034
+ return;
4035
+ }
4036
+ if (lib.isDefault) {
4037
+ logErr(
4038
+ `Library "${lib.name}" is the default; make another library the default with \`skaile library default <name>\` instead of unsetting it.`
4039
+ );
4040
+ process.exit(1);
4041
+ }
4042
+ patch.isDefault = false;
4043
+ } else if (field === "path") {
4044
+ const dir = path23.resolve(value);
4045
+ if (!fs9.existsSync(dir) || !fs9.statSync(dir).isDirectory()) {
3717
4046
  logErr(`Directory does not exist: ${dir}. \`library set path=\` does not move files.`);
3718
4047
  process.exit(1);
3719
4048
  }
@@ -3722,6 +4051,10 @@ function makeLibraryCommand() {
3722
4051
  patch.path = dir;
3723
4052
  } else if (field.startsWith("backendConfig.")) {
3724
4053
  const key = field.split(".")[1];
4054
+ if (key === "url" && lib.backend !== "git") {
4055
+ logErr("backendConfig.url only applies to git-backed libraries.");
4056
+ process.exit(1);
4057
+ }
3725
4058
  if (key === "url" && lib.backend === "git") {
3726
4059
  const branch = lib.backendConfig.branch ?? "main";
3727
4060
  ensureGitRepo(lib.path, value, branch);
@@ -3743,6 +4076,10 @@ function makeLibraryCommand() {
3743
4076
  }
3744
4077
  });
3745
4078
  cmd.command("remove <name>").description("Unregister a library (use --purge to also delete files)").option("--purge", "Also delete the library directory from disk", false).option("-y, --yes", "Skip confirmation", false).action(async (name, opts) => {
4079
+ if (!opts.yes && !process.stdin.isTTY) {
4080
+ logErr("library remove needs confirmation: pass -y");
4081
+ process.exit(1);
4082
+ }
3746
4083
  const { manager, close } = await openLibraryManager();
3747
4084
  try {
3748
4085
  if (!opts.yes) {
@@ -3755,25 +4092,31 @@ function makeLibraryCommand() {
3755
4092
  return;
3756
4093
  }
3757
4094
  }
4095
+ const lib = await manager.requireLibrary(name);
3758
4096
  await manager.removeLibrary(name, { purge: opts.purge });
4097
+ if (opts.purge) pruneEmptyLibraryParents(lib.path);
3759
4098
  logOk(`Removed ${name}.`);
4099
+ } catch (err2) {
4100
+ exitOnSyncError(err2);
3760
4101
  } finally {
3761
4102
  close();
3762
4103
  }
3763
4104
  });
3764
4105
  cmd.command("sync <name>").description("Pull then push (as backend permits)").action(async (name) => {
3765
- const { manager, close } = await openLibraryManager();
4106
+ const { manager, library, close } = await openLibraryManager();
3766
4107
  try {
3767
4108
  const lib = await manager.requireLibrary(name);
3768
4109
  requireGitBackend(lib, "sync");
3769
4110
  const drv = manager.driverFor(lib.backend);
3770
4111
  const pull = await drv.pull(lib);
4112
+ if (pull.conflicts.length > 0) exitOnSyncError(new Error(pull.conflicts[0].reason));
3771
4113
  logInfo(`Pulled: applied=${pull.applied}, conflicts=${pull.conflicts.length}`);
3772
4114
  if (lib.ownership === "owner") {
3773
4115
  const push = await drv.push(lib);
3774
4116
  logInfo(`Pushed: ${push.pushed}`);
3775
4117
  }
3776
4118
  await manager.updateLibrary(name, { lastSyncAt: /* @__PURE__ */ new Date() });
4119
+ if (pull.applied > 0) await indexPulledLibrary(lib, library, name);
3777
4120
  logOk(`Synced ${name}.`);
3778
4121
  } catch (err2) {
3779
4122
  exitOnSyncError(err2);
@@ -3785,40 +4128,22 @@ function makeLibraryCommand() {
3785
4128
  const { manager, library, close } = await openLibraryManager();
3786
4129
  try {
3787
4130
  const lib = await manager.requireLibrary(name);
3788
- assertManifestEditableOrExit(lib.path);
3789
- const removed = await syncManifestWithDisk(
3790
- lib.path,
3791
- resolveLibraryPublisher(lib, {}, getStoreIdentity()),
3792
- getKindRegistry()
3793
- );
3794
- const manifest = loadSkPublishManifest(lib.path);
3795
- for (const a of removed) {
3796
- const ref = manifest ? assetEntryRef(a, manifest) : `${a.kind}:${a.name}`;
3797
- logInfo(`Removed manifest entry ${ref} (root ${a.root} is gone)`);
3798
- }
3799
- const res = await indexLibrary(lib, library);
3800
- const unparsable = res.errors.filter((e) => e.includes("ManifestSchemaError:"));
3801
- for (const e of res.errors) (unparsable.includes(e) ? logErr : logWarn)(e);
3802
- logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
3803
- warnIgnoredDomainFiles(lib.path);
3804
- if (unparsable.length > 0) {
3805
- logErr(`${unparsable.length} asset(s) skipped: manifest could not be parsed.`);
3806
- process.exitCode = 1;
3807
- }
4131
+ await reindexLibrary(lib, library, name);
3808
4132
  } finally {
3809
4133
  close();
3810
4134
  }
3811
4135
  });
3812
4136
  cmd.command("pull <name>").description("Pull from remote").action(async (name) => {
3813
- const { manager, close } = await openLibraryManager();
4137
+ const { manager, library, close } = await openLibraryManager();
3814
4138
  try {
3815
4139
  const lib = await manager.requireLibrary(name);
3816
4140
  requireGitBackend(lib, "pull");
3817
4141
  const res = await manager.driverFor(lib.backend).pull(lib);
3818
4142
  if (res.conflicts.length > 0) {
3819
- logWarn(`Conflicts: ${res.conflicts.map((c) => c.path).join(", ")}`);
4143
+ exitOnSyncError(new Error(res.conflicts[0].reason));
3820
4144
  } else {
3821
4145
  logOk(`Pulled ${res.applied} change(s).`);
4146
+ if (res.applied > 0) await indexPulledLibrary(lib, library, name);
3822
4147
  }
3823
4148
  } catch (err2) {
3824
4149
  exitOnSyncError(err2);
@@ -3862,6 +4187,13 @@ function makeLibraryCommand() {
3862
4187
  );
3863
4188
  process.exit(1);
3864
4189
  }
4190
+ const unfinished = unfinishedGitState(lib.path);
4191
+ if (unfinished) {
4192
+ logErr(
4193
+ `library commit refused: ${unfinished} in ${lib.path}. Resolve the conflicts (\`skaile library git ${name} status\`), finish or abort the rebase/merge, then commit again.`
4194
+ );
4195
+ process.exit(1);
4196
+ }
3865
4197
  const add = spawnSync("git", ["add", "-A"], { cwd: lib.path, stdio: "inherit" });
3866
4198
  if (add.status !== 0) {
3867
4199
  logErr(`git add failed in ${lib.path}.`);
@@ -3916,16 +4248,16 @@ function makeLibraryCommand() {
3916
4248
  "With --create-repo: create the repo private (the store only accepts public repos)"
3917
4249
  ).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(
3918
4250
  async (lib, opts) => {
3919
- const { runLibraryPublish } = await import('../library-publish-LFOJJVMK.js');
4251
+ const { runLibraryPublish } = await import('../library-publish-PICMDSB2.js');
3920
4252
  await withStoreErrorHandling(() => runLibraryPublish(lib, opts));
3921
4253
  }
3922
4254
  );
3923
4255
  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) => {
3924
- const { runLibraryRegister } = await import('../library-publish-LFOJJVMK.js');
4256
+ const { runLibraryRegister } = await import('../library-publish-PICMDSB2.js');
3925
4257
  await withStoreErrorHandling(() => runLibraryRegister(lib, opts));
3926
4258
  });
3927
4259
  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) => {
3928
- const { runLibraryYank } = await import('../library-publish-LFOJJVMK.js');
4260
+ const { runLibraryYank } = await import('../library-publish-PICMDSB2.js');
3929
4261
  await withStoreErrorHandling(() => runLibraryYank(lib, opts));
3930
4262
  });
3931
4263
  return cmd;
@@ -3976,9 +4308,9 @@ async function printOverallStatus(projectDir, asJson) {
3976
4308
  } catch {
3977
4309
  secretsStrategy = "unavailable";
3978
4310
  }
3979
- const resolvedProjectDir = path25.resolve(projectDir);
3980
- const hasWorkspaceConfig = existsSync(path25.join(resolvedProjectDir, "skaile.yaml"));
3981
- const hasLockFile = existsSync(path25.join(resolvedProjectDir, "skaile.lock.yaml"));
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"));
3982
4314
  let assignments = [];
3983
4315
  if (hasWorkspaceConfig) {
3984
4316
  try {
@@ -4585,13 +4917,18 @@ function scheduleSoftDepPreview() {
4585
4917
  }
4586
4918
  async function loadAssets() {
4587
4919
  softDepPreviewCache.clear();
4588
- const { gatherAssetFeeds } = await import('../asset-feeds-LU7NHOAP.js');
4920
+ const { gatherAssetFeeds } = await import('../asset-feeds-EYRZR4K5.js');
4589
4921
  const { entries, notes } = await gatherAssetFeeds(am, am.projectDir);
4590
4922
  if (notes.length > 0) {
4591
4923
  state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
4592
4924
  }
4593
4925
  const installed = new Set(am.listDeployed().map((e) => `${e.kind}:${e.name}`));
4594
- const rows = buildAssetRows(entries, installed);
4926
+ let lock = null;
4927
+ try {
4928
+ lock = readLock(path23__default.join(am.projectDir, "skaile.lock.yaml"));
4929
+ } catch {
4930
+ }
4931
+ const rows = buildAssetRows(entries, installed, lockedLibraryByIdentity(lock));
4595
4932
  state.assetRows = rows;
4596
4933
  reconcileCollapsedSets(rows);
4597
4934
  rebuildVisible();
@@ -4605,7 +4942,7 @@ function rebuildSourceTree() {
4605
4942
  rebuildVisibleSources();
4606
4943
  }
4607
4944
  function sourceOrgRepo(s) {
4608
- const parts = s.path.split(path25__default.sep).filter(Boolean);
4945
+ const parts = s.path.split(path23__default.sep).filter(Boolean);
4609
4946
  if (parts.length < 2) return null;
4610
4947
  return { org: parts[parts.length - 2], repo: parts[parts.length - 1] };
4611
4948
  }
@@ -4678,7 +5015,22 @@ function rebuildVisibleLibraries() {
4678
5015
  );
4679
5016
  clampCursor();
4680
5017
  }
4681
- function buildAssetRows(entries, installed) {
5018
+ function lockedLibraryByIdentity(lock) {
5019
+ const out = /* @__PURE__ */ new Map();
5020
+ for (const [key, locked] of Object.entries(lock?.assets ?? {})) {
5021
+ if (!locked.library) continue;
5022
+ const ref = parseAssetRefLoose(key);
5023
+ if (ref?.publisher) out.set(`${ref.kind}:${ref.publisher}/${ref.name}`, locked.library.name);
5024
+ }
5025
+ return out;
5026
+ }
5027
+ function isRowInstalled(origin, group, entry, installed, lockedLibrary) {
5028
+ if (!installed.has(`${entry.kind}:${entry.name}`)) return false;
5029
+ const publisher = entry.publisher?.replace(/^@/, "");
5030
+ const locked = publisher ? lockedLibrary.get(`${entry.kind}:${publisher}/${entry.name}`) : void 0;
5031
+ return locked === void 0 || origin === "library" && group === locked;
5032
+ }
5033
+ function buildAssetRows(entries, installed, lockedLibrary = /* @__PURE__ */ new Map()) {
4682
5034
  const byOrigin = /* @__PURE__ */ new Map();
4683
5035
  for (const { origin, entry, group } of entries) {
4684
5036
  const publisher = group || entry.publisher || "other";
@@ -4706,7 +5058,7 @@ function buildAssetRows(entries, installed) {
4706
5058
  source: group,
4707
5059
  org: entry.repo?.includes("/") ? entry.repo.slice(0, entry.repo.indexOf("/")) : void 0,
4708
5060
  entry,
4709
- installed: installed.has(`${entry.kind}:${entry.name}`),
5061
+ installed: isRowInstalled(origin, group, entry, installed, lockedLibrary),
4710
5062
  plugin
4711
5063
  });
4712
5064
  }
@@ -4752,13 +5104,13 @@ function reconcileCollapsedSets(rows) {
4752
5104
  async function loadSourcesAndLibraries() {
4753
5105
  try {
4754
5106
  const [{ openLibraryManager: openLibraryManager2 }, { getGlobalCacheDir: getGlobalCacheDir2, globalSkaileDir: globalSkaileDir2 }] = await Promise.all([
4755
- import('../open-library-4WUMQHES.js'),
5107
+ import('../open-library-OG457THY.js'),
4756
5108
  import('../core/index.js')
4757
5109
  ]);
4758
5110
  const { manager, library, close } = await openLibraryManager2();
4759
5111
  try {
4760
5112
  const newRoot = getGlobalCacheDir2();
4761
- const legacyRoot = path25__default.join(globalSkaileDir2(), "sources");
5113
+ const legacyRoot = path23__default.join(globalSkaileDir2(), "sources");
4762
5114
  const isSourceRow = (l) => l.path.startsWith(newRoot) || l.path.startsWith(legacyRoot);
4763
5115
  const libs = await manager.listLibraries();
4764
5116
  const defs = await library.listAssetDefs();
@@ -5125,12 +5477,21 @@ async function applyChanges() {
5125
5477
  render();
5126
5478
  let added = 0;
5127
5479
  let removed = 0;
5480
+ let pruned = 0;
5128
5481
  const appliedAdds = [];
5129
5482
  const appliedRemoves = [];
5130
5483
  for (const ref of state.pendingRemoves) {
5131
- if (am.remove(ref)) {
5132
- removed++;
5133
- appliedRemoves.push(ref);
5484
+ try {
5485
+ const result = await am.removeWithDependencies(ref);
5486
+ if (result.changed) {
5487
+ removed++;
5488
+ pruned += result.pruned.length;
5489
+ appliedRemoves.push(ref);
5490
+ }
5491
+ } catch (err2) {
5492
+ state.message = pc5.red(
5493
+ `Failed to remove ${ref}: ${err2 instanceof Error ? err2.message : err2}`
5494
+ );
5134
5495
  }
5135
5496
  }
5136
5497
  for (const ref of state.pendingAdds) {
@@ -5148,6 +5509,7 @@ async function applyChanges() {
5148
5509
  const parts = [];
5149
5510
  if (added > 0) parts.push(pc5.green(`+${added} added`));
5150
5511
  if (removed > 0) parts.push(pc5.red(`-${removed} removed`));
5512
+ if (pruned > 0) parts.push(pc5.red(`-${pruned} no longer required`));
5151
5513
  const softDeps = appliedAdds.length > 0 ? await am.reportSoftDeps(appliedAdds) : [];
5152
5514
  if (softDeps.length > 0) {
5153
5515
  parts.push(pc5.dim(`${softDeps.length} soft dep${softDeps.length === 1 ? "" : "s"} referenced`));
@@ -5187,7 +5549,10 @@ async function showInfo() {
5187
5549
  console.log(` installed: ${row.installed ? pc5.green("yes") : pc5.red("no")}`);
5188
5550
  if (e.requires.length) {
5189
5551
  console.log(` requires:`);
5190
- for (const d of e.requires) console.log(` ${kindColor(d.kind)}:${d.name}`);
5552
+ for (const d of e.requires) {
5553
+ const scope = d.publisher ? `@${d.publisher}/` : "";
5554
+ console.log(` ${kindColor(d.kind)}:${scope}${d.name}`);
5555
+ }
5191
5556
  }
5192
5557
  if (e.dependencies.length) {
5193
5558
  console.log(` dependencies:`);
@@ -5694,7 +6059,7 @@ async function run(projectDir) {
5694
6059
  }
5695
6060
  function makeManageCommand() {
5696
6061
  return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
5697
- await run(path25__default.resolve(opts.projectDir));
6062
+ await run(path23__default.resolve(opts.projectDir));
5698
6063
  });
5699
6064
  }
5700
6065
  function makeMcpServerCommand() {
@@ -5747,10 +6112,10 @@ function walkFiles(root, match) {
5747
6112
  return;
5748
6113
  }
5749
6114
  for (const entry of entries) {
5750
- const full = path25__default.join(dir, entry.name);
6115
+ const full = path23__default.join(dir, entry.name);
5751
6116
  if (entry.isDirectory()) {
5752
6117
  if (SKIPPED_DIRS.has(entry.name)) continue;
5753
- if (entry.name === "cache" && path25__default.basename(dir) === ".skaile") continue;
6118
+ if (entry.name === "cache" && path23__default.basename(dir) === ".skaile") continue;
5754
6119
  visit(full);
5755
6120
  } else if (entry.isFile() && match(entry.name)) {
5756
6121
  out.push(full);
@@ -5768,14 +6133,14 @@ function applyChanges2(changes) {
5768
6133
  switch (change.type) {
5769
6134
  case "write":
5770
6135
  case "create":
5771
- mkdirSync(path25__default.dirname(change.path), { recursive: true });
6136
+ mkdirSync(path23__default.dirname(change.path), { recursive: true });
5772
6137
  writeFileSync(change.path, change.after, "utf-8");
5773
6138
  break;
5774
6139
  case "delete":
5775
6140
  rmSync(change.path, { force: true });
5776
6141
  break;
5777
6142
  case "move":
5778
- mkdirSync(path25__default.dirname(change.to), { recursive: true });
6143
+ mkdirSync(path23__default.dirname(change.to), { recursive: true });
5779
6144
  writeFileSync(change.to, change.after, "utf-8");
5780
6145
  rmSync(change.from, { force: true });
5781
6146
  break;
@@ -5868,7 +6233,7 @@ function unifiedDiff(before, after, oldLabel, newLabel, context = 3) {
5868
6233
  return `${out.join("\n")}
5869
6234
  `;
5870
6235
  }
5871
- var posix = (p6) => p6.split(path25__default.sep).join("/");
6236
+ var posix = (p6) => p6.split(path23__default.sep).join("/");
5872
6237
  function colorizeDiff(diff) {
5873
6238
  return diff.split("\n").map((line) => {
5874
6239
  if (line.startsWith("+++") || line.startsWith("---")) return S.bold(line);
@@ -5879,7 +6244,7 @@ function colorizeDiff(diff) {
5879
6244
  }).join("\n");
5880
6245
  }
5881
6246
  function renderChange(change, base) {
5882
- const rel = (p6) => posix(path25__default.relative(base, p6) || path25__default.basename(p6));
6247
+ const rel = (p6) => posix(path23__default.relative(base, p6) || path23__default.basename(p6));
5883
6248
  switch (change.type) {
5884
6249
  case "write":
5885
6250
  return unifiedDiff(
@@ -5906,7 +6271,7 @@ ${diff}`;
5906
6271
  }
5907
6272
  }
5908
6273
  function changeLabel(change, base) {
5909
- const rel = (p6) => posix(path25__default.relative(base, p6) || path25__default.basename(p6));
6274
+ const rel = (p6) => posix(path23__default.relative(base, p6) || path23__default.basename(p6));
5910
6275
  switch (change.type) {
5911
6276
  case "write":
5912
6277
  return `modify ${rel(change.path)}`;
@@ -5966,10 +6331,10 @@ function loadAsset(projectDir, id, ref) {
5966
6331
  )
5967
6332
  };
5968
6333
  }
5969
- const manifestPath = path25__default.join(dir, AGENT_MANIFEST_FILE);
6334
+ const manifestPath = path23__default.join(dir, AGENT_MANIFEST_FILE);
5970
6335
  let text;
5971
6336
  try {
5972
- text = fs11__default.readFileSync(manifestPath, "utf-8");
6337
+ text = fs9__default.readFileSync(manifestPath, "utf-8");
5973
6338
  } catch {
5974
6339
  return {
5975
6340
  diagnostic: err(
@@ -6148,12 +6513,12 @@ function findManifestCandidates(rootPath) {
6148
6513
  function walk(dir) {
6149
6514
  let entries;
6150
6515
  try {
6151
- entries = fs11__default.readdirSync(dir, { withFileTypes: true });
6516
+ entries = fs9__default.readdirSync(dir, { withFileTypes: true });
6152
6517
  } catch {
6153
6518
  return;
6154
6519
  }
6155
6520
  for (const entry of entries) {
6156
- const fullPath = path25__default.join(dir, entry.name);
6521
+ const fullPath = path23__default.join(dir, entry.name);
6157
6522
  if (entry.isDirectory()) {
6158
6523
  if (!SKIP_DIRS.has(entry.name)) walk(fullPath);
6159
6524
  } else if (entry.isFile()) {
@@ -6189,16 +6554,16 @@ function checkManifestIdentity(kind, parsed) {
6189
6554
  return null;
6190
6555
  }
6191
6556
  function parseManifestCandidate(c, absRoot) {
6192
- const content = fs11__default.readFileSync(c.filePath, "utf-8");
6557
+ const content = fs9__default.readFileSync(c.filePath, "utf-8");
6193
6558
  const res = parseManifestFile(c.filePath, content);
6194
6559
  if (!res.ok) {
6195
- logErr(`${path25__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 parse error: ${res.reason}`);
6560
+ logErr(`${path23__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 parse error: ${res.reason}`);
6196
6561
  return { kind: "error" };
6197
6562
  }
6198
6563
  return {
6199
6564
  kind: "value",
6200
6565
  parsed: res.data,
6201
- body: c.filePath.endsWith(".md") ? parseFrontmatter(content).body : void 0
6566
+ body: readAssetBody(c.filePath, content)
6202
6567
  };
6203
6568
  }
6204
6569
  var PSEUDO_COMPOSE_KINDS = /* @__PURE__ */ new Set(["soul"]);
@@ -6222,7 +6587,7 @@ function checkComposeKinds(parsed, registry) {
6222
6587
  return diagnostics;
6223
6588
  }
6224
6589
  function validateManifestCandidate(c, parsed, body, absRoot, registry, strictConformance) {
6225
- const relPath = path25__default.relative(absRoot, c.filePath);
6590
+ const relPath = path23__default.relative(absRoot, c.filePath);
6226
6591
  let errors = 0;
6227
6592
  let warnings = 0;
6228
6593
  const identityError = checkManifestIdentity(c.kind, parsed);
@@ -6230,9 +6595,15 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
6230
6595
  logErr(`${relPath} [${c.kind}] \u2014 ${identityError}`);
6231
6596
  errors++;
6232
6597
  }
6233
- if (c.kind === "skill" && parsed && typeof parsed === "object") {
6234
- const dirName = path25__default.basename(path25__default.dirname(c.filePath));
6235
- for (const f of checkSkillManifest(parsed, body, dirName)) {
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`);
6603
+ errors++;
6604
+ }
6605
+ const dirName = path23__default.basename(path23__default.dirname(c.filePath));
6606
+ for (const f of checkAssetManifest(c.kind, manifest, body, dirName)) {
6236
6607
  const line = `${relPath} [${f.tag}] \u2014 ${f.text}`;
6237
6608
  if (f.conformance && strictConformance) {
6238
6609
  logErr(line);
@@ -6243,7 +6614,7 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
6243
6614
  }
6244
6615
  }
6245
6616
  }
6246
- if (c.kind === "agent" && path25__default.basename(c.filePath) === "agent.yaml") {
6617
+ if (c.kind === "agent" && path23__default.basename(c.filePath) === "agent.yaml") {
6247
6618
  for (const d of [
6248
6619
  ...checkComposeKinds(parsed, registry),
6249
6620
  ...composeSlotDiagnostics(parsed),
@@ -6274,8 +6645,8 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
6274
6645
  return { errors, warnings };
6275
6646
  }
6276
6647
  function validateManifests(rootPath, strictConformance) {
6277
- const absRoot = path25__default.resolve(rootPath);
6278
- if (!fs11__default.existsSync(absRoot)) {
6648
+ const absRoot = path23__default.resolve(rootPath);
6649
+ if (!fs9__default.existsSync(absRoot)) {
6279
6650
  logErr(`Path does not exist: ${absRoot}`);
6280
6651
  return { total: 0, errors: 1, warnings: 0 };
6281
6652
  }
@@ -6283,6 +6654,7 @@ function validateManifests(rootPath, strictConformance) {
6283
6654
  const candidates = findManifestCandidates(absRoot);
6284
6655
  let errors = 0;
6285
6656
  let warnings = 0;
6657
+ const seenIdentity = /* @__PURE__ */ new Map();
6286
6658
  for (const c of candidates) {
6287
6659
  const parseResult = parseManifestCandidate(c, absRoot);
6288
6660
  if (parseResult.kind === "error") {
@@ -6299,6 +6671,21 @@ function validateManifests(rootPath, strictConformance) {
6299
6671
  );
6300
6672
  errors += delta.errors;
6301
6673
  warnings += delta.warnings;
6674
+ const obj = parseResult.parsed;
6675
+ const identity = obj && typeof obj === "object" ? obj[c.kind === "flow" ? "id" : "name"] : null;
6676
+ if (typeof identity === "string" && identity.length > 0) {
6677
+ const dir = path23__default.dirname(c.filePath);
6678
+ const key = `${c.kind}:${identity}`;
6679
+ const first = seenIdentity.get(key);
6680
+ if (first === void 0) {
6681
+ seenIdentity.set(key, dir);
6682
+ } else if (first !== dir) {
6683
+ 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).`
6685
+ );
6686
+ errors++;
6687
+ }
6688
+ }
6302
6689
  }
6303
6690
  return { total: candidates.length, errors, warnings };
6304
6691
  }
@@ -6307,12 +6694,12 @@ function findWorkspaceManifests(rootPath) {
6307
6694
  function walk(dir) {
6308
6695
  let entries;
6309
6696
  try {
6310
- entries = fs11__default.readdirSync(dir, { withFileTypes: true });
6697
+ entries = fs9__default.readdirSync(dir, { withFileTypes: true });
6311
6698
  } catch {
6312
6699
  return;
6313
6700
  }
6314
6701
  for (const entry of entries) {
6315
- const full = path25__default.join(dir, entry.name);
6702
+ const full = path23__default.join(dir, entry.name);
6316
6703
  if (entry.isDirectory()) {
6317
6704
  if (!SKIP_DIRS.has(entry.name)) walk(full);
6318
6705
  } else if (entry.isFile() && /(^|\.)skaile\.yaml$/.test(entry.name)) {
@@ -6375,14 +6762,14 @@ function validateWorkspaceAssets(parsed, relPath) {
6375
6762
  return errors;
6376
6763
  }
6377
6764
  function validateWorkspaceManifests(rootPath) {
6378
- const absRoot = path25__default.resolve(rootPath);
6765
+ const absRoot = path23__default.resolve(rootPath);
6379
6766
  const files = findWorkspaceManifests(absRoot);
6380
6767
  let errors = 0;
6381
6768
  for (const file of files) {
6382
- const relPath = path25__default.relative(absRoot, file);
6769
+ const relPath = path23__default.relative(absRoot, file);
6383
6770
  let parsed;
6384
6771
  try {
6385
- parsed = parse(fs11__default.readFileSync(file, "utf-8")) ?? {};
6772
+ parsed = parse(fs9__default.readFileSync(file, "utf-8")) ?? {};
6386
6773
  } catch (e) {
6387
6774
  logErr(`${relPath} \u2014 parse error: ${e instanceof Error ? e.message : String(e)}`);
6388
6775
  errors++;
@@ -6390,7 +6777,7 @@ function validateWorkspaceManifests(rootPath) {
6390
6777
  }
6391
6778
  errors += validateWorkspaceRefs(collectWorkspaceRefFields(parsed), relPath);
6392
6779
  errors += validateWorkspaceAssets(parsed, relPath);
6393
- for (const d of checkAgentInstances(path25__default.dirname(file), parsed)) {
6780
+ for (const d of checkAgentInstances(path23__default.dirname(file), parsed)) {
6394
6781
  const line = `${relPath} [agents] \u2014 ${d.code}: ${d.path ? `${d.path}: ` : ""}${d.message}`;
6395
6782
  if (d.severity === "error") {
6396
6783
  logErr(line);
@@ -6403,7 +6790,7 @@ function validateWorkspaceManifests(rootPath) {
6403
6790
  return { total: files.length, errors };
6404
6791
  }
6405
6792
  function validatePublishManifestRoots(rootPath) {
6406
- const absRoot = path25__default.resolve(rootPath);
6793
+ const absRoot = path23__default.resolve(rootPath);
6407
6794
  const manifest = loadSkPublishManifest(absRoot);
6408
6795
  if (!manifest) return 0;
6409
6796
  const missing = missingRootAssets(absRoot, manifest);
@@ -6414,99 +6801,133 @@ function validatePublishManifestRoots(rootPath) {
6414
6801
  }
6415
6802
  return missing.length;
6416
6803
  }
6804
+ function validatePublishManifestRequires(rootPath) {
6805
+ const problems = manifestRequiresProblems(path23__default.resolve(rootPath));
6806
+ for (const p6 of problems) {
6807
+ logErr(
6808
+ `${SKAILE_MANIFEST_FILENAME} [assets] \u2014 ${p6.asset}: ${p6.message}. Use the \`kind:@<publisher>/name[#version]\` form.`
6809
+ );
6810
+ }
6811
+ return problems.length;
6812
+ }
6813
+ function validatePublishManifestVersions(rootPath) {
6814
+ const absRoot = path23__default.resolve(rootPath);
6815
+ const manifest = loadSkPublishManifest(absRoot);
6816
+ if (!manifest || manifest.source) return 0;
6817
+ let warnings = 0;
6818
+ for (const a of manifest.assets ?? []) {
6819
+ if (!a.root || a.source || !a.version) continue;
6820
+ const file = findAssetManifestFile(path23__default.join(absRoot, a.root), a.kind, a.name);
6821
+ if (!file) continue;
6822
+ const res = parseManifestFile(file, fs9__default.readFileSync(file, "utf-8"));
6823
+ if (!res.ok) continue;
6824
+ const fileVersion = declaredVersion(res.data);
6825
+ if (fileVersion === void 0 || fileVersion === a.version) continue;
6826
+ logWarn(
6827
+ manifestVersionMismatchMessage(
6828
+ assetEntryRef(a, manifest),
6829
+ a.version,
6830
+ toPosix(path23__default.relative(absRoot, file)),
6831
+ fileVersion
6832
+ )
6833
+ );
6834
+ warnings++;
6835
+ }
6836
+ return warnings;
6837
+ }
6838
+ function validatePublishManifestPublishers(rootPath) {
6839
+ const absRoot = path23__default.resolve(rootPath);
6840
+ const manifest = loadSkPublishManifest(absRoot);
6841
+ if (!manifest || manifest.source) return 0;
6842
+ const bare = (p6) => p6.trim().replace(/^@/, "");
6843
+ let warnings = 0;
6844
+ for (const a of manifest.assets ?? []) {
6845
+ const resolved = a.publisher ?? manifest.publisher;
6846
+ if (!a.root || a.source || !resolved) continue;
6847
+ const file = findAssetManifestFile(path23__default.join(absRoot, a.root), a.kind, a.name);
6848
+ if (!file) continue;
6849
+ const res = parseManifestFile(file, fs9__default.readFileSync(file, "utf-8"));
6850
+ if (!res.ok) continue;
6851
+ const meta = res.data.metadata;
6852
+ const declared = meta !== null && typeof meta === "object" ? meta.publisher : null;
6853
+ if (typeof declared !== "string" || bare(declared) === bare(resolved)) continue;
6854
+ 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}.`
6856
+ );
6857
+ warnings++;
6858
+ }
6859
+ return warnings;
6860
+ }
6417
6861
  var EXCLUDED_PATHS = ["skaileup-shared/", "external/", "docs/"];
6418
6862
  function toPosix(p6) {
6419
- return p6.split(path25__default.sep).join("/");
6863
+ return p6.split(path23__default.sep).join("/");
6420
6864
  }
6421
6865
  function isExcludedPath(relPath) {
6422
6866
  const rel = toPosix(relPath);
6423
6867
  return EXCLUDED_PATHS.some((prefix) => rel.startsWith(prefix));
6424
6868
  }
6425
- function collectAssetVersions() {
6426
- const assets = [];
6427
- if (!fs11__default.existsSync(AI_RESOURCES)) return assets;
6428
- const kindDirs = (kindDirName) => findKindDirs(AI_RESOURCES, kindDirName).filter(
6429
- (dir) => !isExcludedPath(path25__default.relative(AI_RESOURCES, dir))
6430
- );
6431
- for (const dir of kindDirs("skills")) collectSkillVersions(dir, assets);
6432
- for (const dir of kindDirs("agents")) collectAgentVersions(dir, assets);
6433
- for (const dir of kindDirs("flows")) collectFlowVersions(dir, assets);
6434
- for (const dir of kindDirs("prompts")) collectPromptVersions(dir, assets);
6435
- const seen = /* @__PURE__ */ new Set();
6436
- return assets.filter((a) => !seen.has(a.filePath) && seen.add(a.filePath));
6437
- }
6438
- function collectFlowVersions(dir, out) {
6439
- for (const f of fs11__default.readdirSync(dir)) {
6440
- if (!f.endsWith(".flow.yaml")) continue;
6441
- const fp = path25__default.join(dir, f);
6442
- const content = fs11__default.readFileSync(fp, "utf-8");
6443
- const parsed = parse(content);
6444
- out.push({
6445
- kind: "flow",
6446
- name: parsed?.id ?? f.replace(".flow.yaml", ""),
6447
- version: parsed?.version ?? "",
6448
- filePath: fp
6449
- });
6450
- }
6451
- }
6452
- function collectPromptVersions(dir, out) {
6453
- for (const f of fs11__default.readdirSync(dir)) {
6454
- if (!f.endsWith(".prompt.md")) continue;
6455
- const fp = path25__default.join(dir, f);
6456
- const content = fs11__default.readFileSync(fp, "utf-8");
6869
+ var VERSIONED_KINDS = {
6870
+ skill: true,
6871
+ agent: true,
6872
+ flow: true,
6873
+ prompt: true
6874
+ };
6875
+ function readAssetVersion(c) {
6876
+ 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");
6880
+ if (c.filePath.endsWith(".md")) {
6457
6881
  const fm = parseSkillFrontmatter(content);
6458
- out.push({
6459
- kind: "prompt",
6460
- name: fm?.name ?? f.replace(".prompt.md", ""),
6882
+ const stem = fileName.replace(/\.prompt\.md$/, "");
6883
+ return {
6884
+ kind,
6885
+ name: fm?.name ?? (kind === "prompt" ? stem : dirName),
6461
6886
  version: fm?.metadata?.version ?? "",
6462
- filePath: fp
6463
- });
6887
+ filePath: c.filePath
6888
+ };
6464
6889
  }
6465
- }
6466
- function collectSkillVersions(dir, out) {
6467
- for (const entry of fs11__default.readdirSync(dir, { withFileTypes: true })) {
6468
- if (!entry.isDirectory()) continue;
6469
- const full = path25__default.join(dir, entry.name);
6470
- const skillMd = path25__default.join(full, "SKILL.md");
6471
- if (fs11__default.existsSync(skillMd)) {
6472
- const content = fs11__default.readFileSync(skillMd, "utf-8");
6473
- const fm = parseSkillFrontmatter(content);
6474
- out.push({
6475
- kind: "skill",
6476
- name: fm?.name ?? entry.name,
6477
- version: fm?.metadata?.version ?? "",
6478
- filePath: skillMd
6479
- });
6480
- } else {
6481
- collectSkillVersions(full, out);
6482
- }
6890
+ let parsed = null;
6891
+ try {
6892
+ parsed = parse(content);
6893
+ } catch {
6894
+ }
6895
+ if (kind === "flow") {
6896
+ return {
6897
+ kind,
6898
+ name: String(parsed?.id ?? fileName.replace(".flow.yaml", "")),
6899
+ version: String(parsed?.version ?? ""),
6900
+ filePath: c.filePath
6901
+ };
6483
6902
  }
6903
+ return {
6904
+ kind,
6905
+ name: String(parsed?.name ?? dirName),
6906
+ version: String(parsed?.version ?? ""),
6907
+ filePath: c.filePath
6908
+ };
6484
6909
  }
6485
- function collectAgentVersions(dir, out) {
6486
- for (const entry of fs11__default.readdirSync(dir, { withFileTypes: true })) {
6487
- if (!entry.isDirectory()) continue;
6488
- const agentYaml = path25__default.join(dir, entry.name, "agent.yaml");
6489
- if (!fs11__default.existsSync(agentYaml)) continue;
6490
- const content = fs11__default.readFileSync(agentYaml, "utf-8");
6491
- const parsed = parse(content);
6492
- out.push({
6493
- kind: "agent",
6494
- name: parsed?.name ?? entry.name,
6495
- version: parsed?.version ?? "",
6496
- filePath: agentYaml
6497
- });
6910
+ function collectAssetVersions(root) {
6911
+ if (!fs9__default.existsSync(root)) return [];
6912
+ const assets = [];
6913
+ for (const c of findManifestCandidates(root)) {
6914
+ if (!VERSIONED_KINDS[c.kind]) continue;
6915
+ if (c.filePath.endsWith(".flow.json")) continue;
6916
+ if (isExcludedPath(path23__default.relative(root, c.filePath))) continue;
6917
+ assets.push(readAssetVersion(c));
6498
6918
  }
6919
+ return assets;
6499
6920
  }
6500
- function assetLocation(a) {
6501
- return toPosix(path25__default.relative(AI_RESOURCES, a.filePath));
6921
+ function assetLocation(a, root) {
6922
+ return toPosix(path23__default.relative(root, a.filePath));
6502
6923
  }
6503
6924
  function findChangelogUnit(assetRelPath, root) {
6504
- let dir = path25__default.posix.dirname(toPosix(assetRelPath));
6925
+ let dir = path23__default.posix.dirname(toPosix(assetRelPath));
6505
6926
  for (; ; ) {
6506
6927
  const candidate = dir === "." ? "CHANGELOG.md" : `${dir}/CHANGELOG.md`;
6507
- if (fs11__default.existsSync(path25__default.join(root, candidate))) return candidate;
6928
+ if (fs9__default.existsSync(path23__default.join(root, candidate))) return candidate;
6508
6929
  if (dir === ".") return null;
6509
- dir = path25__default.posix.dirname(dir);
6930
+ dir = path23__default.posix.dirname(dir);
6510
6931
  }
6511
6932
  }
6512
6933
  function checkChangelogUnits(modifiedFiles, root) {
@@ -6525,7 +6946,7 @@ function checkChangelogUnits(modifiedFiles, root) {
6525
6946
  return { updated, stale, orphans };
6526
6947
  }
6527
6948
  function isValidSemver(v) {
6528
- return /^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/.test(v);
6949
+ return SEMVER_RE.test(v);
6529
6950
  }
6530
6951
  function extractVersionFromContent(filePath, content) {
6531
6952
  if (filePath.endsWith(".yaml")) {
@@ -6537,51 +6958,37 @@ function extractVersionFromContent(filePath, content) {
6537
6958
  const parsed = parse(fmMatch[1]);
6538
6959
  return parsed?.metadata?.version ?? parsed?.version ?? null;
6539
6960
  }
6540
- function filterToChangedAssets(assets) {
6541
- try {
6542
- const diffOutput = execSync("git diff --name-only HEAD", {
6543
- cwd: AI_RESOURCES,
6544
- encoding: "utf-8"
6545
- });
6546
- const changedFiles = new Set(
6547
- diffOutput.trim().split("\n").filter(Boolean).map((f) => path25__default.resolve(AI_RESOURCES, f))
6548
- );
6549
- return assets.filter((a) => changedFiles.has(a.filePath));
6550
- } catch {
6551
- logErr("Failed to run git diff \u2014 are you in a git repository?");
6552
- process.exit(1);
6553
- }
6554
- }
6555
- function checkAssetVersions(assets) {
6961
+ function checkAssetVersions(assets, root) {
6556
6962
  let errors = 0;
6557
- let warnings = 0;
6963
+ const warnings = 0;
6558
6964
  for (const a of assets) {
6559
6965
  if (!a.version) {
6560
- logErr(`${a.kind}:${a.name} (${assetLocation(a)}) \u2014 missing version`);
6966
+ logErr(`${a.kind}:${a.name} (${assetLocation(a, root)}) \u2014 missing version`);
6561
6967
  errors++;
6562
6968
  } else if (!isValidSemver(a.version)) {
6563
- logWarn(
6564
- `${a.kind}:${a.name} (${assetLocation(a)}) \u2014 version "${a.version}" is not valid semver`
6969
+ logErr(
6970
+ `${a.kind}:${a.name} (${assetLocation(a, root)}) \u2014 version "${a.version}" is not valid semver`
6565
6971
  );
6566
- warnings++;
6972
+ errors++;
6567
6973
  }
6568
6974
  }
6569
6975
  return { errors, warnings };
6570
6976
  }
6571
- function checkVersionBumps(assets) {
6977
+ function checkVersionBumps(assets, root) {
6572
6978
  let warnings = 0;
6573
6979
  for (const a of assets) {
6574
6980
  if (!a.version) continue;
6575
- const relPath = path25__default.relative(AI_RESOURCES, a.filePath);
6981
+ const relPath = toPosix(path23__default.relative(root, a.filePath));
6576
6982
  try {
6577
- const headContent = execSync(`git show HEAD:${relPath}`, {
6578
- cwd: AI_RESOURCES,
6579
- encoding: "utf-8"
6983
+ const headContent = execFileSync("git", ["show", `HEAD:./${relPath}`], {
6984
+ cwd: root,
6985
+ encoding: "utf-8",
6986
+ stdio: ["ignore", "pipe", "pipe"]
6580
6987
  });
6581
6988
  const headVersion = extractVersionFromContent(a.filePath, headContent);
6582
6989
  if (headVersion && headVersion === a.version) {
6583
6990
  logWarn(
6584
- `${a.kind}:${a.name} (${assetLocation(a)}) \u2014 file changed but version not bumped (${a.version})`
6991
+ `${a.kind}:${a.name} (${assetLocation(a, root)}) \u2014 file changed but version not bumped (${a.version})`
6585
6992
  );
6586
6993
  warnings++;
6587
6994
  }
@@ -6590,7 +6997,7 @@ function checkVersionBumps(assets) {
6590
6997
  }
6591
6998
  return warnings;
6592
6999
  }
6593
- function checkFlowVersionPins(assets) {
7000
+ function checkFlowVersionPins(assets, root) {
6594
7001
  const flows = assets.filter((a) => a.kind === "flow");
6595
7002
  const skillVersionMap = /* @__PURE__ */ new Map();
6596
7003
  for (const a of assets.filter((a2) => a2.kind === "skill")) {
@@ -6604,7 +7011,7 @@ function checkFlowVersionPins(assets) {
6604
7011
  pins = flowSkillVersionPins(loadFlow(f.filePath));
6605
7012
  } catch (err2) {
6606
7013
  logWarn(
6607
- `flow:${f.name} (${path25__default.relative(AI_RESOURCES, f.filePath)}) \u2014 could not be read: ${err2 instanceof Error ? err2.message : err2}`
7014
+ `flow:${f.name} (${path23__default.relative(root, f.filePath)}) \u2014 could not be read: ${err2 instanceof Error ? err2.message : err2}`
6608
7015
  );
6609
7016
  warnings++;
6610
7017
  continue;
@@ -6620,18 +7027,63 @@ function checkFlowVersionPins(assets) {
6620
7027
  }
6621
7028
  return { errors, warnings };
6622
7029
  }
6623
- function runVersionsCheck(opts) {
6624
- let assets = collectAssetVersions();
7030
+ function resolveCheckRoot(pathArg) {
7031
+ if (pathArg) {
7032
+ const abs = path23__default.resolve(pathArg);
7033
+ if (!fs9__default.existsSync(abs)) {
7034
+ logErr(`Path does not exist: ${abs}`);
7035
+ return null;
7036
+ }
7037
+ return abs;
7038
+ }
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;
7042
+ }
7043
+ }
7044
+ function changedFiles(root, ref) {
7045
+ try {
7046
+ const out = execFileSync(
7047
+ "git",
7048
+ ["diff", "--name-only", "--relative", "--end-of-options", ref],
7049
+ {
7050
+ cwd: root,
7051
+ encoding: "utf-8",
7052
+ stdio: ["ignore", "pipe", "pipe"]
7053
+ }
7054
+ );
7055
+ return out.trim().split("\n").filter(Boolean);
7056
+ } catch (err2) {
7057
+ const stderr = err2 instanceof Error && "stderr" in err2 ? String(err2.stderr).trim() : "";
7058
+ const reason = (stderr || (err2 instanceof Error ? err2.message : String(err2))).split("\n")[0];
7059
+ logErr(`git diff failed in ${root}: ${reason}`);
7060
+ return null;
7061
+ }
7062
+ }
7063
+ function runVersionsCheck(pathArg, opts) {
7064
+ const root = resolveCheckRoot(pathArg);
7065
+ if (root === null) {
7066
+ process.exit(1);
7067
+ return;
7068
+ }
7069
+ let assets = collectAssetVersions(root);
6625
7070
  if (opts.changedOnly) {
6626
- assets = filterToChangedAssets(assets);
7071
+ const changed = changedFiles(root, "HEAD");
7072
+ if (changed === null) {
7073
+ process.exit(1);
7074
+ return;
7075
+ }
7076
+ const changedAbs = new Set(changed.map((f) => path23__default.resolve(root, f)));
7077
+ assets = assets.filter((a) => changedAbs.has(a.filePath));
6627
7078
  }
6628
- const versionCheck = checkAssetVersions(assets);
7079
+ logInfo(`Checking versions in ${root}`);
7080
+ const versionCheck = checkAssetVersions(assets, root);
6629
7081
  let errors = versionCheck.errors;
6630
7082
  let warnings = versionCheck.warnings;
6631
7083
  if (opts.changedOnly) {
6632
- warnings += checkVersionBumps(assets);
7084
+ warnings += checkVersionBumps(assets, root);
6633
7085
  }
6634
- const pinCheck = checkFlowVersionPins(assets);
7086
+ const pinCheck = checkFlowVersionPins(assets, root);
6635
7087
  errors += pinCheck.errors;
6636
7088
  warnings += pinCheck.warnings;
6637
7089
  console.log();
@@ -6654,7 +7106,7 @@ function makeValidateCommand() {
6654
7106
  "--strict-conformance",
6655
7107
  "Treat Agent Skills (agentskills.io) standard findings as errors"
6656
7108
  ).action((targetPath, opts) => {
6657
- const absPath = path25__default.resolve(targetPath);
7109
+ const absPath = path23__default.resolve(targetPath);
6658
7110
  logInfo(`Validating manifests in ${absPath}`);
6659
7111
  const { total, errors, warnings } = validateManifests(
6660
7112
  absPath,
@@ -6662,11 +7114,16 @@ function makeValidateCommand() {
6662
7114
  );
6663
7115
  const ws = validateWorkspaceManifests(absPath);
6664
7116
  const rootErrors = validatePublishManifestRoots(absPath);
6665
- const totalErrors = errors + ws.errors + rootErrors;
7117
+ const requiresErrors = validatePublishManifestRequires(absPath);
7118
+ const versionWarnings = validatePublishManifestVersions(absPath);
7119
+ const publisherWarnings = validatePublishManifestPublishers(absPath);
7120
+ const totalErrors = errors + ws.errors + rootErrors + requiresErrors;
6666
7121
  console.log();
6667
7122
  warnIgnoredDomainFiles(absPath);
7123
+ warnLegacyBundleFiles(absPath);
6668
7124
  logInfo(`Scanned ${total} asset manifest(s) and ${ws.total} skaile.yaml file(s)`);
6669
- if (warnings > 0) logWarn(`${warnings} warning(s)`);
7125
+ const totalWarnings = warnings + versionWarnings + publisherWarnings;
7126
+ if (totalWarnings > 0) logWarn(`${totalWarnings} warning(s)`);
6670
7127
  if (totalErrors === 0) {
6671
7128
  logOk("All manifests valid");
6672
7129
  } else {
@@ -6674,23 +7131,24 @@ function makeValidateCommand() {
6674
7131
  process.exit(1);
6675
7132
  }
6676
7133
  });
6677
- cmd.command("versions").description("Check version fields and flow version pins").option("--changed-only", "Only check assets modified since last commit").option("--strict", "Exit 1 on warnings (for CI)").action((opts) => {
6678
- runVersionsCheck(opts);
6679
- });
6680
- cmd.command("changelog").description("Check that modified assets have an updated nearest CHANGELOG.md").option("--base <ref>", "Git base ref for diff", "HEAD").action((opts) => {
6681
- let diffOutput;
6682
- try {
6683
- diffOutput = execSync(`git diff --name-only --relative ${opts.base}`, {
6684
- cwd: AI_RESOURCES,
6685
- encoding: "utf-8"
6686
- });
6687
- } catch {
6688
- logErr("Failed to run git diff \u2014 are you in a git repository?");
7134
+ cmd.command("versions").description("Check version fields and flow version pins").argument("[path]", "Library or asset directory (default: the current library)").option("--changed-only", "Only check assets modified since last commit").option("--strict", "Exit 1 on warnings (for CI)").addOption(removedDomainOption()).action(
7135
+ (pathArg, opts) => {
7136
+ rejectRemovedDomainOption(opts);
7137
+ runVersionsCheck(pathArg, opts);
7138
+ }
7139
+ );
7140
+ cmd.command("changelog").description("Check that modified assets have an updated nearest CHANGELOG.md").argument("[path]", "Library or asset directory (default: the current library)").option("--base <ref>", "Git base ref for diff", "HEAD").action((pathArg, opts) => {
7141
+ const root = resolveCheckRoot(pathArg);
7142
+ if (root === null) {
6689
7143
  process.exit(1);
6690
7144
  return;
6691
7145
  }
6692
- const modifiedFiles = diffOutput.trim().split("\n").filter(Boolean);
6693
- const { updated, stale, orphans } = checkChangelogUnits(modifiedFiles, AI_RESOURCES);
7146
+ const modifiedFiles = changedFiles(root, opts.base);
7147
+ if (modifiedFiles === null) {
7148
+ process.exit(1);
7149
+ return;
7150
+ }
7151
+ const { updated, stale, orphans } = checkChangelogUnits(modifiedFiles, root);
6694
7152
  if (updated.length + stale.length + orphans.length === 0) {
6695
7153
  logOk("No modified assets found");
6696
7154
  return;
@@ -6734,7 +7192,7 @@ function itemFromRef(raw, defaultKind, ctx) {
6734
7192
  return { kind: prefixed[1], ref: value };
6735
7193
  }
6736
7194
  if (PATH_LIKE.test(value)) return { kind: defaultKind, ref: value };
6737
- if (defaultKind === "skill" && !value.includes("/") && existsSync(path25__default.join(ctx.agentDir, "skills", value, "SKILL.md"))) {
7195
+ if (defaultKind === "skill" && !value.includes("/") && existsSync(path23__default.join(ctx.agentDir, "skills", value, "SKILL.md"))) {
6738
7196
  return { kind: "skill", ref: `./skills/${value}` };
6739
7197
  }
6740
7198
  return { kind: defaultKind, ref: `${defaultKind}:${value}` };
@@ -6870,7 +7328,7 @@ function migrateAgentYaml(source, options) {
6870
7328
  manual.push("metadata.soul: not a string; left unchanged");
6871
7329
  continue;
6872
7330
  }
6873
- if (path25__default.posix.basename(soul.replace(/\\/g, "/")).toLowerCase() === "soul.md") {
7331
+ if (path23__default.posix.basename(soul.replace(/\\/g, "/")).toLowerCase() === "soul.md") {
6874
7332
  notes.push("metadata.soul \u2192 dropped (SOUL.md is a convention file)");
6875
7333
  } else {
6876
7334
  derived.push({ kind: "persona", ref: soul });
@@ -7104,7 +7562,7 @@ function migrateSubagents(skaileYamlPath, source) {
7104
7562
  if (!isMap(agentNode)) return void 0;
7105
7563
  const subNode = agentNode.get("subagents", true);
7106
7564
  if (!isMap(subNode)) return void 0;
7107
- const dir = path25__default.dirname(skaileYamlPath);
7565
+ const dir = path23__default.dirname(skaileYamlPath);
7108
7566
  const notes = [];
7109
7567
  const manual = [];
7110
7568
  const changes = [];
@@ -7122,10 +7580,10 @@ function migrateSubagents(skaileYamlPath, source) {
7122
7580
  continue;
7123
7581
  }
7124
7582
  const id = instanceId(name);
7125
- const assetDir = path25__default.join(dir, ".skaile", "agents", id);
7583
+ const assetDir = path23__default.join(dir, ".skaile", "agents", id);
7126
7584
  if (takenIds.has(id) || existsSync(assetDir)) {
7127
7585
  manual.push(
7128
- `agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${path25__default.relative(dir, assetDir)} already exists`}; left in place`
7586
+ `agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${path23__default.relative(dir, assetDir)} already exists`}; left in place`
7129
7587
  );
7130
7588
  continue;
7131
7589
  }
@@ -7149,13 +7607,13 @@ function migrateSubagents(skaileYamlPath, source) {
7149
7607
  manifest.tools = { ...allowed ? { allowed } : {}, ...denied ? { denied } : {} };
7150
7608
  }
7151
7609
  const text = stringify(manifest, { lineWidth: 0 });
7152
- const manifestPath = path25__default.join(assetDir, "agent.yaml");
7610
+ const manifestPath = path23__default.join(assetDir, "agent.yaml");
7153
7611
  changes.push({ type: "create", path: manifestPath, after: text });
7154
7612
  assetManifests.push({ file: manifestPath, text });
7155
7613
  if (typeof spec.prompt === "string" && spec.prompt.trim() !== "") {
7156
7614
  changes.push({
7157
7615
  type: "create",
7158
- path: path25__default.join(assetDir, "SOUL.md"),
7616
+ path: path23__default.join(assetDir, "SOUL.md"),
7159
7617
  after: `${spec.prompt.replace(/\s+$/, "")}
7160
7618
  `
7161
7619
  });
@@ -7214,7 +7672,7 @@ function validateMigratedAgent(text, registry) {
7214
7672
  function collectAgentFiles(paths) {
7215
7673
  const files = /* @__PURE__ */ new Set();
7216
7674
  for (const input of paths) {
7217
- const abs = path25__default.resolve(input);
7675
+ const abs = path23__default.resolve(input);
7218
7676
  if (!existsSync(abs)) continue;
7219
7677
  if (statSync(abs).isDirectory()) {
7220
7678
  for (const f of walkFiles(abs, (b) => b === "agent.yaml" || b === "skaile.yaml"))
@@ -7231,7 +7689,7 @@ function planAgentMigration(options) {
7231
7689
  const reports = [];
7232
7690
  for (const file of collectAgentFiles(options.paths)) {
7233
7691
  const source = readText(file);
7234
- const base = path25__default.basename(file);
7692
+ const base = path23__default.basename(file);
7235
7693
  if (base === "skaile.yaml") {
7236
7694
  const result = migrateSubagents(file, source);
7237
7695
  if (!result) continue;
@@ -7239,7 +7697,7 @@ function planAgentMigration(options) {
7239
7697
  for (const asset of result.assetManifests) {
7240
7698
  const v = validateMigratedAgent(asset.text, options.registry);
7241
7699
  validation2.errors.push(
7242
- ...v.errors.map((e) => `${path25__default.basename(path25__default.dirname(asset.file))}: ${e}`)
7700
+ ...v.errors.map((e) => `${path23__default.basename(path23__default.dirname(asset.file))}: ${e}`)
7243
7701
  );
7244
7702
  validation2.warnings.push(...v.warnings);
7245
7703
  }
@@ -7267,7 +7725,7 @@ function planAgentMigration(options) {
7267
7725
  });
7268
7726
  continue;
7269
7727
  }
7270
- migration = migrateAgentYaml(source, { agentDir: path25__default.dirname(file), knownKinds });
7728
+ migration = migrateAgentYaml(source, { agentDir: path23__default.dirname(file), knownKinds });
7271
7729
  } catch (error) {
7272
7730
  reports.push({
7273
7731
  file,
@@ -7296,7 +7754,7 @@ function planAgentMigration(options) {
7296
7754
  }
7297
7755
  var DEFAULT_PUBLISHER = "skaile-ai";
7298
7756
  var FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
7299
- var posix2 = (p6) => p6.split(path25__default.sep).join("/");
7757
+ var posix2 = (p6) => p6.split(path23__default.sep).join("/");
7300
7758
  var MOVED_KINDS = { persona: "PERSONA.md", ruleset: "RULESET.md" };
7301
7759
  var KIND_MANIFEST_FILES = /* @__PURE__ */ new Set(["PERSONA.md", "RULESET.md", "SKILL.md"]);
7302
7760
  function readFrontmatterType(text) {
@@ -7327,14 +7785,14 @@ function planMarkdownMoves(root, knownKinds, manual, unknownTypes) {
7327
7785
  if (!text.startsWith("---")) continue;
7328
7786
  const found = readFrontmatterType(text);
7329
7787
  if (!found) continue;
7330
- const base = path25__default.basename(file);
7331
- const inAgentParts = file.split(path25__default.sep).includes("_agent-parts");
7788
+ const base = path23__default.basename(file);
7789
+ const inAgentParts = file.split(path23__default.sep).includes("_agent-parts");
7332
7790
  const targetName = MOVED_KINDS[found.type];
7333
7791
  if (targetName !== void 0 && !KIND_MANIFEST_FILES.has(base)) {
7334
- const to = path25__default.join(path25__default.dirname(file), base.replace(/\.md$/i, ""), targetName);
7792
+ const to = path23__default.join(path23__default.dirname(file), base.replace(/\.md$/i, ""), targetName);
7335
7793
  if (existsSync(to) || targets.has(to)) {
7336
7794
  manual.push(
7337
- `${posix2(path25__default.relative(root, file))}: ${posix2(path25__default.relative(root, to))} already exists; not moved`
7795
+ `${posix2(path23__default.relative(root, file))}: ${posix2(path23__default.relative(root, to))} already exists; not moved`
7338
7796
  );
7339
7797
  continue;
7340
7798
  }
@@ -7355,13 +7813,13 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
7355
7813
  const changes = [];
7356
7814
  for (const file of walkFiles(root, (b) => b === "agent.yaml")) {
7357
7815
  const source = readText(file);
7358
- const agentDir = path25__default.dirname(file);
7816
+ const agentDir = path23__default.dirname(file);
7359
7817
  let hits = 0;
7360
7818
  const refRewrite = (_kind, ref) => {
7361
- const moved = byOldPath.get(path25__default.resolve(agentDir, ref));
7819
+ const moved = byOldPath.get(path23__default.resolve(agentDir, ref));
7362
7820
  if (moved === void 0) return ref;
7363
7821
  hits++;
7364
- const rel = posix2(path25__default.relative(agentDir, moved));
7822
+ const rel = posix2(path23__default.relative(agentDir, moved));
7365
7823
  return rel.startsWith(".") ? rel : `./${rel}`;
7366
7824
  };
7367
7825
  let output;
@@ -7378,7 +7836,7 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
7378
7836
  if (hits === 0 || output === source) continue;
7379
7837
  changes.push({ type: "write", path: file, before: source, after: output });
7380
7838
  notes.push(
7381
- `${posix2(path25__default.relative(root, file))}: persona/ruleset refs \u2192 composes items at the new paths`
7839
+ `${posix2(path23__default.relative(root, file))}: persona/ruleset refs \u2192 composes items at the new paths`
7382
7840
  );
7383
7841
  }
7384
7842
  return changes;
@@ -7403,14 +7861,14 @@ function presetText(name, description, refs, publisher) {
7403
7861
  }
7404
7862
  function skillDirs(dir) {
7405
7863
  try {
7406
- return readdirSync(path25__default.join(dir, "skills"), { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync(path25__default.join(dir, "skills", e.name, "SKILL.md"))).map((e) => e.name).sort();
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();
7407
7865
  } catch {
7408
7866
  return [];
7409
7867
  }
7410
7868
  }
7411
7869
  function repoPublisher(root) {
7412
7870
  for (const name of ["skaile.manifest.yaml", "skaile.yaml"]) {
7413
- const file = path25__default.join(root, name);
7871
+ const file = path23__default.join(root, name);
7414
7872
  if (!existsSync(file)) continue;
7415
7873
  try {
7416
7874
  const parsed = parse(readText(file));
@@ -7426,9 +7884,9 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
7426
7884
  const changes = [];
7427
7885
  const presets = [];
7428
7886
  const handled = /* @__PURE__ */ new Set();
7429
- const rel = (p6) => posix2(path25__default.relative(root, p6));
7887
+ const rel = (p6) => posix2(path23__default.relative(root, p6));
7430
7888
  const convert = (name, bundleFile, dir) => {
7431
- const target = path25__default.join(dir, `${name}.preset.yaml`);
7889
+ const target = path23__default.join(dir, `${name}.preset.yaml`);
7432
7890
  if (existsSync(target)) {
7433
7891
  manual.push(`${rel(target)} already exists; bundle ${name} not converted`);
7434
7892
  return;
@@ -7454,7 +7912,7 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
7454
7912
  }
7455
7913
  if (refs.length === 0) {
7456
7914
  manual.push(
7457
- `bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(path25__default.join(dir, "skills"))}`}; no preset generated`
7915
+ `bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(path23__default.join(dir, "skills"))}`}; no preset generated`
7458
7916
  );
7459
7917
  return;
7460
7918
  }
@@ -7476,18 +7934,18 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
7476
7934
  const assets = Array.isArray(raw.assets) ? raw.assets : [];
7477
7935
  for (const entry of assets) {
7478
7936
  if (!isRecord(entry) || entry.kind !== "bundle" || typeof entry.name !== "string") continue;
7479
- const baseDir = path25__default.dirname(file);
7480
- const entryRoot = typeof entry.root === "string" ? path25__default.join(baseDir, entry.root) : baseDir;
7937
+ const baseDir = path23__default.dirname(file);
7938
+ const entryRoot = typeof entry.root === "string" ? path23__default.join(baseDir, entry.root) : baseDir;
7481
7939
  const files = Array.isArray(entry.files) ? entry.files : [];
7482
7940
  const bundleName = files.find(
7483
7941
  (f) => typeof f === "string" && f.endsWith(".bundle.yaml")
7484
7942
  );
7485
- convert(entry.name, bundleName ? path25__default.join(entryRoot, bundleName) : void 0, entryRoot);
7943
+ convert(entry.name, bundleName ? path23__default.join(entryRoot, bundleName) : void 0, entryRoot);
7486
7944
  }
7487
7945
  }
7488
7946
  for (const bundleFile of walkFiles(root, (b) => b.endsWith(".bundle.yaml"))) {
7489
7947
  if (handled.has(bundleFile)) continue;
7490
- const base = path25__default.basename(bundleFile);
7948
+ const base = path23__default.basename(bundleFile);
7491
7949
  let name = base.replace(/\.bundle\.yaml$/, "");
7492
7950
  try {
7493
7951
  const parsed = parse(readText(bundleFile));
@@ -7496,7 +7954,7 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
7496
7954
  } catch {
7497
7955
  }
7498
7956
  if (presets.some((p6) => p6.bundleFile === bundleFile)) continue;
7499
- convert(name, bundleFile, path25__default.dirname(bundleFile));
7957
+ convert(name, bundleFile, path23__default.dirname(bundleFile));
7500
7958
  }
7501
7959
  return changes;
7502
7960
  }
@@ -7506,8 +7964,8 @@ function planSkaileYaml(root, file, source, notes, manual) {
7506
7964
  if (doc.errors.length > 0 || !isMap(doc.contents)) return [];
7507
7965
  const map = doc.contents;
7508
7966
  const raw = doc.toJS();
7509
- const dir = path25__default.dirname(file);
7510
- const rel = (p6) => posix2(path25__default.relative(root, p6));
7967
+ const dir = path23__default.dirname(file);
7968
+ const rel = (p6) => posix2(path23__default.relative(root, p6));
7511
7969
  const changes = [];
7512
7970
  let changed = false;
7513
7971
  const deps = map.get("dependencies", true);
@@ -7524,7 +7982,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
7524
7982
  const hasPublication = PUBLICATION_KEYS.some((k) => raw[k] !== void 0);
7525
7983
  let remove = false;
7526
7984
  if (hasPublication) {
7527
- const manifestPath = path25__default.join(dir, "skaile.manifest.yaml");
7985
+ const manifestPath = path23__default.join(dir, "skaile.manifest.yaml");
7528
7986
  if (existsSync(manifestPath)) {
7529
7987
  manual.push(
7530
7988
  `${rel(file)}: publisher/version/assets left in place \u2014 ${rel(manifestPath)} already exists; merge by hand`
@@ -7581,7 +8039,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
7581
8039
  return changes;
7582
8040
  }
7583
8041
  function planAssetMigration(options) {
7584
- const root = path25__default.resolve(options.root);
8042
+ const root = path23__default.resolve(options.root);
7585
8043
  const knownKinds = new Set(options.registry.getAllKinds());
7586
8044
  const notes = [];
7587
8045
  const manual = [];
@@ -7589,7 +8047,7 @@ function planAssetMigration(options) {
7589
8047
  const { moves, changes: moveChanges } = planMarkdownMoves(root, knownKinds, manual, unknownTypes);
7590
8048
  for (const move of moves) {
7591
8049
  notes.push(
7592
- `${posix2(path25__default.relative(root, move.from))} \u2192 ${posix2(path25__default.relative(root, move.to))} (${move.kind})`
8050
+ `${posix2(path23__default.relative(root, move.from))} \u2192 ${posix2(path23__default.relative(root, move.to))} (${move.kind})`
7593
8051
  );
7594
8052
  }
7595
8053
  const agentChanges = planAgentRefRewrites(root, moves, knownKinds, notes);
@@ -7601,7 +8059,7 @@ function planAssetMigration(options) {
7601
8059
  const raw = parse(source);
7602
8060
  if (isRecord(raw)) skaileYamls.push({ file, source, raw });
7603
8061
  } catch {
7604
- manual.push(`${posix2(path25__default.relative(root, file))}: invalid YAML; skipped`);
8062
+ manual.push(`${posix2(path23__default.relative(root, file))}: invalid YAML; skipped`);
7605
8063
  }
7606
8064
  }
7607
8065
  const publisher = repoPublisher(root);
@@ -7755,7 +8213,7 @@ function workspaceConfigFiles(dir) {
7755
8213
  } catch {
7756
8214
  return [];
7757
8215
  }
7758
- return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) => path25__default.join(dir, name));
8216
+ return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) => path23__default.join(dir, name));
7759
8217
  }
7760
8218
  function readAgentConfigBlock(raw) {
7761
8219
  const key = AGENT_CONFIG_KEYS.find((candidate) => raw[candidate] !== void 0);
@@ -7767,7 +8225,7 @@ function readAgentConfigBlock(raw) {
7767
8225
  return flat ? { key, profiles: { default: profiles }, flat } : { key, profiles, flat };
7768
8226
  }
7769
8227
  function planProviderMigration(options) {
7770
- const projectDir = path25__default.resolve(options.projectDir);
8228
+ const projectDir = path23__default.resolve(options.projectDir);
7771
8229
  const registryPath = options.workspace ? workspaceProviderRegistryPath(projectDir) : userProviderRegistryPath();
7772
8230
  const plan = {
7773
8231
  registryPath,
@@ -7783,7 +8241,7 @@ function planProviderMigration(options) {
7783
8241
  raw = parseDocument(readFileSync(file, "utf-8")).toJS() ?? {};
7784
8242
  } catch (error) {
7785
8243
  plan.warnings.push(
7786
- `${path25__default.basename(file)}: not valid YAML (${error instanceof Error ? error.message : String(error)}) \u2014 skipped`
8244
+ `${path23__default.basename(file)}: not valid YAML (${error instanceof Error ? error.message : String(error)}) \u2014 skipped`
7787
8245
  );
7788
8246
  continue;
7789
8247
  }
@@ -7832,7 +8290,7 @@ function planProviderMigration(options) {
7832
8290
  });
7833
8291
  if (!model) {
7834
8292
  plan.warnings.push(
7835
- `${path25__default.basename(file)}: profile '${profile}' had no model: \u2014 it now resolves against registry order. Pin it with 'model: ${providerId}/<modelId>'.`
8293
+ `${path23__default.basename(file)}: profile '${profile}' had no model: \u2014 it now resolves against registry order. Pin it with 'model: ${providerId}/<modelId>'.`
7836
8294
  );
7837
8295
  }
7838
8296
  touched = true;
@@ -7899,7 +8357,7 @@ function printPlan(plan) {
7899
8357
  for (const entry of plan.entries) {
7900
8358
  const base = entry.entry.base_url ?? S.dim("(transport-derived)");
7901
8359
  console.log(
7902
- ` ${S.label(`${path25__default.basename(entry.file)} ${entry.profile}`)} provider: ${entry.legacy.provider}, cloud: ${entry.legacy.cloud}`
8360
+ ` ${S.label(`${path23__default.basename(entry.file)} ${entry.profile}`)} provider: ${entry.legacy.provider}, cloud: ${entry.legacy.cloud}`
7903
8361
  );
7904
8362
  console.log(` \u2192 providers.yml ${S.bold(entry.providerId)} ${base}`);
7905
8363
  console.log(
@@ -7915,7 +8373,7 @@ function printPlan(plan) {
7915
8373
  console.log();
7916
8374
  }
7917
8375
  async function runMigrateProviders(opts) {
7918
- const projectDir = opts.projectDir ? path25__default.resolve(opts.projectDir) : process.cwd();
8376
+ const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
7919
8377
  const plan = planProviderMigration({ projectDir, workspace: opts.workspace });
7920
8378
  for (const warning of plan.warnings) logWarn(warning);
7921
8379
  if (plan.entries.length === 0 && Object.keys(plan.providers).length === 0) {
@@ -8046,7 +8504,7 @@ async function runMigrateAgents(paths, opts) {
8046
8504
  let failures = 0;
8047
8505
  let manualCount = 0;
8048
8506
  for (const report of plan.reports) {
8049
- const rel = path25__default.relative(base, report.file) || report.file;
8507
+ const rel = path23__default.relative(base, report.file) || report.file;
8050
8508
  for (const note of report.notes) console.log(` ${S.label(rel)} ${note}`);
8051
8509
  for (const note of report.manual) {
8052
8510
  manualCount++;
@@ -8073,14 +8531,14 @@ async function runMigrateAssets(root, opts) {
8073
8531
  const write = resolveMode(opts);
8074
8532
  const base = process.cwd();
8075
8533
  const plan = planAssetMigration({
8076
- root: path25__default.resolve(root ?? base),
8534
+ root: path23__default.resolve(root ?? base),
8077
8535
  registry: getKindRegistry()
8078
8536
  });
8079
8537
  for (const note of plan.notes) console.log(` ${note}`);
8080
8538
  for (const note of plan.manual) logWarn(note);
8081
8539
  for (const { file, type } of plan.unknownTypes) {
8082
8540
  logWarn(
8083
- `${path25__default.relative(base, file) || file}: frontmatter type "${type}" is not a registered asset kind (reported, not rewritten)`
8541
+ `${path23__default.relative(base, file) || file}: frontmatter type "${type}" is not a registered asset kind (reported, not rewritten)`
8084
8542
  );
8085
8543
  }
8086
8544
  printChanges(plan.changes, base);
@@ -8103,8 +8561,8 @@ function makeNpxCommand() {
8103
8561
  skills.command("add <url>").description(
8104
8562
  "Clone a repo, register it in the project's skaile.yaml sources[], and install a skill from it"
8105
8563
  ).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) => {
8106
- const projectDir = path25__default.resolve(opts.projectDir);
8107
- const projYaml = path25__default.join(projectDir, "skaile.yaml");
8564
+ const projectDir = path23__default.resolve(opts.projectDir);
8565
+ const projYaml = path23__default.join(projectDir, "skaile.yaml");
8108
8566
  if (!existsSync(projYaml)) {
8109
8567
  logErr(`No skaile.yaml in ${projectDir} \u2014 run \`skaile init\` first.`);
8110
8568
  process.exit(1);
@@ -8117,11 +8575,11 @@ function makeNpxCommand() {
8117
8575
  }
8118
8576
  const spinner = createSpinner();
8119
8577
  const key = sourceCacheKey(url);
8120
- const clonePath = path25__default.join(getGlobalCacheDir(), key);
8578
+ const clonePath = path23__default.join(getGlobalCacheDir(), key);
8121
8579
  spinner.start(`Cloning ${url}`);
8122
8580
  try {
8123
8581
  if (!existsSync(clonePath)) {
8124
- mkdirSync(path25__default.dirname(clonePath), { recursive: true });
8582
+ mkdirSync(path23__default.dirname(clonePath), { recursive: true });
8125
8583
  execSync(`git clone ${url} ${clonePath}`, { stdio: "ignore" });
8126
8584
  }
8127
8585
  spinner.stop(`Cloned to ${key}`);
@@ -8176,7 +8634,7 @@ function makeNpxCommand() {
8176
8634
  return npx;
8177
8635
  }
8178
8636
  function resolvePublisher(clonePath, url) {
8179
- const manifestPath = path25__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
8637
+ const manifestPath = path23__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
8180
8638
  if (existsSync(manifestPath)) {
8181
8639
  try {
8182
8640
  const { manifest } = decodeSkaileManifest(readFileSync(manifestPath, "utf8"));
@@ -8189,12 +8647,12 @@ function resolvePublisher(clonePath, url) {
8189
8647
  return url.match(/github\.com[/:]([^/]+)\/[^/]+/)?.[1];
8190
8648
  }
8191
8649
  function resolveSkillName(clonePath, requested) {
8192
- const skillsDir = path25__default.join(clonePath, "skills");
8193
- if (existsSync(path25__default.join(skillsDir, requested, "SKILL.md"))) return requested;
8650
+ const skillsDir = path23__default.join(clonePath, "skills");
8651
+ if (existsSync(path23__default.join(skillsDir, requested, "SKILL.md"))) return requested;
8194
8652
  if (!existsSync(skillsDir)) return requested;
8195
8653
  for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
8196
8654
  if (!entry.isDirectory()) continue;
8197
- const md = path25__default.join(skillsDir, entry.name, "SKILL.md");
8655
+ const md = path23__default.join(skillsDir, entry.name, "SKILL.md");
8198
8656
  if (!existsSync(md)) continue;
8199
8657
  try {
8200
8658
  const { data } = parseFrontmatter(readFileSync(md, "utf8"));
@@ -8205,6 +8663,7 @@ function resolveSkillName(clonePath, requested) {
8205
8663
  return requested;
8206
8664
  }
8207
8665
  function outdatedRef(e) {
8666
+ if (!e.kind) return e.name;
8208
8667
  const publisher = e.publisher?.replace(/^@/, "");
8209
8668
  return publisher ? `${e.kind}:@${publisher}/${e.name}` : `${e.kind}:${e.name}`;
8210
8669
  }
@@ -8225,7 +8684,7 @@ function makeOutdatedCommand() {
8225
8684
  ).action(async (filter, opts) => {
8226
8685
  const am2 = new AssetManager({
8227
8686
  registry: getKindRegistry(),
8228
- projectDir: path25__default.resolve(opts.projectDir),
8687
+ projectDir: path23__default.resolve(opts.projectDir),
8229
8688
  driverTarget: opts.target
8230
8689
  });
8231
8690
  const entries = await am2.outdated();
@@ -8243,16 +8702,16 @@ function makeOutdatedCommand() {
8243
8702
  console.log(S.heading(" Outdated Assets"));
8244
8703
  console.log(` ${S.rule(refW + 34)}`);
8245
8704
  for (const e of filtered) {
8246
- const status4 = e.problem !== void 0 ? e.problem : e.library !== void 0 ? `${e.currentVersion} \u2192 ${e.latestVersion} ${S.dim(`(library ${e.library})`)}` : `${e.behind} commit(s) behind`;
8705
+ const status4 = e.problem !== void 0 ? e.problem : e.contentChanged ? `${e.currentVersion} content changed since lock ${S.dim(`(library ${e.library})`)}` : e.library !== void 0 ? `${e.currentVersion} \u2192 ${e.latestVersion} ${S.dim(`(library ${e.library})`)}` : `${e.behind} commit(s) behind`;
8247
8706
  console.log(
8248
8707
  ` ${colorRef(outdatedRef(e))}${" ".repeat(refW - outdatedRef(e).length)} ${e.problem !== void 0 ? pc5.red(status4) : pc5.yellow(status4)}`
8249
8708
  );
8250
8709
  }
8251
8710
  console.log();
8252
8711
  if (filtered.some((e) => e.problem === void 0)) {
8253
- logWarn(`Run ${S.cmd("skaile update")} to re-deploy.`);
8712
+ logWarn(`Run ${S.cmd("skaile update")} to re-lock and re-deploy.`);
8254
8713
  }
8255
- if (filtered.some((e) => e.problem !== void 0)) {
8714
+ if (filtered.some((e) => e.problem !== void 0 && !e.manualFix)) {
8256
8715
  logWarn(`Run ${S.cmd("skaile install")} to restore or re-lock the broken assets.`);
8257
8716
  }
8258
8717
  });
@@ -8262,7 +8721,7 @@ function makePatchCommand() {
8262
8721
  cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
8263
8722
  const am2 = new AssetManager({
8264
8723
  registry: getKindRegistry(),
8265
- projectDir: path25__default.resolve(opts.projectDir)
8724
+ projectDir: path23__default.resolve(opts.projectDir)
8266
8725
  });
8267
8726
  try {
8268
8727
  const dest = await am2.patch(ref);
@@ -8276,7 +8735,7 @@ function makePatchCommand() {
8276
8735
  cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
8277
8736
  const am2 = new AssetManager({
8278
8737
  registry: getKindRegistry(),
8279
- projectDir: path25__default.resolve(opts.projectDir)
8738
+ projectDir: path23__default.resolve(opts.projectDir)
8280
8739
  });
8281
8740
  try {
8282
8741
  const patchFile = await am2.patchCommit(ref);
@@ -8290,7 +8749,7 @@ function makePatchCommand() {
8290
8749
  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) => {
8291
8750
  const am2 = new AssetManager({
8292
8751
  registry: getKindRegistry(),
8293
- projectDir: path25__default.resolve(opts.projectDir)
8752
+ projectDir: path23__default.resolve(opts.projectDir)
8294
8753
  });
8295
8754
  try {
8296
8755
  await am2.patchSubmit(ref);
@@ -8306,7 +8765,7 @@ function makePatchCommand() {
8306
8765
  cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
8307
8766
  const am2 = new AssetManager({
8308
8767
  registry: getKindRegistry(),
8309
- projectDir: path25__default.resolve(opts.projectDir)
8768
+ projectDir: path23__default.resolve(opts.projectDir)
8310
8769
  });
8311
8770
  am2.patchRemove(ref);
8312
8771
  logOk(`Patch removed for ${ref}`);
@@ -8325,7 +8784,7 @@ function action2(fn) {
8325
8784
  };
8326
8785
  }
8327
8786
  async function reconcileAndReport(projectDir, plugins) {
8328
- const { reconcilePlugins } = await import('../plugin-store-66QFBNEO.js');
8787
+ const { reconcilePlugins } = await import('../plugin-store-MPAMD5OT.js');
8329
8788
  if (plugins.length === 0) {
8330
8789
  logInfo("No plugins declared \u2014 nothing to reconcile.");
8331
8790
  return;
@@ -8339,10 +8798,10 @@ async function reconcileAndReport(projectDir, plugins) {
8339
8798
  }
8340
8799
  }
8341
8800
  async function runInstall2(spec, opts) {
8342
- const projectDir = path25__default.resolve(opts.projectDir);
8801
+ const projectDir = path23__default.resolve(opts.projectDir);
8343
8802
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
8344
- const { specName } = await import('../plugin-store-66QFBNEO.js');
8345
- const yamlPath = path25__default.join(projectDir, "skaile.yaml");
8803
+ const { specName } = await import('../plugin-store-MPAMD5OT.js');
8804
+ const yamlPath = path23__default.join(projectDir, "skaile.yaml");
8346
8805
  const editor = WorkspaceYamlEditor2.load(yamlPath);
8347
8806
  const replaced = editor.addPlugin(spec, specName);
8348
8807
  editor.save();
@@ -8351,10 +8810,10 @@ async function runInstall2(spec, opts) {
8351
8810
  await reconcileAndReport(projectDir, editor.getPlugins());
8352
8811
  }
8353
8812
  async function runRemove(name, opts) {
8354
- const projectDir = path25__default.resolve(opts.projectDir);
8813
+ const projectDir = path23__default.resolve(opts.projectDir);
8355
8814
  const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
8356
- const { specName } = await import('../plugin-store-66QFBNEO.js');
8357
- const yamlPath = path25__default.join(projectDir, "skaile.yaml");
8815
+ const { specName } = await import('../plugin-store-MPAMD5OT.js');
8816
+ const yamlPath = path23__default.join(projectDir, "skaile.yaml");
8358
8817
  const editor = WorkspaceYamlEditor2.load(yamlPath);
8359
8818
  const removed = editor.removePlugin(name, specName);
8360
8819
  if (!removed) {
@@ -8366,7 +8825,7 @@ async function runRemove(name, opts) {
8366
8825
  await reconcileAndReport(projectDir, editor.getPlugins());
8367
8826
  }
8368
8827
  async function runList(opts) {
8369
- const projectDir = path25__default.resolve(opts.projectDir);
8828
+ const projectDir = path23__default.resolve(opts.projectDir);
8370
8829
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
8371
8830
  const config = resolveSkWorkspaceConfig2(projectDir);
8372
8831
  const declared = config.plugins ?? [];
@@ -8381,7 +8840,7 @@ async function runList(opts) {
8381
8840
  const registry = createPluginRegistry();
8382
8841
  if (declared.length > 0) {
8383
8842
  try {
8384
- const { loadPlugins } = await import('../plugin-store-66QFBNEO.js');
8843
+ const { loadPlugins } = await import('../plugin-store-MPAMD5OT.js');
8385
8844
  const result = await loadPlugins(projectDir, declared, registry);
8386
8845
  for (const f of result.failed) logWarn(f.error);
8387
8846
  } catch (err2) {
@@ -8556,7 +9015,7 @@ function neededSources(config, lock) {
8556
9015
  }
8557
9016
  function sourcesWithSidecar(sources) {
8558
9017
  const dir = getStoreManifestsDir();
8559
- return sources.filter((s) => existsSync(path25.join(dir, `${storeManifestSlug(s.url)}.yaml`))).map((s) => s.url);
9018
+ return sources.filter((s) => existsSync(path23.join(dir, `${storeManifestSlug(s.url)}.yaml`))).map((s) => s.url);
8560
9019
  }
8561
9020
  function compact(obj) {
8562
9021
  const out = {};
@@ -8672,7 +9131,7 @@ function makePresetCommand() {
8672
9131
  cmd.command("init [name]").description("Scaffold a new .preset.yaml file").option("--dir <path>", "Output directory", process.cwd()).action(async (name, opts) => {
8673
9132
  const presetName = name ?? "my-preset";
8674
9133
  const filename = `${presetName}.preset.yaml`;
8675
- const outPath = path25__default.join(path25__default.resolve(opts.dir), filename);
9134
+ const outPath = path23__default.join(path23__default.resolve(opts.dir), filename);
8676
9135
  if (existsSync(outPath)) {
8677
9136
  logErr(`File already exists: ${outPath}`);
8678
9137
  logInfo("Choose a different name or remove the existing file.");
@@ -8705,7 +9164,7 @@ function makePresetCommand() {
8705
9164
  return cmd;
8706
9165
  }
8707
9166
  async function runPresetExport(name, opts) {
8708
- const projectDir = path25__default.resolve(opts.projectDir);
9167
+ const projectDir = path23__default.resolve(opts.projectDir);
8709
9168
  const file = loadSkWorkspaceConfig(projectDir);
8710
9169
  if (!file) {
8711
9170
  logErr(`No skaile.yaml found in ${projectDir}`);
@@ -8715,7 +9174,7 @@ async function runPresetExport(name, opts) {
8715
9174
  const presetName = name ?? file.config.name ?? "my-preset";
8716
9175
  let lock = null;
8717
9176
  try {
8718
- lock = readLock(path25__default.join(projectDir, "skaile.lock.yaml"));
9177
+ lock = readLock(path23__default.join(projectDir, "skaile.lock.yaml"));
8719
9178
  } catch {
8720
9179
  lock = null;
8721
9180
  }
@@ -8756,7 +9215,7 @@ async function runPresetExport(name, opts) {
8756
9215
  const contents = header ? `${header}
8757
9216
  ${body}` : body;
8758
9217
  if (opts.out && opts.dir !== process.cwd()) logWarn("--dir is ignored when --out is set.");
8759
- const outPath = opts.out ? path25__default.resolve(opts.out) : path25__default.join(path25__default.resolve(opts.dir), `${presetName}.preset.yaml`);
9218
+ const outPath = opts.out ? path23__default.resolve(opts.out) : path23__default.join(path23__default.resolve(opts.dir), `${presetName}.preset.yaml`);
8760
9219
  if (existsSync(outPath) && !opts.force) {
8761
9220
  logErr(`File already exists: ${outPath}`);
8762
9221
  logInfo("Pass --force to overwrite, or choose a different --out/--dir.");
@@ -8768,7 +9227,7 @@ ${body}` : body;
8768
9227
  logErr(`Failed to write ${outPath}: ${e.message}`);
8769
9228
  process.exit(1);
8770
9229
  }
8771
- logOk(`Exported ${S.brand(path25__default.basename(outPath))}`);
9230
+ logOk(`Exported ${S.brand(path23__default.basename(outPath))}`);
8772
9231
  logInfo(`Path: ${outPath}`);
8773
9232
  if (unresolved.length > 0) {
8774
9233
  console.error(S.err("This file is NOT safe to share."));
@@ -8809,13 +9268,13 @@ function collectInput(value, acc) {
8809
9268
  return acc;
8810
9269
  }
8811
9270
  async function runPresetApply(filePath, opts) {
8812
- const projectDir = path25__default.resolve(opts.projectDir);
9271
+ const projectDir = path23__default.resolve(opts.projectDir);
8813
9272
  const file = loadSkWorkspaceConfig(projectDir);
8814
9273
  if (!file) {
8815
9274
  logErr("No skaile.yaml \u2014 run `skaile init` first");
8816
9275
  process.exit(1);
8817
9276
  }
8818
- const resolved = path25__default.resolve(filePath);
9277
+ const resolved = path23__default.resolve(filePath);
8819
9278
  if (!existsSync(resolved)) {
8820
9279
  logErr(`File not found: ${resolved}`);
8821
9280
  process.exit(1);
@@ -8994,7 +9453,7 @@ async function runPresetInstall(projectDir) {
8994
9453
  logInfo("Installing new dependencies\u2026");
8995
9454
  const result = await am2.install({});
8996
9455
  for (const d of result.deployed) logOk(d);
8997
- for (const m of result.missing) logErr(`Missing: ${m}`);
9456
+ for (const m of result.missing) logErr(`Missing: ${m}${result.missingHints?.[m] ?? ""}`);
8998
9457
  await reportInstalledSoftDeps(am2);
8999
9458
  } catch (err2) {
9000
9459
  logErr(`Install failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
@@ -9031,7 +9490,7 @@ async function reportNestedPresetRefs(preset) {
9031
9490
  }
9032
9491
  async function checkPresetCycles(preset, resolved) {
9033
9492
  const { detectCycles } = await import('../discovery/index.js');
9034
- const presetRef = path25__default.basename(resolved, ".preset.yaml");
9493
+ const presetRef = path23__default.basename(resolved, ".preset.yaml");
9035
9494
  const edges = [];
9036
9495
  for (const item of preset.items) {
9037
9496
  if (item.ref) {
@@ -9083,7 +9542,7 @@ function printPresetSummary(preset, placeholderCount, hasWarnings) {
9083
9542
  }
9084
9543
  }
9085
9544
  async function runPresetValidate(filePath) {
9086
- const resolved = path25__default.resolve(filePath);
9545
+ const resolved = path23__default.resolve(filePath);
9087
9546
  const preset = await loadPresetForValidation(resolved);
9088
9547
  await reportNestedPresetRefs(preset);
9089
9548
  await checkPresetCycles(preset, resolved);
@@ -9133,11 +9592,11 @@ items:
9133
9592
  }
9134
9593
  function makeRebuildCommand() {
9135
9594
  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) => {
9136
- const projectDir = path25__default.resolve(opts.projectDir);
9595
+ const projectDir = path23__default.resolve(opts.projectDir);
9137
9596
  let agentDir;
9138
9597
  if (agentArg) {
9139
9598
  if (agentArg.includes("/") || agentArg.includes("\\")) {
9140
- agentDir = path25__default.resolve(projectDir, agentArg);
9599
+ agentDir = path23__default.resolve(projectDir, agentArg);
9141
9600
  } else {
9142
9601
  let resolved;
9143
9602
  try {
@@ -9146,7 +9605,7 @@ function makeRebuildCommand() {
9146
9605
  if (!(err2 instanceof AgentRefResolutionError)) throw err2;
9147
9606
  logWarn(`${err2.message} \u2014 using "${agentArg}"`);
9148
9607
  }
9149
- agentDir = resolved ?? path25__default.resolve(projectDir, agentArg);
9608
+ agentDir = resolved ?? path23__default.resolve(projectDir, agentArg);
9150
9609
  }
9151
9610
  } else {
9152
9611
  let resolved;
@@ -9216,9 +9675,9 @@ Try a different harness with \`--driver claude-sdk\`.`;
9216
9675
  // cli/src/commands/run.ts
9217
9676
  function resolveSingleShotAgentDir(projectDir, agentDefinition) {
9218
9677
  if (!agentDefinition) return resolveAgentDir(projectDir);
9219
- const asPath = agentDefinition.endsWith("agent.yaml") ? path25__default.dirname(path25__default.resolve(projectDir, agentDefinition)) : agentDefinition;
9678
+ const asPath = agentDefinition.endsWith("agent.yaml") ? path23__default.dirname(path23__default.resolve(projectDir, agentDefinition)) : agentDefinition;
9220
9679
  const dir = resolveAgentDefinitionDir(projectDir, asPath);
9221
- if (!dir || !fs11__default.existsSync(path25__default.join(dir, "agent.yaml"))) {
9680
+ if (!dir || !fs9__default.existsSync(path23__default.join(dir, "agent.yaml"))) {
9222
9681
  throw new Error(
9223
9682
  `--agent-definition "${agentDefinition}" does not resolve to an agent directory with agent.yaml${dir ? ` (looked in ${dir})` : ""}`
9224
9683
  );
@@ -9317,7 +9776,7 @@ function makeRunCommand() {
9317
9776
  "--agent-definition <ref|path>",
9318
9777
  "Agent asset for this one invocation (agent:@pub/name, ai-assets://\u2026, or a directory with agent.yaml); single-shot prompts only"
9319
9778
  ).option("--skill <name>", "Skill name (for single-shot mode)").action(async (positional, opts) => {
9320
- const projectDir = path25__default.resolve(opts.projectDir);
9779
+ const projectDir = path23__default.resolve(opts.projectDir);
9321
9780
  const cliDriver = opts.driver;
9322
9781
  const dryRun = opts.dryRun ?? false;
9323
9782
  const agentDefinition = opts.agentDefinition?.trim() || void 0;
@@ -9436,7 +9895,7 @@ function makeRunCommand() {
9436
9895
  }
9437
9896
  function makeResumeCommand() {
9438
9897
  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) => {
9439
- const projectDir = path25__default.resolve(opts.projectDir);
9898
+ const projectDir = path23__default.resolve(opts.projectDir);
9440
9899
  const sessionId = opts.session;
9441
9900
  const dryRun = opts.dryRun ?? false;
9442
9901
  const session = sessionId ? await loadSessionById(projectDir, sessionId) : await loadSession(projectDir);
@@ -9463,7 +9922,7 @@ function makeResumeCommand() {
9463
9922
  }
9464
9923
  function makeStatusCommand() {
9465
9924
  return new Command("status").description("Show current session state").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
9466
- const projectDir = path25__default.resolve(opts.projectDir);
9925
+ const projectDir = path23__default.resolve(opts.projectDir);
9467
9926
  const session = await loadSession(projectDir);
9468
9927
  if (!session) {
9469
9928
  logInfo("No active session.");
@@ -9488,7 +9947,7 @@ function makeStatusCommand() {
9488
9947
  }
9489
9948
  function makeClearCommand() {
9490
9949
  return new Command("clear").description("Unset current session pointer").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
9491
- const projectDir = path25__default.resolve(opts.projectDir);
9950
+ const projectDir = path23__default.resolve(opts.projectDir);
9492
9951
  await clearSession(projectDir);
9493
9952
  logOk("Session cleared.");
9494
9953
  });
@@ -9498,7 +9957,7 @@ function makeReplCommand() {
9498
9957
  const { findWorkspaceRoot } = await import('../core/index.js');
9499
9958
  const { startRepl } = await import('../tui/index.js');
9500
9959
  const os2 = await import('os');
9501
- const userCwd = path25__default.resolve(opts.projectDir ?? process.cwd());
9960
+ const userCwd = path23__default.resolve(opts.projectDir ?? process.cwd());
9502
9961
  const workspaceRoot = findWorkspaceRoot(userCwd);
9503
9962
  let projectDir;
9504
9963
  let agentCwd;
@@ -9520,13 +9979,13 @@ function makeReplCommand() {
9520
9979
  p4.cancel("Cancelled.");
9521
9980
  process.exit(0);
9522
9981
  }
9523
- const tmpDir = fs11__default.mkdtempSync(path25__default.join(os2.tmpdir(), "skaile-repl-"));
9982
+ const tmpDir = fs9__default.mkdtempSync(path23__default.join(os2.tmpdir(), "skaile-repl-"));
9524
9983
  projectDir = tmpDir;
9525
9984
  agentCwd = userCwd;
9526
9985
  logOk(`Temporary workspace: ${S.cmd(tmpDir)}`);
9527
9986
  if (!driverOverride) {
9528
- const claudeDir = path25__default.join(os2.homedir(), ".claude");
9529
- if (fs11__default.existsSync(claudeDir)) {
9987
+ const claudeDir = path23__default.join(os2.homedir(), ".claude");
9988
+ if (fs9__default.existsSync(claudeDir)) {
9530
9989
  driverOverride = "claude-sdk";
9531
9990
  logInfo(`Detected ${S.cmd("~/.claude")} \u2192 using ${S.cmd("claude-sdk")} harness`);
9532
9991
  } else {
@@ -9598,12 +10057,12 @@ function makeServeCommand() {
9598
10057
  );
9599
10058
  }
9600
10059
  async function ensurePluginsLoadedForServe(projectDir) {
9601
- const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-R44RUTDY.js');
10060
+ const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-MWZDRBLD.js');
9602
10061
  try {
9603
10062
  const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
9604
10063
  const config = resolveSkWorkspaceConfig2(projectDir);
9605
10064
  if (!config.plugins || config.plugins.length === 0) return;
9606
- const { ensurePluginsLoaded } = await import('../plugin-store-66QFBNEO.js');
10065
+ const { ensurePluginsLoaded } = await import('../plugin-store-MPAMD5OT.js');
9607
10066
  const { pluginRegistry } = await import('../plugin-registry/index.js');
9608
10067
  const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
9609
10068
  if (result.loaded.length > 0) {
@@ -9617,14 +10076,14 @@ async function ensurePluginsLoadedForServe(projectDir) {
9617
10076
  }
9618
10077
  }
9619
10078
  async function runCompileTest(opts) {
9620
- const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-R44RUTDY.js');
10079
+ const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-MWZDRBLD.js');
9621
10080
  const { tmpdir } = await import('os');
9622
10081
  const { dirname: dirname3, join: join7, resolve: resolve5 } = await import('path');
9623
10082
  const { fileURLToPath: fileURLToPath2 } = await import('url');
9624
10083
  const { unlinkSync, existsSync: existsSync18 } = await import('fs');
9625
10084
  const { spawn } = await import('child_process');
9626
10085
  const { portableSpawnSync: portableSpawnSync2 } = await import('../core/index.js');
9627
- const { MONOREPO_ROOT } = await import('../paths-YUCP7K6U.js');
10086
+ const { MONOREPO_ROOT } = await import('../paths-FQ64OLJG.js');
9628
10087
  if (MONOREPO_ROOT === null) {
9629
10088
  logErr2("--compile-test is only available inside the skaile-dev workspace.");
9630
10089
  logInfo2("Run it from a checkout of skaile-ai/skaile-dev (the monorepo shell).");
@@ -10107,7 +10566,7 @@ function resolveMode2(opts) {
10107
10566
  if (opts.forceLocal && opts.forceRemote) {
10108
10567
  throw new Error("Cannot use both --local and --remote");
10109
10568
  }
10110
- const startDir = path25__default.resolve(opts.projectDir ?? process.cwd());
10569
+ const startDir = path23__default.resolve(opts.projectDir ?? process.cwd());
10111
10570
  const localDb = findLogsDb(startDir);
10112
10571
  if (opts.forceLocal) {
10113
10572
  if (!localDb) {
@@ -10140,14 +10599,14 @@ function resolveMode2(opts) {
10140
10599
  function findLogsDb(startDir) {
10141
10600
  let dir = startDir;
10142
10601
  for (let i = 0; i < MAX_WALK_LEVELS; i++) {
10143
- const candidate = path25__default.join(dir, ".skaile", "logs.db");
10602
+ const candidate = path23__default.join(dir, ".skaile", "logs.db");
10144
10603
  if (existsSync(candidate)) {
10145
10604
  try {
10146
10605
  if (statSync(candidate).isFile()) return candidate;
10147
10606
  } catch {
10148
10607
  }
10149
10608
  }
10150
- const parent = path25__default.dirname(dir);
10609
+ const parent = path23__default.dirname(dir);
10151
10610
  if (parent === dir) return void 0;
10152
10611
  dir = parent;
10153
10612
  }
@@ -10322,7 +10781,7 @@ function parsePositiveInt(value, flag) {
10322
10781
  function makeSessionCommand() {
10323
10782
  const cmd = new Command("session").description("Manage sessions");
10324
10783
  cmd.command("list").description("List all sessions for a project").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
10325
- const projectDir = path25__default.resolve(opts.projectDir);
10784
+ const projectDir = path23__default.resolve(opts.projectDir);
10326
10785
  const sessions = await listSessions(projectDir);
10327
10786
  const current = await loadSession(projectDir);
10328
10787
  if (sessions.length === 0) {
@@ -10350,7 +10809,7 @@ function makeSessionCommand() {
10350
10809
  console.log();
10351
10810
  });
10352
10811
  cmd.command("show <run-id>").description("Show a specific session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
10353
- const projectDir = path25__default.resolve(opts.projectDir);
10812
+ const projectDir = path23__default.resolve(opts.projectDir);
10354
10813
  const session = await loadSessionById(projectDir, runId);
10355
10814
  if (!session) {
10356
10815
  logErr(`Session not found: ${runId}`);
@@ -10359,12 +10818,20 @@ function makeSessionCommand() {
10359
10818
  console.log(JSON.stringify(session, null, 2));
10360
10819
  });
10361
10820
  cmd.command("switch <run-id>").description("Switch the current session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
10362
- const projectDir = path25__default.resolve(opts.projectDir);
10821
+ const projectDir = path23__default.resolve(opts.projectDir);
10822
+ if (!await loadSessionById(projectDir, runId)) {
10823
+ logErr(`Session not found: ${runId}`);
10824
+ process.exit(1);
10825
+ }
10363
10826
  await setCurrentSession(projectDir, runId);
10364
10827
  logOk(`Switched to session: ${S.dim(runId.slice(0, 8))}`);
10365
10828
  });
10366
10829
  cmd.command("delete <run-id>").description("Delete a session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
10367
- const projectDir = path25__default.resolve(opts.projectDir);
10830
+ const projectDir = path23__default.resolve(opts.projectDir);
10831
+ if (!await loadSessionById(projectDir, runId)) {
10832
+ logErr(`Session not found: ${runId}`);
10833
+ process.exit(1);
10834
+ }
10368
10835
  await deleteSession(projectDir, runId);
10369
10836
  logOk(`Deleted session: ${S.dim(runId.slice(0, 8))}`);
10370
10837
  });
@@ -10418,12 +10885,12 @@ function showOverview(am2) {
10418
10885
  }
10419
10886
  async function showAsset(am2, kind, name) {
10420
10887
  const entry = await am2.info(`${kind}:${name}`);
10421
- if (entry?.source && fs11__default.existsSync(entry.source)) {
10888
+ if (entry?.source && fs9__default.existsSync(entry.source)) {
10422
10889
  console.log();
10423
10890
  console.log(` ${kindColor(entry.kind)} ${S.heading(entry.name)}`);
10424
10891
  console.log(` ${S.rule(40)}`);
10425
10892
  console.log();
10426
- console.log(fs11__default.readFileSync(entry.source, "utf-8"));
10893
+ console.log(fs9__default.readFileSync(entry.source, "utf-8"));
10427
10894
  return;
10428
10895
  }
10429
10896
  logErr(`Asset not found: ${kind}:${name}`);
@@ -10433,7 +10900,7 @@ function makeShowCommand() {
10433
10900
  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) => {
10434
10901
  const am2 = new AssetManager({
10435
10902
  registry: getKindRegistry(),
10436
- projectDir: path25__default.resolve(opts.projectDir),
10903
+ projectDir: path23__default.resolve(opts.projectDir),
10437
10904
  driverTarget: opts.target
10438
10905
  });
10439
10906
  if (!kind) {
@@ -10496,14 +10963,14 @@ function makeStoreCommand() {
10496
10963
  });
10497
10964
  store.command("mode <auto|local|remote>").description("Set the catalog resolution mode (not yet wired)").action((_mode) => {
10498
10965
  logErr(
10499
- `\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${path25__default.join(globalSkaileDir(), "store", "config.yaml")}.`
10966
+ `\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${path23__default.join(globalSkaileDir(), "store", "config.yaml")}.`
10500
10967
  );
10501
10968
  process.exit(2);
10502
10969
  });
10503
10970
  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) => {
10504
- const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-4WUMQHES.js');
10971
+ const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-OG457THY.js');
10505
10972
  try {
10506
- const remote = await openCatalogSource2({ projectDir: path25__default.resolve(opts.projectDir) });
10973
+ const remote = await openCatalogSource2({ projectDir: path23__default.resolve(opts.projectDir) });
10507
10974
  const assets = await remote.listAssets(opts.kind ? { kind: opts.kind } : {});
10508
10975
  const results = filterCatalogAssets(assets, query);
10509
10976
  if (results.length === 0) {
@@ -10518,7 +10985,7 @@ function makeStoreCommand() {
10518
10985
  `
10519
10986
  );
10520
10987
  } catch (e) {
10521
- if (e instanceof LocalCatalogDisabledError) {
10988
+ if (e instanceof LocalCatalogDisabledError2) {
10522
10989
  logErr(
10523
10990
  `Remote catalog disabled (catalog.url: local). Set \`catalog.url: https://skaile.store\` in ${userConfigPath()}.`
10524
10991
  );
@@ -10529,10 +10996,10 @@ function makeStoreCommand() {
10529
10996
  }
10530
10997
  });
10531
10998
  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) => {
10532
- const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-4WUMQHES.js');
10533
- const { supportsInstallManifest } = await import('../project-VMOHUXBD.js');
10999
+ const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-OG457THY.js');
11000
+ const { supportsInstallManifest } = await import('../project-2GFT5LEZ.js');
10534
11001
  try {
10535
- const remote = await openCatalogSource2({ projectDir: path25__default.resolve(opts.projectDir) });
11002
+ const remote = await openCatalogSource2({ projectDir: path23__default.resolve(opts.projectDir) });
10536
11003
  const asset = await remote.resolve(ref);
10537
11004
  if (!asset) {
10538
11005
  logErr(`Not found in store: ${ref} (try a full ref, e.g. skill:@publisher/name#version)`);
@@ -10580,7 +11047,7 @@ function makeStoreCommand() {
10580
11047
  console.log(` ${S.dim(`Install: skaile add ${canonical}`)}`);
10581
11048
  console.log();
10582
11049
  } catch (e) {
10583
- if (e instanceof LocalCatalogDisabledError) {
11050
+ if (e instanceof LocalCatalogDisabledError2) {
10584
11051
  logErr(
10585
11052
  `Remote catalog disabled (catalog.url: local). Set \`catalog.url: https://skaile.store\` in ${userConfigPath()}.`
10586
11053
  );
@@ -10643,29 +11110,31 @@ function makeStoreCommand() {
10643
11110
  });
10644
11111
  return store;
10645
11112
  }
10646
- function printTree(node, prefix = "", isLast = true) {
10647
- const connector = prefix === "" ? "" : isLast ? "\u2514\u2500 " : "\u251C\u2500 ";
10648
- const line = prefix + connector + colorRef(node.ref);
10649
- console.log(` ${line}`);
10650
- const childPrefix = prefix + (prefix === "" ? "" : isLast ? " " : "\u2502 ");
10651
- for (let i = 0; i < node.children.length; i++) {
10652
- printTree(node.children[i], childPrefix, i === node.children.length - 1);
10653
- }
11113
+ function printChildren(nodes, prefix) {
11114
+ nodes.forEach((node, i) => {
11115
+ const isLast = i === nodes.length - 1;
11116
+ console.log(` ${prefix}${isLast ? "\u2514\u2500 " : "\u251C\u2500 "}${colorRef(node.ref)}`);
11117
+ printChildren(node.children, prefix + (isLast ? " " : "\u2502 "));
11118
+ });
11119
+ }
11120
+ function treeRefs(nodes) {
11121
+ return [...new Set(nodes.flatMap((n) => [n.ref, ...treeRefs(n.children)]))];
10654
11122
  }
10655
11123
  function makeTreeCommand() {
10656
11124
  return new Command("tree").description("Show full dependency tree").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
10657
11125
  const am2 = new AssetManager({
10658
11126
  registry: getKindRegistry(),
10659
- projectDir: path25__default.resolve(opts.projectDir)
11127
+ projectDir: path23__default.resolve(opts.projectDir)
10660
11128
  });
10661
- const root = am2.tree();
11129
+ const root = await am2.tree();
10662
11130
  if (root.children.length === 0) {
10663
11131
  logInfo("No dependencies in lock file. Run `skaile install` first.");
10664
11132
  return;
10665
11133
  }
10666
11134
  console.log();
10667
- printTree(root);
10668
- const softDeps = await am2.softDepsOf(root.children.map((c) => c.ref));
11135
+ console.log(` ${colorRef(root.ref)}`);
11136
+ printChildren(root.children, "");
11137
+ const softDeps = await am2.softDepsOf(treeRefs(root.children));
10669
11138
  if (softDeps.length > 0) {
10670
11139
  console.log(` ${S.label("Soft dependencies (inferred)")}:`);
10671
11140
  for (const e of softDeps)
@@ -10683,20 +11152,24 @@ function makeUpdateCommand() {
10683
11152
  const catalogSpinner = createSpinner();
10684
11153
  catalogSpinner.start("Refreshing catalog cache");
10685
11154
  try {
10686
- const remote = await openCatalogSource({ projectDir: path25__default.resolve(opts.projectDir) });
11155
+ const remote = await openCatalogSource({ projectDir: path23__default.resolve(opts.projectDir) });
10687
11156
  const result2 = await remote.refresh();
10688
11157
  catalogSpinner.stop(
10689
11158
  `Catalog refreshed: ${S.heading(String(result2.assetsCached))} assets cached`
10690
11159
  );
10691
11160
  logInfo(`Source: ${remote.baseUrl}`);
10692
11161
  } catch (err2) {
10693
- catalogSpinner.stop("Catalog refresh failed");
10694
- logErr(`Catalog refresh failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
10695
- logInfo("Continuing with asset re-deploy. Run `skaile catalog test` to debug.");
11162
+ if (err2 instanceof LocalCatalogDisabledError) {
11163
+ catalogSpinner.stop("Catalog refresh skipped (catalog.url: local)");
11164
+ } else {
11165
+ catalogSpinner.stop("Catalog refresh failed");
11166
+ logErr(`Catalog refresh failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
11167
+ logInfo("Continuing with asset re-deploy. Run `skaile catalog test` to debug.");
11168
+ }
10696
11169
  }
10697
11170
  }
10698
11171
  if (opts.catalogOnly) return;
10699
- const projectDir = path25__default.resolve(opts.projectDir);
11172
+ const projectDir = path23__default.resolve(opts.projectDir);
10700
11173
  if (await shouldSyncSources(opts)) {
10701
11174
  const syncSpinner = createSpinner();
10702
11175
  syncSpinner.start("Syncing sources");
@@ -10704,6 +11177,7 @@ function makeUpdateCommand() {
10704
11177
  syncSpinner.stop(
10705
11178
  total === 0 ? "No sources to sync." : `Synced ${S.heading(`${synced}/${total}`)} source(s)` + (failed ? ` (${failed} failed)` : "")
10706
11179
  );
11180
+ if (failed > 0) process.exitCode = 1;
10707
11181
  }
10708
11182
  const warnings = deferredWarnings();
10709
11183
  const am2 = new AssetManager({
@@ -10726,7 +11200,17 @@ function makeUpdateCommand() {
10726
11200
  warnings.flush();
10727
11201
  if (result.deployed.length > 0) {
10728
11202
  for (const d of result.deployed) logOk(`Updated ${d}`);
10729
- } else {
11203
+ }
11204
+ for (const r of result.removed) logWarn(`Removed: ${r}`);
11205
+ reportRelocked(result.relocked);
11206
+ const changed = result.deployed.length > 0 || result.removed.length > 0 || !!result.relocked?.length;
11207
+ if (result.lockWritten && changed) {
11208
+ logInfo(`Lock file written: ${S.dim("skaile.lock.yaml")}`);
11209
+ }
11210
+ if (result.missing.length > 0) {
11211
+ for (const m of result.missing) logErr(`Missing: ${m}${result.missingHints?.[m] ?? ""}`);
11212
+ process.exitCode = 1;
11213
+ } else if (!changed) {
10730
11214
  logInfo("Nothing to update.");
10731
11215
  }
10732
11216
  }
@@ -10840,9 +11324,9 @@ function makeWhyCommand() {
10840
11324
  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) => {
10841
11325
  const am2 = new AssetManager({
10842
11326
  registry: getKindRegistry(),
10843
- projectDir: path25__default.resolve(opts.projectDir)
11327
+ projectDir: path23__default.resolve(opts.projectDir)
10844
11328
  });
10845
- const chain = am2.why(ref);
11329
+ const chain = await am2.why(ref);
10846
11330
  if (chain.length === 0) {
10847
11331
  let declared;
10848
11332
  try {
@@ -10875,10 +11359,19 @@ function makeWhyCommand() {
10875
11359
  var _defaultFormatHelp = Help.prototype.formatHelp;
10876
11360
  var pkg = JSON.parse(
10877
11361
  readFileSync(
10878
- path25__default.resolve(path25__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
11362
+ path23__default.resolve(path23__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
10879
11363
  "utf-8"
10880
11364
  )
10881
11365
  );
11366
+ for (const key of [
11367
+ "SKAILE_HOME",
11368
+ "SKAILE_INDEX_PATH",
11369
+ "SKAILE_LIBRARIES_DIR",
11370
+ "SKAILE_CACHE_DIR"
11371
+ ]) {
11372
+ const value = process.env[key];
11373
+ if (value) process.env[key] = path23__default.resolve(value);
11374
+ }
10882
11375
  var program = new Command("skaile").description("AI asset manager").version(pkg.version, "-v, --version", "Show the skaile CLI version").enablePositionalOptions().configureHelp({
10883
11376
  formatHelp(cmd, helper) {
10884
11377
  if (cmd.name() !== "skaile") return _defaultFormatHelp.call(helper, cmd, helper);
@@ -10938,7 +11431,7 @@ Execution:
10938
11431
  debug tools|connectors|mcp|config|state Inspect running container state
10939
11432
  connect <url> Interactive WebSocket REPL
10940
11433
  logs [--follow] [--filter] Tail skaile container logs
10941
- session list|show|switch|del Session management
11434
+ session list|show|switch|delete Session management
10942
11435
  status Current session state
10943
11436
  clear Unset current session
10944
11437
 
@@ -11006,31 +11499,31 @@ async function runInit(projectDir, opts) {
11006
11499
  process.exitCode = 1;
11007
11500
  return;
11008
11501
  }
11009
- const resolved = path25__default.resolve(projectDir ?? ".");
11010
- const projectName = path25__default.basename(resolved);
11502
+ const resolved = path23__default.resolve(projectDir ?? ".");
11503
+ const projectName = path23__default.basename(resolved);
11011
11504
  const created = [];
11012
11505
  const { existsSync: existsSync18 } = await import('fs');
11013
11506
  if (!existsSync18(resolved)) {
11014
11507
  mkdirSync5(resolved, { recursive: true });
11015
11508
  created.push(".");
11016
11509
  }
11017
- const skaileDir = path25__default.join(resolved, ".skaile");
11510
+ const skaileDir = path23__default.join(resolved, ".skaile");
11018
11511
  if (!existsSync18(skaileDir)) {
11019
- mkdirSync5(path25__default.join(skaileDir, "sessions"), { recursive: true });
11512
+ mkdirSync5(path23__default.join(skaileDir, "sessions"), { recursive: true });
11020
11513
  created.push(".skaile/");
11021
11514
  }
11022
- const settingsPath = path25__default.join(skaileDir, "settings.json");
11515
+ const settingsPath = path23__default.join(skaileDir, "settings.json");
11023
11516
  if (!existsSync18(settingsPath)) {
11024
11517
  writeFileSync7(settingsPath, "{}\n");
11025
11518
  created.push(".skaile/settings.json");
11026
11519
  }
11027
- const wsConfigPath = path25__default.join(resolved, "skaile.yaml");
11520
+ const wsConfigPath = path23__default.join(resolved, "skaile.yaml");
11028
11521
  if (!existsSync18(wsConfigPath)) {
11029
11522
  writeFileSync7(wsConfigPath, stringify2(buildInitWorkspaceConfig(projectName, harness)));
11030
11523
  created.push("skaile.yaml");
11031
11524
  }
11032
11525
  for (const dir of new Set(Object.values(DRIVER_TARGETS[harness].local))) {
11033
- const full = path25__default.join(resolved, dir);
11526
+ const full = path23__default.join(resolved, dir);
11034
11527
  if (!existsSync18(full)) {
11035
11528
  mkdirSync5(full, { recursive: true });
11036
11529
  created.push(`${dir}/`);
@@ -11060,9 +11553,9 @@ function buildInitWorkspaceConfig(projectName, harness) {
11060
11553
  };
11061
11554
  }
11062
11555
  async function initGitScaffold(resolved, created) {
11063
- const { execSync: execSync3 } = await import('child_process');
11556
+ const { execSync: execSync2 } = await import('child_process');
11064
11557
  const { existsSync: existsSync18, readFileSync: readFileSync10, writeFileSync: writeFileSync7 } = await import('fs');
11065
- const gitignorePath = path25__default.join(resolved, ".gitignore");
11558
+ const gitignorePath = path23__default.join(resolved, ".gitignore");
11066
11559
  const entries = [
11067
11560
  "node_modules/",
11068
11561
  ".skaile/sessions/",
@@ -11088,9 +11581,9 @@ async function initGitScaffold(resolved, created) {
11088
11581
  `);
11089
11582
  if (!existing) created.push(".gitignore");
11090
11583
  }
11091
- if (!existsSync18(path25__default.join(resolved, ".git"))) {
11584
+ if (!existsSync18(path23__default.join(resolved, ".git"))) {
11092
11585
  try {
11093
- execSync3("git init", { cwd: resolved, stdio: "pipe" });
11586
+ execSync2("git init", { cwd: resolved, stdio: "pipe" });
11094
11587
  created.push(".git/");
11095
11588
  } catch (err2) {
11096
11589
  const msg = err2 instanceof Error ? err2.message : String(err2);
@@ -11118,7 +11611,7 @@ async function bootstrapUserConfig() {
11118
11611
  }
11119
11612
  async function hydrateInitSources(resolved, created) {
11120
11613
  try {
11121
- const { ensureSourcesCloned } = await import('../ensure-sources-DSTSXJWK.js');
11614
+ const { ensureSourcesCloned } = await import('../ensure-sources-SKLNM4UZ.js');
11122
11615
  const hydrate = ensureSourcesCloned(resolved, { quiet: true });
11123
11616
  for (const n of hydrate.cloned) created.push(`~/.skaile/cache/sources/${n}/`);
11124
11617
  if (hydrate.failed.length > 0) {
@@ -11134,7 +11627,7 @@ function printInitSummary(resolved, projectDir, created) {
11134
11627
  logOk(`Initialized project at ${S.heading(resolved)}`);
11135
11628
  console.log();
11136
11629
  console.log(S.heading(" Next steps:"));
11137
- const isCurrentDir = resolved === path25__default.resolve(".");
11630
+ const isCurrentDir = resolved === path23__default.resolve(".");
11138
11631
  let step = 1;
11139
11632
  if (!isCurrentDir) {
11140
11633
  console.log(` ${S.dim(`${step}.`)} ${S.cmd(`cd ${projectDir}`)}`);
@@ -11158,7 +11651,7 @@ function printInitSummary(resolved, projectDir, created) {
11158
11651
  console.log();
11159
11652
  }
11160
11653
  program.command("setup").description("Interactive provider setup wizard").action(async () => {
11161
- const { cmdSetup } = await import('../setup-PYY23HGZ.js');
11654
+ const { cmdSetup } = await import('../setup-WHMCSIF2.js');
11162
11655
  await cmdSetup([], { projectDir: process.cwd() });
11163
11656
  });
11164
11657
  program.addCommand(makeInstallCommand());
@@ -11232,6 +11725,10 @@ program.command("path").description("Show resolved paths (honours SKAILE_HOME an
11232
11725
  console.log();
11233
11726
  });
11234
11727
  program.addCommand(makeCompleteCommand(program));
11728
+ process.stdout.on("error", (err2) => {
11729
+ if (err2.code === "EPIPE") process.exit(0);
11730
+ throw err2;
11731
+ });
11235
11732
  try {
11236
11733
  await program.parseAsync();
11237
11734
  } catch (err2) {