@skaile/workspaces 6.4.0 → 6.6.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 (405) hide show
  1. package/CHANGELOG.md +58 -1
  2. package/README.md +4 -0
  3. package/dist/ai-sdk.js +55 -25
  4. package/dist/ai-sdk.js.map +1 -1
  5. package/dist/app-sdk/index.js +1 -1
  6. package/dist/{asset-feeds-UJSYGKCX.js → asset-feeds-WQ6YQPHV.js} +22 -22
  7. package/dist/{asset-feeds-UJSYGKCX.js.map → asset-feeds-WQ6YQPHV.js.map} +1 -1
  8. package/dist/asset-manager/catalog-deployer.js +8 -8
  9. package/dist/asset-manager/index.js +14 -14
  10. package/dist/asset-manager/installer.js +10 -10
  11. package/dist/asset-manager/renderers.js +9 -9
  12. package/dist/asset-manager/src/index.d.ts +114 -12
  13. package/dist/asset-manager/src/index.d.ts.map +1 -1
  14. package/dist/asset-manager/src/installer.d.ts +6 -0
  15. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  16. package/dist/bridge/harnesses/claude-sdk.js +24 -19
  17. package/dist/bridge/harnesses/claude-sdk.js.map +1 -1
  18. package/dist/bridge/harnesses/codex.js +38 -36
  19. package/dist/bridge/harnesses/codex.js.map +1 -1
  20. package/dist/bridge/harnesses/continue.js +12 -13
  21. package/dist/bridge/harnesses/continue.js.map +1 -1
  22. package/dist/bridge/harnesses/echo.js +5 -6
  23. package/dist/bridge/harnesses/echo.js.map +1 -1
  24. package/dist/bridge/harnesses/gemini.js +9 -10
  25. package/dist/bridge/harnesses/goose.js +12 -13
  26. package/dist/bridge/harnesses/goose.js.map +1 -1
  27. package/dist/bridge/harnesses/omp.js +17 -12
  28. package/dist/bridge/harnesses/omp.js.map +1 -1
  29. package/dist/bridge/harnesses/opencode.js +12 -13
  30. package/dist/bridge/harnesses/opencode.js.map +1 -1
  31. package/dist/bridge/harnesses/qwen.js +9 -10
  32. package/dist/bridge/harnesses/qwen.js.map +1 -1
  33. package/dist/bridge/index.js +20 -21
  34. package/dist/bridge/src/ai-sdk.d.ts +0 -2
  35. package/dist/bridge/src/ai-sdk.d.ts.map +1 -1
  36. package/dist/bridge/src/codex/login-fallback.d.ts +39 -0
  37. package/dist/bridge/src/codex/login-fallback.d.ts.map +1 -0
  38. package/dist/bridge/src/error-classifier.d.ts +6 -0
  39. package/dist/bridge/src/error-classifier.d.ts.map +1 -1
  40. package/dist/bridge/src/harnesses/claude-sdk.d.ts.map +1 -1
  41. package/dist/bridge/src/harnesses/codex.d.ts +0 -6
  42. package/dist/bridge/src/harnesses/codex.d.ts.map +1 -1
  43. package/dist/bridge/src/harnesses/omp.d.ts.map +1 -1
  44. package/dist/bridge/src/index.d.ts +1 -0
  45. package/dist/bridge/src/index.d.ts.map +1 -1
  46. package/dist/{chunk-GTMANMBZ.js → chunk-2M3VLKT2.js} +3 -3
  47. package/dist/{chunk-GTMANMBZ.js.map → chunk-2M3VLKT2.js.map} +1 -1
  48. package/dist/{chunk-2WOA3TKK.js → chunk-2TLPC6TQ.js} +34 -19
  49. package/dist/chunk-2TLPC6TQ.js.map +1 -0
  50. package/dist/{chunk-O7KAQQAI.js → chunk-4BFEPZ6J.js} +4 -4
  51. package/dist/{chunk-O7KAQQAI.js.map → chunk-4BFEPZ6J.js.map} +1 -1
  52. package/dist/{chunk-TPQKFX6X.js → chunk-4J7JQX4G.js} +4 -4
  53. package/dist/{chunk-TPQKFX6X.js.map → chunk-4J7JQX4G.js.map} +1 -1
  54. package/dist/{chunk-6OHZUUR7.js → chunk-5DE3DGVR.js} +11 -5
  55. package/dist/chunk-5DE3DGVR.js.map +1 -0
  56. package/dist/{chunk-Q4XWCVFA.js → chunk-5ETYBC2X.js} +8 -8
  57. package/dist/{chunk-Q4XWCVFA.js.map → chunk-5ETYBC2X.js.map} +1 -1
  58. package/dist/{chunk-ZWCGJYR7.js → chunk-5XHQBCB5.js} +3 -3
  59. package/dist/{chunk-ZWCGJYR7.js.map → chunk-5XHQBCB5.js.map} +1 -1
  60. package/dist/{chunk-JSWMRYLM.js → chunk-65UAC3ZR.js} +31 -7
  61. package/dist/chunk-65UAC3ZR.js.map +1 -0
  62. package/dist/{chunk-UBLZALKP.js → chunk-6A6HE5LW.js} +3 -3
  63. package/dist/{chunk-UBLZALKP.js.map → chunk-6A6HE5LW.js.map} +1 -1
  64. package/dist/{chunk-ABVWUM2E.js → chunk-6ARPZHOV.js} +47 -25
  65. package/dist/chunk-6ARPZHOV.js.map +1 -0
  66. package/dist/{chunk-TDKZL5ZC.js → chunk-6RHWTZPT.js} +4 -4
  67. package/dist/{chunk-TDKZL5ZC.js.map → chunk-6RHWTZPT.js.map} +1 -1
  68. package/dist/{chunk-6WQGJF65.js → chunk-6SXSVKQY.js} +88 -17
  69. package/dist/chunk-6SXSVKQY.js.map +1 -0
  70. package/dist/{chunk-YFGXYQW4.js → chunk-7I5PNB2G.js} +3 -3
  71. package/dist/{chunk-YFGXYQW4.js.map → chunk-7I5PNB2G.js.map} +1 -1
  72. package/dist/{serve-preflight-NPWI4MV6.js → chunk-7PVGND4J.js} +30 -61
  73. package/dist/chunk-7PVGND4J.js.map +1 -0
  74. package/dist/{chunk-P7EL7QRD.js → chunk-7SJHSGUV.js} +34 -20
  75. package/dist/chunk-7SJHSGUV.js.map +1 -0
  76. package/dist/{chunk-VSCLUPGZ.js → chunk-AQNW2FET.js} +289 -44
  77. package/dist/chunk-AQNW2FET.js.map +1 -0
  78. package/dist/{chunk-45KLCFQB.js → chunk-B6N653ZG.js} +6 -6
  79. package/dist/{chunk-45KLCFQB.js.map → chunk-B6N653ZG.js.map} +1 -1
  80. package/dist/{chunk-6UP2EDFN.js → chunk-BSMW3PX2.js} +313 -4
  81. package/dist/chunk-BSMW3PX2.js.map +1 -0
  82. package/dist/{chunk-HTGTNN2B.js → chunk-CMXDFTA2.js} +3 -3
  83. package/dist/{chunk-HTGTNN2B.js.map → chunk-CMXDFTA2.js.map} +1 -1
  84. package/dist/{chunk-YJNE4V2M.js → chunk-DI6J2PJB.js} +70 -37
  85. package/dist/chunk-DI6J2PJB.js.map +1 -0
  86. package/dist/{chunk-V4OXHEWY.js → chunk-DS6UUCFG.js} +4 -4
  87. package/dist/{chunk-V4OXHEWY.js.map → chunk-DS6UUCFG.js.map} +1 -1
  88. package/dist/{chunk-U6S5CXKB.js → chunk-E2EC6SAX.js} +4 -4
  89. package/dist/{chunk-U6S5CXKB.js.map → chunk-E2EC6SAX.js.map} +1 -1
  90. package/dist/{chunk-TF5CWJQZ.js → chunk-EPXZQIC6.js} +23 -80
  91. package/dist/chunk-EPXZQIC6.js.map +1 -0
  92. package/dist/{chunk-6X3GDPCB.js → chunk-F4CZQD3T.js} +3 -4
  93. package/dist/chunk-F4CZQD3T.js.map +1 -0
  94. package/dist/{chunk-VZU67OKK.js → chunk-G5SYFFMD.js} +2 -2
  95. package/dist/{chunk-VZU67OKK.js.map → chunk-G5SYFFMD.js.map} +1 -1
  96. package/dist/{chunk-VV2DJT4I.js → chunk-GNUA7XT2.js} +4 -3
  97. package/dist/chunk-GNUA7XT2.js.map +1 -0
  98. package/dist/{chunk-E237FGGX.js → chunk-GTAHU4N4.js} +4 -4
  99. package/dist/{chunk-E237FGGX.js.map → chunk-GTAHU4N4.js.map} +1 -1
  100. package/dist/{chunk-SISUT7VR.js → chunk-GTGWRKMJ.js} +7 -7
  101. package/dist/{chunk-SISUT7VR.js.map → chunk-GTGWRKMJ.js.map} +1 -1
  102. package/dist/{chunk-BX7PSWJA.js → chunk-HGZN6JLP.js} +4 -4
  103. package/dist/{chunk-BX7PSWJA.js.map → chunk-HGZN6JLP.js.map} +1 -1
  104. package/dist/{chunk-L45IHRDH.js → chunk-HQAPUPBE.js} +3 -3
  105. package/dist/{chunk-L45IHRDH.js.map → chunk-HQAPUPBE.js.map} +1 -1
  106. package/dist/{chunk-L4OYPFLB.js → chunk-I5IF3JCG.js} +4 -4
  107. package/dist/{chunk-L4OYPFLB.js.map → chunk-I5IF3JCG.js.map} +1 -1
  108. package/dist/{chunk-IYZAJ2J2.js → chunk-J262X4JU.js} +36 -36
  109. package/dist/chunk-J262X4JU.js.map +1 -0
  110. package/dist/{chunk-WENTJ5KP.js → chunk-J4WKNJHO.js} +6 -6
  111. package/dist/{chunk-WENTJ5KP.js.map → chunk-J4WKNJHO.js.map} +1 -1
  112. package/dist/{chunk-3ENE6ZOF.js → chunk-JIQUF3X2.js} +9 -8
  113. package/dist/chunk-JIQUF3X2.js.map +1 -0
  114. package/dist/{chunk-TGB4E5Z6.js → chunk-JRVQV7WC.js} +414 -95
  115. package/dist/chunk-JRVQV7WC.js.map +1 -0
  116. package/dist/{chunk-BOS7P2Y4.js → chunk-KSH5CFQS.js} +3 -3
  117. package/dist/{chunk-BOS7P2Y4.js.map → chunk-KSH5CFQS.js.map} +1 -1
  118. package/dist/{chunk-UUKCPPTQ.js → chunk-KSUT5KAE.js} +3 -3
  119. package/dist/{chunk-UUKCPPTQ.js.map → chunk-KSUT5KAE.js.map} +1 -1
  120. package/dist/{chunk-DF5WJC3Q.js → chunk-LBJ4M5J2.js} +4 -4
  121. package/dist/{chunk-DF5WJC3Q.js.map → chunk-LBJ4M5J2.js.map} +1 -1
  122. package/dist/{chunk-GBXQFJ4G.js → chunk-MMOWIRHP.js} +310 -175
  123. package/dist/chunk-MMOWIRHP.js.map +1 -0
  124. package/dist/{chunk-G63KOHFS.js → chunk-MXI3XWV6.js} +4 -4
  125. package/dist/{chunk-G63KOHFS.js.map → chunk-MXI3XWV6.js.map} +1 -1
  126. package/dist/{chunk-ACBL7X62.js → chunk-N2PBAXAA.js} +3 -3
  127. package/dist/{chunk-ACBL7X62.js.map → chunk-N2PBAXAA.js.map} +1 -1
  128. package/dist/{chunk-5NHBLKKU.js → chunk-O7QZI6MQ.js} +3 -3
  129. package/dist/{chunk-5NHBLKKU.js.map → chunk-O7QZI6MQ.js.map} +1 -1
  130. package/dist/{chunk-U3SXCVR7.js → chunk-OY22B7E2.js} +4 -4
  131. package/dist/{chunk-U3SXCVR7.js.map → chunk-OY22B7E2.js.map} +1 -1
  132. package/dist/{chunk-C7TQARGC.js → chunk-PTJTOPE5.js} +3 -3
  133. package/dist/{chunk-C7TQARGC.js.map → chunk-PTJTOPE5.js.map} +1 -1
  134. package/dist/{chunk-HSF665NV.js → chunk-RAU5QPI6.js} +5 -5
  135. package/dist/{chunk-HSF665NV.js.map → chunk-RAU5QPI6.js.map} +1 -1
  136. package/dist/{chunk-RKI35EAN.js → chunk-RHCEX2EV.js} +3 -3
  137. package/dist/{chunk-RKI35EAN.js.map → chunk-RHCEX2EV.js.map} +1 -1
  138. package/dist/{chunk-76WSWPOB.js → chunk-SCRYXAHH.js} +15 -6
  139. package/dist/chunk-SCRYXAHH.js.map +1 -0
  140. package/dist/{chunk-DKXNKFKP.js → chunk-SGI5MRKP.js} +75 -3
  141. package/dist/chunk-SGI5MRKP.js.map +1 -0
  142. package/dist/{chunk-24D7IW5O.js → chunk-SHTXMERQ.js} +7 -8
  143. package/dist/chunk-SHTXMERQ.js.map +1 -0
  144. package/dist/{chunk-IZV3HDVG.js → chunk-SZKCE7EC.js} +5 -5
  145. package/dist/{chunk-IZV3HDVG.js.map → chunk-SZKCE7EC.js.map} +1 -1
  146. package/dist/{chunk-UAOHR6AL.js → chunk-TCH5UDKT.js} +4 -4
  147. package/dist/{chunk-UAOHR6AL.js.map → chunk-TCH5UDKT.js.map} +1 -1
  148. package/dist/{chunk-UVTN4O7N.js → chunk-TUFNY6OD.js} +33 -10
  149. package/dist/chunk-TUFNY6OD.js.map +1 -0
  150. package/dist/{chunk-PTBX55QF.js → chunk-U3UDOX6I.js} +4 -4
  151. package/dist/{chunk-PTBX55QF.js.map → chunk-U3UDOX6I.js.map} +1 -1
  152. package/dist/{chunk-BUU2DLPC.js → chunk-USSP43U3.js} +3 -3
  153. package/dist/{chunk-BUU2DLPC.js.map → chunk-USSP43U3.js.map} +1 -1
  154. package/dist/{chunk-IZQOO6MN.js → chunk-V5KG6CCV.js} +2 -2
  155. package/dist/{chunk-IZQOO6MN.js.map → chunk-V5KG6CCV.js.map} +1 -1
  156. package/dist/{chunk-CK3CJSRY.js → chunk-VJRL6ZK6.js} +4 -4
  157. package/dist/{chunk-CK3CJSRY.js.map → chunk-VJRL6ZK6.js.map} +1 -1
  158. package/dist/{chunk-76FLBODK.js → chunk-VT6G5AJV.js} +10 -7
  159. package/dist/chunk-VT6G5AJV.js.map +1 -0
  160. package/dist/{chunk-EXRQKOY6.js → chunk-VXYZ5M7Z.js} +83 -34
  161. package/dist/chunk-VXYZ5M7Z.js.map +1 -0
  162. package/dist/{chunk-QSIFEHSN.js → chunk-WW5NAU6N.js} +3 -3
  163. package/dist/{chunk-QSIFEHSN.js.map → chunk-WW5NAU6N.js.map} +1 -1
  164. package/dist/chunk-XD3RYAMR.js +83 -0
  165. package/dist/chunk-XD3RYAMR.js.map +1 -0
  166. package/dist/{chunk-HXZ3FQQN.js → chunk-XYCYGN3Q.js} +82 -50
  167. package/dist/chunk-XYCYGN3Q.js.map +1 -0
  168. package/dist/{chunk-5T3DTK7A.js → chunk-YN6N3RBM.js} +9 -10
  169. package/dist/chunk-YN6N3RBM.js.map +1 -0
  170. package/dist/{chunk-DCJ4BION.js → chunk-Z4FERR4U.js} +2 -2
  171. package/dist/{chunk-DCJ4BION.js.map → chunk-Z4FERR4U.js.map} +1 -1
  172. package/dist/{claude-code-UBT4ZME7.js → claude-code-LZH7Y4Y5.js} +5 -5
  173. package/dist/{claude-code-UBT4ZME7.js.map → claude-code-LZH7Y4Y5.js.map} +1 -1
  174. package/dist/cli/index.js +308 -162
  175. package/dist/cli/index.js.map +1 -1
  176. package/dist/cli/src/commands/cache.d.ts.map +1 -1
  177. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  178. package/dist/cli/src/commands/config.d.ts.map +1 -1
  179. package/dist/cli/src/commands/connector.d.ts.map +1 -1
  180. package/dist/cli/src/commands/deploy.d.ts.map +1 -1
  181. package/dist/cli/src/commands/harness.d.ts +5 -4
  182. package/dist/cli/src/commands/harness.d.ts.map +1 -1
  183. package/dist/cli/src/commands/integration.d.ts.map +1 -1
  184. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  185. package/dist/cli/src/commands/library-index.d.ts +6 -0
  186. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  187. package/dist/cli/src/commands/migrate-files.d.ts +3 -6
  188. package/dist/cli/src/commands/migrate-files.d.ts.map +1 -1
  189. package/dist/cli/src/commands/migrate-harness.d.ts +4 -3
  190. package/dist/cli/src/commands/migrate-harness.d.ts.map +1 -1
  191. package/dist/cli/src/commands/migrate.d.ts +2 -2
  192. package/dist/cli/src/commands/outdated.d.ts.map +1 -1
  193. package/dist/cli/src/commands/plugin-registry-cmd.d.ts.map +1 -1
  194. package/dist/cli/src/commands/project.d.ts +7 -1
  195. package/dist/cli/src/commands/project.d.ts.map +1 -1
  196. package/dist/cli/src/commands/run.d.ts.map +1 -1
  197. package/dist/cli/src/commands/serve-preflight.d.ts +21 -0
  198. package/dist/cli/src/commands/serve-preflight.d.ts.map +1 -1
  199. package/dist/cli/src/commands/serve.d.ts.map +1 -1
  200. package/dist/cli/src/commands/source-manifest.d.ts.map +1 -1
  201. package/dist/cli/src/commands/source.d.ts +8 -0
  202. package/dist/cli/src/commands/source.d.ts.map +1 -1
  203. package/dist/cli/src/commands/update.d.ts.map +1 -1
  204. package/dist/cli/src/commands/validate-instances.d.ts +6 -0
  205. package/dist/cli/src/commands/validate-instances.d.ts.map +1 -1
  206. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  207. package/dist/cli/src/commands/verify.d.ts.map +1 -1
  208. package/dist/cli/src/config-checks.d.ts +8 -0
  209. package/dist/cli/src/config-checks.d.ts.map +1 -1
  210. package/dist/cli/src/ensure-sources.d.ts.map +1 -1
  211. package/dist/cli/src/helpers.d.ts +3 -2
  212. package/dist/cli/src/helpers.d.ts.map +1 -1
  213. package/dist/cli/src/plugin-store/index.d.ts.map +1 -1
  214. package/dist/cli/src/plugin-store/reconcile.d.ts.map +1 -1
  215. package/dist/cli/src/plugin-store/spec.d.ts +1 -0
  216. package/dist/cli/src/plugin-store/spec.d.ts.map +1 -1
  217. package/dist/cli/src/skill-checks.d.ts +2 -0
  218. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  219. package/dist/connectors/config.js +5 -5
  220. package/dist/connectors/index.js +24 -25
  221. package/dist/connectors/src/connector-manager.d.ts.map +1 -1
  222. package/dist/connectors/src/index.d.ts +2 -2
  223. package/dist/connectors/src/index.d.ts.map +1 -1
  224. package/dist/connectors/src/managed-gitconfig.d.ts +22 -0
  225. package/dist/connectors/src/managed-gitconfig.d.ts.map +1 -1
  226. package/dist/connectors/src/mount-ledger.d.ts.map +1 -1
  227. package/dist/connectors/src/npm-installer.d.ts +11 -3
  228. package/dist/connectors/src/npm-installer.d.ts.map +1 -1
  229. package/dist/connectors-HU5MHSUJ.js +49 -0
  230. package/dist/{connectors-4WH32NK2.js.map → connectors-HU5MHSUJ.js.map} +1 -1
  231. package/dist/connectors-shared/index.js +2 -2
  232. package/dist/core/index.js +7 -7
  233. package/dist/core/logging.js +1 -1
  234. package/dist/core/manifest.js +2 -2
  235. package/dist/core/models.js +1 -1
  236. package/dist/core/publish-manifest.js +3 -3
  237. package/dist/core/ref.js +1 -1
  238. package/dist/core/runtime-assets.js +5 -5
  239. package/dist/core/src/agent-instances.d.ts +6 -0
  240. package/dist/core/src/agent-instances.d.ts.map +1 -1
  241. package/dist/core/src/config-key-diagnostics.d.ts +2 -1
  242. package/dist/core/src/config-key-diagnostics.d.ts.map +1 -1
  243. package/dist/core/src/index.d.ts +4 -4
  244. package/dist/core/src/index.d.ts.map +1 -1
  245. package/dist/core/src/lock.d.ts +20 -1
  246. package/dist/core/src/lock.d.ts.map +1 -1
  247. package/dist/core/src/logging/index.d.ts +1 -0
  248. package/dist/core/src/logging/index.d.ts.map +1 -1
  249. package/dist/core/src/logging/log-safe-text.d.ts +20 -0
  250. package/dist/core/src/logging/log-safe-text.d.ts.map +1 -0
  251. package/dist/core/src/manifest-yaml-editor.d.ts +4 -1
  252. package/dist/core/src/manifest-yaml-editor.d.ts.map +1 -1
  253. package/dist/core/src/manifest.d.ts.map +1 -1
  254. package/dist/core/src/models.d.ts +10 -0
  255. package/dist/core/src/models.d.ts.map +1 -1
  256. package/dist/core/src/repo-manager.d.ts +11 -0
  257. package/dist/core/src/repo-manager.d.ts.map +1 -1
  258. package/dist/core/src/runtime-assets.d.ts +12 -1
  259. package/dist/core/src/runtime-assets.d.ts.map +1 -1
  260. package/dist/core/src/walker.d.ts +3 -0
  261. package/dist/core/src/walker.d.ts.map +1 -1
  262. package/dist/core/src/workspace-config.d.ts +10 -2
  263. package/dist/core/src/workspace-config.d.ts.map +1 -1
  264. package/dist/core/workspace-config.js +4 -4
  265. package/dist/deploy/index.js +7 -7
  266. package/dist/discovery/index.js +5 -5
  267. package/dist/{ensure-sources-UC2RBYMP.js → ensure-sources-CAMWJTMR.js} +32 -32
  268. package/dist/ensure-sources-CAMWJTMR.js.map +1 -0
  269. package/dist/factory-assets/connectors/box.js +24 -25
  270. package/dist/factory-assets/connectors/deploy.js +24 -25
  271. package/dist/factory-assets/connectors/devserver.js +24 -25
  272. package/dist/factory-assets/connectors/flow/adapter.js +24 -25
  273. package/dist/factory-assets/connectors/flow/engine.js +8 -8
  274. package/dist/factory-assets/connectors/flow/run-flow.js +26 -27
  275. package/dist/factory-assets/connectors/flow.js +24 -25
  276. package/dist/factory-assets/connectors/git.js +24 -25
  277. package/dist/factory-assets/connectors/gmail.js +24 -25
  278. package/dist/factory-assets/connectors/googledrive.js +24 -25
  279. package/dist/factory-assets/connectors/local.js +24 -25
  280. package/dist/factory-assets/connectors/mattermost.js +24 -25
  281. package/dist/factory-assets/connectors/memory.js +24 -25
  282. package/dist/factory-assets/connectors/minio.js +24 -25
  283. package/dist/factory-assets/connectors/postgres.js +24 -25
  284. package/dist/factory-assets/connectors/s3.js +24 -25
  285. package/dist/factory-assets/connectors/sharepoint.js +24 -25
  286. package/dist/factory-assets/connectors/sqlite.js +24 -25
  287. package/dist/factory-assets/connectors/static-server.js +24 -25
  288. package/dist/factory-assets/connectors/tunnel.js +24 -25
  289. package/dist/factory-assets/connectors/webdav.js +24 -25
  290. package/dist/factory-assets/connectors/xstate-store.js +24 -25
  291. package/dist/factory-assets/connectors/xstate.js +24 -25
  292. package/dist/factory-assets/skills/authoring-skaile-assets/SKILL.md +2 -1
  293. package/dist/{flows-LYTKNGKE.js → flows-GVOVQGQW.js} +12 -12
  294. package/dist/{flows-LYTKNGKE.js.map → flows-GVOVQGQW.js.map} +1 -1
  295. package/dist/{helpers-SSSKT5XK.js → helpers-WMCCODAV.js} +29 -30
  296. package/dist/{helpers-SSSKT5XK.js.map → helpers-WMCCODAV.js.map} +1 -1
  297. package/dist/library/index.js +11 -11
  298. package/dist/library/install.js +4 -4
  299. package/dist/library/src/manifest-writer.d.ts +9 -0
  300. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  301. package/dist/library/src/remote/remote-catalog-source.d.ts +9 -0
  302. package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
  303. package/dist/library/src/remote/rest-catalog-source.d.ts +1 -0
  304. package/dist/library/src/remote/rest-catalog-source.d.ts.map +1 -1
  305. package/dist/{library-publish-GQMNTAKK.js → library-publish-UQQMHTND.js} +55 -55
  306. package/dist/{library-publish-GQMNTAKK.js.map → library-publish-UQQMHTND.js.map} +1 -1
  307. package/dist/model-endpoint/index.js +10 -11
  308. package/dist/open-library-OJ4HT2X4.js +57 -0
  309. package/dist/{open-library-XGUCUJYE.js.map → open-library-OJ4HT2X4.js.map} +1 -1
  310. package/dist/open-registry-LWGIOJDK.js +32 -0
  311. package/dist/{open-registry-DIFEPDF6.js.map → open-registry-LWGIOJDK.js.map} +1 -1
  312. package/dist/paths-FR2752HV.js +22 -0
  313. package/dist/{paths-G4GFJLE2.js.map → paths-FR2752HV.js.map} +1 -1
  314. package/dist/{plugin-store-BBLDFD3L.js → plugin-store-IALJUBN2.js} +10 -10
  315. package/dist/{plugin-store-BBLDFD3L.js.map → plugin-store-IALJUBN2.js.map} +1 -1
  316. package/dist/project-UQFCYHYS.js +88 -0
  317. package/dist/{project-LB745WVZ.js.map → project-UQFCYHYS.js.map} +1 -1
  318. package/dist/resolver/index.js +8 -8
  319. package/dist/runner/index.js +40 -41
  320. package/dist/runner/src/composition/resolve-instance.d.ts.map +1 -1
  321. package/dist/runner/src/composition/resolve.d.ts +6 -0
  322. package/dist/runner/src/composition/resolve.d.ts.map +1 -1
  323. package/dist/runner/src/credential-notice.d.ts +3 -2
  324. package/dist/runner/src/credential-notice.d.ts.map +1 -1
  325. package/dist/runner/src/external-mcp.d.ts +22 -0
  326. package/dist/runner/src/external-mcp.d.ts.map +1 -1
  327. package/dist/runner/src/mcp-tools-snapshot.d.ts +13 -0
  328. package/dist/runner/src/mcp-tools-snapshot.d.ts.map +1 -0
  329. package/dist/runner/src/resources.d.ts +14 -0
  330. package/dist/runner/src/resources.d.ts.map +1 -1
  331. package/dist/runner/src/serve.d.ts.map +1 -1
  332. package/dist/sdk/asset-manager.js +14 -14
  333. package/dist/sdk/bridge.js +20 -21
  334. package/dist/sdk/core.js +7 -7
  335. package/dist/sdk/flow.js +8 -8
  336. package/dist/sdk/index.js +40 -41
  337. package/dist/sdk/index.js.map +1 -1
  338. package/dist/sdk/resolver.js +8 -8
  339. package/dist/sdk/runner.js +40 -41
  340. package/dist/sdk/session.js +2 -2
  341. package/dist/sdk/transport/ws/server.js +8 -8
  342. package/dist/sdk/transport/ws.js +8 -8
  343. package/dist/sdk/transport.js +8 -8
  344. package/dist/sdk/types.js +1 -1
  345. package/dist/serve-preflight-TYEKHC32.js +56 -0
  346. package/dist/serve-preflight-TYEKHC32.js.map +1 -0
  347. package/dist/session/index.js +2 -2
  348. package/dist/{setup-X6ZYH2MW.js → setup-4JV2IMCB.js} +30 -31
  349. package/dist/setup-4JV2IMCB.js.map +1 -0
  350. package/dist/{skills-62PXDBPJ.js → skills-6QTKFMLW.js} +13 -13
  351. package/dist/{skills-62PXDBPJ.js.map → skills-6QTKFMLW.js.map} +1 -1
  352. package/dist/source-XYMMJVKR.js +86 -0
  353. package/dist/{source-LAYCTRHP.js.map → source-XYMMJVKR.js.map} +1 -1
  354. package/dist/{source-manifest-publish-3S6PJ25W.js → source-manifest-publish-SZFGGKB4.js} +52 -53
  355. package/dist/source-manifest-publish-SZFGGKB4.js.map +1 -0
  356. package/dist/transport/index.js +8 -8
  357. package/dist/transport/ws/server.js +8 -8
  358. package/dist/transport/ws.js +8 -8
  359. package/dist/tui/index.js +40 -41
  360. package/dist/tui/index.js.map +1 -1
  361. package/dist/types/index.js +1 -1
  362. package/dist/types/manifests.js +1 -1
  363. package/dist/types/src/manifests/agent.d.ts +2 -2
  364. package/dist/types/src/manifests/agent.d.ts.map +1 -1
  365. package/dist/types/src/version.d.ts +8 -8
  366. package/dist/workspace-plugin/adapters/mcp.js +31 -32
  367. package/dist/workspace-plugin/adapters/omp.js +14 -14
  368. package/dist/workspace-plugin/index.js +2 -2
  369. package/package.json +1 -1
  370. package/dist/chunk-24D7IW5O.js.map +0 -1
  371. package/dist/chunk-2WOA3TKK.js.map +0 -1
  372. package/dist/chunk-3ENE6ZOF.js.map +0 -1
  373. package/dist/chunk-5T3DTK7A.js.map +0 -1
  374. package/dist/chunk-6OHZUUR7.js.map +0 -1
  375. package/dist/chunk-6UP2EDFN.js.map +0 -1
  376. package/dist/chunk-6WQGJF65.js.map +0 -1
  377. package/dist/chunk-6X3GDPCB.js.map +0 -1
  378. package/dist/chunk-76FLBODK.js.map +0 -1
  379. package/dist/chunk-76WSWPOB.js.map +0 -1
  380. package/dist/chunk-ABVWUM2E.js.map +0 -1
  381. package/dist/chunk-DKXNKFKP.js.map +0 -1
  382. package/dist/chunk-EXRQKOY6.js.map +0 -1
  383. package/dist/chunk-GBXQFJ4G.js.map +0 -1
  384. package/dist/chunk-HXZ3FQQN.js.map +0 -1
  385. package/dist/chunk-IYZAJ2J2.js.map +0 -1
  386. package/dist/chunk-JSWMRYLM.js.map +0 -1
  387. package/dist/chunk-P7EL7QRD.js.map +0 -1
  388. package/dist/chunk-QJQQNBVT.js +0 -315
  389. package/dist/chunk-QJQQNBVT.js.map +0 -1
  390. package/dist/chunk-TF5CWJQZ.js.map +0 -1
  391. package/dist/chunk-TGB4E5Z6.js.map +0 -1
  392. package/dist/chunk-UVTN4O7N.js.map +0 -1
  393. package/dist/chunk-VSCLUPGZ.js.map +0 -1
  394. package/dist/chunk-VV2DJT4I.js.map +0 -1
  395. package/dist/chunk-YJNE4V2M.js.map +0 -1
  396. package/dist/connectors-4WH32NK2.js +0 -50
  397. package/dist/ensure-sources-UC2RBYMP.js.map +0 -1
  398. package/dist/open-library-XGUCUJYE.js +0 -58
  399. package/dist/open-registry-DIFEPDF6.js +0 -32
  400. package/dist/paths-G4GFJLE2.js +0 -22
  401. package/dist/project-LB745WVZ.js +0 -88
  402. package/dist/serve-preflight-NPWI4MV6.js.map +0 -1
  403. package/dist/setup-X6ZYH2MW.js.map +0 -1
  404. package/dist/source-LAYCTRHP.js +0 -87
  405. package/dist/source-manifest-publish-3S6PJ25W.js.map +0 -1
