@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 +0,0 @@
1
- {"version":3,"sources":["../core/src/models.ts"],"names":[],"mappings":";;;AAuCO,SAAS,SAAS,CAAA,EAAuB;AAC9C,EAAA,MAAM,CAAA,GAAI,CAAA,CAAE,OAAA,CAAQ,GAAG,CAAA;AACvB,EAAA,IAAI,MAAM,EAAA,EAAI;AACZ,IAAA,MAAM,OAAO,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,EAAE,IAAA,EAAK;AAChC,IAAA,MAAM,OAAO,CAAA,CAAE,KAAA,CAAM,CAAA,GAAI,CAAC,EAAE,IAAA,EAAK;AACjC,IAAA,OAAO,EAAE,MAAM,IAAA,EAAK;AAAA,EACtB;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,CAAA,CAAE,MAAK,EAAE;AACzC;AASO,SAAS,SAAS,CAAA,EAAuB;AAC9C,EAAA,OAAO,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,EAAE,IAAI,CAAA,CAAA;AAC5B;AAsEO,SAAS,aAAa,CAAA,EAA0C;AACrE,EAAA,MAAM,UAAU,CAAA,CAAE,YAAA;AAClB,EAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,OAAO,IAAK,OAAA,CAAqB,MAAA,CAAO,OAAO,CAAA,GAAI,EAAC;AAC/E,EAAA,MAAM,KAAA,GAAsB;AAAA,IAC1B,IAAA,EAAM,MAAA,CAAO,CAAA,CAAE,IAAA,IAAQ,EAAE,CAAA;AAAA,IACzB,IAAA,EAAM,MAAA,CAAO,CAAA,CAAE,IAAA,IAAQ,OAAO,CAAA;AAAA,IAC9B,WAAA,EAAa,MAAA,CAAO,CAAA,CAAE,WAAA,IAAe,EAAE,CAAA;AAAA,IACvC,MAAA,EAAQ,MAAA,CAAO,CAAA,CAAE,MAAA,IAAU,EAAE,CAAA;AAAA,IAC7B,WAAW,CAAA,CAAE,SAAA,IAAa,OAAO,MAAA,CAAO,CAAA,CAAE,SAAS,CAAA,GAAI,MAAA;AAAA,IACvD,MAAM,CAAA,CAAE,IAAA,IAAQ,OAAO,MAAA,CAAO,CAAA,CAAE,IAAI,CAAA,GAAI,MAAA;AAAA,IACxC,QAAQ,CAAA,CAAE,MAAA,IAAU,OAAO,MAAA,CAAO,CAAA,CAAE,MAAM,CAAA,GAAI,MAAA;AAAA,IAC9C,OAAA,EAAS,MAAA,CAAO,CAAA,CAAE,OAAA,IAAW,EAAE,CAAA;AAAA,IAC/B,QAAA,EAAU,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,QAAQ,CAAA,GAC7B,CAAA,CAAE,QAAA,CAAsB,MAAA,CAAO,OAAO,CAAA,CAAE,GAAA,CAAI,QAAQ,IACrD,EAAC;AAAA,IACL,YAAA,EAAc;AAAA,GAChB;AACA,EAAA,IAAI,CAAA,CAAE,QAAA,IAAY,IAAA,IAAQ,OAAO,CAAA,CAAE,QAAA,KAAa,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,QAAQ,CAAA,EAAG;AACtF,IAAA,KAAA,CAAM,WAAW,CAAA,CAAE,QAAA;AAAA,EACrB;AACA,EAAA,IAAI,EAAE,QAAA,IAAY,IAAA,QAAY,QAAA,GAAW,MAAA,CAAO,EAAE,QAAQ,CAAA;AAC1D,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,QAAQ,CAAA,EAAG;AAC7B,IAAA,KAAA,CAAM,QAAA,GAAY,EAAE,QAAA,CAAuB,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,MAAM,QAAQ,CAAA;AAAA,EAC7F;AACA,EAAA,IAAI,EAAE,OAAA,IAAW,IAAA,QAAY,OAAA,GAAU,MAAA,CAAO,EAAE,OAAO,CAAA;AACvD,EAAA,IAAI,EAAE,QAAA,IAAY,IAAA,QAAY,QAAA,GAAW,MAAA,CAAO,EAAE,QAAQ,CAAA;AAC1D,EAAA,OAAO,KAAA;AACT;AASO,SAAS,WAAW,CAAA,EAA0C;AACnE,EAAA,MAAM,GAAA,GAA+B;AAAA,IACnC,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,aAAa,CAAA,CAAE,WAAA;AAAA,IACf,QAAQ,CAAA,CAAE,MAAA;AAAA,IACV,WAAW,CAAA,CAAE,SAAA;AAAA,IACb,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,SAAS,CAAA,CAAE,OAAA;AAAA,IACX,GAAI,EAAE,MAAA,IAAU,IAAA,GAAO,EAAE,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO,GAAI,EAAC;AAAA,IAC/C,QAAA,EAAU,CAAA,CAAE,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA;AAAA,IACjC,cAAc,CAAA,CAAE;AAAA,GAClB;AACA,EAAA,IAAI,CAAA,CAAE,QAAA,EAAU,GAAA,CAAI,QAAA,GAAW,CAAA,CAAE,QAAA;AACjC,EAAA,IAAI,CAAA,CAAE,QAAA,IAAY,IAAA,EAAM,GAAA,CAAI,WAAW,CAAA,CAAE,QAAA;AACzC,EAAA,IAAI,CAAA,CAAE,YAAY,CAAA,CAAE,QAAA,CAAS,SAAS,CAAA,EAAG,GAAA,CAAI,WAAW,CAAA,CAAE,QAAA;AAC1D,EAAA,IAAI,CAAA,CAAE,OAAA,IAAW,IAAA,EAAM,GAAA,CAAI,UAAU,CAAA,CAAE,OAAA;AACvC,EAAA,IAAI,CAAA,CAAE,QAAA,IAAY,IAAA,EAAM,GAAA,CAAI,WAAW,CAAA,CAAE,QAAA;AACzC,EAAA,OAAO,GAAA;AACT;AAwBA,IAAM,MAAA,GAAS,iBAAA;AAQf,IAAM,aAAA,GACJ,kHAAA;AAMF,IAAM,aAAA,GAAgB,4BAAA;AAMtB,IAAM,eAAA,GAAkB,mDAAA;AAGjB,IAAM,eAAA,GACX;AASK,SAAS,iBAAiB,IAAA,EAAuB;AACtD,EAAA,OAAO,aAAA,CAAc,KAAK,IAAI,CAAA;AAChC;AAqBO,SAAS,iBAAiB,GAAA,EAAqB;AACpD,EAAA,MAAM,OAAO,GAAA,CACV,SAAA,CAAU,MAAM,CAAA,CAChB,QAAQ,kBAAA,EAAoB,EAAE,CAAA,CAC9B,WAAA,GACA,OAAA,CAAQ,aAAA,EAAe,GAAG,CAAA,CAC1B,OAAA,CAAQ,YAAY,EAAE,CAAA;AACzB,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2CAAA,EAA8C,GAAG,CAAA,SAAA,EAAO,eAAe,CAAA,CAAA,CAAG,CAAA;AAAA,EAC5F;AACA,EAAA,OAAO,IAAA;AACT;AAGA,SAAS,WAAW,GAAA,EAAsB;AACxC,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,EAAG,OAAO,IAAA;AAC7B,EAAA,IAAI,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,EAAG,OAAO,IAAA;AAC9B,EAAA,IAAI,MAAA,CAAO,UAAA,CAAW,GAAG,CAAA,EAAG,OAAO,IAAA;AACnC,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,iBAAA,CAAkB,GAAW,GAAA,EAAoB;AACxD,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,CAAA,mBAAA,EAAsB,GAAG,CAAA,MAAA,EAAS,CAAC,CAAA,8IAAA;AAAA,GAGrC;AACF;AAGA,SAAS,iBAAA,CAAkB,GAAW,IAAA,EAAqB;AACzD,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,CAAA,oBAAA,EAAuB,IAAI,CAAA,UAAA,EAAa,CAAC,YAAO,eAAe,CAAA,gEAAA;AAAA,GAEjE;AACF;AAuBO,SAAS,cAAc,CAAA,EAAqB;AACjD,EAAA,MAAM,OAAA,GAAU,EAAE,IAAA,EAAK;AACvB,EAAA,MAAM,CAAA,GAAI,aAAA,CAAc,IAAA,CAAK,OAAO,CAAA;AACpC,EAAA,IAAI,CAAA,EAAG;AACL,IAAA,MAAM,OAAA,GAAU,CAAA,CAAE,CAAC,CAAA,IAAK,OAAA;AACxB,IAAA,MAAM,IAAA,GAAO,OAAA,KAAY,KAAA,GAAQ,YAAA,GAAe,OAAA;AAChD,IAAA,MAAM,SAAA,GAAY,EAAE,CAAC,CAAA;AACrB,IAAA,MAAM,IAAA,GAAO,EAAE,CAAC,CAAA;AAChB,IAAA,MAAM,GAAA,GAAM,CAAA,CAAE,CAAC,CAAA,EAAG,MAAK,IAAK,MAAA;AAC5B,IAAA,IAAI,CAAC,gBAAA,CAAiB,IAAI,CAAA,EAAG,iBAAA,CAAkB,GAAG,IAAI,CAAA;AACtD,IAAA,IAAI,GAAA,KAAQ,UAAa,CAAC,UAAA,CAAW,GAAG,CAAA,EAAG,iBAAA,CAAkB,GAAG,GAAG,CAAA;AACnE,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,SAAA,EAAW,GAAA,EAAI;AAAA,EACtC;AAOA,EAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,IAAA,CAAK,OAAO,CAAA;AAC3C,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,CAAC,CAAA,CAAE,IAAA,EAAK;AACjC,IAAA,IAAI,CAAC,gBAAA,CAAiB,SAAS,CAAA,EAAG,iBAAA,CAAkB,GAAG,SAAS,CAAA;AAAA,EAClE;AAEA,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,oCAAoC,CAAC,CAAA,uGAAA;AAAA,GAEvC;AACF;AAUO,SAAS,mBAAmB,GAAA,EAA8B;AAC/D,EAAA,IAAI;AACF,IAAA,OAAO,cAAc,GAAG,CAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA;AAC5B,IAAA,IAAI,IAAA,GAAO,GAAG,OAAO,IAAA;AACrB,IAAA,IAAI;AACF,MAAA,OAAO,aAAA,CAAc,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,IAAI,CAAC,CAAA;AAAA,IACzC,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AACF;AAYO,SAAS,cAAc,GAAA,EAAuB;AACnD,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,SAAA,GAAY,CAAA,CAAA,EAAI,GAAA,CAAI,SAAS,CAAA,CAAA,EAAI,GAAA,CAAI,IAAI,CAAA,CAAA,GAAK,GAAA,CAAI,IAAA;AACpE,EAAA,OAAO,CAAA,EAAG,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,EAAG,GAAA,CAAI,GAAA,GAAM,CAAA,CAAA,EAAI,GAAA,CAAI,GAAG,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA;AAC5D;AASO,SAAS,cAAc,GAAA,EAA2B;AAEvD,EAAA,OAAO,EAAE,IAAA,EAAM,GAAA,CAAI,IAAA,EAAM,IAAA,EAAM,IAAI,IAAA,EAAK;AAC1C;AAqHO,SAAS,kBAAkB,CAAA,EAAwC;AACxE,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA,CAAO,CAAA,CAAE,IAAA,IAAQ,EAAE,CAAA;AAAA,IACzB,IAAA,EAAM,MAAA,CAAO,CAAA,CAAE,IAAA,IAAQ,OAAO,CAAA;AAAA,IAC9B,IAAA,EAAM,MAAA,CAAO,CAAA,CAAE,IAAA,IAAQ,EAAE,CAAA;AAAA,IACzB,MAAA,EAAQ,MAAA,CAAO,CAAA,CAAE,MAAA,IAAU,MAAM,CAAA;AAAA,IACjC,UAAU,CAAA,CAAE,QAAA,IAAY,OAAO,MAAA,CAAO,CAAA,CAAE,QAAQ,CAAA,GAAI;AAAA,GACtD;AACF;AAUO,SAAS,gBAAgB,CAAA,EAAwC;AACtE,EAAA,MAAM,CAAA,GAA6B;AAAA,IACjC,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,MAAM,CAAA,CAAE;AAAA,GACV;AACA,EAAA,IAAI,CAAA,CAAE,MAAA,KAAW,MAAA,EAAQ,CAAA,CAAE,SAAS,CAAA,CAAE,MAAA;AACtC,EAAA,IAAI,CAAA,CAAE,QAAA,IAAY,IAAA,EAAM,CAAA,CAAE,WAAW,CAAA,CAAE,QAAA;AACvC,EAAA,OAAO,CAAA;AACT","file":"chunk-AO7VJ6G6.js","sourcesContent":["/**\n * Pure data models — no I/O, no side effects.\n */\n\nimport semver from \"semver\";\n\n/**\n * Discriminator for catalog entries and asset references.\n * Used in asset ref strings (e.g. `'skill:my-skill'`, `'agent:my-agent'`).\n *\n * Any string: the provider registry (`@skaile/workspaces/discovery`\n * `AssetKindRegistry`) is the only authority on which kinds exist — a kind exists\n * iff a provider is registered for it.\n * @docLink packages/core/concepts#asset-kind\n */\nexport type AssetKind = string;\n\n// ── Dependency ────────────────────────────────────────────────────────────────\n\n/**\n * Declared dependency on another catalog asset.\n * @docLink packages/core/concepts#dependency\n */\nexport interface Dependency {\n /** Asset kind (e.g. \"skill\", \"agent\", \"contract\"). */\n kind: string;\n /** Asset name within that kind. */\n name: string;\n /** Canonical publisher namespace (when known). */\n publisher?: string;\n}\n\n/**\n * Parse a `\"kind:name\"` dependency string, or a bare `\"name\"` (defaults kind to `\"skill\"`).\n *\n * @param s - Dependency string, e.g. `\"skill:use-exa\"` or `\"use-exa\"`\n * @returns Parsed `{ kind, name }` dependency object\n * @docLink packages/core/concepts#parse-dep\n */\nexport function parseDep(s: string): Dependency {\n const i = s.indexOf(\":\");\n if (i !== -1) {\n const kind = s.slice(0, i).trim();\n const name = s.slice(i + 1).trim();\n return { kind, name };\n }\n return { kind: \"skill\", name: s.trim() };\n}\n\n/**\n * Serialize a Dependency back to its `\"kind:name\"` string form.\n *\n * @param d - Dependency to serialize\n * @returns String in `\"kind:name\"` format\n * @docLink packages/core/concepts#dep-to-str\n */\nexport function depToStr(d: Dependency): string {\n return `${d.kind}:${d.name}`;\n}\n\n// ── CatalogEntry ──────────────────────────────────────────────────────────────\n\n/**\n * A resolved catalog entry describing an installable asset.\n * Produced by manifest parsers and stored in the catalog YAML.\n * @docLink packages/core/concepts#catalog-entry\n */\nexport interface CatalogEntry {\n /** Unique asset name within its kind. */\n name: string;\n /** Asset kind discriminator. */\n kind: AssetKind;\n /** Short description of what this asset does. */\n description: string;\n /** Absolute path to manifest file */\n source: string;\n /** Canonical publisher namespace this asset belongs to (formerly `repository`). */\n publisher?: string;\n /**\n * Canonical ref (`kind:@publisher/name#version`) the CLI prints for this entry.\n * Set by the asset manager where `publisher` is not the real publisher (a\n * clone-sourced entry carries its clone key there); absent → derived from\n * `publisher` + `version`.\n */\n canonicalRef?: string;\n /**\n * `\"<org>/<repo>\"` coordinate the asset came from. Absent → the asset groups\n * directly under its publisher (local library with no git remote, or a\n * non-GitHub source).\n */\n repo?: string;\n /**\n * Claude plugin (from `.claude-plugin/marketplace.json` / `plugin.json`\n * membership) this asset belongs to, or absent when no plugin lists it.\n * Display-only — groups assets in the manage TUI; never part of identity or\n * the install layout.\n */\n plugin?: string;\n /** Semantic version string (may be empty if not declared in the manifest). */\n version: string;\n /** Skills, agents, or other assets this entry depends on. */\n requires: Dependency[];\n /** Asset refs this entry pulls in (presets: the asset items; flows: `requires`). */\n dependencies: string[];\n /**\n * Kind-specific metadata extracted from the manifest frontmatter.\n * Used by MCP servers to carry default config (transport, command, args, env, url, headers)\n * so that `mcp:name` dependency refs resolve to a runnable declaration without\n * requiring verbose inline config in `skaile.yaml`.\n */\n metadata?: Record<string, unknown>;\n /** Curated facet, surfaced as a badge in the manage TUI (not a tree axis). */\n category?: string;\n /** Store-listing keywords (manifest `assets[].keywords`, else frontmatter). */\n keywords?: string[];\n /** Store-listing license (manifest `assets[].license`, else repo-level default). */\n license?: string;\n /** Store-listing homepage (manifest `assets[].homepage`, else repo-level default). */\n homepage?: string;\n}\n\n/**\n * Construct a CatalogEntry from a raw deserialized record (e.g. from catalog.yaml).\n *\n * @param d - Raw object with loosely typed fields\n * @returns Normalized CatalogEntry\n * @docLink packages/core/concepts#entry-from-raw\n */\nexport function entryFromRaw(d: Record<string, unknown>): CatalogEntry {\n const rawDeps = d.dependencies;\n const deps = Array.isArray(rawDeps) ? (rawDeps as string[]).filter(Boolean) : [];\n const entry: CatalogEntry = {\n name: String(d.name ?? \"\"),\n kind: String(d.kind ?? \"skill\") as AssetKind,\n description: String(d.description ?? \"\"),\n source: String(d.source ?? \"\"),\n publisher: d.publisher != null ? String(d.publisher) : undefined,\n repo: d.repo != null ? String(d.repo) : undefined,\n plugin: d.plugin != null ? String(d.plugin) : undefined,\n version: String(d.version ?? \"\"),\n requires: Array.isArray(d.requires)\n ? (d.requires as string[]).filter(Boolean).map(parseDep)\n : [],\n dependencies: deps,\n };\n if (d.metadata != null && typeof d.metadata === \"object\" && !Array.isArray(d.metadata)) {\n entry.metadata = d.metadata as Record<string, unknown>;\n }\n if (d.category != null) entry.category = String(d.category);\n if (Array.isArray(d.keywords)) {\n entry.keywords = (d.keywords as unknown[]).filter((k): k is string => typeof k === \"string\");\n }\n if (d.license != null) entry.license = String(d.license);\n if (d.homepage != null) entry.homepage = String(d.homepage);\n return entry;\n}\n\n/**\n * Serialize a CatalogEntry to a plain record suitable for YAML/JSON persistence.\n *\n * @param e - CatalogEntry to serialize\n * @returns Plain object with string-serialized requires and dependencies\n * @docLink packages/core/concepts#entry-to-raw\n */\nexport function entryToRaw(e: CatalogEntry): Record<string, unknown> {\n const raw: Record<string, unknown> = {\n name: e.name,\n kind: e.kind,\n description: e.description,\n source: e.source,\n publisher: e.publisher,\n repo: e.repo,\n version: e.version,\n ...(e.plugin != null ? { plugin: e.plugin } : {}),\n requires: e.requires.map(depToStr),\n dependencies: e.dependencies,\n };\n if (e.metadata) raw.metadata = e.metadata;\n if (e.category != null) raw.category = e.category;\n if (e.keywords && e.keywords.length > 0) raw.keywords = e.keywords;\n if (e.license != null) raw.license = e.license;\n if (e.homepage != null) raw.homepage = e.homepage;\n return raw;\n}\n\n// ── AssetRef ─────────────────────────────────────────────────────────────────\n\n/**\n * A parsed asset reference: `kind:@<publisher>/name[#pin]`.\n *\n * `publisher` is the canonical, GitHub-shaped publisher namespace (≤39 chars,\n * alphanumeric+hyphen). `pin` is a SemVer constraint, exact SHA, or absent.\n * Floating refs (`main`, `latest`, `HEAD`) are rejected at parse time.\n *\n * Produced by `parseAssetRef`; consumed by `resolveAsset` and `resolveAll`.\n * @docLink packages/core/concepts#asset-ref\n */\nexport interface AssetRef {\n kind: string;\n name: string;\n /** Canonical publisher namespace. Optional only for ambiguity-resolution\n * during migration; new manifests require it. */\n publisher?: string;\n /** SemVer constraint (^1.4.0, ~1.4, 1.x, exact 1.4.0), 40-char SHA, or undefined. */\n pin?: string;\n}\n\nconst SHA_RE = /^[0-9a-f]{40}$/i;\n\n// Scoped grammar: `kind:@publisher/name[#version]`. The publisher sub-pattern is\n// GitHub-shaped (1-39 chars, alphanumeric + single hyphens, no leading/trailing or\n// double hyphen); `@` is the scope sigil and `#` the version sigil. `name` is\n// intentionally permissive (`[^/#\\s]+` — only the structural separators are\n// forbidden); floating-ref rejection stays in `isValidPin`, so `#main`/`#latest`\n// match here and fail there with a clear message.\nconst SCOPED_REF_RE =\n /^(?:([a-z][a-z0-9-]*):)?@([A-Za-z0-9](?:[A-Za-z0-9]|-(?!-)){0,37}[A-Za-z0-9]|[A-Za-z0-9])\\/([^/#\\s]+)(?:#(.+))?$/;\n\n// Canonical asset-name grammar: lowercase kebab-case (npm-style, scope-free) —\n// `a-z` / `0-9` segments joined by single hyphens, no leading/trailing hyphen,\n// no uppercase, spaces, dots, or underscores. Names become directory names,\n// lock keys, and CLI args, so the constraint is intentionally narrow.\nconst ASSET_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n// Diagnostic-only matcher: a ref carrying a `kind:@publisher/` scope prefix,\n// capturing whatever follows (sans `#pin`) as the candidate name. Used solely\n// to tell \"missing publisher\" apart from \"malformed name\" when the strict\n// grammar above fails (e.g. a space in the name).\nconst SCOPE_PREFIX_RE = /^(?:[a-z][a-z0-9-]*:)?@[^/\\s]+\\/([^#]+?)(?:#.*)?$/;\n\n/** Human-readable statement of the canonical asset-name rule. */\nexport const ASSET_NAME_HINT =\n 'names must be lowercase kebab-case (a-z, 0-9, single hyphens; e.g. \"cli-concept\")';\n\n/**\n * True when `name` is a canonical asset name: lowercase kebab-case, scope-free.\n *\n * This is the single source of truth for asset-name validity — `parseAssetRef`\n * enforces it, and `skaile validate` reports violations across a repo tree.\n * @docLink packages/core/concepts#is-valid-asset-name\n */\nexport function isValidAssetName(name: string): boolean {\n return ASSET_NAME_RE.test(name);\n}\n\n/**\n * Coerce an arbitrary string into a canonical asset name (lowercase kebab-case).\n *\n * For **third-party sources we don't control**, an upstream asset may carry a\n * human-styled identity (`\"Complex App\"`, `\"CLI_Concept\"`). The canonical grammar\n * (`isValidAssetName`) rejects those, so the ingestion boundary slugifies them to\n * a valid identity rather than crashing: Unicode is folded to ASCII, the result is\n * lowercased, every run of non-`[a-z0-9]` becomes a single hyphen, and\n * leading/trailing hyphens are trimmed. The transform is idempotent and a no-op on\n * already-canonical names.\n *\n * This is intentionally **lossy** — the pretty original is not part of identity.\n * Callers that want to preserve it for display must stash it themselves (e.g. on\n * `CatalogEntry.metadata.displayName`). Authoring-time validation (`skaile validate`)\n * still uses `isValidAssetName` on raw frontmatter, so first-party typos surface there.\n *\n * @throws When `raw` contains no `[a-z0-9]` character (nothing to slugify).\n * @docLink packages/core/concepts#slugify-asset-name\n */\nexport function slugifyAssetName(raw: string): string {\n const slug = raw\n .normalize(\"NFKD\")\n .replace(/[\\u0300-\\u036f]/g, \"\") // strip combining accents\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n if (!slug) {\n throw new Error(`cannot derive a canonical asset name from \"${raw}\" — ${ASSET_NAME_HINT}.`);\n }\n return slug;\n}\n\n/** True when `pin` is a SemVer constraint, exact SemVer, or 40-char SHA. */\nfunction isValidPin(pin: string): boolean {\n if (SHA_RE.test(pin)) return true;\n if (semver.valid(pin)) return true;\n if (semver.validRange(pin)) return true;\n return false;\n}\n\n/** Throw the canonical non-canonical-pin error for a ref `s` carrying `pin`. */\nfunction rejectFloatingPin(s: string, pin: string): never {\n throw new Error(\n `non-canonical pin \"${pin}\" in \"${s}\" — pin must be a SemVer ` +\n \"constraint (1.4.0, ^1.4, ~1.4, 1.x), a 40-char SHA, or absent. \" +\n \"Floating refs (main/latest/HEAD) are not allowed.\",\n );\n}\n\n/** Throw the canonical malformed-name error for a ref `s` carrying `name`. */\nfunction rejectInvalidName(s: string, name: string): never {\n throw new Error(\n `invalid asset name \"${name}\" in ref \"${s}\" — ${ASSET_NAME_HINT}. ` +\n \"Run the `migrate-skaile-manifest` skill on legacy manifests.\",\n );\n}\n\n/**\n * Parse a canonical asset reference string into an `AssetRef` object.\n *\n * Grammar: `kind:@<publisher>/name[#version]`\n * \"skill:@skaile-ai/audit\" → { kind: \"skill\", name: \"audit\", publisher: \"skaile-ai\" }\n * \"skill:@skaile-ai/audit#^1.4.0\" → { …, pin: \"^1.4.0\" }\n * \"skill:@skaile-ai/audit#<40-sha>\" → { …, pin: \"<40-sha>\" }\n *\n * `@` is the scope sigil and `#` the version sigil. `<publisher>` is GitHub-shaped\n * (≤39 chars, alphanumeric+hyphen, no leading/trailing or double hyphen). `pin`\n * accepts a SemVer constraint (`^`, `~`, `x`, exact), a 40-char SHA, or is absent.\n * Floating refs (`main`/`latest`/`HEAD`/anything non-canonical) are parse-time errors.\n *\n * The shorthand `mcp:` is normalized to `mcp-server:`. `kind` defaults to `\"skill\"`.\n *\n * @param s - Asset reference string\n * @returns Parsed `AssetRef`\n * @throws When the ref matches no grammar, the publisher is malformed, or the pin\n * is a floating ref.\n * @docLink packages/core/concepts#parse-asset-ref\n */\nexport function parseAssetRef(s: string): AssetRef {\n const trimmed = s.trim();\n const m = SCOPED_REF_RE.exec(trimmed);\n if (m) {\n const kindRaw = m[1] ?? \"skill\";\n const kind = kindRaw === \"mcp\" ? \"mcp-server\" : kindRaw;\n const publisher = m[2];\n const name = m[3];\n const pin = m[4]?.trim() || undefined;\n if (!isValidAssetName(name)) rejectInvalidName(s, name);\n if (pin !== undefined && !isValidPin(pin)) rejectFloatingPin(s, pin);\n return { kind, name, publisher, pin };\n }\n\n // The strict grammar failed. If the ref nonetheless carries a `@publisher/`\n // scope and the fault is the name (e.g. an embedded space), surface a\n // name-specific error rather than the misleading \"publisher required\" — the\n // publisher is plainly present. A *valid* captured name means the publisher\n // itself is malformed, so fall through to the publisher error below.\n const scoped = SCOPE_PREFIX_RE.exec(trimmed);\n if (scoped) {\n const candidate = scoped[1].trim();\n if (!isValidAssetName(candidate)) rejectInvalidName(s, candidate);\n }\n\n throw new Error(\n `publisher required in asset ref \"${s}\" — use \\`kind:@<publisher>/name\\`. ` +\n \"Run the `migrate-skaile-manifest` skill on legacy manifests.\",\n );\n}\n\n/**\n * Parse a ref for identity matching, tolerating a non-canonical pin. A lock key\n * can pin a content-sha pseudo-version (`#0.0.0-sha.<hash>`) that\n * {@link parseAssetRef} rejects; matchers only need the version-agnostic\n * `kind/publisher/name`, so drop the pin and retry before giving up.\n *\n * @returns The parsed ref (its `pin` empty when the pin was dropped), or `null`.\n */\nexport function parseAssetRefLoose(ref: string): AssetRef | null {\n try {\n return parseAssetRef(ref);\n } catch {\n const hash = ref.indexOf(\"#\");\n if (hash < 0) return null;\n try {\n return parseAssetRef(ref.slice(0, hash));\n } catch {\n return null;\n }\n }\n}\n\n/**\n * Serialize an AssetRef back to its canonical string form.\n *\n * Emits the scope form `kind:@publisher/name[#pin]` when `publisher` is present,\n * and the bare `kind:name[#pin]` form for transitive refs that inherit it.\n *\n * @param ref - AssetRef to serialize\n * @returns String in `\"kind:@publisher/name[#pin]\"` (or bare `\"kind:name[#pin]\"`) format\n * @docLink packages/core/concepts#asset-ref-to-str\n */\nexport function assetRefToStr(ref: AssetRef): string {\n const scope = ref.publisher ? `@${ref.publisher}/${ref.name}` : ref.name;\n return `${ref.kind}:${scope}${ref.pin ? `#${ref.pin}` : \"\"}`;\n}\n\n/**\n * Convert an AssetRef to a simple Dependency, dropping the repository and pin qualifiers.\n *\n * @param ref - Full asset reference (may include repository and pin)\n * @returns Dependency with only kind and name\n * @docLink packages/core/concepts#asset-ref-to-dep\n */\nexport function assetRefToDep(ref: AssetRef): Dependency {\n // Grammar-agnostic — drops publisher/pin, so the scope-sigil change doesn't touch it.\n return { kind: ref.kind, name: ref.name };\n}\n\n// ── Lock File ────────────────────────────────────────────────────────────────\n\n/** A path/sha256 pair recorded for one file inside a locked asset. */\nexport interface LockFileEntry {\n path: string;\n sha256: string;\n}\n\n/**\n * Library-origin marker on a {@link LockEntry}: the asset was resolved from a\n * registered library (a local authoring place) rather than a git source/store.\n */\nexport interface LockLibraryOrigin {\n /** Name of the library the asset was resolved from. */\n name: string;\n /** Library version of the asset at lock time. */\n version: string;\n /** Content hash recorded in the library index at lock time; absent when the library was never indexed. */\n sha256?: string;\n /**\n * Set by `skaile asset install`: the files were copied or linked straight into\n * the project, not deployed from a `skaile.yaml` dependency. `skaile install`\n * leaves such an entry and its files alone instead of reconciling them away.\n */\n installed?: \"copy\" | \"link\";\n}\n\n/**\n * Per-asset entry in the lock file (v3 schema).\n * Keyed in `LockFile.assets` by canonical ref (`<kind>:@<publisher>/<name>#<version>`).\n * Source-origin entries carry `source` + `files`; library-origin entries carry\n * `library` instead (no `source`, empty `files`). Both fields are additive, so\n * lock files written before library origin existed still load unchanged.\n * @docLink packages/core/api-reference#lock-entry\n */\nexport interface LockEntry {\n /** Composite sha256 over sorted `<path>:<sha256>\\n` rows (library-origin: the library's hash, `\"\"` when unknown). */\n sha256: string;\n /** Resolved upstream source + commit. Absent for library-origin entries. */\n source?: { url: string; commit: string };\n /** Files that constitute the asset. Empty for library-origin entries. */\n files: LockFileEntry[];\n /** True when an `overrides[]` entry pinned this resolution. */\n override_applied: boolean;\n /** Set when the asset was resolved from a registered library. */\n library?: LockLibraryOrigin;\n}\n\n/** Per-source-URL entry in `LockFile.sources`. */\nexport interface LockSourceEntry {\n url: string;\n commit: string;\n}\n\n/**\n * Full skaile.lock.yaml structure (v3 schema).\n * @docLink packages/core/api-reference#lock-file\n */\nexport interface LockFile {\n /**\n * Lock file schema version: 3, or 4 when the lock holds a library-origin\n * entry (no `source`), so CLIs that predate library origin reject it cleanly.\n */\n schema_version: 3 | 4;\n /** ISO timestamp of when the lock was generated. */\n locked_at: string;\n /** Resolved assets keyed by canonical ref `<kind>:@<publisher>/<name>#<version>`. */\n assets: Record<string, LockEntry>;\n /** Every source URL that contributed at least one resolved asset. */\n sources: LockSourceEntry[];\n /**\n * Resolved plugin packages (from `skaile.yaml` `plugins:`), keyed by package\n * name. The plugin-store reconciler reads this slice into its reconcile-hash\n * so a lock change reinstalls even when the manifest list is unchanged.\n */\n plugins?: Record<string, LockPluginEntry>;\n}\n\n/** One pinned plugin package in the lock file's `plugins` slice. */\nexport interface LockPluginEntry {\n /** Resolved exact version (e.g. \"0.1.3\"). */\n version: string;\n /** Package integrity hash (e.g. \"sha512-...\"); may be empty until populated from bun's output. */\n integrity: string;\n}\n\n// ── Repository ───────────────────────────────────────────────────────────────\n\ntype RepositoryKind = \"local\" | \"github\";\n\n/**\n * A registered asset repository (local path or cloned GitHub repo).\n * Stored in the catalog; consumed by `repo-manager` for cloning and scanning.\n * @docLink packages/core/concepts#repository\n */\nexport interface Repository {\n /** Logical repository name. */\n name: string;\n /** Storage kind: \"local\" for paths, \"github\" for remote URLs. */\n kind: RepositoryKind;\n /** Absolute path (local) or remote URL (github). */\n path: string;\n /** Active branch. */\n branch: string;\n /** Upstream fork URL (for fork-based workflows). */\n upstream?: string;\n}\n\n/**\n * Construct a `Repository` from a raw deserialized record.\n *\n * @param d - Raw object from YAML/JSON\n * @returns Normalized `Repository`\n * @docLink packages/core/concepts#repository-from-raw\n */\nexport function repositoryFromRaw(d: Record<string, unknown>): Repository {\n return {\n name: String(d.name ?? \"\"),\n kind: String(d.kind ?? \"local\") as RepositoryKind,\n path: String(d.path ?? \"\"),\n branch: String(d.branch ?? \"main\"),\n upstream: d.upstream != null ? String(d.upstream) : undefined,\n };\n}\n\n/**\n * Serialize a `Repository` to a plain record for YAML/JSON persistence.\n * Omits the `branch` field when it equals `\"main\"` to keep serialized output clean.\n *\n * @param r - Repository to serialize\n * @returns Plain object suitable for YAML/JSON\n * @docLink packages/core/concepts#repository-to-raw\n */\nexport function repositoryToRaw(r: Repository): Record<string, unknown> {\n const d: Record<string, unknown> = {\n name: r.name,\n kind: r.kind,\n path: r.path,\n };\n if (r.branch !== \"main\") d.branch = r.branch;\n if (r.upstream != null) d.upstream = r.upstream;\n return d;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../asset-manager/src/install-agent.ts","../asset-manager/src/installer.ts"],"names":["parseYaml","join","resolve","basename","existsSync"],"mappings":"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","file":"chunk-IPWR33AW.js","sourcesContent":["/**\n * Agent installation — renders a GitAgent package (agent.yaml + SOUL.md + RULES.md)\n * into the framework-native format (`.claude/agents/<name>.md`, `.omp/agents/<name>/`,\n * `.codex/agents/<name>.toml`) and resolves abilities, contracts, fragments, and\n * prompt extensions from the workspace config along the way.\n *\n * System prompt phases (per agent):\n * 1. extends merge — inherit from parent agent.yaml if manifest.extends is set\n * 2. instance overrides — model / budget / lifecycle of the `skaile.yaml` instance\n * 3. ability refs — read SKILL.md frontmatter of the composed skills\n * 4. contract refs — locate CONTRACT.md files of the composed contracts\n * 5. fragments — resolve framework fragments (agent-mode, handoff, etc.)\n * 6. prompt-extensions — load per-project markdown extensions from skaile.yaml\n *\n * Used by `installer.ts` (the asset-install path, one agent asset under its own\n * name) and `install-instances.ts` (`skaile install`, one rendering per\n * `skaile.yaml` agent instance, named by the instance id). Sub-agents composed as\n * `composes: [{ kind: agent }]` (binding `delegate`, the default) are installed\n * flat (no nesting) in the same deploy directory; `binding: run` sub-agents are\n * host-executed and get no native file.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { basename, join, relative, resolve } from \"node:path\";\nimport type { AgentInstanceConfig, DriverTarget, SkWorkspaceConfig } from \"@skaile/workspaces/core\";\nimport {\n AGENT_INSTANCE_ID_PATTERN,\n DRIVER_TARGETS,\n parseAssetRefLoose,\n resolveAgentDefinitionDir,\n} from \"@skaile/workspaces/core\";\nimport type { AgentComposeItem, AgentLifecycle } from \"@skaile/workspaces/types/manifests\";\nimport { parse as parseYaml } from \"yaml\";\nimport {\n type AbilityRef,\n type ConnectorRef,\n type ContractRef,\n type FragmentContext,\n loadPromptExtensions,\n resolveFragments,\n} from \"./fragments.js\";\nimport { type AgentManifest, type AgentRenderInput, renderAgentToFramework } from \"./renderers.js\";\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction readManifest(agentDir: string): AgentManifest | null {\n const yamlPath = join(agentDir, \"agent.yaml\");\n if (!existsSync(yamlPath)) return null;\n try {\n return parseYaml(readFileSync(yamlPath, \"utf-8\")) as AgentManifest;\n } catch {\n return null;\n }\n}\n\nfunction readFile(agentDir: string, name: string): string | null {\n const p = join(agentDir, name);\n if (!existsSync(p)) return null;\n try {\n return readFileSync(p, \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/**\n * A name becomes a file or directory name under the deploy dir; one with a path\n * segment (`../x`, `a/b`) would write outside it. Refused, never sanitized.\n */\nfunction isSafeFileName(name: string): boolean {\n return name.length > 0 && name !== \".\" && name !== \"..\" && !/[\\\\/\\0]/.test(name);\n}\n\n/** Extract YAML frontmatter from a markdown file (content between first two --- delimiters). */\nfunction parseFrontmatter(content: string): Record<string, unknown> {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return {};\n try {\n return (parseYaml(match[1]!) as Record<string, unknown>) ?? {};\n } catch {\n return {};\n }\n}\n\n/**\n * Merge parent and child agent manifests.\n * Scalars: child wins. Arrays: parent + child, deduplicated (`composes` by\n * kind + ref + slot id, other arrays by value).\n */\nfunction mergeManifests(parent: AgentManifest, child: AgentManifest): AgentManifest {\n const result: AgentManifest = { ...parent };\n for (const [k, val] of Object.entries(child) as [keyof AgentManifest, unknown][]) {\n if (val === undefined) continue;\n const parentVal = result[k as keyof AgentManifest];\n if (k === \"composes\" && Array.isArray(val) && Array.isArray(parentVal)) {\n const merged = new Map<string, AgentComposeItem>();\n for (const item of [...parentVal, ...val] as AgentComposeItem[]) {\n merged.set(`${item.kind}\\u0000${item.ref}\\u0000${item.id ?? \"\"}`, item);\n }\n result.composes = [...merged.values()];\n } else if (Array.isArray(val) && Array.isArray(parentVal)) {\n (result as Record<string, unknown>)[k] = [...new Set([...parentVal, ...val])];\n } else {\n (result as Record<string, unknown>)[k] = val;\n }\n }\n return result;\n}\n\n/**\n * Phase 1: inherit scalars/arrays from a parent agent when `manifest.extends` is set.\n * Returns the (possibly merged) manifest; pushes a warning when the parent is missing.\n */\nfunction applyExtendsMerge(\n manifest: AgentManifest,\n srcDir: string,\n warnings: string[],\n): AgentManifest {\n if (!manifest.extends) return manifest;\n const parentDir = resolve(srcDir, manifest.extends);\n const parentManifest = readManifest(parentDir);\n if (parentManifest) {\n return mergeManifests(parentManifest, manifest);\n }\n warnings.push(\n `extends: parent agent not found at \"${manifest.extends}\" (from ${srcDir}) — skipping inheritance`,\n );\n return manifest;\n}\n\n/**\n * Phase 2: apply the instance's overrides to the asset's manifest — the model\n * selector, the turn budget (`budget.max_turns` → `runtime.max_turns`) and the\n * lifecycle. Returns the effective manifest and lifecycle.\n */\nfunction applyInstanceOverrides(\n manifest: AgentManifest,\n instance: AgentInstanceConfig | undefined,\n): { manifest: AgentManifest; lifecycle: AgentLifecycle } {\n const lifecycle = instance?.lifecycle ?? manifest.lifecycle ?? \"standing\";\n if (!instance) return { manifest, lifecycle };\n const effective: AgentManifest = { ...manifest, lifecycle };\n if (instance.model) {\n effective.model = { ...manifest.model, ...instance.model } as AgentManifest[\"model\"];\n }\n if (instance.budget?.max_turns !== undefined) {\n effective.runtime = { ...manifest.runtime, max_turns: instance.budget.max_turns };\n }\n return { manifest: effective, lifecycle };\n}\n\n/**\n * The name a composed asset is installed under: the asset name of a canonical\n * ref (`skill:@pub/name#1.0.0` → `name`), else the last path segment\n * (`./skills/name` → `name`).\n */\nfunction composeRefName(ref: string): string {\n const parsed = parseAssetRefLoose(ref);\n if (parsed) return parsed.name;\n const tail = ref.replace(/\\/+$/, \"\").split(\"/\").pop() ?? ref;\n return tail.replace(/^[a-z-]+:/, \"\").replace(/#.*$/, \"\") || ref;\n}\n\n/** Names of the composed items of `kind`, in declaration order, de-duplicated. */\nfunction composedNames(manifest: AgentManifest, kind: string): string[] {\n const names = (manifest.composes ?? [])\n .filter((item) => item.kind === kind)\n .map((item) => composeRefName(item.ref));\n return [...new Set(names)];\n}\n\n/**\n * The MCP servers an agent's `mcp-server` slots are bound to: the server the\n * instance's `connectors` map binds the slot id to, else the composed asset's\n * own name (the id its server is rendered under).\n */\nfunction boundMcpServers(\n manifest: AgentManifest,\n instance: AgentInstanceConfig | undefined,\n): string[] {\n const names = (manifest.composes ?? [])\n .filter((item) => item.kind === \"mcp-server\")\n .map(\n (item) => (item.id ? instance?.connectors?.[item.id] : undefined) ?? composeRefName(item.ref),\n );\n return [...new Set(names)];\n}\n\n/** Phase 3: resolve ability refs — read description from the installed SKILL.md of each composed skill. */\nfunction resolveAbilityRefs(\n manifest: AgentManifest,\n workspaceRoot: string,\n skillsRelDir: string,\n): AbilityRef[] {\n const abilityRefs: AbilityRef[] = [];\n for (const name of composedNames(manifest, \"skill\")) {\n const skillMdPath = join(workspaceRoot, skillsRelDir, name, \"SKILL.md\");\n if (!existsSync(skillMdPath)) continue;\n try {\n const fm = parseFrontmatter(readFileSync(skillMdPath, \"utf-8\"));\n const desc = typeof fm.description === \"string\" ? fm.description : undefined;\n if (desc) abilityRefs.push({ name, description: desc });\n } catch {\n // skip unreadable SKILL.md\n }\n }\n return abilityRefs;\n}\n\n/** Phase 4: resolve contract refs — locate the CONTRACT.md of each composed contract in the skills dir. */\nfunction resolveContractRefs(\n manifest: AgentManifest,\n workspaceRoot: string,\n skillsRelDir: string,\n): ContractRef[] {\n const contractRefs: ContractRef[] = [];\n for (const name of composedNames(manifest, \"contract\")) {\n const contractAbsPath = join(workspaceRoot, skillsRelDir, name, \"CONTRACT.md\");\n if (!existsSync(contractAbsPath)) continue;\n contractRefs.push({ name, relativePath: relative(workspaceRoot, contractAbsPath) });\n }\n return contractRefs;\n}\n\n/** A `kind: agent` composition item rendered as its own native sub-agent file. */\ninterface DelegateSubAgent {\n /** `composes[].ref` as written. */\n ref: string;\n /** Absolute path of the sub-agent's source directory. */\n srcDir: string;\n /** File name: the item's `as`, else the sub-agent's own `name`. */\n name: string;\n /** `composes[].as`, forwarded as the install name override. */\n alias: string | undefined;\n}\n\n/**\n * Phase 5a: the `delegate` sub-agents of an agent — its `kind: agent` items\n * whose binding is not `run` (`delegate` is the default for the harnesses that\n * render native agent files). Catalog refs resolve like `agents.<id>.ref`;\n * anything else is a path relative to the composing agent's directory. An\n * unresolvable item is skipped with a warning.\n */\nfunction resolveDelegates(\n manifest: AgentManifest,\n agentName: string,\n srcDir: string,\n workspaceRoot: string,\n warnings: string[],\n): DelegateSubAgent[] {\n const delegates: DelegateSubAgent[] = [];\n for (const item of manifest.composes ?? []) {\n if (item.kind !== \"agent\" || item.binding === \"run\") continue;\n let subSrc: string | undefined;\n try {\n subSrc =\n item.ref.startsWith(\"agent:\") || item.ref.startsWith(\"ai-assets://\")\n ? resolveAgentDefinitionDir(workspaceRoot, item.ref)\n : resolve(srcDir, item.ref);\n } catch (err) {\n warnings.push(\n `Sub-agent ${item.ref} (from ${agentName}): ${err instanceof Error ? err.message : String(err)}`,\n );\n continue;\n }\n if (!subSrc || !existsSync(subSrc)) {\n warnings.push(`Sub-agent source not found: ${item.ref} (from ${agentName})`);\n continue;\n }\n const sub = readManifest(subSrc);\n const name = item.as ?? sub?.name ?? basename(subSrc);\n // The name is a file name under the deploy dir: refuse anything that is not a plain id.\n if (typeof name !== \"string\" || !AGENT_INSTANCE_ID_PATTERN.test(name)) {\n warnings.push(\n `Sub-agent ${item.ref} (from ${agentName}): name ${JSON.stringify(name)} must match ${AGENT_INSTANCE_ID_PATTERN} — skipped`,\n );\n continue;\n }\n delegates.push({\n ref: item.ref,\n srcDir: subSrc,\n name,\n alias: item.as,\n });\n }\n return delegates;\n}\n\n/** Phase 5b: assemble the fragment context from the manifest, workspace config, and resolved refs. */\nfunction buildFragmentContext(\n subAgentNames: string[],\n driverTarget: string,\n skillsRelDir: string,\n wsConfig: SkWorkspaceConfig | undefined,\n abilityRefs: AbilityRef[],\n contractRefs: ContractRef[],\n): FragmentContext {\n const connectors: ConnectorRef[] = (wsConfig?.connectors ?? []).map((c) => ({\n id: c.id,\n driver: c.driver,\n access: c.access ?? \"read-write\",\n }));\n\n const agentsRelDir = DRIVER_TARGETS[driverTarget as DriverTarget]?.local.agent ?? \"\";\n\n return {\n framework: driverTarget,\n skillsDir: skillsRelDir,\n agentsDir: agentsRelDir,\n subAgents: subAgentNames,\n connectors,\n abilityRefs,\n contractRefs,\n };\n}\n\n// ── Core installation ─────────────────────────────────────────────────────────\n\n/**\n * Install a single GitAgent source directory using the appropriate renderer.\n *\n * When `includeSubAgents` is `true`, recursively installs the `delegate`\n * sub-agents (`composes: [{ kind: agent }]`) as separate flat agents in the\n * same deploy directory (no nesting). Tracks visited directories to prevent\n * infinite loops in sub-agent cycles.\n *\n * @param srcDir - Absolute path to the GitAgent source directory (contains `agent.yaml`).\n * @param agentDeployDir - Absolute path to the framework's agent deploy directory.\n * @param workspaceRoot - Absolute path to the workspace root.\n * @param driverTarget - Agent framework ID used to select the renderer.\n * @param skillsRelDir - Relative path to the installed skills dir (e.g. `\".claude/skills\"`).\n * @param nameOverride - Override name for the installed agent. Defaults to `manifest.name`;\n * an instance render passes the instance id.\n * @param includeSubAgents - When `true`, recursively install `delegate` sub-agents.\n * @param visited - Set of resolved source paths already processed (cycle guard).\n * @param wsConfig - Workspace config from `skaile.yaml` (fragments, connectors, extensions).\n * @param log - Optional logger callback for progress messages.\n * @param instance - The `skaile.yaml` instance being rendered; its model / budget / lifecycle\n * override the asset's and its `connectors` map binds the `mcp-server` slots.\n * @returns Object with `created` file paths and `warnings` list.\n * @docLink packages/asset-manager/concepts#install-agent\n */\nexport function installAgent(\n srcDir: string,\n agentDeployDir: string,\n workspaceRoot: string,\n driverTarget: string,\n /** Relative path to the installed skills dir (e.g. \".claude/skills\") */\n skillsRelDir: string,\n nameOverride: string | undefined,\n includeSubAgents: boolean,\n visited: Set<string>,\n wsConfig: SkWorkspaceConfig | undefined,\n log?: (msg: string) => void,\n instance?: AgentInstanceConfig,\n): { created: string[]; warnings: string[] } {\n const created: string[] = [];\n const warnings: string[] = [];\n\n const realSrc = resolve(srcDir);\n if (visited.has(realSrc)) return { created, warnings };\n visited.add(realSrc);\n\n const initialManifest = readManifest(srcDir);\n if (!initialManifest) {\n warnings.push(`${srcDir} has no agent.yaml — skipping (not a valid GitAgent package)`);\n return { created, warnings };\n }\n\n // Phase 1: extends merge — inherit scalars/arrays from parent agent\n // Phase 2: instance overrides — model / budget / lifecycle\n const { manifest, lifecycle } = applyInstanceOverrides(\n applyExtendsMerge(initialManifest, srcDir, warnings),\n instance,\n );\n\n const agentName = nameOverride ?? manifest.name ?? basename(srcDir);\n if (typeof agentName !== \"string\" || !isSafeFileName(agentName)) {\n warnings.push(\n `${srcDir}: agent name ${JSON.stringify(agentName)} is not a valid file name (no path separators) — skipping`,\n );\n return { created, warnings };\n }\n\n log?.(`Installing git-agent: ${agentName} (${driverTarget})`);\n\n // Phase 3: resolve ability refs — read description from installed SKILL.md files\n const abilityRefs = resolveAbilityRefs(manifest, workspaceRoot, skillsRelDir);\n\n // Phase 4: resolve contract refs — locate CONTRACT.md files in the skills dir\n const contractRefs = resolveContractRefs(manifest, workspaceRoot, skillsRelDir);\n\n // Phase 5: delegate sub-agents, fragment context, framework fragments + prompt extensions\n const delegates = resolveDelegates(manifest, agentName, srcDir, workspaceRoot, warnings);\n const fragmentCtx = buildFragmentContext(\n delegates.map((d) => d.name),\n driverTarget,\n skillsRelDir,\n wsConfig,\n abilityRefs,\n contractRefs,\n );\n\n const frameworkFragments = resolveFragments(\n fragmentCtx,\n wsConfig?.agent?.fragments,\n workspaceRoot,\n );\n const promptExtensions = loadPromptExtensions(\n wsConfig?.agent?.[\"prompt-extensions\"],\n workspaceRoot,\n );\n\n const input: AgentRenderInput = {\n manifest,\n soul: readFile(srcDir, \"SOUL.md\"),\n rules: readFile(srcDir, \"RULES.md\"),\n duties: readFile(srcDir, \"DUTIES.md\"),\n agentName,\n agentDeployDir,\n workspaceRoot,\n abilityRefs,\n contractRefs,\n frameworkFragments,\n promptExtensions,\n lifecycle,\n skills: composedNames(manifest, \"skill\"),\n mcpServers: boundMcpServers(manifest, instance),\n };\n\n const result = renderAgentToFramework(input, driverTarget, log);\n created.push(...result.created);\n warnings.push(...result.warnings);\n\n // Recursively install delegate sub-agents as flat top-level agents\n if (includeSubAgents) {\n for (const delegate of delegates) {\n const sub = installAgent(\n delegate.srcDir,\n agentDeployDir,\n workspaceRoot,\n driverTarget,\n skillsRelDir,\n delegate.alias, // undefined → the sub-agent's own name from its agent.yaml\n includeSubAgents,\n visited,\n wsConfig,\n log,\n );\n created.push(...sub.created);\n warnings.push(...sub.warnings);\n }\n }\n\n return { created, warnings };\n}\n","/**\n * Asset deployment — copies assets into framework dirs by default (self-contained,\n * cache-safe, portable); `--link` opts into a symlink for the local-path dev loop.\n */\n\nimport {\n cpSync,\n existsSync,\n lstatSync,\n mkdirSync,\n readdirSync,\n rmSync,\n statSync,\n symlinkSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport type {\n AiComponent,\n CatalogEntry,\n DriverTarget,\n SourceDeclaration,\n} from \"@skaile/workspaces/core\";\nimport {\n applyPatch,\n assetRefToStr,\n computeHash,\n DRIVER_TARGETS,\n deployedBase,\n deployedDir,\n isDeployed,\n resolveSkWorkspaceConfig,\n} from \"@skaile/workspaces/core\";\nimport {\n SKILL_BODY_PLACEHOLDER,\n SKILL_DESCRIPTION_PLACEHOLDER,\n SKILL_DESCRIPTION_PLACEHOLDER_PREFIX,\n} from \"@skaile/workspaces/types/manifests\";\nimport type { IAssetKindProvider, IAssetKindRegistry } from \"@skaile/workspaces/plugins\";\nimport { installAgent } from \"./install-agent.js\";\nimport type { Log } from \"./renderers.js\";\n\nexport type { Log } from \"./renderers.js\";\n\nconst noop: Log = () => {};\n\n/**\n * The printable canonical ref of a resolved entry — `kind:@publisher/name#version`,\n * the one ref grammar the CLI shows. An entry whose `publisher` is a clone key\n * carries the real ref in `canonicalRef`; with neither a `canonicalRef` nor a\n * publisher there is nothing to namespace it by, so it falls back to `kind:name`.\n */\nexport function canonicalEntryRef(entry: CatalogEntry): string {\n if (entry.canonicalRef) return entry.canonicalRef;\n const publisher = entry.publisher?.replace(/^@/, \"\");\n if (!publisher) return `${entry.kind}:${entry.name}`;\n return assetRefToStr({\n kind: entry.kind,\n name: entry.name,\n publisher,\n pin: entry.version || undefined,\n });\n}\n\n// ── Filesystem helpers ────────────────────────────────────────────────────────\n\nfunction clearDest(dest: string): void {\n try {\n const s = lstatSync(dest);\n if (s.isSymbolicLink()) unlinkSync(dest);\n else rmSync(dest, { recursive: true, force: true });\n } catch {}\n}\n\n/**\n * The harness component directory a kind installs into — the provider's\n * `installTarget` — or `undefined` for composition-only kinds (connector,\n * mcp-server, knowledge, persona, ruleset, preset) and unregistered kinds.\n * The registry is the only authority: there is no static list of deployable kinds.\n */\nexport function installTargetOf(\n registry: IAssetKindRegistry,\n kind: string,\n): AiComponent | undefined {\n return registry.getProvider(kind)?.installTarget;\n}\n\n/**\n * The manifest file of a resolved entry. `source` is normally the manifest file\n * itself; a directory source is searched for the provider's manifest.\n * `undefined` when `source` is a directory holding none.\n */\nfunction manifestFileOf(provider: IAssetKindProvider, source: string): string | undefined {\n if (!statSync(source).isDirectory()) return source;\n const hit = readdirSync(source).find((f) => provider.matchesPath(f));\n return hit ? join(source, hit) : undefined;\n}\n\n/**\n * A resolved entry ready to deploy: a {@link CatalogEntry} that may carry the\n * asset's authoritative file list.\n */\nexport interface DeployableEntry extends CatalogEntry {\n /**\n * Asset files relative to the manifest's directory. Set for store-staged\n * assets, whose verified pointer (not the provider's default filter) defines\n * what the asset is — a manifest-mode publish may list files the default filter\n * would not pick. Absent → the provider's `defaultFileFilter`.\n */\n files?: readonly string[];\n}\n\n/**\n * Copy an asset into `dest`: the entry's explicit `files` when it has them, else\n * exactly the files the provider's `defaultFileFilter` selects (the same set the\n * store publishes and hashes). A directory source without a recognisable\n * manifest is copied whole.\n */\nfunction copyAsset(provider: IAssetKindProvider, entry: DeployableEntry, dest: string): void {\n const source = entry.source;\n clearDest(dest);\n const manifestPath = manifestFileOf(provider, source);\n if (!manifestPath) {\n cpSync(source, dest, { recursive: true });\n return;\n }\n const filter = provider.defaultFileFilter(manifestPath);\n const assetRoot = filter.assetRoot;\n const files = entry.files ?? filter.files;\n mkdirSync(dest, { recursive: true });\n for (const rel of files) {\n const target = join(dest, rel);\n mkdirSync(dirname(target), { recursive: true });\n cpSync(join(assetRoot, rel), target);\n }\n}\n\n/**\n * Symlink an asset (the `--link` dev-loop). A multi-file asset, or one living in\n * a directory named after it, links its whole directory; a lone manifest file\n * links into `dest/`.\n */\nfunction symlinkAsset(\n provider: IAssetKindProvider,\n source: string,\n dest: string,\n name: string,\n): void {\n clearDest(dest);\n mkdirSync(dirname(dest), { recursive: true });\n const manifestPath = manifestFileOf(provider, source);\n if (!manifestPath) {\n symlinkSync(resolve(source), dest);\n return;\n }\n const { assetRoot, files } = provider.defaultFileFilter(manifestPath);\n if (files.length > 1 || basename(assetRoot) === name) {\n symlinkSync(resolve(assetRoot), dest);\n } else {\n mkdirSync(dest, { recursive: true });\n symlinkSync(resolve(manifestPath), join(dest, basename(manifestPath)));\n }\n}\n\n// ── Deploy options ───────────────────────────────────────────────────────────\n\n/**\n * Options controlling where and how assets are deployed.\n *\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport interface DeployOptions {\n /** Asset-kind registry — decides, per kind, the harness install target and file set. */\n registry: IAssetKindRegistry;\n /** Agent framework to target (determines framework-specific directory layout). Defaults to `\"claude-code\"`. */\n driverTarget?: DriverTarget;\n /** When `true`, deploy into the global Skaile cache rather than a project workspace. */\n global?: boolean;\n /** Absolute path to the workspace root. Defaults to `process.cwd()`. */\n cwd?: string;\n /**\n * Opt into a symlink (the author dev-loop) instead of a copy — honoured only\n * when the source has a real local path. Machine-local / not for committing;\n * for store/factory sources (no stable local path) it is a no-op (still copy).\n */\n link?: boolean;\n}\n\n// ── Deploy / remove ──────────────────────────────────────────────────────────\n\n/**\n * Deploy a single asset to the framework-specific directory.\n *\n * Copies by default — self-contained, cache-safe, and portable, so a deployed\n * asset survives a `cache clean` of its source and a committed `.claude/` stays\n * machine-independent. `opts.link` opts into a symlink (the live dev-loop), but\n * only when the source has a real local path; store/factory sources (no stable\n * local path) ignore it and still copy. Agents are rendered via the enriched\n * `installAgent` path which resolves abilities, contracts, and framework\n * fragments before writing the native agent file.\n *\n * @param entry - Catalog entry describing the asset to deploy.\n * @param repositories - Repository declarations from `skaile.yaml` (used to\n * determine whether the source is a local path or a remote clone).\n * @param opts - Deployment target options.\n * @param log - Optional logger callback for progress messages.\n * @returns `true` when the asset was deployed successfully.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function deployAsset(\n entry: DeployableEntry,\n repositories: Record<string, SourceDeclaration>,\n opts: DeployOptions,\n log: Log = noop,\n): boolean {\n const driverTarget = opts.driverTarget ?? \"claude-code\";\n const globalInstall = opts.global ?? false;\n const cwd = opts.cwd;\n\n // Composition-only kinds (no `installTarget`) never land in a harness dir:\n // they are fetched + verified into the store cache and composed at session start.\n const provider = opts.registry.getProvider(entry.kind);\n const component = provider?.installTarget;\n if (!provider || !component) return true;\n\n // Agents need framework-specific rendering via the enriched installAgent path\n if (component === \"agent\") {\n const workspaceRoot = cwd ?? process.cwd();\n const agentDeployDir = deployedBase(\n component,\n driverTarget as DriverTarget,\n globalInstall,\n cwd,\n );\n const targetMap = DRIVER_TARGETS[driverTarget as DriverTarget];\n const skillsRelDir = targetMap?.local.skill ?? \"\";\n const wsConfig = resolveSkWorkspaceConfig(workspaceRoot);\n const srcDir = statSync(entry.source).isDirectory() ? entry.source : dirname(entry.source);\n const result = installAgent(\n srcDir,\n agentDeployDir,\n workspaceRoot,\n driverTarget,\n skillsRelDir,\n entry.name,\n /* includeSubAgents */ true,\n new Set<string>(),\n wsConfig,\n log,\n );\n for (const w of result.warnings) log(` warn: ${w}`);\n if (result.created.length > 0) return true;\n // Fall through to raw deploy if renderer produces no files (unsupported framework, etc.)\n }\n\n const dest = deployedDir(component, entry.name, driverTarget, globalInstall, cwd);\n mkdirSync(dirname(dest), { recursive: true });\n\n // Symlink only on explicit opt-in AND when the source has a real local path.\n // Factory sources have a `path` (the bundled dir under node_modules, replaced\n // on every upgrade) but no stable dev-loop, so they always copy. Default copy\n // keeps deploys cache-safe and portable.\n const repoDecl = entry.publisher ? repositories[entry.publisher] : undefined;\n const hasLocalPath = repoDecl?.path != null && repoDecl.factory !== true;\n\n if (opts.link === true && hasLocalPath) {\n symlinkAsset(provider, entry.source, dest, entry.name);\n log(` symlink ${entry.kind}:${entry.name}`);\n } else {\n copyAsset(provider, entry, dest);\n log(` copy ${entry.kind}:${entry.name}`);\n }\n return true;\n}\n\n/**\n * Deploy all resolved assets, applying patches where configured.\n *\n * Already-deployed assets are skipped unless their deployed manifest content differs\n * from the source. This handles copies that have gone stale after a source update.\n * In copy mode (the default, `!opts.link`) an existing **symlink** dest is healed:\n * it is removed and re-deployed as a real copy, so an old/legacy symlink deploy is\n * silently upgraded. With `opts.link` an existing symlink is left alone.\n *\n * @param resolved - Catalog entries to deploy (output of `resolveAll`).\n * @param repositories - Repository declarations from `skaile.yaml`.\n * @param patches - Map of `kind:name` → patch file path for patch application.\n * @param opts - Deployment target options.\n * @param log - Optional logger callback for progress messages.\n * @returns Canonical refs (`kind:@publisher/name[#version]`; bare `kind:name`\n * when the entry carries no publisher) of the assets newly deployed in this call.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function deployAll(\n resolved: DeployableEntry[],\n repositories: Record<string, SourceDeclaration>,\n patches: Record<string, string>,\n opts: DeployOptions,\n log: Log = noop,\n): string[] {\n const deployed: string[] = [];\n const driverTarget = opts.driverTarget ?? \"claude-code\";\n const globalInstall = opts.global ?? false;\n const cwd = opts.cwd;\n\n for (const entry of resolved) {\n // Skip composition-only kinds (no `installTarget`) — they live in the store\n // cache and are composed at session start, never copied into a harness dir.\n const component = installTargetOf(opts.registry, entry.kind);\n if (!component) continue;\n\n const ref = `${entry.kind}:${entry.name}`;\n\n if (isDeployed(component, entry.name, driverTarget, globalInstall, cwd)) {\n // Compare the deployed manifest file against the source to detect stale copies.\n // For symlinks the deployed path resolves through to the source file, so hashes\n // always match — symlinked installs are never needlessly re-linked.\n const dest = deployedDir(component, entry.name, driverTarget, globalInstall, cwd);\n // Heal: in copy mode an existing symlink dest is left to fall through to a\n // real copy below (cache-safe + portable) — bypass the hash skip entirely.\n // With --link a symlink dest is intentional, so it takes the normal skip path.\n let destIsSymlink = false;\n try {\n destIsSymlink = lstatSync(dest).isSymbolicLink();\n } catch {}\n const healSymlink = destIsSymlink && opts.link !== true;\n // Surface the one-time symlink→copy migration so an author who relied on a\n // live symlink dev-loop knows why edits stopped reflecting.\n if (healSymlink) log(` healed symlink → copy: ${ref} (use --link for the dev-loop)`);\n\n if (!healSymlink) {\n const manifestName = basename(entry.source);\n const deployedManifest = join(dest, manifestName);\n // isDeployed() only lstats the dir, so a present-but-empty dir (manifest\n // file deleted) reads as deployed. A missing manifest must never count as\n // \"already deployed\" — fall through to re-deploy instead of skipping.\n // (existsSync follows symlinks, so for symlinked installs the manifest\n // resolves through to the live source and the hash check below still\n // skips them.)\n if (existsSync(deployedManifest)) {\n try {\n const srcHash = computeHash(entry.source);\n const depHash = computeHash(deployedManifest);\n if (srcHash === depHash) {\n log(` already deployed: ${ref}`);\n continue;\n }\n log(` updating: ${ref} (content changed)`);\n // fall through to redeploy\n } catch {\n // Deployed manifest unreadable (e.g. agent rendered to a different path) — skip\n log(` already deployed: ${ref}`);\n continue;\n }\n }\n }\n }\n\n deployAsset(entry, repositories, opts, log);\n deployed.push(canonicalEntryRef(entry));\n\n // Apply patch if configured\n const patchFile = patches[ref];\n if (patchFile && existsSync(patchFile)) {\n const dest = deployedDir(component, entry.name, driverTarget, globalInstall, cwd);\n if (applyPatch(dest, patchFile)) {\n log(` patched ${ref}`);\n } else {\n log(` patch failed for ${ref}`);\n }\n }\n }\n\n return deployed;\n}\n\n/**\n * Remove a deployed asset from the framework directory.\n *\n * Removes symlinks with `unlink`; removes copied directories with `rm -rf`.\n *\n * @param kind - Asset kind (`skill`, `agent`, `prompt`, `flow`, `contract`).\n * @param name - Asset name as registered in the catalog.\n * @param opts - Deployment target options (must match the options used at install time).\n * @returns `true` if the asset existed and was removed; `false` if it was not deployed.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function removeAsset(kind: string, name: string, opts: DeployOptions): boolean {\n const driverTarget = opts.driverTarget ?? \"claude-code\";\n const globalInstall = opts.global ?? false;\n const cwd = opts.cwd;\n\n // Composition-only kinds have no harness dir — never resolve (and delete) one.\n const component = installTargetOf(opts.registry, kind);\n if (!component) return false;\n const dest = deployedDir(component, name, driverTarget, globalInstall, cwd);\n try {\n const s = lstatSync(dest);\n if (s.isSymbolicLink()) unlinkSync(dest);\n else rmSync(dest, { recursive: true, force: true });\n return true;\n } catch {\n return false;\n }\n}\n\n// ── Scaffold ─────────────────────────────────────────────────────────────────\n\n/** Markdown-marker scaffold (SKILL.md / AGENT.md / CONTRACT.md / `*.prompt.md`). */\nfunction markdownTemplate(name: string, description: string): string {\n // JSON.stringify yields a valid YAML double-quoted scalar, so any\n // user-supplied description (colons, quotes, `#`) survives the round-trip.\n return `---\nname: \"${name}\"\ndescription: ${JSON.stringify(description)}\nmetadata:\n version: \"0.1.0\"\n---\n\n# ${name}\n\n${SKILL_BODY_PLACEHOLDER}\n`;\n}\n\nfunction presetTemplate(name: string, description: string): string {\n return `name: ${name}\ndescription: ${JSON.stringify(description)}\nversion: 0.1.0\nitems:\n - ref: skill:@your-publisher/example-skill\n`;\n}\n\nfunction flowTemplate(name: string, description: string): string {\n return `id: \"${name}\"\nversion: \"0.1.0\"\nname: \"${name}\"\ndescription: ${JSON.stringify(description)}\n\nglobals:\n approval_mode: checkpoint\n\nnodes: []\n`;\n}\n\n/** Options for {@link createScaffold}. */\nexport interface ScaffoldOptions {\n /**\n * Description written into the manifest. Omitted: markdown kinds get a\n * `TODO:` placeholder that `skaile validate` rejects until it is replaced;\n * presets and flows keep their generic default.\n */\n description?: string;\n}\n\n/**\n * Create a minimal scaffold directory for a new asset.\n *\n * Writes the appropriate manifest file (`SKILL.md`, `AGENT.md`, `CONTRACT.md`,\n * `<name>.preset.yaml`, `<name>.flow.yaml`, or `<name>.prompt.md`) inside a\n * new `<destDir>/<name>/` directory.\n *\n * @param name - Asset name (also used as the directory name).\n * @param kind - Asset kind: `skill` | `agent` | `preset` | `flow` | `prompt` | `contract`.\n * @param destDir - Parent directory to create the asset in.\n * @param opts - Optional scaffold content ({@link ScaffoldOptions}).\n * @returns `{ ok: true, path }` on success, `{ ok: false, path: errorMessage }` if the\n * directory already exists.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function createScaffold(\n name: string,\n kind: string,\n destDir: string,\n opts: ScaffoldOptions = {},\n): { ok: boolean; path: string } {\n const dest = join(destDir, name);\n if (existsSync(dest)) {\n return { ok: false, path: `Directory '${name}' already exists in ${destDir}` };\n }\n mkdirSync(dest, { recursive: true });\n\n const mdDescription =\n opts.description ??\n ([\"agent\", \"contract\", \"prompt\"].includes(kind)\n ? `${SKILL_DESCRIPTION_PLACEHOLDER_PREFIX} describe this ${kind}.`\n : SKILL_DESCRIPTION_PLACEHOLDER);\n\n if (kind === \"preset\") {\n writeFileSync(\n join(dest, `${name}.preset.yaml`),\n presetTemplate(name, opts.description ?? \"A curated set of assets\"),\n \"utf8\",\n );\n } else if (kind === \"flow\") {\n writeFileSync(\n join(dest, `${name}.flow.yaml`),\n flowTemplate(name, opts.description ?? \"Flow description\"),\n \"utf8\",\n );\n } else if (kind === \"prompt\") {\n writeFileSync(join(dest, `${name}.prompt.md`), markdownTemplate(name, mdDescription), \"utf8\");\n } else if (kind === \"agent\") {\n writeFileSync(join(dest, \"AGENT.md\"), markdownTemplate(name, mdDescription), \"utf8\");\n } else if (kind === \"contract\") {\n writeFileSync(join(dest, \"CONTRACT.md\"), markdownTemplate(name, mdDescription), \"utf8\");\n } else {\n // Default: skill\n writeFileSync(join(dest, \"SKILL.md\"), markdownTemplate(name, mdDescription), \"utf8\");\n }\n\n return { ok: true, path: dest };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../core/src/cache-paths.ts"],"names":[],"mappings":"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","file":"chunk-MFHKHXDE.js","sourcesContent":["/**\n * Cache-root resolution + lazy legacy-dir migration primitives.\n *\n * `globalCacheRoot()` is the single root for all re-derivable global bytes\n * (`<root>/sources`, `<root>/catalog`). Sidecars are authored content and live\n * OUTSIDE this root (see `library/.../sidecar-paths.ts`).\n *\n * @docLink packages/core/api-reference#cache-paths\n */\nimport { existsSync, mkdirSync, readdirSync, renameSync, rmdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * The Skaile home dir — the single root for everything skaile keeps per user\n * (`index.db`, `libraries/`, `cache/`, `store/`, `sidecars/`, `config.yaml`,\n * `settings.json`, `providers.yml`, `skaile.yaml` SSOT, `skaile.lock.yaml`).\n * `$SKAILE_HOME` wins (tests point it at a temp dir); else `~/.skaile`. Every\n * per-user path MUST derive from this — never rebuild `~/.skaile` from\n * `os.homedir()`. More specific overrides (`SKAILE_INDEX_PATH`,\n * `SKAILE_LIBRARIES_DIR`, `SKAILE_CACHE_DIR`) layer on top of it.\n */\nexport function globalSkaileDir(): string {\n return process.env.SKAILE_HOME ?? join(homedir(), \".skaile\");\n}\n\n/**\n * The user-level config file, `$SKAILE_HOME/config.yaml` (`~/.skaile/config.yaml`\n * when `SKAILE_HOME` is unset). Lives in core so user-facing messages can name\n * the file that is actually read instead of hard-coding `~/.skaile`.\n */\nexport function userConfigPath(): string {\n return join(globalSkaileDir(), \"config.yaml\");\n}\n\n/**\n * The global cache root. `$SKAILE_CACHE_DIR` (now the cache *root*, not the\n * repos dir) wins; else `$SKAILE_HOME/cache`; else `~/.skaile/cache`.\n */\nexport function globalCacheRoot(): string {\n if (process.env.SKAILE_CACHE_DIR) return process.env.SKAILE_CACHE_DIR;\n return join(globalSkaileDir(), \"cache\");\n}\n\nconst migratedWholeTree = new Set<string>();\n\n/**\n * One-time whole-tree migration: if `newPath` is absent but `legacyPath` exists,\n * `rename()` legacy → new. Best-effort — a cross-device/raced rename is swallowed\n * (the caller's dir is re-derivable). Returns `newPath` always. Memoized per\n * `newPath` so hot resolvers don't stat on every call.\n */\nexport function migrateLegacyDir(newPath: string, legacyPath: string): string {\n if (migratedWholeTree.has(newPath)) return newPath;\n migratedWholeTree.add(newPath);\n try {\n if (!existsSync(newPath) && existsSync(legacyPath)) {\n mkdirSync(dirname(newPath), { recursive: true });\n renameSync(legacyPath, newPath);\n }\n } catch {\n // best-effort: re-derivable on miss\n }\n return newPath;\n}\n\nconst mergedEntries = new Set<string>();\n\n/**\n * Per-entry merge: move each immediate child of `legacyDir` that passes `filter`\n * into `targetDir/<name>`, skipping names already present in `targetDir`. Used\n * where two legacy roots feed one new root (so a whole-tree rename would clobber\n * or orphan). Removes `legacyDir` if it ends up empty. Idempotent; memoized per\n * `targetDir|legacyDir` pair.\n *\n * @param filter - receives the absolute child path; return true to move it.\n */\nexport function mergeLegacyEntriesInto(\n targetDir: string,\n legacyDir: string,\n filter: (childAbsPath: string) => boolean,\n): void {\n const key = `${targetDir}\\0${legacyDir}`;\n if (mergedEntries.has(key)) return;\n mergedEntries.add(key);\n if (!existsSync(legacyDir)) return;\n try {\n mkdirSync(targetDir, { recursive: true });\n for (const name of readdirSync(legacyDir)) {\n const from = join(legacyDir, name);\n if (!filter(from)) continue;\n const to = join(targetDir, name);\n if (existsSync(to)) continue; // don't clobber\n try {\n renameSync(from, to);\n } catch {\n // best-effort per entry\n }\n }\n if (readdirSync(legacyDir).length === 0) rmdirSync(legacyDir);\n } catch {\n // best-effort\n }\n}\n\n/**\n * Key-aware per-entry merge: like {@link mergeLegacyEntriesInto}, but each moved\n * child is placed at `targetDir/<remap(childAbsPath, name)>` instead of preserving\n * the bare `name`. Used to migrate legacy bare-name clones (`~/.skaile/sources/cli`)\n * into the URL-keyed cache layout (`<cacheRoot>/sources/<host>/<owner>/<repo>`) so a\n * later URL-keyed lookup finds them. `remap` returning `null`/`undefined` (or a\n * value equal to `name`) falls back to preserving the bare name.\n *\n * Nested target keys (`host/owner/repo`) create intermediate dirs. Skips a child\n * when its computed target already exists (don't clobber). Removes `legacyDir`\n * if it empties. Idempotent; memoized per `targetDir|legacyDir` pair.\n *\n * @param filter - receives the absolute child path; return true to consider it.\n * @param remap - receives `(childAbsPath, name)`; returns the target key (a\n * possibly-nested relative path) or a falsy value to keep `name`.\n */\nexport function mergeLegacyEntriesKeyed(\n targetDir: string,\n legacyDir: string,\n filter: (childAbsPath: string) => boolean,\n remap: (childAbsPath: string, name: string) => string | null | undefined,\n): void {\n const key = `${targetDir}\\0${legacyDir}`;\n if (mergedEntries.has(key)) return;\n mergedEntries.add(key);\n if (!existsSync(legacyDir)) return;\n try {\n mkdirSync(targetDir, { recursive: true });\n for (const name of readdirSync(legacyDir)) {\n const from = join(legacyDir, name);\n if (!filter(from)) continue;\n const targetKey = remap(from, name) || name;\n const to = join(targetDir, targetKey);\n if (existsSync(to)) continue; // don't clobber\n try {\n mkdirSync(dirname(to), { recursive: true });\n renameSync(from, to);\n } catch {\n // best-effort per entry\n }\n }\n if (readdirSync(legacyDir).length === 0) rmdirSync(legacyDir);\n } catch {\n // best-effort\n }\n}\n\n/** Test-only: reset migration memoization between cases. */\nexport function __resetCacheMigrationMemo(): void {\n migratedWholeTree.clear();\n mergedEntries.clear();\n}\n"]}