@skaile/workspaces 5.10.0 → 5.11.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 (255) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +12 -0
  3. package/dist/{asset-feeds-ELEBTNUS.js → asset-feeds-CXGQIDFR.js} +18 -18
  4. package/dist/{asset-feeds-ELEBTNUS.js.map → asset-feeds-CXGQIDFR.js.map} +1 -1
  5. package/dist/asset-manager/catalog-deployer.js +7 -7
  6. package/dist/asset-manager/index.js +13 -13
  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 +103 -2
  10. package/dist/asset-manager/src/index.d.ts.map +1 -1
  11. package/dist/asset-manager/src/install-instances.d.ts.map +1 -1
  12. package/dist/asset-manager/src/installer.d.ts +23 -3
  13. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  14. package/dist/bridge/drivers/claude-sdk.js +10 -10
  15. package/dist/bridge/drivers/codex.js +9 -9
  16. package/dist/bridge/drivers/continue.js +9 -9
  17. package/dist/bridge/drivers/echo.js +1 -1
  18. package/dist/bridge/drivers/gemini.js +6 -6
  19. package/dist/bridge/drivers/goose.js +9 -9
  20. package/dist/bridge/drivers/omp.js +18 -2
  21. package/dist/bridge/drivers/omp.js.map +1 -1
  22. package/dist/bridge/drivers/opencode.js +9 -9
  23. package/dist/bridge/drivers/qwen.js +6 -6
  24. package/dist/bridge/index.js +11 -11
  25. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  26. package/dist/{chunk-3BEY4WK3.js → chunk-2F5AWQX5.js} +77 -11
  27. package/dist/chunk-2F5AWQX5.js.map +1 -0
  28. package/dist/{chunk-IJHH4DSW.js → chunk-3SM2DL2T.js} +8 -8
  29. package/dist/{chunk-IJHH4DSW.js.map → chunk-3SM2DL2T.js.map} +1 -1
  30. package/dist/{chunk-HJ5MCB3L.js → chunk-47U4GZ4M.js} +2 -2
  31. package/dist/{chunk-HJ5MCB3L.js.map → chunk-47U4GZ4M.js.map} +1 -1
  32. package/dist/{chunk-7CR6HT2X.js → chunk-4A4OD24G.js} +9 -9
  33. package/dist/{chunk-7CR6HT2X.js.map → chunk-4A4OD24G.js.map} +1 -1
  34. package/dist/{chunk-5QI2JYJC.js → chunk-6O2X3GPW.js} +2 -2
  35. package/dist/{chunk-5QI2JYJC.js.map → chunk-6O2X3GPW.js.map} +1 -1
  36. package/dist/{chunk-JZCSNEHK.js → chunk-ALEYHUC5.js} +42 -20
  37. package/dist/chunk-ALEYHUC5.js.map +1 -0
  38. package/dist/{chunk-4OV5DSBB.js → chunk-BNMZVPYA.js} +5 -5
  39. package/dist/chunk-BNMZVPYA.js.map +1 -0
  40. package/dist/{chunk-SBFW3CJH.js → chunk-CAHB6MHA.js} +5 -5
  41. package/dist/{chunk-SBFW3CJH.js.map → chunk-CAHB6MHA.js.map} +1 -1
  42. package/dist/{chunk-4P3KTUZH.js → chunk-CJERAGFY.js} +24 -13
  43. package/dist/chunk-CJERAGFY.js.map +1 -0
  44. package/dist/{chunk-MVQ3Q2HM.js → chunk-COH6FQAG.js} +4 -4
  45. package/dist/{chunk-MVQ3Q2HM.js.map → chunk-COH6FQAG.js.map} +1 -1
  46. package/dist/{chunk-ZGQTS3Y4.js → chunk-CPWLNZGJ.js} +3 -3
  47. package/dist/{chunk-ZGQTS3Y4.js.map → chunk-CPWLNZGJ.js.map} +1 -1
  48. package/dist/{chunk-MGGFBZWA.js → chunk-D3B36CYC.js} +4 -3
  49. package/dist/chunk-D3B36CYC.js.map +1 -0
  50. package/dist/{chunk-2JMLDZLP.js → chunk-DZMNFCWB.js} +416 -55
  51. package/dist/chunk-DZMNFCWB.js.map +1 -0
  52. package/dist/{chunk-GFCXNFTW.js → chunk-EDYHEMJA.js} +4 -4
  53. package/dist/{chunk-GFCXNFTW.js.map → chunk-EDYHEMJA.js.map} +1 -1
  54. package/dist/{chunk-PE36IF2D.js → chunk-FH7W6TJ4.js} +65 -31
  55. package/dist/chunk-FH7W6TJ4.js.map +1 -0
  56. package/dist/{chunk-G54USEUP.js → chunk-G4FFOV3N.js} +4 -4
  57. package/dist/{chunk-G54USEUP.js.map → chunk-G4FFOV3N.js.map} +1 -1
  58. package/dist/{chunk-HOHUEKES.js → chunk-GCHPUTA3.js} +3 -3
  59. package/dist/{chunk-HOHUEKES.js.map → chunk-GCHPUTA3.js.map} +1 -1
  60. package/dist/{chunk-TRSQP3JD.js → chunk-GV4DZ6MT.js} +20 -4
  61. package/dist/chunk-GV4DZ6MT.js.map +1 -0
  62. package/dist/{chunk-QG3HOJEK.js → chunk-HCEVNYSH.js} +3 -3
  63. package/dist/{chunk-QG3HOJEK.js.map → chunk-HCEVNYSH.js.map} +1 -1
  64. package/dist/{chunk-6HHE63CO.js → chunk-HZXUXHIV.js} +4 -4
  65. package/dist/{chunk-6HHE63CO.js.map → chunk-HZXUXHIV.js.map} +1 -1
  66. package/dist/{chunk-FRPBSUFH.js → chunk-IER3KIPH.js} +5 -5
  67. package/dist/{chunk-FRPBSUFH.js.map → chunk-IER3KIPH.js.map} +1 -1
  68. package/dist/{chunk-GEWAIQZ5.js → chunk-J4RBUFGM.js} +10 -12
  69. package/dist/chunk-J4RBUFGM.js.map +1 -0
  70. package/dist/{chunk-OOWHXOK6.js → chunk-M3B6EIJD.js} +4 -4
  71. package/dist/{chunk-OOWHXOK6.js.map → chunk-M3B6EIJD.js.map} +1 -1
  72. package/dist/{chunk-VLXDXRRX.js → chunk-MZG34MBZ.js} +3 -3
  73. package/dist/{chunk-VLXDXRRX.js.map → chunk-MZG34MBZ.js.map} +1 -1
  74. package/dist/{chunk-2FMEGSBN.js → chunk-PBBPZYVG.js} +31 -9
  75. package/dist/chunk-PBBPZYVG.js.map +1 -0
  76. package/dist/{chunk-CLTHEKHR.js → chunk-PQFHMQHQ.js} +4 -4
  77. package/dist/{chunk-CLTHEKHR.js.map → chunk-PQFHMQHQ.js.map} +1 -1
  78. package/dist/{chunk-SX5U422E.js → chunk-QVFAS5IO.js} +3 -3
  79. package/dist/{chunk-SX5U422E.js.map → chunk-QVFAS5IO.js.map} +1 -1
  80. package/dist/{chunk-JFXQEVLF.js → chunk-QZNJOHN6.js} +3 -3
  81. package/dist/{chunk-JFXQEVLF.js.map → chunk-QZNJOHN6.js.map} +1 -1
  82. package/dist/{chunk-V5TZH4GF.js → chunk-R7NHYEJF.js} +4 -4
  83. package/dist/{chunk-V5TZH4GF.js.map → chunk-R7NHYEJF.js.map} +1 -1
  84. package/dist/{chunk-V7PQZOBR.js → chunk-RYYLMBA2.js} +5 -5
  85. package/dist/{chunk-V7PQZOBR.js.map → chunk-RYYLMBA2.js.map} +1 -1
  86. package/dist/{chunk-WBYDAL6X.js → chunk-S3O3GKB7.js} +4 -4
  87. package/dist/{chunk-WBYDAL6X.js.map → chunk-S3O3GKB7.js.map} +1 -1
  88. package/dist/{chunk-Y34MSWEZ.js → chunk-SBSA3IQA.js} +3 -3
  89. package/dist/{chunk-Y34MSWEZ.js.map → chunk-SBSA3IQA.js.map} +1 -1
  90. package/dist/{chunk-Y63UQZ7P.js → chunk-T42WRQ4O.js} +3 -3
  91. package/dist/{chunk-Y63UQZ7P.js.map → chunk-T42WRQ4O.js.map} +1 -1
  92. package/dist/{chunk-OBVJ7RPW.js → chunk-T7CTHHG7.js} +3 -3
  93. package/dist/{chunk-OBVJ7RPW.js.map → chunk-T7CTHHG7.js.map} +1 -1
  94. package/dist/{chunk-7I5VRVDP.js → chunk-TCHRMVTO.js} +4 -4
  95. package/dist/{chunk-7I5VRVDP.js.map → chunk-TCHRMVTO.js.map} +1 -1
  96. package/dist/{chunk-NRDSGLCQ.js → chunk-VLTQGE2E.js} +65 -22
  97. package/dist/chunk-VLTQGE2E.js.map +1 -0
  98. package/dist/{chunk-Z2K6BGUR.js → chunk-WSBKB4CJ.js} +13 -13
  99. package/dist/{chunk-Z2K6BGUR.js.map → chunk-WSBKB4CJ.js.map} +1 -1
  100. package/dist/{chunk-3MKPZZRE.js → chunk-X77SUM4P.js} +3 -3
  101. package/dist/{chunk-3MKPZZRE.js.map → chunk-X77SUM4P.js.map} +1 -1
  102. package/dist/{chunk-XCNK4UE5.js → chunk-XDKH7XSA.js} +5 -5
  103. package/dist/{chunk-XCNK4UE5.js.map → chunk-XDKH7XSA.js.map} +1 -1
  104. package/dist/{chunk-TH4CTXHX.js → chunk-XUSALIEI.js} +6 -6
  105. package/dist/{chunk-TH4CTXHX.js.map → chunk-XUSALIEI.js.map} +1 -1
  106. package/dist/{chunk-3KHYGOEY.js → chunk-Y3HTGHJC.js} +3 -3
  107. package/dist/{chunk-3KHYGOEY.js.map → chunk-Y3HTGHJC.js.map} +1 -1
  108. package/dist/{chunk-YBQONMH2.js → chunk-YOH2L76X.js} +90 -50
  109. package/dist/chunk-YOH2L76X.js.map +1 -0
  110. package/dist/{chunk-32XKCNCL.js → chunk-ZCAJZ4B2.js} +3 -3
  111. package/dist/chunk-ZCAJZ4B2.js.map +1 -0
  112. package/dist/{chunk-IXWODEED.js → chunk-ZPWTOUTK.js} +43 -7
  113. package/dist/chunk-ZPWTOUTK.js.map +1 -0
  114. package/dist/cli/index.js +210 -163
  115. package/dist/cli/index.js.map +1 -1
  116. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  117. package/dist/cli/src/commands/diff.d.ts +1 -1
  118. package/dist/cli/src/commands/diff.d.ts.map +1 -1
  119. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  120. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  121. package/dist/cli/src/commands/manage.d.ts +6 -0
  122. package/dist/cli/src/commands/manage.d.ts.map +1 -1
  123. package/dist/cli/src/commands/outdated.d.ts.map +1 -1
  124. package/dist/cli/src/commands/project.d.ts +3 -1
  125. package/dist/cli/src/commands/project.d.ts.map +1 -1
  126. package/dist/cli/src/commands/run.d.ts.map +1 -1
  127. package/dist/cli/src/commands/update.d.ts.map +1 -1
  128. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  129. package/dist/cli/src/commands/why.d.ts +1 -0
  130. package/dist/cli/src/commands/why.d.ts.map +1 -1
  131. package/dist/cli/src/helpers.d.ts +12 -0
  132. package/dist/cli/src/helpers.d.ts.map +1 -1
  133. package/dist/cli/src/skill-checks.d.ts +14 -6
  134. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  135. package/dist/connectors/config.js +5 -5
  136. package/dist/connectors/index.js +15 -15
  137. package/dist/{connectors-OXP2JBGI.js → connectors-4QWAKPHB.js} +18 -18
  138. package/dist/{connectors-OXP2JBGI.js.map → connectors-4QWAKPHB.js.map} +1 -1
  139. package/dist/core/index.js +6 -6
  140. package/dist/core/manifest.js +2 -2
  141. package/dist/core/models.js +1 -1
  142. package/dist/core/publish-manifest.js +2 -2
  143. package/dist/core/ref.js +1 -1
  144. package/dist/core/runtime-assets.js +5 -5
  145. package/dist/core/src/lock.d.ts +4 -3
  146. package/dist/core/src/lock.d.ts.map +1 -1
  147. package/dist/core/src/models.d.ts +1 -1
  148. package/dist/core/src/models.d.ts.map +1 -1
  149. package/dist/core/src/publish-manifest.d.ts +11 -1
  150. package/dist/core/src/publish-manifest.d.ts.map +1 -1
  151. package/dist/core/src/workspace-config.d.ts +4 -1
  152. package/dist/core/src/workspace-config.d.ts.map +1 -1
  153. package/dist/core/workspace-config.js +4 -4
  154. package/dist/deploy/index.js +6 -6
  155. package/dist/discovery/index.js +5 -5
  156. package/dist/discovery/src/source-config.d.ts.map +1 -1
  157. package/dist/{ensure-sources-5ISVIA4T.js → ensure-sources-2RONZKCU.js} +16 -16
  158. package/dist/{ensure-sources-5ISVIA4T.js.map → ensure-sources-2RONZKCU.js.map} +1 -1
  159. package/dist/factory-assets/connectors/box.js +15 -15
  160. package/dist/factory-assets/connectors/deploy.js +15 -15
  161. package/dist/factory-assets/connectors/devserver.js +15 -15
  162. package/dist/factory-assets/connectors/flow/adapter.js +15 -15
  163. package/dist/factory-assets/connectors/flow/contract/normalize.d.ts.map +1 -1
  164. package/dist/factory-assets/connectors/flow/contract.js +1 -1
  165. package/dist/factory-assets/connectors/flow/engine.js +8 -8
  166. package/dist/factory-assets/connectors/flow/run-flow.js +17 -17
  167. package/dist/factory-assets/connectors/flow.js +15 -15
  168. package/dist/factory-assets/connectors/git.js +15 -15
  169. package/dist/factory-assets/connectors/gmail.js +15 -15
  170. package/dist/factory-assets/connectors/googledrive.js +15 -15
  171. package/dist/factory-assets/connectors/local.js +15 -15
  172. package/dist/factory-assets/connectors/mattermost.js +15 -15
  173. package/dist/factory-assets/connectors/memory.js +15 -15
  174. package/dist/factory-assets/connectors/minio.js +15 -15
  175. package/dist/factory-assets/connectors/postgres.js +15 -15
  176. package/dist/factory-assets/connectors/s3.js +15 -15
  177. package/dist/factory-assets/connectors/sharepoint.js +15 -15
  178. package/dist/factory-assets/connectors/sqlite.js +15 -15
  179. package/dist/factory-assets/connectors/static-server.js +15 -15
  180. package/dist/factory-assets/connectors/tunnel.js +15 -15
  181. package/dist/factory-assets/connectors/webdav.js +15 -15
  182. package/dist/factory-assets/connectors/xstate-store.js +15 -15
  183. package/dist/factory-assets/connectors/xstate.js +15 -15
  184. package/dist/factory-assets/skills/authoring-skaile-manifests/references/dependency-standard.md +4 -2
  185. package/dist/{flows-HMSE76PO.js → flows-EQF2CH4U.js} +11 -11
  186. package/dist/{flows-HMSE76PO.js.map → flows-EQF2CH4U.js.map} +1 -1
  187. package/dist/{helpers-X6URBGSF.js → helpers-CFK6YP6R.js} +16 -16
  188. package/dist/{helpers-X6URBGSF.js.map → helpers-CFK6YP6R.js.map} +1 -1
  189. package/dist/library/index.js +10 -10
  190. package/dist/library/install.js +3 -3
  191. package/dist/library/src/index.d.ts +1 -1
  192. package/dist/library/src/index.d.ts.map +1 -1
  193. package/dist/library/src/local/library-dir.d.ts +26 -0
  194. package/dist/library/src/local/library-dir.d.ts.map +1 -1
  195. package/dist/library/src/local/library-manager.d.ts.map +1 -1
  196. package/dist/library/src/sync/git-driver.d.ts +2 -0
  197. package/dist/library/src/sync/git-driver.d.ts.map +1 -1
  198. package/dist/{library-publish-OS3JDW4S.js → library-publish-53UTB3MB.js} +51 -24
  199. package/dist/library-publish-53UTB3MB.js.map +1 -0
  200. package/dist/open-library-BOSPJVID.js +40 -0
  201. package/dist/{open-library-4QSUORI6.js.map → open-library-BOSPJVID.js.map} +1 -1
  202. package/dist/open-registry-4FI7HKET.js +32 -0
  203. package/dist/{open-registry-VCKS3MP5.js.map → open-registry-4FI7HKET.js.map} +1 -1
  204. package/dist/{paths-BVO56A25.js → paths-SUS4S4YT.js} +9 -9
  205. package/dist/{paths-BVO56A25.js.map → paths-SUS4S4YT.js.map} +1 -1
  206. package/dist/{plugin-store-X7GPWGBG.js → plugin-store-AGQDMING.js} +8 -8
  207. package/dist/{plugin-store-X7GPWGBG.js.map → plugin-store-AGQDMING.js.map} +1 -1
  208. package/dist/{project-PAXP46RD.js → project-I55A4O2T.js} +20 -20
  209. package/dist/{project-PAXP46RD.js.map → project-I55A4O2T.js.map} +1 -1
  210. package/dist/resolver/index.js +7 -7
  211. package/dist/runner/index.js +28 -28
  212. package/dist/runner/src/serve.d.ts.map +1 -1
  213. package/dist/runner/src/usage-limit-turn-hold.d.ts +51 -0
  214. package/dist/runner/src/usage-limit-turn-hold.d.ts.map +1 -0
  215. package/dist/sdk/asset-manager.js +13 -13
  216. package/dist/sdk/bridge.js +11 -11
  217. package/dist/sdk/core.js +6 -6
  218. package/dist/sdk/flow.js +8 -8
  219. package/dist/sdk/index.js +28 -28
  220. package/dist/sdk/resolver.js +7 -7
  221. package/dist/sdk/runner.js +28 -28
  222. package/dist/{setup-BV55VHWC.js → setup-7DQJKHUI.js} +21 -21
  223. package/dist/{setup-BV55VHWC.js.map → setup-7DQJKHUI.js.map} +1 -1
  224. package/dist/{skills-EDFUCJPX.js → skills-NUEN5NDX.js} +12 -12
  225. package/dist/{skills-EDFUCJPX.js.map → skills-NUEN5NDX.js.map} +1 -1
  226. package/dist/{source-E4VAT5RZ.js → source-G2LV5LVD.js} +21 -21
  227. package/dist/{source-E4VAT5RZ.js.map → source-G2LV5LVD.js.map} +1 -1
  228. package/dist/{source-manifest-publish-CLEE6TNH.js → source-manifest-publish-6RM7SWLZ.js} +23 -23
  229. package/dist/{source-manifest-publish-CLEE6TNH.js.map → source-manifest-publish-6RM7SWLZ.js.map} +1 -1
  230. package/dist/tui/index.js +59 -39
  231. package/dist/tui/index.js.map +1 -1
  232. package/dist/tui/src/repl.d.ts.map +1 -1
  233. package/dist/types/manifests.js +1 -1
  234. package/dist/types/src/manifests/preset.d.ts +1 -1
  235. package/dist/workspace-plugin/adapters/mcp.js +22 -22
  236. package/dist/workspace-plugin/adapters/omp.js +14 -14
  237. package/dist/workspace-plugin/index.js +1 -1
  238. package/package.json +1 -1
  239. package/dist/chunk-2FMEGSBN.js.map +0 -1
  240. package/dist/chunk-2JMLDZLP.js.map +0 -1
  241. package/dist/chunk-32XKCNCL.js.map +0 -1
  242. package/dist/chunk-3BEY4WK3.js.map +0 -1
  243. package/dist/chunk-4OV5DSBB.js.map +0 -1
  244. package/dist/chunk-4P3KTUZH.js.map +0 -1
  245. package/dist/chunk-GEWAIQZ5.js.map +0 -1
  246. package/dist/chunk-IXWODEED.js.map +0 -1
  247. package/dist/chunk-JZCSNEHK.js.map +0 -1
  248. package/dist/chunk-MGGFBZWA.js.map +0 -1
  249. package/dist/chunk-NRDSGLCQ.js.map +0 -1
  250. package/dist/chunk-PE36IF2D.js.map +0 -1
  251. package/dist/chunk-TRSQP3JD.js.map +0 -1
  252. package/dist/chunk-YBQONMH2.js.map +0 -1
  253. package/dist/library-publish-OS3JDW4S.js.map +0 -1
  254. package/dist/open-library-4QSUORI6.js +0 -40
  255. package/dist/open-registry-VCKS3MP5.js +0 -32
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1055](https://github.com/skaile-ai/workspaces/pull/1055) [`3c15671`](https://github.com/skaile-ai/workspaces/commit/3c1567160077b7e0e0ca888c02c2e7bf0bf02358) Thanks [@mortegro](https://github.com/mortegro)! - `validate`, `library index` and `library publish --dry-run` now give one verdict for every asset kind.
8
+
9
+ - `library create flow` and `library create preset` write the `TODO: describe this <kind>.` description when `--description` is missing, as the other kinds do. An unedited flow or preset (the `TODO:` description, `nodes: []`, the example preset item) fails all three commands with exit 1. It was a warning before.
10
+ - A manifest `dependencies:` entry with an invalid publisher fails `publish --dry-run` with the same message as `validate` and `index`.
11
+ - A missing `version` reads as `0.1.0` for all six kinds, and an empty `metadata:` as no metadata. A version that is present but not a string says `set version: 0.1.0` (`set metadata.version: 0.1.0` for skill, prompt and contract) instead of raw schema text.
12
+ - An asset name over 64 characters fails `library create`, `validate`, `index` and `publish --dry-run` with the asset-name rule. `library create skill <300-char name>` no longer ends in `ENAMETOOLONG` with a stack trace. `isValidAssetName` applies the 64-character limit.
13
+ - `library publish --ref` and `library register --ref` exit 1 before the plan when the ref is not a valid git ref name, or is not a branch, tag or commit of the library repo.
14
+ - `references/dependency-standard.md` of the `authoring-skaile-manifests` skill says the asset file's own version wins.
15
+
16
+ - [#1055](https://github.com/skaile-ai/workspaces/pull/1055) [`3c15671`](https://github.com/skaile-ai/workspaces/commit/3c1567160077b7e0e0ca888c02c2e7bf0bf02358) Thanks [@mortegro](https://github.com/mortegro)! - A locked asset is now identified by kind, publisher, name and the library its lock entry names.
17
+
18
+ - `skaile remove skill:@acme/x` no longer deletes the deployed copy of `skill:@mortegro/x` when only the mortegro one was added. It prints `Not deployed or declared` and exits 1. The deployed copy, the lock and `skaile.yaml` stay as they are.
19
+ - `skaile install` keeps a locked library asset on the library its lock entry names, also after `library default <other>` or when another library holds the same ref. `skaile update` and `skaile add` still pick the library by the default rules, and a pin moves an asset to the library that holds it. A move prints `! <ref> moved from <a> to <b>`. `AssetManager.install` takes `moveLibraries` (set by `update`), `InstallResult` has `moved`, and `AssetManager.add` takes `onLibraryMoved`.
20
+ - A `#0.1.0` pin resolves for an `AGENT.md` agent that has no version in its frontmatter, in `skaile add agent:@acme/x#0.1.0` and in a `skaile.yaml` dependency. The pin matches the version in the library manifest, as the lock key does.
21
+
22
+ - [#1055](https://github.com/skaile-ai/workspaces/pull/1055) [`3c15671`](https://github.com/skaile-ai/workspaces/commit/3c1567160077b7e0e0ca888c02c2e7bf0bf02358) Thanks [@mortegro](https://github.com/mortegro)! - The lock changes only when an entry changes, and a hand-edited deployed copy is no longer invisible.
23
+
24
+ - `skaile.lock.yaml` is written in one canonical order (`schema_version` and `locked_at` first, then every key sorted). `add`, `install` and `update` write nothing when only the order or `locked_at` differs, so the first `install` after `add`, and a `library rename` matched by URL, leave a committed lock byte-identical and print no `Lock file written`.
25
+ - `skaile check`, `doctor` and `outdated` exit 1 when a deployed file was edited by hand or an asset folder holds a file the asset does not ship, including a file a harness or agent wrote there after deploy. `skaile install --locked`, `install` and `update` overwrite or remove it and print `Restored <file>` (or `Removed <file> (not part of <ref>)`). `diff` shows the edit and keeps exit 0.
26
+ - `.venv/`, `venv/`, `.pytest_cache/`, `.mypy_cache/`, `.ruff_cache/`, `.idea/`, `.vscode/`, `*.pyo`, `Thumbs.db`, `.env` and `.env.*` in an asset folder are neither deployed nor hashed, so running `pytest` in a library no longer makes the lock drift. The templates `.env.example`, `.env.sample`, `.env.template` and `.env.dist` stay part of the asset. `skaile add` warns once per other `.env` file it finds in an asset folder.
27
+
28
+ - [#1055](https://github.com/skaile-ai/workspaces/pull/1055) [`3c15671`](https://github.com/skaile-ai/workspaces/commit/3c1567160077b7e0e0ca888c02c2e7bf0bf02358) Thanks [@mortegro](https://github.com/mortegro)! - A `skaile.yaml` that does not parse (a duplicate key, bad YAML, a root that is not a mapping) now stops `install`, `update`, `check`, `doctor`, `outdated`, `diff`, `add` and `remove` with `skaile.yaml — parse error: <reason>` and exit 1, before anything is deployed, undeployed or locked. Before, `install` read the broken file as "nothing declared", deleted every deployed asset and emptied the lock. `resolveSkWorkspaceConfig` and `resolveGlobalSkWorkspaceConfig` throw that error instead of returning `{}`. Outside a project, `check`, `doctor`, `outdated`, `install`, `update` and `diff` exit 1 with `No skaile.yaml found. Run skaile init to create one.` and write nothing, as `add` does.
29
+
30
+ - [#1055](https://github.com/skaile-ai/workspaces/pull/1055) [`3c15671`](https://github.com/skaile-ai/workspaces/commit/3c1567160077b7e0e0ca888c02c2e7bf0bf02358) Thanks [@mortegro](https://github.com/mortegro)! - `skaile run` and `skaile repl` end with the driver's error and exit 1 when the omp bridge does not start. Before, they ended on an unsettled top-level await with exit code 13 and no message (p137). `OmpDriver.start()` now rejects when omp exits before it is ready, and the CLI ends any command that has nothing left to wait for with one line and exit 1.
31
+
32
+ `skaile repl` no longer prints log records as raw JSON on stdout. They go to the project's log database; only warnings and errors print, on stderr (p47).
33
+
34
+ The README quick start and tutorial 01 name the optional SDK to install per driver: `@anthropic-ai/claude-agent-sdk` for `claude-sdk`, `@openai/codex-sdk` for `codex` (p138).
35
+
36
+ - [#1055](https://github.com/skaile-ai/workspaces/pull/1055) [`3c15671`](https://github.com/skaile-ai/workspaces/commit/3c1567160077b7e0e0ca888c02c2e7bf0bf02358) Thanks [@mortegro](https://github.com/mortegro)! - A command now ends with the verdict it printed.
37
+
38
+ - `skaile diff <ref>` of a locked asset whose library is not registered, or that has an unresolvable requirement, prints the state problem only and exits 1. It no longer prints `No differences.` first. A plain difference (edited copy, changed library files) still shows the diff and exits 0.
39
+ - `skaile update` ends with `Failed` and exit 1 (never `Done`) when a declared asset is missing, a source pull failed, an agent instance cannot be rendered or a library is not registered. `Nothing to update.` is no longer printed after a failure.
40
+ - `skaile add <ref>` of an asset whose requirement no registered library or source holds exits 1 with `<ref> requires <dep> (not found — register the library that holds it with skaile library init <name> --path <dir>, or remove the requirement from the asset's manifest) — nothing was added`. It was exit 0 with `was added without unresolved dependencies`, which left a project that `check`, `install` and `diff` all fail. `skaile.yaml`, the lock and the deployed files stay as they were. `AssetManager.add` throws instead of warning, so `skaile update <name>`, `skaile manage` and `skaile npx` fail the same way.
41
+
42
+ ### Patch Changes
43
+
44
+ - [#1054](https://github.com/skaile-ai/workspaces/pull/1054) [`87945dd`](https://github.com/skaile-ai/workspaces/commit/87945ddc111f3cdd5c2e354d387170ce2f6ca6a5) Thanks [@Frozen666](https://github.com/Frozen666)! - A flow turn refused by a Claude usage limit that no seat switch could clear no longer triggers an immediate re-prompt into the same limit. The runner holds the flow's automatic turns until something outside it asks for one (a chat message, the platform's continuation prompt, a wake, an approval or input) or the session moves to another seat.
45
+
46
+ - [#1055](https://github.com/skaile-ai/workspaces/pull/1055) [`3c15671`](https://github.com/skaile-ai/workspaces/commit/3c1567160077b7e0e0ca888c02c2e7bf0bf02358) Thanks [@mortegro](https://github.com/mortegro)! - `skaile manage` ticks a library group only when the group's own rows are installed: with the same ref in two libraries, only the group that holds the installed copy gets the tick. `skaile diff preset:<ref>` of an installed preset says `preset has no files of its own` and exits 0, and `skaile why preset:<ref>` finds the preset in the lock instead of printing `not found in lock file`. `AssetManager.diff()` can return the new status `no-files`.
47
+
48
+ - [#1055](https://github.com/skaile-ai/workspaces/pull/1055) [`3c15671`](https://github.com/skaile-ai/workspaces/commit/3c1567160077b7e0e0ca888c02c2e7bf0bf02358) Thanks [@mortegro](https://github.com/mortegro)! - `library rename` of a local library no longer breaks projects that lock it: the rename is recorded, and `install --locked`, `check` and `install` find the library under its new name. `library rename` and `library show` of a library whose folder is gone print the missing-directory line and exit 1, with no raw `ENOENT`. `library pull`, `sync` and `push` print `merge in progress; resolve the conflicts, then git commit` and exit 1 while a merge is unfinished, like they do for a rebase.
49
+
50
+ - [#1055](https://github.com/skaile-ai/workspaces/pull/1055) [`3c15671`](https://github.com/skaile-ai/workspaces/commit/3c1567160077b7e0e0ca888c02c2e7bf0bf02358) Thanks [@mortegro](https://github.com/mortegro)! - Every command now gives the fix text of the shared project state. For a declared ref that no library or source holds, `install`, `install --locked`, `update` and `why` print the `check` fix (`register the library ... or drop it with skaile remove`). They no longer say `run skaile install first` for a ref that `install` cannot resolve. `outdated` no longer advises `skaile install` for a requirement whose locked library is not registered; it names `library init` or `remove`. `run skaile add agent:... first` is printed only when a registered library holds the agent; otherwise the advice names `library init` or the binding to drop. `check`, `doctor` and `outdated` print the requiring asset as `kind:@publisher/name`. `LockGap.asset` of a `requires` gap now carries the publisher.
51
+
3
52
  ## 5.10.0
4
53
 
5
54
  ### Minor Changes
package/README.md CHANGED
@@ -76,6 +76,18 @@ cli (top-level CLI — orchestrates everything below)
76
76
 
77
77
  ## Quick Start
78
78
 
79
+ `skaile run` and `skaile repl` start a driver (a harness), and two of the drivers need an
80
+ optional SDK that `skaile-cli` does not install. Install the one for your driver before the
81
+ first `run` or `repl`:
82
+
83
+ | Driver | Install |
84
+ |---|---|
85
+ | `claude-sdk` (default) | `npm i -D @anthropic-ai/claude-agent-sdk` (with Bun: `bun add @anthropic-ai/claude-agent-sdk`) |
86
+ | `codex` | `npm i -D @openai/codex-sdk` (with Bun: `bun add @openai/codex-sdk`) |
87
+ | `omp` | none; needs the `omp` binary on your `PATH` and a configured model |
88
+
89
+ Without the SDK, `skaile run` exits 1 with `Claude Agent SDK not installed` (or `Codex SDK not installed`).
90
+
79
91
  ```bash
80
92
  # Installed from npm (npm i -D skaile-cli)
81
93
  npx skaile --help # run the skaile CLI
@@ -1,27 +1,27 @@
1
- import { getKnownKinds } from './chunk-SBFW3CJH.js';
2
- import './chunk-7I5VRVDP.js';
3
- import './chunk-MGGFBZWA.js';
1
+ import { getKnownKinds } from './chunk-CAHB6MHA.js';
2
+ import './chunk-TCHRMVTO.js';
3
+ import './chunk-D3B36CYC.js';
4
4
  import './chunk-7RGTAEG6.js';
5
5
  import './chunk-NUELZWCF.js';
6
- import './chunk-3BEY4WK3.js';
7
- import './chunk-GEWAIQZ5.js';
8
- import './chunk-MVQ3Q2HM.js';
6
+ import './chunk-2F5AWQX5.js';
7
+ import './chunk-J4RBUFGM.js';
8
+ import './chunk-COH6FQAG.js';
9
9
  import './chunk-R7FOF242.js';
10
10
  import './chunk-3TXEJN4W.js';
11
- import './chunk-32XKCNCL.js';
12
- import './chunk-2FMEGSBN.js';
11
+ import './chunk-ZCAJZ4B2.js';
12
+ import './chunk-PBBPZYVG.js';
13
13
  import './chunk-4GY63JU6.js';
14
- import { factoryAssetRoots } from './chunk-GFCXNFTW.js';
14
+ import { factoryAssetRoots } from './chunk-EDYHEMJA.js';
15
15
  import './chunk-PMECEZK3.js';
16
16
  import './chunk-5BEFNLOR.js';
17
17
  import './chunk-A2ULN3KX.js';
18
- import { scanRepo } from './chunk-JZCSNEHK.js';
18
+ import { scanRepo } from './chunk-ALEYHUC5.js';
19
19
  import './chunk-L5VSIPQD.js';
20
20
  import './chunk-CPSIPIX7.js';
21
- import './chunk-IXWODEED.js';
21
+ import './chunk-ZPWTOUTK.js';
22
22
  import './chunk-RVRB27AN.js';
23
- import { parseRequires } from './chunk-Y34MSWEZ.js';
24
- import './chunk-4OV5DSBB.js';
23
+ import { parseRequires } from './chunk-SBSA3IQA.js';
24
+ import './chunk-BNMZVPYA.js';
25
25
  import './chunk-ICSCSM5D.js';
26
26
  import './chunk-DALV4HHP.js';
27
27
  import './chunk-MJHSLODD.js';
@@ -51,8 +51,8 @@ function libraryEntryOf(asset) {
51
51
  async function libraryAssets() {
52
52
  const notes = [];
53
53
  try {
54
- const { openLibraryManager } = await import('./open-library-4QSUORI6.js');
55
- const { getKindRegistry } = await import('./open-registry-VCKS3MP5.js');
54
+ const { openLibraryManager } = await import('./open-library-BOSPJVID.js');
55
+ const { getKindRegistry } = await import('./open-registry-4FI7HKET.js');
56
56
  const { scanAuthoringLibraries } = await import('./library/index.js');
57
57
  const { library: index, close } = await openLibraryManager();
58
58
  try {
@@ -85,7 +85,7 @@ async function libraryAssets() {
85
85
  async function storeAssets(projectDir) {
86
86
  const notes = [];
87
87
  try {
88
- const { resolveCatalogSource } = await import('./open-library-4QSUORI6.js');
88
+ const { resolveCatalogSource } = await import('./open-library-BOSPJVID.js');
89
89
  const { source, close } = await resolveCatalogSource({ projectDir });
90
90
  try {
91
91
  const assets = await source.listAssets();
@@ -164,5 +164,5 @@ async function gatherAssetFeeds(am, projectDir) {
164
164
  }
165
165
 
166
166
  export { gatherAssetFeeds };
167
- //# sourceMappingURL=asset-feeds-ELEBTNUS.js.map
168
- //# sourceMappingURL=asset-feeds-ELEBTNUS.js.map
167
+ //# sourceMappingURL=asset-feeds-CXGQIDFR.js.map
168
+ //# sourceMappingURL=asset-feeds-CXGQIDFR.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../cli/src/asset-feeds.ts"],"names":[],"mappings":"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","file":"asset-feeds-ELEBTNUS.js","sourcesContent":["/**\n * asset-feeds.ts — gather installable assets from every feed the manage TUI\n * surfaces.\n *\n * Four feeds, normalized into `CatalogEntry`:\n * - **Project sources** — `skaile.yaml` `sources:` entries (scanned via\n * `AssetManager.search()`; the new `sources:` field is merged into the\n * legacy repositories map in `AssetManager.loadConfig`).\n * - **Local libraries** — user authoring places from `LocalIndex`, read through\n * `scanAuthoringLibraries` (`@skaile/workspaces/library`): the same scan\n * `library index` / `search --local` use, so publishers and refs match them\n * (per-asset `publisher_overrides` honoured), `dev_paths` assets are left out,\n * and a library that fails to scan becomes one note while the rest stay listed.\n * - **Factory assets** — the bundled first-party `factory-assets` tree\n * (`factoryAssetRoots()`), scanned from disk. Always present; no network.\n * - **Remote store** — the configured catalog source when `catalog.url` is\n * not `local`. Failures are non-fatal — they surface as notes.\n */\n\nimport * as path from \"node:path\";\nimport {\n type AssetKind,\n type CatalogEntry,\n factoryAssetRoots,\n parseRequires,\n scanRepo,\n} from \"@skaile/workspaces/core\";\nimport { getKnownKinds } from \"./open-registry.ts\";\nimport type { DiscoveredAsset } from \"@skaile/workspaces/discovery\";\n\n/** One non-fatal note returned to the caller for surfacing in the UI. */\nexport interface FeedNote {\n feed: \"sources\" | \"libraries\" | \"store\" | \"factory\";\n message: string;\n}\n\n/**\n * Which feed an asset came from. This is the top-level grouping axis in the\n * manage TUI (\"where is this skill coming from?\") and is intentionally distinct\n * from `publisher` (asset-intrinsic identity): the same publisher can legitimately\n * appear under more than one origin (e.g. a github repo you added as a `source`\n * that is also listed in the remote `store`).\n */\nexport type AssetOrigin = \"source\" | \"library\" | \"factory\" | \"store\";\n\n/** A catalog entry tagged with the feed it was gathered from. */\nexport interface OriginEntry {\n origin: AssetOrigin;\n entry: CatalogEntry;\n /**\n * Second-level grouping label for the manage tree. Defaults (when unset) to the\n * entry's `publisher`; the source feed sets it to the source's short repo name\n * so the Sources band groups by source — \"which repo did this come from\" — not\n * by the asset-intrinsic publisher.\n */\n group?: string;\n}\n\nexport interface AssetFeedResult {\n entries: OriginEntry[];\n notes: FeedNote[];\n}\n\n/**\n * Map one discovered library asset to the `CatalogEntry` the manage rows read.\n * `publisher` is the bare per-asset publisher (what `search --local` prints),\n * `source` the manifest path. `repo` is left unset: it only feeds the Sources-tree\n * org grouping. `requires` / `dependencies` come from the manifest the way the\n * scanner fills them — string `requires:` refs parsed to `{kind, name}`, a bundle's\n * string `dependencies:` list verbatim.\n */\nfunction libraryEntryOf(asset: DiscoveredAsset): CatalogEntry {\n const { manifest } = asset;\n const nested = (manifest.metadata as Record<string, unknown> | undefined)?.requires;\n const rawRequires = manifest.requires ?? nested;\n const requireRefs =\n typeof rawRequires === \"string\"\n ? rawRequires\n : Array.isArray(rawRequires)\n ? rawRequires.filter((r): r is string => typeof r === \"string\")\n : undefined;\n const deps = manifest.dependencies;\n return {\n name: asset.name,\n kind: asset.kind as AssetKind,\n description: typeof manifest.description === \"string\" ? manifest.description : \"\",\n source: asset.manifestPath,\n publisher: asset.publisher,\n ...(asset.plugin ? { plugin: asset.plugin } : {}),\n version: asset.version,\n requires: requireRefs === undefined ? [] : parseRequires({ requires: requireRefs }),\n dependencies:\n asset.kind === \"bundle\" && Array.isArray(deps)\n ? deps.filter((d): d is string => typeof d === \"string\" && d.length > 0)\n : [],\n };\n}\n\n/**\n * Pull assets from local libraries (the authoring places under\n * `~/.skaile/libraries/<name>/`, not the `~/.skaile/cache/sources/` cache) through\n * `scanAuthoringLibraries`, grouped under the bare library name\n * (`group: <name>`) so the manage TUI shows a clean `<name>` band — no\n * `library:` prefix (mirrors the source feed). Plugin grouping (`entry.plugin`)\n * comes from `DiscoveredAsset.plugin`. A library whose scan fails becomes one\n * `FeedNote`; the outer `catch` covers only opening the index.\n */\nasync function libraryAssets(): Promise<{\n entries: OriginEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n // Lazy: the library subpath pulls in SQLite, which the other feeds never need.\n const { openLibraryManager } = await import(\"./open-library.ts\");\n const { getKindRegistry } = await import(\"./open-registry.ts\");\n const { scanAuthoringLibraries } = await import(\"@skaile/workspaces/library\");\n const { library: index, close } = await openLibraryManager();\n try {\n const entries: OriginEntry[] = [];\n for (const scan of await scanAuthoringLibraries(index, getKindRegistry())) {\n if (scan.error !== undefined) {\n notes.push({ feed: \"libraries\", message: `${scan.library.name}: ${scan.error}` });\n continue;\n }\n for (const asset of scan.assets) {\n entries.push({\n origin: \"library\",\n entry: libraryEntryOf(asset),\n group: scan.library.name,\n });\n }\n }\n return { entries, notes };\n } finally {\n close();\n }\n } catch (err) {\n notes.push({\n feed: \"libraries\",\n message: err instanceof Error ? err.message : String(err),\n });\n return { entries: [], notes };\n }\n}\n\n/**\n * Pull a (best-effort) snapshot of the connected remote store catalog.\n *\n * - Returns no entries when the resolved catalog is local-only or the host\n * is unreachable (the failure becomes a note, not an exception).\n * - Maps `CatalogAsset` → `CatalogEntry`, carrying `publisher`, `repo`, and\n * `category` straight through and using `source = \"store://<id>\"`; per-file\n * `source` paths are not available for remote assets so the canonical ref is\n * a stable placeholder.\n */\nasync function storeAssets(projectDir: string): Promise<{\n entries: CatalogEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n const { resolveCatalogSource } = await import(\"./open-library.ts\");\n const { source, close } = await resolveCatalogSource({ projectDir });\n try {\n const assets = await source.listAssets();\n const entries: CatalogEntry[] = assets.map((a) => ({\n name: a.name,\n kind: (a.kind as AssetKind) ?? \"skill\",\n description: a.description ?? \"\",\n source: `store://${a.id}`,\n publisher: a.publisher,\n repo: a.repo,\n plugin: a.plugin,\n category: a.category,\n version: a.version,\n requires: [],\n dependencies: [],\n }));\n return { entries, notes };\n } finally {\n close();\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // Local-only catalog throws a recognizable message — silence it; absence\n // is the user's choice, not an error.\n if (!/local/i.test(msg)) {\n notes.push({ feed: \"store\", message: msg });\n }\n return { entries: [], notes };\n }\n}\n\n/** The slice of `AssetManager` the source feed needs (kept narrow for tests). */\ninterface AssetManagerLike {\n search: () => Promise<CatalogEntry[]>;\n searchRepoRoots: () => { repoName: string; root: string }[];\n}\n\n/**\n * Project-source feed: leans on `AssetManager.search()`, which merges\n * `skaile.yaml`'s `sources:` field into the repositories map. Plugin grouping\n * (`entry.plugin`) is stamped by the scanner, so entries pass through as-is.\n */\nasync function sourceAssets(am: AssetManagerLike): Promise<OriginEntry[]> {\n // The bundled factory tree is injected into the repositories map as an implicit\n // source, so `am.search()` returns it too. It has its own `factory` origin band,\n // so drop it here — otherwise the same first-party skills list twice under Sources.\n const factoryPrefixes = factoryAssetRoots().map((r) => (r.endsWith(path.sep) ? r : r + path.sep));\n const isFactoryPath = (p: string) =>\n factoryPrefixes.some((fp) => p === fp.slice(0, -1) || p.startsWith(fp));\n\n const all = (await am.search()).filter((e) => !isFactoryPath(e.source));\n const entries: OriginEntry[] = [];\n // Group each source's entries under the source node (its short repo name), not\n // the publisher: under Sources the navigational question is \"which repo did\n // this come from\". Each entry's `source` (absolute manifest path) lives under\n // exactly one declared root, so group by prefix. The cache slug is\n // URL-keyed `github.com/<org>/<repo>` — take the trailing segment.\n for (const { repoName, root } of am.searchRepoRoots()) {\n if (isFactoryPath(root)) continue;\n const prefix = root.endsWith(path.sep) ? root : root + path.sep;\n const owned = all.filter((e) => e.source === root || e.source.startsWith(prefix));\n if (owned.length === 0) continue;\n const sourceName = repoName.split(\"/\").pop() || repoName;\n for (const entry of owned) entries.push({ origin: \"source\", entry, group: sourceName });\n }\n return entries;\n}\n\n/**\n * Factory-asset feed: scan the bundled first-party `factory-assets` tree(s)\n * resolved by `factoryAssetRoots()` (the `SKAILE_FACTORY_ASSETS_DIR` override\n * layer ahead of the bundled tree). Local disk only, no network — the entries are\n * the built-in skills / connectors / bundles that ship with `@skaile/workspaces`.\n * `factoryAssetRoots()` already dedupes, so the env override pointing at the\n * bundled dir collapses to one root.\n */\nasync function factoryAssets(): Promise<{\n entries: CatalogEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n const entries: CatalogEntry[] = [];\n for (const root of factoryAssetRoots()) {\n entries.push(...(await scanRepo(root, \"skaile-factory\", { knownKinds: getKnownKinds() })));\n }\n return { entries, notes };\n } catch (err) {\n notes.push({\n feed: \"factory\",\n message: err instanceof Error ? err.message : String(err),\n });\n return { entries: [], notes };\n }\n}\n\n/** Tag a flat entry list with a single origin. */\nfunction tag(origin: AssetOrigin, entries: CatalogEntry[]): OriginEntry[] {\n return entries.map((entry) => ({ origin, entry }));\n}\n\n/**\n * Run all feeds and return a single normalized result.\n *\n * Feeds run in parallel where possible — the store fetch is the slow one\n * (one HTTP call) and is fired alongside the local library walk. The factory\n * scan is local disk only, so it runs inline.\n */\nexport async function gatherAssetFeeds(\n am: AssetManagerLike,\n projectDir: string,\n): Promise<AssetFeedResult> {\n const [libs, store] = await Promise.all([libraryAssets(), storeAssets(projectDir)]);\n const factory = await factoryAssets();\n const src = await sourceAssets(am);\n return {\n entries: [\n ...src,\n ...libs.entries,\n ...tag(\"factory\", factory.entries),\n ...tag(\"store\", store.entries),\n ],\n notes: [...libs.notes, ...store.notes, ...factory.notes],\n };\n}\n"]}
1
+ {"version":3,"sources":["../cli/src/asset-feeds.ts"],"names":[],"mappings":"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","file":"asset-feeds-CXGQIDFR.js","sourcesContent":["/**\n * asset-feeds.ts — gather installable assets from every feed the manage TUI\n * surfaces.\n *\n * Four feeds, normalized into `CatalogEntry`:\n * - **Project sources** — `skaile.yaml` `sources:` entries (scanned via\n * `AssetManager.search()`; the new `sources:` field is merged into the\n * legacy repositories map in `AssetManager.loadConfig`).\n * - **Local libraries** — user authoring places from `LocalIndex`, read through\n * `scanAuthoringLibraries` (`@skaile/workspaces/library`): the same scan\n * `library index` / `search --local` use, so publishers and refs match them\n * (per-asset `publisher_overrides` honoured), `dev_paths` assets are left out,\n * and a library that fails to scan becomes one note while the rest stay listed.\n * - **Factory assets** — the bundled first-party `factory-assets` tree\n * (`factoryAssetRoots()`), scanned from disk. Always present; no network.\n * - **Remote store** — the configured catalog source when `catalog.url` is\n * not `local`. Failures are non-fatal — they surface as notes.\n */\n\nimport * as path from \"node:path\";\nimport {\n type AssetKind,\n type CatalogEntry,\n factoryAssetRoots,\n parseRequires,\n scanRepo,\n} from \"@skaile/workspaces/core\";\nimport { getKnownKinds } from \"./open-registry.ts\";\nimport type { DiscoveredAsset } from \"@skaile/workspaces/discovery\";\n\n/** One non-fatal note returned to the caller for surfacing in the UI. */\nexport interface FeedNote {\n feed: \"sources\" | \"libraries\" | \"store\" | \"factory\";\n message: string;\n}\n\n/**\n * Which feed an asset came from. This is the top-level grouping axis in the\n * manage TUI (\"where is this skill coming from?\") and is intentionally distinct\n * from `publisher` (asset-intrinsic identity): the same publisher can legitimately\n * appear under more than one origin (e.g. a github repo you added as a `source`\n * that is also listed in the remote `store`).\n */\nexport type AssetOrigin = \"source\" | \"library\" | \"factory\" | \"store\";\n\n/** A catalog entry tagged with the feed it was gathered from. */\nexport interface OriginEntry {\n origin: AssetOrigin;\n entry: CatalogEntry;\n /**\n * Second-level grouping label for the manage tree. Defaults (when unset) to the\n * entry's `publisher`; the source feed sets it to the source's short repo name\n * so the Sources band groups by source — \"which repo did this come from\" — not\n * by the asset-intrinsic publisher.\n */\n group?: string;\n}\n\nexport interface AssetFeedResult {\n entries: OriginEntry[];\n notes: FeedNote[];\n}\n\n/**\n * Map one discovered library asset to the `CatalogEntry` the manage rows read.\n * `publisher` is the bare per-asset publisher (what `search --local` prints),\n * `source` the manifest path. `repo` is left unset: it only feeds the Sources-tree\n * org grouping. `requires` / `dependencies` come from the manifest the way the\n * scanner fills them — string `requires:` refs parsed to `{kind, name}`, a bundle's\n * string `dependencies:` list verbatim.\n */\nfunction libraryEntryOf(asset: DiscoveredAsset): CatalogEntry {\n const { manifest } = asset;\n const nested = (manifest.metadata as Record<string, unknown> | undefined)?.requires;\n const rawRequires = manifest.requires ?? nested;\n const requireRefs =\n typeof rawRequires === \"string\"\n ? rawRequires\n : Array.isArray(rawRequires)\n ? rawRequires.filter((r): r is string => typeof r === \"string\")\n : undefined;\n const deps = manifest.dependencies;\n return {\n name: asset.name,\n kind: asset.kind as AssetKind,\n description: typeof manifest.description === \"string\" ? manifest.description : \"\",\n source: asset.manifestPath,\n publisher: asset.publisher,\n ...(asset.plugin ? { plugin: asset.plugin } : {}),\n version: asset.version,\n requires: requireRefs === undefined ? [] : parseRequires({ requires: requireRefs }),\n dependencies:\n asset.kind === \"bundle\" && Array.isArray(deps)\n ? deps.filter((d): d is string => typeof d === \"string\" && d.length > 0)\n : [],\n };\n}\n\n/**\n * Pull assets from local libraries (the authoring places under\n * `~/.skaile/libraries/<name>/`, not the `~/.skaile/cache/sources/` cache) through\n * `scanAuthoringLibraries`, grouped under the bare library name\n * (`group: <name>`) so the manage TUI shows a clean `<name>` band — no\n * `library:` prefix (mirrors the source feed). Plugin grouping (`entry.plugin`)\n * comes from `DiscoveredAsset.plugin`. A library whose scan fails becomes one\n * `FeedNote`; the outer `catch` covers only opening the index.\n */\nasync function libraryAssets(): Promise<{\n entries: OriginEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n // Lazy: the library subpath pulls in SQLite, which the other feeds never need.\n const { openLibraryManager } = await import(\"./open-library.ts\");\n const { getKindRegistry } = await import(\"./open-registry.ts\");\n const { scanAuthoringLibraries } = await import(\"@skaile/workspaces/library\");\n const { library: index, close } = await openLibraryManager();\n try {\n const entries: OriginEntry[] = [];\n for (const scan of await scanAuthoringLibraries(index, getKindRegistry())) {\n if (scan.error !== undefined) {\n notes.push({ feed: \"libraries\", message: `${scan.library.name}: ${scan.error}` });\n continue;\n }\n for (const asset of scan.assets) {\n entries.push({\n origin: \"library\",\n entry: libraryEntryOf(asset),\n group: scan.library.name,\n });\n }\n }\n return { entries, notes };\n } finally {\n close();\n }\n } catch (err) {\n notes.push({\n feed: \"libraries\",\n message: err instanceof Error ? err.message : String(err),\n });\n return { entries: [], notes };\n }\n}\n\n/**\n * Pull a (best-effort) snapshot of the connected remote store catalog.\n *\n * - Returns no entries when the resolved catalog is local-only or the host\n * is unreachable (the failure becomes a note, not an exception).\n * - Maps `CatalogAsset` → `CatalogEntry`, carrying `publisher`, `repo`, and\n * `category` straight through and using `source = \"store://<id>\"`; per-file\n * `source` paths are not available for remote assets so the canonical ref is\n * a stable placeholder.\n */\nasync function storeAssets(projectDir: string): Promise<{\n entries: CatalogEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n const { resolveCatalogSource } = await import(\"./open-library.ts\");\n const { source, close } = await resolveCatalogSource({ projectDir });\n try {\n const assets = await source.listAssets();\n const entries: CatalogEntry[] = assets.map((a) => ({\n name: a.name,\n kind: (a.kind as AssetKind) ?? \"skill\",\n description: a.description ?? \"\",\n source: `store://${a.id}`,\n publisher: a.publisher,\n repo: a.repo,\n plugin: a.plugin,\n category: a.category,\n version: a.version,\n requires: [],\n dependencies: [],\n }));\n return { entries, notes };\n } finally {\n close();\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // Local-only catalog throws a recognizable message — silence it; absence\n // is the user's choice, not an error.\n if (!/local/i.test(msg)) {\n notes.push({ feed: \"store\", message: msg });\n }\n return { entries: [], notes };\n }\n}\n\n/** The slice of `AssetManager` the source feed needs (kept narrow for tests). */\ninterface AssetManagerLike {\n search: () => Promise<CatalogEntry[]>;\n searchRepoRoots: () => { repoName: string; root: string }[];\n}\n\n/**\n * Project-source feed: leans on `AssetManager.search()`, which merges\n * `skaile.yaml`'s `sources:` field into the repositories map. Plugin grouping\n * (`entry.plugin`) is stamped by the scanner, so entries pass through as-is.\n */\nasync function sourceAssets(am: AssetManagerLike): Promise<OriginEntry[]> {\n // The bundled factory tree is injected into the repositories map as an implicit\n // source, so `am.search()` returns it too. It has its own `factory` origin band,\n // so drop it here — otherwise the same first-party skills list twice under Sources.\n const factoryPrefixes = factoryAssetRoots().map((r) => (r.endsWith(path.sep) ? r : r + path.sep));\n const isFactoryPath = (p: string) =>\n factoryPrefixes.some((fp) => p === fp.slice(0, -1) || p.startsWith(fp));\n\n const all = (await am.search()).filter((e) => !isFactoryPath(e.source));\n const entries: OriginEntry[] = [];\n // Group each source's entries under the source node (its short repo name), not\n // the publisher: under Sources the navigational question is \"which repo did\n // this come from\". Each entry's `source` (absolute manifest path) lives under\n // exactly one declared root, so group by prefix. The cache slug is\n // URL-keyed `github.com/<org>/<repo>` — take the trailing segment.\n for (const { repoName, root } of am.searchRepoRoots()) {\n if (isFactoryPath(root)) continue;\n const prefix = root.endsWith(path.sep) ? root : root + path.sep;\n const owned = all.filter((e) => e.source === root || e.source.startsWith(prefix));\n if (owned.length === 0) continue;\n const sourceName = repoName.split(\"/\").pop() || repoName;\n for (const entry of owned) entries.push({ origin: \"source\", entry, group: sourceName });\n }\n return entries;\n}\n\n/**\n * Factory-asset feed: scan the bundled first-party `factory-assets` tree(s)\n * resolved by `factoryAssetRoots()` (the `SKAILE_FACTORY_ASSETS_DIR` override\n * layer ahead of the bundled tree). Local disk only, no network — the entries are\n * the built-in skills / connectors / bundles that ship with `@skaile/workspaces`.\n * `factoryAssetRoots()` already dedupes, so the env override pointing at the\n * bundled dir collapses to one root.\n */\nasync function factoryAssets(): Promise<{\n entries: CatalogEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n const entries: CatalogEntry[] = [];\n for (const root of factoryAssetRoots()) {\n entries.push(...(await scanRepo(root, \"skaile-factory\", { knownKinds: getKnownKinds() })));\n }\n return { entries, notes };\n } catch (err) {\n notes.push({\n feed: \"factory\",\n message: err instanceof Error ? err.message : String(err),\n });\n return { entries: [], notes };\n }\n}\n\n/** Tag a flat entry list with a single origin. */\nfunction tag(origin: AssetOrigin, entries: CatalogEntry[]): OriginEntry[] {\n return entries.map((entry) => ({ origin, entry }));\n}\n\n/**\n * Run all feeds and return a single normalized result.\n *\n * Feeds run in parallel where possible — the store fetch is the slow one\n * (one HTTP call) and is fired alongside the local library walk. The factory\n * scan is local disk only, so it runs inline.\n */\nexport async function gatherAssetFeeds(\n am: AssetManagerLike,\n projectDir: string,\n): Promise<AssetFeedResult> {\n const [libs, store] = await Promise.all([libraryAssets(), storeAssets(projectDir)]);\n const factory = await factoryAssets();\n const src = await sourceAssets(am);\n return {\n entries: [\n ...src,\n ...libs.entries,\n ...tag(\"factory\", factory.entries),\n ...tag(\"store\", store.entries),\n ],\n notes: [...libs.notes, ...store.notes, ...factory.notes],\n };\n}\n"]}
@@ -1,17 +1,17 @@
1
- export { WORKSPACE_MOUNT_ENV_VAR, deployAll, deployCatalogEntry, findAiAssetsRoot, isUnderWorkspaceMount, resolveFlowSkills, undeployCatalogEntry, workspaceMountDirs } from '../chunk-HOHUEKES.js';
2
- import '../chunk-2FMEGSBN.js';
1
+ export { WORKSPACE_MOUNT_ENV_VAR, deployAll, deployCatalogEntry, findAiAssetsRoot, isUnderWorkspaceMount, resolveFlowSkills, undeployCatalogEntry, workspaceMountDirs } from '../chunk-GCHPUTA3.js';
2
+ import '../chunk-PBBPZYVG.js';
3
3
  import '../chunk-4GY63JU6.js';
4
- import '../chunk-GFCXNFTW.js';
4
+ import '../chunk-EDYHEMJA.js';
5
5
  import '../chunk-PMECEZK3.js';
6
6
  import '../chunk-5BEFNLOR.js';
7
7
  import '../chunk-A2ULN3KX.js';
8
- import '../chunk-JZCSNEHK.js';
8
+ import '../chunk-ALEYHUC5.js';
9
9
  import '../chunk-L5VSIPQD.js';
10
10
  import '../chunk-CPSIPIX7.js';
11
- import '../chunk-IXWODEED.js';
11
+ import '../chunk-ZPWTOUTK.js';
12
12
  import '../chunk-RVRB27AN.js';
13
- import '../chunk-Y34MSWEZ.js';
14
- import '../chunk-4OV5DSBB.js';
13
+ import '../chunk-SBSA3IQA.js';
14
+ import '../chunk-BNMZVPYA.js';
15
15
  import '../chunk-ICSCSM5D.js';
16
16
  import '../chunk-DALV4HHP.js';
17
17
  import '../chunk-MJHSLODD.js';
@@ -1,28 +1,28 @@
1
- export { AssetManager, FACTORY_SOURCE_URL, MissingManifestError, installAgentInstances, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, softDepName } from '../chunk-2JMLDZLP.js';
2
- import '../chunk-3BEY4WK3.js';
3
- import '../chunk-GEWAIQZ5.js';
4
- import '../chunk-MVQ3Q2HM.js';
1
+ export { AssetManager, FACTORY_SOURCE_URL, MissingManifestError, installAgentInstances, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, softDepName } from '../chunk-DZMNFCWB.js';
2
+ import '../chunk-2F5AWQX5.js';
3
+ import '../chunk-J4RBUFGM.js';
4
+ import '../chunk-COH6FQAG.js';
5
5
  import '../chunk-R7FOF242.js';
6
6
  import '../chunk-3TXEJN4W.js';
7
- export { SCAFFOLD_KINDS, createScaffold, deployAll, installAgent, installTargetOf, removeAsset } from '../chunk-PE36IF2D.js';
7
+ export { SCAFFOLD_KINDS, createScaffold, deployAll, installAgent, installTargetOf, removeAsset } from '../chunk-FH7W6TJ4.js';
8
8
  export { BUILT_IN_FRAGMENTS, loadPromptExtensions, resolveFragments } from '../chunk-CGYEHQOX.js';
9
9
  export { appendHistory, clearHistory, getRecentHistory, loadHistory } from '../chunk-KTBKW2FI.js';
10
10
  import '../chunk-UQ6LFBPZ.js';
11
- export { AGENT_RENDERERS, claudeCodeRenderer, codexRenderer, driverTargetSupportsAgents, ompRenderer, renderAgentToFramework } from '../chunk-6HHE63CO.js';
12
- import '../chunk-32XKCNCL.js';
13
- import '../chunk-2FMEGSBN.js';
11
+ export { AGENT_RENDERERS, claudeCodeRenderer, codexRenderer, driverTargetSupportsAgents, ompRenderer, renderAgentToFramework } from '../chunk-HZXUXHIV.js';
12
+ import '../chunk-ZCAJZ4B2.js';
13
+ import '../chunk-PBBPZYVG.js';
14
14
  import '../chunk-4GY63JU6.js';
15
- import '../chunk-GFCXNFTW.js';
15
+ import '../chunk-EDYHEMJA.js';
16
16
  import '../chunk-PMECEZK3.js';
17
17
  import '../chunk-5BEFNLOR.js';
18
18
  import '../chunk-A2ULN3KX.js';
19
- import '../chunk-JZCSNEHK.js';
19
+ import '../chunk-ALEYHUC5.js';
20
20
  import '../chunk-L5VSIPQD.js';
21
21
  import '../chunk-CPSIPIX7.js';
22
- import '../chunk-IXWODEED.js';
22
+ import '../chunk-ZPWTOUTK.js';
23
23
  import '../chunk-RVRB27AN.js';
24
- import '../chunk-Y34MSWEZ.js';
25
- import '../chunk-4OV5DSBB.js';
24
+ import '../chunk-SBSA3IQA.js';
25
+ import '../chunk-BNMZVPYA.js';
26
26
  import '../chunk-ICSCSM5D.js';
27
27
  import '../chunk-DALV4HHP.js';
28
28
  import '../chunk-MJHSLODD.js';
@@ -1,20 +1,20 @@
1
- export { SCAFFOLD_KINDS, canonicalEntryRef, createScaffold, deployAll, deployAsset, diffDeployedAgent, installTargetOf, removeAsset } from '../chunk-PE36IF2D.js';
1
+ export { SCAFFOLD_KINDS, canonicalEntryRef, createScaffold, deployAll, deployAsset, deployedAssetDrift, diffDeployedAgent, installTargetOf, removeAsset } from '../chunk-FH7W6TJ4.js';
2
2
  import '../chunk-CGYEHQOX.js';
3
- import '../chunk-6HHE63CO.js';
4
- import '../chunk-32XKCNCL.js';
5
- import '../chunk-2FMEGSBN.js';
3
+ import '../chunk-HZXUXHIV.js';
4
+ import '../chunk-ZCAJZ4B2.js';
5
+ import '../chunk-PBBPZYVG.js';
6
6
  import '../chunk-4GY63JU6.js';
7
- import '../chunk-GFCXNFTW.js';
7
+ import '../chunk-EDYHEMJA.js';
8
8
  import '../chunk-PMECEZK3.js';
9
9
  import '../chunk-5BEFNLOR.js';
10
10
  import '../chunk-A2ULN3KX.js';
11
- import '../chunk-JZCSNEHK.js';
11
+ import '../chunk-ALEYHUC5.js';
12
12
  import '../chunk-L5VSIPQD.js';
13
13
  import '../chunk-CPSIPIX7.js';
14
- import '../chunk-IXWODEED.js';
14
+ import '../chunk-ZPWTOUTK.js';
15
15
  import '../chunk-RVRB27AN.js';
16
- import '../chunk-Y34MSWEZ.js';
17
- import '../chunk-4OV5DSBB.js';
16
+ import '../chunk-SBSA3IQA.js';
17
+ import '../chunk-BNMZVPYA.js';
18
18
  import '../chunk-ICSCSM5D.js';
19
19
  import '../chunk-DALV4HHP.js';
20
20
  import '../chunk-MJHSLODD.js';
@@ -1,18 +1,18 @@
1
- export { AGENT_RENDERERS, CODEX_IDENTITY_DIR, claudeCodeRenderer, codexRenderer, driverTargetSupportsAgents, ompRenderer, renderAgentToFramework } from '../chunk-6HHE63CO.js';
2
- import '../chunk-32XKCNCL.js';
3
- import '../chunk-2FMEGSBN.js';
1
+ export { AGENT_RENDERERS, CODEX_IDENTITY_DIR, claudeCodeRenderer, codexRenderer, driverTargetSupportsAgents, ompRenderer, renderAgentToFramework } from '../chunk-HZXUXHIV.js';
2
+ import '../chunk-ZCAJZ4B2.js';
3
+ import '../chunk-PBBPZYVG.js';
4
4
  import '../chunk-4GY63JU6.js';
5
- import '../chunk-GFCXNFTW.js';
5
+ import '../chunk-EDYHEMJA.js';
6
6
  import '../chunk-PMECEZK3.js';
7
7
  import '../chunk-5BEFNLOR.js';
8
8
  import '../chunk-A2ULN3KX.js';
9
- import '../chunk-JZCSNEHK.js';
9
+ import '../chunk-ALEYHUC5.js';
10
10
  import '../chunk-L5VSIPQD.js';
11
11
  import '../chunk-CPSIPIX7.js';
12
- import '../chunk-IXWODEED.js';
12
+ import '../chunk-ZPWTOUTK.js';
13
13
  import '../chunk-RVRB27AN.js';
14
- import '../chunk-Y34MSWEZ.js';
15
- import '../chunk-4OV5DSBB.js';
14
+ import '../chunk-SBSA3IQA.js';
15
+ import '../chunk-BNMZVPYA.js';
16
16
  import '../chunk-ICSCSM5D.js';
17
17
  import '../chunk-DALV4HHP.js';
18
18
  import '../chunk-MJHSLODD.js';
@@ -79,6 +79,15 @@ export declare function softDepName(ref: string): string;
79
79
  * @internal Exported for unit tests; not part of the stable public surface.
80
80
  */
81
81
  export declare function parseRefTolerant(ref: string): AssetRef | null;
82
+ /** A locked asset that now resolves from another library than its lock entry named. */
83
+ export interface LibraryMove {
84
+ /** `kind:@publisher/name` (no version). */
85
+ ref: string;
86
+ /** Library name the lock entry recorded. */
87
+ from: string;
88
+ /** Library name the asset resolved from now. */
89
+ to: string;
90
+ }
82
91
  /**
83
92
  * Reconciliation state of a declared dependency relative to the lock + disk.
84
93
  * `invalid` flags a `dependencies:` entry that isn't a parseable canonical ref —
@@ -204,6 +213,15 @@ export interface RepoStatusInfo {
204
213
  /** Error message when status check failed. */
205
214
  error?: string;
206
215
  }
216
+ /** One deployed copy `install` made equal to its locked bytes again. */
217
+ export interface RestoredAsset {
218
+ /** Canonical ref of the asset. */
219
+ ref: string;
220
+ /** Deployed files whose hand edit was overwritten (project-relative POSIX paths). */
221
+ restored: string[];
222
+ /** Files the asset does not ship that were deleted from its deployed directory. */
223
+ removed: string[];
224
+ }
207
225
  /** One asset `install` moved from one locked version to another. */
208
226
  export interface ReplacedAsset {
209
227
  /** `kind:@publisher/name`, no version. */
@@ -246,12 +264,24 @@ export interface InstallResult {
246
264
  * content. A re-lock can happen with nothing to deploy. Absent when none changed.
247
265
  */
248
266
  relocked?: string[];
267
+ /**
268
+ * Library-origin assets whose lock entry now names another library than before. `install`
269
+ * keeps a locked asset on its library; only `update`, a pin, or a locked library that no
270
+ * longer holds the asset moves it. Absent when none moved.
271
+ */
272
+ moved?: LibraryMove[];
249
273
  /**
250
274
  * Assets whose locked version `install` replaced with another version of the same asset
251
275
  * (`ref` is `kind:@publisher/name`). Not part of {@link InstallResult.removed}: nothing
252
276
  * left the project. Absent when none changed.
253
277
  */
254
278
  replaced?: ReplacedAsset[];
279
+ /**
280
+ * Deployed copies `install` made equal to their locked bytes again: a file edited by hand
281
+ * (`restored`) or an extra file in the asset directory (`removed`), both as project-relative
282
+ * POSIX paths. Absent when every deployed copy already matched.
283
+ */
284
+ restored?: RestoredAsset[];
255
285
  /** Whether `skaile.lock.yaml` was written or updated. */
256
286
  lockWritten: boolean;
257
287
  /**
@@ -336,6 +366,8 @@ export interface OutdatedEntry {
336
366
  * - `not-deployed` — the asset resolves, but there is no deployed copy to compare.
337
367
  * - `identical` — the deployed copy matches the source.
338
368
  * - `differs` — the deployed copy differs; `diff` carries the unified diff.
369
+ * - `no-files` — the asset kind has no files of its own (a preset: its items are the assets to
370
+ * compare) and the lock records it.
339
371
  *
340
372
  * @docLink packages/asset-manager/concepts#asset-manager
341
373
  */
@@ -345,6 +377,8 @@ export type DiffResult = {
345
377
  status: "not-deployed";
346
378
  } | {
347
379
  status: "identical";
380
+ } | {
381
+ status: "no-files";
348
382
  } | {
349
383
  status: "differs";
350
384
  diff: string;
@@ -409,10 +443,10 @@ export interface DepIssue {
409
443
  * @docLink packages/asset-manager/concepts#asset-manager
410
444
  */
411
445
  export interface LockGap {
412
- type: "declared" | "invalid" | "drift" | "pin" | "requires" | "unresolved" | "library" | "incomplete" | "content" | "agent";
446
+ type: "declared" | "invalid" | "drift" | "pin" | "requires" | "unresolved" | "library" | "incomplete" | "content" | "modified" | "agent";
413
447
  /** The ref to act on: the declared ref, the unmet dependency `kind:name`, or the asset itself. */
414
448
  ref: string;
415
- /** Set on a `requires` gap: the `kind:name` of the asset whose requirement is unmet. */
449
+ /** Set on a `requires` gap: the requiring asset, `kind:@publisher/name` (`kind:name` when the lock knows no publisher). */
416
450
  asset?: string;
417
451
  /** What is wrong, as a phrase that follows `ref` (e.g. `is declared but not locked — run …`). */
418
452
  reason: string;
@@ -679,6 +713,9 @@ export declare class AssetManager {
679
713
  * builds an error hint must not warn).
680
714
  * @param opts.library - Resolve only from this library (the one a lock entry names), not
681
715
  * from every registered one. Never warns: no choice is made between libraries.
716
+ * @param opts.lockedLibraries - `kind:publisher/name` → the library its lock entry names
717
+ * ({@link AssetManager.lockedLibraryNames}). A ref listed here resolves from that library
718
+ * when it holds a match, whatever the default library is.
682
719
  * @returns the matched deploy entries, the set of `missing` refs covered, and
683
720
  * each entry's originating library name.
684
721
  */
@@ -967,11 +1004,15 @@ export declare class AssetManager {
967
1004
  * @param opts.link - When `true`, symlink local-path assets instead of copying them
968
1005
  * (the author dev-loop). Machine-local / not for committing; a no-op for
969
1006
  * store/factory sources. Defaults to copy.
1007
+ * @param opts.moveLibraries - When `true` (`skaile update`), a locked library asset is
1008
+ * re-resolved from every library and may move to another one; {@link InstallResult.moved}
1009
+ * lists the moves. Without it a locked asset stays on the library its lock entry names.
970
1010
  * @returns {@link InstallResult} summarising what was deployed, what was missing, and any collisions.
971
1011
  */
972
1012
  install(opts?: {
973
1013
  locked?: boolean;
974
1014
  link?: boolean;
1015
+ moveLibraries?: boolean;
975
1016
  }): Promise<InstallResult>;
976
1017
  /**
977
1018
  * Extend `kept` (see {@link keptLockEntries}) with every previous lock entry a kept asset
@@ -1026,6 +1067,13 @@ export declare class AssetManager {
1026
1067
  * to pull every connector's deps). Future: add a flag to opt in.
1027
1068
  */
1028
1069
  private installRuntimeAssetDeps;
1070
+ /**
1071
+ * Give every ref `install` could not resolve, and that has no hint yet, the fix the shared
1072
+ * {@link AssetManager.projectState} names for it (a declared ref no library or source holds,
1073
+ * a requirement nothing holds). Runs after the deploy, so a requirer is known by then.
1074
+ * Mutates `hints`: ` <reason>` follows the ref in the `Missing:` line.
1075
+ */
1076
+ private adviseMissing;
1029
1077
  private installLocked;
1030
1078
  /**
1031
1079
  * Parse the ref `add` was given. A ref the grammar rejects fails with the parser's message
@@ -1055,6 +1103,8 @@ export declare class AssetManager {
1055
1103
  * store/factory sources. Defaults to copy.
1056
1104
  * @param opts.onLibraryOrigin - Called once per deployed library-origin asset with its
1057
1105
  * canonical ref and the name of the library it was resolved from.
1106
+ * @param opts.onLibraryMoved - Called once per asset whose lock entry named another library
1107
+ * than the one this add resolved it from.
1058
1108
  * @param opts.onPresets - Called once with the presets expanded into this add (the
1059
1109
  * added preset and any it nests); a library-held preset names its library.
1060
1110
  * @returns Array of asset refs that were deployed in this call.
@@ -1064,9 +1114,13 @@ export declare class AssetManager {
1064
1114
  add(ref: string, opts?: {
1065
1115
  link?: boolean;
1066
1116
  onLibraryOrigin?: (deployedRef: string, library: string) => void;
1117
+ /** Called per already-locked asset this add moved to another library than its lock entry named. */
1118
+ onLibraryMoved?: (move: LibraryMove) => void;
1067
1119
  onPresets?: (presets: PresetExpansion[]) => void;
1068
1120
  /** Called per symlink an asset's copy deploy leaves out (`ref`, path under the asset dir). */
1069
1121
  onSkippedSymlink?: (ref: string, path: string) => void;
1122
+ /** Called per `.env` file in an asset's directory that a copy deploy leaves out. */
1123
+ onEnvFile?: (ref: string, path: string) => void;
1070
1124
  }): Promise<string[]>;
1071
1125
  /**
1072
1126
  * Report the body-link **soft dependencies** of the given assets that are not
@@ -1238,6 +1292,12 @@ export declare class AssetManager {
1238
1292
  * when `target` is not locked or nothing else requires it.
1239
1293
  */
1240
1294
  private requiredByOthers;
1295
+ /**
1296
+ * Publishers under which the lock or `skaile.yaml` track `kind:name`. A deployed dir carries
1297
+ * no publisher, so this is what says whose copy it is. `undefined` stands for a
1298
+ * publisher-less declaration.
1299
+ */
1300
+ private trackedPublishers;
1241
1301
  /** Undeploy `parsed` from every target harness and drop its declaration and lock entry. */
1242
1302
  private removeResolved;
1243
1303
  /**
@@ -1423,6 +1483,14 @@ export declare class AssetManager {
1423
1483
  * instead. `[]` when the asset is not in the lock file.
1424
1484
  */
1425
1485
  why(ref: string): Promise<string[]>;
1486
+ /**
1487
+ * The {@link AssetManager.why} chain of a preset. A preset is never a lock asset: its record
1488
+ * is the lock's `presets` slice. Declared in `skaile.yaml` it is `direct`; one only a declared
1489
+ * preset nests is traced through the presets that list it.
1490
+ *
1491
+ * @returns `[]` when the lock does not record the preset.
1492
+ */
1493
+ private whyPreset;
1426
1494
  /**
1427
1495
  * List installed assets that have a newer upstream available.
1428
1496
  *
@@ -1570,6 +1638,18 @@ export declare class AssetManager {
1570
1638
  * @returns The {@link ProjectState}; `gaps` is empty when the project is as declared and locked.
1571
1639
  */
1572
1640
  projectState(): Promise<ProjectState>;
1641
+ /**
1642
+ * Why the `agent:` ref of agent instance `id` binds to nothing, as the phrase that follows
1643
+ * the ref in a {@link LockGap}; see {@link AssetManager.unboundAgentAdvice}.
1644
+ */
1645
+ private unboundAgentReason;
1646
+ /**
1647
+ * What is wrong with an `agent:` ref bound by an agent instance and what to do (`lead`, then
1648
+ * `advice`). `skaile add` is named only when a registered library or source holds the agent
1649
+ * and `add` takes the ref (it needs a publisher); otherwise the user registers the library
1650
+ * that holds it, writes the publisher, or drops the binding.
1651
+ */
1652
+ private unboundAgentAdvice;
1573
1653
  /** @deprecated Use `(await projectState()).gaps`; removed in the next major. */
1574
1654
  lockGaps(): Promise<LockGap[]>;
1575
1655
  /**
@@ -1588,6 +1668,27 @@ export declare class AssetManager {
1588
1668
  * @param named - `kind:name` identities already reported; they are skipped.
1589
1669
  */
1590
1670
  private libraryOriginGaps;
1671
+ /**
1672
+ * The {@link RestoredAsset} rows for the drifted copies (see {@link lockedCopyDrift}) a
1673
+ * deploy just wrote again: those whose ref is among the `deployed` canonical refs.
1674
+ */
1675
+ private restoredCopies;
1676
+ /**
1677
+ * Locked assets whose deployed copy differs from the bytes the lock covers: a file edited by
1678
+ * hand, or a file the asset does not ship. One row per asset, `ref` being `kind:@publisher/name`
1679
+ * and `key` its lock key. The one comparison behind the `modified` gap and the `Restored` lines
1680
+ * of `install`.
1681
+ *
1682
+ * - A library-origin asset is compared with its library's files, but only while those equal the
1683
+ * locked hash (changed library content is the `content` gap's business), both modified and
1684
+ * extra files.
1685
+ * - A source asset is compared with the per-file hashes the lock records (modified files only:
1686
+ * the lock lists what the source covers, not what the deploy copies).
1687
+ *
1688
+ * An agent (rendered, not copied), a `--link` deploy, an asset with a configured patch, and a
1689
+ * copy that is missing are not compared: other gaps cover them. Project mode only.
1690
+ */
1691
+ private lockedCopyDrift;
1591
1692
  /**
1592
1693
  * Locked assets (declared or required by one) whose deployed copy is gone: `skaile install`
1593
1694
  * restores them. Same deployability rule as {@link AssetManager.listDeclared}'s `drift`.