@@ -1,24 +1,24 @@
1
- import { unregisteredLibraryNames, renamedLibraryName, resolveConfig, RemoteCatalogSource, OfflineError, describeCatalogError, CatalogHttpError, scanUnlistedAssets, missingRootAssets, storeManifestFile, missingLibraryDirMessage, lastLibraryName, filesEntryPaths } from './chunk-GBXQFJ4G.js';
2
- import { SEMVER_RE, invalidSemverMessage, flowFileNameError, computeDeterministicHash, readManifestSourceConfig, discoverAssetsInTree, isManifestMode } from './chunk-WENTJ5KP.js';
1
+ import { unregisteredLibraryNames, renamedLibraryName, resolveConfig, RemoteCatalogSource, OfflineError, describeCatalogError, CatalogHttpError, scanUnlistedAssets, missingRootAssets, storeManifestFile, missingLibraryDirMessage, lastLibraryName, filesEntryPaths } from './chunk-MMOWIRHP.js';
2
+ import { SEMVER_RE, invalidSemverMessage, flowFileNameError, computeDeterministicHash, readManifestSourceConfig, discoverAssetsInTree, isManifestMode } from './chunk-J4WKNJHO.js';
3
3
  import { parseFlowDefinition } from './chunk-JRN5QF4C.js';
