@skaile/workspaces 5.14.0 → 5.15.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 (322) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +1 -1
  3. package/dist/{asset-feeds-PAOX3FUT.js → asset-feeds-LIDC7547.js} +19 -19
  4. package/dist/{asset-feeds-PAOX3FUT.js.map → asset-feeds-LIDC7547.js.map} +1 -1
  5. package/dist/asset-manager/catalog-deployer.js +7 -7
  6. package/dist/asset-manager/index.js +14 -14
  7. package/dist/asset-manager/installer.js +9 -9
  8. package/dist/asset-manager/renderers.js +8 -8
  9. package/dist/asset-manager/src/index.d.ts +128 -6
  10. package/dist/asset-manager/src/index.d.ts.map +1 -1
  11. package/dist/asset-manager/src/install-instances.d.ts +19 -0
  12. package/dist/asset-manager/src/install-instances.d.ts.map +1 -1
  13. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  14. package/dist/asset-manager/src/mcp-config.d.ts +5 -0
  15. package/dist/asset-manager/src/mcp-config.d.ts.map +1 -1
  16. package/dist/bridge/drivers/claude-sdk.js +23 -23
  17. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  18. package/dist/bridge/drivers/codex.js +80 -16
  19. package/dist/bridge/drivers/codex.js.map +1 -1
  20. package/dist/bridge/drivers/continue.js +10 -10
  21. package/dist/bridge/drivers/echo.js +2 -2
  22. package/dist/bridge/drivers/gemini.js +7 -7
  23. package/dist/bridge/drivers/goose.js +10 -10
  24. package/dist/bridge/drivers/omp.js +111 -39
  25. package/dist/bridge/drivers/omp.js.map +1 -1
  26. package/dist/bridge/drivers/opencode.js +10 -10
  27. package/dist/bridge/drivers/qwen.js +7 -7
  28. package/dist/bridge/index.js +12 -12
  29. package/dist/bridge/src/codex/friendly-error.d.ts +19 -0
  30. package/dist/bridge/src/codex/friendly-error.d.ts.map +1 -0
  31. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  32. package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
  33. package/dist/bridge/src/drivers/omp-models-yml.d.ts +17 -7
  34. package/dist/bridge/src/drivers/omp-models-yml.d.ts.map +1 -1
  35. package/dist/bridge/src/drivers/omp.d.ts +7 -0
  36. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  37. package/dist/{chunk-ZDTZGEJG.js → chunk-2LTF2ZHH.js} +4 -4
  38. package/dist/{chunk-ZDTZGEJG.js.map → chunk-2LTF2ZHH.js.map} +1 -1
  39. package/dist/{chunk-DWRYUWOK.js → chunk-4AKR4XPQ.js} +3 -3
  40. package/dist/{chunk-DWRYUWOK.js.map → chunk-4AKR4XPQ.js.map} +1 -1
  41. package/dist/{chunk-OX2W5YF3.js → chunk-4QINFQ27.js} +159 -20
  42. package/dist/chunk-4QINFQ27.js.map +1 -0
  43. package/dist/{chunk-V7AWO5FL.js → chunk-54TVXZP3.js} +3 -3
  44. package/dist/{chunk-V7AWO5FL.js.map → chunk-54TVXZP3.js.map} +1 -1
  45. package/dist/{chunk-DHUJRIQQ.js → chunk-74THIMZV.js} +3 -3
  46. package/dist/{chunk-DHUJRIQQ.js.map → chunk-74THIMZV.js.map} +1 -1
  47. package/dist/{chunk-IY5E7Y5W.js → chunk-ANSZULXH.js} +32 -9
  48. package/dist/chunk-ANSZULXH.js.map +1 -0
  49. package/dist/{chunk-PGVSOHWE.js → chunk-AVUJBSFA.js} +2 -2
  50. package/dist/{chunk-PGVSOHWE.js.map → chunk-AVUJBSFA.js.map} +1 -1
  51. package/dist/{chunk-BASMWKPM.js → chunk-AXNX2SKZ.js} +483 -32
  52. package/dist/chunk-AXNX2SKZ.js.map +1 -0
  53. package/dist/{chunk-H5U7LNTJ.js → chunk-BFMYYNDT.js} +25 -3
  54. package/dist/chunk-BFMYYNDT.js.map +1 -0
  55. package/dist/{chunk-CNZI37HV.js → chunk-BV7NLPI6.js} +4 -4
  56. package/dist/{chunk-CNZI37HV.js.map → chunk-BV7NLPI6.js.map} +1 -1
  57. package/dist/{chunk-IPN7N2AZ.js → chunk-D2MZZ2KB.js} +3 -3
  58. package/dist/{chunk-IPN7N2AZ.js.map → chunk-D2MZZ2KB.js.map} +1 -1
  59. package/dist/{chunk-VTXXBYB3.js → chunk-DP6YRAPZ.js} +65 -21
  60. package/dist/chunk-DP6YRAPZ.js.map +1 -0
  61. package/dist/{chunk-WTEYDNTR.js → chunk-DPCEQOIZ.js} +3 -3
  62. package/dist/{chunk-WTEYDNTR.js.map → chunk-DPCEQOIZ.js.map} +1 -1
  63. package/dist/{chunk-U27JRO5L.js → chunk-ESXZJP4M.js} +3 -3
  64. package/dist/{chunk-U27JRO5L.js.map → chunk-ESXZJP4M.js.map} +1 -1
  65. package/dist/{chunk-YFIHFJEB.js → chunk-GLMKS6V6.js} +4 -4
  66. package/dist/{chunk-YFIHFJEB.js.map → chunk-GLMKS6V6.js.map} +1 -1
  67. package/dist/{chunk-6VIVUBNN.js → chunk-GQ5OYFVD.js} +2 -2
  68. package/dist/{chunk-6VIVUBNN.js.map → chunk-GQ5OYFVD.js.map} +1 -1
  69. package/dist/{chunk-O3Q3MOAV.js → chunk-I3JO3NIZ.js} +4 -4
  70. package/dist/{chunk-O3Q3MOAV.js.map → chunk-I3JO3NIZ.js.map} +1 -1
  71. package/dist/{chunk-CAPKENNF.js → chunk-J76LDUDS.js} +84 -16
  72. package/dist/chunk-J76LDUDS.js.map +1 -0
  73. package/dist/{chunk-3NNL334S.js → chunk-JHP6MIW2.js} +56 -19
  74. package/dist/chunk-JHP6MIW2.js.map +1 -0
  75. package/dist/{chunk-PXDWTJ3P.js → chunk-KRRHADE7.js} +5 -5
  76. package/dist/{chunk-PXDWTJ3P.js.map → chunk-KRRHADE7.js.map} +1 -1
  77. package/dist/{chunk-MCLT3BJG.js → chunk-KUB4HFGK.js} +11 -6
  78. package/dist/chunk-KUB4HFGK.js.map +1 -0
  79. package/dist/{chunk-ZU24LWBI.js → chunk-LEOXPIC6.js} +3 -3
  80. package/dist/{chunk-ZU24LWBI.js.map → chunk-LEOXPIC6.js.map} +1 -1
  81. package/dist/{chunk-57SF6W6E.js → chunk-MGM5EJQQ.js} +3 -3
  82. package/dist/chunk-MGM5EJQQ.js.map +1 -0
  83. package/dist/{chunk-UK3LRPJ5.js → chunk-MKTJZLQM.js} +6 -11
  84. package/dist/chunk-MKTJZLQM.js.map +1 -0
  85. package/dist/{chunk-QELQDY5K.js → chunk-N36S36OZ.js} +3 -3
  86. package/dist/{chunk-QELQDY5K.js.map → chunk-N36S36OZ.js.map} +1 -1
  87. package/dist/{chunk-NVO6WECE.js → chunk-NKDSU4Q7.js} +6 -6
  88. package/dist/{chunk-NVO6WECE.js.map → chunk-NKDSU4Q7.js.map} +1 -1
  89. package/dist/{chunk-OQ5MKDS3.js → chunk-NOF73BUH.js} +27 -6
  90. package/dist/chunk-NOF73BUH.js.map +1 -0
  91. package/dist/{chunk-IQVZIVSA.js → chunk-O673TBWJ.js} +3 -3
  92. package/dist/{chunk-IQVZIVSA.js.map → chunk-O673TBWJ.js.map} +1 -1
  93. package/dist/{chunk-ODQGLELI.js → chunk-OOQ5Q75W.js} +111 -20
  94. package/dist/chunk-OOQ5Q75W.js.map +1 -0
  95. package/dist/{chunk-GJGEDWRT.js → chunk-PIDMOE7R.js} +4 -4
  96. package/dist/{chunk-GJGEDWRT.js.map → chunk-PIDMOE7R.js.map} +1 -1
  97. package/dist/{chunk-6JKIOPT3.js → chunk-PK5XQBOC.js} +4 -4
  98. package/dist/{chunk-6JKIOPT3.js.map → chunk-PK5XQBOC.js.map} +1 -1
  99. package/dist/{chunk-5NVDOEWX.js → chunk-PQF5QHVS.js} +4 -4
  100. package/dist/{chunk-5NVDOEWX.js.map → chunk-PQF5QHVS.js.map} +1 -1
  101. package/dist/{chunk-ZBD6EITA.js → chunk-PV47EEHD.js} +4 -4
  102. package/dist/{chunk-ZBD6EITA.js.map → chunk-PV47EEHD.js.map} +1 -1
  103. package/dist/{chunk-PUG7IWFF.js → chunk-QR7W5JV4.js} +66 -16
  104. package/dist/chunk-QR7W5JV4.js.map +1 -0
  105. package/dist/{chunk-OKQXY6FS.js → chunk-RTYDYSUV.js} +4 -4
  106. package/dist/{chunk-OKQXY6FS.js.map → chunk-RTYDYSUV.js.map} +1 -1
  107. package/dist/{chunk-S6FZUR5H.js → chunk-SAKVAG23.js} +7 -7
  108. package/dist/{chunk-S6FZUR5H.js.map → chunk-SAKVAG23.js.map} +1 -1
  109. package/dist/{chunk-7LGNJJ76.js → chunk-SCUEPCSJ.js} +12 -9
  110. package/dist/chunk-SCUEPCSJ.js.map +1 -0
  111. package/dist/{chunk-M3P4BYRK.js → chunk-SP5NGNBV.js} +6 -3
  112. package/dist/chunk-SP5NGNBV.js.map +1 -0
  113. package/dist/{chunk-PAUM35HD.js → chunk-SRKU7QUG.js} +80 -34
  114. package/dist/chunk-SRKU7QUG.js.map +1 -0
  115. package/dist/{chunk-2BIESC6S.js → chunk-SZPE55SB.js} +3 -3
  116. package/dist/{chunk-2BIESC6S.js.map → chunk-SZPE55SB.js.map} +1 -1
  117. package/dist/{chunk-YTZFSKWL.js → chunk-TCWECSEB.js} +3 -3
  118. package/dist/{chunk-YTZFSKWL.js.map → chunk-TCWECSEB.js.map} +1 -1
  119. package/dist/{chunk-J4OYIYFQ.js → chunk-VY6NTFE7.js} +2 -2
  120. package/dist/{chunk-J4OYIYFQ.js.map → chunk-VY6NTFE7.js.map} +1 -1
  121. package/dist/{chunk-FD2IPIE2.js → chunk-WWUWMOX2.js} +15 -11
  122. package/dist/chunk-WWUWMOX2.js.map +1 -0
  123. package/dist/{chunk-USHB5KEY.js → chunk-WXKNM2JJ.js} +3 -3
  124. package/dist/{chunk-USHB5KEY.js.map → chunk-WXKNM2JJ.js.map} +1 -1
  125. package/dist/{chunk-TYUJPQNX.js → chunk-X7DIT65W.js} +4 -4
  126. package/dist/{chunk-TYUJPQNX.js.map → chunk-X7DIT65W.js.map} +1 -1
  127. package/dist/{chunk-QAYL3PYY.js → chunk-XX4C72CC.js} +544 -68
  128. package/dist/chunk-XX4C72CC.js.map +1 -0
  129. package/dist/{chunk-UQ4SQOR6.js → chunk-YL23KWBX.js} +5 -5
  130. package/dist/{chunk-UQ4SQOR6.js.map → chunk-YL23KWBX.js.map} +1 -1
  131. package/dist/{chunk-5IMGZAKH.js → chunk-YUURCZWY.js} +5 -5
  132. package/dist/{chunk-5IMGZAKH.js.map → chunk-YUURCZWY.js.map} +1 -1
  133. package/dist/cli/index.js +4303 -4076
  134. package/dist/cli/index.js.map +1 -1
  135. package/dist/cli/src/agent-checks.d.ts +21 -0
  136. package/dist/cli/src/agent-checks.d.ts.map +1 -1
  137. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  138. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  139. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  140. package/dist/cli/src/commands/library-index.d.ts +25 -5
  141. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  142. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  143. package/dist/cli/src/commands/outdated.d.ts.map +1 -1
  144. package/dist/cli/src/commands/plugin-registry-cmd.d.ts.map +1 -1
  145. package/dist/cli/src/commands/preset-cmd.d.ts.map +1 -1
  146. package/dist/cli/src/commands/project.d.ts +16 -1
  147. package/dist/cli/src/commands/project.d.ts.map +1 -1
  148. package/dist/cli/src/commands/rebuild.d.ts.map +1 -1
  149. package/dist/cli/src/commands/run.d.ts.map +1 -1
  150. package/dist/cli/src/commands/serve-preflight.d.ts +5 -6
  151. package/dist/cli/src/commands/serve-preflight.d.ts.map +1 -1
  152. package/dist/cli/src/commands/serve.d.ts +12 -0
  153. package/dist/cli/src/commands/serve.d.ts.map +1 -1
  154. package/dist/cli/src/commands/session.d.ts.map +1 -1
  155. package/dist/cli/src/commands/source.d.ts +7 -0
  156. package/dist/cli/src/commands/source.d.ts.map +1 -1
  157. package/dist/cli/src/commands/update.d.ts.map +1 -1
  158. package/dist/cli/src/commands/validate.d.ts +0 -9
  159. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  160. package/dist/cli/src/skill-checks.d.ts +8 -1
  161. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  162. package/dist/connectors/config.js +5 -5
  163. package/dist/connectors/index.js +15 -15
  164. package/dist/connectors/src/config.d.ts.map +1 -1
  165. package/dist/connectors/src/connector-manager.d.ts +8 -1
  166. package/dist/connectors/src/connector-manager.d.ts.map +1 -1
  167. package/dist/connectors/src/connector-prompt.d.ts +9 -0
  168. package/dist/connectors/src/connector-prompt.d.ts.map +1 -1
  169. package/dist/{connectors-2TEGRRYC.js → connectors-JQR5RAMC.js} +18 -18
  170. package/dist/{connectors-2TEGRRYC.js.map → connectors-JQR5RAMC.js.map} +1 -1
  171. package/dist/core/index.js +6 -6
  172. package/dist/core/manifest.js +2 -2
  173. package/dist/core/models.js +1 -1
  174. package/dist/core/publish-manifest.js +3 -3
  175. package/dist/core/ref.js +1 -1
  176. package/dist/core/runtime-assets.js +5 -5
  177. package/dist/core/src/driver-sdk.d.ts +31 -0
  178. package/dist/core/src/driver-sdk.d.ts.map +1 -0
  179. package/dist/core/src/index.d.ts +3 -2
  180. package/dist/core/src/index.d.ts.map +1 -1
  181. package/dist/core/src/lock.d.ts.map +1 -1
  182. package/dist/core/src/manifest-yaml-editor.d.ts +5 -0
  183. package/dist/core/src/manifest-yaml-editor.d.ts.map +1 -1
  184. package/dist/core/src/manifest.d.ts.map +1 -1
  185. package/dist/core/src/models.d.ts +8 -0
  186. package/dist/core/src/models.d.ts.map +1 -1
  187. package/dist/core/src/publish-manifest.d.ts +28 -7
  188. package/dist/core/src/publish-manifest.d.ts.map +1 -1
  189. package/dist/core/src/repo-manager.d.ts.map +1 -1
  190. package/dist/core/src/walker.d.ts +4 -0
  191. package/dist/core/src/walker.d.ts.map +1 -1
  192. package/dist/core/src/workspace-config.d.ts +28 -0
  193. package/dist/core/src/workspace-config.d.ts.map +1 -1
  194. package/dist/core/workspace-config.js +4 -4
  195. package/dist/deploy/index.js +6 -6
  196. package/dist/discovery/index.js +5 -5
  197. package/dist/{ensure-sources-EG7YKKZL.js → ensure-sources-NAGBSMJE.js} +17 -17
  198. package/dist/{ensure-sources-EG7YKKZL.js.map → ensure-sources-NAGBSMJE.js.map} +1 -1
  199. package/dist/factory-assets/connectors/box.js +15 -15
  200. package/dist/factory-assets/connectors/deploy.js +15 -15
  201. package/dist/factory-assets/connectors/devserver.js +15 -15
  202. package/dist/factory-assets/connectors/flow/adapter.js +15 -15
  203. package/dist/factory-assets/connectors/flow/engine.js +7 -7
  204. package/dist/factory-assets/connectors/flow/run-flow.d.ts +5 -0
  205. package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
  206. package/dist/factory-assets/connectors/flow/run-flow.js +17 -17
  207. package/dist/factory-assets/connectors/flow.js +15 -15
  208. package/dist/factory-assets/connectors/git.js +15 -15
  209. package/dist/factory-assets/connectors/gmail.js +15 -15
  210. package/dist/factory-assets/connectors/googledrive.js +15 -15
  211. package/dist/factory-assets/connectors/local.js +15 -15
  212. package/dist/factory-assets/connectors/mattermost.js +15 -15
  213. package/dist/factory-assets/connectors/memory.js +15 -15
  214. package/dist/factory-assets/connectors/minio.js +15 -15
  215. package/dist/factory-assets/connectors/postgres.js +15 -15
  216. package/dist/factory-assets/connectors/s3.js +15 -15
  217. package/dist/factory-assets/connectors/sharepoint.js +15 -15
  218. package/dist/factory-assets/connectors/sqlite.js +15 -15
  219. package/dist/factory-assets/connectors/static-server.js +15 -15
  220. package/dist/factory-assets/connectors/tunnel.js +15 -15
  221. package/dist/factory-assets/connectors/webdav.js +15 -15
  222. package/dist/factory-assets/connectors/xstate-store.js +15 -15
  223. package/dist/factory-assets/connectors/xstate.js +15 -15
  224. package/dist/{flows-5TW3XFMH.js → flows-CYJI3URW.js} +11 -11
  225. package/dist/{flows-5TW3XFMH.js.map → flows-CYJI3URW.js.map} +1 -1
  226. package/dist/{helpers-BQGXEKRP.js → helpers-XFHJDJOA.js} +17 -17
  227. package/dist/{helpers-BQGXEKRP.js.map → helpers-XFHJDJOA.js.map} +1 -1
  228. package/dist/library/index.js +11 -11
  229. package/dist/library/install.js +5 -5
  230. package/dist/library/src/index.d.ts +1 -1
  231. package/dist/library/src/index.d.ts.map +1 -1
  232. package/dist/library/src/install/source-fetch-github.d.ts.map +1 -1
  233. package/dist/library/src/manifest-writer.d.ts +15 -0
  234. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  235. package/dist/library/src/remote/remote-catalog-source.d.ts +6 -1
  236. package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
  237. package/dist/library/src/remote/rest-catalog-source.d.ts +6 -1
  238. package/dist/library/src/remote/rest-catalog-source.d.ts.map +1 -1
  239. package/dist/{library-publish-EUP524PE.js → library-publish-FC3ZABR2.js} +91 -29
  240. package/dist/library-publish-FC3ZABR2.js.map +1 -0
  241. package/dist/model-endpoint/index.js +3 -3
  242. package/dist/open-library-5ET7SAJC.js +40 -0
  243. package/dist/{open-library-QNMIMZYS.js.map → open-library-5ET7SAJC.js.map} +1 -1
  244. package/dist/open-registry-X6YQVP7V.js +32 -0
  245. package/dist/{open-registry-BOUCBDLF.js.map → open-registry-X6YQVP7V.js.map} +1 -1
  246. package/dist/{paths-B6SX6J6T.js → paths-NXWIBZCX.js} +9 -9
  247. package/dist/{paths-B6SX6J6T.js.map → paths-NXWIBZCX.js.map} +1 -1
  248. package/dist/{plugin-store-MLFP3WJ7.js → plugin-store-BIITCNOZ.js} +8 -8
  249. package/dist/{plugin-store-MLFP3WJ7.js.map → plugin-store-BIITCNOZ.js.map} +1 -1
  250. package/dist/{project-GXCIEJGM.js → project-2UXHSVVA.js} +40 -40
  251. package/dist/{project-GXCIEJGM.js.map → project-2UXHSVVA.js.map} +1 -1
  252. package/dist/resolver/index.js +7 -7
  253. package/dist/runner/index.js +32 -32
  254. package/dist/runner/src/event-gap-buffer.d.ts.map +1 -1
  255. package/dist/runner/src/resources.d.ts.map +1 -1
  256. package/dist/runner/src/serve.d.ts +8 -0
  257. package/dist/runner/src/serve.d.ts.map +1 -1
  258. package/dist/runner/src/session.d.ts +15 -0
  259. package/dist/runner/src/session.d.ts.map +1 -1
  260. package/dist/sdk/asset-manager.js +14 -14
  261. package/dist/sdk/bridge.js +12 -12
  262. package/dist/sdk/core.js +6 -6
  263. package/dist/sdk/flow.js +7 -7
  264. package/dist/sdk/index.js +32 -32
  265. package/dist/sdk/resolver.js +7 -7
  266. package/dist/sdk/runner.js +32 -32
  267. package/dist/sdk/transport/ws/server.js +1 -1
  268. package/dist/sdk/transport/ws.js +1 -1
  269. package/dist/sdk/transport.js +1 -1
  270. package/dist/serve-preflight-GD7IQFA3.js +54 -0
  271. package/dist/serve-preflight-GD7IQFA3.js.map +1 -0
  272. package/dist/{setup-HJEYEXLS.js → setup-IKH4R7UN.js} +23 -23
  273. package/dist/{setup-HJEYEXLS.js.map → setup-IKH4R7UN.js.map} +1 -1
  274. package/dist/{skills-4WMYGJDL.js → skills-XVHOXOOH.js} +12 -12
  275. package/dist/{skills-4WMYGJDL.js.map → skills-XVHOXOOH.js.map} +1 -1
  276. package/dist/source-M6IARYNO.js +83 -0
  277. package/dist/{source-5VL6PHER.js.map → source-M6IARYNO.js.map} +1 -1
  278. package/dist/source-fetch-github-ST4MFL3D.js +4 -0
  279. package/dist/{source-fetch-github-PIO6EMMF.js.map → source-fetch-github-ST4MFL3D.js.map} +1 -1
  280. package/dist/{source-manifest-publish-Q66H7EJI.js → source-manifest-publish-UP2IS2QW.js} +65 -24
  281. package/dist/source-manifest-publish-UP2IS2QW.js.map +1 -0
  282. package/dist/transport/index.js +1 -1
  283. package/dist/transport/src/ws/server.d.ts +16 -0
  284. package/dist/transport/src/ws/server.d.ts.map +1 -1
  285. package/dist/transport/ws/server.js +1 -1
  286. package/dist/transport/ws.js +1 -1
  287. package/dist/tui/index.js +32 -32
  288. package/dist/types/manifests.js +1 -1
  289. package/dist/types/src/manifests/mcp-server.d.ts.map +1 -1
  290. package/dist/workspace-plugin/adapters/mcp.js +22 -22
  291. package/dist/workspace-plugin/adapters/omp.js +14 -14
  292. package/dist/workspace-plugin/index.js +1 -1
  293. package/dist/workspace-plugin/src/adapters/mcp.d.ts.map +1 -1
  294. package/package.json +3 -3
  295. package/dist/chunk-3NNL334S.js.map +0 -1
  296. package/dist/chunk-57SF6W6E.js.map +0 -1
  297. package/dist/chunk-7LGNJJ76.js.map +0 -1
  298. package/dist/chunk-BASMWKPM.js.map +0 -1
  299. package/dist/chunk-CAPKENNF.js.map +0 -1
  300. package/dist/chunk-FD2IPIE2.js.map +0 -1
  301. package/dist/chunk-H5U7LNTJ.js.map +0 -1
  302. package/dist/chunk-IY5E7Y5W.js.map +0 -1
  303. package/dist/chunk-M3P4BYRK.js.map +0 -1
  304. package/dist/chunk-MCLT3BJG.js.map +0 -1
  305. package/dist/chunk-ODQGLELI.js.map +0 -1
  306. package/dist/chunk-OQ5MKDS3.js.map +0 -1
  307. package/dist/chunk-OX2W5YF3.js.map +0 -1
  308. package/dist/chunk-PAUM35HD.js.map +0 -1
  309. package/dist/chunk-PUG7IWFF.js.map +0 -1
  310. package/dist/chunk-QAYL3PYY.js.map +0 -1
  311. package/dist/chunk-UK3LRPJ5.js.map +0 -1
  312. package/dist/chunk-VTG5Z3KD.js +0 -345
  313. package/dist/chunk-VTG5Z3KD.js.map +0 -1
  314. package/dist/chunk-VTXXBYB3.js.map +0 -1
  315. package/dist/library-publish-EUP524PE.js.map +0 -1
  316. package/dist/open-library-QNMIMZYS.js +0 -40
  317. package/dist/open-registry-BOUCBDLF.js +0 -32
  318. package/dist/serve-preflight-GNBW3O4U.js +0 -64
  319. package/dist/serve-preflight-GNBW3O4U.js.map +0 -1
  320. package/dist/source-5VL6PHER.js +0 -42
  321. package/dist/source-fetch-github-PIO6EMMF.js +0 -4
  322. package/dist/source-manifest-publish-Q66H7EJI.js.map +0 -1
