@skaile/workspaces 5.6.1 → 5.7.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 (260) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +4 -2
  3. package/dist/{asset-feeds-LU7NHOAP.js → asset-feeds-K36CR52Q.js} +17 -17
  4. package/dist/{asset-feeds-LU7NHOAP.js.map → asset-feeds-K36CR52Q.js.map} +1 -1
  5. package/dist/asset-manager/catalog-deployer.js +9 -9
  6. package/dist/asset-manager/index.js +14 -14
  7. package/dist/asset-manager/installer.js +10 -10
  8. package/dist/asset-manager/renderers.js +9 -9
  9. package/dist/asset-manager/src/index.d.ts +106 -16
  10. package/dist/asset-manager/src/index.d.ts.map +1 -1
  11. package/dist/asset-manager/src/installer.d.ts +4 -1
  12. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  13. package/dist/bridge/drivers/claude-sdk.js +11 -11
  14. package/dist/bridge/drivers/codex.js +10 -10
  15. package/dist/bridge/drivers/continue.js +12 -12
  16. package/dist/bridge/drivers/echo.js +1 -1
  17. package/dist/bridge/drivers/gemini.js +5 -5
  18. package/dist/bridge/drivers/goose.js +12 -12
  19. package/dist/bridge/drivers/omp.js +2 -2
  20. package/dist/bridge/drivers/opencode.js +12 -12
  21. package/dist/bridge/drivers/qwen.js +5 -5
  22. package/dist/bridge/index.js +12 -12
  23. package/dist/{chunk-VX3INFBA.js → chunk-34C42MJX.js} +3 -3
  24. package/dist/{chunk-VX3INFBA.js.map → chunk-34C42MJX.js.map} +1 -1
  25. package/dist/{chunk-QD772CGQ.js → chunk-53MSCGR2.js} +5 -5
  26. package/dist/{chunk-QD772CGQ.js.map → chunk-53MSCGR2.js.map} +1 -1
  27. package/dist/chunk-6C654TFI.js +84 -0
  28. package/dist/chunk-6C654TFI.js.map +1 -0
  29. package/dist/{chunk-6NPINANG.js → chunk-6UFFKMVC.js} +5 -5
  30. package/dist/{chunk-6NPINANG.js.map → chunk-6UFFKMVC.js.map} +1 -1
  31. package/dist/{chunk-XOGG7VDZ.js → chunk-6VRJH4MR.js} +16 -24
  32. package/dist/chunk-6VRJH4MR.js.map +1 -0
  33. package/dist/{chunk-2KOKBTR4.js → chunk-74EEFB52.js} +15 -8
  34. package/dist/chunk-74EEFB52.js.map +1 -0
  35. package/dist/{chunk-OGLDAJFL.js → chunk-7FJQT3GT.js} +4 -4
  36. package/dist/{chunk-OGLDAJFL.js.map → chunk-7FJQT3GT.js.map} +1 -1
  37. package/dist/{chunk-VKSXST23.js → chunk-AVCUPPG6.js} +3 -3
  38. package/dist/{chunk-VKSXST23.js.map → chunk-AVCUPPG6.js.map} +1 -1
  39. package/dist/{chunk-5B5IZVEP.js → chunk-BTK7ECLH.js} +2 -2
  40. package/dist/{chunk-5B5IZVEP.js.map → chunk-BTK7ECLH.js.map} +1 -1
  41. package/dist/{chunk-GP6ZL7PE.js → chunk-BWZF2ZIF.js} +3 -3
  42. package/dist/{chunk-GP6ZL7PE.js.map → chunk-BWZF2ZIF.js.map} +1 -1
  43. package/dist/{chunk-PJS2YWGG.js → chunk-CWM3MYGX.js} +6 -6
  44. package/dist/{chunk-PJS2YWGG.js.map → chunk-CWM3MYGX.js.map} +1 -1
  45. package/dist/{chunk-PTO2YDDG.js → chunk-D5HOETOB.js} +410 -96
  46. package/dist/chunk-D5HOETOB.js.map +1 -0
  47. package/dist/{chunk-MX3UQXLU.js → chunk-DFFD4BFG.js} +96 -20
  48. package/dist/chunk-DFFD4BFG.js.map +1 -0
  49. package/dist/{chunk-KXTO7HON.js → chunk-EAZECHPM.js} +3 -3
  50. package/dist/{chunk-KXTO7HON.js.map → chunk-EAZECHPM.js.map} +1 -1
  51. package/dist/{chunk-ZBBM6O6P.js → chunk-EB4XN3KE.js} +3 -3
  52. package/dist/{chunk-ZBBM6O6P.js.map → chunk-EB4XN3KE.js.map} +1 -1
  53. package/dist/{chunk-WIHQWVWL.js → chunk-EU3Q5AQ4.js} +26 -18
  54. package/dist/chunk-EU3Q5AQ4.js.map +1 -0
  55. package/dist/{chunk-BTISGSK4.js → chunk-FAP63KV7.js} +4 -4
  56. package/dist/{chunk-BTISGSK4.js.map → chunk-FAP63KV7.js.map} +1 -1
  57. package/dist/{chunk-46OVMT76.js → chunk-G67BOI2J.js} +3 -3
  58. package/dist/{chunk-46OVMT76.js.map → chunk-G67BOI2J.js.map} +1 -1
  59. package/dist/{chunk-I4QBZLOR.js → chunk-GIC3G5YG.js} +6 -6
  60. package/dist/{chunk-I4QBZLOR.js.map → chunk-GIC3G5YG.js.map} +1 -1
  61. package/dist/{chunk-27HS2DHB.js → chunk-GWXFSLBK.js} +3 -3
  62. package/dist/{chunk-27HS2DHB.js.map → chunk-GWXFSLBK.js.map} +1 -1
  63. package/dist/{chunk-VSQFGU5D.js → chunk-ILFGVSTJ.js} +3 -3
  64. package/dist/{chunk-VSQFGU5D.js.map → chunk-ILFGVSTJ.js.map} +1 -1
  65. package/dist/{chunk-KYXOGHY6.js → chunk-IUUYRXT6.js} +4 -4
  66. package/dist/{chunk-KYXOGHY6.js.map → chunk-IUUYRXT6.js.map} +1 -1
  67. package/dist/{chunk-D2V42LUE.js → chunk-IZLQ4GDO.js} +63 -44
  68. package/dist/chunk-IZLQ4GDO.js.map +1 -0
  69. package/dist/{chunk-LLKKLKZJ.js → chunk-JLSCA5T5.js} +3 -3
  70. package/dist/{chunk-LLKKLKZJ.js.map → chunk-JLSCA5T5.js.map} +1 -1
  71. package/dist/{chunk-SX4UIDKT.js → chunk-KM7XWC4Y.js} +3 -3
  72. package/dist/{chunk-SX4UIDKT.js.map → chunk-KM7XWC4Y.js.map} +1 -1
  73. package/dist/{chunk-KUFNKVBM.js → chunk-KNWCFEWU.js} +3 -3
  74. package/dist/{chunk-KUFNKVBM.js.map → chunk-KNWCFEWU.js.map} +1 -1
  75. package/dist/{chunk-MFHKHXDE.js → chunk-L5VSIPQD.js} +5 -5
  76. package/dist/chunk-L5VSIPQD.js.map +1 -0
  77. package/dist/{chunk-AOAZCSDI.js → chunk-LBQ4BBX4.js} +3 -3
  78. package/dist/{chunk-AOAZCSDI.js.map → chunk-LBQ4BBX4.js.map} +1 -1
  79. package/dist/{chunk-2W4LBLIN.js → chunk-LCU5U5IW.js} +6 -6
  80. package/dist/{chunk-2W4LBLIN.js.map → chunk-LCU5U5IW.js.map} +1 -1
  81. package/dist/{chunk-65EYRFZJ.js → chunk-LXY4BUA3.js} +5 -5
  82. package/dist/{chunk-65EYRFZJ.js.map → chunk-LXY4BUA3.js.map} +1 -1
  83. package/dist/{chunk-7KLC4LZO.js → chunk-MKLBK7HI.js} +8 -8
  84. package/dist/{chunk-7KLC4LZO.js.map → chunk-MKLBK7HI.js.map} +1 -1
  85. package/dist/{chunk-4GNJELPH.js → chunk-N6FBTXQ5.js} +2 -2
  86. package/dist/{chunk-4GNJELPH.js.map → chunk-N6FBTXQ5.js.map} +1 -1
  87. package/dist/{chunk-2XFUXGV6.js → chunk-NWQB7UTY.js} +3 -3
  88. package/dist/{chunk-2XFUXGV6.js.map → chunk-NWQB7UTY.js.map} +1 -1
  89. package/dist/{chunk-SDFROXSA.js → chunk-O4Z7MAW7.js} +3 -3
  90. package/dist/{chunk-SDFROXSA.js.map → chunk-O4Z7MAW7.js.map} +1 -1
  91. package/dist/{chunk-AO7VJ6G6.js → chunk-O7VPNKYN.js} +8 -3
  92. package/dist/chunk-O7VPNKYN.js.map +1 -0
  93. package/dist/{chunk-TZCQ7ZWQ.js → chunk-OOLT6HGP.js} +10 -11
  94. package/dist/chunk-OOLT6HGP.js.map +1 -0
  95. package/dist/{chunk-2GRB5ITE.js → chunk-PSA6ONFB.js} +4 -4
  96. package/dist/{chunk-2GRB5ITE.js.map → chunk-PSA6ONFB.js.map} +1 -1
  97. package/dist/{chunk-45VFGT7A.js → chunk-RNPHRRLG.js} +3 -3
  98. package/dist/{chunk-45VFGT7A.js.map → chunk-RNPHRRLG.js.map} +1 -1
  99. package/dist/{chunk-7ZHLYXTI.js → chunk-RVIZQ5XD.js} +3 -3
  100. package/dist/{chunk-7ZHLYXTI.js.map → chunk-RVIZQ5XD.js.map} +1 -1
  101. package/dist/{chunk-BF33SCLY.js → chunk-SWO25LTO.js} +4 -4
  102. package/dist/{chunk-BF33SCLY.js.map → chunk-SWO25LTO.js.map} +1 -1
  103. package/dist/{chunk-UAP2XHRF.js → chunk-SZWRPEF7.js} +8 -8
  104. package/dist/{chunk-UAP2XHRF.js.map → chunk-SZWRPEF7.js.map} +1 -1
  105. package/dist/{chunk-VJENKWXF.js → chunk-THEJJBOU.js} +3 -3
  106. package/dist/{chunk-VJENKWXF.js.map → chunk-THEJJBOU.js.map} +1 -1
  107. package/dist/{chunk-PA7WLID3.js → chunk-TTPSDC2G.js} +33 -3
  108. package/dist/chunk-TTPSDC2G.js.map +1 -0
  109. package/dist/{chunk-VBBBZDI7.js → chunk-UX3K4RKE.js} +3 -3
  110. package/dist/{chunk-VBBBZDI7.js.map → chunk-UX3K4RKE.js.map} +1 -1
  111. package/dist/{chunk-RGXVQZOV.js → chunk-VOOI7B2L.js} +23 -21
  112. package/dist/chunk-VOOI7B2L.js.map +1 -0
  113. package/dist/{chunk-OLLAQLFJ.js → chunk-WIEC3ZE4.js} +5 -5
  114. package/dist/{chunk-OLLAQLFJ.js.map → chunk-WIEC3ZE4.js.map} +1 -1
  115. package/dist/cli/index.js +901 -589
  116. package/dist/cli/index.js.map +1 -1
  117. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  118. package/dist/cli/src/commands/catalog.d.ts +12 -3
  119. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  120. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  121. package/dist/cli/src/commands/library-index.d.ts +41 -4
  122. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  123. package/dist/cli/src/commands/library-publish.d.ts +9 -0
  124. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  125. package/dist/cli/src/commands/manage.d.ts +8 -2
  126. package/dist/cli/src/commands/manage.d.ts.map +1 -1
  127. package/dist/cli/src/commands/outdated.d.ts +3 -2
  128. package/dist/cli/src/commands/outdated.d.ts.map +1 -1
  129. package/dist/cli/src/commands/project.d.ts +13 -4
  130. package/dist/cli/src/commands/project.d.ts.map +1 -1
  131. package/dist/cli/src/commands/source.d.ts +4 -3
  132. package/dist/cli/src/commands/source.d.ts.map +1 -1
  133. package/dist/cli/src/commands/update.d.ts +1 -1
  134. package/dist/cli/src/commands/update.d.ts.map +1 -1
  135. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  136. package/dist/cli/src/skill-checks.d.ts +21 -10
  137. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  138. package/dist/connectors/config.js +6 -6
  139. package/dist/connectors/index.js +15 -15
  140. package/dist/{connectors-HWENZFKW.js → connectors-SSOTIDHT.js} +18 -18
  141. package/dist/{connectors-HWENZFKW.js.map → connectors-SSOTIDHT.js.map} +1 -1
  142. package/dist/core/index.js +8 -8
  143. package/dist/core/manifest.js +2 -2
  144. package/dist/core/models.js +1 -1
  145. package/dist/core/publish-manifest.js +2 -2
  146. package/dist/core/ref.js +1 -1
  147. package/dist/core/runtime-assets.js +6 -6
  148. package/dist/core/src/cache-paths.d.ts.map +1 -1
  149. package/dist/core/src/index.d.ts +1 -1
  150. package/dist/core/src/index.d.ts.map +1 -1
  151. package/dist/core/src/lock.d.ts +3 -3
  152. package/dist/core/src/lock.d.ts.map +1 -1
  153. package/dist/core/src/manifest.d.ts +6 -1
  154. package/dist/core/src/manifest.d.ts.map +1 -1
  155. package/dist/core/src/models.d.ts +8 -0
  156. package/dist/core/src/models.d.ts.map +1 -1
  157. package/dist/core/store.js +2 -2
  158. package/dist/core/workspace-config.js +5 -5
  159. package/dist/deploy/index.js +8 -8
  160. package/dist/discovery/index.js +4 -4
  161. package/dist/discovery/src/index.d.ts +1 -1
  162. package/dist/discovery/src/index.d.ts.map +1 -1
  163. package/dist/discovery/src/source-config.d.ts +12 -0
  164. package/dist/discovery/src/source-config.d.ts.map +1 -1
  165. package/dist/discovery/src/tree-entries.d.ts.map +1 -1
  166. package/dist/{ensure-sources-DSTSXJWK.js → ensure-sources-277VI7R3.js} +17 -17
  167. package/dist/{ensure-sources-DSTSXJWK.js.map → ensure-sources-277VI7R3.js.map} +1 -1
  168. package/dist/factory-assets/connectors/box.js +15 -15
  169. package/dist/factory-assets/connectors/deploy.js +15 -15
  170. package/dist/factory-assets/connectors/devserver.js +15 -15
  171. package/dist/factory-assets/connectors/flow/adapter.js +15 -15
  172. package/dist/factory-assets/connectors/flow/engine.js +9 -9
  173. package/dist/factory-assets/connectors/flow/run-flow.js +17 -17
  174. package/dist/factory-assets/connectors/flow.js +15 -15
  175. package/dist/factory-assets/connectors/git.js +15 -15
  176. package/dist/factory-assets/connectors/gmail.js +15 -15
  177. package/dist/factory-assets/connectors/googledrive.js +15 -15
  178. package/dist/factory-assets/connectors/local.js +15 -15
  179. package/dist/factory-assets/connectors/mattermost.js +15 -15
  180. package/dist/factory-assets/connectors/memory.js +15 -15
  181. package/dist/factory-assets/connectors/minio.js +15 -15
  182. package/dist/factory-assets/connectors/postgres.js +15 -15
  183. package/dist/factory-assets/connectors/s3.js +15 -15
  184. package/dist/factory-assets/connectors/sharepoint.js +15 -15
  185. package/dist/factory-assets/connectors/sqlite.js +15 -15
  186. package/dist/factory-assets/connectors/static-server.js +15 -15
  187. package/dist/factory-assets/connectors/tunnel.js +15 -15
  188. package/dist/factory-assets/connectors/webdav.js +15 -15
  189. package/dist/factory-assets/connectors/xstate-store.js +15 -15
  190. package/dist/factory-assets/connectors/xstate.js +15 -15
  191. package/dist/{flows-ENQY2DV7.js → flows-J2UEU2QM.js} +13 -13
  192. package/dist/{flows-ENQY2DV7.js.map → flows-J2UEU2QM.js.map} +1 -1
  193. package/dist/{helpers-R44RUTDY.js → helpers-KC5O7CML.js} +17 -17
  194. package/dist/{helpers-R44RUTDY.js.map → helpers-KC5O7CML.js.map} +1 -1
  195. package/dist/library/index.js +11 -11
  196. package/dist/library/install.js +3 -3
  197. package/dist/library/src/index.d.ts +3 -3
  198. package/dist/library/src/index.d.ts.map +1 -1
  199. package/dist/library/src/local/library-manager.d.ts +6 -0
  200. package/dist/library/src/local/library-manager.d.ts.map +1 -1
  201. package/dist/library/src/local/local-catalog-source.d.ts +5 -2
  202. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  203. package/dist/library/src/manifest-writer.d.ts +23 -1
  204. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  205. package/dist/library/src/sync/git-driver.d.ts +12 -0
  206. package/dist/library/src/sync/git-driver.d.ts.map +1 -1
  207. package/dist/{library-publish-LFOJJVMK.js → library-publish-FGXF5TJO.js} +85 -41
  208. package/dist/library-publish-FGXF5TJO.js.map +1 -0
  209. package/dist/{open-library-4WUMQHES.js → open-library-P3D337NH.js} +20 -20
  210. package/dist/{open-library-4WUMQHES.js.map → open-library-P3D337NH.js.map} +1 -1
  211. package/dist/open-registry-Z3P2X2AB.js +32 -0
  212. package/dist/{open-registry-NVPCQPND.js.map → open-registry-Z3P2X2AB.js.map} +1 -1
  213. package/dist/paths-JKEKXM52.js +22 -0
  214. package/dist/{paths-YUCP7K6U.js.map → paths-JKEKXM52.js.map} +1 -1
  215. package/dist/{plugin-store-66QFBNEO.js → plugin-store-WI4MZJLP.js} +10 -10
  216. package/dist/{plugin-store-66QFBNEO.js.map → plugin-store-WI4MZJLP.js.map} +1 -1
  217. package/dist/project-WFUDVYNN.js +41 -0
  218. package/dist/{project-VMOHUXBD.js.map → project-WFUDVYNN.js.map} +1 -1
  219. package/dist/resolver/index.js +9 -9
  220. package/dist/runner/index.js +28 -28
  221. package/dist/runner/src/serve.d.ts.map +1 -1
  222. package/dist/sdk/asset-manager.js +14 -14
  223. package/dist/sdk/bridge.js +12 -12
  224. package/dist/sdk/core.js +8 -8
  225. package/dist/sdk/flow.js +9 -9
  226. package/dist/sdk/index.js +28 -28
  227. package/dist/sdk/resolver.js +9 -9
  228. package/dist/sdk/runner.js +28 -28
  229. package/dist/secrets/index.js +2 -2
  230. package/dist/{setup-PYY23HGZ.js → setup-RAMLTORM.js} +22 -22
  231. package/dist/{setup-PYY23HGZ.js.map → setup-RAMLTORM.js.map} +1 -1
  232. package/dist/skills-EOHZ2DZ4.js +26 -0
  233. package/dist/{skills-CS7NE5TT.js.map → skills-EOHZ2DZ4.js.map} +1 -1
  234. package/dist/{source-JCF6KSQN.js → source-FYVSFYEI.js} +21 -21
  235. package/dist/{source-JCF6KSQN.js.map → source-FYVSFYEI.js.map} +1 -1
  236. package/dist/{source-manifest-publish-O6P7G2M7.js → source-manifest-publish-4FPIPPLV.js} +23 -23
  237. package/dist/{source-manifest-publish-O6P7G2M7.js.map → source-manifest-publish-4FPIPPLV.js.map} +1 -1
  238. package/dist/tui/index.js +28 -28
  239. package/dist/workspace-plugin/adapters/mcp.js +22 -22
  240. package/dist/workspace-plugin/adapters/omp.js +14 -14
  241. package/dist/workspace-plugin/index.js +1 -1
  242. package/package.json +1 -1
  243. package/dist/chunk-2KOKBTR4.js.map +0 -1
  244. package/dist/chunk-2NYXQYHN.js +0 -22
  245. package/dist/chunk-2NYXQYHN.js.map +0 -1
  246. package/dist/chunk-AO7VJ6G6.js.map +0 -1
  247. package/dist/chunk-D2V42LUE.js.map +0 -1
  248. package/dist/chunk-MFHKHXDE.js.map +0 -1
  249. package/dist/chunk-MX3UQXLU.js.map +0 -1
  250. package/dist/chunk-PA7WLID3.js.map +0 -1
  251. package/dist/chunk-PTO2YDDG.js.map +0 -1
  252. package/dist/chunk-RGXVQZOV.js.map +0 -1
  253. package/dist/chunk-TZCQ7ZWQ.js.map +0 -1
  254. package/dist/chunk-WIHQWVWL.js.map +0 -1
  255. package/dist/chunk-XOGG7VDZ.js.map +0 -1
  256. package/dist/library-publish-LFOJJVMK.js.map +0 -1
  257. package/dist/open-registry-NVPCQPND.js +0 -32
  258. package/dist/paths-YUCP7K6U.js +0 -22
  259. package/dist/project-VMOHUXBD.js +0 -41
  260. package/dist/skills-CS7NE5TT.js +0 -26