4
- import { installTargetOf, readKeptLegacyCopies, writeKeptLegacyCopies, canonicalEntryRef, diffDeployedAgent, deployedAssetDrift, assertNoLibrarySymlinks, deployAll, removeAsset, composedDriftRefs, sourceComposedFiles, cachedComposedFiles, createScaffold, installAgent } from './chunk-YJNE4V2M.js';
4
+ import { installTargetOf, readKeptLegacyCopies, writeKeptLegacyCopies, canonicalEntryRef, diffDeployedAgent, deployedAssetDrift, entriesNeedingDeploy, assertNoLibrarySymlinks, deployAll, removeAsset, composedDriftRefs, sourceComposedFiles, cachedComposedFiles, createScaffold, installAgent } from './chunk-DI6J2PJB.js';
5
5
  import { appendHistory, getRecentHistory, clearHistory } from './chunk-KTBKW2FI.js';
6
6
  import { commitChanges } from './chunk-UQ6LFBPZ.js';
7
- import { harnessTargetSupportsAgents, CODEX_IDENTITY_DIR, agentRenderFiles } from './chunk-V4OXHEWY.js';
8
- import { isScaffoldBody, isScaffoldDescription } from './chunk-76FLBODK.js';
9
- import { resolveConfiguredHarnessName, FACTORY_SOURCE_URL, GLOBAL_INSTALL_DIR_NAME, resolveLibraryDir, buildLibraryLockEntries, writeLock, computeHash, buildLockFile, readLock, assertLockHashes, verifyLock, mergeLockFile, resyncLockSources, extractForPatch, generatePatch, savePatch, applyPatch, LOCK_SCHEMA_VERSION } from './chunk-ABVWUM2E.js';
10
- import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-3ENE6ZOF.js';
7
+ import { harnessTargetSupportsAgents, CODEX_IDENTITY_DIR, agentRenderFiles } from './chunk-DS6UUCFG.js';
8
+ import { isScaffoldBody, isScaffoldDescription } from './chunk-VT6G5AJV.js';
9
+ import { resolveConfiguredHarnessName, FACTORY_SOURCE_URL, isFactoryMemorySource, GLOBAL_INSTALL_DIR_NAME, resolveLibraryDir, buildLibraryLockEntries, writeLock, computeHash, buildLockFile, readLock, LockParseError, assertLockHashes, verifyLock, mergeLockFile, resyncLockSources, extractForPatch, generatePatch, savePatch, applyPatch, LOCK_SCHEMA_VERSION } from './chunk-6ARPZHOV.js';
10
+ import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-JIQUF3X2.js';
11
11
  import { deployedBase, isDeployed, deployedPaths, deployedDir } from './chunk-5KRMNUL4.js';