@@ -1,23 +1,24 @@
1
- import { unregisteredLibraryNames, renamedLibraryName, resolveConfig, RemoteCatalogSource, OfflineError, describeCatalogError, CatalogHttpError, scanUnlistedAssets, getStoreManifestsDir, missingLibraryDirMessage } from './chunk-ODQGLELI.js';
2
- import { readManifestSourceConfig, discoverAssetsInTree, isManifestMode } from './chunk-NVO6WECE.js';
3
- import { installTargetOf, canonicalEntryRef, deployedAssetDrift, deployAll, removeAsset, diffDeployedAgent, createScaffold, installAgent } from './chunk-FD2IPIE2.js';
1
+ import { unregisteredLibraryNames, renamedLibraryName, resolveConfig, RemoteCatalogSource, OfflineError, describeCatalogError, CatalogHttpError, scanUnlistedAssets, getStoreManifestsDir, missingLibraryDirMessage } from './chunk-OOQ5Q75W.js';
2
+ import { SEMVER_RE, readManifestSourceConfig, discoverAssetsInTree, isManifestMode } from './chunk-NKDSU4Q7.js';
3
+ import { installTargetOf, canonicalEntryRef, deployedAssetDrift, deployAll, removeAsset, diffDeployedAgent, createScaffold, installAgent } from './chunk-WWUWMOX2.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-CNZI37HV.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-OX2W5YF3.js';
8
- import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-TYUJPQNX.js';
6
+ import { driverTargetSupportsAgents, CODEX_IDENTITY_DIR } from './chunk-BV7NLPI6.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-4QINFQ27.js';
8
+ import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-X7DIT65W.js';
9
9
  import { deployedBase, deployedDir, isDeployed, deployedPaths } from './chunk-D54T2F54.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-CAPKENNF.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-J76LDUDS.js';