@@ -1,17 +1,17 @@
1
- import { getStoreManifestsDir } from './chunk-MX3UQXLU.js';
2
- import { readManifestSourceConfig, discoverAssetsInTree } from './chunk-XOGG7VDZ.js';
3
- import { installAgent, installTargetOf, deployAll, removeAsset, canonicalEntryRef, createScaffold } from './chunk-2KOKBTR4.js';
1
+ import { getStoreManifestsDir } from './chunk-DFFD4BFG.js';
2
+ import { readManifestSourceConfig, discoverAssetsInTree } from './chunk-6VRJH4MR.js';
3
+ import { installAgent, installTargetOf, deployAll, removeAsset, canonicalEntryRef, createScaffold } from './chunk-74EEFB52.js';
4
4
  import { appendHistory, getRecentHistory, clearHistory } from './chunk-KTBKW2FI.js';
5
5
  import { commitChanges } from './chunk-UQ6LFBPZ.js';
6
- import { driverTargetSupportsAgents, CODEX_IDENTITY_DIR } from './chunk-VKSXST23.js';
7
- import { resolveConfiguredDriverTarget, GLOBAL_INSTALL_DIR_NAME, resolveLibraryDir, buildLibraryLockEntries, writeLock, buildLockFile, readLock, verifyLock, mergeLockFile, extractForPatch, generatePatch, savePatch, applyPatch } from './chunk-TZCQ7ZWQ.js';
8
- import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-BF33SCLY.js';
9
- import { deployedBase, deployedDir, isDeployed } from './chunk-46OVMT76.js';
10
- import { resolveSkWorkspaceConfig, effectiveAgentInstances, resolveAgentDefinitionDir, loadMcpServerDeclarations, resolveGlobalHarnesses, resolveGlobalSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, matchPin, coerceVersion, resolveAll, buildProvenanceIndex, ensureRepo, sourceShortName, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus, resolveAsset, readLinks, storeManifestSlug } from './chunk-2W4LBLIN.js';
11
- import { globalSkaileDir, globalCacheRoot, migrateLegacyDir } from './chunk-MFHKHXDE.js';
6
+ import { driverTargetSupportsAgents, CODEX_IDENTITY_DIR } from './chunk-AVCUPPG6.js';
7
+ import { resolveConfiguredDriverTarget, GLOBAL_INSTALL_DIR_NAME, resolveLibraryDir, buildLibraryLockEntries, writeLock, buildLockFile, readLock, verifyLock, mergeLockFile, extractForPatch, generatePatch, savePatch, applyPatch } from './chunk-OOLT6HGP.js';
8
+ import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-SWO25LTO.js';
9
+ import { deployedBase, deployedDir, isDeployed } from './chunk-G67BOI2J.js';
10
+ import { resolveSkWorkspaceConfig, effectiveAgentInstances, resolveAgentDefinitionDir, loadMcpServerDeclarations, resolveGlobalHarnesses, resolveGlobalSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, matchPin, coerceVersion, resolveAll, buildProvenanceIndex, ensureRepo, sourceShortName, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus, resolveAsset, readLinks, storeManifestSlug } from './chunk-LCU5U5IW.js';
11
+ import { globalSkaileDir, globalCacheRoot, migrateLegacyDir } from './chunk-L5VSIPQD.js';
12
12
  import { DRIVER_TARGETS } from './chunk-CPSIPIX7.js';