12
- import { resolveSkWorkspaceConfig, effectiveAgentInstances, mcpDeclarationFromMdContent, loadMcpServerDeclarations, resolveGlobalHarnesses, resolveGlobalSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, matchPin, buildProvenanceIndex, coerceVersion, sourceShortName, readLinks, isCommitOnRemote, findWorkspaceRoot, resolveAll, agentSourceCacheDir, ensureRepo, resolveAgentDefinitionDir, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus, resolveAsset, MAX_PRESET_DEPTH, PresetDepthError, DEFAULT_AGENT_INSTANCE_ID } from './chunk-6WQGJF65.js';
12
+ import { resolveSkWorkspaceConfig, effectiveAgentInstances, mcpDeclarationFromMdContent, loadMcpServerDeclarations, resolveGlobalHarnesses, resolveGlobalSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, matchPin, buildProvenanceIndex, coerceVersion, sourceShortName, readLinks, isCommitOnRemote, findWorkspaceRoot, resolveSourcePublisher, resolveAll, agentSourceCacheDir, ensureRepo, resolveAgentDefinitionDir, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus, resolveAsset, DEFAULT_AGENT_INSTANCE_ID, MAX_PRESET_DEPTH, PresetDepthError } from './chunk-6SXSVKQY.js';
13
13
  import { globalSkaileDir, globalCacheRoot, migrateLegacyDir } from './chunk-L5VSIPQD.js';
14
14
  import { HARNESS_TARGETS, SUPPORTED_HARNESSES } from './chunk-VTETQCR6.js';
15
- import { listAssetFiles, loadSkPublishManifest, decodeSkaileManifest, isNonAssetDir, isNonAssetFile } from './chunk-U6S5CXKB.js';
16
- import { scanDirectory, parseFrontmatter, parseRequires, dedupeRequirements, readAssetBody } from './chunk-VV2DJT4I.js';
17
- import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName, depToStr, parseDep } from './chunk-IZQOO6MN.js';
15
+ import { listAssetFiles, loadSkPublishManifest, decodeSkaileManifest, isNonAssetDir, isNonAssetFile } from './chunk-E2EC6SAX.js';
16
+ import { scanDirectory, parseFrontmatter, parseRequires, dedupeRequirements, readAssetBody } from './chunk-GNUA7XT2.js';
17
+ import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName, depToStr, parseDep } from './chunk-V5KG6CCV.js';
18
18
  import { spawnSync } from 'child_process';
19
- import { existsSync, rmSync, readFileSync, writeFileSync, readdirSync, lstatSync, statSync, unlinkSync, mkdirSync } from 'fs';
19
+ import { existsSync, rmSync, readFileSync, writeFileSync, readdirSync, lstatSync, statSync, realpathSync, unlinkSync, mkdirSync } from 'fs';
20
20
  import { homedir } from 'os';
21
- import path, { resolve, dirname, sep, join, relative, posix } from 'path';
21
+ import path, { resolve, dirname, sep, join, relative, isAbsolute, posix } from 'path';
22
22
  import { gt } from 'semver';
23
23
  import { parse, stringify } from 'yaml';
24
24
  import { createHash } from 'crypto';
@@ -821,6 +821,10 @@ function lockedAssetFiles(kind, files) {
821
821
  });
822
822
  }
823
823
  var GITHUB_REPO_URL = /github\.com[/:]/i;
824
+ function isBundledFactoryEntry(entry) {
825
+ if (isFactoryMemorySource(entry.source)) return true;
826
+ return entry.origin === void 0 && entry.source !== void 0 && normalizeRepoUrl(entry.source.url) === normalizeRepoUrl(FACTORY_SOURCE_URL);
827
+ }
824
828
  var GIT_URL = /^(?:[a-z][a-z0-9+.-]*:\/\/|[\w.-]+@[\w.-]+:)/i;
825
829
  function indexLockByKindName(lock) {
826
830
  const lockByKindName = /* @__PURE__ */ new Map();
@@ -1421,6 +1425,8 @@ var AssetManager = class {
1421
1425
  warnedStoreVersionLookups = /* @__PURE__ */ new Set();
1422
1426
  /** Stores a lookup could not reach (store URL -> one line why); `add` reports them instead of "not found". */
1423
1427
  storeFailures = /* @__PURE__ */ new Map();
1428
+ /** Source origins `outdated` could not fetch; read once through {@link takeUnreachableSources}. */
1429
+ unreachableSources = [];
1424
1430
  /** Store URLs a lookup failed on because the client is air-gapped (`cache_ttl: 0`), not because the store is down. */
1425
1431
  airGappedStores = /* @__PURE__ */ new Set();
1426
1432
  /** Sources a provenance walk had to skip (source URL → why); one warning per source. */
@@ -1522,13 +1528,38 @@ var AssetManager = class {
1522
1528
  });
1523
1529
  }
1524
1530
  /**
1525
- * A 5.12.0 global record has no `global_asset_harnesses:` key, yet `add --global --harness`
1526
- * wrote one copy only. On the first global `install`, an entry with exactly one existing copy
1527
- * among several default harnesses is that harness's subset (OQ6): record it, so the install
1528
- * does not fan the asset out to harnesses the user never asked for (p1442). A copy under the
1529
- * 5.12.0 omp folder (`~/.omp/skills`) counts as an omp copy. Nothing is inferred once the key
1530
- * exists (an entry without a row then means "every harness"), with one default harness, or
1531
- * with no copy yet. Global mode only; returns the rows written.
1531
+ * The harness a 5.12.0 `add --global --harness omp` left as the asset's only copy: the copy sits
1532
+ * under the 5.12.0 omp folder (`~/.omp/skills`) and no other default harness holds one. That
1533
+ * folder is the only real 5.12.0 evidence: a current `add --global` writes no row either, so a
1534
+ * lone copy elsewhere may be a copy the user deleted or a harness added later (p1442).
1535
+ */
1536
+ legacySingleCopyHarness(component, name, all) {
1537
+ if (!all.includes("omp") || legacyOmpPaths(component, name).length === 0) return [];
1538
+ const others = all.filter((h) => h !== "omp" && isDeployed(component, name, h, true));
1539
+ return others.length === 0 ? ["omp"] : [];
1540
+ }
1541
+ /**
1542
+ * Whether `~/.skaile/skaile.yaml` is a 5.12.0 record: it exists and has no
1543
+ * `global_asset_harnesses:` key yet, so {@link inferLegacyHarnessSubsets} has not run.
1544
+ */
1545
+ isLegacyHarnessRecord() {
1546
+ if (!this.global) return false;
1547
+ const configPath = join(this.stateRoot, "skaile.yaml");
1548
+ if (!existsSync(configPath)) return false;
1549
+ try {
1550
+ const raw = parse(readFileSync(configPath, "utf8"));
1551
+ return !!raw && typeof raw === "object" && !(ENTRY_HARNESSES_KEY in raw);
1552
+ } catch {
1553
+ return false;
1554
+ }
1555
+ }
1556
+ /**
1557
+ * A 5.12.0 global record has no `global_asset_harnesses:` key, yet `add --global --harness omp`
1558
+ * wrote one copy only, under `~/.omp/skills`. On the first global `install`, an entry whose only
1559
+ * copy sits there (see {@link legacySingleCopyHarness}) is omp's subset (OQ6): record it, so the
1560
+ * install does not fan the asset out to harnesses the user never asked for (p1442). Nothing is
1561
+ * inferred without that evidence, once the key exists (an entry without a row then means "every
1562
+ * harness"), or with one default harness. Global mode only; returns the rows written.
1532
1563
  */