11
11
  import { globalSkaileDir, globalCacheRoot, migrateLegacyDir } from './chunk-L5VSIPQD.js';
12
12
  import { DRIVER_TARGETS } from './chunk-IG5LZ3WU.js';
13
- import { loadSkPublishManifest } from './chunk-IY5E7Y5W.js';
14
- import { scanDirectory, parseFrontmatter, parseRequires, dedupeRequirements } from './chunk-M3P4BYRK.js';
15
- import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName, depToStr, parseDep } from './chunk-J4OYIYFQ.js';
13
+ import { loadSkPublishManifest } from './chunk-ANSZULXH.js';
14
+ import { scanDirectory, parseFrontmatter, parseRequires, dedupeRequirements } from './chunk-SP5NGNBV.js';
15
+ import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName, depToStr, parseDep } from './chunk-VY6NTFE7.js';
16
16
  import { spawnSync } from 'child_process';
17
- import { existsSync, rmSync, readdirSync, lstatSync, readFileSync, unlinkSync, mkdirSync, writeFileSync } from 'fs';
17
+ import { existsSync, rmSync, readdirSync, readFileSync, lstatSync, unlinkSync, mkdirSync, writeFileSync } from 'fs';
18
18
  import path, { resolve, dirname, sep, join, relative, posix } from 'path';
19
19
  import { gt } from 'semver';
20
- import { stringify, parse } from 'yaml';
20
+ import { parse, stringify } from 'yaml';
21
+ import { createHash } from 'crypto';
21
22
  import fs from 'fs/promises';
22
23
 
23
24
  var ledgerPath = (projectDir) => join(projectDir, ".skaile", "agent-instances-managed.json");
@@ -37,6 +38,31 @@ function writeLedger(projectDir, ledger) {
37
38
  writeFileSync(p, `${JSON.stringify(ledger, null, 2)}
38
39
  `, "utf-8");
39
40
  }
