@skaile/workspaces 5.11.0 → 5.12.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 (403) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/README.md +2 -2
  3. package/dist/{asset-feeds-CXGQIDFR.js → asset-feeds-AM6PSSGM.js} +24 -21
  4. package/dist/asset-feeds-AM6PSSGM.js.map +1 -0
  5. package/dist/asset-manager/catalog-deployer.js +8 -8
  6. package/dist/asset-manager/fragments.js +1 -1
  7. package/dist/asset-manager/index.js +16 -16
  8. package/dist/asset-manager/installer.js +11 -11
  9. package/dist/asset-manager/renderers.js +9 -9
  10. package/dist/asset-manager/src/fragments.d.ts +5 -0
  11. package/dist/asset-manager/src/fragments.d.ts.map +1 -1
  12. package/dist/asset-manager/src/index.d.ts +95 -10
  13. package/dist/asset-manager/src/index.d.ts.map +1 -1
  14. package/dist/asset-manager/src/install-agent.d.ts +9 -1
  15. package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
  16. package/dist/asset-manager/src/installer.d.ts +10 -0
  17. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  18. package/dist/asset-manager/src/renderers.d.ts +5 -0
  19. package/dist/asset-manager/src/renderers.d.ts.map +1 -1
  20. package/dist/bridge/drivers/claude-sdk.js +16 -13
  21. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  22. package/dist/bridge/drivers/codex.js +43 -16
  23. package/dist/bridge/drivers/codex.js.map +1 -1
  24. package/dist/bridge/drivers/continue.js +10 -10
  25. package/dist/bridge/drivers/echo.js +2 -2
  26. package/dist/bridge/drivers/gemini.js +7 -7
  27. package/dist/bridge/drivers/goose.js +10 -10
  28. package/dist/bridge/drivers/omp.js +37 -10
  29. package/dist/bridge/drivers/omp.js.map +1 -1
  30. package/dist/bridge/drivers/opencode.js +10 -10
  31. package/dist/bridge/drivers/qwen.js +7 -7
  32. package/dist/bridge/index.js +12 -12
  33. package/dist/bridge/src/codex/config-toml.d.ts +8 -3
  34. package/dist/bridge/src/codex/config-toml.d.ts.map +1 -1
  35. package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
  36. package/dist/bridge/src/drivers/claude-sdk.d.ts +1 -1
  37. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  38. package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
  39. package/dist/bridge/src/drivers/omp-models-yml.d.ts.map +1 -1
  40. package/dist/bridge/src/drivers/omp.d.ts +9 -0
  41. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  42. package/dist/bridge/src/provider-materialize/credential-env.d.ts +15 -0
  43. package/dist/bridge/src/provider-materialize/credential-env.d.ts.map +1 -1
  44. package/dist/{chunk-4A4OD24G.js → chunk-27L6BBAT.js} +9 -9
  45. package/dist/{chunk-4A4OD24G.js.map → chunk-27L6BBAT.js.map} +1 -1
  46. package/dist/{chunk-HCEVNYSH.js → chunk-2JFIFDDO.js} +3 -3
  47. package/dist/{chunk-HCEVNYSH.js.map → chunk-2JFIFDDO.js.map} +1 -1
  48. package/dist/{chunk-3SM2DL2T.js → chunk-2X3JBVGD.js} +11 -10
  49. package/dist/chunk-2X3JBVGD.js.map +1 -0
  50. package/dist/{chunk-G4FFOV3N.js → chunk-3HUV2LJF.js} +4 -4
  51. package/dist/{chunk-G4FFOV3N.js.map → chunk-3HUV2LJF.js.map} +1 -1
  52. package/dist/{chunk-QZNJOHN6.js → chunk-3LVB3HGH.js} +3 -3
  53. package/dist/{chunk-QZNJOHN6.js.map → chunk-3LVB3HGH.js.map} +1 -1
  54. package/dist/{chunk-ZCAJZ4B2.js → chunk-6VLHITAM.js} +145 -3
  55. package/dist/chunk-6VLHITAM.js.map +1 -0
  56. package/dist/{chunk-J4RBUFGM.js → chunk-7CR2OZPA.js} +6 -6
  57. package/dist/{chunk-J4RBUFGM.js.map → chunk-7CR2OZPA.js.map} +1 -1
  58. package/dist/{chunk-HZXUXHIV.js → chunk-7QWQTA5S.js} +89 -12
  59. package/dist/chunk-7QWQTA5S.js.map +1 -0
  60. package/dist/{chunk-TCHRMVTO.js → chunk-7XWUJC3A.js} +4 -4
  61. package/dist/{chunk-TCHRMVTO.js.map → chunk-7XWUJC3A.js.map} +1 -1
  62. package/dist/{chunk-2F5AWQX5.js → chunk-C3BMXXTN.js} +137 -31
  63. package/dist/chunk-C3BMXXTN.js.map +1 -0
  64. package/dist/{chunk-ZPWTOUTK.js → chunk-CTP3XBMF.js} +7 -4
  65. package/dist/chunk-CTP3XBMF.js.map +1 -0
  66. package/dist/{chunk-GCHPUTA3.js → chunk-DCHQ6BAZ.js} +3 -3
  67. package/dist/{chunk-GCHPUTA3.js.map → chunk-DCHQ6BAZ.js.map} +1 -1
  68. package/dist/{chunk-DALV4HHP.js → chunk-DKXNKFKP.js} +3 -2
  69. package/dist/{chunk-DALV4HHP.js.map → chunk-DKXNKFKP.js.map} +1 -1
  70. package/dist/{chunk-X77SUM4P.js → chunk-G3X4MLDB.js} +3 -3
  71. package/dist/{chunk-X77SUM4P.js.map → chunk-G3X4MLDB.js.map} +1 -1
  72. package/dist/{chunk-CAHB6MHA.js → chunk-GWD3QNVS.js} +5 -5
  73. package/dist/{chunk-CAHB6MHA.js.map → chunk-GWD3QNVS.js.map} +1 -1
  74. package/dist/chunk-H5U7LNTJ.js +122 -0
  75. package/dist/chunk-H5U7LNTJ.js.map +1 -0
  76. package/dist/{chunk-QVFAS5IO.js → chunk-HYMERG57.js} +3 -3
  77. package/dist/{chunk-QVFAS5IO.js.map → chunk-HYMERG57.js.map} +1 -1
  78. package/dist/{chunk-R7NHYEJF.js → chunk-ICIYSJBQ.js} +4 -4
  79. package/dist/{chunk-R7NHYEJF.js.map → chunk-ICIYSJBQ.js.map} +1 -1
  80. package/dist/{chunk-YOH2L76X.js → chunk-ID745F3R.js} +353 -233
  81. package/dist/chunk-ID745F3R.js.map +1 -0
  82. package/dist/{chunk-PQFHMQHQ.js → chunk-JQ3DXNQV.js} +4 -4
  83. package/dist/{chunk-PQFHMQHQ.js.map → chunk-JQ3DXNQV.js.map} +1 -1
  84. package/dist/chunk-K4VOEYOR.js +21 -0
  85. package/dist/chunk-K4VOEYOR.js.map +1 -0
  86. package/dist/{chunk-XDKH7XSA.js → chunk-KVSDRB35.js} +5 -5
  87. package/dist/{chunk-XDKH7XSA.js.map → chunk-KVSDRB35.js.map} +1 -1
  88. package/dist/{chunk-47U4GZ4M.js → chunk-MF54ZHWT.js} +20 -3
  89. package/dist/chunk-MF54ZHWT.js.map +1 -0
  90. package/dist/{chunk-VLTQGE2E.js → chunk-N5M2EISA.js} +197 -52
  91. package/dist/chunk-N5M2EISA.js.map +1 -0
  92. package/dist/{chunk-T7CTHHG7.js → chunk-NDF24LYP.js} +3 -3
  93. package/dist/{chunk-T7CTHHG7.js.map → chunk-NDF24LYP.js.map} +1 -1
  94. package/dist/{chunk-CPWLNZGJ.js → chunk-NGJIVDDD.js} +3 -3
  95. package/dist/{chunk-CPWLNZGJ.js.map → chunk-NGJIVDDD.js.map} +1 -1
  96. package/dist/{chunk-FH7W6TJ4.js → chunk-NJV5SLEK.js} +104 -23
  97. package/dist/chunk-NJV5SLEK.js.map +1 -0
  98. package/dist/{chunk-M3B6EIJD.js → chunk-NJXR5OAM.js} +4 -4
  99. package/dist/{chunk-M3B6EIJD.js.map → chunk-NJXR5OAM.js.map} +1 -1
  100. package/dist/{chunk-CGYEHQOX.js → chunk-NOA6EJXE.js} +11 -2
  101. package/dist/chunk-NOA6EJXE.js.map +1 -0
  102. package/dist/{chunk-RYYLMBA2.js → chunk-NR7H7ZJP.js} +14 -6
  103. package/dist/chunk-NR7H7ZJP.js.map +1 -0
  104. package/dist/{chunk-OBYKJB4U.js → chunk-O2SYFJWP.js} +79 -5
  105. package/dist/chunk-O2SYFJWP.js.map +1 -0
  106. package/dist/{chunk-5LKOAX7I.js → chunk-OQ5MKDS3.js} +21 -5
  107. package/dist/chunk-OQ5MKDS3.js.map +1 -0
  108. package/dist/{chunk-CJERAGFY.js → chunk-P23WJCH2.js} +37 -11
  109. package/dist/chunk-P23WJCH2.js.map +1 -0
  110. package/dist/{chunk-NWDSLXOX.js → chunk-PHRNUTSG.js} +118 -118
  111. package/dist/chunk-PHRNUTSG.js.map +1 -0
  112. package/dist/{chunk-ALEYHUC5.js → chunk-PNOGX36L.js} +104 -24
  113. package/dist/chunk-PNOGX36L.js.map +1 -0
  114. package/dist/{chunk-BNMZVPYA.js → chunk-PNTXHTBC.js} +2 -2
  115. package/dist/{chunk-BNMZVPYA.js.map → chunk-PNTXHTBC.js.map} +1 -1
  116. package/dist/{chunk-GV4DZ6MT.js → chunk-POQ6PGNE.js} +4 -4
  117. package/dist/{chunk-GV4DZ6MT.js.map → chunk-POQ6PGNE.js.map} +1 -1
  118. package/dist/{chunk-T42WRQ4O.js → chunk-QCEKGYHF.js} +3 -3
  119. package/dist/{chunk-T42WRQ4O.js.map → chunk-QCEKGYHF.js.map} +1 -1
  120. package/dist/{chunk-EDYHEMJA.js → chunk-SHQMPGOL.js} +4 -4
  121. package/dist/{chunk-EDYHEMJA.js.map → chunk-SHQMPGOL.js.map} +1 -1
  122. package/dist/{chunk-S3O3GKB7.js → chunk-SMT3LNAG.js} +4 -4
  123. package/dist/{chunk-S3O3GKB7.js.map → chunk-SMT3LNAG.js.map} +1 -1
  124. package/dist/{chunk-PBBPZYVG.js → chunk-T5TSLSRO.js} +110 -44
  125. package/dist/chunk-T5TSLSRO.js.map +1 -0
  126. package/dist/{chunk-DZMNFCWB.js → chunk-TVAR4JHA.js} +530 -126
  127. package/dist/chunk-TVAR4JHA.js.map +1 -0
  128. package/dist/{chunk-COH6FQAG.js → chunk-UTKENBB6.js} +5 -5
  129. package/dist/{chunk-COH6FQAG.js.map → chunk-UTKENBB6.js.map} +1 -1
  130. package/dist/{chunk-XUSALIEI.js → chunk-VRLKHL74.js} +6 -6
  131. package/dist/{chunk-XUSALIEI.js.map → chunk-VRLKHL74.js.map} +1 -1
  132. package/dist/{chunk-WSBKB4CJ.js → chunk-WI4T3KIS.js} +51 -16
  133. package/dist/chunk-WI4T3KIS.js.map +1 -0
  134. package/dist/{chunk-D3B36CYC.js → chunk-X3RMRJNR.js} +4 -3
  135. package/dist/chunk-X3RMRJNR.js.map +1 -0
  136. package/dist/{chunk-IER3KIPH.js → chunk-X6LKA3TJ.js} +5 -5
  137. package/dist/{chunk-IER3KIPH.js.map → chunk-X6LKA3TJ.js.map} +1 -1
  138. package/dist/{chunk-Y3HTGHJC.js → chunk-XMAJJPA4.js} +3 -3
  139. package/dist/{chunk-Y3HTGHJC.js.map → chunk-XMAJJPA4.js.map} +1 -1
  140. package/dist/{chunk-SBSA3IQA.js → chunk-XTVSNWLL.js} +19 -7
  141. package/dist/chunk-XTVSNWLL.js.map +1 -0
  142. package/dist/{chunk-MZG34MBZ.js → chunk-XZY6SBGU.js} +3 -3
  143. package/dist/{chunk-MZG34MBZ.js.map → chunk-XZY6SBGU.js.map} +1 -1
  144. package/dist/{chunk-6O2X3GPW.js → chunk-YQU2BPQD.js} +7 -5
  145. package/dist/chunk-YQU2BPQD.js.map +1 -0
  146. package/dist/cli/index.js +1077 -497
  147. package/dist/cli/index.js.map +1 -1
  148. package/dist/cli/src/agent-checks.d.ts +40 -0
  149. package/dist/cli/src/agent-checks.d.ts.map +1 -0
  150. package/dist/cli/src/asset-feeds.d.ts.map +1 -1
  151. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  152. package/dist/cli/src/commands/catalog.d.ts +24 -0
  153. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  154. package/dist/cli/src/commands/config.d.ts.map +1 -1
  155. package/dist/cli/src/commands/diff.d.ts.map +1 -1
  156. package/dist/cli/src/commands/integration.d.ts.map +1 -1
  157. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  158. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  159. package/dist/cli/src/commands/mcp-server.d.ts +1 -1
  160. package/dist/cli/src/commands/migrate-assets.d.ts +2 -1
  161. package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
  162. package/dist/cli/src/commands/migrate.d.ts.map +1 -1
  163. package/dist/cli/src/commands/plugin/claude-code.d.ts +1 -1
  164. package/dist/cli/src/commands/plugin/claude-code.d.ts.map +1 -1
  165. package/dist/cli/src/commands/plugin/types.d.ts +1 -1
  166. package/dist/cli/src/commands/plugin-registry-cmd.d.ts.map +1 -1
  167. package/dist/cli/src/commands/project.d.ts.map +1 -1
  168. package/dist/cli/src/commands/publish-core.d.ts +5 -0
  169. package/dist/cli/src/commands/publish-core.d.ts.map +1 -1
  170. package/dist/cli/src/commands/run.d.ts +2 -1
  171. package/dist/cli/src/commands/run.d.ts.map +1 -1
  172. package/dist/cli/src/commands/serve-preflight.d.ts +22 -0
  173. package/dist/cli/src/commands/serve-preflight.d.ts.map +1 -0
  174. package/dist/cli/src/commands/serve.d.ts.map +1 -1
  175. package/dist/cli/src/commands/source-manifest-publish.d.ts.map +1 -1
  176. package/dist/cli/src/commands/source-manifest.d.ts.map +1 -1
  177. package/dist/cli/src/commands/source.d.ts.map +1 -1
  178. package/dist/cli/src/commands/store.d.ts.map +1 -1
  179. package/dist/cli/src/commands/tree.d.ts.map +1 -1
  180. package/dist/cli/src/commands/update.d.ts.map +1 -1
  181. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  182. package/dist/cli/src/commands/why.d.ts.map +1 -1
  183. package/dist/cli/src/curated-manifests.d.ts +21 -0
  184. package/dist/cli/src/curated-manifests.d.ts.map +1 -0
  185. package/dist/cli/src/index-busy.d.ts +8 -0
  186. package/dist/cli/src/index-busy.d.ts.map +1 -0
  187. package/dist/cli/src/plugin-store/paths.d.ts +7 -3
  188. package/dist/cli/src/plugin-store/paths.d.ts.map +1 -1
  189. package/dist/cli/src/skill-checks.d.ts +15 -2
  190. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  191. package/dist/cli/src/store-addable.d.ts +18 -0
  192. package/dist/cli/src/store-addable.d.ts.map +1 -0
  193. package/dist/connectors/config.js +5 -5
  194. package/dist/connectors/index.js +16 -16
  195. package/dist/{connectors-4QWAKPHB.js → connectors-UNKUKEPG.js} +19 -19
  196. package/dist/{connectors-4QWAKPHB.js.map → connectors-UNKUKEPG.js.map} +1 -1
  197. package/dist/core/index.js +7 -7
  198. package/dist/core/logging.js +1 -1
  199. package/dist/core/manifest.js +2 -2
  200. package/dist/core/models.js +1 -1
  201. package/dist/core/publish-manifest.js +2 -2
  202. package/dist/core/ref.js +1 -1
  203. package/dist/core/runtime-assets.js +5 -5
  204. package/dist/core/src/index.d.ts +5 -4
  205. package/dist/core/src/index.d.ts.map +1 -1
  206. package/dist/core/src/lock.d.ts +15 -5
  207. package/dist/core/src/lock.d.ts.map +1 -1
  208. package/dist/core/src/logging/sinks/sqlite-sink.d.ts.map +1 -1
  209. package/dist/core/src/manifest.d.ts +5 -0
  210. package/dist/core/src/manifest.d.ts.map +1 -1
  211. package/dist/core/src/models.d.ts +3 -3
  212. package/dist/core/src/package-manager.d.ts +19 -0
  213. package/dist/core/src/package-manager.d.ts.map +1 -0
  214. package/dist/core/src/publish-manifest.d.ts.map +1 -1
  215. package/dist/core/src/repo-manager.d.ts +11 -0
  216. package/dist/core/src/repo-manager.d.ts.map +1 -1
  217. package/dist/core/src/settings.d.ts +26 -6
  218. package/dist/core/src/settings.d.ts.map +1 -1
  219. package/dist/core/src/walker.d.ts +6 -1
  220. package/dist/core/src/walker.d.ts.map +1 -1
  221. package/dist/core/src/workspace-config.d.ts.map +1 -1
  222. package/dist/core/workspace-config.js +4 -4
  223. package/dist/deploy/index.js +7 -7
  224. package/dist/discovery/index.js +5 -5
  225. package/dist/{ensure-sources-2RONZKCU.js → ensure-sources-POMEQSTM.js} +19 -19
  226. package/dist/{ensure-sources-2RONZKCU.js.map → ensure-sources-POMEQSTM.js.map} +1 -1
  227. package/dist/factory-assets/connectors/box.js +16 -16
  228. package/dist/factory-assets/connectors/deploy.js +16 -16
  229. package/dist/factory-assets/connectors/devserver.js +16 -16
  230. package/dist/factory-assets/connectors/flow/adapter.js +16 -16
  231. package/dist/factory-assets/connectors/flow/contract/normalize.d.ts.map +1 -1
  232. package/dist/factory-assets/connectors/flow/contract.js +1 -1
  233. package/dist/factory-assets/connectors/flow/engine.js +9 -9
  234. package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
  235. package/dist/factory-assets/connectors/flow/run-flow.js +18 -18
  236. package/dist/factory-assets/connectors/flow.js +16 -16
  237. package/dist/factory-assets/connectors/git.js +16 -16
  238. package/dist/factory-assets/connectors/gmail.js +16 -16
  239. package/dist/factory-assets/connectors/googledrive.js +16 -16
  240. package/dist/factory-assets/connectors/local.js +16 -16
  241. package/dist/factory-assets/connectors/mattermost.js +16 -16
  242. package/dist/factory-assets/connectors/memory.js +16 -16
  243. package/dist/factory-assets/connectors/minio.js +16 -16
  244. package/dist/factory-assets/connectors/postgres.js +16 -16
  245. package/dist/factory-assets/connectors/s3.js +16 -16
  246. package/dist/factory-assets/connectors/sharepoint.js +16 -16
  247. package/dist/factory-assets/connectors/sqlite.js +16 -16
  248. package/dist/factory-assets/connectors/static-server.js +16 -16
  249. package/dist/factory-assets/connectors/tunnel.js +16 -16
  250. package/dist/factory-assets/connectors/webdav.js +16 -16
  251. package/dist/factory-assets/connectors/xstate-store.js +16 -16
  252. package/dist/factory-assets/connectors/xstate.js +16 -16
  253. package/dist/factory-assets/skills/authoring-skaile-assets/SKILL.md +10 -8
  254. package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +15 -11
  255. package/dist/factory-assets/skills/authoring-skaile-manifests/references/dependency-standard.md +12 -9
  256. package/dist/factory-assets/skills/skaile-author-asset/SKILL.md +2 -2
  257. package/dist/{flows-EQF2CH4U.js → flows-DVKMZKM4.js} +12 -12
  258. package/dist/{flows-EQF2CH4U.js.map → flows-DVKMZKM4.js.map} +1 -1
  259. package/dist/{helpers-CFK6YP6R.js → helpers-Y4OT7VIS.js} +19 -19
  260. package/dist/{helpers-CFK6YP6R.js.map → helpers-Y4OT7VIS.js.map} +1 -1
  261. package/dist/library/index.js +12 -12
  262. package/dist/library/install.js +4 -4
  263. package/dist/library/src/index.d.ts +2 -2
  264. package/dist/library/src/index.d.ts.map +1 -1
  265. package/dist/library/src/install/source-fetch-github.d.ts.map +1 -1
  266. package/dist/library/src/local/db.d.ts +2 -0
  267. package/dist/library/src/local/db.d.ts.map +1 -1
  268. package/dist/library/src/local/library-manager.d.ts +5 -0
  269. package/dist/library/src/local/library-manager.d.ts.map +1 -1
  270. package/dist/library/src/local/library.d.ts +5 -3
  271. package/dist/library/src/local/library.d.ts.map +1 -1
  272. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  273. package/dist/library/src/local/store-paths.d.ts +9 -0
  274. package/dist/library/src/local/store-paths.d.ts.map +1 -1
  275. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  276. package/dist/library/src/remote/index.d.ts +1 -1
  277. package/dist/library/src/remote/index.d.ts.map +1 -1
  278. package/dist/library/src/remote/remote-catalog-source.d.ts +17 -0
  279. package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
  280. package/dist/library/src/sync/git-driver.d.ts.map +1 -1
  281. package/dist/{library-publish-53UTB3MB.js → library-publish-DI4Q5UOG.js} +45 -37
  282. package/dist/library-publish-DI4Q5UOG.js.map +1 -0
  283. package/dist/open-library-N6ESO6IK.js +40 -0
  284. package/dist/{open-library-BOSPJVID.js.map → open-library-N6ESO6IK.js.map} +1 -1
  285. package/dist/open-registry-CBZ5MWTT.js +32 -0
  286. package/dist/{open-registry-4FI7HKET.js.map → open-registry-CBZ5MWTT.js.map} +1 -1
  287. package/dist/paths-U6W6MQNQ.js +22 -0
  288. package/dist/{paths-SUS4S4YT.js.map → paths-U6W6MQNQ.js.map} +1 -1
  289. package/dist/{plugin-store-AGQDMING.js → plugin-store-XMZSPVBF.js} +48 -12
  290. package/dist/plugin-store-XMZSPVBF.js.map +1 -0
  291. package/dist/project-UP52HEHC.js +79 -0
  292. package/dist/{project-I55A4O2T.js.map → project-UP52HEHC.js.map} +1 -1
  293. package/dist/resolver/index.js +8 -8
  294. package/dist/runner/index.js +33 -33
  295. package/dist/runner/src/agent.d.ts.map +1 -1
  296. package/dist/runner/src/agents/in-process-host.d.ts.map +1 -1
  297. package/dist/runner/src/composition/index.d.ts +1 -0
  298. package/dist/runner/src/composition/index.d.ts.map +1 -1
  299. package/dist/runner/src/composition/prompt-sections.d.ts +7 -4
  300. package/dist/runner/src/composition/prompt-sections.d.ts.map +1 -1
  301. package/dist/runner/src/composition/resolve.d.ts +10 -1
  302. package/dist/runner/src/composition/resolve.d.ts.map +1 -1
  303. package/dist/runner/src/composition/verify.d.ts +29 -0
  304. package/dist/runner/src/composition/verify.d.ts.map +1 -0
  305. package/dist/runner/src/credential-notice.d.ts +14 -0
  306. package/dist/runner/src/credential-notice.d.ts.map +1 -0
  307. package/dist/runner/src/environment.d.ts.map +1 -1
  308. package/dist/runner/src/final-text.d.ts +17 -0
  309. package/dist/runner/src/final-text.d.ts.map +1 -0
  310. package/dist/runner/src/index.d.ts +2 -0
  311. package/dist/runner/src/index.d.ts.map +1 -1
  312. package/dist/runner/src/resource-handler.d.ts.map +1 -1
  313. package/dist/runner/src/serve.d.ts +13 -0
  314. package/dist/runner/src/serve.d.ts.map +1 -1
  315. package/dist/sdk/asset-manager.js +16 -16
  316. package/dist/sdk/bridge.js +12 -12
  317. package/dist/sdk/core.js +7 -7
  318. package/dist/sdk/flow.js +9 -9
  319. package/dist/sdk/index.js +36 -34
  320. package/dist/sdk/index.js.map +1 -1
  321. package/dist/sdk/resolver.js +8 -8
  322. package/dist/sdk/runner.js +33 -33
  323. package/dist/sdk/src/local-runtime.d.ts.map +1 -1
  324. package/dist/sdk/transport/ws/client.js +1 -1
  325. package/dist/sdk/transport/ws/server.js +1 -1
  326. package/dist/sdk/transport/ws.js +2 -2
  327. package/dist/sdk/transport.js +2 -2
  328. package/dist/serve-preflight-6P2JJEJ3.js +47 -0
  329. package/dist/serve-preflight-6P2JJEJ3.js.map +1 -0
  330. package/dist/{setup-7DQJKHUI.js → setup-5IRUH5OS.js} +24 -24
  331. package/dist/{setup-7DQJKHUI.js.map → setup-5IRUH5OS.js.map} +1 -1
  332. package/dist/{skills-NUEN5NDX.js → skills-HA36RFNM.js} +13 -13
  333. package/dist/{skills-NUEN5NDX.js.map → skills-HA36RFNM.js.map} +1 -1
  334. package/dist/source-DX5SGWEI.js +41 -0
  335. package/dist/{source-G2LV5LVD.js.map → source-DX5SGWEI.js.map} +1 -1
  336. package/dist/source-fetch-github-PIO6EMMF.js +4 -0
  337. package/dist/{source-fetch-github-QN4LLTL5.js.map → source-fetch-github-PIO6EMMF.js.map} +1 -1
  338. package/dist/{source-manifest-publish-6RM7SWLZ.js → source-manifest-publish-NMRLXWVW.js} +27 -26
  339. package/dist/source-manifest-publish-NMRLXWVW.js.map +1 -0
  340. package/dist/transport/index.js +2 -2
  341. package/dist/transport/src/ws/client.d.ts +6 -0
  342. package/dist/transport/src/ws/client.d.ts.map +1 -1
  343. package/dist/transport/src/ws/server.d.ts +4 -0
  344. package/dist/transport/src/ws/server.d.ts.map +1 -1
  345. package/dist/transport/ws/client.js +1 -1
  346. package/dist/transport/ws/server.js +1 -1
  347. package/dist/transport/ws.js +2 -2
  348. package/dist/tui/index.js +58 -41
  349. package/dist/tui/index.js.map +1 -1
  350. package/dist/tui/src/repl-session.d.ts +1 -1
  351. package/dist/tui/src/repl-session.d.ts.map +1 -1
  352. package/dist/tui/src/repl.d.ts +3 -0
  353. package/dist/tui/src/repl.d.ts.map +1 -1
  354. package/dist/types/manifests.js +1 -1
  355. package/dist/types/src/manifests/agent-composition.d.ts +20 -0
  356. package/dist/types/src/manifests/agent-composition.d.ts.map +1 -1
  357. package/dist/types/src/manifests/agent.d.ts.map +1 -1
  358. package/dist/types/src/manifests/cron.d.ts +15 -0
  359. package/dist/types/src/manifests/cron.d.ts.map +1 -0
  360. package/dist/types/src/manifests/index.d.ts +3 -2
  361. package/dist/types/src/manifests/index.d.ts.map +1 -1
  362. package/dist/workspace-plugin/adapters/mcp.js +23 -23
  363. package/dist/workspace-plugin/adapters/omp.js +106 -51
  364. package/dist/workspace-plugin/adapters/omp.js.map +1 -1
  365. package/dist/workspace-plugin/index.js +2 -2
  366. package/dist/workspace-plugin/src/adapters/claude-code.d.ts.map +1 -1
  367. package/dist/workspace-plugin/src/adapters/omp.d.ts +11 -2
  368. package/dist/workspace-plugin/src/adapters/omp.d.ts.map +1 -1
  369. package/package.json +1 -1
  370. package/dist/asset-feeds-CXGQIDFR.js.map +0 -1
  371. package/dist/chunk-2F5AWQX5.js.map +0 -1
  372. package/dist/chunk-3SM2DL2T.js.map +0 -1
  373. package/dist/chunk-47U4GZ4M.js.map +0 -1
  374. package/dist/chunk-5LKOAX7I.js.map +0 -1
  375. package/dist/chunk-6O2X3GPW.js.map +0 -1
  376. package/dist/chunk-ALEYHUC5.js.map +0 -1
  377. package/dist/chunk-CGYEHQOX.js.map +0 -1
  378. package/dist/chunk-CJERAGFY.js.map +0 -1
  379. package/dist/chunk-D3B36CYC.js.map +0 -1
  380. package/dist/chunk-DZMNFCWB.js.map +0 -1
  381. package/dist/chunk-FH7W6TJ4.js.map +0 -1
  382. package/dist/chunk-HZXUXHIV.js.map +0 -1
  383. package/dist/chunk-NWDSLXOX.js.map +0 -1
  384. package/dist/chunk-OBYKJB4U.js.map +0 -1
  385. package/dist/chunk-PBBPZYVG.js.map +0 -1
  386. package/dist/chunk-R7FOF242.js +0 -59
  387. package/dist/chunk-R7FOF242.js.map +0 -1
  388. package/dist/chunk-RYYLMBA2.js.map +0 -1
  389. package/dist/chunk-SBSA3IQA.js.map +0 -1
  390. package/dist/chunk-VLTQGE2E.js.map +0 -1
  391. package/dist/chunk-WSBKB4CJ.js.map +0 -1
  392. package/dist/chunk-YOH2L76X.js.map +0 -1
  393. package/dist/chunk-ZCAJZ4B2.js.map +0 -1
  394. package/dist/chunk-ZPWTOUTK.js.map +0 -1
  395. package/dist/library-publish-53UTB3MB.js.map +0 -1
  396. package/dist/open-library-BOSPJVID.js +0 -40
  397. package/dist/open-registry-4FI7HKET.js +0 -32
  398. package/dist/paths-SUS4S4YT.js +0 -22
  399. package/dist/plugin-store-AGQDMING.js.map +0 -1
  400. package/dist/project-I55A4O2T.js +0 -41
  401. package/dist/source-G2LV5LVD.js +0 -41
  402. package/dist/source-fetch-github-QN4LLTL5.js +0 -4
  403. package/dist/source-manifest-publish-6RM7SWLZ.js.map +0 -1