1533
1564
  inferLegacyHarnessSubsets(entries) {
1534
1565
  if (!this.global) return [];
@@ -1547,9 +1578,7 @@ var AssetManager = class {
1547
1578
  for (const e of entries) {
1548
1579
  const component = this.installTarget(e.kind);
1549
1580
  if (!component || !e.name) continue;
1550
- const holding = all.filter(
1551
- (h) => isDeployed(component, e.name, h, true) || h === "omp" && legacyOmpPaths(component, e.name).length > 0
1552
- );
1581
+ const holding = this.legacySingleCopyHarness(component, e.name, all);
1553
1582
  if (holding.length !== 1) continue;
1554
1583
  const publisher = e.publisher?.replace(/^@/, "");
1555
1584
  const ref = `${e.kind}:${publisher ? `@${publisher}/` : ""}${e.name}`;
@@ -1720,6 +1749,13 @@ var AssetManager = class {
1720
1749
  takeLegacyCopiesRemoved() {
1721
1750
  return this.legacyCopiesRemoved.splice(0);
1722
1751
  }
1752
+ /**
1753
+ * The source origins the last {@link outdated} call could not fetch (name, URL, why). Their
1754
+ * behind count was not checked, so the CLI must not call the project up to date (p1820).
1755
+ */
1756
+ takeUnreachableSources() {
1757
+ return this.unreachableSources.splice(0);
1758
+ }
1723
1759
  /**
1724
1760
  * The harnesses `add` / `install` deploy into: `[harness]` for a project, the global
1725
1761
  * harness set (see {@link AssetManager.targetHarnesses}) for a global manager.
@@ -1969,11 +2005,7 @@ var AssetManager = class {
1969
2005
  };
1970
2006
  }
1971
2007
  const factory = resolveFactorySource();
1972
- const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);
1973
- const alreadyDeclared = Object.values(repositories).some(
1974
- (d) => d.url !== void 0 && normalizeRepoUrl(d.url) === factoryUrl
1975
- );
1976
- if (factory && !alreadyDeclared && !repositories[factory.publisher]) {
2008
+ if (factory && !repositories[factory.publisher]) {
1977
2009
  repositories[factory.publisher] = {
1978
2010
  path: factory.dir,
1979
2011
  url: FACTORY_SOURCE_URL,
@@ -1988,7 +2020,7 @@ var AssetManager = class {
1988
2020
  for (const [slug, decl] of Object.entries(repositories)) {
1989
2021
  const localPath = this.resolveRepoDir(decl, slug);
1990
2022
  if (!localPath || !existsSync(localPath)) continue;
1991
- if (decl.url && normalizeRepoUrl(decl.url) !== normalizeRepoUrl(FACTORY_SOURCE_URL) && !existsSync(join(localPath, ".git"))) {
2023
+ if (decl.url && !decl.factory && !existsSync(join(localPath, ".git"))) {
1992
2024
  this.reportSourceError(
1993
2025
  { localPath, sourceUrl: decl.url, commit: "" },
1994
2026
  new Error(
@@ -2085,8 +2117,8 @@ var AssetManager = class {
2085
2117
  const { publisher, kind, name, version } = parseCanonicalLockKey(key);
2086
2118
  if (!publisher || !kind || !name) return null;
2087
2119
  const url = entry.source.url;
2088
- const factory = Object.values(repositories).find((d) => d.factory);
2089
- const declared = factory?.url !== void 0 && normalizeRepoUrl(url) === normalizeRepoUrl(factory.url) ? factory : repositories[sourceCacheKey(url)];
2120
+ const factory = isFactoryMemorySource(entry.source) ? Object.values(repositories).find((d) => d.factory) : void 0;
2121
+ const declared = factory ?? repositories[sourceCacheKey(url)];
2090
2122
  return {
2091
2123
  publisher,
2092
2124
  kind,
@@ -2397,7 +2429,6 @@ var AssetManager = class {
2397
2429
  knownKinds: this.knownKinds,
2398
2430
  onSourceError: this.reportSourceError
2399
2431
  });
2400
- const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);
2401
2432
  const hasFactory = Object.values(repositories).some((d) => d.factory);
2402
2433
  const out = /* @__PURE__ */ new Map();
2403
2434
  const originsOf = (key) => {
@@ -2421,7 +2452,7 @@ var AssetManager = class {
2421
2452
  return a.sourceUrl.localeCompare(b.sourceUrl);
2422
2453
  });
2423
2454
  for (const c of held) {
2424
- const factory = hasFactory && normalizeRepoUrl(c.sourceUrl) === factoryUrl;
2455
+ const factory = hasFactory && isFactoryMemorySource({ url: c.sourceUrl, commit: c.commit });
2425
2456
  originsOf(key).push({
2426
2457
  kind: factory ? "factory" : "source",
2427
2458
  label: factory ? "factory" : sourceShortName(c.sourceUrl),
@@ -2845,7 +2876,8 @@ var AssetManager = class {
2845
2876
  });
2846
2877
  }
2847
2878
  /**
2848
- * Open the local index and snapshot its libraries + asset definitions.
2879
+ * Open the local index and snapshot its libraries + asset definitions, scoped to this
2880
+ * project's `sources:` ({@link scopeLibraryIndex}).
2849
2881
  * Best-effort: no index file (never indexed), or any open/guard failure,
2850
2882
  * yields `null` — a lock/outdated read must never create `index.db` or throw.
2851
2883
  */
@@ -2856,14 +2888,7 @@ var AssetManager = class {
2856
2888
  if (!existsSync(indexPath)) return null;
2857
2889
  const index = new LocalIndex({ indexPath });
2858
2890
  try {
2859
- const libraries = await index.listSources();
2860
- const defs = await index.listAssetDefs();
2861
- const hidden = this.undeclaredSourceClones(libraries);
2862
- if (hidden.size === 0) return { libraries, defs };
2863
- return {
2864
- libraries: libraries.filter((l) => !hidden.has(l.id)),
2865
- defs: defs.filter((d) => !d.libraryId || !hidden.has(d.libraryId))
2866
- };
2891
+ return this.scopeLibraryIndex(await index.listSources(), await index.listAssetDefs());
2867
2892
  } finally {
2868
2893
  index.close();
2869
2894
  }
@@ -2871,32 +2896,85 @@ var AssetManager = class {
2871
2896
  return null;
2872
2897
  }
2873
2898
  }
2899
+ /**
2900
+ * The `sources:` this project declares by clone key, or `undefined` outside a project (no
2901
+ * `skaile.yaml` in `projectDir` or a parent) or when the file does not parse. Outside a
2902
+ * project nothing declares sources, so the machine-wide search reads every clone.
2903
+ */
2904
+ declaredSourceEntries() {
2905
+ if (!this.global && !findWorkspaceRoot(this.projectDir)) return void 0;
2906
+ try {
2907
+ return new Map(this.loadConfig().sources.map((s) => [sourceCacheKey(s.url), s]));
2908
+ } catch {
2909
+ return void 0;
2910
+ }
2911
+ }
2912
+ /** The clone-cache key a source-clone reader row stands for, or `undefined` for any other library. */
2913
+ sourceCloneKey(l) {
2914
+ if (l.ownership !== "reader" || !("url" in l.backendConfig)) return void 0;
2915
+ const cloneRoots = [
2916
+ join(globalCacheRoot(), "sources"),
2917
+ join(globalSkaileDir(), "sources"),
2918
+ this.reposDir
2919
+ ].map((d) => resolve(d));
2920
+ const at = resolve(l.path);
2921
+ return cloneRoots.some((root) => at.startsWith(root + sep)) ? sourceCacheKey(l.backendConfig.url) : void 0;
2922
+ }
2874
2923
  /**
2875
2924
  * Ids of the registered libraries that are the clone of a source this project does not
2876
2925
  * declare. `source add` registers the clone as a machine-wide reader library so `search`
2877
2926
  * and the indexer can read it, but a `sources:` clone belongs to the projects that declare
2878
- * it (OQ12, p321): another project neither resolves it, nor ties with it by name, nor has
2927
+ * it (OQ4, p321): another project neither resolves it, nor ties with it by name, nor has
2879
2928
  * `update` re-pin its locked assets to it. A reader library the user registered by hand
2880
2929
  * (`library init --reader --git`) lives outside the sources cache and is never hidden.
2881
2930
  */
2882
2931
  undeclaredSourceClones(libraries) {
2883
2932
  const hidden = /* @__PURE__ */ new Set();
2884
- if (!this.global && !findWorkspaceRoot(this.projectDir)) return hidden;
2885
- let declared;
2886
- try {
2887
- declared = new Set(this.loadConfig().sources.map((s) => sourceCacheKey(s.url)));
2888
- } catch {
2889
- return hidden;
2890
- }
2891
- const cloneRoots = [join(globalCacheRoot(), "sources"), this.reposDir].map((d) => resolve(d));
2933
+ const declared = this.declaredSourceEntries();
2934
+ if (!declared) return hidden;
2892
2935
  for (const l of libraries) {
2893
- if (l.ownership !== "reader" || !("url" in l.backendConfig)) continue;
2894
- const at = resolve(l.path);
2895
- if (!cloneRoots.some((root) => at.startsWith(root + sep))) continue;
2896
- if (!declared.has(sourceCacheKey(l.backendConfig.url))) hidden.add(l.id);
2936
+ const key = this.sourceCloneKey(l);
2937
+ if (key !== void 0 && !declared.has(key)) hidden.add(l.id);
2897
2938
  }
2898
2939
  return hidden;
2899
2940
  }
2941
+ /**
2942
+ * The index as this project sees it: the source clones of other projects are dropped
2943
+ * ({@link undeclaredSourceClones}) and the assets of a declared source carry the publisher
2944
+ * this project's `sources:` entry names. The clone and its index rows are shared by every
2945
+ * project that declares the source, so a project that declares another `--publisher` is
2946
+ * re-labelled here, at read time, and never changes what the others see (p1822).
2947
+ */
2948
+ scopeLibraryIndex(libraries, defs) {
2949
+ const hidden = this.undeclaredSourceClones(libraries);
2950
+ const declared = this.declaredSourceEntries();
2951
+ const relabel = /* @__PURE__ */ new Map();
2952
+ for (const l of libraries) {
2953
+ const key = this.sourceCloneKey(l);
2954
+ const entry = key === void 0 ? void 0 : declared?.get(key);
2955
+ if (!entry?.publisher || hidden.has(l.id) || !("url" in l.backendConfig)) continue;
2956
+ const indexed = resolveSourcePublisher(l.path, l.backendConfig.publisher);
2957
+ const mine = resolveSourcePublisher(l.path, entry.publisher);
2958
+ if (indexed && mine && indexed !== mine) relabel.set(l.id, { from: indexed, to: mine });
2959
+ }
2960
+ if (hidden.size === 0 && relabel.size === 0) return { libraries, defs };
2961
+ const bare = (publisher) => publisher.replace(/^@/, "");
2962
+ return {
2963
+ libraries: libraries.filter((l) => !hidden.has(l.id)).map((l) => {
2964
+ const r = relabel.get(l.id);
2965
+ return r && "url" in l.backendConfig ? { ...l, backendConfig: { ...l.backendConfig, publisher: r.to } } : l;
2966
+ }),
2967
+ defs: defs.filter((d) => !d.libraryId || !hidden.has(d.libraryId)).map((d) => {
2968
+ const r = d.libraryId ? relabel.get(d.libraryId) : void 0;
2969
+ if (!r || bare(d.publisher) !== r.from) return d;
2970
+ return {
2971
+ ...d,
2972
+ publisher: d.publisher.startsWith("@") ? `@${r.to}` : r.to,
2973
+ id: d.id.replace(`@${r.from}/`, `@${r.to}/`)
2974
+ };
2975
+ })
2976
+ };
2977
+ }
2900
2978
  /**
2901
2979
  * Library-origin lock entries for the assets {@link resolveLibraryEntries}
2902
2980
  * matched. The locked version is the one actually deployed: the on-disk
@@ -2971,6 +3049,82 @@ var AssetManager = class {
2971
3049
  })
2972
3050
  );
2973
3051
  }
3052
+ /**
3053
+ * The entries a deploy would write into some target harness: those without a current deployed
3054
+ * copy. An intact copy stays as it is, so a library change that does not reach it (a symlink
3055
+ * added next to the files) stops no `install` or `update` (p1857).
3056
+ */
3057
+ needingDeploy(entries, link = false) {
3058
+ const targets = this.targetHarnesses();
3059
+ return entries.filter(
3060
+ (e) => targets.some((t) => entriesNeedingDeploy([e], this.deployOptsFor(t, link)).length > 0)
3061
+ );
3062
+ }
3063
+ /**
3064
+ * The files of a library asset that git has not committed (edited, new or staged only), as
3065
+ * paths relative to the library root. The asset's own folder, or its one manifest file when it
3066
+ * shares the folder with other assets. Empty when the asset is not in a git work tree.
3067
+ */
3068
+ uncommittedAssetFiles(entry, libPath) {
3069
+ const provider = this.registry.getProvider(entry.kind);
3070
+ if (!provider) return [];
3071
+ let scope;
3072
+ try {
3073
+ const manifest = statSync(entry.source).isDirectory() ? readdirSync(entry.source).find((f) => provider.matchesPath(f)) : entry.source;
3074
+ if (!manifest) return [];
3075
+ const manifestPath = isAbsolute(manifest) ? manifest : join(entry.source, manifest);
3076
+ const filter = provider.defaultFileFilter(manifestPath);
3077
+ const rootName = relative(dirname(filter.assetRoot), filter.assetRoot);
3078
+ scope = filter.files.length > 1 || rootName === entry.name ? filter.assetRoot : manifestPath;
3079
+ } catch {
3080
+ return [];
3081
+ }
3082
+ const cwd = statSync(scope).isDirectory() ? scope : dirname(scope);
3083
+ const top = spawnSync("git", ["-C", cwd, "rev-parse", "--show-toplevel"], {
3084
+ encoding: "utf8"
3085
+ });
3086
+ if (top.status !== 0) return [];
3087
+ const status = spawnSync(
3088
+ "git",
3089
+ ["-C", cwd, "status", "--porcelain", "--untracked-files=all", "--", scope],
3090
+ { encoding: "utf8" }
3091
+ );
3092
+ if (status.status !== 0) return [];
3093
+ const root = top.stdout.trim();
3094
+ return status.stdout.split("\n").filter((l) => l.trim() !== "").map(
3095
+ (l) => relative(realpathSync(libPath), join(root, l.slice(3).trim().replace(/^"|"$/g, "")))
3096
+ );
3097
+ }
3098
+ /**
3099
+ * Warn when a library with a git remote has uncommitted changes in the folders of the assets
3100
+ * `add` or `install` lock: the lock records the bytes on this disk, which no clone of the
3101
+ * remote holds, so a teammate (or CI) cannot restore them. One line per library naming the
3102
+ * files; the command goes on (OQ5, p1859).
3103
+ */
3104
+ async warnUncommittedLibraryAssets(lib) {
3105
+ if (lib.entries.length === 0) return;
3106
+ const snap = await this.loadLibraryIndex();
3107
+ const files = /* @__PURE__ */ new Map();
3108
+ for (const e of lib.entries) {
3109
+ const name = lib.libraryOf.get(e);
3110
+ const registered = name ? snap?.libraries.find((l) => l.name === name) : void 0;
3111
+ if (!name || !registered || !libraryRemoteUrl(registered)) continue;
3112
+ const libPath = this.libraryPath({ name }, snap);
3113
+ if (!libPath) continue;
3114
+ const set = files.get(name) ?? /* @__PURE__ */ new Set();
3115
+ for (const f of this.uncommittedAssetFiles(e, libPath)) set.add(f);
3116
+ if (set.size > 0) files.set(name, set);
3117
+ }
3118
+ for (const [name, set] of files) {
3119
+ const list = [...set].sort();
3120
+ const shown = list.slice(0, 5).join(", ");
3121
+ const more = list.length > 5 ? `, +${list.length - 5} more` : "";
3122
+ this.emitLibraryCollision(
3123
+ `library "${name}" has uncommitted changes (${shown}${more}): other machines cannot restore those bytes from its remote. Commit and push them.`,
3124
+ []
3125
+ );
3126
+ }
3127
+ }
2974
3128
  /**
2975
3129
  * Whether every declared ref is locked and no declared pin differs from the locked version:
2976
3130
  * `skaile.yaml` asks for nothing the lock does not hold. A declared preset counts when the
@@ -3144,7 +3298,7 @@ var AssetManager = class {
3144
3298
  const onDisk = libraryDiskHashes(libPath, diskHashes, this.registry).get(`${kind}:${name}`);
3145
3299
  if (onDisk !== void 0 && onDisk !== origin.sha256) {
3146
3300
  missing.push(
3147
- `${ref} (library "${lookup.name}" content changed since lock \u2014 or the lock predates the one shared asset hash; re-lock with \`skaile install\`)`
3301
+ `${ref} (library "${lookup.name}" content changed since lock \u2014 or the lock predates the one shared asset hash; re-lock with \`skaile update\`)`
3148
3302
  );
3149
3303
  continue;
3150
3304
  }
@@ -3266,12 +3420,21 @@ var AssetManager = class {
3266
3420
  async keepLockedLibraryEntries(lock) {
3267
3421
  if (!lock) return void 0;
3268
3422
  const out = /* @__PURE__ */ new Map();
3423
+ const snap = await this.loadLibraryIndex();
3424
+ const diskHashes = /* @__PURE__ */ new Map();
3269
3425
  for (const [key, entry] of Object.entries(lock.assets)) {
3270
3426
  if (!entry.library || entry.library.installed || !entry.library.version) continue;
3271
3427
  const id = parseCanonicalLockKey(key);
3272
3428
  if (!id.publisher || !id.kind || !id.name) continue;
3273
3429
  const requires = entry.requires ?? await this.deployedRequirementsOf(id);
3274
- out.set(`${id.publisher}/${id.kind}:${id.name}`, { key, entry, requires });
3430
+ const lookup = this.lockedLibrary(entry.library, snap, {
3431
+ kind: id.kind,
3432
+ publisher: id.publisher,
3433
+ name: id.name
3434
+ });
3435
+ const onDisk = lookup.state === "ok" && entry.library.sha256 ? libraryDiskHashes(lookup.path, diskHashes, this.registry).get(`${id.kind}:${id.name}`) : void 0;
3436
+ const contentChanged = onDisk !== void 0 && onDisk !== entry.library.sha256;
3437
+ out.set(`${id.publisher}/${id.kind}:${id.name}`, { key, entry, requires, contentChanged });
3275
3438
  }
3276
3439
  return out.size > 0 ? out : void 0;
3277
3440
  }
@@ -3582,6 +3745,7 @@ var AssetManager = class {
3582
3745
  const requiredBy = /* @__PURE__ */ new Map();
3583
3746
  const keptVersions = {};
3584
3747
  const versionBlocked = [];
3748
+ const contentHeld = [];
3585
3749
  const lib = { entries: [], resolved: /* @__PURE__ */ new Set(), libraryOf: /* @__PURE__ */ new Map() };
3586
3750
  const missing = /* @__PURE__ */ new Set();
3587
3751
  const seen = /* @__PURE__ */ new Set();
@@ -3596,6 +3760,9 @@ var AssetManager = class {
3596
3760
  const locked = opts.keepLocked?.get(id);
3597
3761
  const lockedVersion = locked?.entry.library?.version;
3598
3762
  if (!locked || !lockedVersion || !e.version) return void 0;
3763
+ if (locked.contentChanged && coerceVersion(e.version) === coerceVersion(lockedVersion)) {
3764
+ return locked;
3765
+ }
3599
3766
  if (isPseudoVersion(lockedVersion) || isPseudoVersion(e.version)) return void 0;
3600
3767
  if (coerceVersion(e.version) === coerceVersion(lockedVersion)) return void 0;
3601
3768
  for (const r of asked) if (refIdentity(r) === id && r.includes("#")) return void 0;
@@ -3632,10 +3799,18 @@ var AssetManager = class {
3632
3799
  });
3633
3800
  } else if (keep) {
3634
3801
  keptVersions[keep.key] = keep.entry;
3802
+ const sameVersion = coerceVersion(e.version ?? "") === coerceVersion(keep.entry.library?.version ?? "");
3803
+ const libraryName = origin ?? keep.entry.library?.name ?? "";
3635
3804
  if (!this.lockedCopyDeployed(e.kind, e.name)) {
3636
3805
  versionBlocked.push(
3637
- `${keep.key} (library "${origin ?? keep.entry.library?.name}" is at ${e.version}, locked ${keep.entry.library?.version}; the deployed copy is gone and cannot be restored from the ${gt(coerceVersion(e.version ?? ""), coerceVersion(keep.entry.library?.version ?? "")) ? "newer" : "older"} files \u2014 \`skaile update\` moves the lock to it)`
3806
+ sameVersion ? `${keep.key} (library "${libraryName}" content changed since lock; the deployed copy is gone and cannot be restored from the changed files \u2014 \`skaile update\` takes the change)` : `${keep.key} (library "${origin ?? keep.entry.library?.name}" is at ${e.version}, locked ${keep.entry.library?.version}; the deployed copy is gone and cannot be restored from the ${gt(coerceVersion(e.version ?? ""), coerceVersion(keep.entry.library?.version ?? "")) ? "newer" : "older"} files \u2014 \`skaile update\` moves the lock to it)`
3638
3807
  );
3808
+ } else if (sameVersion) {
3809
+ contentHeld.push({
3810
+ ref: keep.key,
3811
+ library: libraryName,
3812
+ version: keep.entry.library?.version ?? ""
3813
+ });
3639
3814
  }
3640
3815
  } else {
3641
3816
  lib.entries.push(e);
@@ -3738,7 +3913,8 @@ var AssetManager = class {
3738
3913
  presets,
3739
3914
  requiredBy,
3740
3915
  keptVersions,
3741
- versionBlocked
3916
+ versionBlocked,
3917
+ contentHeld
3742
3918
  };
3743
3919
  }
3744
3920
  /**
@@ -4064,7 +4240,8 @@ var AssetManager = class {
4064
4240
  presets,
4065
4241
  requiredBy,
4066
4242
  keptVersions,
4067
- versionBlocked
4243
+ versionBlocked,
4244
+ contentHeld
4068
4245
  } = await this.resolveLibraryFirst(dependencies, {
4069
4246
  provenanceIndex,
4070
4247
  overrides,
@@ -4132,6 +4309,7 @@ var AssetManager = class {
4132
4309
  missingHints[ref] = `${fix ? "" : missingHints[ref] ?? ""} (${notes.join("; ")})`;
4133
4310
  }
4134
4311
  const directLock = this.directInstallLockEntries();
4312
+ await this.warnUncommittedLibraryAssets(lib);
4135
4313
  const libraryLock = {
4136
4314
  ...directLock,
4137
4315
  ...await this.libraryLockEntries(lib, opts?.moveLibraries === true),
@@ -4144,7 +4322,12 @@ var AssetManager = class {
4144
4322
  await this.keepRequiredByKept(prevLock, kept, Object.keys(freshLock.assets));
4145
4323
  const entries = [...await this.buildCatalogEntries(resolved, repositories), ...lib.entries];
4146
4324
  assertFlowsLoad(entries, "installed");
4147
- assertNoLibrarySymlinks(entries, this.registry, repositories, opts?.link === true);
4325
+ assertNoLibrarySymlinks(
4326
+ this.needingDeploy(entries, opts?.link === true),
4327
+ this.registry,
4328
+ repositories,
4329
+ opts?.link === true
4330
+ );
4148
4331
  if (libraryAssetCheck && lib.entries.length > 0) {
4149
4332
  const lockedIds = new Set([...lockedKeys].map((k) => k.split("#")[0]));
4150
4333
  const snap = await this.loadLibraryIndex();
@@ -4224,6 +4407,8 @@ Fix the asset, then run \`skaile library index ${origin}\` and install again.`
4224
4407
  ...mcpRestored
4225
4408
  ];
4226
4409
  const rewritten = this.rewrittenAgentFiles(unrecordedAgents);
4410
+ const editedHeld = new Set(copyDrift.filter((d) => d.libraryChanged).map((d) => d.ref));
4411
+ const heldEdits = editedHeld.size > 0 && opts?.moveLibraries !== true ? (await this.projectState()).gaps.filter((g) => g.type === "modified" && editedHeld.has(g.ref)).map((g) => g.message) : [];
4227
4412
  const lockWanted = resolved.length > 0 || lib.entries.length > 0 || existsSync(this.lockPath);
4228
4413
  let lockWritten = false;
4229
4414
  let relocked = [];
@@ -4261,13 +4446,15 @@ Fix the asset, then run \`skaile library index ${origin}\` and install again.`
4261
4446
  missing: [
4262
4447
  ...reportedMissing,
4263
4448
  ...versionBlocked.filter((b) => !reportedMissing.includes(b)),
4264
- ...composedDrift
4449
+ ...composedDrift,
4450
+ ...heldEdits.filter((h) => !reportedMissing.includes(h))
4265
4451
  ],
4266
4452
  ...placeholderBodies.length > 0 ? { placeholderBodies } : {},
4267
4453
  ...placeholderDescriptions.length > 0 ? { placeholderDescriptions } : {},
4268
4454
  ...storeNotChecked.length > 0 ? { storeNotChecked } : {},
4269
4455
  ...Object.keys(missingHints).length > 0 ? { missingHints } : {},
4270
4456
  ...relocked.length > 0 ? { relocked } : {},
4457
+ ...contentHeld.length > 0 ? { contentHeld } : {},
4271
4458
  ...inferredHarnesses.length > 0 ? { inferredHarnesses } : {},
4272
4459
  ...moved.length > 0 ? { moved } : {},
4273
4460
  ...replaced.length > 0 ? { replaced } : {},
@@ -4739,11 +4926,15 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
4739
4926
  });
4740
4927
  }
4741
4928
  }
4742
- /** Read the lock, returning null on a legacy v1 lock instead of throwing. */
4929
+ /**
4930
+ * Read the lock, returning null on a legacy v1 lock instead of throwing. A lock that is not
4931
+ * valid YAML throws {@link LockParseError}: it is not an empty lock (p1892).
4932
+ */
4743
4933
  tryReadLock() {
4744
4934
  try {
4745
4935
  return readLock(this.lockPath);
4746
- } catch {
4936
+ } catch (err) {
4937
+ if (err instanceof LockParseError) throw err;
4747
4938
  return null;
4748
4939
  }
4749
4940
  }
@@ -4913,13 +5104,11 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
4913
5104
  );
4914
5105
  }
4915
5106
  const declBySlug = new Map(Object.entries(repositories));
4916
- const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);
4917
5107
  const factoryDecl = Object.values(repositories).find((d) => d.factory);
4918
5108
  const factoryDir = factoryDecl?.path ?? null;
4919
- const isFactoryUrl = (url) => factoryDir !== null && normalizeRepoUrl(url) === factoryUrl;
4920
5109
  const unavailable = [];
4921
5110
  for (const src of lock.sources) {
4922
- if (isFactoryUrl(src.url)) continue;
5111
+ if (factoryDir !== null && isFactoryMemorySource(src)) continue;
4923
5112
  const slug = sourceCacheKey(src.url);
4924
5113
  const declared = declBySlug.get(slug);
4925
5114
  if (!declared && GITHUB_REPO_URL.test(src.url)) continue;
@@ -4949,8 +5138,8 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
4949
5138
  cloneOrigin[key] = entry;
4950
5139
  }
4951
5140
  }