13
- import { scanDirectory, parseRequires } from './chunk-PA7WLID3.js';
14
- import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName } from './chunk-AO7VJ6G6.js';
13
+ import { scanDirectory, parseRequires } from './chunk-TTPSDC2G.js';
14
+ import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName } from './chunk-O7VPNKYN.js';
15
15
  import { spawnSync } from 'child_process';
16
16
  import { existsSync, rmSync, readdirSync, lstatSync, unlinkSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
17
17
  import path, { join, resolve, dirname, sep, posix } from 'path';
@@ -336,6 +336,25 @@ function indexLockByKindName(lock) {
336
336
  }
337
337
  return lockByKindName;
338
338
  }
339
+ function commitsBetween(repoDir, from, to, cache) {
340
+ const key = `${from}..${to}`;
341
+ const hit = cache.get(key);
342
+ if (hit !== void 0) return hit;
343
+ let count = 1;
344
+ if (COMMIT_ID.test(from) && COMMIT_ID.test(to)) {
345
+ const r = spawnSync("git", ["-C", repoDir, "rev-list", "--count", key], {
346
+ encoding: "utf8",
347
+ stdio: "pipe"
348
+ });
349
+ if (r.status === 0) {
350
+ const n = Number.parseInt(r.stdout.trim(), 10);
351
+ if (Number.isFinite(n) && n >= 0) count = n;
352
+ }
353
+ }
354
+ cache.set(key, count);
355
+ return count;
356
+ }
357
+ var COMMIT_ID = /^[0-9a-f]{7,64}$/;
339
358
  function libraryDiskHashes(libPath, cache, registry) {
340
359
  let hashes = cache.get(libPath);
341
360
  if (!hashes) {
@@ -367,6 +386,39 @@ function newestLibraryDef(snap, libraryName, id) {
367
386
  }
368
387
  return best;
369
388
  }
389
+ function qualifyDepRef(ref, fallback) {
390
+ const hash = ref.indexOf("#");
391
+ const head = hash === -1 ? ref : ref.slice(0, hash);
392
+ if (head.includes("@") || !fallback) return ref;
393
+ const pin = hash === -1 ? void 0 : ref.slice(hash + 1) || void 0;
394
+ const colon = head.indexOf(":");
395
+ return assetRefToStr({
396
+ kind: colon === -1 ? "skill" : head.slice(0, colon),
397
+ name: colon === -1 ? head : head.slice(colon + 1),
398
+ publisher: fallback,
399
+ pin
400
+ });
401
+ }
402
+ function libraryEntryDepRefs(e) {
403
+ const publisher = e.publisher ?? "";
404
+ const refs = /* @__PURE__ */ new Set();
405
+ for (const d of e.dependencies ?? []) {
406
+ if (d) refs.add(qualifyDepRef(d, publisher));
407
+ }
408
+ for (const r of e.requires ?? []) {
409
+ const p = r.publisher ?? publisher;
410
+ if (p) refs.add(assetRefToStr({ kind: r.kind, name: r.name, publisher: p }));
411
+ }
412
+ return [...refs];
413
+ }
414
+ function refIdentity(ref) {
415
+ try {
416
+ const p = parseAssetRef(ref);
417
+ return p.publisher ? `${p.publisher}/${p.kind}:${p.name}` : null;
418
+ } catch {
419
+ return null;
420
+ }
421
+ }
370
422
  function computeSyncStatus(repoStatus) {
371
423
  if (!repoStatus) return "unknown";
372
424
  if (repoStatus.kind === "local") return "local";
@@ -517,6 +569,8 @@ var AssetManager = class {
517
569
  indexPathOverride;
518
570
  /** Sink for cross-library collision warnings; else `console.warn`. */
519
571
  onLibraryCollision;
572
+ /** Store URLs whose failed version lookup was already reported (one warning per URL). */
573
+ warnedStoreVersionLookups = /* @__PURE__ */ new Set();
520
574
  constructor(opts) {
521
575
  this.projectDir = resolve(opts.projectDir);
522
576
  this.global = opts.global ?? false;
@@ -765,10 +819,12 @@ var AssetManager = class {
765
819
  * content. The returned `libraryOf` map names the library each entry came from
766
820
  * so callers can lock it as library-origin (see {@link libraryLockEntries}).
767
821
  *
822
+ * @param opts.quiet - Skip the cross-library collision warning (a lookup that only
823
+ * builds an error hint must not warn).
768
824
  * @returns the matched deploy entries, the set of `missing` refs covered, and
769
825
  * each entry's originating library name.
770
826
  */
771
- async resolveLibraryEntries(missing) {
827
+ async resolveLibraryEntries(missing, opts = {}) {
772
828
  const resolved = /* @__PURE__ */ new Set();
773
829
  const libraryOf = /* @__PURE__ */ new Map();
774
830
  if (missing.length === 0) return { entries: [], resolved, libraryOf };
@@ -807,18 +863,15 @@ var AssetManager = class {
807
863
  }
808
864
  if (byKey.size === 0) return { entries: [], resolved, libraryOf };
809
865
  const entries = [];
866
+ const allCandidates = [...byKey.values()].flat();
810
867
  for (const ref of missing) {
811
- let parsed;
812
- try {
813
- parsed = parseAssetRef(ref);
814
- } catch {
815
- continue;
816
- }
817
- if (!parsed.publisher) continue;
818
- const key = `${parsed.kind}:@${parsed.publisher}/${parsed.name}`;
819
- const candidates = (byKey.get(key) ?? []).filter(
820
- (c) => !parsed.pin || matchPin(parsed.pin, c.entry.version ?? "")
821
- );
868
+ const parsed = parseRefTolerant(ref);
869
+ if (!parsed) continue;
870
+ const hash = ref.indexOf("#");
871
+ const pin = parsed.pin ?? (hash >= 0 ? ref.slice(hash + 1) : void 0);
872
+ const key = parsed.publisher ? `${parsed.kind}:@${parsed.publisher}/${parsed.name}` : void 0;
873
+ const pool = key ? byKey.get(key) ?? [] : allCandidates.filter((c) => c.entry.kind === parsed.kind && c.entry.name === parsed.name);
874
+ const candidates = pool.filter((c) => !pin || matchPin(pin, c.entry.version ?? ""));
822
875
  if (candidates.length === 0) continue;
823
876
  candidates.sort((a, b) => {
824
877
  const va = coerceVersion(a.entry.version ?? "");
@@ -830,13 +883,65 @@ var AssetManager = class {
830
883
  return da - db || a.library.localeCompare(b.library);
831
884
  });
832
885
  const hit = candidates[0];
833
- this.warnLibraryCollision(key, candidates, hit);
886
+ if (!opts.quiet) {
887
+ this.warnLibraryCollision(
888
+ `${hit.entry.kind}:@${hit.entry.publisher}/${hit.entry.name}`,
889
+ candidates,
890
+ hit
891
+ );
892
+ }
834
893
  entries.push(hit.entry);
835
894
  libraryOf.set(hit.entry, hit.library);
836
895
  resolved.add(ref);
837
896
  }
838
897
  return { entries, resolved, libraryOf };
839
898
  }
899
+ /**
900
+ * Explain misses caused by a publisher change, for every missed publisher-qualified
901
+ * ref at once (one library scan, one lock read). Per ref:
902
+ * - `did you mean <ref>?` when a registered library holds the same kind + name
903
+ * under another publisher;
904
+ * - `locked as <lockRef>; run skaile install to re-resolve` when the lock holds the
905
+ * same kind + name under another publisher, records the library it came from, and
906
+ * that library now holds the asset under yet another publisher than the locked
907
+ * one. An unrelated asset that merely shares kind + name does not qualify.
908
+ *
909
+ * @param refs - Missed refs; a trailing `(reason)` after the first space is ignored.
910
+ * @returns hint text per ref, only for refs that have one. Never warns.
911
+ */
912
+ async publisherChangeHints(refs) {
913
+ const out = {};
914
+ const wanted = /* @__PURE__ */ new Map();
915
+ for (const ref of refs) {
916
+ const parsed = parseRefTolerant(ref.split(" ")[0] ?? ref);
917
+ if (parsed?.publisher) {
918
+ wanted.set(ref, { kind: parsed.kind, name: parsed.name, publisher: parsed.publisher });
919
+ }
920
+ }
921
+ if (wanted.size === 0) return out;
922
+ const lockEntries = Object.entries(this.tryReadLock()?.assets ?? {});
923
+ const bare = [...new Set([...wanted.values()].map((w) => `${w.kind}:${w.name}`))];
924
+ const lib = await this.resolveLibraryEntries(bare, { quiet: true });
925
+ for (const [ref, w] of wanted) {
926
+ const moved = lib.entries.find((e) => e.kind === w.kind && e.name === w.name);
927
+ const movedLibrary = moved ? lib.libraryOf.get(moved) : void 0;
928
+ const hints = [];
929
+ for (const [key, entry] of lockEntries) {
930
+ const id = parseCanonicalLockKey(key);
931
+ if (id.kind === w.kind && id.name === w.name && id.publisher && id.publisher !== w.publisher && entry.library && moved && movedLibrary === entry.library.name && moved.publisher !== id.publisher) {
932
+ hints.push(
933
+ `locked as ${id.kind}:@${id.publisher}/${id.name}; run skaile install to re-resolve`
934
+ );
935
+ break;
936
+ }
937
+ }
938
+ if (moved && moved.publisher !== w.publisher) {
939
+ hints.push(`did you mean ${moved.kind}:@${moved.publisher}/${moved.name}?`);
940
+ }
941
+ if (hints.length > 0) out[ref] = hints.map((h) => ` (${h})`).join("");
942
+ }
943
+ return out;
944
+ }
840
945
  /** Collision messages already printed by this instance (one warning per ref + library set). */
841
946
  warnedLibraryCollisions = /* @__PURE__ */ new Set();
842
947
  /**
@@ -875,10 +980,12 @@ var AssetManager = class {
875
980
  }
876
981
  /**
877
982
  * Library-origin lock entries for the assets {@link resolveLibraryEntries}
878
- * matched. The locked version comes from the library index when it knows the
879
- * asset (its manifest-declared version is authoritative), else from the
880
- * on-disk asset. The hash is computed from the files on disk, so it matches
881
- * what `install --locked` re-hashes.
983
+ * matched. The locked version is the one actually deployed: the on-disk
984
+ * entry's version, falling back to the library index only when the disk entry
985
+ * carries none — the index lags until the next `skaile library index`, so
986
+ * preferring it would lock a stale version after an in-place bump. The hash is
987
+ * computed from the files on disk, so it matches what `install --locked`
988
+ * re-hashes.
882
989
  */
883
990
  async libraryLockEntries(lib) {
884
991
  if (lib.entries.length === 0) return {};
@@ -895,7 +1002,7 @@ var AssetManager = class {
895
1002
  kind: e.kind,
896
1003
  publisher,
897
1004
  name: e.name,
898
- library: { name, version: def?.version || e.version || "0.0.0", sha256 }
1005
+ library: { name, version: e.version || def?.version || "0.0.0", sha256 }
899
1006
  };
900
1007
  })
901
1008
  );
@@ -937,7 +1044,7 @@ var AssetManager = class {
937
1044
  continue;
938
1045
  }
939
1046
  const def = newestLibraryDef(snap, origin.name, { kind, publisher, name });
940
- const current = def?.version || found.version || "0.0.0";
1047
+ const current = found.version || def?.version || "0.0.0";
941
1048
  if (current !== origin.version) {
942
1049
  missing.push(
943
1050
  `${ref} (library "${origin.name}" is at ${current}, locked ${origin.version})`
@@ -1012,6 +1119,93 @@ var AssetManager = class {
1012
1119
  return first;
1013
1120
  }
1014
1121
  }
1122
+ /**
1123
+ * Resolve `deps` library-first, then walk the dependencies of every library
1124
+ * asset it picks.
1125
+ *
1126
+ * A publisher-qualified ref that no project source declares is looked up in the
1127
+ * registered **libraries** before any store is asked, so a locally authored
1128
+ * asset resolves (and deploys) with the store unreachable and without a
1129
+ * version-discovery round trip. Only refs the libraries did not satisfy go to
1130
+ * {@link resolveWithStores}; its misses get one more library try (a ref a source
1131
+ * knows only under another version). A `#version` pin still selects through
1132
+ * `matchPin` inside {@link resolveLibraryEntries}.
1133
+ *
1134
+ * Library assets declare `dependencies` / `requires`. Those are fed back through
1135
+ * the same resolution with a `seen` identity set (mirrors `resolveAll`), so deps
1136
+ * deploy, get lock entries, and a dependency cycle terminates.
1137
+ *
1138
+ * @returns source/store candidates, still-unresolved refs, applied overrides,
1139
+ * expanded presets, and the library leg (entries + originating library per entry).
1140
+ */
1141
+ async resolveLibraryFirst(deps, opts) {
1142
+ const resolved = [];
1143
+ const overridesApplied = /* @__PURE__ */ new Set();
1144
+ const presets = [];
1145
+ const lib = { entries: [], resolved: /* @__PURE__ */ new Set(), libraryOf: /* @__PURE__ */ new Map() };
1146
+ const missing = /* @__PURE__ */ new Set();
1147
+ const seen = /* @__PURE__ */ new Set();
1148
+ const covered = /* @__PURE__ */ new Set();
1149
+ const absorb = (hit) => {
1150
+ const next = [];
1151
+ for (const e of hit.entries) {
1152
+ lib.entries.push(e);
1153
+ const origin = hit.libraryOf.get(e);
1154
+ if (origin) lib.libraryOf.set(e, origin);
1155
+ const id = `${e.publisher}/${e.kind}:${e.name}`;
1156
+ seen.add(id);
1157
+ covered.add(id);
1158
+ next.push(...libraryEntryDepRefs(e));
1159
+ }
1160
+ for (const r of hit.resolved) lib.resolved.add(r);
1161
+ return next;
1162
+ };
1163
+ let wave = deps;
1164
+ while (wave.length > 0) {
1165
+ const fresh = [];
1166
+ for (const ref of wave) {
1167
+ const id = refIdentity(ref);
1168
+ if (id !== null) {
1169
+ if (seen.has(id)) continue;
1170
+ seen.add(id);
1171
+ }
1172
+ fresh.push(ref);
1173
+ }
1174
+ if (fresh.length === 0) break;
1175
+ const libraryTried = new Set(
1176
+ fresh.filter((ref) => {
1177
+ const id = refIdentity(ref);
1178
+ return id !== null && !id.includes("/preset:") && (opts.provenanceIndex.get(id)?.length ?? 0) === 0;
1179
+ })
1180
+ );
1181
+ const hit = await this.resolveLibraryEntries([...libraryTried]);
1182
+ const next = absorb(hit);
1183
+ const rest = fresh.filter((ref) => !hit.resolved.has(ref));
1184
+ if (rest.length > 0) {
1185
+ const r = await this.resolveWithStores(rest, opts);
1186
+ for (const c of r.resolved) {
1187
+ const id = `${c.publisher}/${c.kind}:${c.name}`;
1188
+ if (covered.has(id)) continue;
1189
+ seen.add(id);
1190
+ covered.add(id);
1191
+ resolved.push(c);
1192
+ }
1193
+ for (const o of r.overridesApplied) overridesApplied.add(o);
1194
+ presets.push(...r.presets);
1195
+ const hit2 = await this.resolveLibraryEntries(
1196
+ r.missing.filter((m) => !libraryTried.has(m))
1197
+ );
1198
+ next.push(...absorb(hit2));
1199
+ for (const m of r.missing) if (!hit2.resolved.has(m)) missing.add(m);
1200
+ }
1201
+ wave = next;
1202
+ }
1203
+ const stillMissing = [...missing].filter((m) => {
1204
+ const id = refIdentity(m);
1205
+ return !lib.resolved.has(m) && !(id !== null && covered.has(id));
1206
+ });
1207
+ return { resolved, missing: stillMissing, overridesApplied, lib, presets };
1208
+ }
1015
1209
  /** The catalog fetcher to use: an injected one, else built from `stores`. */
1016
1210
  storeFetcherFor(stores) {
1017
1211
  return this.injectedStoreFetcher ?? this.buildStoreFetcher(stores);
@@ -1185,15 +1379,12 @@ var AssetManager = class {
1185
1379
  projectDir: this.projectDir,
1186
1380
  knownKinds: this.knownKinds
1187
1381
  });
1188
- const { resolved, missing, overridesApplied, presets } = await this.resolveWithStores(
1382
+ const { resolved, missing, overridesApplied, lib, presets } = await this.resolveLibraryFirst(
1189
1383
  dependencies,
1190
- {
1191
- provenanceIndex,
1192
- overrides,
1193
- stores
1194
- }
1384
+ { provenanceIndex, overrides, stores }
1195
1385
  );
1196
- const lib = await this.resolveLibraryEntries(missing);
1386
+ const stillMissing = missing.filter((m) => !lib.resolved.has(m));
1387
+ const missingHints = await this.publisherChangeHints(stillMissing);
1197
1388
  const directLock = this.directInstallLockEntries();
1198
1389
  const libraryLock = { ...directLock, ...await this.libraryLockEntries(lib) };
1199
1390
  const removed = this.reconcileRemovedAssets(resolved, new Set(Object.keys(libraryLock)));
@@ -1213,11 +1404,11 @@ var AssetManager = class {
1213
1404
  }
1214
1405
  this.recordInstallHistory(deployed, removed);
1215
1406
  const { npmInstalled, npmFailed } = await this.installRuntimeAssetDeps();
1216
- const stillMissing = missing.filter((m) => !lib.resolved.has(m));
1217
1407
  return {
1218
1408
  deployed,
1219
1409
  removed,
1220
1410
  missing: stillMissing,
1411
+ ...Object.keys(missingHints).length > 0 ? { missingHints } : {},
1221
1412
  lockWritten,
1222
1413
  npmInstalled,
1223
1414
  npmFailed,
@@ -1374,7 +1565,10 @@ var AssetManager = class {
1374
1565
  try {
1375
1566
  return await src.listVersions(ref);
1376
1567
  } catch (err) {
1377
- console.warn(`skaile: store ${storeUrl} version lookup for ${ref} failed \u2014 ${err}`);
1568
+ if (!this.warnedStoreVersionLookups.has(storeUrl)) {
1569
+ this.warnedStoreVersionLookups.add(storeUrl);
1570
+ console.warn(`skaile: store ${storeUrl} version lookup for ${ref} failed \u2014 ${err}`);
1571
+ }
1378
1572
  return [];
1379
1573
  }
1380
1574
  }
@@ -1510,15 +1704,19 @@ var AssetManager = class {
1510
1704
  projectDir: this.projectDir,
1511
1705
  knownKinds: this.knownKinds
1512
1706
  });
1513
- const { resolved, missing, overridesApplied } = await this.resolveWithStores([ref], {
1707
+ const { resolved, missing, overridesApplied, lib } = await this.resolveLibraryFirst([ref], {
1514
1708
  provenanceIndex,
1515
1709
  overrides,
1516
1710
  stores
1517
1711
  });
1518
- const lib = await this.resolveLibraryEntries(missing);
1519
1712
  if (resolved.length === 0 && lib.entries.length === 0) {
1520
1713
  throw new Error(
1521
- `Asset not found: ${ref}${missing.length ? ` (missing: ${missing.join(", ")})` : ""}`
1714
+ `Asset not found: ${ref}${(await this.publisherChangeHints([ref]))[ref] ?? ""}${missing.length ? ` (missing: ${missing.join(", ")})` : ""}`
1715
+ );
1716
+ }
1717
+ if (missing.length > 0) {
1718
+ console.warn(
1719
+ `skaile: ${ref} was added without unresolved dependencies: ${missing.join(", ")}`
1522
1720
  );
1523
1721
  }
1524
1722
  const entries = [...await this.buildCatalogEntries(resolved, repositories), ...lib.entries];
@@ -1784,7 +1982,11 @@ var AssetManager = class {
1784
1982
  return refs;
1785
1983
  }
1786
1984
  /**
1787
- * Remove a deployed asset and unregister it from `skaile.yaml`.
1985
+ * Remove a deployed asset and unregister it from `skaile.yaml` and the lock.
1986
+ *
1987
+ * A declared asset is always unregistered, even when nothing is deployed any
1988
+ * more (e.g. its library file was deleted): the declaration and lock entry
1989
+ * would otherwise be stuck behind a "not deployed" refusal.
1788
1990
  *
1789
1991
  * Deliberately does NOT re-render the driver target's MCP config: the render
1790
1992
  * step is async (the declaration resolver is), and making this synchronous
@@ -1793,37 +1995,40 @@ var AssetManager = class {
1793
1995
  * {@link renderMcpServerConfig}.
1794
1996
  *
1795
1997
  * @param ref - Asset ref in `kind:name` form (e.g. `skill:my-skill`).
1796
- * @returns `true` if the asset was found and removed, `false` if it was not deployed.
1797
- * A `preset:` ref has no deployed files: it is found when declared in `skaile.yaml`, and
1798
- * only its declaration goes — its expanded items leave with the next `skaile install`.
1998
+ * @returns `true` if anything changed (files undeployed, declaration or lock
1999
+ * entry removed), `false` if the asset was neither deployed nor declared.
2000
+ * A `preset:` ref has no deployed files: only its declaration goes — its
2001
+ * expanded items leave with the next `skaile install`.
1799
2002
  */
1800
2003
  remove(ref) {
1801
2004
  const parsed = parseAssetRef(ref);
1802
- let ok = parsed.kind === "preset" ? this.removeDependencyFromConfig(parsed) : false;
2005
+ let undeployed = false;
1803
2006
  for (const t of this.targetHarnesses()) {
1804
- if (removeAsset(parsed.kind, parsed.name, this.deployOptsFor(t))) ok = true;
2007
+ if (removeAsset(parsed.kind, parsed.name, this.deployOptsFor(t))) undeployed = true;
1805
2008
  }
1806
- if (ok) {
1807
- const depRef = `${parsed.kind}:${parsed.name}`;
1808
- this.removeDependencyFromConfig(parsed);
1809
- this.pruneLockEntry(parsed);
2009
+ const undeclared = this.removeDependencyFromConfig(parsed);
2010
+ const unlocked = undeployed || undeclared ? this.pruneLockEntry(parsed) : false;
2011
+ const changed = undeployed || undeclared || unlocked;
2012
+ if (changed) {
1810
2013
  appendHistory(this.projectDir, {
1811
- ref: depRef,
2014
+ ref: `${parsed.kind}:${parsed.name}`,
1812
2015
  action: "remove",
1813
2016
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1814
2017
  context: this.global ? "global" : "project"
1815
2018
  });
1816
2019
  }
1817
- return ok;
2020
+ return changed;
1818
2021
  }
1819
2022
  /**
1820
2023
  * Drop every lock entry matching a removed asset's identity, version-agnostic so
1821
2024
  * a content-sha pseudo-version key is pruned too. Symmetric with {@link add}'s
1822
2025
  * lock-merge — stops a stale entry reporting a phantom "removed" on next install.
2026
+ *
2027
+ * @returns `true` when at least one lock entry was dropped.
1823
2028
  */
1824
2029
  pruneLockEntry(parsed) {
1825
2030
  const lock = this.tryReadLock();
1826
- if (!lock) return;
2031
+ if (!lock) return false;
1827
2032
  let changed = false;
1828
2033
  for (const key of Object.keys(lock.assets)) {
1829
2034
  const id = parseCanonicalLockKey(key);
@@ -1833,6 +2038,7 @@ var AssetManager = class {
1833
2038
  }
1834
2039
  }
1835
2040
  if (changed) writeLock(this.lockPath, lock);
2041
+ return changed;
1836
2042
  }
1837
2043
  // ── Query ──────────────────────────────────────────────────────────────
1838
2044
  /**
@@ -2202,7 +2408,14 @@ var AssetManager = class {
2202
2408
  const lock = this.tryReadLock();
2203
2409
  if (!lock) return [];
2204
2410
  const bare = (s) => s.includes("#") ? s.slice(0, s.indexOf("#")) : s;
2205
- const key = lock.assets[ref] ? ref : Object.keys(lock.assets).find((k) => bare(k) === bare(ref));
2411
+ const asked = parseRefTolerant(ref);
2412
+ const matchesIdentity = (k) => {
2413
+ if (bare(k) === bare(ref)) return true;
2414
+ if (!asked || asked.publisher) return false;
2415
+ const locked = parseCanonicalLockKey(k);
2416
+ return locked.kind === asked.kind && locked.name === asked.name;
2417
+ };
2418
+ const key = lock.assets[ref] ? ref : Object.keys(lock.assets).find(matchesIdentity);
2206
2419
  if (!key) return [];
2207
2420
  return [key, "direct (skaile.yaml)"];
2208
2421
  }
@@ -2211,10 +2424,13 @@ var AssetManager = class {
2211
2424
  *
2212
2425
  * Two kinds of staleness are reported:
2213
2426
  * - **Source assets** — only remote repositories (not local paths) are checked;
2214
- * `behind` is the number of commits the local clone is missing.
2215
- * - **Library assets** — a library-origin lock entry whose library index now
2216
- * offers a newer version than the locked one; `behind` is 0, `latestVersion`
2217
- * and `library` are set. A library not indexed (or removed) is not reported.
2427
+ * `behind` counts the commits the clone is missing from the remote plus the
2428
+ * commits the clone moved past the locked commit (`source sync` after `add`).
2429
+ * - **Library assets** — a library-origin lock entry whose library files on disk
2430
+ * (not the index, which lags until `skaile library index`) hold a newer version
2431
+ * than the locked one (`latestVersion`, `library` set), or the same version with
2432
+ * different bytes (`contentChanged`). `behind` is 0. An unregistered library is a
2433
+ * `problem` row.
2218
2434
  *
2219
2435
  * @returns Array of {@link OutdatedEntry} objects.
2220
2436
  */
@@ -2224,22 +2440,28 @@ var AssetManager = class {
2224
2440
  if (!lock) return [];
2225
2441
  const result = [];
2226
2442
  const reported = /* @__PURE__ */ new Set();
2443
+ const commitCounts = /* @__PURE__ */ new Map();
2227
2444
  for (const src of lock.sources) {
2228
2445
  const slug = sourceCacheKey(src.url);
2229
2446
  const decl = repositories[slug];
2230
2447
  if (!decl) continue;
2231
2448
  const status = checkRepoStatus(decl, slug, this.reposDir);
2232
- if (status.behind <= 0) continue;
2449
+ if (status.kind !== "remote" || !status.localHead) continue;
2450
+ const clone = decl.path ?? join(this.reposDir, slug);
2233
2451
  for (const [ref, entry] of Object.entries(lock.assets)) {
2234
2452
  if (entry.source?.url !== src.url) continue;
2235
2453
  const { publisher, kind, name, version } = parseCanonicalLockKey(ref);
2236
2454
  if (!kind || !name) continue;
2455
+ const lockedCommit = entry.source.commit || src.commit;
2456
+ const moved = lockedCommit && !/^0+$/.test(lockedCommit) && lockedCommit !== status.localHead ? commitsBetween(clone, lockedCommit, status.localHead, commitCounts) : 0;
2457
+ const behind = status.behind + moved;
2458
+ if (behind <= 0) continue;
2237
2459
  result.push({
2238
2460
  kind,
2239
2461
  name,
2240
2462
  publisher: publisher ?? sourceShortName(src.url),
2241
2463
  currentVersion: version ?? "",
2242
- behind: status.behind
2464
+ behind
2243
2465
  });
2244
2466
  reported.add(ref);
2245
2467
  }
@@ -2249,11 +2471,14 @@ var AssetManager = class {
2249
2471
  );
2250
2472
  if (libraryAssets.length > 0) {
2251
2473
  const snap = await this.loadLibraryIndex();
2474
+ const diskHashes = /* @__PURE__ */ new Map();
2475
+ const scans = /* @__PURE__ */ new Map();
2252
2476
  for (const [ref, entry] of libraryAssets) {
2253
2477
  const origin = entry.library;
2254
2478
  const { publisher, kind, name } = parseCanonicalLockKey(ref);
2255
2479
  if (!publisher || !kind || !name) continue;
2256
- if (!this.libraryPath(origin.name, snap)) {
2480
+ const libPath = this.libraryPath(origin.name, snap);
2481
+ if (!libPath) {
2257
2482
  result.push({
2258
2483
  kind,
2259
2484
  name,
@@ -2266,18 +2491,45 @@ var AssetManager = class {
2266
2491
  reported.add(ref);
2267
2492
  continue;
2268
2493
  }
2269
- const def = newestLibraryDef(snap, origin.name, { kind, publisher, name });
2270
- if (!def || !gt(coerceVersion(def.version), coerceVersion(origin.version))) continue;
2271
- result.push({
2272
- kind,
2273
- name,
2274
- publisher,
2275
- currentVersion: origin.version,
2276
- behind: 0,
2277
- latestVersion: def.version,
2278
- library: origin.name
2279
- });
2280
- reported.add(ref);
2494
+ const scanKey = `${libPath}\0${publisher}`;
2495
+ let scanned = scans.get(scanKey);
2496
+ if (!scanned) {
2497
+ scanned = await scanDirectory(libPath, publisher, { knownKinds: this.knownKinds });
2498
+ scans.set(scanKey, scanned);
2499
+ }
2500
+ const found = scanned.find((x) => x.kind === kind && x.name === name);
2501
+ if (!found) continue;
2502
+ const diskVersion = found.version || newestLibraryDef(snap, origin.name, { kind, publisher, name })?.version;
2503
+ if (diskVersion && gt(coerceVersion(diskVersion), coerceVersion(origin.version))) {
2504
+ result.push({
2505
+ kind,
2506
+ name,
2507
+ publisher,
2508
+ currentVersion: origin.version,
2509
+ behind: 0,
2510
+ latestVersion: diskVersion,
2511
+ library: origin.name
2512
+ });
2513
+ reported.add(ref);
2514
+ continue;
2515
+ }
2516
+ if (origin.sha256) {
2517
+ const onDisk = libraryDiskHashes(libPath, diskHashes, this.registry).get(
2518
+ `${kind}:${name}`
2519
+ );
2520
+ if (onDisk !== void 0 && onDisk !== origin.sha256) {
2521
+ result.push({
2522
+ kind,
2523
+ name,
2524
+ publisher,
2525
+ currentVersion: origin.version,
2526
+ behind: 0,
2527
+ library: origin.name,
2528
+ contentChanged: true
2529
+ });
2530
+ reported.add(ref);
2531
+ }
2532
+ }
2281
2533
  }
2282
2534
  }
2283
2535
  for (const [ref, entry] of Object.entries(lock.assets)) {
@@ -2315,7 +2567,8 @@ var AssetManager = class {
2315
2567
  * @throws When `diff(1)` itself fails (exit status other than 0/1).
2316
2568
  */
2317
2569
  async diff(ref) {
2318
- const parsed = parseAssetRef(ref);
2570
+ const parsed = parseRefTolerant(ref);
2571
+ if (!parsed) return { status: "not-found" };
2319
2572
  const entry = await this.info(ref);
2320
2573
  if (!entry || !existsSync(entry.source)) return { status: "not-found" };
2321
2574
  const component = this.installTarget(parsed.kind);
@@ -2346,12 +2599,12 @@ var AssetManager = class {
2346
2599
  projectDir: this.projectDir,
2347
2600
  knownKinds: this.knownKinds
2348
2601
  });
2349
- const { resolved, missing, overridesApplied } = await this.resolveWithStores(dependencies, {
2602
+ const { resolved, overridesApplied, lib } = await this.resolveLibraryFirst(dependencies, {
2350
2603
  provenanceIndex,
2351
2604
  overrides,
2352
2605
  stores
2353
2606
  });
2354
- const libraryLock = await this.libraryLockEntries(await this.resolveLibraryEntries(missing));
2607
+ const libraryLock = await this.libraryLockEntries(lib);
2355
2608
  const lockData = buildLockFile(resolved, overridesApplied, libraryLock);
2356
2609
  writeLock(this.lockPath, lockData);
2357
2610
  return lockData;
@@ -2445,7 +2698,13 @@ var AssetManager = class {
2445
2698
  *
2446
2699
  * For each deployed asset, checks that all entries in its `requires` list are
2447
2700
  * also deployed. Returns a list of issues with a flag indicating whether the
2448
- * missing dependency can be resolved from a configured repository.
2701
+ * missing dependency can be resolved from a configured repository or library.
2702
+ *
2703
+ * A deployed asset is looked up by its publisher-qualified identity taken from
2704
+ * the lock key (`kind:@pub/name`), so library and source assets resolve alike.
2705
+ * A lock-managed asset that no source or library can be found for is reported
2706
+ * as an issue with `unresolved: true` (its `requires` cannot be verified);
2707
+ * unmanaged deployed files carry no declared origin and are skipped.
2449
2708
  *
2450
2709
  * @returns Array of {@link DepIssue} objects. An empty array means the workspace is healthy.
2451
2710
  */
@@ -2453,9 +2712,31 @@ var AssetManager = class {
2453
2712
  const { repositories } = this.loadConfig();
2454
2713
  const deployed = this.listDeployed();
2455
2714
  const issues = [];
2715
+ const lock = this.tryReadLock();
2716
+ const lockedPublisher = {};
2717
+ for (const key of Object.keys(lock?.assets ?? {})) {
2718
+ const { kind, name, publisher } = parseCanonicalLockKey(key);
2719
+ if (kind && name && publisher) lockedPublisher[`${kind}:${name}`] = publisher;
2720
+ }
2456
2721
  for (const entry of deployed) {
2457
- const full = await this.info(`${entry.kind}:${entry.name}`);
2458
- if (!full) continue;
2722
+ const publisher = lockedPublisher[`${entry.kind}:${entry.name}`];
2723
+ const full = await this.info(
2724
+ publisher ? `${entry.kind}:@${publisher}/${entry.name}` : `${entry.kind}:${entry.name}`
2725
+ );
2726
+ if (!full) {
2727
+ if (publisher) {
2728
+ issues.push({
2729
+ assetKind: entry.kind,
2730
+ assetName: entry.name,
2731
+ depKind: entry.kind,
2732
+ depName: entry.name,
2733
+ inRepos: false,
2734
+ unresolved: true
2735
+ });
2736
+ }
2737
+ continue;
2738
+ }
2739
+ const gaps = [];
2459
2740
  for (const req of full.requires) {
2460
2741
  const dep = memberIdentity(`${req.kind}:${req.name}`);
2461
2742
  if (!dep) continue;
@@ -2464,15 +2745,19 @@ var AssetManager = class {
2464
2745
  const inRepos = await resolveAsset({ kind: dep.kind, name: dep.name }, repositories, this.reposDir, {
2465
2746
  knownKinds: this.knownKinds
2466
2747
  }) !== null;
2467
- issues.push({
2748
+ const issue = {
2468
2749
  assetKind: entry.kind,
2469
2750
  assetName: entry.name,
2470
2751
  depKind: req.kind,
2471
2752
  depName: req.name,
2472
2753
  inRepos
2473
- });
2754
+ };
2755
+ issues.push(issue);
2756
+ if (!inRepos) gaps.push({ issue, ref: `${dep.kind}:${dep.name}` });
2474
2757
  }
2475
2758
  }
2759
+ const inLibrary = await this.resolveLibraryEntries(gaps.map((g) => g.ref));
2760
+ for (const g of gaps) g.issue.inRepos = inLibrary.resolved.has(g.ref);
2476
2761
  }
2477
2762
  return issues;
2478
2763
  }
@@ -2485,7 +2770,7 @@ var AssetManager = class {
2485
2770
  * @param destDir - Parent directory to create the asset in.
2486
2771
  * @param opts - Optional scaffold content (`description`).
2487
2772
  * @returns `{ ok: true, path }` on success, `{ ok: false, path: errorMessage }` if the
2488
- * directory already exists.
2773
+ * directory already exists or `kind` has no scaffold template.
2489
2774
  */
2490
2775
  create(name, kind, destDir, opts) {
2491
2776
  return createScaffold(name, kind, destDir, opts);
@@ -2613,15 +2898,44 @@ var AssetManager = class {
2613
2898
  return;
2614
2899
  }
2615
2900
  const raw = parse(readFileSync(configPath, "utf8")) ?? {};
2616
- if (!raw.dependencies) raw.dependencies = [];
2617
- if (!raw.dependencies.includes(ref)) {
2618
- raw.dependencies.push(ref);
2619
- writeFileSync(configPath, stringify(raw, { lineWidth: 120 }));
2901
+ if (!Array.isArray(raw.dependencies)) raw.dependencies = [];
2902
+ const deps = raw.dependencies;
2903
+ if (deps.includes(ref) && deps.filter((d) => this.sameDeclaredAsset(d, ref)).length === 1) {
2904
+ return;
2620
2905
  }
2906
+ const next = [];
2907
+ let placed = false;
2908
+ for (const dep of deps) {
2909
+ if (!this.sameDeclaredAsset(dep, ref)) {
2910
+ next.push(dep);
2911
+ } else if (!placed) {
2912
+ next.push(ref);
2913
+ placed = true;
2914
+ }
2915
+ }
2916
+ if (!placed) next.push(ref);
2917
+ raw.dependencies = next;
2918
+ writeFileSync(configPath, stringify(raw, { lineWidth: 120 }));
2919
+ }
2920
+ /**
2921
+ * Whether the declared `dep` names the same asset (kind, publisher, name) as
2922
+ * `ref`, ignoring the version pin. A publisher must agree on both sides —
2923
+ * unlike {@link removeDependencyFromConfig}, a bare `kind:name` never replaces a
2924
+ * publisher-qualified line. Unparseable entries only match on string equality.
2925
+ */
2926
+ sameDeclaredAsset(dep, ref) {
2927
+ if (typeof dep !== "string") return false;
2928
+ if (dep === ref) return true;
2929
+ const a = parseAssetRefLoose(dep);
2930
+ const b = parseAssetRefLoose(ref);
2931
+ if (!a || !b) return false;
2932
+ return a.kind === b.kind && a.name === b.name && a.publisher?.replace(/^@/, "") === b.publisher?.replace(/^@/, "");
2621
2933
  }
2622
2934
  /**
2623
2935
  * Remove a dependency ref from the manifest `dependencies:`. Targets the same
2624
2936
  * file as {@link addDependencyToConfig} (`~/.skaile/skaile.yaml` in global mode).
2937
+ *
2938
+ * @returns `true` when a declaration was removed.
2625
2939
  */
2626
2940
  removeDependencyFromConfig(target) {
2627
2941
  const configPath = join(this.stateRoot, "skaile.yaml");
@@ -2629,15 +2943,15 @@ var AssetManager = class {
2629
2943
  const raw = parse(readFileSync(configPath, "utf8")) ?? {};
2630
2944
  if (!Array.isArray(raw.dependencies)) return false;
2631
2945
  const wantPub = target.publisher?.replace(/^@/, "");
2632
- const idx = raw.dependencies.findIndex((dep) => {
2633
- if (typeof dep !== "string") return false;
2946
+ const before = raw.dependencies.length;
2947
+ raw.dependencies = raw.dependencies.filter((dep) => {
2948
+ if (typeof dep !== "string") return true;
2634
2949
  const p = parseAssetRefLoose(dep);
2635
- if (!p || p.kind !== target.kind || p.name !== target.name) return false;
2950
+ if (!p || p.kind !== target.kind || p.name !== target.name) return true;
2636
2951
  const havePub = p.publisher?.replace(/^@/, "");
2637
- return wantPub === void 0 || havePub === void 0 || havePub === wantPub;
2952
+ return !(wantPub === void 0 || havePub === void 0 || havePub === wantPub);
2638
2953
  });
2639
- if (idx === -1) return false;
2640
- raw.dependencies.splice(idx, 1);
2954
+ if (raw.dependencies.length === before) return false;
2641
2955
  writeFileSync(configPath, stringify(raw, { lineWidth: 120 }));
2642
2956
  return true;
2643
2957
  }
@@ -2659,5 +2973,5 @@ var AssetManager = class {
2659
2973
  };
2660
2974
 
2661
2975
  export { AssetManager, FACTORY_SOURCE_URL, MissingManifestError, installAgentInstances, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, softDepName };
2662
- //# sourceMappingURL=chunk-PTO2YDDG.js.map
2663
- //# sourceMappingURL=chunk-PTO2YDDG.js.map
2976
+ //# sourceMappingURL=chunk-D5HOETOB.js.map
2977
+ //# sourceMappingURL=chunk-D5HOETOB.js.map