@@ -1,18 +1,18 @@
1
- import { unregisteredLibraryNames, renamedLibraryName, scanUnlistedAssets, getStoreManifestsDir, missingLibraryDirMessage } from './chunk-2F5AWQX5.js';
2
- import { readManifestSourceConfig, isManifestMode, discoverAssetsInTree } from './chunk-J4RBUFGM.js';
3
- import { installTargetOf, canonicalEntryRef, deployAll, removeAsset, diffDeployedAgent, deployedAssetDrift, createScaffold, installAgent } from './chunk-FH7W6TJ4.js';
1
+ import { unregisteredLibraryNames, renamedLibraryName, resolveConfig, RemoteCatalogSource, OfflineError, describeCatalogError, CatalogHttpError, scanUnlistedAssets, getStoreManifestsDir, missingLibraryDirMessage } from './chunk-C3BMXXTN.js';
2
+ import { readManifestSourceConfig, discoverAssetsInTree, isManifestMode } from './chunk-7CR2OZPA.js';
3
+ import { installTargetOf, canonicalEntryRef, deployAll, removeAsset, diffDeployedAgent, removeExcludedLeftovers, deployedAssetDrift, createScaffold, installAgent } from './chunk-NJV5SLEK.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-HZXUXHIV.js';
7
- import { resolveConfiguredDriverTarget, GLOBAL_INSTALL_DIR_NAME, resolveLibraryDir, buildLibraryLockEntries, buildLockFile, writeLock, readLock, verifyLock, mergeLockFile, extractForPatch, generatePatch, savePatch, applyPatch, computeHash } from './chunk-PBBPZYVG.js';
8
- import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-EDYHEMJA.js';
6
+ import { driverTargetSupportsAgents, CODEX_IDENTITY_DIR } from './chunk-7QWQTA5S.js';
7
+ import { resolveConfiguredDriverTarget, GLOBAL_INSTALL_DIR_NAME, resolveLibraryDir, buildLibraryLockEntries, computeHash, buildLockFile, writeLock, readLock, verifyLock, mergeLockFile, extractForPatch, generatePatch, savePatch, applyPatch, LOCK_SCHEMA_VERSION } from './chunk-T5TSLSRO.js';
8
+ import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-SHQMPGOL.js';
9
9
  import { deployedBase, deployedDir, isDeployed, deployedPaths } from './chunk-PMECEZK3.js';