4952
- const verification = verifyLock({ ...lock, assets: cloneOrigin }, (sourceUrl) => {
4953
- if (isFactoryUrl(sourceUrl)) return factoryDir;
5141
+ const verification = verifyLock({ ...lock, assets: cloneOrigin }, (sourceUrl, entry) => {
5142
+ if (factoryDir !== null && isFactoryMemorySource(entry.source)) return factoryDir;
4954
5143
  const slug = sourceCacheKey(sourceUrl);
4955
5144
  return this.resolveRepoDir(repositories[slug] ?? { url: sourceUrl }, slug);
4956
5145
  });
@@ -4982,7 +5171,11 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
4982
5171
  }
4983
5172
  const library = await this.restoreLibraryLockEntries(lock, { storeFallback: true });
4984
5173
  assertFlowsLoad([...resolved, ...library.entries], "installed");
4985
- assertNoLibrarySymlinks([...resolved, ...library.entries], this.registry, repositories);
5174
+ assertNoLibrarySymlinks(
5175
+ this.needingDeploy([...resolved, ...library.entries]),
5176
+ this.registry,
5177
+ repositories
5178
+ );
4986
5179
  const inferredHarnesses = this.inferLegacyHarnessSubsets([...resolved, ...library.entries]);
4987
5180
  const composedPre = /* @__PURE__ */ new Set();
4988
5181
  if (!this.global) {
@@ -5046,7 +5239,12 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
5046
5239
  const p = parseRefTolerant(g.ref);
5047
5240
  return !(p && alreadyMissing.has(`${p.kind}:${p.name}`));
5048
5241
  }).map((g) => g.message);
