@skaile/workspaces 5.6.0 → 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 (261) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/README.md +4 -2
  3. package/dist/{asset-feeds-4O2JK5S4.js → asset-feeds-K36CR52Q.js} +17 -17
  4. package/dist/{asset-feeds-4O2JK5S4.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-NLXIALVO.js → chunk-53MSCGR2.js} +5 -5
  26. package/dist/{chunk-NLXIALVO.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-IPWR33AW.js → chunk-74EEFB52.js} +31 -15
  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-O5GDKC5I.js → chunk-BWZF2ZIF.js} +3 -3
  42. package/dist/{chunk-O5GDKC5I.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-4CTGEEN6.js → chunk-D5HOETOB.js} +424 -98
  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-MX6LZE2C.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-V7NN3HXR.js → chunk-GIC3G5YG.js} +6 -6
  60. package/dist/{chunk-V7NN3HXR.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-436GRQC2.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-DZM73WDN.js → chunk-LXY4BUA3.js} +5 -5
  82. package/dist/{chunk-DZM73WDN.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-S7QXEXKY.js → chunk-THEJJBOU.js} +3 -3
  106. package/dist/{chunk-S7QXEXKY.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 +944 -600
  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/migrate-agents.d.ts.map +1 -1
  128. package/dist/cli/src/commands/outdated.d.ts +3 -2
  129. package/dist/cli/src/commands/outdated.d.ts.map +1 -1
  130. package/dist/cli/src/commands/project.d.ts +13 -4
  131. package/dist/cli/src/commands/project.d.ts.map +1 -1
  132. package/dist/cli/src/commands/source.d.ts +4 -3
  133. package/dist/cli/src/commands/source.d.ts.map +1 -1
  134. package/dist/cli/src/commands/update.d.ts +1 -1
  135. package/dist/cli/src/commands/update.d.ts.map +1 -1
  136. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  137. package/dist/cli/src/skill-checks.d.ts +21 -10
  138. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  139. package/dist/connectors/config.js +6 -6
  140. package/dist/connectors/index.js +15 -15
  141. package/dist/{connectors-HWENZFKW.js → connectors-SSOTIDHT.js} +18 -18
  142. package/dist/{connectors-HWENZFKW.js.map → connectors-SSOTIDHT.js.map} +1 -1
  143. package/dist/core/index.js +8 -8
  144. package/dist/core/manifest.js +2 -2
  145. package/dist/core/models.js +1 -1
  146. package/dist/core/publish-manifest.js +2 -2
  147. package/dist/core/ref.js +1 -1
  148. package/dist/core/runtime-assets.js +6 -6
  149. package/dist/core/src/cache-paths.d.ts.map +1 -1
  150. package/dist/core/src/index.d.ts +1 -1
  151. package/dist/core/src/index.d.ts.map +1 -1
  152. package/dist/core/src/lock.d.ts +3 -3
  153. package/dist/core/src/lock.d.ts.map +1 -1
  154. package/dist/core/src/manifest.d.ts +6 -1
  155. package/dist/core/src/manifest.d.ts.map +1 -1
  156. package/dist/core/src/models.d.ts +8 -0
  157. package/dist/core/src/models.d.ts.map +1 -1
  158. package/dist/core/store.js +2 -2
  159. package/dist/core/workspace-config.js +5 -5
  160. package/dist/deploy/index.js +8 -8
  161. package/dist/discovery/index.js +4 -4
  162. package/dist/discovery/src/index.d.ts +1 -1
  163. package/dist/discovery/src/index.d.ts.map +1 -1
  164. package/dist/discovery/src/source-config.d.ts +12 -0
  165. package/dist/discovery/src/source-config.d.ts.map +1 -1
  166. package/dist/discovery/src/tree-entries.d.ts.map +1 -1
  167. package/dist/{ensure-sources-VCPKNPK2.js → ensure-sources-277VI7R3.js} +17 -17
  168. package/dist/{ensure-sources-VCPKNPK2.js.map → ensure-sources-277VI7R3.js.map} +1 -1
  169. package/dist/factory-assets/connectors/box.js +15 -15
  170. package/dist/factory-assets/connectors/deploy.js +15 -15
  171. package/dist/factory-assets/connectors/devserver.js +15 -15
  172. package/dist/factory-assets/connectors/flow/adapter.js +15 -15
  173. package/dist/factory-assets/connectors/flow/engine.js +9 -9
  174. package/dist/factory-assets/connectors/flow/run-flow.js +17 -17
  175. package/dist/factory-assets/connectors/flow.js +15 -15
  176. package/dist/factory-assets/connectors/git.js +15 -15
  177. package/dist/factory-assets/connectors/gmail.js +15 -15
  178. package/dist/factory-assets/connectors/googledrive.js +15 -15
  179. package/dist/factory-assets/connectors/local.js +15 -15
  180. package/dist/factory-assets/connectors/mattermost.js +15 -15
  181. package/dist/factory-assets/connectors/memory.js +15 -15
  182. package/dist/factory-assets/connectors/minio.js +15 -15
  183. package/dist/factory-assets/connectors/postgres.js +15 -15
  184. package/dist/factory-assets/connectors/s3.js +15 -15
  185. package/dist/factory-assets/connectors/sharepoint.js +15 -15
  186. package/dist/factory-assets/connectors/sqlite.js +15 -15
  187. package/dist/factory-assets/connectors/static-server.js +15 -15
  188. package/dist/factory-assets/connectors/tunnel.js +15 -15
  189. package/dist/factory-assets/connectors/webdav.js +15 -15
  190. package/dist/factory-assets/connectors/xstate-store.js +15 -15
  191. package/dist/factory-assets/connectors/xstate.js +15 -15
  192. package/dist/{flows-ENQY2DV7.js → flows-J2UEU2QM.js} +13 -13
  193. package/dist/{flows-ENQY2DV7.js.map → flows-J2UEU2QM.js.map} +1 -1
  194. package/dist/{helpers-IW36CEJX.js → helpers-KC5O7CML.js} +17 -17
  195. package/dist/{helpers-IW36CEJX.js.map → helpers-KC5O7CML.js.map} +1 -1
  196. package/dist/library/index.js +11 -11
  197. package/dist/library/install.js +3 -3
  198. package/dist/library/src/index.d.ts +3 -3
  199. package/dist/library/src/index.d.ts.map +1 -1
  200. package/dist/library/src/local/library-manager.d.ts +6 -0
  201. package/dist/library/src/local/library-manager.d.ts.map +1 -1
  202. package/dist/library/src/local/local-catalog-source.d.ts +5 -2
  203. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  204. package/dist/library/src/manifest-writer.d.ts +23 -1
  205. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  206. package/dist/library/src/sync/git-driver.d.ts +12 -0
  207. package/dist/library/src/sync/git-driver.d.ts.map +1 -1
  208. package/dist/{library-publish-R3DQLMTD.js → library-publish-FGXF5TJO.js} +85 -41
  209. package/dist/library-publish-FGXF5TJO.js.map +1 -0
  210. package/dist/{open-library-FAJZRDKE.js → open-library-P3D337NH.js} +20 -20
  211. package/dist/{open-library-FAJZRDKE.js.map → open-library-P3D337NH.js.map} +1 -1
  212. package/dist/open-registry-Z3P2X2AB.js +32 -0
  213. package/dist/{open-registry-NVPCQPND.js.map → open-registry-Z3P2X2AB.js.map} +1 -1
  214. package/dist/paths-JKEKXM52.js +22 -0
  215. package/dist/{paths-YUCP7K6U.js.map → paths-JKEKXM52.js.map} +1 -1
  216. package/dist/{plugin-store-66QFBNEO.js → plugin-store-WI4MZJLP.js} +10 -10
  217. package/dist/{plugin-store-66QFBNEO.js.map → plugin-store-WI4MZJLP.js.map} +1 -1
  218. package/dist/project-WFUDVYNN.js +41 -0
  219. package/dist/{project-ALJIVFHI.js.map → project-WFUDVYNN.js.map} +1 -1
  220. package/dist/resolver/index.js +9 -9
  221. package/dist/runner/index.js +28 -28
  222. package/dist/runner/src/serve.d.ts.map +1 -1
  223. package/dist/sdk/asset-manager.js +14 -14
  224. package/dist/sdk/bridge.js +12 -12
  225. package/dist/sdk/core.js +8 -8
  226. package/dist/sdk/flow.js +9 -9
  227. package/dist/sdk/index.js +28 -28
  228. package/dist/sdk/resolver.js +9 -9
  229. package/dist/sdk/runner.js +28 -28
  230. package/dist/secrets/index.js +2 -2
  231. package/dist/{setup-35JXIA3N.js → setup-RAMLTORM.js} +22 -22
  232. package/dist/{setup-35JXIA3N.js.map → setup-RAMLTORM.js.map} +1 -1
  233. package/dist/skills-EOHZ2DZ4.js +26 -0
  234. package/dist/{skills-CS7NE5TT.js.map → skills-EOHZ2DZ4.js.map} +1 -1
  235. package/dist/{source-ISR4KRZV.js → source-FYVSFYEI.js} +21 -21
  236. package/dist/{source-ISR4KRZV.js.map → source-FYVSFYEI.js.map} +1 -1
  237. package/dist/{source-manifest-publish-P22IPK5F.js → source-manifest-publish-4FPIPPLV.js} +23 -23
  238. package/dist/{source-manifest-publish-P22IPK5F.js.map → source-manifest-publish-4FPIPPLV.js.map} +1 -1
  239. package/dist/tui/index.js +28 -28
  240. package/dist/workspace-plugin/adapters/mcp.js +22 -22
  241. package/dist/workspace-plugin/adapters/omp.js +14 -14
  242. package/dist/workspace-plugin/index.js +1 -1
  243. package/package.json +3 -1
  244. package/dist/chunk-2NYXQYHN.js +0 -22
  245. package/dist/chunk-2NYXQYHN.js.map +0 -1
  246. package/dist/chunk-436GRQC2.js.map +0 -1
  247. package/dist/chunk-4CTGEEN6.js.map +0 -1
  248. package/dist/chunk-AO7VJ6G6.js.map +0 -1
  249. package/dist/chunk-IPWR33AW.js.map +0 -1
  250. package/dist/chunk-MFHKHXDE.js.map +0 -1
  251. package/dist/chunk-MX3UQXLU.js.map +0 -1
  252. package/dist/chunk-MX6LZE2C.js.map +0 -1
  253. package/dist/chunk-PA7WLID3.js.map +0 -1
  254. package/dist/chunk-RGXVQZOV.js.map +0 -1
  255. package/dist/chunk-TZCQ7ZWQ.js.map +0 -1
  256. package/dist/chunk-XOGG7VDZ.js.map +0 -1
  257. package/dist/library-publish-R3DQLMTD.js.map +0 -1
  258. package/dist/open-registry-NVPCQPND.js +0 -32
  259. package/dist/paths-YUCP7K6U.js +0 -22
  260. package/dist/project-ALJIVFHI.js +0 -41
  261. 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-IPWR33AW.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';
@@ -317,6 +317,10 @@ function commonDirPrefix(paths) {
317
317
  }
318
318
  return common.join("/");
319
319
  }