10
- import { resolveSkWorkspaceConfig, effectiveAgentInstances, loadMcpServerDeclarations, resolveGlobalHarnesses, resolveGlobalSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, matchPin, buildProvenanceIndex, coerceVersion, sourceShortName, resolveAll, ensureRepo, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus, resolveAsset, readLinks, MAX_PRESET_DEPTH, PresetDepthError, DEFAULT_AGENT_INSTANCE_ID, resolveAgentDefinitionDir, storeManifestSlug } from './chunk-ALEYHUC5.js';
10
+ import { resolveSkWorkspaceConfig, effectiveAgentInstances, loadMcpServerDeclarations, resolveGlobalHarnesses, resolveGlobalSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, matchPin, buildProvenanceIndex, coerceVersion, sourceShortName, readLinks, isCommitOnRemote, resolveAll, agentSourceCacheDir, ensureRepo, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus, resolveAsset, MAX_PRESET_DEPTH, PresetDepthError, DEFAULT_AGENT_INSTANCE_ID, resolveAgentDefinitionDir, storeManifestSlug } from './chunk-PNOGX36L.js';
11
11
  import { globalSkaileDir, globalCacheRoot, migrateLegacyDir } from './chunk-L5VSIPQD.js';
12
12
  import { DRIVER_TARGETS } from './chunk-CPSIPIX7.js';
13
- import { loadSkPublishManifest } from './chunk-ZPWTOUTK.js';
14
- import { scanDirectory, parseRequires, dedupeRequirements } from './chunk-SBSA3IQA.js';
15
- import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName, depToStr } from './chunk-BNMZVPYA.js';
13
+ import { loadSkPublishManifest } from './chunk-CTP3XBMF.js';
14
+ import { scanDirectory, parseRequires, dedupeRequirements } from './chunk-XTVSNWLL.js';
15
+ import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName, depToStr, parseDep } from './chunk-PNTXHTBC.js';
16
16
  import { spawnSync } from 'child_process';