5049
- const libraryNotices = this.storeRestoreNotices(lock, library.viaStore, library.storeOrigins);
5242
+ const libraryNotices = this.storeRestoreNotices(
5243
+ lock,
5244
+ library.viaStore,
5245
+ library.storeOrigins,
5246
+ deployed.length > 0 || restored.length > 0
5247
+ );
5050
5248
  const placeholderBodies = scaffoldBodyRefs(library.entries, deployed);
5051
5249
  const placeholderDescriptions = scaffoldDescriptionRefs(library.entries, deployed);
5052
5250
  return {
@@ -5070,7 +5268,7 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
5070
5268
  * the library to move the lock later (OQ8, p1655). Every file was SHA-verified against the
5071
5269
  * hash the lock recorded.
5072
5270
  */
5073
- storeRestoreNotices(lock, viaStore, storeOrigins) {
5271
+ storeRestoreNotices(lock, viaStore, storeOrigins, wroteFiles) {
5074
5272
  const byLibrary = /* @__PURE__ */ new Map();
5075
5273
  for (const key of viaStore) {
5076
5274
  const origin = lock.assets[key]?.library;
@@ -5088,7 +5286,20 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
5088
5286
  }
5089
5287
  return [...byLibrary].map(([name, { url, refs, from }]) => {
5090
5288
  const register = url ? `skaile library init ${name} --git ${url}` : `skaile library init ${name} --path <dir>`;
5091
- const where = from.size > 0 ? ` from the store ${[...from].join(", ")}` : " from a store";
5289
+ if (!wroteFiles) {
5290
+ return `Library "${name}" is not registered here. Register it with \`${register}\` to move the lock later.`;
5291
+ }
5292
+ const byStore = /* @__PURE__ */ new Map();
5293
+ for (const f of from) {
5294
+ const storeUrl = f.split(" (")[0] ?? f;
5295
+ const pointers = byStore.get(storeUrl) ?? /* @__PURE__ */ new Set();
5296
+ pointers.add(f);
5297
+ byStore.set(storeUrl, pointers);
5298
+ }
5299
+ const stores = [...byStore].map(
5300
+ ([storeUrl, pointers]) => pointers.size === 1 ? [...pointers][0] : storeUrl
5301
+ );
5302
+ const where = stores.length > 0 ? ` from the store ${stores.join(", ")}` : " from a store";
5092
5303
  return `Library "${name}" is not registered here: restored ${refs.length} asset${refs.length === 1 ? "" : "s"}${where}, every file checked against the lock. Register it with \`${register}\` to move the lock later.`;
5093
5304
  });
5094
5305
  }
@@ -5173,7 +5384,6 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
5173
5384
  */
5174
5385
  planAddItems(resolved, lib, stores, parsed) {
5175
5386
  const storeUrls = new Set(stores.map((s) => normalizeRepoUrl(s.url)));
5176
- const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);
5177
5387
  const shownPath = (dir) => {
5178
5388
  const rel = relative(this.projectDir, dir);
5179
5389
  return this.global || rel.startsWith("..") ? dir.replace(homedir(), "~") : `${rel}${dir.endsWith(sep) ? sep : ""}`;
@@ -5206,7 +5416,7 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
5206
5416
  publisher: c.publisher.replace(/^@/, "")
5207
5417
  }),
5208
5418
  version: c.version,
5209
- origin: storeUrls.has(url) ? `store ${c.sourceUrl}` : url === factoryUrl ? "factory" : `source ${sourceShortName(c.sourceUrl)}`,
5419
+ origin: storeUrls.has(url) ? `store ${c.sourceUrl}` : isFactoryMemorySource({ url: c.sourceUrl, commit: c.commit }) ? "factory" : `source ${sourceShortName(c.sourceUrl)}`,
5210
5420
  requested: asked(c.kind, c.name, c.publisher),
5211
5421
  ...planPaths(
5212
5422
  folders(c.kind, c.name),
@@ -5382,6 +5592,30 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
5382
5592
  }
5383
5593
  }
5384
5594
  }
5595
+ if (libraryAssetCheck) {
5596
+ for (const l of snap?.libraries ?? []) {
5597
+ const libPath = this.libraryPath({ name: l.name }, snap);
5598
+ const manifest = libPath ? loadSkPublishManifest(libPath) : null;
5599
+ if (!libPath || !manifest || manifest.source) continue;
5600
+ const entry = (manifest.assets ?? []).find(
5601
+ (a) => a.kind === parsed.kind && a.name === parsed.name && !a.source && (!parsed.publisher || bare(a.publisher ?? manifest.publisher) === bare(parsed.publisher))
5602
+ );
5603
+ if (!entry?.root || isAbsolute(entry.root) || entry.root.split(/[\\/]+/).includes("..")) {
5604
+ continue;
5605
+ }
5606
+ const problems = libraryAssetCheck(
5607
+ { kind: entry.kind, name: entry.name, source: join(libPath, entry.root) },
5608
+ libPath
5609
+ );
5610
+ if (problems.length > 0) {
5611
+ throw new Error(
5612
+ `${parsed.kind}:${parsed.name} in library "${l.name}" fails the checks of \`skaile validate\` - nothing was added:
5613
+ ${problems.map((line) => ` ${line}`).join("\n")}
5614
+ Fix the asset, then run \`skaile library index ${l.name}\` and add it again.`
5615
+ );
5616
+ }
5617
+ }
5618
+ }
5385
5619
  const unreachable = [...this.storeFailures.values()];