320
+ function filesUnderManifestDir(paths, manifestRel) {
321
+ const manifestDir = posix.dirname(manifestRel);
322
+ return paths.map((p) => posix.relative(manifestDir, p)).filter((rel) => rel !== "" && !rel.startsWith(".."));
323
+ }
320
324
  function indexLockByKindName(lock) {
321
325
  const lockByKindName = /* @__PURE__ */ new Map();
322
326
  for (const [key, entry] of Object.entries(lock?.assets ?? {})) {
@@ -332,6 +336,25 @@ function indexLockByKindName(lock) {
332
336
  }
333
337
  return lockByKindName;
334
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}$/;
335
358
  function libraryDiskHashes(libPath, cache, registry) {
336
359
  let hashes = cache.get(libPath);
337
360
  if (!hashes) {
@@ -363,6 +386,39 @@ function newestLibraryDef(snap, libraryName, id) {
363
386
  }
364
387
  return best;
365
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
+ }
366
422
  function computeSyncStatus(repoStatus) {
367
423
  if (!repoStatus) return "unknown";
368
424
  if (repoStatus.kind === "local") return "local";
@@ -513,6 +569,8 @@ var AssetManager = class {
513
569
  indexPathOverride;
514
570
  /** Sink for cross-library collision warnings; else `console.warn`. */
515
571
  onLibraryCollision;
572
+ /** Store URLs whose failed version lookup was already reported (one warning per URL). */
573
+ warnedStoreVersionLookups = /* @__PURE__ */ new Set();
516
574
  constructor(opts) {
517
575
  this.projectDir = resolve(opts.projectDir);
518
576
  this.global = opts.global ?? false;
@@ -718,6 +776,12 @@ var AssetManager = class {
718
776
  ) ?? c.files[0]?.path;
719
777
  const source = mdRel ? join(cloneDir, mdRel) : cloneDir;
720
778
  const entry = {
779
+ ...mdRel ? {
780
+ files: filesUnderManifestDir(
781
+ c.files.map((f) => f.path),
782
+ mdRel
783
+ )
784
+ } : {},
721
785
  name: c.name,
722
786
  kind: c.kind,
723
787
  description: c.description ?? "",
@@ -755,10 +819,12 @@ var AssetManager = class {
755
819
  * content. The returned `libraryOf` map names the library each entry came from
756
820
  * so callers can lock it as library-origin (see {@link libraryLockEntries}).
757
821
  *
822
+ * @param opts.quiet - Skip the cross-library collision warning (a lookup that only
823
+ * builds an error hint must not warn).
758
824
  * @returns the matched deploy entries, the set of `missing` refs covered, and
759
825
  * each entry's originating library name.
760
826
  */
761
- async resolveLibraryEntries(missing) {
827
+ async resolveLibraryEntries(missing, opts = {}) {
762
828
  const resolved = /* @__PURE__ */ new Set();
763
829
  const libraryOf = /* @__PURE__ */ new Map();
764
830
  if (missing.length === 0) return { entries: [], resolved, libraryOf };
@@ -797,18 +863,15 @@ var AssetManager = class {
797
863
  }
798
864
  if (byKey.size === 0) return { entries: [], resolved, libraryOf };
799
865
  const entries = [];
866
+ const allCandidates = [...byKey.values()].flat();
800
867
  for (const ref of missing) {
801
- let parsed;
802
- try {
803
- parsed = parseAssetRef(ref);
804
- } catch {
805
- continue;
806
- }
807
- if (!parsed.publisher) continue;
808
- const key = `${parsed.kind}:@${parsed.publisher}/${parsed.name}`;
809
- const candidates = (byKey.get(key) ?? []).filter(
810
- (c) => !parsed.pin || matchPin(parsed.pin, c.entry.version ?? "")
811
- );
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 ?? ""));
812
875
  if (candidates.length === 0) continue;
813
876
  candidates.sort((a, b) => {
814
877
  const va = coerceVersion(a.entry.version ?? "");
@@ -820,13 +883,65 @@ var AssetManager = class {
820
883
  return da - db || a.library.localeCompare(b.library);
821
884
  });
822
885
  const hit = candidates[0];
823
- 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
+ }
824
893
  entries.push(hit.entry);
825
894
  libraryOf.set(hit.entry, hit.library);
826
895
  resolved.add(ref);
827
896
  }
828
897
  return { entries, resolved, libraryOf };
829
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
+ }
830
945
  /** Collision messages already printed by this instance (one warning per ref + library set). */
831
946
  warnedLibraryCollisions = /* @__PURE__ */ new Set();
832
947
  /**
@@ -865,10 +980,12 @@ var AssetManager = class {
865
980
  }
866
981
  /**
867
982
  * Library-origin lock entries for the assets {@link resolveLibraryEntries}
868
- * matched. The locked version comes from the library index when it knows the
869
- * asset (its manifest-declared version is authoritative), else from the
870
- * on-disk asset. The hash is computed from the files on disk, so it matches
871
- * 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.
872
989
  */
873
990
  async libraryLockEntries(lib) {
874
991
  if (lib.entries.length === 0) return {};
@@ -885,7 +1002,7 @@ var AssetManager = class {
885
1002
  kind: e.kind,
886
1003
  publisher,
887
1004
  name: e.name,
888
- library: { name, version: def?.version || e.version || "0.0.0", sha256 }
1005
+ library: { name, version: e.version || def?.version || "0.0.0", sha256 }
889
1006
  };
890
1007
  })
891
1008
  );
@@ -927,7 +1044,7 @@ var AssetManager = class {
927
1044
  continue;
928
1045
  }
929
1046
  const def = newestLibraryDef(snap, origin.name, { kind, publisher, name });
930
- const current = def?.version || found.version || "0.0.0";
1047
+ const current = found.version || def?.version || "0.0.0";
931
1048
  if (current !== origin.version) {
932
1049
  missing.push(
933
1050
  `${ref} (library "${origin.name}" is at ${current}, locked ${origin.version})`
@@ -1002,6 +1119,93 @@ var AssetManager = class {
1002
1119
  return first;
1003
1120
  }
1004
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
+ }
1005
1209
  /** The catalog fetcher to use: an injected one, else built from `stores`. */
1006
1210
  storeFetcherFor(stores) {
1007
1211
  return this.injectedStoreFetcher ?? this.buildStoreFetcher(stores);
@@ -1125,8 +1329,10 @@ var AssetManager = class {
1125
1329
  stagedCandidateToEntry(c, stagedManifestPath) {
1126
1330
  const paths = (c.files ?? []).map((f) => f.path);
1127
1331
  const root = commonDirPrefix(paths);
1128
- const manifestDir = posix.dirname(this.stagedManifestRel(c));
1129
- const files = paths.map((p) => root && p.startsWith(`${root}/`) ? p.slice(root.length + 1) : p).map((p) => posix.relative(manifestDir, p)).filter((rel) => rel !== "" && !rel.startsWith(".."));
1332
+ const files = filesUnderManifestDir(
1333
+ paths.map((p) => root && p.startsWith(`${root}/`) ? p.slice(root.length + 1) : p),
1334
+ this.stagedManifestRel(c)
1335
+ );
1130
1336
  const entry = {
1131
1337
  files,
1132
1338
  name: c.name,
@@ -1173,15 +1379,12 @@ var AssetManager = class {
1173
1379
  projectDir: this.projectDir,
1174
1380
  knownKinds: this.knownKinds
1175
1381
  });
1176
- const { resolved, missing, overridesApplied, presets } = await this.resolveWithStores(
1382
+ const { resolved, missing, overridesApplied, lib, presets } = await this.resolveLibraryFirst(
1177
1383
  dependencies,
1178
- {
1179
- provenanceIndex,
1180
- overrides,
1181
- stores
1182
- }
1384
+ { provenanceIndex, overrides, stores }
1183
1385
  );
1184
- const lib = await this.resolveLibraryEntries(missing);
1386
+ const stillMissing = missing.filter((m) => !lib.resolved.has(m));
1387
+ const missingHints = await this.publisherChangeHints(stillMissing);
1185
1388
  const directLock = this.directInstallLockEntries();
1186
1389
  const libraryLock = { ...directLock, ...await this.libraryLockEntries(lib) };
1187
1390
  const removed = this.reconcileRemovedAssets(resolved, new Set(Object.keys(libraryLock)));
@@ -1201,11 +1404,11 @@ var AssetManager = class {
1201
1404
  }
1202
1405
  this.recordInstallHistory(deployed, removed);
1203
1406
  const { npmInstalled, npmFailed } = await this.installRuntimeAssetDeps();
1204
- const stillMissing = missing.filter((m) => !lib.resolved.has(m));
1205
1407
  return {
1206
1408
  deployed,
1207
1409
  removed,
1208
1410
  missing: stillMissing,
1411
+ ...Object.keys(missingHints).length > 0 ? { missingHints } : {},
1209
1412
  lockWritten,
1210
1413
  npmInstalled,
1211
1414
  npmFailed,
@@ -1362,7 +1565,10 @@ var AssetManager = class {
1362
1565
  try {
1363
1566
  return await src.listVersions(ref);
1364
1567
  } catch (err) {
1365
- 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
+ }
1366
1572
  return [];
1367
1573
  }
1368
1574
  }
@@ -1498,15 +1704,19 @@ var AssetManager = class {
1498
1704
  projectDir: this.projectDir,
1499
1705
  knownKinds: this.knownKinds
1500
1706
  });
1501
- const { resolved, missing, overridesApplied } = await this.resolveWithStores([ref], {
1707
+ const { resolved, missing, overridesApplied, lib } = await this.resolveLibraryFirst([ref], {
1502
1708
  provenanceIndex,
1503
1709
  overrides,
1504
1710
  stores
1505
1711
  });
1506
- const lib = await this.resolveLibraryEntries(missing);
1507
1712
  if (resolved.length === 0 && lib.entries.length === 0) {
1508
1713
  throw new Error(
1509
- `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(", ")}`
1510
1720
  );
1511
1721
  }
1512
1722
  const entries = [...await this.buildCatalogEntries(resolved, repositories), ...lib.entries];
@@ -1772,7 +1982,11 @@ var AssetManager = class {
1772
1982
  return refs;
1773
1983
  }
1774
1984
  /**
1775
- * 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.
1776
1990
  *
1777
1991
  * Deliberately does NOT re-render the driver target's MCP config: the render
1778
1992
  * step is async (the declaration resolver is), and making this synchronous
@@ -1781,37 +1995,40 @@ var AssetManager = class {
1781
1995
  * {@link renderMcpServerConfig}.
1782
1996
  *
1783
1997
  * @param ref - Asset ref in `kind:name` form (e.g. `skill:my-skill`).
1784
- * @returns `true` if the asset was found and removed, `false` if it was not deployed.
1785
- * A `preset:` ref has no deployed files: it is found when declared in `skaile.yaml`, and
1786
- * 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`.
1787
2002
  */
1788
2003
  remove(ref) {
1789
2004
  const parsed = parseAssetRef(ref);
1790
- let ok = parsed.kind === "preset" ? this.removeDependencyFromConfig(parsed) : false;
2005
+ let undeployed = false;
1791
2006
  for (const t of this.targetHarnesses()) {
1792
- if (removeAsset(parsed.kind, parsed.name, this.deployOptsFor(t))) ok = true;
2007
+ if (removeAsset(parsed.kind, parsed.name, this.deployOptsFor(t))) undeployed = true;
1793
2008
  }
1794
- if (ok) {
1795
- const depRef = `${parsed.kind}:${parsed.name}`;
1796
- this.removeDependencyFromConfig(parsed);
1797
- 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) {
1798
2013
  appendHistory(this.projectDir, {
1799
- ref: depRef,
2014
+ ref: `${parsed.kind}:${parsed.name}`,
1800
2015
  action: "remove",
1801
2016
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1802
2017
  context: this.global ? "global" : "project"
1803
2018
  });
1804
2019
  }
1805
- return ok;
2020
+ return changed;
1806
2021
  }
1807
2022
  /**
1808
2023
  * Drop every lock entry matching a removed asset's identity, version-agnostic so
1809
2024
  * a content-sha pseudo-version key is pruned too. Symmetric with {@link add}'s
1810
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.
1811
2028
  */
1812
2029
  pruneLockEntry(parsed) {
1813
2030
  const lock = this.tryReadLock();
1814
- if (!lock) return;
2031
+ if (!lock) return false;
1815
2032
  let changed = false;
1816
2033
  for (const key of Object.keys(lock.assets)) {
1817
2034
  const id = parseCanonicalLockKey(key);
@@ -1821,6 +2038,7 @@ var AssetManager = class {
1821
2038
  }
1822
2039
  }
1823
2040
  if (changed) writeLock(this.lockPath, lock);
2041
+ return changed;
1824
2042
  }
1825
2043
  // ── Query ──────────────────────────────────────────────────────────────
1826
2044
  /**
@@ -2190,7 +2408,14 @@ var AssetManager = class {
2190
2408
  const lock = this.tryReadLock();
2191
2409
  if (!lock) return [];
2192
2410
  const bare = (s) => s.includes("#") ? s.slice(0, s.indexOf("#")) : s;
2193
- 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);
2194
2419
  if (!key) return [];
2195
2420
  return [key, "direct (skaile.yaml)"];
2196
2421
  }
@@ -2199,10 +2424,13 @@ var AssetManager = class {
2199
2424
  *
2200
2425
  * Two kinds of staleness are reported:
2201
2426
  * - **Source assets** — only remote repositories (not local paths) are checked;
2202
- * `behind` is the number of commits the local clone is missing.
2203
- * - **Library assets** — a library-origin lock entry whose library index now
2204
- * offers a newer version than the locked one; `behind` is 0, `latestVersion`
2205
- * 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.
2206
2434
  *
2207
2435
  * @returns Array of {@link OutdatedEntry} objects.
2208
2436
  */
@@ -2212,22 +2440,28 @@ var AssetManager = class {
2212
2440
  if (!lock) return [];
2213
2441
  const result = [];
2214
2442
  const reported = /* @__PURE__ */ new Set();
2443
+ const commitCounts = /* @__PURE__ */ new Map();
2215
2444
  for (const src of lock.sources) {
2216
2445
  const slug = sourceCacheKey(src.url);
2217
2446
  const decl = repositories[slug];
2218
2447
  if (!decl) continue;
2219
2448
  const status = checkRepoStatus(decl, slug, this.reposDir);
2220
- if (status.behind <= 0) continue;
2449
+ if (status.kind !== "remote" || !status.localHead) continue;
2450
+ const clone = decl.path ?? join(this.reposDir, slug);
2221
2451
  for (const [ref, entry] of Object.entries(lock.assets)) {
2222
2452
  if (entry.source?.url !== src.url) continue;
2223
2453
  const { publisher, kind, name, version } = parseCanonicalLockKey(ref);
2224
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;
2225
2459
  result.push({
2226
2460
  kind,
2227
2461
  name,
2228
2462
  publisher: publisher ?? sourceShortName(src.url),
2229
2463
  currentVersion: version ?? "",
2230
- behind: status.behind
2464
+ behind
2231
2465
  });
2232
2466
  reported.add(ref);
2233
2467
  }
@@ -2237,11 +2471,14 @@ var AssetManager = class {
2237
2471
  );
2238
2472
  if (libraryAssets.length > 0) {
2239
2473
  const snap = await this.loadLibraryIndex();
2474
+ const diskHashes = /* @__PURE__ */ new Map();
2475
+ const scans = /* @__PURE__ */ new Map();
2240
2476
  for (const [ref, entry] of libraryAssets) {
2241
2477
  const origin = entry.library;
2242
2478
  const { publisher, kind, name } = parseCanonicalLockKey(ref);
2243
2479
  if (!publisher || !kind || !name) continue;
2244
- if (!this.libraryPath(origin.name, snap)) {
2480
+ const libPath = this.libraryPath(origin.name, snap);
2481
+ if (!libPath) {
2245
2482
  result.push({
2246
2483
  kind,
2247
2484
  name,
@@ -2254,18 +2491,45 @@ var AssetManager = class {
2254
2491
  reported.add(ref);
2255
2492
  continue;
2256
2493
  }
2257
- const def = newestLibraryDef(snap, origin.name, { kind, publisher, name });
2258
- if (!def || !gt(coerceVersion(def.version), coerceVersion(origin.version))) continue;
2259
- result.push({
2260
- kind,
2261
- name,
2262
- publisher,
2263
- currentVersion: origin.version,
2264
- behind: 0,
2265
- latestVersion: def.version,
2266
- library: origin.name
2267
- });
2268
- 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
+ }
2269
2533
  }
2270
2534
  }
2271
2535
  for (const [ref, entry] of Object.entries(lock.assets)) {
@@ -2303,7 +2567,8 @@ var AssetManager = class {
2303
2567
  * @throws When `diff(1)` itself fails (exit status other than 0/1).
2304
2568
  */
2305
2569
  async diff(ref) {
2306
- const parsed = parseAssetRef(ref);
2570
+ const parsed = parseRefTolerant(ref);
2571
+ if (!parsed) return { status: "not-found" };
2307
2572
  const entry = await this.info(ref);
2308
2573
  if (!entry || !existsSync(entry.source)) return { status: "not-found" };
2309
2574
  const component = this.installTarget(parsed.kind);
@@ -2334,12 +2599,12 @@ var AssetManager = class {
2334
2599
  projectDir: this.projectDir,
2335
2600
  knownKinds: this.knownKinds
2336
2601
  });
2337
- const { resolved, missing, overridesApplied } = await this.resolveWithStores(dependencies, {
2602
+ const { resolved, overridesApplied, lib } = await this.resolveLibraryFirst(dependencies, {
2338
2603
  provenanceIndex,
2339
2604
  overrides,
2340
2605
  stores
2341
2606
  });
2342
- const libraryLock = await this.libraryLockEntries(await this.resolveLibraryEntries(missing));
2607
+ const libraryLock = await this.libraryLockEntries(lib);
2343
2608
  const lockData = buildLockFile(resolved, overridesApplied, libraryLock);
2344
2609
  writeLock(this.lockPath, lockData);
2345
2610
  return lockData;
@@ -2433,7 +2698,13 @@ var AssetManager = class {
2433
2698
  *
2434
2699
  * For each deployed asset, checks that all entries in its `requires` list are
2435
2700
  * also deployed. Returns a list of issues with a flag indicating whether the
2436
- * 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.
2437
2708
  *
2438
2709
  * @returns Array of {@link DepIssue} objects. An empty array means the workspace is healthy.
2439
2710
  */
@@ -2441,9 +2712,31 @@ var AssetManager = class {
2441
2712
  const { repositories } = this.loadConfig();
2442
2713
  const deployed = this.listDeployed();
2443
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
+ }
2444
2721
  for (const entry of deployed) {
2445
- const full = await this.info(`${entry.kind}:${entry.name}`);
2446
- 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 = [];
2447
2740
  for (const req of full.requires) {
2448
2741
  const dep = memberIdentity(`${req.kind}:${req.name}`);
2449
2742
  if (!dep) continue;
@@ -2452,15 +2745,19 @@ var AssetManager = class {
2452
2745
  const inRepos = await resolveAsset({ kind: dep.kind, name: dep.name }, repositories, this.reposDir, {
2453
2746
  knownKinds: this.knownKinds
2454
2747
  }) !== null;
2455
- issues.push({
2748
+ const issue = {
2456
2749
  assetKind: entry.kind,
2457
2750
  assetName: entry.name,
2458
2751
  depKind: req.kind,
2459
2752
  depName: req.name,
2460
2753
  inRepos
2461
- });
2754
+ };
2755
+ issues.push(issue);
2756
+ if (!inRepos) gaps.push({ issue, ref: `${dep.kind}:${dep.name}` });
2462
2757
  }
2463
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);
2464
2761
  }
2465
2762
  return issues;
2466
2763
  }
@@ -2473,7 +2770,7 @@ var AssetManager = class {
2473
2770
  * @param destDir - Parent directory to create the asset in.
2474
2771
  * @param opts - Optional scaffold content (`description`).
2475
2772
  * @returns `{ ok: true, path }` on success, `{ ok: false, path: errorMessage }` if the
2476
- * directory already exists.
2773
+ * directory already exists or `kind` has no scaffold template.
2477
2774
  */
2478
2775
  create(name, kind, destDir, opts) {
2479
2776
  return createScaffold(name, kind, destDir, opts);
@@ -2601,15 +2898,44 @@ var AssetManager = class {
2601
2898
  return;
2602
2899
  }
2603
2900
  const raw = parse(readFileSync(configPath, "utf8")) ?? {};
2604
- if (!raw.dependencies) raw.dependencies = [];
2605
- if (!raw.dependencies.includes(ref)) {
2606
- raw.dependencies.push(ref);
2607
- 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;
2608
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(/^@/, "");
2609
2933
  }
2610
2934
  /**
2611
2935
  * Remove a dependency ref from the manifest `dependencies:`. Targets the same
2612
2936
  * file as {@link addDependencyToConfig} (`~/.skaile/skaile.yaml` in global mode).
2937
+ *
2938
+ * @returns `true` when a declaration was removed.
2613
2939
  */
2614
2940
  removeDependencyFromConfig(target) {
2615
2941
  const configPath = join(this.stateRoot, "skaile.yaml");
@@ -2617,15 +2943,15 @@ var AssetManager = class {
2617
2943
  const raw = parse(readFileSync(configPath, "utf8")) ?? {};
2618
2944
  if (!Array.isArray(raw.dependencies)) return false;
2619
2945
  const wantPub = target.publisher?.replace(/^@/, "");
2620
- const idx = raw.dependencies.findIndex((dep) => {
2621
- 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;
2622
2949
  const p = parseAssetRefLoose(dep);
2623
- 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;
2624
2951
  const havePub = p.publisher?.replace(/^@/, "");
2625
- return wantPub === void 0 || havePub === void 0 || havePub === wantPub;
2952
+ return !(wantPub === void 0 || havePub === void 0 || havePub === wantPub);
2626
2953
  });
2627
- if (idx === -1) return false;
2628
- raw.dependencies.splice(idx, 1);
2954
+ if (raw.dependencies.length === before) return false;
2629
2955
  writeFileSync(configPath, stringify(raw, { lineWidth: 120 }));
2630
2956
  return true;
2631
2957
  }
@@ -2647,5 +2973,5 @@ var AssetManager = class {
2647
2973
  };
2648
2974
 
2649
2975
  export { AssetManager, FACTORY_SOURCE_URL, MissingManifestError, installAgentInstances, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, softDepName };
2650
- //# sourceMappingURL=chunk-4CTGEEN6.js.map
2651
- //# sourceMappingURL=chunk-4CTGEEN6.js.map
2976
+ //# sourceMappingURL=chunk-D5HOETOB.js.map
2977
+ //# sourceMappingURL=chunk-D5HOETOB.js.map