17
17
  import { existsSync, rmSync, readdirSync, lstatSync, unlinkSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
18
18
  import path, { resolve, dirname, sep, join, relative, posix } from 'path';
@@ -401,6 +401,19 @@ function filesUnderManifestDir(paths, manifestRel) {
401
401
  const manifestDir = posix.dirname(manifestRel);
402
402
  return paths.map((p) => posix.relative(manifestDir, p)).filter((rel) => rel !== "" && !rel.startsWith(".."));
403
403
  }
404
+ function lockedAssetFiles(kind, files) {
405
+ const manifestRel = matchManifestPath(
406
+ kind,
407
+ files.map((f) => f.path)
408
+ ) ?? files[0]?.path;
409
+ if (!manifestRel) return [];
410
+ const manifestDir = posix.dirname(manifestRel);
411
+ return files.flatMap((f) => {
412
+ const rel = posix.relative(manifestDir, f.path);
413
+ return rel === "" || rel.startsWith("..") ? [] : [{ rel, sha256: f.sha256 }];
414
+ });
415
+ }
416
+ var GITHUB_REPO_URL = /github\.com[/:]/i;
404
417
  function indexLockByKindName(lock) {
405
418
  const lockByKindName = /* @__PURE__ */ new Map();
406
419
  for (const [key, entry] of Object.entries(lock?.assets ?? {})) {
@@ -435,6 +448,28 @@ function commitsBetween(repoDir, from, to, cache) {
435
448
  return count;
436
449
  }
437
450
  var COMMIT_ID = /^[0-9a-f]{7,64}$/;
451
+ function commitsTouching(repoDir, from, to, dir, cache) {
452
+ if (!COMMIT_ID.test(from) || !COMMIT_ID.test(to)) return null;
453
+ if (from === to) return 0;
454
+ const key = `${from}..${to} -- ${dir}`;
455
+ const hit = cache.get(key);
456
+ if (hit !== void 0) return hit;
457
+ const r = spawnSync("git", ["-C", repoDir, "rev-list", "--count", `${from}..${to}`, "--", dir], {
458
+ encoding: "utf8",
459
+ stdio: "pipe"
460
+ });
461
+ const n = r.status === 0 ? Number.parseInt(r.stdout.trim(), 10) : Number.NaN;
462
+ if (!Number.isFinite(n) || n < 0) return null;
463
+ cache.set(key, n);
464
+ return n;
465
+ }
466
+ function lockedAssetDir(kind, files) {
467
+ const manifestRel = matchManifestPath(
468
+ kind,
469
+ files.map((f) => f.path)
470
+ ) ?? files[0]?.path;
471
+ return manifestRel ? posix.dirname(manifestRel) : ".";
472
+ }
438
473
  function libraryDiskHashes(libPath, cache, registry) {
439
474
  let hashes = cache.get(libPath);
440
475
  if (!hashes) {
@@ -506,7 +541,7 @@ function newestLibraryDef(snap, libraryName, id) {
506
541
  }
507
542
  return best;
508
543
  }
509
- function libraryPreference(isDefaultLib) {
544
+ function libraryPreference(isDefaultLib, rank) {
510
545
  return (a, b) => {
511
546
  const va = coerceVersion(a.entry.version ?? "");
512
547
  const vb = coerceVersion(b.entry.version ?? "");
@@ -514,7 +549,9 @@ function libraryPreference(isDefaultLib) {
514
549
  if (gt(vb, va)) return 1;
515
550
  const da = isDefaultLib.get(a.library) ? 0 : 1;
516
551
  const db = isDefaultLib.get(b.library) ? 0 : 1;
517
- return da - db || a.library.localeCompare(b.library);
552
+ if (da !== db) return da - db;
553
+ const byRank = rank ? rank(a) - rank(b) : 0;
554
+ return byRank || a.library.localeCompare(b.library);
518
555
  };
519
556
  }
520
557
  function qualifyDepRef(ref, fallback) {
@@ -649,8 +686,7 @@ function withKeptLockEntries(lock, kept) {
649
686
  for (const s of kept.sources) if (!sources.has(s.url)) sources.set(s.url, s);
650
687
  return {
651
688
  ...lock,
652
- // v4 once a library-origin entry is present (see buildLockFile).
653
- schema_version: lock.schema_version === 4 || Object.values(kept.assets).some((e) => e.library) ? 4 : 3,
689
+ schema_version: LOCK_SCHEMA_VERSION,
654
690
  assets: { ...lock.assets, ...kept.assets },
655
691
  sources: [...sources.values()].sort((a, b) => a.url.localeCompare(b.url))
656
692
  };
@@ -793,6 +829,17 @@ var AssetManager = class {
793
829
  onLibraryCollision;
794
830
  /** Store URLs whose failed version lookup was already reported (one warning per URL). */
795
831
  warnedStoreVersionLookups = /* @__PURE__ */ new Set();
832
+ /** Stores a lookup could not reach (store URL -> one line why); `add` reports them instead of "not found". */
833
+ storeFailures = /* @__PURE__ */ new Map();
834
+ /** Sources a provenance walk had to skip (source URL → why); one warning per source. */
835
+ skippedSources = /* @__PURE__ */ new Map();
836
+ /** `onSourceError` of every provenance walk: name the source once, leave it out, go on. */
837
+ reportSourceError = (clone, err) => {
838
+ const why = err instanceof Error ? err.message : String(err);
839
+ if (this.skippedSources.has(clone.sourceUrl)) return;
840
+ this.skippedSources.set(clone.sourceUrl, why);
841
+ console.warn(`skaile: source ${clone.sourceUrl} skipped: ${why}`);
842
+ };
796
843
  constructor(opts) {
797
844
  this.projectDir = resolve(opts.projectDir);
798
845
  this.global = opts.global ?? false;
@@ -827,15 +874,27 @@ var AssetManager = class {
827
874
  return this.global ? globalSkaileDir() : this.projectDir;
828
875
  }
829
876
  /**
830
- * The harnesses a global deploy fans out to: the explicit `harnesses` override
831
- * (a `--harness` filter), else `resolveGlobalHarnesses()`. In project mode this
832
- * is exactly `[driverTarget]`, so the shared fan-out loop degenerates to the
877
+ * The harnesses a global deploy fans out to: the explicit `harnesses` override (a `--harness`
878
+ * filter), else the explicit `global_harnesses:` of `~/.skaile/skaile.yaml`, else every harness
879
+ * whose root dir exists under `~` plus the harness the project is configured for (a project on
880
+ * a harness whose dir does not exist yet still gets its user-scope assets). In project mode
881
+ * this is exactly `[driverTarget]`, so the shared fan-out loop degenerates to the
833
882
  * single-target path.
834
883
  */
835
884
  targetHarnesses() {
836
885
  if (!this.global) return [this.driverTarget];
837
886
  if (this.harnessesOverride && this.harnessesOverride.length > 0) return this.harnessesOverride;
838
- return resolveGlobalHarnesses();
887
+ const resolved = resolveGlobalHarnesses();
888
+ if (resolveGlobalSkWorkspaceConfig().global_harnesses?.length) return resolved;
889
+ const configured = resolveConfiguredDriverTarget(this.projectDir);
890
+ return configured && !resolved.includes(configured) ? [...resolved, configured] : resolved;
891
+ }
892
+ /**
893
+ * The harnesses `add` / `install` deploy into: `[driverTarget]` for a project, the global
894
+ * harness set (see {@link AssetManager.targetHarnesses}) for a global manager.
895
+ */
896
+ deployTargets() {
897
+ return this.targetHarnesses();
839
898
  }
840
899
  get storeCacheDir() {
841
900
  if (this.global) return join(globalCacheRoot(), "store");
@@ -1039,6 +1098,31 @@ var AssetManager = class {
1039
1098
  if (c.homepage != null) entry.homepage = c.homepage;
1040
1099
  return entry;
1041
1100
  }
1101
+ /**
1102
+ * The {@link ProvenanceCandidate} a source- or store-origin lock entry stands for: what a
1103
+ * deploy needs to restore the asset from the commit the lock names (`files[]` is the asset's
1104
+ * whole file set). `null` for a library-origin entry or a key that is not a canonical ref.
1105
+ * The source URL is the declared source's own spelling (the bundled factory tree and a
1106
+ * `sources:` entry match their declaration by it).
1107
+ */
1108
+ lockedCandidate(key, entry, repositories) {
1109
+ if (!entry.source) return null;
1110
+ const { publisher, kind, name, version } = parseCanonicalLockKey(key);
1111
+ if (!publisher || !kind || !name) return null;
1112
+ const url = entry.source.url;
1113
+ const factory = Object.values(repositories).find((d) => d.factory);
1114
+ const declared = factory?.url !== void 0 && normalizeRepoUrl(url) === normalizeRepoUrl(factory.url) ? factory : repositories[sourceCacheKey(url)];
1115
+ return {
1116
+ publisher,
1117
+ kind,
1118
+ name,
1119
+ version: version ?? "",
1120
+ sourceUrl: declared?.url ?? url,
1121
+ commit: entry.source.commit,
1122
+ files: entry.files,
1123
+ sha256: entry.sha256
1124
+ };
1125
+ }
1042
1126
  /**
1043
1127
  * Resolve refs the source/store pass could not against the user's registered
1044
1128
  * **libraries** (local authoring places). Each library dir is scanned on disk
@@ -1071,6 +1155,7 @@ var AssetManager = class {
1071
1155
  const { byKey, isDefaultLib, libraryDir } = scan;
1072
1156
  const entries = [];
1073
1157
  const fileSets = /* @__PURE__ */ new Map();
1158
+ const diskHashes = /* @__PURE__ */ new Map();
1074
1159
  let snap;
1075
1160
  const allCandidates = [...byKey.values()].flat();
1076
1161
  for (const ref of missing) {
@@ -1098,23 +1183,34 @@ var AssetManager = class {
1098
1183
  }
1099
1184
  let candidates = pool.filter((c) => !pin || matchPin(pin, c.entry.version ?? ""));
1100
1185
  let lockedLibrary;
1186
+ const lockedMap = opts.preferLocked?.libraries ?? opts.lockedLibraries;
1101
1187
  if (parsed.publisher) {
1102
- lockedLibrary = opts.lockedLibraries?.get(
1188
+ lockedLibrary = lockedMap?.get(
1103
1189
  `${parsed.kind}:${parsed.publisher.replace(/^@/, "")}/${parsed.name}`
1104
1190
  );
1105
1191
  } else {
1106
- const same = [...opts.lockedLibraries ?? []].filter(([k]) => {
1192
+ const same = [...lockedMap ?? []].filter(([k]) => {
1107
1193
  const slash = k.indexOf("/");
1108
1194
  return k.startsWith(`${parsed.kind}:`) && k.slice(slash + 1) === parsed.name;
1109
1195
  });
1110
1196
  if (same.length === 1) lockedLibrary = same[0][1];
1111
1197
  }
1112
- if (lockedLibrary) {
1198
+ if (lockedLibrary && !opts.preferLocked) {
1113
1199
  const inLocked = candidates.filter((c) => c.library === lockedLibrary);
1114
1200
  if (inLocked.length > 0) candidates = inLocked;
1115
1201
  }
1116
1202
  if (candidates.length === 0) continue;
1117
- candidates.sort(libraryPreference(isDefaultLib));
1203
+ const prefer = opts.preferLocked ? (c) => {
1204
+ if (lockedLibrary && c.library === lockedLibrary) return 0;
1205
+ const id = `${c.entry.kind}:${(c.entry.publisher ?? "").replace(/^@/, "")}/${c.entry.name}`;
1206
+ const lockedSha = opts.preferLocked?.shas.get(id);
1207
+ const libPath = libraryDir.get(c.library);
1208
+ const onDisk = lockedSha && libPath ? libraryDiskHashes(libPath, diskHashes, this.registry).get(
1209
+ `${c.entry.kind}:${c.entry.name}`
1210
+ ) : void 0;
1211
+ return onDisk !== void 0 && onDisk === lockedSha ? 1 : 2;
1212
+ } : void 0;
1213
+ candidates.sort(libraryPreference(isDefaultLib, prefer));
1118
1214
  const hit = candidates[0];
1119
1215
  if (!opts.quiet && !opts.library) {
1120
1216
  this.warnLibraryCollision(
@@ -1255,7 +1351,8 @@ var AssetManager = class {
1255
1351
  const cloneDirs = new Set(clones.map((c) => resolve(c.localPath)));
1256
1352
  const index = await buildProvenanceIndex(clones, {
1257
1353
  projectDir: this.projectDir,
1258
- knownKinds: this.knownKinds
1354
+ knownKinds: this.knownKinds,
1355
+ onSourceError: this.reportSourceError
1259
1356
  });
1260
1357
  const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);
1261
1358
  const hasFactory = Object.values(repositories).some((d) => d.factory);
@@ -1464,6 +1561,34 @@ var AssetManager = class {
1464
1561
  publisher: ref?.publisher ?? entry.publisher?.replace(/^@/, "")
1465
1562
  };
1466
1563
  }
1564
+ /**
1565
+ * Refuse to lock a source commit another machine cannot check out. A commit made in the clone
1566
+ * itself (or one `source sync` could not fast-forward past) is in no remote branch: the lock
1567
+ * would name bytes nobody else has, and `install --locked` there could not restore them.
1568
+ * Linked (dev-override) and user-owned local sources are never checked: their lock is
1569
+ * machine-local by choice.
1570
+ *
1571
+ * @param resolved - Candidates about to be locked.
1572
+ * @param repositories - Source declarations of the project.
1573
+ * @throws With `<url> clone has unpublished commit <sha>` and the way out.
1574
+ */
1575
+ assertSourceCommitsPublished(resolved, repositories) {
1576
+ const links = readLinks(this.projectDir);
1577
+ const checked = /* @__PURE__ */ new Set();
1578
+ for (const c of resolved) {
1579
+ if (!c.commit || /^0+$/.test(c.commit) || checked.has(`${c.sourceUrl}@${c.commit}`)) continue;
1580
+ checked.add(`${c.sourceUrl}@${c.commit}`);
1581
+ const hit = Object.entries(repositories).find(
1582
+ ([, d]) => d.url !== void 0 && !d.factory && d.url === c.sourceUrl
1583
+ );
1584
+ if (!hit || links[hit[0]]) continue;
1585
+ const dir = this.resolveRepoDir(hit[1], hit[0]);
1586
+ if (!dir || isCommitOnRemote(dir, c.commit)) continue;
1587
+ throw new Error(
1588
+ `${c.sourceUrl} clone has unpublished commit ${c.commit.slice(0, 7)} - push it, or reset the clone (git -C ${dir} reset --hard origin/${hit[1].branch ?? "main"}) - nothing was locked`
1589
+ );
1590
+ }
1591
+ }
1467
1592
  /**
1468
1593
  * Refuse assets of one kind and name from different publishers: they deploy into the
1469
1594
  * same folder, so the later one would silently overwrite the earlier. Throws one line
@@ -1771,6 +1896,14 @@ var AssetManager = class {
1771
1896
  const found = this.lockedLibrary(origin, snap);
1772
1897
  return found.state === "ok" ? found.path : null;
1773
1898
  }
1899
+ /**
1900
+ * The `kind:@publisher/name` identities the lock holds for one `kind` and `name`, whatever
1901
+ * their publisher. `diff` uses it to accept a ref without a publisher only when it names
1902
+ * exactly one locked asset.
1903
+ */
1904
+ lockedRefsNamed(kind, name) {
1905
+ return Object.keys(this.tryReadLock()?.assets ?? {}).map(parseCanonicalLockKey).filter((id) => id.kind === kind && id.name === name).map((id) => id.publisher ? `${kind}:@${id.publisher}/${name}` : `${kind}:${name}`);
1906
+ }
1774
1907
  /**
1775
1908
  * Where each library-origin lock entry of this project resolves on this machine: identity
1776
1909
  * `kind:publisher/name` (no scope sigil, no version) → the name the locked library is
@@ -1800,6 +1933,19 @@ var AssetManager = class {
1800
1933
  }
1801
1934
  return out;
1802
1935
  }
1936
+ /**
1937
+ * What `update` prefers when libraries tie: the library each lock entry resolves to here
1938
+ * ({@link lockedLibraryNames}, a `library rename` followed) and the sha256 it locked.
1939
+ */
1940
+ async lockedPreference() {
1941
+ const shas = /* @__PURE__ */ new Map();
1942
+ for (const [key, e] of Object.entries(this.tryReadLock()?.assets ?? {})) {
1943
+ if (!e.library?.sha256 || e.library.installed) continue;
1944
+ const { publisher, kind, name } = parseCanonicalLockKey(key);
1945
+ if (publisher && kind && name) shas.set(`${kind}:${publisher}/${name}`, e.library.sha256);
1946
+ }
1947
+ return { libraries: await this.lockedLibraryNames(), shas };
1948
+ }
1803
1949
  // ── Store fetch-then-deploy ────────────────────────────────────────────
1804
1950
  /** A candidate's stable identity key (`<publisher>/<kind>:<name>@<version>`). */
1805
1951
  candidateKey(c) {
@@ -1865,6 +2011,7 @@ var AssetManager = class {
1865
2011
  const resolved = [];
1866
2012
  const overridesApplied = /* @__PURE__ */ new Set();
1867
2013
  const presets = [];
2014
+ const requiredBy = /* @__PURE__ */ new Map();
1868
2015
  const lib = { entries: [], resolved: /* @__PURE__ */ new Set(), libraryOf: /* @__PURE__ */ new Map() };
1869
2016
  const missing = /* @__PURE__ */ new Set();
1870
2017
  const seen = /* @__PURE__ */ new Set();
@@ -1913,6 +2060,13 @@ var AssetManager = class {
1913
2060
  return depId !== null && declaredById.get(depId) || dep;
1914
2061
  })
1915
2062
  );
2063
+ if (e.kind !== "preset") {
2064
+ for (const dep of deps2) {
2065
+ const depId = refIdentity(dep);
2066
+ if (depId !== null && declaredById.has(depId)) continue;
2067
+ requiredBy.set(dep, [...requiredBy.get(dep) ?? [], canonicalEntryRef(e)]);
2068
+ }
2069
+ }
1916
2070
  }
1917
2071
  for (const r of hit.resolved) lib.resolved.add(r);
1918
2072
  return next;
@@ -1937,7 +2091,8 @@ var AssetManager = class {
1937
2091
  );
1938
2092
  const hit = await this.resolveLibraryEntries([...libraryTried], {
1939
2093
  quiet: !opts.warnCollisions,
1940
- lockedLibraries: opts.lockedLibraries
2094
+ lockedLibraries: opts.lockedLibraries,
2095
+ preferLocked: opts.preferLocked
1941
2096
  });
1942
2097
  const next = absorb(hit);
1943
2098
  const rest = fresh.filter((ref) => !hit.resolved.has(ref));
@@ -1954,7 +2109,11 @@ var AssetManager = class {
1954
2109
  presets.push(...r.presets);
1955
2110
  const hit2 = await this.resolveLibraryEntries(
1956
2111
  r.missing.filter((m) => !libraryTried.has(m)),
1957
- { quiet: !opts.warnCollisions, lockedLibraries: opts.lockedLibraries }
2112
+ {
2113
+ quiet: !opts.warnCollisions,
2114
+ lockedLibraries: opts.lockedLibraries,
2115
+ preferLocked: opts.preferLocked
2116
+ }
1958
2117
  );
1959
2118
  next.push(...absorb(hit2));
1960
2119
  for (const m of r.missing) if (!hit2.resolved.has(m)) missing.add(m);
@@ -1965,7 +2124,7 @@ var AssetManager = class {
1965
2124
  const id = refIdentity(m);
1966
2125
  return !lib.resolved.has(m) && !(id !== null && covered.has(id));
1967
2126
  });
1968
- return { resolved, missing: stillMissing, overridesApplied, lib, presets };
2127
+ return { resolved, missing: stillMissing, overridesApplied, lib, presets, requiredBy };
1969
2128
  }
1970
2129
  /** The catalog fetcher to use: an injected one, else built from `stores`. */
1971
2130
  storeFetcherFor(stores) {
@@ -1980,8 +2139,8 @@ var AssetManager = class {
1980
2139
  let url = this.catalogUrlOverride;
1981
2140
  if (url === void 0) {
1982
2141
  try {
1983
- const { resolveConfig } = await import('./library/index.js');
1984
- url = resolveConfig({ projectDir: this.projectDir }).catalog.url;
2142
+ const { resolveConfig: resolveConfig2 } = await import('./library/index.js');
2143
+ url = resolveConfig2({ projectDir: this.projectDir }).catalog.url;
1985
2144
  } catch {
1986
2145
  return [];
1987
2146
  }
@@ -2039,13 +2198,31 @@ var AssetManager = class {
2039
2198
  // from source.url@commit and ignores it, so "" is inert.
2040
2199
  tier: ""
2041
2200
  };
2042
- const { installPath } = await installFromManifest({
2043
- manifest,
2044
- libraryRoot: this.storeCacheDir,
2045
- targetDir,
2046
- fetcher: this.injectedAssetFetcher
2201
+ const root = commonDirPrefix(c.files.map((f) => f.path));
2202
+ const intact = c.files.every((f) => {
2203
+ const rel = root && f.path.startsWith(`${root}/`) ? f.path.slice(root.length + 1) : f.path;
2204
+ try {
2205
+ return computeHash(join(targetDir, rel)) === f.sha256;
2206
+ } catch {
2207
+ return false;
2208
+ }
2047
2209
  });
2048
- staged.set(this.candidateKey(c), join(installPath, this.stagedManifestRel(c)));
2210
+ if (intact) {
2211
+ staged.set(this.candidateKey(c), join(targetDir, this.stagedManifestRel(c)));
2212
+ continue;
2213
+ }
2214
+ try {
2215
+ const { installPath } = await installFromManifest({
2216
+ manifest,
2217
+ libraryRoot: this.storeCacheDir,
2218
+ targetDir,
2219
+ fetcher: this.injectedAssetFetcher
2220
+ });
2221
+ staged.set(this.candidateKey(c), join(installPath, this.stagedManifestRel(c)));
2222
+ } catch (err) {
2223
+ const reason = err instanceof Error ? err.message : String(err);
2224
+ throw new Error(`${manifest.ref} (${c.sourceUrl} at ${c.commit.slice(0, 7)}): ${reason}`);
2225
+ }
2049
2226
  }
2050
2227
  return staged;
2051
2228
  }
@@ -2155,22 +2332,43 @@ var AssetManager = class {
2155
2332
  if (cloneError) return cloneError;
2156
2333
  const provenanceIndex = await buildProvenanceIndex(this.buildClones(repositories), {
2157
2334
  projectDir: this.projectDir,
2158
- knownKinds: this.knownKinds
2335
+ knownKinds: this.knownKinds,
2336
+ onSourceError: this.reportSourceError
2337
+ });
2338
+ const { resolved, missing, overridesApplied, lib, presets, requiredBy } = await this.resolveLibraryFirst(dependencies, {
2339
+ provenanceIndex,
2340
+ overrides,
2341
+ stores,
2342
+ declaredRefs: dependencies,
2343
+ // `install` restores what the lock recorded: a changed default library or a second
2344
+ // library holding the same ref does not move a locked asset. `update` re-resolves.
2345
+ ...opts?.moveLibraries ? { preferLocked: await this.lockedPreference() } : { lockedLibraries: await this.lockedLibraryNames() }
2159
2346
  });
2160
- const { resolved, missing, overridesApplied, lib, presets } = await this.resolveLibraryFirst(
2161
- dependencies,
2162
- {
2163
- provenanceIndex,
2164
- overrides,
2165
- stores,
2166
- declaredRefs: dependencies,
2167
- // `install` restores what the lock recorded: a changed default library or a second
2168
- // library holding the same ref does not move a locked asset. `update` re-resolves.
2169
- ...opts?.moveLibraries ? {} : { lockedLibraries: await this.lockedLibraryNames() }
2170
- }
2171
- );
2172
2347
  this.assertNoFolderCollision([...resolved, ...lib.entries.map((e) => this.entryIdentity(e))]);
2348
+ this.assertSourceCommitsPublished(resolved, repositories);
2173
2349
  const stillMissing = missing.filter((m) => !lib.resolved.has(m));
2350
+ const lockedKeys = new Set(Object.keys(this.tryReadLock()?.assets ?? {}));
2351
+ const unmetByNew = /* @__PURE__ */ new Map();
2352
+ for (const m of stillMissing) {
2353
+ const newcomers = (requiredBy.get(m) ?? []).filter((parent) => !lockedKeys.has(parent));
2354
+ if (newcomers.length > 0) unmetByNew.set(m, newcomers);
2355
+ }
2356
+ if (unmetByNew.size > 0) {
2357
+ const hints = {};
2358
+ for (const [m, parents] of unmetByNew) {
2359
+ const requirer = parents.map((p) => p.split("#")[0]).join(", ");
2360
+ hints[m] = ` is required by ${requirer} (not found \u2014 ${REGISTER_HOLDER}, or drop ${requirer} with \`skaile remove ${parents[0].split("#")[0]}\`) \u2014 nothing was installed`;
2361
+ }
2362
+ return {
2363
+ deployed: [],
2364
+ removed: [],
2365
+ missing: [...unmetByNew.keys()],
2366
+ missingHints: hints,
2367
+ lockWritten: false,
2368
+ npmInstalled: [],
2369
+ npmFailed: []
2370
+ };
2371
+ }
2174
2372
  const missingHints = await this.publisherChangeHints(stillMissing);
2175
2373
  const prevLock = this.tryReadLock();
2176
2374
  const kept = keptLockEntries(prevLock, stillMissing);
@@ -2203,7 +2401,7 @@ var AssetManager = class {
2203
2401
  )
2204
2402
  )
2205
2403
  ];
2206
- const restored = this.restoredCopies(copyDrift, deployed);
2404
+ let restored = this.restoredCopies(copyDrift, deployed);
2207
2405
  await this.renderDriverMcpConfig();
2208
2406
  const agentRender = await this.renderAgentInstances();
2209
2407
  const lockWanted = resolved.length > 0 || lib.entries.length > 0 || existsSync(this.lockPath);
@@ -2213,6 +2411,7 @@ var AssetManager = class {
2213
2411
  if (lockWanted) {
2214
2412
  const lockData = withKeptLockEntries(freshLock, kept);
2215
2413
  relocked = relockedRefs(prevLock, lockData);
2414
+ restored = [...restored, ...this.removeExcludedLeftovers(relocked)];
2216
2415
  moved = libraryMoves(prevLock, libraryLock);
2217
2416
  lockWritten = writeLock(this.lockPath, lockData);
2218
2417
  }
@@ -2273,7 +2472,8 @@ var AssetManager = class {
2273
2472
  const { kind, name, publisher } = id;
2274
2473
  const component = kind ? this.installTarget(kind) : void 0;
2275
2474
  if (!kind || !name || !component) return [];
2276
- const dir = deployedDir(component, name, this.driverTarget, this.global, this.projectDir);
2475
+ const keptAgent = kind === "agent" && !this.global ? join(agentSourceCacheDir(this.projectDir), name) : null;
2476
+ const dir = keptAgent && existsSync(keptAgent) ? keptAgent : deployedDir(component, name, this.driverTarget, this.global, this.projectDir);
2277
2477
  if (!existsSync(dir)) return [];
2278
2478
  try {
2279
2479
  const scanned = await scanDirectory(dir, publisher ?? "", { knownKinds: this.knownKinds });
@@ -2397,13 +2597,33 @@ var AssetManager = class {
2397
2597
  return null;
2398
2598
  }
2399
2599
  }
2600
+ /**
2601
+ * A catalog client for `storeUrl` that honours `catalog.cache_ttl` (`0` = air-gapped: no
2602
+ * network, so every lookup that is not cached throws `OfflineError`).
2603
+ */
2604
+ remoteStore(storeUrl) {
2605
+ let cacheTtlMs;
2606
+ try {
2607
+ cacheTtlMs = resolveConfig({ projectDir: this.projectDir }).catalog.cache_ttl * 1e3;
2608
+ } catch {
2609
+ }
2610
+ return new RemoteCatalogSource({ baseUrl: storeUrl, cacheTtlMs });
2611
+ }
2612
+ /**
2613
+ * Remember why a store could not be asked (store URL → one line without a JS error class
2614
+ * name), so `add` can say `store unreachable` instead of a bare `Asset not found`.
2615
+ */
2616
+ noteStoreFailure(storeUrl, err) {
2617
+ const text = err instanceof OfflineError ? `${storeUrl}: air-gapped (catalog.cache_ttl: 0), the store was not asked` : describeCatalogError(err, storeUrl);
2618
+ this.storeFailures.set(storeUrl, text);
2619
+ return text;
2620
+ }
2400
2621
  /** Build a store fetcher from the configured stores, or undefined when none. */
2401
2622
  buildStoreFetcher(stores) {
2402
2623
  if (stores.length === 0) return void 0;
2403
2624
  return {
2404
2625
  getInstallManifest: async (storeUrl, ref) => {
2405
- const { RemoteCatalogSource, CatalogHttpError } = await import('./library/index.js');
2406
- const src = new RemoteCatalogSource({ baseUrl: storeUrl });
2626
+ const src = this.remoteStore(storeUrl);
2407
2627
  try {
2408
2628
  const m = await src.getInstallManifest(ref);
2409
2629
  let deps;
@@ -2416,7 +2636,7 @@ var AssetManager = class {
2416
2636
  else if (deps === void 0)
2417
2637
  gap = `has a cached catalog row for ${ref} without dependencies`;
2418
2638
  } catch (err) {
2419
- gap = `dependency lookup for ${ref} failed \u2014 ${err}`;
2639
+ gap = `dependency lookup for ${ref} failed \u2014 ${describeCatalogError(err, storeUrl)}`;
2420
2640
  }
2421
2641
  if (gap) {
2422
2642
  console.warn(`skaile: store ${storeUrl} ${gap}; installing without its dependencies`);
@@ -2430,23 +2650,23 @@ var AssetManager = class {
2430
2650
  };
2431
2651
  } catch (err) {
2432
2652
  if (err instanceof CatalogHttpError && err.status === 404) return null;
2653
+ this.noteStoreFailure(storeUrl, err);
2433
2654
  throw err;
2434
2655
  }
2435
2656
  },
2436
2657
  getCanonicalDigest: async (storeUrl, ref) => {
2437
- const { RemoteCatalogSource } = await import('./library/index.js');
2438
- const src = new RemoteCatalogSource({ baseUrl: storeUrl });
2658
+ const src = this.remoteStore(storeUrl);
2439
2659
  return src.getCanonicalDigest(ref);
2440
2660
  },
2441
2661
  listVersions: async (storeUrl, ref) => {
2442
- const { RemoteCatalogSource } = await import('./library/index.js');
2443
- const src = new RemoteCatalogSource({ baseUrl: storeUrl });
2662
+ const src = this.remoteStore(storeUrl);
2444
2663
  try {
2445
2664
  return await src.listVersions(ref);
2446
2665
  } catch (err) {
2666
+ const text = this.noteStoreFailure(storeUrl, err);
2447
2667
  if (!this.warnedStoreVersionLookups.has(storeUrl)) {
2448
2668
  this.warnedStoreVersionLookups.add(storeUrl);
2449
- console.warn(`skaile: store ${storeUrl} version lookup for ${ref} failed \u2014 ${err}`);
2669
+ console.warn(`skaile: store lookup of ${ref} failed: ${text}`);
2450
2670
  }
2451
2671
  return [];
2452
2672
  }
@@ -2522,20 +2742,46 @@ var AssetManager = class {
2522
2742
  this.assertNoFolderCollision(Object.keys(lock.assets).map(parseCanonicalLockKey));
2523
2743
  const declBySlug = new Map(Object.entries(repositories));
2524
2744
  const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);
2525
- const factoryDir = Object.values(repositories).find((d) => d.factory)?.path ?? null;
2745
+ const factoryDecl = Object.values(repositories).find((d) => d.factory);
2746
+ const factoryDir = factoryDecl?.path ?? null;
2747
+ const isFactoryUrl = (url) => factoryDir !== null && normalizeRepoUrl(url) === factoryUrl;
2748
+ const unavailable = [];
2526
2749
  for (const src of lock.sources) {
2527
- if (factoryDir && normalizeRepoUrl(src.url) === factoryUrl) continue;
2750
+ if (isFactoryUrl(src.url)) continue;
2528
2751
  const slug = sourceCacheKey(src.url);
2529
- const decl = declBySlug.get(slug) ?? { url: src.url };
2530
- ensureRepo(decl, slug, this.reposDir, { projectDir: this.projectDir, pin: src.commit });
2752
+ const declared = declBySlug.get(slug);
2753
+ if (!declared && GITHUB_REPO_URL.test(src.url)) continue;
2754
+ try {
2755
+ const dir = ensureRepo(declared ?? { url: src.url }, slug, this.reposDir, {
2756
+ projectDir: this.projectDir,
2757
+ // A lock restore deploys the pinned commit's bytes or fails: never another commit's.
2758
+ .../^0*$/.test(src.commit) ? {} : { pin: src.commit, strictPin: true }
2759
+ });
2760
+ if (!declared) repositories[slug] = { url: src.url, path: dir };
2761
+ } catch (err) {
2762
+ const reason = err instanceof Error ? err.message : String(err);
2763
+ unavailable.push(`unavailable: ${src.url} at ${src.commit.slice(0, 7)} (${reason})`);
2764
+ }
2765
+ }
2766
+ if (unavailable.length > 0) {
2767
+ throw new Error(`Lock file verification failed:
2768
+ ${unavailable.join("\n ")}`);
2769
+ }
2770
+ const candidates = [];
2771
+ const cloneOrigin = {};
2772
+ for (const [key, entry] of Object.entries(lock.assets)) {
2773
+ const candidate = this.lockedCandidate(key, entry, repositories);
2774
+ if (!candidate) continue;
2775
+ candidates.push(candidate);
2776
+ if (isFactoryUrl(candidate.sourceUrl) || this.candidateHasLocalBytes(candidate, repositories)) {
2777
+ cloneOrigin[key] = entry;
2778
+ }
2531
2779
  }
2532
- const resolveCloneDir = (sourceUrl) => {
2533
- if (factoryDir && normalizeRepoUrl(sourceUrl) === factoryUrl) return factoryDir;
2780
+ const verification = verifyLock({ ...lock, assets: cloneOrigin }, (sourceUrl) => {
2781
+ if (isFactoryUrl(sourceUrl)) return factoryDir;
2534
2782
  const slug = sourceCacheKey(sourceUrl);
2535
- const decl = declBySlug.get(slug) ?? { url: sourceUrl };
2536
- return this.resolveRepoDir(decl, slug);
2537
- };
2538
- const verification = verifyLock(lock, resolveCloneDir);
2783
+ return this.resolveRepoDir(repositories[slug] ?? { url: sourceUrl }, slug);
2784
+ });
2539
2785
  if (!verification.ok) {
2540
2786
  const issues = [
2541
2787
  ...verification.drifted.map((r) => `drifted: ${r}`),
@@ -2554,28 +2800,13 @@ var AssetManager = class {
2554
2800
  ${lines.join("\n ")}`
2555
2801
  );
2556
2802
  }
2557
- const resolved = [];
2558
- for (const [ref, entry] of Object.entries(lock.assets)) {
2559
- if (!entry.source) continue;
2560
- const { publisher, kind, name } = parseCanonicalLockKey(ref);
2561
- if (!publisher || !kind || !name) continue;
2562
- const slug = sourceCacheKey(entry.source.url);
2563
- const cloneDir = resolveCloneDir(entry.source.url) ?? join(this.reposDir, slug);
2564
- const mdRel = entry.files.find((f) => /\.(md|yaml)$/i.test(f.path))?.path ?? entry.files[0]?.path ?? "";
2565
- resolved.push({
2566
- name,
2567
- kind,
2568
- description: "",
2569
- source: mdRel ? join(cloneDir, mdRel) : cloneDir,
2570
- // Keep the publisher label slash-free (repo name), not the full cache key.
2571
- publisher: sourceShortName(entry.source.url),
2572
- version: entry.source.commit,
2573
- // The lock key is the canonical ref; `publisher` above is only a clone label.
2574
- canonicalRef: ref,
2575
- requires: [],
2576
- dependencies: []
2577
- });
2578
- if (!repositories[slug]) repositories[slug] = { url: entry.source.url, path: cloneDir };
2803
+ let resolved;
2804
+ try {
2805
+ resolved = await this.buildCatalogEntries(candidates, repositories);
2806
+ } catch (err) {
2807
+ const reason = err instanceof Error ? err.message : String(err);
2808
+ throw new Error(`Lock file verification failed:
2809
+ ${reason}`);
2579
2810
  }
2580
2811
  const library = await this.restoreLibraryLockEntries(lock);
2581
2812
  const copyDrift = await this.lockedCopyDrift();
@@ -2664,7 +2895,8 @@ var AssetManager = class {
2664
2895
  this.ensureSourceClonesQuiet(repositories, sources);
2665
2896
  const index = await buildProvenanceIndex(this.buildClones(repositories), {
2666
2897
  projectDir: this.projectDir,
2667
- knownKinds: this.knownKinds
2898
+ knownKinds: this.knownKinds,
2899
+ onSourceError: this.reportSourceError
2668
2900
  });
2669
2901
  for (const candidates of index.values()) for (const c of candidates) note(c);
2670
2902
  for (const { entry } of await this.libraryAssets()) note(entry);
@@ -2699,11 +2931,19 @@ var AssetManager = class {
2699
2931
  this.ensureSourceClonesQuiet(repositories, sources);
2700
2932
  const provenanceIndex = await buildProvenanceIndex(this.buildClones(repositories), {
2701
2933
  projectDir: this.projectDir,
2702
- knownKinds: this.knownKinds
2934
+ knownKinds: this.knownKinds,
2935
+ onSourceError: this.reportSourceError
2703
2936
  });
2704
2937
  const { resolved, missing, overridesApplied, lib, presets } = await this.resolveLibraryFirst(
2705
2938
  [ref],
2706
- { provenanceIndex, overrides, stores, declaredRefs: dependencies, warnCollisions: true }
2939
+ {
2940
+ provenanceIndex,
2941
+ overrides,
2942
+ stores,
2943
+ declaredRefs: dependencies,
2944
+ warnCollisions: true,
2945
+ ...opts?.preferLockedLibrary ? { preferLocked: await this.lockedPreference() } : {}
2946
+ }
2707
2947
  );
2708
2948
  if (resolved.length === 0 && lib.entries.length === 0 && presets.length === 0) {
2709
2949
  const snap = await this.loadLibraryIndex();
@@ -2721,6 +2961,12 @@ var AssetManager = class {
2721
2961
  );
2722
2962
  }
2723
2963
  }
2964
+ const unreachable = [...this.storeFailures.values()];
2965
+ if (unreachable.length > 0) {
2966
+ throw new Error(
2967
+ `Store unreachable \u2014 ${ref} was not looked up: ${unreachable.join("; ")}. Check the URL with \`skaile catalog test\`; a library or source can still hold the asset.`
2968
+ );
2969
+ }
2724
2970
  throw new Error(
2725
2971
  `Asset not found: ${ref}${(await this.publisherChangeHints([ref]))[ref] ?? ""}${missing.length ? ` (missing: ${missing.join(", ")})` : ""}`
2726
2972
  );
@@ -2742,6 +2988,7 @@ var AssetManager = class {
2742
2988
  }
2743
2989
  }
2744
2990
  }
2991
+ this.assertSourceCommitsPublished(resolved, repositories);
2745
2992
  this.assertNoFolderCollision(
2746
2993
  [...resolved, ...lib.entries.map((e) => this.entryIdentity(e))],
2747
2994
  [
@@ -3542,12 +3789,12 @@ var AssetManager = class {
3542
3789
  return out;
3543
3790
  }
3544
3791
  /**
3545
- * Library-locked assets whose deployed directory lacks files the deploy writes —
3546
- * a deleted `build.py` / `scripts/` helper next to an intact `SKILL.md`. The
3547
- * expected set is the library entry's file set (every file under its manifest
3548
- * `root:`), the same bytes the lock hashes; only presence is checked, so a
3549
- * local edit never counts. An asset with no deployed directory is not listed
3550
- * (`listDeclared` reports it as drift); an agent is rendered, not copied, so it
3792
+ * Locked assets whose deployed directory lacks files the deploy writes — a deleted
3793
+ * `build.py` / `scripts/` helper next to an intact `SKILL.md`. The expected set is the file
3794
+ * set the lock covers: a library entry's files (every file under its manifest `root:`), a
3795
+ * source or store entry's `files[]` (the asset's whole file set at the locked commit). Only
3796
+ * presence is checked, so a local edit never counts. An asset with no deployed directory is
3797
+ * not listed (`listDeclared` reports it as drift); an agent is rendered, not copied, so it
3551
3798
  * has no file mirror to compare. `skaile install` restores what is listed.
3552
3799
  *
3553
3800
  * @returns One {@link IncompleteDeploy} per affected asset; empty when healthy
@@ -3556,10 +3803,25 @@ var AssetManager = class {
3556
3803
  async incompleteDeploys() {
3557
3804
  const lock = this.tryReadLock();
3558
3805
  if (!lock) return [];
3806
+ const out = [];
3807
+ const { patches } = this.loadConfig();
3808
+ for (const [key, entry] of Object.entries(lock.assets)) {
3809
+ if (!entry.source || entry.files.length === 0) continue;
3810
+ const { publisher, kind, name } = parseCanonicalLockKey(key);
3811
+ const component = kind ? this.installTarget(kind) : void 0;
3812
+ if (!publisher || !kind || !name || !component || component === "agent") continue;
3813
+ if (patches[`${kind}:${name}`]) continue;
3814
+ const dest = join(
3815
+ deployedBase(component, this.driverTarget, this.global, this.projectDir),
3816
+ name
3817
+ );
3818
+ if (!existsSync(dest) || lstatSync(dest).isSymbolicLink()) continue;
3819
+ const missing = lockedAssetFiles(kind, entry.files).map((f) => f.rel).filter((rel) => !existsSync(join(dest, rel)));
3820
+ if (missing.length > 0) out.push({ ref: `${kind}:@${publisher}/${name}`, missing });
3821
+ }
3559
3822
  const locked = Object.entries(lock.assets).filter(([, e]) => e.library !== void 0 && !e.library.installed).map(([key]) => key);
3560
- if (locked.length === 0) return [];
3823
+ if (locked.length === 0) return out;
3561
3824
  const lib = await this.resolveLibraryEntries(locked, { quiet: true });
3562
- const out = [];
3563
3825
  for (const entry of lib.entries) {
3564
3826
  const component = this.installTarget(entry.kind);
3565
3827
  if (!entry.files || !component || component === "agent") continue;
@@ -3900,7 +4162,17 @@ var AssetManager = class {
3900
4162
  if (!kind || !name) continue;
3901
4163
  const lockedCommit = entry.source.commit || src.commit;
3902
4164
  const moved = lockedCommit && !/^0+$/.test(lockedCommit) && lockedCommit !== status.localHead ? commitsBetween(clone, lockedCommit, status.localHead, commitCounts) : 0;
3903
- const behind = status.behind + moved;
4165
+ let behind = status.behind + moved;
4166
+ if (behind > 0) {
4167
+ const touching = commitsTouching(
4168
+ clone,
4169
+ COMMIT_ID.test(lockedCommit) && !/^0+$/.test(lockedCommit) ? lockedCommit : status.localHead,
4170
+ status.behind > 0 && status.remoteHead ? status.remoteHead : status.localHead,
4171
+ lockedAssetDir(kind, entry.files),
4172
+ commitCounts
4173
+ );
4174
+ if (touching !== null) behind = touching;
4175
+ }
3904
4176
  if (behind <= 0) continue;
3905
4177
  result.push({
3906
4178
  kind,
@@ -4018,6 +4290,37 @@ var AssetManager = class {
4018
4290
  }
4019
4291
  return null;
4020
4292
  }
4293
+ /**
4294
+ * The deploy entry of a source- or store-origin asset, carrying the file set its lock entry
4295
+ * lists (so a missing or edited helper shows in `diff`, not only the manifest). A source asset
4296
+ * reads from its clone; a store asset from the bytes `add`/`install` staged in the project
4297
+ * store cache. `null` when the lock has no such entry or its bytes are not on disk.
4298
+ *
4299
+ * @param want - Kind, name and optional publisher of the asset.
4300
+ */
4301
+ lockedSourceEntry(want) {
4302
+ const { repositories } = this.loadConfig();
4303
+ for (const [key, e] of Object.entries(this.tryReadLock()?.assets ?? {})) {
4304
+ const id = parseCanonicalLockKey(key);
4305
+ if (!e.source || id.kind !== want.kind || id.name !== want.name) continue;
4306
+ if (want.publisher && id.publisher !== want.publisher) continue;
4307
+ const c = this.lockedCandidate(key, e, repositories);
4308
+ if (!c) continue;
4309
+ if (this.candidateHasLocalBytes(c, repositories)) {
4310
+ return this.candidateToCatalogEntry(c, repositories);
4311
+ }
4312
+ const staged = join(
4313
+ this.storeCacheDir,
4314
+ c.publisher,
4315
+ c.kind,
4316
+ c.name,
4317
+ c.version,
4318
+ this.stagedManifestRel(c)
4319
+ );
4320
+ if (existsSync(staged)) return this.stagedCandidateToEntry(c, staged);
4321
+ }
4322
+ return null;
4323
+ }
4021
4324
  /**
4022
4325
  * Produce a unified diff from the deployed asset to its catalog source: `-` lines
4023
4326
  * are in the deployed copy only (local edits `update` would overwrite), `+` lines
@@ -4035,8 +4338,15 @@ var AssetManager = class {
4035
4338
  async diff(ref) {
4036
4339
  const parsed = parseRefTolerant(ref);
4037
4340
  if (!parsed) return { status: "not-found" };
4038
- const entry = await this.lockedLibraryEntry(parsed) ?? await this.info(ref);
4341
+ const entry = await this.lockedLibraryEntry(parsed) ?? this.lockedSourceEntry(parsed) ?? await this.info(ref);
4039
4342
  if (!entry || !existsSync(entry.source)) return { status: "not-found" };
4343
+ const wantPublisher = parsed.publisher?.replace(/^@/, "");
4344
+ if (wantPublisher) {
4345
+ const lockedHere = Object.keys(this.tryReadLock()?.assets ?? {}).map(parseCanonicalLockKey).filter((id) => id.kind === parsed.kind && id.name === parsed.name);
4346
+ if (lockedHere.length > 0 && !lockedHere.some((id) => id.publisher === wantPublisher)) {
4347
+ return { status: "not-deployed" };
4348
+ }
4349
+ }
4040
4350
  const component = this.installTarget(parsed.kind);
4041
4351
  if (parsed.kind === "preset" && this.presetRecorded(parsed)) return { status: "no-files" };
4042
4352
  if (!component) return { status: "not-deployed" };
@@ -4079,7 +4389,8 @@ var AssetManager = class {
4079
4389
  this.ensureSourceClonesQuiet(repositories, sources);
4080
4390
  const provenanceIndex = await buildProvenanceIndex(this.buildClones(repositories), {
4081
4391
  projectDir: this.projectDir,
4082
- knownKinds: this.knownKinds
4392
+ knownKinds: this.knownKinds,
4393
+ onSourceError: this.reportSourceError
4083
4394
  });
4084
4395
  const { resolved, overridesApplied, lib } = await this.resolveLibraryFirst(dependencies, {
4085
4396
  provenanceIndex,
@@ -4206,7 +4517,11 @@ var AssetManager = class {
4206
4517
  const full = await this.info(
4207
4518
  publisher ? `${entry.kind}:@${publisher}/${entry.name}` : `${entry.kind}:${entry.name}`
4208
4519
  );
4209
- if (!full) {
4520
+ const restorable = !full && publisher !== void 0 && Object.entries(lock?.assets ?? {}).some(([key, e]) => {
4521
+ const id = parseCanonicalLockKey(key);
4522
+ return e.source !== void 0 && id.kind === entry.kind && id.name === entry.name && id.publisher === publisher;
4523
+ });
4524
+ if (!full && !restorable) {
4210
4525
  if (publisher) {
4211
4526
  const canonical = `${entry.kind}:@${publisher}/${entry.name}`;
4212
4527
  const fix = (await this.unresolvedFixes([canonical])).get(canonical);
@@ -4222,8 +4537,9 @@ var AssetManager = class {
4222
4537
  }
4223
4538
  continue;
4224
4539
  }
4540
+ const declaredRequires = full ? full.requires : (await this.deployedRequirementsOf({ ...entry, publisher })).map(parseDep);
4225
4541
  const gaps = [];
4226
- const requirements = dedupeRequirements(full.requires, publisher).map(
4542
+ const requirements = dedupeRequirements(declaredRequires, publisher).map(
4227
4543
  (r) => r.publisher || !publisher ? r : { ...r, publisher }
4228
4544
  );
4229
4545
  for (const req of requirements) {
@@ -4332,8 +4648,8 @@ var AssetManager = class {
4332
4648
  type: "requires",
4333
4649
  ref: dep,
4334
4650
  asset,
4335
- reason: `is required by ${asset} but neither deployed nor locked (fixable)`,
4336
- message: `${asset} requires ${dep} (fixable)`
4651
+ reason: `is required by ${asset} but neither deployed nor locked (run skaile install)`,
4652
+ message: `${asset} requires ${dep} (run skaile install)`
4337
4653
  });
4338
4654
  } else {
4339
4655
  const fix = requirementNoHolderFix(asset);
@@ -4378,6 +4694,25 @@ var AssetManager = class {
4378
4694
  const reason = `is deployed without ${d.missing.join(", ")} \u2014 run \`skaile install\` to restore it`;
4379
4695
  gaps.push({ type: "incomplete", ref: d.ref, reason, message: `${d.ref} ${reason}` });
4380
4696
  }
4697
+ const skipped = [];
4698
+ await buildProvenanceIndex(this.buildClones(this.loadConfig().repositories), {
4699
+ projectDir: this.projectDir,
4700
+ knownKinds: this.knownKinds,
4701
+ onSourceError: (clone, err) => skipped.push({
4702
+ url: clone.sourceUrl,
4703
+ why: err instanceof Error ? err.message : String(err)
4704
+ })
4705
+ });
4706
+ for (const s of skipped) {
4707
+ const reason = `is skipped: ${s.why.replace(`${s.url}: `, "")} \u2014 fix it or run \`skaile source remove\``;
4708
+ gaps.push({
4709
+ type: "source",
4710
+ ref: s.url,
4711
+ reason,
4712
+ message: `source ${s.url} ${reason}`,
4713
+ manualFix: true
4714
+ });
4715
+ }
4381
4716
  for (const u of unboundAgentInstances(this.projectDir, this.driverTarget)) {
4382
4717
  const reason = u.ref.startsWith("agent:") ? await this.unboundAgentReason(u.id, u.ref) : `is bound by agent instance "${u.id}" but resolves to no agent.yaml \u2014 fix the path, or drop the binding from skaile.yaml`;
4383
4718
  gaps.push({
@@ -4411,7 +4746,18 @@ var AssetManager = class {
4411
4746
  */
4412
4747
  async unboundAgentAdvice(ref) {
4413
4748
  const drop = "or drop the binding from skaile.yaml";
4414
- const publisher = parseRefTolerant(ref)?.publisher;
4749
+ const parsedRef = parseRefTolerant(ref);
4750
+ const publisher = parsedRef?.publisher;
4751
+ const lockedAgent = Object.keys(this.tryReadLock()?.assets ?? {}).some((key) => {
4752
+ const k = parseCanonicalLockKey(key);
4753
+ return k.kind === "agent" && k.name === parsedRef?.name && (!publisher || !k.publisher || k.publisher === publisher);
4754
+ });
4755
+ if (lockedAgent) {
4756
+ return {
4757
+ lead: "the agent is locked but not restored here",
4758
+ advice: `run \`skaile install --locked\` first, ${drop}`
4759
+ };
4760
+ }
4415
4761
  if (publisher && await this.info(ref) !== null) {
4416
4762
  return {
4417
4763
  lead: "no agent was added for it",
@@ -4458,6 +4804,52 @@ var AssetManager = class {
4458
4804
  (g) => names(g.ref) || g.asset && names(g.asset)
4459
4805
  );
4460
4806
  }
4807
+ /**
4808
+ * The {@link ProjectState} gaps of everything `ref` requires, transitively: what `check`
4809
+ * says about the requirements of `ref`, so a command that answers for one asset (`diff`)
4810
+ * does not call it fine while a requirement of it is broken. The requirements are read from
4811
+ * the deployed copies (the lock records no edges), the way `remove` and `install` read them
4812
+ * when no library holds the asset any more. The gaps of `ref` itself are not included
4813
+ * ({@link gapsOf}).
4814
+ *
4815
+ * @param ref - Asset ref in `kind:name` or `kind:@publisher/name` form.
4816
+ */
4817
+ async requirementGapsOf(ref) {
4818
+ const want = parseRefTolerant(ref);
4819
+ if (!want) return [];
4820
+ const gaps = (await this.projectState()).gaps;
4821
+ const lockedIds = Object.keys(this.tryReadLock()?.assets ?? {}).map(parseCanonicalLockKey);
4822
+ const idKey = (id) => `${id.publisher ?? ""}/${id.kind}:${id.name}`;
4823
+ const seen = /* @__PURE__ */ new Set();
4824
+ const queue = [
4825
+ {
4826
+ kind: want.kind,
4827
+ name: want.name,
4828
+ publisher: want.publisher?.replace(/^@/, "") ?? lockedIds.find((l) => l.kind === want.kind && l.name === want.name)?.publisher
4829
+ }
4830
+ ];
4831
+ seen.add(idKey(queue[0]));
4832
+ const out = [];
4833
+ for (const asset of queue) {
4834
+ for (const dep of await this.deployedRequirementsOf(asset)) {
4835
+ const id = memberIdentity(dep);
4836
+ if (!id) continue;
4837
+ const publisher = id.publisher ?? lockedIds.find((l) => l.kind === id.kind && l.name === id.name)?.publisher;
4838
+ const next = { kind: id.kind, name: id.name, publisher };
4839
+ if (seen.has(idKey(next))) continue;
4840
+ seen.add(idKey(next));
4841
+ queue.push(next);
4842
+ for (const g of gaps) {
4843
+ if (out.includes(g)) continue;
4844
+ const p = parseRefTolerant(g.ref);
4845
+ if (p !== null && p.kind === next.kind && p.name === next.name && (!publisher || !p.publisher || p.publisher.replace(/^@/, "") === publisher)) {
4846
+ out.push(g);
4847
+ }
4848
+ }
4849
+ }
4850
+ }
4851
+ return out;
4852
+ }
4461
4853
  /**
4462
4854
  * Locked library assets whose library cannot supply them: the library is not registered
4463
4855
  * (renamed or removed) or no longer holds the asset. Another library holding it makes the
@@ -4523,6 +4915,28 @@ var AssetManager = class {
4523
4915
  }
4524
4916
  return gaps;
4525
4917
  }
4918
+ /**
4919
+ * Remove the files a deploy never writes (`.env`, `.venv/`, `.pytest_cache/`, ...) from the
4920
+ * deployed folders of re-locked assets, as {@link RestoredAsset} rows. The lock covers what
4921
+ * the exclusion list leaves; the extras an older release copied are the owner's to drop, and
4922
+ * this is the one point where they are: the lock was just rewritten.
4923
+ *
4924
+ * @param refs - Lock keys the install re-locked (hash or commit changed).
4925
+ */
4926
+ removeExcludedLeftovers(refs) {
4927
+ const out = [];
4928
+ for (const key of refs) {
4929
+ const { kind, name } = parseCanonicalLockKey(key);
4930
+ const component = kind ? this.installTarget(kind) : void 0;
4931
+ if (!kind || !name || !component || component === "agent") continue;
4932
+ const dest = deployedDir(component, name, this.driverTarget, this.global, this.projectDir);
4933
+ const removed = removeExcludedLeftovers(dest);
4934
+ if (removed.length === 0) continue;
4935
+ const dir = relative(this.projectDir, dest).split(sep).join("/");
4936
+ out.push({ ref: key, restored: [], removed: removed.map((f) => `${dir}/${f}`) });
4937
+ }
4938
+ return out;
4939
+ }
4526
4940
  /**
4527
4941
  * The {@link RestoredAsset} rows for the drifted copies (see {@link lockedCopyDrift}) a
4528
4942
  * deploy just wrote again: those whose ref is among the `deployed` canonical refs.
@@ -4601,25 +5015,14 @@ var AssetManager = class {
4601
5015
  } catch {
4602
5016
  continue;
4603
5017
  }
4604
- const dirs = entry.files.map(
4605
- (f) => posix.dirname(f.path).split("/").filter((s) => s !== ".")
4606
- );
4607
- let common = dirs[0] ?? [];
4608
- for (const d of dirs.slice(1)) {
4609
- let i = 0;
4610
- while (i < common.length && i < d.length && common[i] === d[i]) i++;
4611
- common = common.slice(0, i);
4612
- }
4613
- const prefix = common.length > 0 ? `${common.join("/")}/` : "";
4614
5018
  const modified = [];
4615
- for (const f of entry.files) {
4616
- const rel = f.path.startsWith(prefix) ? f.path.slice(prefix.length) : f.path;
4617
- const deployedFile = join(dest, rel);
5019
+ for (const f of lockedAssetFiles(kind, entry.files)) {
5020
+ const deployedFile = join(dest, f.rel);
4618
5021
  if (!existsSync(deployedFile)) continue;
4619
5022
  try {
4620
- if (computeHash(deployedFile) !== f.sha256) modified.push(rel);
5023
+ if (computeHash(deployedFile) !== f.sha256) modified.push(f.rel);
4621
5024
  } catch {
4622
- modified.push(rel);
5025
+ modified.push(f.rel);
4623
5026
  }
4624
5027
  }
4625
5028
  if (modified.length > 0)
@@ -4768,7 +5171,8 @@ var AssetManager = class {
4768
5171
  const { repositories } = this.loadConfig();
4769
5172
  const provenanceIndex = await buildProvenanceIndex(this.buildClones(repositories), {
4770
5173
  projectDir: this.projectDir,
4771
- knownKinds: this.knownKinds
5174
+ knownKinds: this.knownKinds,
5175
+ onSourceError: this.reportSourceError
4772
5176
  });
4773
5177
  const lockKeys = Object.keys(lock.assets).map(parseCanonicalLockKey);
4774
5178
  const sourceCandidate = (ref) => {
@@ -5076,5 +5480,5 @@ var AssetManager = class {
5076
5480
  };
5077
5481
 
5078
5482
  export { AssetManager, FACTORY_SOURCE_URL, MissingManifestError, installAgentInstances, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, softDepName };
5079
- //# sourceMappingURL=chunk-DZMNFCWB.js.map
5080
- //# sourceMappingURL=chunk-DZMNFCWB.js.map
5483
+ //# sourceMappingURL=chunk-TVAR4JHA.js.map
5484
+ //# sourceMappingURL=chunk-TVAR4JHA.js.map