5386
5620
  if (unreachable.length > 0) {
5387
5621
  throw new Error(
@@ -5574,9 +5808,15 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
5574
5808
  }
5575
5809
  this.addDependencyToConfig(ref, opts?.only === true);
5576
5810
  this.widenDependencyRows(entries, parsed);
5811
+ if (!opts?.preferLockedLibrary) {
5812
+ const bound = this.bindAgentInstance(entries, parsed);
5813
+ if (bound?.keptRef !== void 0) opts?.onAgentBindingKept?.(bound.id, bound.keptRef);
5814
+ else if (bound) opts?.onAgentBound?.(bound.id, bound.ref);
5815
+ }
5577
5816
  await this.renderHarnessMcpConfig();
5578
5817
  await this.renderAgentInstances();
5579
5818
  if (resolved.length > 0 || lib.entries.length > 0) {
5819
+ await this.warnUncommittedLibraryAssets(lib);
5580
5820
  const libraryLock = await this.libraryLockEntries(lib);
5581
5821
  const fresh = {
5582
5822
  ...buildLockFile(resolved, overridesApplied, libraryLock),
@@ -6385,17 +6625,18 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
6385
6625
  listStaleHarnessCopies() {
6386
6626
  if (this.global) return [];
6387
6627
  const tracked = /* @__PURE__ */ new Map();
6388
- const track = (kind, name) => {
6628
+ const track = (kind, name, locked = false) => {
6389
6629
  const component = kind ? this.installTarget(kind) : void 0;
6390
6630
  if (kind && name && component) {
6391
- tracked.set(`${kind}:${name}`, { kind, name, component });
6631
+ const key = `${kind}:${name}`;
6632
+ tracked.set(key, { kind, name, component, locked: locked || !!tracked.get(key)?.locked });
6392
6633
  }
6393
6634
  };
6394
6635
  const lock = this.tryReadLock();
6395
6636
  if (lock) {
6396
6637
  for (const key of Object.keys(lock.assets)) {
6397
6638
  const { kind, name } = parseCanonicalLockKey(key);
6398
- track(kind, name);
6639
+ track(kind, name, true);
6399
6640
  }
6400
6641
  }
6401
6642
  try {
@@ -6411,23 +6652,36 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
6411
6652
  const out = [];
6412
6653
  for (const other of SUPPORTED_HARNESSES) {
6413
6654
  if (other === this.harness) continue;
6414
- for (const { kind, name, component: k } of tracked.values()) {
6655
+ for (const { kind, name, component: k, locked } of tracked.values()) {
6415
6656
  if (deployedDir(k, name, other, false, this.projectDir) === deployedDir(k, name, this.harness, false, this.projectDir)) {
6416
6657
  continue;
6417
6658
  }
6418
- const found = deployedPaths(k, name, other, false, this.projectDir).find((p) => {
6659
+ const footprints = deployedPaths(k, name, other, false, this.projectDir);
6660
+ if (k === "agent" && other === "codex") {
6661
+ footprints.push(
6662
+ join(
6663
+ dirname(deployedBase(k, other, false, this.projectDir)),
6664
+ CODEX_IDENTITY_DIR,
6665
+ `${name}.md`
6666
+ )
6667
+ );
6668
+ }
6669
+ const otherBase = deployedBase(k, other, false, this.projectDir);
6670
+ const activeBase = deployedBase(k, this.harness, false, this.projectDir);
6671
+ for (const p of footprints) {
6419
6672
  try {
6420
6673
  lstatSync(p);
6421
- return true;
6422
6674
  } catch {
6423
- return false;
6675
+ continue;
6424
6676
  }
6425
- });
6426
- if (found) out.push({ harness: other, kind, name, path: found });
6677
+ const twin = join(activeBase, relative(otherBase, p));
6678
+ const skaileWrote = k === "agent" ? locked : !relative(otherBase, p).startsWith("..") && sameBytes(p, twin);
6679
+ out.push({ harness: other, kind, name, path: p, skaileWrote });
6680
+ }
6427
6681
  }
6428
6682
  }
6429
6683
  return out.sort(
6430
- (a, b) => a.harness.localeCompare(b.harness) || a.kind.localeCompare(b.kind) || a.name.localeCompare(b.name)
6684
+ (a, b) => a.harness.localeCompare(b.harness) || a.kind.localeCompare(b.kind) || a.name.localeCompare(b.name) || a.path.localeCompare(b.path)
6431
6685
  );
6432
6686
  }
6433
6687
  /**
@@ -6674,7 +6928,13 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
6674
6928
  const locked = parsed.kind === "preset" ? lock !== null : lockKeys.some(
6675
6929
  (k) => k.kind === parsed.kind && k.name === parsed.name && (!parsed.publisher || k.publisher === parsed.publisher)
6676
6930
  );
6677
- const recorded = this.entryHarnessRecord(parsed.kind, parsed.name, parsed.publisher);
6931
+ let recorded = this.entryHarnessRecord(parsed.kind, parsed.name, parsed.publisher);
6932
+ if (!recorded && this.isLegacyHarnessRecord()) {
6933
+ const all = this.defaultGlobalHarnesses();
6934
+ const component = this.installTarget(parsed.kind);
6935
+ const holding = all.length >= 2 && component ? this.legacySingleCopyHarness(component, parsed.name, all) : [];
6936
+ if (holding.length === 1) recorded = holding;
6937
+ }
6678
6938
  for (const harness of recorded ? harnesses.filter((h) => recorded.includes(h)) : harnesses) {
6679
6939
  let state;
6680
6940
  if (!locked) {
@@ -6959,6 +7219,13 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
6959
7219
  if (!decl) continue;
6960
7220
  const status = checkRepoStatus(decl, slug, this.reposDir);
6961
7221
  if (status.kind !== "remote" || !status.localHead) continue;
7222
+ if (status.error !== void 0) {
7223
+ this.unreachableSources.push({
7224
+ name: sourceShortName(src.url),
7225
+ url: src.url,
7226
+ reason: status.error
7227
+ });
7228
+ }
6962
7229
  const clone = decl.path ?? join(this.reposDir, slug);
6963
7230
  for (const [ref, entry] of Object.entries(lock.assets)) {
6964
7231
  if (entry.source?.url !== src.url) continue;
@@ -8102,7 +8369,7 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
8102
8369
  found.version
8103
8370
  );
8104
8371
  if (!diskVersion || isPseudoVersion(diskVersion) || !gt(coerceVersion(diskVersion), coerceVersion(origin.version)) && (isPseudoVersion(origin.version) || diskVersion === origin.version)) {
8105
- const reason2 = `is locked, but library "${lookup.name}" content changed since lock \u2014 or the lock predates the one shared asset hash; run \`skaile install\` to re-lock it`;
8372
+ const reason2 = `is locked, but library "${lookup.name}" content changed since lock \u2014 or the lock predates the one shared asset hash; run \`skaile update\` to re-lock it`;
8106
8373
  gaps.push({ type: "content", ref, reason: reason2, message: `${ref} ${reason2}` });
8107
8374
  }
8108
8375
  }
@@ -8157,16 +8424,19 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
8157
8424
  for (const [key, entry] of Object.entries(this.tryReadLock()?.assets ?? {})) {
8158
8425
  const url = entry.source?.url;
8159
8426
  if (!url || entry.library || !GIT_URL.test(url)) continue;
8427
+ if (entry.origin === "store" && !online) continue;
8160
8428
  if (inScope && !inScope.has(key)) continue;
8161
- if (normalizeRepoUrl(url) === normalizeRepoUrl(FACTORY_SOURCE_URL)) continue;
8429
+ if (isBundledFactoryEntry(entry)) continue;
8162
8430
  const { publisher, kind, name, version } = parseCanonicalLockKey(key);
8163
8431
  if (!publisher || !kind || !name) continue;
8164
8432
  if (registered.has(sourceCacheKey(url))) continue;
8165
8433
  const ref = `${kind}:@${publisher}/${name}`;
8166
8434
  const locked = version ? `${ref}#${version}` : void 0;
8167
- if (GITHUB_REPO_URL.test(url) && await this.storeListsRef(stores, ref, online, locked))
8435
+ const askStores = entry.origin === "store" && entry.store && !stores.some((s) => s.url === entry.store) ? [...stores, { url: entry.store }] : stores;
8436
+ if (GITHUB_REPO_URL.test(url) && await this.storeListsRef(askStores, ref, online, locked))
8168
8437
  continue;
8169
- const reason = `is locked, but its source ${url} is not in skaile.yaml sources: any more \u2014 register it again with \`skaile source add ${url}\`, or drop the dependency with \`skaile remove ${ref}\``;
8438
+ const base = `is locked, but its source ${url} is not in skaile.yaml sources: any more \u2014 register it again with \`skaile source add ${url}\`, or drop the dependency with \`skaile remove ${ref}\``;
8439
+ const reason = stores.length > 0 && GITHUB_REPO_URL.test(url) && entry.origin !== "store" ? `${base}. If a store supplied it (store unreachable, or its cache is cold), run \`skaile install\` with the store online to record the store as its origin` : base;
8170
8440
  out.set(key, { type: "source", ref, reason, message: `${ref} ${reason}`, manualFix: true });
8171
8441
  }
8172
8442
  return out;
@@ -8179,6 +8449,7 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
8179
8449
  * its cached catalog holds.
8180
8450
  */
8181
8451
  async storeListsRef(stores, ref, online, lockedRef) {
8452
+ if (online && this.catalogUrlOverride === "") return true;
8182
8453
  for (const store of stores) {
8183
8454
  try {
8184
8455
  if (this.injectedStoreFetcher) {
@@ -8215,8 +8486,8 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
8215
8486
  const gaps = [];
8216
8487
  for (const [key, entry] of Object.entries(this.tryReadLock()?.assets ?? {})) {
8217
8488
  const url = entry.source?.url;
8218
- if (!url || entry.library || !GIT_URL.test(url)) continue;
8219
- if (normalizeRepoUrl(url) === normalizeRepoUrl(FACTORY_SOURCE_URL)) continue;
8489
+ if (!url || entry.library || entry.origin === "store" || !GIT_URL.test(url)) continue;
8490
+ if (isBundledFactoryEntry(entry)) continue;
8220
8491
  const { publisher, kind, name } = parseCanonicalLockKey(key);
8221
8492
  if (!publisher || !kind || !name || named.has(`${kind}:${name}`)) continue;
8222
8493
  const ref = `${kind}:@${publisher}/${name}`;
@@ -8244,7 +8515,8 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
8244
8515
  const want = sourceCacheKey(url);
8245
8516
  const out = [];
8246
8517
  for (const [key, entry] of Object.entries(this.tryReadLock()?.assets ?? {})) {
8247
- if (entry.library || !entry.source || sourceCacheKey(entry.source.url) !== want) continue;
8518
+ if (entry.library || !entry.source || isFactoryMemorySource(entry.source)) continue;
8519
+ if (sourceCacheKey(entry.source.url) !== want) continue;
8248
8520
  const { publisher, kind, name } = parseCanonicalLockKey(key);
8249
8521
  if (kind && name) out.push(publisher ? `${kind}:@${publisher}/${name}` : `${kind}:${name}`);
8250
8522
  }
@@ -9221,6 +9493,53 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
9221
9493
  }
9222
9494
  return out;
9223
9495
  }
9496
+ /**
9497
+ * Bind the agent `skaile add agent:<ref>` just added as an instance `agents.<name>:
9498
+ * {ref: agent:@publisher/name}` of `skaile.yaml`, so `run --instance <name>` and the repl
9499
+ * banner hint work at once. An agent that an instance or `agent:` already binds, or an id
9500
+ * `agents:` already holds, is left as it is. Project mode only.
9501
+ *
9502
+ * @returns the instance id and ref bound; the id with `keptRef` (what that id binds instead)
9503
+ * when the id is taken by another agent; `undefined` when nothing was bound and nothing needs saying.
9504
+ */
9505
+ bindAgentInstance(entries, parsed) {
9506
+ if (this.global || parsed.kind !== "agent") return void 0;
9507
+ const configPath = join(this.stateRoot, "skaile.yaml");
9508
+ if (!existsSync(configPath)) return void 0;
9509
+ const bare = (p) => p?.replace(/^@/, "");
9510
+ const entry = entries.find(
9511
+ (e) => e.kind === "agent" && e.name === parsed.name && (!parsed.publisher || bare(e.publisher) === bare(parsed.publisher))
9512
+ );
9513
+ const publisher = bare(entry?.publisher ?? parsed.publisher);
9514
+ const ref = publisher ? `agent:@${publisher}/${parsed.name}` : `agent:${parsed.name}`;
9515
+ const id = parsed.name.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^[^a-z]+/, "");
9516
+ if (!/^[a-z][a-z0-9_-]*$/.test(id)) return void 0;
9517
+ let raw;
9518
+ try {
9519
+ raw = parse(readFileSync(configPath, "utf8"));
9520
+ } catch {
9521
+ return void 0;
9522
+ }
9523
+ if (!raw || typeof raw !== "object") return void 0;
9524
+ const bound = (value) => {
9525
+ const p = typeof value === "string" ? parseRefTolerant(value) : null;
9526
+ return !!p && p.kind === "agent" && p.name === parsed.name && (!publisher || !p.publisher || bare(p.publisher) === publisher);
9527
+ };
9528
+ const instances = raw.agents && typeof raw.agents === "object" && !Array.isArray(raw.agents) ? raw.agents : {};
9529
+ const primary = raw.agent && typeof raw.agent === "object" ? raw.agent.definition : void 0;
9530
+ if (bound(primary) || Object.values(instances).some((i) => bound(i?.ref))) {
9531
+ return void 0;
9532
+ }
9533
+ const taken = instances[id]?.ref;
9534
+ if (id in instances)
9535
+ return { id, ref, keptRef: typeof taken === "string" ? taken : "another agent" };
9536
+ if (id === DEFAULT_AGENT_INSTANCE_ID && typeof primary === "string") {
9537
+ return { id, ref, keptRef: primary };
9538
+ }
9539
+ raw.agents = { ...instances, [id]: { ref } };
9540
+ writeFileSync(configPath, stringify(raw, { lineWidth: 120 }));
9541
+ return { id, ref };
9542
+ }
9224
9543
  /** The refs `skaile.yaml` binds agent instances to: every `agents.<id>.ref` and `agent.definition`. Project mode only. */
9225
9544
  declaredAgentInstanceRefs() {
9226
9545
  if (this.global) return [];
@@ -9303,5 +9622,5 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
9303
9622
  };
9304
9623
 
9305
9624
  export { AssetManager, LibraryEntryError, MissingManifestError, installAgentInstances, labelDiffHeaders, mcpNotRunnableReason, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, setLibraryAssetCheck, setRenamedEntryLookup, softDepName };
9306
- //# sourceMappingURL=chunk-TGB4E5Z6.js.map
9307
- //# sourceMappingURL=chunk-TGB4E5Z6.js.map
9625
+ //# sourceMappingURL=chunk-JRVQV7WC.js.map
9626
+ //# sourceMappingURL=chunk-JRVQV7WC.js.map