41
+ function renderedInstanceFiles(projectDir, driverTarget) {
42
+ const recorded = readLedger(projectDir).targets[driverTarget];
43
+ if (!recorded) return [];
44
+ let instances;
45
+ try {
46
+ instances = effectiveAgentInstances(resolveSkWorkspaceConfig(projectDir));
47
+ } catch {
48
+ return [];
49
+ }
50
+ return Object.entries(instances).filter(([id]) => recorded[id]?.length).map(([id, instance]) => ({ id, ref: instance.ref, files: recorded[id] }));
51
+ }
52
+ function instanceRenderedAgentNames(projectDir, driverTarget) {
53
+ const names = /* @__PURE__ */ new Set();
54
+ if (!driverTargetSupportsAgents(driverTarget)) return names;
55
+ const agentDir = resolve(deployedBase("agent", driverTarget, false, projectDir));
56
+ for (const files of Object.values(readLedger(projectDir).targets[driverTarget] ?? {})) {
57
+ for (const rel of files) {
58
+ const abs = resolve(projectDir, rel);
59
+ if (!abs.startsWith(agentDir + sep)) continue;
60
+ const top = abs.slice(agentDir.length + 1).split(sep)[0] ?? "";
61
+ if (top) names.add(top.replace(/\.(md|toml|yaml|json)$/, ""));
62
+ }
63
+ }
64
+ return names;
65
+ }
40
66
  function bindInstance(projectDir, id, instance) {
41
67
  const errors = [];
42
68
  let srcDir;
@@ -177,6 +203,8 @@ var UNSUPPORTED_SECRET_PREFIXES = [
177
203
  "connector:",
178
204
  "mcp:"
179
205
  ];
206
+ var TEMPLATE_PLACEHOLDER = /<[^<>\s/]+>/;
207
+ var PAYLOAD_FETCH_TIMEOUT_MS = 6e4;
180
208
  var WORKSPACE_MARKER = /\$\{workspace\}/g;
181
209
  function substituteWorkspace(value, projectDir) {
182
210
  return value.replace(WORKSPACE_MARKER, projectDir);
@@ -207,10 +235,90 @@ function skipReason(decl) {
207
235
  const transport = decl.transport ?? "stdio";
208
236
  if (transport === "stdio" && !decl.command) return "no command";
209
237
  if (transport !== "stdio" && !decl.url) return "no url";
238
+ const placeholder = decl.url ? TEMPLATE_PLACEHOLDER.exec(decl.url)?.[0] : void 0;
239
+ if (placeholder) {
240
+ return `its url still holds the placeholder ${placeholder} \u2014 set the real value with an mcp_servers entry (id: ${decl.id}, url: ...) in skaile.yaml`;
241
+ }
210
242
  const badRef = findUnsupportedSecretRef(decl);
211
243
  if (badRef) return `unsupported secret reference '${badRef}'`;
212
244
  return void 0;
213
245
  }
246
+ function payloadDir(projectDir, id) {
247
+ const name = id.split("/").pop() ?? id;
248
+ if (!isPlainName(name)) return void 0;
249
+ return path.join(projectDir, ".skaile", "assets", "mcp-server", name);
250
+ }
251
+ function isPlainName(name) {
252
+ return name !== "" && name !== "." && name !== ".." && !/[/\\\0]/.test(name) && !path.isAbsolute(name) && !path.win32.isAbsolute(name);
253
+ }
254
+ function decodeSegment(segment) {
255
+ try {
256
+ return decodeURIComponent(segment);
257
+ } catch {
258
+ return void 0;
259
+ }
260
+ }
261
+ async function defaultFetchPayload(url) {
262
+ const res = await fetch(url, {
263
+ redirect: "follow",
264
+ signal: AbortSignal.timeout(PAYLOAD_FETCH_TIMEOUT_MS)
265
+ });
266
+ if (!res.ok) throw new Error(`${url} answered ${res.status}`);
267
+ return new Uint8Array(await res.arrayBuffer());
268
+ }
269
+ async function ensurePayload(projectDir, decl, fetchPayload) {
270
+ const payload = decl.payload;
271
+ if (!payload) return void 0;
272
+ let dest = payload.dest;
273
+ if (dest === void 0) {
274
+ try {
275
+ dest = decodeSegment(new URL(payload.url).pathname.split("/").pop() ?? "");
276
+ } catch {
277
+ dest = void 0;
278
+ }
279
+ }
280
+ if (dest === void 0 || !isPlainName(dest)) {
281
+ return `payload ${payload.url} has no usable file name (${JSON.stringify(dest ?? "")}): a plain file name is required`;
282
+ }
283
+ const dir = payloadDir(projectDir, decl.id);
284
+ if (!dir) return `payload of '${decl.id}' has no usable directory name`;
285
+ const file = path.join(dir, dest);
286
+ const sha = (bytes2) => createHash("sha256").update(bytes2).digest("hex");
287
+ try {
288
+ if (sha(await fs.readFile(file)) === payload.sha256) return void 0;
289
+ } catch {
290
+ }
291
+ let bytes;
292
+ try {
293
+ bytes = await fetchPayload(payload.url);
294
+ } catch (err) {
295
+ const why = err.cause?.code ?? (err instanceof Error ? err.message : String(err));
296
+ return `payload ${payload.url} could not be fetched (${why})`;
297
+ }
298
+ const actual = sha(bytes);
299
+ if (actual !== payload.sha256) {
300
+ return `payload ${payload.url} has sha256 ${actual}, not the pinned ${payload.sha256}; it was not written`;
301
+ }
302
+ try {
303
+ await fs.mkdir(dir, { recursive: true });
304
+ const tmp = `${file}.${process.pid}.tmp`;
305
+ await fs.writeFile(tmp, bytes);
306
+ await fs.rename(tmp, file);
307
+ } catch (err) {
308
+ return `payload ${dest} could not be written: ${err instanceof Error ? err.message : String(err)}`;
309
+ }
310
+ return void 0;
311
+ }
312
+ async function removePayloadDir(projectDir, id) {
313
+ const dir = payloadDir(projectDir, id);
314
+ if (!dir) return;
315
+ try {
316
+ await fs.access(path.join(dir, "MCP.md"));
317
+ return;
318
+ } catch {
319
+ }
320
+ await fs.rm(dir, { recursive: true, force: true });
321
+ }
214
322
  function buildEntry(decl, projectDir) {
215
323
  const transport = decl.transport ?? "stdio";
216
324
  if (transport !== "stdio") {
@@ -294,7 +402,7 @@ async function renderMcpServerConfig(projectDir, driverTarget, opts) {
294
402
  const skipped = [];
295
403
  const renderable = /* @__PURE__ */ new Map();
296
404
  for (const decl of declarations) {
297
- const reason = skipReason(decl);
405
+ const reason = skipReason(decl) ?? await ensurePayload(projectDir, decl, opts?.fetchPayload ?? defaultFetchPayload);
298
406
  if (reason) {
299
407
  skipped.push({ id: decl.id, reason });
300
408
  warn(`MCP server "${decl.id}" not written to ${relConfig}: ${reason}`);
@@ -316,6 +424,7 @@ async function renderMcpServerConfig(projectDir, driverTarget, opts) {
316
424
  warn,
317
425
  relConfig
318
426
  );
427
+ for (const id of removed) await removePayloadDir(projectDir, id);
319
428
  const ledgerStale = JSON.stringify(owned) !== JSON.stringify(managedIds);
320
429
  if (ledgerStale) await writeManagedIds(projectDir, driverTarget, owned);
321
430
  if (Object.keys(next).length === 0 && !existingFile) {
@@ -658,7 +767,7 @@ function parseRefTolerant(ref) {
658
767
  }
659
768
  }
660
769
  function keptLockEntries(prev, missing) {
661
- const out = { assets: {}, sources: [], refs: /* @__PURE__ */ new Set() };
770
+ const out = { assets: {}, sources: [], refs: /* @__PURE__ */ new Set(), keysByRef: /* @__PURE__ */ new Map() };
662
771
  if (!prev) return out;
663
772
  for (const ref of missing) {
664
773
  const want = parseRefTolerant(ref.split(" ")[0] ?? ref);
@@ -670,6 +779,7 @@ function keptLockEntries(prev, missing) {
670
779
  if (want.publisher && id.publisher !== want.publisher) continue;
671
780
  out.assets[key] = entry;
672
781
  out.refs.add(ref);
782
+ out.keysByRef.set(ref, [...out.keysByRef.get(ref) ?? [], key]);
673
783
  const src = entry.source ? prev.sources.find((s) => s.url === entry.source?.url) : void 0;
674
784
  if (src) out.sources.push(src);
675
785
  }
@@ -836,6 +946,8 @@ var AssetManager = class {
836
946
  warnedStoreVersionLookups = /* @__PURE__ */ new Set();
837
947
  /** Stores a lookup could not reach (store URL -> one line why); `add` reports them instead of "not found". */
838
948
  storeFailures = /* @__PURE__ */ new Map();
949
+ /** Store URLs a lookup failed on because the client is air-gapped (`cache_ttl: 0`), not because the store is down. */
950
+ airGappedStores = /* @__PURE__ */ new Set();
839
951
  /** Sources a provenance walk had to skip (source URL → why); one warning per source. */
840
952
  skippedSources = /* @__PURE__ */ new Map();
841
953
  /** `onSourceError` of every provenance walk: name the source once, leave it out, go on. */
@@ -1222,6 +1334,11 @@ var AssetManager = class {
1222
1334
  } : void 0;
1223
1335
  candidates.sort(libraryPreference(isDefaultLib, prefer));
1224
1336
  const hit = candidates[0];
1337
+ if (hit.entry.version && !SEMVER_RE.test(hit.entry.version)) {
1338
+ throw new Error(
1339
+ `${canonicalEntryRef(hit.entry)} (library ${hit.library}): version "${hit.entry.version}" is not valid semver. Set a valid version in the asset file and run \`skaile library index ${hit.library}\`.`
1340
+ );
1341
+ }
1225
1342
  if (!opts.quiet && !opts.library) {
1226
1343
  this.warnLibraryCollision(
1227
1344
  `${hit.entry.kind}:@${hit.entry.publisher}/${hit.entry.name}`,
@@ -1538,14 +1655,35 @@ var AssetManager = class {
1538
1655
  } else if (lookup.state === "unregistered") {
1539
1656
  out.set(ref, unregisteredLibraryFix(origin, plain));
1540
1657
  } else {
1658
+ const renamedTo = await this.renamedFlowRef(lookup, want.publisher, want.kind, want.name);
1541
1659
  out.set(
1542
1660
  ref,
1543
- `library "${lookup.name}" no longer holds it \u2014 restore it there, or drop the dependency with \`skaile remove ${plain}\``
1661
+ renamedTo ? `library "${lookup.name}" holds it as ${renamedTo} now (a flow is named by its \`id:\`) \u2014 run \`skaile remove ${plain}\`, then \`skaile add ${renamedTo}\`` : `library "${lookup.name}" no longer holds it \u2014 restore it there, or drop the dependency with \`skaile remove ${plain}\``
1544
1662
  );
1545
1663
  }
1546
1664
  }
1547
1665
  return out;
1548
1666
  }
1667
+ /**
1668
+ * The ref a library now holds a flow under when a project still locks it by the slug of the
1669
+ * flow's `name:` (5.12.0 named a flow by `name:`; later releases name it by `id:`), or
1670
+ * `undefined` when `kind` is no flow, the library is not at hand or no flow of it matches.
1671
+ */
1672
+ async renamedFlowRef(lookup, publisher, kind, name) {
1673
+ if (kind !== "flow" || !publisher || lookup.state !== "ok") return void 0;
1674
+ const scanned = await scanDirectory(lookup.path, publisher, { knownKinds: this.knownKinds });
1675
+ for (const entry of scanned) {
1676
+ if (entry.kind !== "flow" || entry.name === name) continue;
1677
+ try {
1678
+ const meta = parse(readFileSync(entry.source, "utf8"));
1679
+ if (meta && typeof meta === "object" && "name" in meta && typeof meta.name === "string" && slugifyAssetName(meta.name) === name) {
1680
+ return `flow:@${publisher}/${entry.name}`;
1681
+ }
1682
+ } catch {
1683
+ }
1684
+ }
1685
+ return void 0;
1686
+ }
1549
1687
  /** Collision messages already printed by this instance (one warning per ref + library set). */
1550
1688
  warnedLibraryCollisions = /* @__PURE__ */ new Set();
1551
1689
  /**
@@ -1894,7 +2032,10 @@ var AssetManager = class {
1894
2032
  (x) => x.kind === kind && x.name === name
1895
2033
  );
1896
2034
  if (!found) {
1897
- missing.push(`${ref} (not found in library "${lookup.name}")`);
2035
+ const renamedTo = await this.renamedFlowRef(lookup, publisher, kind, name);
2036
+ missing.push(
2037
+ renamedTo ? `${ref} (library "${lookup.name}" holds it as ${renamedTo} now (a flow is named by its \`id:\`) \u2014 run \`skaile remove ${kind}:@${publisher}/${name}\`, then \`skaile add ${renamedTo}\`)` : `${ref} (not found in library "${lookup.name}")`
2038
+ );
1898
2039
  continue;
1899
2040
  }
1900
2041
  const def = newestLibraryDef(snap, lookup.name, { kind, publisher, name });
@@ -2243,14 +2384,18 @@ var AssetManager = class {
2243
2384
  }
2244
2385
  }
2245
2386
  }
2246
- /** The catalog fetcher to use: an injected one, else built from `stores`. */
2387
+ /**
2388
+ * The catalog fetcher to use: an injected one, else built from `stores`. `catalogUrl: ""`
2389
+ * (`update --no-catalog`) asks no store at all, project `stores:` included.
2390
+ */
2247
2391
  storeFetcherFor(stores) {
2248
- return this.injectedStoreFetcher ?? this.buildStoreFetcher(stores);
2392
+ if (this.injectedStoreFetcher) return this.injectedStoreFetcher;
2393
+ return this.catalogUrlOverride === "" ? void 0 : this.buildStoreFetcher(stores);
2249
2394
  }
2250
2395
  /**
2251
2396
  * The global `catalog.url` as a single-store fallback, or `[]` when no
2252
2397
  * project store should be synthesized — `local` sentinel, already-declared,
2253
- * or no URL. Honours an explicit `catalogUrl` injection (`""` disables it).
2398
+ * or no URL. Honours an explicit `catalogUrl` injection (`""` and `"local"` disable it).
2254
2399
  */
2255
2400
  async globalStoreFallback(projectStores) {
2256
2401
  let url = this.catalogUrlOverride;
@@ -2466,6 +2611,18 @@ var AssetManager = class {
2466
2611
  ...opts?.moveLibraries ? { preferLocked: await this.lockedPreference() } : { lockedLibraries: await this.lockedLibraryNames() }
2467
2612
  });
2468
2613
  this.assertNoFolderCollision([...resolved, ...lib.entries.map((e) => this.entryIdentity(e))]);
2614
+ if (!opts?.force && !(existsSync(this.lockPath) && this.tryReadLock() === null)) {
2615
+ this.assertNoUnownedFolder(
2616
+ [
2617
+ ...resolved.map((c) => ({
2618
+ id: c,
2619
+ entry: this.candidateToCatalogEntry(c, repositories)
2620
+ })),
2621
+ ...lib.entries.map((e) => ({ id: this.entryIdentity(e), entry: e }))
2622
+ ],
2623
+ Object.keys(this.tryReadLock()?.assets ?? {}).map(parseCanonicalLockKey)
2624
+ );
2625
+ }
2469
2626
  this.assertSourceCommitsPublished(resolved, repositories);
2470
2627
  const stillMissing = missing.filter((m) => !lib.resolved.has(m));
2471
2628
  const lockedKeys = new Set(Object.keys(this.tryReadLock()?.assets ?? {}));
@@ -2494,6 +2651,10 @@ var AssetManager = class {
2494
2651
  const missingHints = await this.publisherChangeHints(stillMissing);
2495
2652
  const prevLock = this.tryReadLock();
2496
2653
  const kept = keptLockEntries(prevLock, stillMissing);
2654
+ const storeNotChecked = this.storeNotCheckedRefs(
2655
+ kept,
2656
+ sources.map((s) => s.url)
2657
+ );
2497
2658
  const fixes = await this.unresolvedFixes(stillMissing);
2498
2659
  for (const ref of /* @__PURE__ */ new Set([...kept.refs, ...fixes.keys()])) {
2499
2660
  const fix = fixes.get(ref);
@@ -2516,6 +2677,8 @@ var AssetManager = class {
2516
2677
  );
2517
2678
  const entries = [...await this.buildCatalogEntries(resolved, repositories), ...lib.entries];
2518
2679
  const copyDrift = await this.lockedCopyDrift();
2680
+ const missingCopies = await this.incompleteDeploys();
2681
+ const unrecordedAgents = this.unrecordedAgentFiles(prevLock);
2519
2682
  const deployed = [
2520
2683
  ...new Set(
2521
2684
  this.targetHarnesses().flatMap(
@@ -2523,9 +2686,10 @@ var AssetManager = class {
2523
2686
  )
2524
2687
  )
2525
2688
  ];
2526
- const restored = this.restoredCopies(copyDrift, deployed);
2527
2689
  await this.renderDriverMcpConfig();
2528
2690
  const agentRender = await this.renderAgentInstances();
2691
+ const restored = this.restoredCopies(copyDrift, deployed, missingCopies);
2692
+ const rewritten = this.rewrittenAgentFiles(unrecordedAgents);
2529
2693
  const lockWanted = resolved.length > 0 || lib.entries.length > 0 || existsSync(this.lockPath);
2530
2694
  let lockWritten = false;
2531
2695
  let relocked = [];
@@ -2538,16 +2702,20 @@ var AssetManager = class {
2538
2702
  }
2539
2703
  this.recordInstallHistory(deployed, removed);
2540
2704
  const { npmInstalled, npmFailed } = await this.installRuntimeAssetDeps();
2541
- await this.adviseMissing(stillMissing, missingHints);
2705
+ const reportedMissing = stillMissing.filter((m) => !storeNotChecked.some((n) => n.ref === m));
2706
+ for (const n of storeNotChecked) delete missingHints[n.ref];
2707
+ await this.adviseMissing(reportedMissing, missingHints);
2542
2708
  return {
2543
2709
  deployed,
2544
2710
  removed,
2545
- missing: stillMissing,
2711
+ missing: reportedMissing,
2712
+ ...storeNotChecked.length > 0 ? { storeNotChecked } : {},
2546
2713
  ...Object.keys(missingHints).length > 0 ? { missingHints } : {},
2547
2714
  ...relocked.length > 0 ? { relocked } : {},
2548
2715
  ...moved.length > 0 ? { moved } : {},
2549
2716
  ...replaced.length > 0 ? { replaced } : {},
2550
2717
  ...restored.length > 0 ? { restored } : {},
2718
+ ...rewritten.length > 0 ? { rewritten } : {},
2551
2719
  lockWritten,
2552
2720
  npmInstalled,
2553
2721
  npmFailed,
@@ -2555,6 +2723,41 @@ var AssetManager = class {
2555
2723
  ...agentRender
2556
2724
  };
2557
2725
  }
2726
+ /**
2727
+ * The kept refs whose locked copy came from a store that `install` did not (or could not)
2728
+ * ask, and whose deployed copy is still there: nothing says the copy is wrong, so it stays
2729
+ * and the run does not fail on it. A ref whose store answered "no such asset", one with no
2730
+ * deployed copy, and one a source or library used to supply stay missing.
2731
+ *
2732
+ * @param declaredSourceUrls - The `sources:` URLs of `skaile.yaml`; a lock entry from one of
2733
+ * them is that source's, not the store's.
2734
+ */
2735
+ storeNotCheckedRefs(kept, declaredSourceUrls) {
2736
+ const skipped = this.catalogUrlOverride === "";
2737
+ if (!skipped && this.storeFailures.size === 0) return [];
2738
+ const declared = new Set(declaredSourceUrls.map(normalizeRepoUrl));
2739
+ const out = [];
2740
+ for (const ref of kept.refs) {
2741
+ const keys = kept.keysByRef.get(ref) ?? [];
2742
+ const fromStore = keys.some((key) => {
2743
+ const entry = kept.assets[key];
2744
+ return entry !== void 0 && !entry.library && entry.source !== void 0 && !declared.has(normalizeRepoUrl(entry.source.url));
2745
+ });
2746
+ if (!fromStore || !this.keptCopyDeployed(kept, ref)) continue;
2747
+ if (skipped && this.storeFailures.size === 0) {
2748
+ out.push({ ref, reason: "skipped", detail: "--no-catalog: the store was not asked" });
2749
+ continue;
2750
+ }
2751
+ const urls = [...this.storeFailures.keys()];
2752
+ const airGapped = urls.every((url) => this.airGappedStores.has(url));
2753
+ out.push({
2754
+ ref,
2755
+ reason: airGapped ? "air-gapped" : "unreachable",
2756
+ detail: [...this.storeFailures.values()].join("; ")
2757
+ });
2758
+ }
2759
+ return out;
2760
+ }
2558
2761
  /**
2559
2762
  * Extend `kept` (see {@link keptLockEntries}) with every previous lock entry a kept asset
2560
2763
  * requires, transitively, that the new lock (`freshKeys`) does not already carry. The lock
@@ -2593,17 +2796,35 @@ var AssetManager = class {
2593
2796
  const { kind, name, publisher } = id;
2594
2797
  const component = kind ? this.installTarget(kind) : void 0;
2595
2798
  if (!kind || !name || !component) return [];
2799
+ const locked = this.lockedRequirementsOf(id);
2800
+ const withLocked = (scanned) => [.../* @__PURE__ */ new Set([...scanned, ...locked])];
2596
2801
  const keptAgent = kind === "agent" && !this.global ? join(agentSourceCacheDir(this.projectDir), name) : null;
2597
2802
  const dir = keptAgent && existsSync(keptAgent) ? keptAgent : deployedDir(component, name, this.driverTarget, this.global, this.projectDir);
2598
- if (!existsSync(dir)) return [];
2803
+ if (!existsSync(dir)) return withLocked([]);
2599
2804
  try {
2600
2805
  const scanned = await scanDirectory(dir, publisher ?? "", { knownKinds: this.knownKinds });
2601
2806
  const own = scanned.find((e) => e.kind === kind && e.name === name);
2602
- return own ? libraryEntryDepRefs(own) : [];
2807
+ return withLocked(own ? libraryEntryDepRefs(own) : []);
2603
2808
  } catch {
2604
- return [];
2809
+ return withLocked([]);
2605
2810
  }
2606
2811
  }
2812
+ /**
2813
+ * The `requires:` the lock recorded for the store-resolved asset `id` (see
2814
+ * {@link LockEntry.requires}): what its deployed copy cannot say, a store agent's skills.
2815
+ * Empty for an asset the lock does not hold or records none for.
2816
+ */
2817
+ lockedRequirementsOf(id) {
2818
+ const out = [];
2819
+ for (const [key, entry] of Object.entries(this.tryReadLock()?.assets ?? {})) {
2820
+ if (!entry.requires?.length) continue;
2821
+ const k = parseCanonicalLockKey(key);
2822
+ if (k.kind !== id.kind || k.name !== id.name) continue;
2823
+ if (id.publisher && k.publisher && k.publisher !== id.publisher) continue;
2824
+ out.push(...entry.requires);
2825
+ }
2826
+ return out;
2827
+ }
2607
2828
  /**
2608
2829
  * Ensure all source clones are present/up to date. Returns an early
2609
2830
  * {@link InstallResult} describing the failed source on the first error, or
@@ -2749,6 +2970,8 @@ var AssetManager = class {
2749
2970
  noteStoreFailure(storeUrl, err) {
2750
2971
  const text = err instanceof OfflineError ? `${storeUrl}: air-gapped (catalog.cache_ttl: 0), the store was not asked` : describeCatalogError(err, storeUrl);
2751
2972
  this.storeFailures.set(storeUrl, text);
2973
+ if (err instanceof OfflineError) this.airGappedStores.add(storeUrl);
2974
+ else this.airGappedStores.delete(storeUrl);
2752
2975
  return text;
2753
2976
  }
2754
2977
  /** Build a store fetcher from the configured stores, or undefined when none. */
@@ -2943,6 +3166,8 @@ var AssetManager = class {
2943
3166
  }
2944
3167
  const library = await this.restoreLibraryLockEntries(lock);
2945
3168
  const copyDrift = await this.lockedCopyDrift();
3169
+ const missingCopies = await this.incompleteDeploys();
3170
+ const unrecordedAgents = this.unrecordedAgentFiles(lock);
2946
3171
  const deployed = [
2947
3172
  ...new Set(
2948
3173
  this.targetHarnesses().flatMap(
@@ -2955,9 +3180,10 @@ var AssetManager = class {
2955
3180
  )
2956
3181
  )
2957
3182
  ];
2958
- const restored = this.restoredCopies(copyDrift, deployed);
2959
3183
  await this.renderDriverMcpConfig();
2960
3184
  const agentRender = await this.renderAgentInstances();
3185
+ const restored = this.restoredCopies(copyDrift, deployed, missingCopies);
3186
+ const rewritten = this.rewrittenAgentFiles(unrecordedAgents);
2961
3187
  const alreadyMissing = new Set(
2962
3188
  library.missing.map((m) => {
2963
3189
  const p = parseRefTolerant(m.split(" ")[0] ?? m);
@@ -2975,9 +3201,32 @@ var AssetManager = class {
2975
3201
  missing: [...library.missing, ...gaps],
2976
3202
  lockWritten: false,
2977
3203
  ...restored.length > 0 ? { restored } : {},
3204
+ ...rewritten.length > 0 ? { rewritten } : {},
2978
3205
  ...agentRender
2979
3206
  };
2980
3207
  }
3208
+ /**
3209
+ * The versions of `parsed`'s name that a source, a library or a store holds, newest first,
3210
+ * for the `Asset not found` of a pinned ref. Empty for an unpinned ref (nothing was ruled
3211
+ * out by a version) and when the name is unknown everywhere. A store that cannot be asked
3212
+ * adds nothing here: its failure is reported by the caller.
3213
+ */
3214
+ async availableVersions(parsed, projectStores) {
3215
+ if (!parsed.pin) return [];
3216
+ const unpinned = assetRefToStr({ ...parsed, pin: void 0 });
3217
+ const found = /* @__PURE__ */ new Set();
3218
+ try {
3219
+ const own = await this.info(unpinned);
3220
+ if (own?.version) found.add(own.version);
3221
+ } catch {
3222
+ }
3223
+ const stores = [...projectStores, ...await this.globalStoreFallback(projectStores)];
3224
+ const fetcher = this.storeFetcherFor(stores);
3225
+ for (const store of stores) {
3226
+ for (const v of await fetcher?.listVersions?.(store.url, unpinned) ?? []) found.add(v);
3227
+ }
3228
+ return [...found].sort((a, b) => gt(coerceVersion(a), coerceVersion(b)) ? -1 : 1);
3229
+ }
2981
3230
  /**
2982
3231
  * Parse the ref `add` was given. A ref the grammar rejects fails with the parser's message
2983
3232
  * minus its manifest-migration advice (it points at a skill that is not for `add`), and:
@@ -3100,8 +3349,9 @@ var AssetManager = class {
3100
3349
  `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.`
3101
3350
  );
3102
3351
  }
3352
+ const available = await this.availableVersions(parsed, stores);
3103
3353
  throw new Error(
3104
- `Asset not found: ${ref}${(await this.publisherChangeHints([ref]))[ref] ?? ""}${missing.length ? ` (missing: ${missing.join(", ")})` : ""}`
3354
+ `Asset not found: ${ref}${(await this.publisherChangeHints([ref]))[ref] ?? ""}${missing.length ? ` (missing: ${missing.join(", ")})` : ""}${available.length ? `; ${parsed.name} has version(s): ${available.join(", ")}` : ""}`
3105
3355
  );
3106
3356
  }
3107
3357
  if (parsed.kind === "preset" && missing.length > 0) {
@@ -3189,7 +3439,10 @@ var AssetManager = class {
3189
3439
  if (opts?.onLibraryMoved) {
3190
3440
  for (const m of libraryMoves(prevLock, libraryLock)) opts.onLibraryMoved(m);
3191
3441
  }
3192
- writeLock(this.lockPath, mergeLockFile(prevLock, this.withRenderedAgents(fresh)));
3442
+ writeLock(
3443
+ this.lockPath,
3444
+ this.withInstanceRenderings(mergeLockFile(prevLock, this.withRenderedAgents(fresh)))
3445
+ );
3193
3446
  }
3194
3447
  for (const d of deployed) {
3195
3448
  appendHistory(this.projectDir, {
@@ -3456,9 +3709,9 @@ var AssetManager = class {
3456
3709
  * @throws When `ref` is malformed, or a short ref matches several assets (the
3457
3710
  * message lists them).
3458
3711
  */
3459
- remove(ref) {
3712
+ remove(ref, opts) {
3460
3713
  const target = this.resolveRemoveTarget(ref);
3461
- return target ? this.removeResolved(target) : false;
3714
+ return target ? this.removeResolved(target, { force: opts?.force }) : false;
3462
3715
  }
3463
3716
  /**
3464
3717
  * {@link remove} `ref`, then drop the dependencies that removal left orphaned:
@@ -3489,7 +3742,14 @@ var AssetManager = class {
3489
3742
  }
3490
3743
  let requiredRefs;
3491
3744
  if (entry) {
3492
- requiredRefs = libraryEntryDepRefs(entry);
3745
+ requiredRefs = [
3746
+ ...libraryEntryDepRefs(entry),
3747
+ ...this.lockedRequirementsOf({
3748
+ kind: target.kind,
3749
+ name: target.name,
3750
+ publisher: target.publisher
3751
+ })
3752
+ ];
3493
3753
  } else {
3494
3754
  const lockedAs = Object.keys(this.tryReadLock()?.assets ?? {}).map(parseCanonicalLockKey).find(
3495
3755
  (id) => id.kind === target.kind && id.name === target.name && (!target.publisher || id.publisher === target.publisher)
@@ -3500,9 +3760,11 @@ var AssetManager = class {
3500
3760
  publisher: target.publisher ?? lockedAs?.publisher
3501
3761
  });
3502
3762
  }
3503
- const changed = this.removeResolved(target);
3504
- if (!changed || requiredRefs.length === 0) return { changed, pruned: [] };
3505
- return { changed, pruned: await this.pruneOrphans(requiredRefs) };
3763
+ const kept = [];
3764
+ const changed = this.removeResolved(target, { force: opts?.force, kept });
3765
+ const keptNote = kept.length > 0 ? { kept } : {};
3766
+ if (!changed || requiredRefs.length === 0) return { changed, pruned: [], ...keptNote };
3767
+ return { changed, pruned: await this.pruneOrphans(requiredRefs), ...keptNote };
3506
3768
  }
3507
3769
  /**
3508
3770
  * Resolve the identity {@link remove} acts on. A publisher-qualified ref is taken
@@ -3597,14 +3859,34 @@ var AssetManager = class {
3597
3859
  }
3598
3860
  return found;
3599
3861
  }
3600
- /** Undeploy `parsed` from every target harness and drop its declaration and lock entry. */
3601
- removeResolved(parsed) {
3862
+ /** Whether a lock entry holds `kind:name` (any publisher): the deployed folder is then the project's copy of it. */
3863
+ lockHolds(kind, name) {
3864
+ return Object.keys(this.tryReadLock()?.assets ?? {}).map(parseCanonicalLockKey).some((id) => id.kind === kind && id.name === name);
3865
+ }
3866
+ /** The folders or files of `kind:name` on disk in `target`, shown relative to the project. */
3867
+ heldDeployPaths(kind, name, target) {
3868
+ const component = this.installTarget(kind);
3869
+ if (!component) return [];
3870
+ return deployedPaths(component, name, target, this.global, this.projectDir).filter((p) => existsSync(p)).map((p) => this.global ? p : relative(this.projectDir, p));
3871
+ }
3872
+ /**
3873
+ * Undeploy `parsed` from every target harness and drop its declaration and lock entry.
3874
+ *
3875
+ * A folder no lock entry holds is the user's own work (a hand-made skill of the same name):
3876
+ * it is kept and named in `opts.kept` unless `opts.force`.
3877
+ */
3878
+ removeResolved(parsed, opts = {}) {
3602
3879
  const wantPub = parsed.publisher?.replace(/^@/, "");
3603
3880
  const tracked = this.trackedPublishers(parsed.kind, parsed.name);
3604
3881
  const someoneElses = wantPub !== void 0 && tracked.size > 0 && !tracked.has(wantPub) && !tracked.has(void 0);
3882
+ const owned = opts.force === true || this.lockHolds(parsed.kind, parsed.name);
3605
3883
  let undeployed = false;
3606
3884
  if (!someoneElses) {
3607
3885
  for (const t of this.targetHarnesses()) {
3886
+ if (!owned) {
3887
+ opts.kept?.push(...this.heldDeployPaths(parsed.kind, parsed.name, t));
3888
+ continue;
3889
+ }
3608
3890
  if (removeAsset(parsed.kind, parsed.name, this.deployOptsFor(t))) undeployed = true;
3609
3891
  }
3610
3892
  }
@@ -4066,8 +4348,10 @@ var AssetManager = class {
4066
4348
  const repoStatuses = this.buildRepoStatuses(repositories);
4067
4349
  const lockByKindName = indexLockByKindName(lock);
4068
4350
  const entries = [];
4351
+ const instanceFiles = this.global ? /* @__PURE__ */ new Set() : instanceRenderedAgentNames(this.projectDir, this.driverTarget);
4069
4352
  for (const d of deployed) {
4070
4353
  const lockEntry = lockByKindName.get(`${d.kind}:${d.name}`);
4354
+ if (!lockEntry && d.kind === "agent" && instanceFiles.has(d.name)) continue;
4071
4355
  const publisher = lockEntry?.publisher || "unknown";
4072
4356
  const version = lockEntry?.version ?? "";
4073
4357
  const slug = lockEntry && !lockEntry.library ? sourceCacheKey(lockEntry.url) : "";
@@ -4122,7 +4406,7 @@ var AssetManager = class {
4122
4406
  const out = [];
4123
4407
  try {
4124
4408
  const entry = await this.info(ref);
4125
- const deps = entry ? libraryEntryDepRefs(entry) : lock.assets[node] ? await this.deployedRequirementsOf(parseCanonicalLockKey(node)) : [];
4409
+ const deps = entry ? [...libraryEntryDepRefs(entry), ...lock.assets[node]?.requires ?? []] : lock.assets[node] ? await this.deployedRequirementsOf(parseCanonicalLockKey(node)) : [];
4126
4410
  for (const dep of deps) {
4127
4411
  const key = findKey(dep);
4128
4412
  if (key && key !== node && !out.includes(key)) out.push(key);
@@ -4398,9 +4682,61 @@ var AssetManager = class {
4398
4682
  }
4399
4683
  }
4400
4684
  }
4685
+ await this.addLibraryMoves(libraryAssets, result);
4401
4686
  }
4402
4687
  return this.addLockGapRows(result);
4403
4688
  }
4689
+ /**
4690
+ * List a locked library asset that `update` would move to another library (a default-library
4691
+ * switch, a library that now holds a newer version) as `library → movesTo`, so `outdated`
4692
+ * does not say "up to date" and `update` then re-locks it announced only after the fact.
4693
+ * The resolution is the one `update` runs ({@link lockedPreference}); an asset already listed
4694
+ * with a version row gets the target library on that row.
4695
+ */
4696
+ async addLibraryMoves(libraryAssets, rows) {
4697
+ const refs = [];
4698
+ const lockedIn = /* @__PURE__ */ new Map();
4699
+ for (const [key, entry] of libraryAssets) {
4700
+ const { publisher, kind, name } = parseCanonicalLockKey(key);
4701
+ if (!publisher || !kind || !name || !entry.library) continue;
4702
+ const ref = `${kind}:@${publisher}/${name}`;
4703
+ refs.push(ref);
4704
+ lockedIn.set(ref, { name: entry.library.name, key });
4705
+ }
4706
+ if (refs.length === 0) return;
4707
+ let res;
4708
+ try {
4709
+ res = await this.resolveLibraryEntries(refs, {
4710
+ quiet: true,
4711
+ preferLocked: await this.lockedPreference()
4712
+ });
4713
+ } catch {
4714
+ return;
4715
+ }
4716
+ for (const e of res.entries) {
4717
+ const to = res.libraryOf.get(e);
4718
+ const publisher = (e.publisher ?? "").replace(/^@/, "");
4719
+ const ref = `${e.kind}:@${publisher}/${e.name}`;
4720
+ const from = lockedIn.get(ref);
4721
+ if (!to || !from || from.name === to) continue;
4722
+ const row = rows.find(
4723
+ (r) => r.kind === e.kind && r.name === e.name && r.publisher.replace(/^@/, "") === publisher
4724
+ );
4725
+ if (row) {
4726
+ row.movesTo = to;
4727
+ continue;
4728
+ }
4729
+ rows.push({
4730
+ kind: e.kind,
4731
+ name: e.name,
4732
+ publisher,
4733
+ currentVersion: parseCanonicalLockKey(from.key).version ?? "",
4734
+ behind: 0,
4735
+ library: from.name,
4736
+ movesTo: to
4737
+ });
4738
+ }
4739
+ }
4404
4740
  /**
4405
4741
  * Add one `problem` row per {@link AssetManager.projectState} gap whose asset is not
4406
4742
  * listed yet, so `outdated` lists the same assets `check`, `doctor` and `install --locked`
@@ -4706,7 +5042,7 @@ var AssetManager = class {
4706
5042
  }
4707
5043
  continue;
4708
5044
  }
4709
- const declaredRequires = full ? full.requires : (await this.deployedRequirementsOf({ ...entry, publisher })).map(parseDep);
5045
+ const declaredRequires = full ? [...full.requires, ...(full.dependencies ?? []).filter(Boolean).map(parseDep)] : (await this.deployedRequirementsOf({ ...entry, publisher })).map(parseDep);
4710
5046
  const gaps = [];
4711
5047
  const requirements = dedupeRequirements(declaredRequires, publisher).map(
4712
5048
  (r) => r.publisher || !publisher ? r : { ...r, publisher }
@@ -4872,7 +5208,7 @@ var AssetManager = class {
4872
5208
  }
4873
5209
  gaps.push(...await this.declaredGaps(requirements, named));
4874
5210
  for (const d of await this.incompleteDeploys()) {
4875
- const reason = `is deployed without ${d.missing.join(", ")} \u2014 run \`skaile install\` to restore it`;
5211
+ const reason = `is deployed without ${d.missing.join(", ")} \u2014 run \`skaile install --locked\` to restore it`;
4876
5212
  gaps.push({ type: "incomplete", ref: d.ref, reason, message: `${d.ref} ${reason}` });
4877
5213
  }
4878
5214
  const skipped = [];
@@ -4934,6 +5270,17 @@ var AssetManager = class {
4934
5270
  return k.kind === "agent" && k.name === parsedRef?.name && (!publisher || !k.publisher || k.publisher === publisher);
4935
5271
  });
4936
5272
  if (lockedAgent) {
5273
+ const libraryFix = (await this.unresolvedFixes([ref])).get(ref);
5274
+ if (libraryFix) {
5275
+ const register = libraryFix.replace(
5276
+ /, or drop the dependency with `skaile remove [^`]*`$/,
5277
+ ""
5278
+ );
5279
+ return {
5280
+ lead: "the agent is locked but its library cannot supply it here",
5281
+ advice: `${register}, ${drop}`
5282
+ };
5283
+ }
4937
5284
  return {
4938
5285
  lead: "the agent is locked but not restored here",
4939
5286
  advice: `run \`skaile install --locked\` first, ${drop}`
@@ -5091,7 +5438,8 @@ var AssetManager = class {
5091
5438
  gaps.push({ type: "library", ref, reason: reason2, message: `${ref} ${reason2}` });
5092
5439
  continue;
5093
5440
  }
5094
- const reason = `is locked, but library "${lookup.name}" no longer holds it \u2014 restore it there, or drop the dependency with \`skaile remove ${ref}\``;
5441
+ const renamedTo = await this.renamedFlowRef(lookup, publisher, kind, name);
5442
+ const reason = renamedTo ? `is locked, but library "${lookup.name}" holds it as ${renamedTo} now (a flow is named by its \`id:\`) \u2014 run \`skaile remove ${ref}\`, then \`skaile add ${renamedTo}\`` : `is locked, but library "${lookup.name}" no longer holds it \u2014 restore it there, or drop the dependency with \`skaile remove ${ref}\``;
5095
5443
  gaps.push({ type: "library", ref, reason, message: `${ref} ${reason}`, manualFix: true });
5096
5444
  }
5097
5445
  return gaps;
@@ -5111,53 +5459,153 @@ var AssetManager = class {
5111
5459
  const rendered = this.renderedAgentFiles(name);
5112
5460
  if (rendered.length > 0) entry.rendered = rendered;
5113
5461
  }
5462
+ return this.withInstanceRenderings(lock);
5463
+ }
5464
+ /**
5465
+ * Make the `rendered:` list of every agent entry say exactly which files belong to it: the
5466
+ * asset-named files of its own rendering (hashes kept as recorded) plus the files of the agent
5467
+ * instances whose `ref` names it (`.claude/agents/default.md`, …) with their current sha256,
5468
+ * so a hand edit of an instance file is drift like one of the asset-named file. A path that is
5469
+ * neither is dropped: an instance that left `skaile.yaml`, or was bound to another agent, no
5470
+ * longer lists its file under the old entry. A file that is another entry's own rendering
5471
+ * stays with that entry; an instance whose `ref` names no locked agent (a path ref) has no
5472
+ * entry to hold its files. Call it after `renderAgentInstances`, which rewrites every
5473
+ * instance file, so the bytes hashed are the ones just written.
5474
+ */
5475
+ withInstanceRenderings(lock) {
5476
+ if (this.global) return lock;
5477
+ const agentKeys = Object.keys(lock.assets).filter((k) => {
5478
+ const { kind, name } = parseCanonicalLockKey(k);
5479
+ return kind && name && this.installTarget(kind) === "agent";
5480
+ });
5481
+ const ownFiles = /* @__PURE__ */ new Map();
5482
+ for (const key of agentKeys) {
5483
+ const { name } = parseCanonicalLockKey(key);
5484
+ ownFiles.set(key, new Set(this.renderedAgentFiles(name).map((f) => f.path)));
5485
+ }
5486
+ const instanceFiles = /* @__PURE__ */ new Map();
5487
+ for (const instance of renderedInstanceFiles(this.projectDir, this.driverTarget)) {
5488
+ const want = parseRefTolerant(instance.ref);
5489
+ if (!want || want.kind !== "agent") continue;
5490
+ const wantPublisher = want.publisher?.replace(/^@/, "");
5491
+ const key = agentKeys.find((k) => {
5492
+ const p = parseCanonicalLockKey(k);
5493
+ return p.name === want.name && (wantPublisher === void 0 || p.publisher === wantPublisher);
5494
+ });
5495
+ if (!key) continue;
5496
+ const files = [];
5497
+ for (const rel of instance.files) this.hashTree(join(this.projectDir, rel), files);
5498
+ const held = instanceFiles.get(key) ?? /* @__PURE__ */ new Map();
5499
+ for (const f of files) {
5500
+ const ownedElsewhere = agentKeys.some((k) => k !== key && ownFiles.get(k)?.has(f.path));
5501
+ if (!ownedElsewhere) held.set(f.path, f);
5502
+ }
5503
+ instanceFiles.set(key, held);
5504
+ }
5505
+ for (const key of agentKeys) {
5506
+ const entry = lock.assets[key];
5507
+ if (entry.library?.installed) continue;
5508
+ const own = ownFiles.get(key) ?? /* @__PURE__ */ new Set();
5509
+ const instance = instanceFiles.get(key) ?? /* @__PURE__ */ new Map();
5510
+ const byPath = /* @__PURE__ */ new Map();
5511
+ for (const f of entry.rendered ?? []) if (own.has(f.path)) byPath.set(f.path, f);
5512
+ for (const [path2, f] of instance) byPath.set(path2, f);
5513
+ if (byPath.size > 0) {
5514
+ entry.rendered = [...byPath.values()].sort((x, y) => x.path.localeCompare(y.path));
5515
+ } else {
5516
+ delete entry.rendered;
5517
+ }
5518
+ }
5114
5519
  return lock;
5115
5520
  }
5521
+ /** Append the regular files under `path` (a file or a directory) to `out`, project-relative with sha256. Symlinks are skipped. */
5522
+ hashTree(path2, out) {
5523
+ let stat;
5524
+ try {
5525
+ stat = lstatSync(path2);
5526
+ } catch {
5527
+ return;
5528
+ }
5529
+ if (stat.isSymbolicLink()) return;
5530
+ if (stat.isDirectory()) {
5531
+ for (const child of readdirSync(path2).sort()) this.hashTree(join(path2, child), out);
5532
+ } else if (stat.isFile()) {
5533
+ out.push({
5534
+ path: relative(this.projectDir, path2).split(sep).join("/"),
5535
+ sha256: computeHash(path2)
5536
+ });
5537
+ }
5538
+ }
5116
5539
  /** The files of one agent's rendering for the active harness, project-relative, with sha256. */
5117
5540
  renderedAgentFiles(name) {
5118
5541
  const out = [];
5119
- const walk = (path2) => {
5120
- let stat;
5121
- try {
5122
- stat = lstatSync(path2);
5123
- } catch {
5124
- return;
5125
- }
5126
- if (stat.isSymbolicLink()) return;
5127
- if (stat.isDirectory()) {
5128
- for (const child of readdirSync(path2).sort()) walk(join(path2, child));
5129
- } else if (stat.isFile()) {
5130
- out.push({
5131
- path: relative(this.projectDir, path2).split(sep).join("/"),
5132
- sha256: computeHash(path2)
5133
- });
5134
- }
5135
- };
5136
5542
  for (const path2 of deployedPaths("agent", name, this.driverTarget, false, this.projectDir)) {
5137
- walk(path2);
5543
+ this.hashTree(path2, out);
5138
5544
  }
5139
- walk(
5545
+ this.hashTree(
5140
5546
  join(
5141
5547
  dirname(deployedBase("agent", this.driverTarget, false, this.projectDir)),
5142
5548
  CODEX_IDENTITY_DIR,
5143
5549
  `${name}.md`
5144
- )
5550
+ ),
5551
+ out
5145
5552
  );
5146
5553
  return out.sort((a, b) => a.path.localeCompare(b.path));
5147
5554
  }
5555
+ /**
5556
+ * The rendered native files of every locked agent whose lock entry records no `rendered:`
5557
+ * (a lock an older CLI wrote), as path → sha256, taken before a deploy. `check` cannot tell
5558
+ * such a file from a stale one, so {@link rewrittenAgentFiles} compares it afterwards.
5559
+ * Project mode only.
5560
+ */
5561
+ unrecordedAgentFiles(lock) {
5562
+ const out = /* @__PURE__ */ new Map();
5563
+ if (this.global || !lock) return out;
5564
+ for (const [key, entry] of Object.entries(lock.assets)) {
5565
+ if (entry.rendered || entry.library?.installed) continue;
5566
+ const { kind, name } = parseCanonicalLockKey(key);
5567
+ if (!kind || !name || this.installTarget(kind) !== "agent") continue;
5568
+ const files = this.renderedAgentFiles(name);
5569
+ if (files.length > 0) out.set(key, new Map(files.map((f) => [f.path, f.sha256])));
5570
+ }
5571
+ return out;
5572
+ }
5573
+ /**
5574
+ * The agent files a deploy changed that {@link unrecordedAgentFiles} saw before it: one row
5575
+ * per locked agent, listing the project-relative paths whose bytes differ now. A render the
5576
+ * CLI changed (the 5.12.0 abilities block) otherwise reaches the user as a silent rewrite.
5577
+ */
5578
+ rewrittenAgentFiles(before) {
5579
+ const out = [];
5580
+ for (const [key, files] of before) {
5581
+ const { name } = parseCanonicalLockKey(key);
5582
+ if (!name) continue;
5583
+ const changed = this.renderedAgentFiles(name).filter((f) => files.has(f.path) && files.get(f.path) !== f.sha256).map((f) => f.path);
5584
+ if (changed.length > 0) out.push({ ref: key, files: changed });
5585
+ }
5586
+ return out;
5587
+ }
5148
5588
  /**
5149
5589
  * The {@link RestoredAsset} rows for the drifted copies (see {@link lockedCopyDrift}) a
5150
5590
  * deploy just wrote again: those whose ref is among the `deployed` canonical refs.
5151
5591
  */
5152
- restoredCopies(drifts, deployed) {
5592
+ restoredCopies(drifts, deployed, incomplete = []) {
5153
5593
  const rewritten = new Set(deployed.map((d) => d.split("#")[0]));
5154
5594
  const out = [];
5155
5595
  for (const d of drifts) {
5156
- if (!rewritten.has(d.ref)) continue;
5157
5596
  if (d.rendered) {
5158
- out.push({ ref: d.key, restored: [...d.modified], removed: [] });
5597
+ const restored = d.modified.filter((f) => {
5598
+ if (rewritten.has(d.ref)) return true;
5599
+ try {
5600
+ return computeHash(join(this.projectDir, f)) === d.lockedSha?.get(f);
5601
+ } catch {
5602
+ return false;
5603
+ }
5604
+ });
5605
+ if (restored.length > 0) out.push({ ref: d.key, restored, removed: [] });
5159
5606
  continue;
5160
5607
  }
5608
+ if (!rewritten.has(d.ref)) continue;
5161
5609
  const { kind, name } = parseCanonicalLockKey(d.key);
5162
5610
  const component = kind ? this.installTarget(kind) : void 0;
5163
5611
  if (!kind || !name || !component) continue;
@@ -5171,6 +5619,22 @@ var AssetManager = class {
5171
5619
  removed: d.extra.map((f) => `${dir}/${f}`)
5172
5620
  });
5173
5621
  }
5622
+ for (const inc of incomplete) {
5623
+ const bare = inc.ref.split("#")[0];
5624
+ const key = deployed.find((d) => d.split("#")[0] === bare);
5625
+ if (!key) continue;
5626
+ const { kind, name } = parseCanonicalLockKey(inc.ref);
5627
+ const component = kind ? this.installTarget(kind) : void 0;
5628
+ if (!kind || !name || !component) continue;
5629
+ const dir = relative(
5630
+ this.projectDir,
5631
+ deployedDir(component, name, this.driverTarget, this.global, this.projectDir)
5632
+ ).split(sep).join("/");
5633
+ const files = inc.missing.map((f) => `${dir}/${f}`);
5634
+ const row = out.find((r) => r.ref.split("#")[0] === bare);
5635
+ if (row) row.restored.push(...files.filter((f) => !row.restored.includes(f)));
5636
+ else out.push({ ref: key, restored: files, removed: [] });
5637
+ }
5174
5638
  return out;
5175
5639
  }
5176
5640
  /**
@@ -5257,8 +5721,17 @@ var AssetManager = class {
5257
5721
  modified.push(f.path);
5258
5722
  }
5259
5723
  }
5260
- if (modified.length > 0)
5261
- out.push({ ref: refOf(key), key, modified, extra: [], library: false, rendered: true });
5724
+ if (modified.length > 0) {
5725
+ out.push({
5726
+ ref: refOf(key),
5727
+ key,
5728
+ modified,
5729
+ extra: [],
5730
+ library: false,
5731
+ rendered: true,
5732
+ lockedSha: new Map(entry.rendered.map((f) => [f.path, f.sha256]))
5733
+ });
5734
+ }
5262
5735
  }
5263
5736
  return out;
5264
5737
  }
@@ -5275,7 +5748,10 @@ var AssetManager = class {
5275
5748
  const { publisher, kind, name } = parseCanonicalLockKey(key);
5276
5749
  const component = kind ? this.installTarget(kind) : void 0;
5277
5750
  if (!kind || !name || !component || named.has(`${kind}:${name}`)) continue;
5278
- if (isDeployed(component, name, this.driverTarget, this.global, this.projectDir)) continue;
5751
+ if (isDeployed(component, name, this.driverTarget, this.global, this.projectDir)) {
5752
+ const renderedGone = component === "agent" && !this.global && (entry.rendered ?? []).some((f) => !existsSync(join(this.projectDir, f.path)));
5753
+ if (!renderedGone) continue;
5754
+ }
5279
5755
  const ref = publisher ? `${kind}:@${publisher}/${name}` : `${kind}:${name}`;
5280
5756
  const reason = "is locked but its deployed copy is missing \u2014 run `skaile install --locked`";
5281
5757
  gaps.push({ type: "drift", ref, reason, message: `${ref} ${reason}` });
@@ -5749,5 +6225,5 @@ var AssetManager = class {
5749
6225
  };
5750
6226
 
5751
6227
  export { AssetManager, FACTORY_SOURCE_URL, MissingManifestError, installAgentInstances, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, softDepName };
5752
- //# sourceMappingURL=chunk-QAYL3PYY.js.map
5753
- //# sourceMappingURL=chunk-QAYL3PYY.js.map
6228
+ //# sourceMappingURL=chunk-XX4C72CC.js.map
6229
+ //# sourceMappingURL=chunk-XX4C72CC.js.map