@skaile/workspaces 5.8.0 → 5.10.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 (348) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/{asset-feeds-EYRZR4K5.js → asset-feeds-ELEBTNUS.js} +18 -18
  4. package/dist/{asset-feeds-EYRZR4K5.js.map → asset-feeds-ELEBTNUS.js.map} +1 -1
  5. package/dist/asset-manager/catalog-deployer.js +8 -8
  6. package/dist/asset-manager/index.js +14 -14
  7. package/dist/asset-manager/installer.js +10 -10
  8. package/dist/asset-manager/renderers.js +9 -9
  9. package/dist/asset-manager/src/index.d.ts +300 -36
  10. package/dist/asset-manager/src/index.d.ts.map +1 -1
  11. package/dist/asset-manager/src/install-agent.d.ts +3 -1
  12. package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
  13. package/dist/asset-manager/src/install-instances.d.ts +31 -1
  14. package/dist/asset-manager/src/install-instances.d.ts.map +1 -1
  15. package/dist/asset-manager/src/installer.d.ts +20 -0
  16. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  17. package/dist/asset-manager/src/renderers.d.ts +4 -5
  18. package/dist/asset-manager/src/renderers.d.ts.map +1 -1
  19. package/dist/bridge/drivers/claude-sdk.js +170 -17
  20. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  21. package/dist/bridge/drivers/codex.js +13 -11
  22. package/dist/bridge/drivers/codex.js.map +1 -1
  23. package/dist/bridge/drivers/continue.js +10 -10
  24. package/dist/bridge/drivers/echo.js +4 -4
  25. package/dist/bridge/drivers/gemini.js +7 -7
  26. package/dist/bridge/drivers/goose.js +10 -10
  27. package/dist/bridge/drivers/omp.js +7 -5
  28. package/dist/bridge/drivers/omp.js.map +1 -1
  29. package/dist/bridge/drivers/opencode.js +10 -10
  30. package/dist/bridge/drivers/qwen.js +7 -7
  31. package/dist/bridge/index.js +14 -14
  32. package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
  33. package/dist/bridge/src/drivers/claude-sdk.d.ts +31 -1
  34. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  35. package/dist/bridge/src/drivers/claude-tool-allowlist.d.ts +43 -0
  36. package/dist/bridge/src/drivers/claude-tool-allowlist.d.ts.map +1 -0
  37. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  38. package/dist/bridge/src/types.d.ts +20 -1
  39. package/dist/bridge/src/types.d.ts.map +1 -1
  40. package/dist/{chunk-36AFURKZ.js → chunk-2FMEGSBN.js} +38 -11
  41. package/dist/chunk-2FMEGSBN.js.map +1 -0
  42. package/dist/{chunk-GCICGXDD.js → chunk-2H73V6XR.js} +3 -3
  43. package/dist/{chunk-GCICGXDD.js.map → chunk-2H73V6XR.js.map} +1 -1
  44. package/dist/{chunk-H7QUDDKH.js → chunk-2JMLDZLP.js} +1069 -182
  45. package/dist/chunk-2JMLDZLP.js.map +1 -0
  46. package/dist/{chunk-B6GIW55K.js → chunk-32XKCNCL.js} +6 -3
  47. package/dist/chunk-32XKCNCL.js.map +1 -0
  48. package/dist/{chunk-4MQS7CAF.js → chunk-3BEY4WK3.js} +371 -175
  49. package/dist/chunk-3BEY4WK3.js.map +1 -0
  50. package/dist/{chunk-SH5D7U7N.js → chunk-3KHYGOEY.js} +3 -3
  51. package/dist/{chunk-SH5D7U7N.js.map → chunk-3KHYGOEY.js.map} +1 -1
  52. package/dist/{chunk-CGT45WN7.js → chunk-3MKPZZRE.js} +3 -3
  53. package/dist/{chunk-CGT45WN7.js.map → chunk-3MKPZZRE.js.map} +1 -1
  54. package/dist/{chunk-QVNRCDTV.js → chunk-4OV5DSBB.js} +4 -4
  55. package/dist/chunk-4OV5DSBB.js.map +1 -0
  56. package/dist/{chunk-GXXFLBUQ.js → chunk-4P3KTUZH.js} +33 -33
  57. package/dist/chunk-4P3KTUZH.js.map +1 -0
  58. package/dist/{chunk-I6NLLJHZ.js → chunk-5QI2JYJC.js} +2 -2
  59. package/dist/{chunk-I6NLLJHZ.js.map → chunk-5QI2JYJC.js.map} +1 -1
  60. package/dist/{chunk-EF7NPDDU.js → chunk-6HHE63CO.js} +31 -17
  61. package/dist/chunk-6HHE63CO.js.map +1 -0
  62. package/dist/{chunk-FTJJO3EM.js → chunk-7CR6HT2X.js} +10 -10
  63. package/dist/{chunk-FTJJO3EM.js.map → chunk-7CR6HT2X.js.map} +1 -1
  64. package/dist/{chunk-FZNG4V4J.js → chunk-7I5VRVDP.js} +3 -3
  65. package/dist/{chunk-FZNG4V4J.js.map → chunk-7I5VRVDP.js.map} +1 -1
  66. package/dist/{chunk-HG34RNTK.js → chunk-CLTHEKHR.js} +10 -9
  67. package/dist/chunk-CLTHEKHR.js.map +1 -0
  68. package/dist/{chunk-UMVKJM4Q.js → chunk-DALV4HHP.js} +18 -3
  69. package/dist/chunk-DALV4HHP.js.map +1 -0
  70. package/dist/{chunk-F3RDEH5U.js → chunk-F4NJDSR7.js} +6 -5
  71. package/dist/chunk-F4NJDSR7.js.map +1 -0
  72. package/dist/{chunk-LSXHED6I.js → chunk-FRPBSUFH.js} +6 -6
  73. package/dist/{chunk-LSXHED6I.js.map → chunk-FRPBSUFH.js.map} +1 -1
  74. package/dist/{chunk-W5DWWE4Y.js → chunk-G54USEUP.js} +4 -4
  75. package/dist/{chunk-W5DWWE4Y.js.map → chunk-G54USEUP.js.map} +1 -1
  76. package/dist/{chunk-Y7QA2OLD.js → chunk-GEWAIQZ5.js} +24 -20
  77. package/dist/chunk-GEWAIQZ5.js.map +1 -0
  78. package/dist/{chunk-GB7WDMH2.js → chunk-GFCXNFTW.js} +4 -4
  79. package/dist/{chunk-GB7WDMH2.js.map → chunk-GFCXNFTW.js.map} +1 -1
  80. package/dist/{chunk-AWQYXZVG.js → chunk-HJ5MCB3L.js} +28 -4
  81. package/dist/chunk-HJ5MCB3L.js.map +1 -0
  82. package/dist/{chunk-2LWYNQK7.js → chunk-HOHUEKES.js} +3 -3
  83. package/dist/{chunk-2LWYNQK7.js.map → chunk-HOHUEKES.js.map} +1 -1
  84. package/dist/{chunk-ZKSJMZKD.js → chunk-IJHH4DSW.js} +8 -8
  85. package/dist/{chunk-ZKSJMZKD.js.map → chunk-IJHH4DSW.js.map} +1 -1
  86. package/dist/{chunk-BTE2V4IW.js → chunk-IXWODEED.js} +40 -7
  87. package/dist/chunk-IXWODEED.js.map +1 -0
  88. package/dist/{chunk-OFBIWVCR.js → chunk-JFXQEVLF.js} +3 -3
  89. package/dist/{chunk-OFBIWVCR.js.map → chunk-JFXQEVLF.js.map} +1 -1
  90. package/dist/{chunk-JAKOMFC6.js → chunk-JZCSNEHK.js} +77 -31
  91. package/dist/chunk-JZCSNEHK.js.map +1 -0
  92. package/dist/{chunk-CKQEIY43.js → chunk-MVQ3Q2HM.js} +4 -4
  93. package/dist/{chunk-CKQEIY43.js.map → chunk-MVQ3Q2HM.js.map} +1 -1
  94. package/dist/{chunk-LEMHVDET.js → chunk-NRDSGLCQ.js} +188 -33
  95. package/dist/chunk-NRDSGLCQ.js.map +1 -0
  96. package/dist/{chunk-V2DXZYBB.js → chunk-NWDSLXOX.js} +3 -3
  97. package/dist/{chunk-V2DXZYBB.js.map → chunk-NWDSLXOX.js.map} +1 -1
  98. package/dist/{chunk-6GRX5L6A.js → chunk-OBVJ7RPW.js} +4 -4
  99. package/dist/{chunk-6GRX5L6A.js.map → chunk-OBVJ7RPW.js.map} +1 -1
  100. package/dist/{chunk-PTSGWKHR.js → chunk-OOWHXOK6.js} +4 -4
  101. package/dist/{chunk-PTSGWKHR.js.map → chunk-OOWHXOK6.js.map} +1 -1
  102. package/dist/{chunk-YSHVQGUS.js → chunk-PE36IF2D.js} +119 -30
  103. package/dist/chunk-PE36IF2D.js.map +1 -0
  104. package/dist/{chunk-S53LOR7B.js → chunk-QG3HOJEK.js} +3 -3
  105. package/dist/{chunk-S53LOR7B.js.map → chunk-QG3HOJEK.js.map} +1 -1
  106. package/dist/{chunk-2FRUUDZY.js → chunk-SBFW3CJH.js} +5 -5
  107. package/dist/{chunk-2FRUUDZY.js.map → chunk-SBFW3CJH.js.map} +1 -1
  108. package/dist/{chunk-UAROCOXF.js → chunk-SX5U422E.js} +3 -3
  109. package/dist/{chunk-UAROCOXF.js.map → chunk-SX5U422E.js.map} +1 -1
  110. package/dist/{chunk-QOP6KDFR.js → chunk-TH4CTXHX.js} +6 -6
  111. package/dist/{chunk-QOP6KDFR.js.map → chunk-TH4CTXHX.js.map} +1 -1
  112. package/dist/{chunk-F2EKONM7.js → chunk-TRSQP3JD.js} +3 -3
  113. package/dist/{chunk-F2EKONM7.js.map → chunk-TRSQP3JD.js.map} +1 -1
  114. package/dist/{chunk-FVJK4QWM.js → chunk-V5TZH4GF.js} +4 -4
  115. package/dist/{chunk-FVJK4QWM.js.map → chunk-V5TZH4GF.js.map} +1 -1
  116. package/dist/{chunk-HYDRDNKN.js → chunk-V7PQZOBR.js} +5 -5
  117. package/dist/{chunk-HYDRDNKN.js.map → chunk-V7PQZOBR.js.map} +1 -1
  118. package/dist/{chunk-IONAUNWB.js → chunk-VLXDXRRX.js} +3 -3
  119. package/dist/{chunk-IONAUNWB.js.map → chunk-VLXDXRRX.js.map} +1 -1
  120. package/dist/{chunk-CIFS5K6T.js → chunk-VMKMFS2Q.js} +28 -7
  121. package/dist/chunk-VMKMFS2Q.js.map +1 -0
  122. package/dist/{chunk-Y4N2NUZD.js → chunk-WBYDAL6X.js} +4 -4
  123. package/dist/{chunk-Y4N2NUZD.js.map → chunk-WBYDAL6X.js.map} +1 -1
  124. package/dist/{chunk-WTQ3TATB.js → chunk-X4BAYGMT.js} +3 -3
  125. package/dist/{chunk-WTQ3TATB.js.map → chunk-X4BAYGMT.js.map} +1 -1
  126. package/dist/{chunk-NPLPCRW5.js → chunk-XCNK4UE5.js} +5 -5
  127. package/dist/{chunk-NPLPCRW5.js.map → chunk-XCNK4UE5.js.map} +1 -1
  128. package/dist/{chunk-OJ4N4T4H.js → chunk-XDVR7QIT.js} +20 -6
  129. package/dist/chunk-XDVR7QIT.js.map +1 -0
  130. package/dist/{chunk-GTILM2CI.js → chunk-Y34MSWEZ.js} +43 -12
  131. package/dist/chunk-Y34MSWEZ.js.map +1 -0
  132. package/dist/{chunk-4PTSR4UU.js → chunk-Y63UQZ7P.js} +3 -3
  133. package/dist/{chunk-4PTSR4UU.js.map → chunk-Y63UQZ7P.js.map} +1 -1
  134. package/dist/chunk-YBQONMH2.js +465 -0
  135. package/dist/chunk-YBQONMH2.js.map +1 -0
  136. package/dist/{chunk-P23M65LB.js → chunk-Z2K6BGUR.js} +71 -24
  137. package/dist/chunk-Z2K6BGUR.js.map +1 -0
  138. package/dist/{chunk-BJNUNQAW.js → chunk-ZGQTS3Y4.js} +3 -3
  139. package/dist/{chunk-BJNUNQAW.js.map → chunk-ZGQTS3Y4.js.map} +1 -1
  140. package/dist/cli/index.js +913 -720
  141. package/dist/cli/index.js.map +1 -1
  142. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  143. package/dist/cli/src/commands/catalog.d.ts +8 -5
  144. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  145. package/dist/cli/src/commands/diff.d.ts +3 -1
  146. package/dist/cli/src/commands/diff.d.ts.map +1 -1
  147. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  148. package/dist/cli/src/commands/library-index.d.ts +34 -2
  149. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  150. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  151. package/dist/cli/src/commands/manage.d.ts +6 -5
  152. package/dist/cli/src/commands/manage.d.ts.map +1 -1
  153. package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
  154. package/dist/cli/src/commands/outdated.d.ts +7 -5
  155. package/dist/cli/src/commands/outdated.d.ts.map +1 -1
  156. package/dist/cli/src/commands/project.d.ts +11 -8
  157. package/dist/cli/src/commands/project.d.ts.map +1 -1
  158. package/dist/cli/src/commands/source.d.ts +30 -1
  159. package/dist/cli/src/commands/source.d.ts.map +1 -1
  160. package/dist/cli/src/commands/update.d.ts.map +1 -1
  161. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  162. package/dist/cli/src/commands/why.d.ts.map +1 -1
  163. package/dist/cli/src/skill-checks.d.ts +47 -2
  164. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  165. package/dist/client/index.js +1 -1
  166. package/dist/client/src/client.d.ts +10 -3
  167. package/dist/client/src/client.d.ts.map +1 -1
  168. package/dist/connectors/config.js +5 -5
  169. package/dist/connectors/index.js +18 -18
  170. package/dist/{connectors-O6Y6VESP.js → connectors-OXP2JBGI.js} +21 -21
  171. package/dist/{connectors-O6Y6VESP.js.map → connectors-OXP2JBGI.js.map} +1 -1
  172. package/dist/connectors-shared/index.js +2 -2
  173. package/dist/core/index.js +7 -7
  174. package/dist/core/logging.js +1 -1
  175. package/dist/core/manifest.js +2 -2
  176. package/dist/core/models.js +1 -1
  177. package/dist/core/publish-manifest.js +2 -2
  178. package/dist/core/ref.js +1 -1
  179. package/dist/core/runtime-assets.js +5 -5
  180. package/dist/core/src/index.d.ts +2 -1
  181. package/dist/core/src/index.d.ts.map +1 -1
  182. package/dist/core/src/lock.d.ts +5 -2
  183. package/dist/core/src/lock.d.ts.map +1 -1
  184. package/dist/core/src/logging/sinks/sqlite-runtime.d.ts.map +1 -1
  185. package/dist/core/src/manifest.d.ts.map +1 -1
  186. package/dist/core/src/models.d.ts +21 -5
  187. package/dist/core/src/models.d.ts.map +1 -1
  188. package/dist/core/src/publish-manifest.d.ts +19 -3
  189. package/dist/core/src/publish-manifest.d.ts.map +1 -1
  190. package/dist/core/src/repo-manager.d.ts.map +1 -1
  191. package/dist/core/src/requirements.d.ts +26 -0
  192. package/dist/core/src/requirements.d.ts.map +1 -0
  193. package/dist/core/src/walker.d.ts.map +1 -1
  194. package/dist/core/src/workspace-config.d.ts +18 -0
  195. package/dist/core/src/workspace-config.d.ts.map +1 -1
  196. package/dist/core/src/workspace-yaml-editor.d.ts +4 -1
  197. package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
  198. package/dist/core/workspace-config.js +4 -4
  199. package/dist/deploy/index.js +7 -7
  200. package/dist/discovery/index.js +5 -5
  201. package/dist/discovery/src/builtin-providers.d.ts.map +1 -1
  202. package/dist/discovery/src/discover-manifest.d.ts.map +1 -1
  203. package/dist/discovery/src/discover.d.ts.map +1 -1
  204. package/dist/discovery/src/source-config.d.ts.map +1 -1
  205. package/dist/discovery/src/tree-entries.d.ts.map +1 -1
  206. package/dist/{ensure-sources-SKLNM4UZ.js → ensure-sources-5ISVIA4T.js} +17 -17
  207. package/dist/{ensure-sources-SKLNM4UZ.js.map → ensure-sources-5ISVIA4T.js.map} +1 -1
  208. package/dist/factory-assets/connectors/box.js +18 -18
  209. package/dist/factory-assets/connectors/deploy.js +18 -18
  210. package/dist/factory-assets/connectors/devserver.js +18 -18
  211. package/dist/factory-assets/connectors/flow/adapter.js +18 -18
  212. package/dist/factory-assets/connectors/flow/engine.js +8 -8
  213. package/dist/factory-assets/connectors/flow/run-flow.js +20 -20
  214. package/dist/factory-assets/connectors/flow.js +18 -18
  215. package/dist/factory-assets/connectors/git.js +18 -18
  216. package/dist/factory-assets/connectors/gmail.js +18 -18
  217. package/dist/factory-assets/connectors/googledrive.js +18 -18
  218. package/dist/factory-assets/connectors/local.js +18 -18
  219. package/dist/factory-assets/connectors/mattermost.js +18 -18
  220. package/dist/factory-assets/connectors/memory.js +18 -18
  221. package/dist/factory-assets/connectors/minio.js +18 -18
  222. package/dist/factory-assets/connectors/postgres.js +18 -18
  223. package/dist/factory-assets/connectors/s3.js +18 -18
  224. package/dist/factory-assets/connectors/sharepoint.js +18 -18
  225. package/dist/factory-assets/connectors/sqlite.js +18 -18
  226. package/dist/factory-assets/connectors/static-server.js +18 -18
  227. package/dist/factory-assets/connectors/tunnel.js +18 -18
  228. package/dist/factory-assets/connectors/webdav.js +18 -18
  229. package/dist/factory-assets/connectors/xstate-store.js +18 -18
  230. package/dist/factory-assets/connectors/xstate.js +18 -18
  231. package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +9 -3
  232. package/dist/{flows-CBYRSAGS.js → flows-HMSE76PO.js} +12 -12
  233. package/dist/{flows-CBYRSAGS.js.map → flows-HMSE76PO.js.map} +1 -1
  234. package/dist/{helpers-MWZDRBLD.js → helpers-X6URBGSF.js} +17 -17
  235. package/dist/{helpers-MWZDRBLD.js.map → helpers-X6URBGSF.js.map} +1 -1
  236. package/dist/library/index.js +11 -11
  237. package/dist/library/install.js +3 -3
  238. package/dist/library/src/index.d.ts +2 -1
  239. package/dist/library/src/index.d.ts.map +1 -1
  240. package/dist/library/src/local/library-dir.d.ts +42 -0
  241. package/dist/library/src/local/library-dir.d.ts.map +1 -0
  242. package/dist/library/src/local/library-manager.d.ts +10 -1
  243. package/dist/library/src/local/library-manager.d.ts.map +1 -1
  244. package/dist/library/src/local/library.d.ts +2 -2
  245. package/dist/library/src/local/library.d.ts.map +1 -1
  246. package/dist/library/src/local/local-catalog-source.d.ts +9 -0
  247. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  248. package/dist/library/src/manifest-writer.d.ts +55 -4
  249. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  250. package/dist/library/src/remote/cache.d.ts +18 -1
  251. package/dist/library/src/remote/cache.d.ts.map +1 -1
  252. package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
  253. package/dist/library/src/remote/rest-catalog-source.d.ts.map +1 -1
  254. package/dist/library/src/sync/git-driver.d.ts +5 -6
  255. package/dist/library/src/sync/git-driver.d.ts.map +1 -1
  256. package/dist/{library-publish-PICMDSB2.js → library-publish-OS3JDW4S.js} +123 -41
  257. package/dist/library-publish-OS3JDW4S.js.map +1 -0
  258. package/dist/open-library-4QSUORI6.js +40 -0
  259. package/dist/{open-library-OG457THY.js.map → open-library-4QSUORI6.js.map} +1 -1
  260. package/dist/open-registry-VCKS3MP5.js +32 -0
  261. package/dist/{open-registry-ZUZJ7MS7.js.map → open-registry-VCKS3MP5.js.map} +1 -1
  262. package/dist/paths-BVO56A25.js +22 -0
  263. package/dist/{paths-FQ64OLJG.js.map → paths-BVO56A25.js.map} +1 -1
  264. package/dist/{plugin-store-MPAMD5OT.js → plugin-store-X7GPWGBG.js} +9 -9
  265. package/dist/{plugin-store-MPAMD5OT.js.map → plugin-store-X7GPWGBG.js.map} +1 -1
  266. package/dist/{project-2GFT5LEZ.js → project-PAXP46RD.js} +20 -20
  267. package/dist/{project-2GFT5LEZ.js.map → project-PAXP46RD.js.map} +1 -1
  268. package/dist/resolver/index.js +8 -8
  269. package/dist/runner/index.js +32 -32
  270. package/dist/runner/src/agent.d.ts.map +1 -1
  271. package/dist/runner/src/context-usage/compose.d.ts.map +1 -1
  272. package/dist/runner/src/platform-blocks.d.ts +55 -0
  273. package/dist/runner/src/platform-blocks.d.ts.map +1 -0
  274. package/dist/runner/src/serve.d.ts.map +1 -1
  275. package/dist/runner/src/session-builder.d.ts.map +1 -1
  276. package/dist/sdk/asset-manager.js +14 -14
  277. package/dist/sdk/bridge.js +14 -14
  278. package/dist/sdk/client.js +1 -1
  279. package/dist/sdk/core.js +7 -7
  280. package/dist/sdk/flow.js +8 -8
  281. package/dist/sdk/index.js +33 -33
  282. package/dist/sdk/resolver.js +8 -8
  283. package/dist/sdk/runner.js +32 -32
  284. package/dist/sdk/session.js +2 -2
  285. package/dist/sdk/types.js +1 -1
  286. package/dist/session/index.js +2 -2
  287. package/dist/session/src/dispatcher.d.ts +25 -4
  288. package/dist/session/src/dispatcher.d.ts.map +1 -1
  289. package/dist/session/src/index.d.ts +1 -1
  290. package/dist/session/src/index.d.ts.map +1 -1
  291. package/dist/{setup-WHMCSIF2.js → setup-BV55VHWC.js} +24 -24
  292. package/dist/{setup-WHMCSIF2.js.map → setup-BV55VHWC.js.map} +1 -1
  293. package/dist/{skills-TVO26Y4V.js → skills-EDFUCJPX.js} +13 -13
  294. package/dist/{skills-TVO26Y4V.js.map → skills-EDFUCJPX.js.map} +1 -1
  295. package/dist/source-E4VAT5RZ.js +41 -0
  296. package/dist/{source-LKOFTOEK.js.map → source-E4VAT5RZ.js.map} +1 -1
  297. package/dist/{source-manifest-publish-L5J3QXER.js → source-manifest-publish-CLEE6TNH.js} +23 -23
  298. package/dist/{source-manifest-publish-L5J3QXER.js.map → source-manifest-publish-CLEE6TNH.js.map} +1 -1
  299. package/dist/tui/index.js +32 -32
  300. package/dist/types/index.js +1 -1
  301. package/dist/types/manifests.js +1 -1
  302. package/dist/types/src/events.d.ts +1 -1
  303. package/dist/types/src/events.d.ts.map +1 -1
  304. package/dist/types/src/index.d.ts +2 -2
  305. package/dist/types/src/index.d.ts.map +1 -1
  306. package/dist/types/src/manifests/agent.d.ts +2 -0
  307. package/dist/types/src/manifests/agent.d.ts.map +1 -1
  308. package/dist/types/src/manifests/contract.d.ts +2 -0
  309. package/dist/types/src/manifests/contract.d.ts.map +1 -1
  310. package/dist/types/src/manifests/index.d.ts +3 -3
  311. package/dist/types/src/manifests/index.d.ts.map +1 -1
  312. package/dist/types/src/manifests/prompt.d.ts +2 -0
  313. package/dist/types/src/manifests/prompt.d.ts.map +1 -1
  314. package/dist/types/src/protocol.d.ts +43 -1
  315. package/dist/types/src/protocol.d.ts.map +1 -1
  316. package/dist/types/src/version.d.ts +17 -1
  317. package/dist/types/src/version.d.ts.map +1 -1
  318. package/dist/workspace-plugin/adapters/mcp.js +25 -25
  319. package/dist/workspace-plugin/adapters/omp.js +14 -14
  320. package/dist/workspace-plugin/index.js +2 -2
  321. package/package.json +1 -1
  322. package/dist/chunk-36AFURKZ.js.map +0 -1
  323. package/dist/chunk-4MQS7CAF.js.map +0 -1
  324. package/dist/chunk-AWQYXZVG.js.map +0 -1
  325. package/dist/chunk-B6GIW55K.js.map +0 -1
  326. package/dist/chunk-BTE2V4IW.js.map +0 -1
  327. package/dist/chunk-CIFS5K6T.js.map +0 -1
  328. package/dist/chunk-EF7NPDDU.js.map +0 -1
  329. package/dist/chunk-F3RDEH5U.js.map +0 -1
  330. package/dist/chunk-GTILM2CI.js.map +0 -1
  331. package/dist/chunk-GXXFLBUQ.js.map +0 -1
  332. package/dist/chunk-H7QUDDKH.js.map +0 -1
  333. package/dist/chunk-HG34RNTK.js.map +0 -1
  334. package/dist/chunk-JAKOMFC6.js.map +0 -1
  335. package/dist/chunk-LEMHVDET.js.map +0 -1
  336. package/dist/chunk-OJ4N4T4H.js.map +0 -1
  337. package/dist/chunk-P23M65LB.js.map +0 -1
  338. package/dist/chunk-QVNRCDTV.js.map +0 -1
  339. package/dist/chunk-UMVKJM4Q.js.map +0 -1
  340. package/dist/chunk-Y7QA2OLD.js.map +0 -1
  341. package/dist/chunk-YSHVQGUS.js.map +0 -1
  342. package/dist/chunk-ZAOGFXDO.js +0 -112
  343. package/dist/chunk-ZAOGFXDO.js.map +0 -1
  344. package/dist/library-publish-PICMDSB2.js.map +0 -1
  345. package/dist/open-library-OG457THY.js +0 -40
  346. package/dist/open-registry-ZUZJ7MS7.js +0 -32
  347. package/dist/paths-FQ64OLJG.js +0 -22
  348. package/dist/source-LKOFTOEK.js +0 -41
@@ -1,13 +1,13 @@
1
- import { openLibraryManager } from './chunk-HG34RNTK.js';
2
- import { logErr, logInfo, logWarn, logOk, S } from './chunk-F2EKONM7.js';
3
- import { getKindRegistry } from './chunk-2FRUUDZY.js';
4
- import { getStoreManifestsDir, LocalCatalogSource, curatedManifestOverlay, writeCuratedManifest } from './chunk-4MQS7CAF.js';
5
- import { computeDeterministicHash, discoverAssetsInTree } from './chunk-Y7QA2OLD.js';
6
- import { WorkspaceYamlEditor } from './chunk-36AFURKZ.js';
7
- import { findWorkspaceRoot, workspaceConfigFilename, sourceShortName, sourceCacheKey, storeManifestSlug, getGlobalCacheDir, attachToBranch, legacySourceCacheKey, resolveSourcePublisher } from './chunk-JAKOMFC6.js';
1
+ import { openLibraryManager } from './chunk-CLTHEKHR.js';
2
+ import { logErr, logInfo, logWarn, logOk, S } from './chunk-TRSQP3JD.js';
3
+ import { getKindRegistry } from './chunk-SBFW3CJH.js';
4
+ import { getStoreManifestsDir, LocalCatalogSource, curatedManifestOverlay, writeCuratedManifest } from './chunk-3BEY4WK3.js';
5
+ import { computeDeterministicHash, discoverAssetsInTree } from './chunk-GEWAIQZ5.js';
6
+ import { WorkspaceYamlEditor } from './chunk-2FMEGSBN.js';
7
+ import { findWorkspaceRoot, workspaceConfigFilename, sourceShortName, sourceCacheKey, storeManifestSlug, getGlobalCacheDir, attachToBranch, legacySourceCacheKey, resolveSourcePublisher } from './chunk-JZCSNEHK.js';
8
8
  import { globalCacheRoot } from './chunk-L5VSIPQD.js';
9
- import { decodeSkaileManifest, encodeSkaileManifest } from './chunk-BTE2V4IW.js';
10
- import { parseAssetRef } from './chunk-QVNRCDTV.js';
9
+ import { decodeSkaileManifest, encodeSkaileManifest } from './chunk-IXWODEED.js';
10
+ import { parseAssetRef } from './chunk-4OV5DSBB.js';
11
11
  import { spawnSync } from 'child_process';
12
12
  import { existsSync, rmSync, renameSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
13
13
  import * as path2 from 'path';
@@ -316,12 +316,12 @@ function addSourceManifestCommands(src) {
316
316
  ).option("-C, --project-dir <dir>", "Project directory", process.cwd()).option("--publisher <name>", "Override the publisher (--overwrite only)").option("--dev", "Include assets under the source's dev_paths", false).option("--overwrite", "Discard curation and re-scan the full inventory", false).action((arg, opts) => runRebuild(arg, opts));
317
317
  manifest.command("verify <src>").description("Verify hashes, deps, and schema (read-only)").option("-C, --project-dir <dir>", "Project directory", process.cwd()).option("--strict", "Fail on advisory checks (warnings force a nonzero exit)", false).action((arg, opts) => runVerify(arg, opts));
318
318
  manifest.command("publish <src>").description("Push the curated sidecar manifest and publish it to the store").option("-C, --project-dir <dir>", "Project directory", process.cwd()).option("--as <namespace>", "Publisher namespace (default: your store username)").option("--sidecar-repo <url>", "Public GitHub repo you own to hold the curated manifest").option("--ref <gitref>", "Foreign source ref to ingest (branch/sha; default: main)").option("--dry-run", "Print the publish plan without pushing or calling the store", false).action(async (arg, opts) => {
319
- const { runPublish } = await import('./source-manifest-publish-L5J3QXER.js');
319
+ const { runPublish } = await import('./source-manifest-publish-CLEE6TNH.js');
320
320
  await runPublish(arg, opts);
321
321
  });
322
322
  manifest.command("propose <src>").description("Open a PR to upstream with the sidecar manifest").action(() => notWired("propose"));
323
323
  manifest.command("yank <src>").description("Retract the source's published assets from the store").option("-C, --project-dir <dir>", "Project directory", process.cwd()).option("--asset <ref>", "Yank only the asset matching this ref/name").action(async (arg, opts) => {
324
- const { runYank } = await import('./source-manifest-publish-L5J3QXER.js');
324
+ const { runYank } = await import('./source-manifest-publish-CLEE6TNH.js');
325
325
  await runYank(arg, opts);
326
326
  });
327
327
  }
@@ -356,6 +356,32 @@ function sourceMatchesKey(entry, key) {
356
356
  if (sourceCacheKey(entry.url) === key || sourceShortName(entry.url) === key) return true;
357
357
  return entry.url === normalizeSourceUrl(key);
358
358
  }
359
+ function sourceLabel(entry, all) {
360
+ const short = sourceShortName(entry.url);
361
+ const shared = all.some((s) => s.url !== entry.url && sourceShortName(s.url) === short);
362
+ return shared ? sourceCacheKey(entry.url) : short;
363
+ }
364
+ function resolveSource(sources, key) {
365
+ const tiers = [
366
+ (s) => s.url === key,
367
+ (s) => sourceCacheKey(s.url) === key,
368
+ (s) => sourceShortName(s.url) === key || s.url === normalizeSourceUrl(key)
369
+ ];
370
+ for (const tier of tiers) {
371
+ const hits = sources.filter(tier);
372
+ if (hits.length === 1) return { kind: "one", entry: hits[0] };
373
+ if (hits.length > 1) return { kind: "ambiguous", entries: hits };
374
+ }
375
+ return { kind: "none" };
376
+ }
377
+ function exitAmbiguousSource(key, entries) {
378
+ logErr(`"${key}" matches ${entries.length} sources; pass the URL of the one you mean:`);
379
+ for (const e of entries) console.error(` ${e.url}`);
380
+ process.exit(1);
381
+ }
382
+ function pullFailureReason(stderr) {
383
+ return stderr.split("\n").map((l) => l.trim()).filter((l) => l !== "" && !/^(hint:|From |[*+=!-] )/.test(l)).join(" ");
384
+ }
359
385
  function findCacheKeyCollision(sources, url) {
360
386
  const key = sourceCacheKey(url);
361
387
  return sources.find((s) => s.url !== url && sourceCacheKey(s.url) === key);
@@ -411,8 +437,7 @@ function pullSourceClone(dest, entry) {
411
437
  encoding: "utf8"
412
438
  });
413
439
  if (pull.status === 0) return { ok: true };
414
- const lastLine = pull.stderr.trim().split("\n").pop()?.trim();
415
- const reason = lastLine || `git exited with status ${pull.status}`;
440
+ const reason = pullFailureReason(pull.stderr) || `git exited with status ${pull.status}`;
416
441
  return { ok: false, error: `git pull failed: ${reason}` };
417
442
  }
418
443
  function sourceLibraryName(url, libs) {
@@ -505,6 +530,22 @@ async function syncProjectSources(projectDir, opts = {}) {
505
530
  }
506
531
  return { total: sources.length, synced, failed };
507
532
  }
533
+ function divergedSourceClones(projectDir) {
534
+ const root = findWorkspaceRoot(projectDir) ?? projectDir;
535
+ const diverged = [];
536
+ for (const entry of readProjectSources(path2.join(root, workspaceConfigFilename()))) {
537
+ const dest = sourceClonePath(sourceCacheKey(entry.url));
538
+ if (!existsSync(dest)) continue;
539
+ const ahead = spawnSync("git", ["-C", dest, "rev-list", "--count", "@{upstream}..HEAD"], {
540
+ stdio: "pipe",
541
+ encoding: "utf8"
542
+ });
543
+ if (ahead.status === 0 && Number(ahead.stdout.trim()) > 0) {
544
+ diverged.push(sourceShortName(entry.url));
545
+ }
546
+ }
547
+ return diverged;
548
+ }
508
549
  async function dropManifestCache(url, purgeClone) {
509
550
  const dest = sourceClonePath(sourceCacheKey(url));
510
551
  const { manager, close } = await openLibraryManager();
@@ -597,7 +638,7 @@ function makeSourceCommand() {
597
638
  console.log();
598
639
  console.log(S.heading(" Sources"));
599
640
  for (const s of sources) {
600
- const slug = sourceShortName(s.url);
641
+ const slug = sourceLabel(s, sources);
601
642
  const cached = existsSync(sourceClonePath(sourceCacheKey(s.url))) ? "" : S.warn(" (not cached)");
602
643
  console.log(` ${S.cmd(slug.padEnd(24))} ${S.dim(s.url)}${cached}`);
603
644
  }
@@ -607,12 +648,15 @@ function makeSourceCommand() {
607
648
  });
608
649
  cmd.command("show <name-or-url>").description("Show details for a source (matched by URL or derived slug)").action(async (key) => {
609
650
  const yamlPath = requireProjectYamlPath();
610
- const entry = readProjectSources(yamlPath).find((s) => sourceMatchesKey(s, key));
611
- if (!entry) {
651
+ const all = readProjectSources(yamlPath);
652
+ const resolved = resolveSource(all, key);
653
+ if (resolved.kind === "none") {
612
654
  logErr(`No source matching "${key}" in ${yamlPath}.`);
613
655
  process.exit(1);
614
656
  }
615
- const slug = sourceShortName(entry.url);
657
+ if (resolved.kind === "ambiguous") exitAmbiguousSource(key, resolved.entries);
658
+ const entry = resolved.entry;
659
+ const slug = sourceLabel(entry, all);
616
660
  const clonePath = sourceClonePath(sourceCacheKey(entry.url));
617
661
  console.log(
618
662
  JSON.stringify(
@@ -634,12 +678,15 @@ function makeSourceCommand() {
634
678
  ).action(async (key, opts) => {
635
679
  const yamlPath = requireProjectYamlPath();
636
680
  const editor = WorkspaceYamlEditor.load(yamlPath);
637
- const match = editor.getSources().find((s) => sourceMatchesKey(s, key));
638
- if (!match) {
681
+ const all = editor.getSources();
682
+ const resolved = resolveSource(all, key);
683
+ if (resolved.kind === "none") {
639
684
  logErr(`No source matching "${key}" in ${yamlPath}.`);
640
685
  process.exit(1);
641
686
  }
642
- const slug = sourceShortName(match.url);
687
+ if (resolved.kind === "ambiguous") exitAmbiguousSource(key, resolved.entries);
688
+ const match = resolved.entry;
689
+ const slug = sourceLabel(match, all);
643
690
  editor.removeSource(match.url);
644
691
  editor.save();
645
692
  await dropManifestCache(match.url, opts.purge);
@@ -681,7 +728,7 @@ function makeSourceCommand() {
681
728
  targets = sources.filter((s) => picked.has(s.url));
682
729
  }
683
730
  for (const entry of targets) {
684
- const slug = sourceShortName(entry.url);
731
+ const slug = sourceLabel(entry, sources);
685
732
  const dest = sourceClonePath(sourceCacheKey(entry.url));
686
733
  if (!existsSync(dest)) {
687
734
  ensureClone(entry);
@@ -725,6 +772,6 @@ function makeSourceCommand() {
725
772
  return cmd;
726
773
  }
727
774
 
728
- export { autoSyncForSearch, ensureClone, findCacheKeyCollision, indexingHadFailures, legacySourceConfigHint, makeSourceCommand, normalizeSourceUrl, pullSourceClone, readProjectSources, resolveSourceArg, sourceClonePath, sourceMatchesKey, syncProjectSources };
729
- //# sourceMappingURL=chunk-P23M65LB.js.map
730
- //# sourceMappingURL=chunk-P23M65LB.js.map
775
+ export { autoSyncForSearch, divergedSourceClones, ensureClone, findCacheKeyCollision, indexingHadFailures, legacySourceConfigHint, makeSourceCommand, normalizeSourceUrl, pullSourceClone, readProjectSources, resolveSource, resolveSourceArg, sourceClonePath, sourceLabel, sourceMatchesKey, syncProjectSources };
776
+ //# sourceMappingURL=chunk-Z2K6BGUR.js.map
777
+ //# sourceMappingURL=chunk-Z2K6BGUR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../cli/src/commands/source-manifest.ts","../cli/src/commands/source.ts"],"names":["path","existsSync","spawnSync","dest"],"mappings":"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","file":"chunk-Z2K6BGUR.js","sourcesContent":["/**\n * `skaile source manifest …` — curated `skaile.manifest.yaml` lifecycle for a\n * source you do NOT own. `init` generates a curated manifest from a discovery\n * run and stores it OUTSIDE the source, under the local store catalog\n * (`~/.skaile/store/manifests/<slug>.yaml`); `edit` opens it in `$EDITOR` and\n * re-validates on save. `source add`/`sync` then apply it as a read overlay\n * (see `source.ts` `refreshManifestCache`).\n *\n * `rebuild` refreshes a curated manifest after an upstream change (merge by\n * default — curation is sacred; `--overwrite` re-scans). `verify` is a\n * read-only integrity check (paths, declared hashes, schema, dep refs).\n * `publish`/`propose`/`yank` remain stubs — they need the store publish\n * endpoint (`POST /sources/<id>/manifest`), which lands in a follow-up.\n *\n * @docLink cli/commands/source#manifest\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport {\n type AssetEntry,\n decodeSkaileManifest,\n encodeSkaileManifest,\n findWorkspaceRoot,\n parseAssetRef,\n resolveSourcePublisher,\n type SkPublishManifest,\n type SourceEntry,\n sourceCacheKey,\n sourceShortName,\n storeManifestSlug,\n workspaceConfigFilename,\n} from \"@skaile/workspaces/core\";\nimport { computeDeterministicHash, discoverAssetsInTree } from \"@skaile/workspaces/discovery\";\nimport { getStoreManifestsDir, writeCuratedManifest } from \"@skaile/workspaces/library\";\nimport type { Command } from \"commander\";\nimport { logErr, logInfo, logOk, logWarn, S } from \"../helpers.ts\";\nimport { getKindRegistry } from \"../open-registry.ts\";\nimport {\n ensureClone,\n normalizeSourceUrl,\n readProjectSources,\n sourceClonePath,\n sourceMatchesKey,\n} from \"./source.ts\";\n\nconst NOT_WIRED_MSG =\n \"`skaile source manifest *` is scaffolded but not yet wired. \" +\n \"Server-side endpoint (`POST /sources/<id>/manifest`) lands in a follow-up PR.\";\n\nfunction notWired(verb: string): never {\n logErr(`${NOT_WIRED_MSG} (verb: source manifest ${verb})`);\n process.exit(2);\n}\n\n/**\n * Resolve a `source manifest` argument into a `{ url, slug, dest }` triple.\n *\n * Resolution order:\n * 1. A key matching an already-registered project source (stored URL, cache\n * key, or short slug).\n * 2. A collision-free **store slug** (`<host>__<owner>__<repo>`) whose\n * manifest already exists at `~/.skaile/store/manifests/<arg>.yaml`. This\n * MUST be tried before bare-name expansion: a bare name like `cli` would\n * otherwise expand (via `normalizeSourceUrl`) to the skaile-ai org and a\n * DIFFERENT slug than the one `init` wrote (e.g. `larksuite`). The slug is\n * the exact identifier `init`'s next-step hint prints back.\n * 3. Otherwise a git URL / `owner/repo` / bare name via `normalizeSourceUrl`.\n *\n * The clone dir is the same URL-keyed cache `source add` uses.\n */\nexport function resolveSourceArg(\n arg: string,\n projectDir: string,\n): { url: string; slug: string; dest: string; manifestFile: string } {\n const root = findWorkspaceRoot(projectDir);\n const registered: SourceEntry[] = root\n ? readProjectSources(path.join(root, workspaceConfigFilename()))\n : [];\n const match = registered.find((e) => sourceMatchesKey(e, arg));\n const bySlug = !match ? resolveByStoreSlug(arg) : undefined;\n const url = match ? match.url : (bySlug?.url ?? normalizeSourceUrl(arg));\n const slug = sourceShortName(url); // human-facing label\n const dest = sourceClonePath(sourceCacheKey(url));\n return { url, slug, dest, manifestFile: bySlug?.manifestFile ?? storeManifestPath(url) };\n}\n\n/**\n * When `arg` is a bare store slug (`<host>__<owner>__<repo>`) whose curated\n * manifest already exists on disk, recover the source URL from the slug and\n * point at that manifest file directly. Returns `undefined` when the arg isn't\n * a slug or has no manifest yet (fall back to URL normalization).\n */\nfunction resolveByStoreSlug(arg: string): { url: string; manifestFile: string } | undefined {\n // A slug is our own encoding — no path/URL sigils, at least the `<host>__…`\n // separator. Anything URL/owner-repo shaped is not a slug.\n if (!/^[\\w.-]+__[\\w.-]+/.test(arg) || /[/:\\\\]/.test(arg)) return undefined;\n const manifestFile = path.join(getStoreManifestsDir(), `${arg}.yaml`);\n if (!existsSync(manifestFile)) return undefined;\n // `<host>__<owner>__<repo>` → `https://<host>/<owner>/<repo>` — good enough to\n // key the clone dir + re-derive the same slug; the manifest file is what edit\n // actually opens.\n const [host, owner, repo] = arg.split(\"__\");\n const url = host && owner && repo ? `https://${host}/${owner}/${repo}` : arg;\n return { url, manifestFile };\n}\n\n/**\n * Absolute path to a source's curated store manifest. Keyed by the\n * collision-free {@link storeManifestSlug} (`<host>__<owner>__<repo>`) so\n * `orgA/cli` and `orgB/cli` don't share `cli.yaml`.\n */\nfunction storeManifestPath(url: string): string {\n return path.join(getStoreManifestsDir(), `${storeManifestSlug(url)}.yaml`);\n}\n\n/**\n * Directory-name segments that mark a test-fixture tree. `init`/`rebuild` drop\n * any asset whose repo-relative root contains one of these as an exact path\n * SEGMENT. Repos routinely ship fixture \"skills\" under such dirs (e.g.\n * `scripts/skill-format-check/tests`, `internal/qualitygate/skillscan/testdata/skills/lark-demo`)\n * that are not real, publishable assets.\n */\nconst TEST_FIXTURE_SEGMENTS = new Set([\n \"tests\",\n \"test\",\n \"__tests__\",\n \"testdata\",\n \"fixtures\",\n \"__fixtures__\",\n]);\n\n/**\n * True when an asset's repo-relative `root` sits under a test-fixture directory\n * (see {@link TEST_FIXTURE_SEGMENTS}). Conservative, not repo-specific — finer\n * curation (keeping a genuine fixture asset) stays the user's job via `edit`.\n * `init`/`rebuild`-path only; the general discovery walk (`source add`) is\n * untouched.\n */\nfunction isTestFixtureAsset(relativePath: string): boolean {\n const segments = relativePath.replace(/\\\\/g, \"/\").split(\"/\");\n return segments.some((s) => TEST_FIXTURE_SEGMENTS.has(s));\n}\n\n/**\n * `source manifest init <src>` — clone (if needed), run discovery, and write a\n * curated `skaile.manifest.yaml` to `~/.skaile/store/manifests/<slug>.yaml`.\n */\nasync function runInit(\n arg: string,\n opts: { projectDir: string; publisher?: string; dev?: boolean; force?: boolean },\n): Promise<void> {\n const projectDir = path.resolve(opts.projectDir);\n const { url, dest, manifestFile: target } = resolveSourceArg(arg, projectDir);\n\n if (existsSync(target) && !opts.force) {\n logWarn(\n `A curated manifest already exists at ${S.dim(target)}. ` +\n \"Edit it with `skaile source manifest edit`, refresh it after an upstream \" +\n \"change with `skaile source manifest rebuild`, or pass --force to regenerate.\",\n );\n return;\n }\n\n const entry: SourceEntry = { url };\n ensureClone(entry);\n\n const { assets, errors } = discoverCuratableAssets(dest, opts.dev ?? false);\n\n const publisher = opts.publisher ?? resolveSourcePublisher(dest) ?? sourceShortName(url);\n\n const written = writeCuratedManifest({\n manifestFile: target,\n publisher,\n assets,\n force: opts.force,\n // Init: every asset inherits the top-level repo `publisher`. Do NOT stamp a\n // per-asset publisher — glob discovery here runs without the resolved\n // publisher, so each DiscoveredAsset.publisher is only the clone directory\n // name, which would clobber the intended org/`--publisher` default with\n // junk per-asset overrides.\n inheritPublisher: true,\n });\n\n if (!written.wrote) {\n logWarn(\n `Curated manifest already exists at ${S.dim(target)} — not overwritten. ` +\n \"Pass --force to regenerate.\",\n );\n return;\n }\n\n logOk(`Wrote curated manifest with ${written.assetCount} assets to ${S.dim(target)}.`);\n // Echo the EXACT <src> the user passed so the printed commands actually run.\n // A bare short name would mis-resolve through `normalizeSourceUrl` (→ the\n // skaile-ai org, wrong slug); the original arg is what `resolveSourceArg`\n // maps back to this same manifest.\n logInfo(\n `Edit it with \\`skaile source manifest edit ${arg}\\`, then ` +\n `\\`skaile source add ${arg}\\` to consume it.`,\n );\n if (errors.length > 0) {\n logWarn(`${errors.length} discovery error(s) — inspect the manifest before consuming.`);\n }\n}\n\n/**\n * Run discovery over a clone and drop the test-fixture assets (see\n * {@link isTestFixtureAsset}). Shared by `init` and `rebuild` so both paths\n * produce an identical inventory from the same tree.\n */\nfunction discoverCuratableAssets(\n dest: string,\n includeDev: boolean,\n): { assets: ReturnType<typeof discoverAssetsInTree>[\"assets\"]; errors: string[] } {\n const result = discoverAssetsInTree(dest, {\n registry: getKindRegistry(),\n includeDev,\n });\n const assets = result.assets.filter((a) => !isTestFixtureAsset(a.relativePath));\n return { assets, errors: result.errors.map((e) => `${e.path}: ${e.error}`) };\n}\n\n/**\n * Best-effort `git pull --ff-only` on an existing clone. Never throws: a pull\n * failure (offline, diverged, detached) is warned and the caller continues with\n * the clone as-is.\n */\nfunction pullCloneFfOnly(dest: string): void {\n const res = spawnSync(\"git\", [\"-C\", dest, \"pull\", \"--ff-only\"], { stdio: \"pipe\" });\n if (res.status !== 0) {\n logWarn(\n \"git pull --ff-only failed — continuing with the existing clone \" +\n \"(it may be behind upstream).\",\n );\n }\n}\n\n/**\n * Repo-relative `root` path for a manifest asset entry — the merge match key\n * between an existing curated entry and a freshly-discovered asset. `root:`\n * entries use their declared path; a `files:`-only entry (rare for a curated\n * sidecar) falls back to the entry's dirname of the first file, else the name.\n */\nfunction entryRootKey(entry: AssetEntry): string {\n if (entry.root) return entry.root.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n const files = entry.files;\n if (files && files.length > 0) {\n const first = typeof files[0] === \"string\" ? files[0] : files[0].path;\n const dir = path.posix.dirname(first.replace(/\\\\/g, \"/\"));\n return dir === \".\" ? entry.name : dir;\n }\n return entry.name;\n}\n\n/** Repo-relative `root` path a discovered asset maps to (matches init's writer). */\nfunction discoveredRootKey(relativePath: string): string {\n const dir = path.posix.dirname(relativePath.replace(/\\\\/g, \"/\"));\n return dir === \".\" ? path.posix.basename(relativePath.replace(/\\\\/g, \"/\")) : dir;\n}\n\n/** Human ref for reporting: `kind:name`. */\nfunction entryRef(entry: AssetEntry): string {\n return `${entry.kind}:${entry.name}`;\n}\n\n/**\n * `source manifest rebuild <src>` — refresh a curated manifest after the\n * upstream repo changed. MERGE is the default (curation is sacred); `--overwrite`\n * re-scans from scratch with `init --force` semantics.\n *\n * Merge algorithm (match by repo-relative `root` path):\n * - Existing entries whose root is STILL discovered → KEPT verbatim (all\n * hand-edits preserved).\n * - Existing entries whose root is GONE upstream → DROPPED (reported).\n * - Freshly-discovered assets not already in the manifest → NOT auto-added,\n * only REPORTED (a curated foreign sidecar must not silently absorb new\n * upstream skills). An asset the curator deliberately dropped stays dropped\n * because it is neither in the existing manifest nor re-added here.\n */\nasync function runRebuild(\n arg: string,\n opts: { projectDir: string; publisher?: string; dev?: boolean; overwrite?: boolean },\n): Promise<void> {\n const projectDir = path.resolve(opts.projectDir);\n const { url, dest, slug, manifestFile: target } = resolveSourceArg(arg, projectDir);\n\n if (!existsSync(target)) {\n logErr(\n `No curated manifest for \"${slug}\" at ${S.dim(target)} — ` +\n \"run `skaile source manifest init` first.\",\n );\n process.exit(1);\n }\n\n // Update the clone: clone if absent, else pull --ff-only (best-effort).\n const entry: SourceEntry = { url };\n const cloned = ensureClone(entry);\n if (!cloned) pullCloneFfOnly(dest);\n\n const { assets: freshAssets, errors } = discoverCuratableAssets(dest, opts.dev ?? false);\n\n if (opts.overwrite) {\n logWarn(\n \"--overwrite: replacing the curated manifest with a full fresh inventory. \" +\n \"All hand-curation (dropped assets, per-asset edits) is discarded.\",\n );\n const publisher = opts.publisher ?? resolveSourcePublisher(dest) ?? sourceShortName(url);\n const written = writeCuratedManifest({\n manifestFile: target,\n publisher,\n assets: freshAssets,\n force: true,\n inheritPublisher: true,\n });\n logOk(\n `Rebuilt curated manifest with ${written.assetCount} assets to ${S.dim(target)} (overwrite).`,\n );\n if (errors.length > 0) {\n logWarn(`${errors.length} discovery error(s) — inspect the manifest before consuming.`);\n }\n return;\n }\n\n // MERGE (default). `--publisher` only applies to the full re-derive path.\n if (opts.publisher) {\n logWarn(\n \"--publisher is ignored in merge mode (the curated publisher is preserved). \" +\n \"Use --overwrite to re-derive the publisher from a full re-scan.\",\n );\n }\n\n // Read the existing curated manifest and keep it as the base.\n const { manifest: existing } = decodeSkaileManifest(readFileSync(target, \"utf-8\"));\n const existingEntries = existing.assets ?? [];\n\n // Index fresh discovery by repo-relative root path.\n const freshByRoot = new Map<string, (typeof freshAssets)[number]>();\n for (const a of freshAssets) freshByRoot.set(discoveredRootKey(a.relativePath), a);\n\n const kept: AssetEntry[] = [];\n const dropped: string[] = [];\n for (const e of existingEntries) {\n if (freshByRoot.has(entryRootKey(e))) kept.push(e);\n else dropped.push(entryRef(e));\n }\n\n // Fresh assets not already curated → report as available, do NOT add.\n const existingRoots = new Set(existingEntries.map(entryRootKey));\n const newlyAvailable: string[] = [];\n for (const a of freshAssets) {\n if (!existingRoots.has(discoveredRootKey(a.relativePath))) {\n newlyAvailable.push(`${a.kind}:${a.name}`);\n }\n }\n\n const changed = dropped.length > 0;\n if (dropped.length > 0) {\n logWarn(`removed (gone upstream): ${dropped.sort().join(\", \")}`);\n }\n if (newlyAvailable.length > 0) {\n logInfo(\n `${newlyAvailable.length} new upstream asset(s) available (not added): ` +\n `${newlyAvailable.sort().join(\", \")} — add with \\`skaile source manifest edit ${arg}\\` if wanted`,\n );\n }\n\n if (!changed) {\n logOk(\"already up to date\");\n if (errors.length > 0) {\n logWarn(`${errors.length} discovery error(s) — inspect the source before re-consuming.`);\n }\n return;\n }\n\n const merged: SkPublishManifest = { ...existing, assets: kept };\n writeFileSync(target, encodeSkaileManifest(merged), \"utf-8\");\n logOk(\n `Rebuilt curated manifest: kept ${kept.length}, dropped ${dropped.length} → ${S.dim(target)}.`,\n );\n if (errors.length > 0) {\n logWarn(`${errors.length} discovery error(s) — inspect the source before re-consuming.`);\n }\n}\n\n/**\n * `source manifest verify <src>` — READ-ONLY integrity check of a curated\n * manifest against its clone. Writes nothing. Exit 0 when no errors; with\n * `--strict`, any warning also forces a nonzero exit.\n *\n * Per-asset checks:\n * - `root`/`files` paths still exist upstream (missing → error).\n * - A declared `sha256` recomputes to the same deterministic hash (mismatch → error).\n * - Schema decode diagnostics map to errors/warnings.\n * - Dependency refs parse via `parseAssetRef` (malformed → warning).\n */\nasync function runVerify(\n arg: string,\n opts: { projectDir: string; strict?: boolean },\n): Promise<void> {\n const projectDir = path.resolve(opts.projectDir);\n const { url, dest, slug, manifestFile: target } = resolveSourceArg(arg, projectDir);\n\n if (!existsSync(target)) {\n logErr(\n `No curated manifest for \"${slug}\" at ${S.dim(target)} — ` +\n \"run `skaile source manifest init` first.\",\n );\n process.exit(1);\n }\n\n // Ensure a clone exists to verify paths/hashes against (best-effort; no pull).\n ensureClone({ url });\n\n const text = readFileSync(target, \"utf-8\");\n const { manifest, diagnostics } = decodeSkaileManifest(text);\n\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Schema diagnostics from the decoder.\n for (const d of diagnostics) {\n const line = `${d.code}: ${d.message}`;\n if (d.severity === \"error\") errors.push(line);\n else warnings.push(line);\n }\n\n const assets = manifest.assets ?? [];\n for (const entry of assets) {\n const ref = entryRef(entry);\n\n // Path existence: `root` dir and/or each `files[]` path.\n const relPaths: string[] = [];\n if (entry.root) relPaths.push(entry.root);\n if (entry.files) {\n for (const f of entry.files) relPaths.push(typeof f === \"string\" ? f : f.path);\n }\n if (relPaths.length === 0) relPaths.push(entry.name);\n for (const rel of relPaths) {\n if (!existsSync(path.join(dest, rel))) {\n errors.push(`${ref}: path not found upstream: ${rel}`);\n }\n }\n\n // Declared sha256 → recompute + compare, but ONLY for granular `files:`\n // entries. Discovery (`discover-manifest.ts`) anchors a `files:`-only entry\n // at the REPO ROOT and hashes the files VERBATIM as repo-relative strings\n // (the path is folded into the digest), so verify must hash the same way:\n // `assetRoot = dest`, files kept repo-relative — NOT rebased onto the root.\n // A `root:` entry cannot be verified this way (discovery hashes only the\n // per-kind filtered set, not the whole-dir walk), and the writer never emits\n // sha256 for `root:` entries, so skip the hash check for them.\n if (entry.sha256) {\n if (entry.files && entry.files.length > 0) {\n const hashFiles = entry.files.map((f) =>\n (typeof f === \"string\" ? f : f.path).replace(/\\\\/g, \"/\"),\n );\n const actual = computeDeterministicHash(dest, hashFiles);\n if (actual !== entry.sha256) {\n errors.push(\n `${ref}: sha256 mismatch (declared ${entry.sha256.slice(0, 12)}…, got ${actual.slice(0, 12)}…)`,\n );\n }\n } else {\n warnings.push(\n `${ref}: declared sha256 on a root:-mode entry is not verifiable (discovery hashes only the per-kind filtered set) — skipped`,\n );\n }\n }\n\n // Dependency refs parse.\n for (const dep of entry.dependencies ?? []) {\n try {\n parseAssetRef(dep);\n } catch (err) {\n warnings.push(\n `${ref}: malformed dependency \"${dep}\": ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n for (const w of warnings) logWarn(w);\n for (const e of errors) logErr(e);\n\n if (errors.length === 0) {\n logOk(`verified ${assets.length} asset(s).`);\n } else {\n logErr(`${errors.length} issue(s).`);\n }\n\n const failStrict = opts.strict && warnings.length > 0;\n if (errors.length > 0 || failStrict) process.exit(1);\n}\n\n/**\n * Split a `$VISUAL`/`$EDITOR` value into `{ command, args }` and append the file\n * as the final arg. The env value is a full command line, not a bare binary —\n * `EDITOR=\"code --wait\"` must spawn `code` with `[\"--wait\", <file>]`, and\n * `EDITOR=code` (which returns before save) is the user's problem, not ours.\n * A whitespace split covers the common editors (`code --wait`, `code -w`,\n * `subl -w`, `vi`); paths with embedded spaces are not supported (rare for an\n * editor binary and out of scope). Falls back to `vi` when unset/empty.\n *\n * @docLink cli/commands/source#manifest-edit\n */\nexport function resolveEditorCommand(\n editorEnv: string | undefined,\n target: string,\n): { command: string; args: string[] } {\n const parts = (editorEnv ?? \"\").trim().split(/\\s+/).filter(Boolean);\n const [command, ...rest] = parts.length > 0 ? parts : [\"vi\"];\n return { command: command as string, args: [...rest, target] };\n}\n\n/** Minimal spawn contract runEdit needs — lets tests inject a fake. */\ntype SpawnLike = (\n command: string,\n args: string[],\n opts: { stdio: \"inherit\" },\n) => { status: number | null };\n\n/**\n * `source manifest edit <src>` — open the curated store manifest in `$EDITOR`\n * and re-validate on save. Warnings are surfaced but never hard-fail.\n *\n * `spawn` is injectable so tests can assert the argv without launching a real\n * editor; production passes the default `spawnSync`.\n */\nexport function runEdit(\n arg: string,\n opts: { projectDir: string },\n spawn: SpawnLike = spawnSync as unknown as SpawnLike,\n): void {\n const projectDir = path.resolve(opts.projectDir);\n const { slug, manifestFile: target } = resolveSourceArg(arg, projectDir);\n\n if (!existsSync(target)) {\n logErr(\n `No curated manifest for \"${slug}\" at ${target}. ` +\n \"Run `skaile source manifest init` first.\",\n );\n process.exit(1);\n }\n\n const { command, args } = resolveEditorCommand(process.env.VISUAL || process.env.EDITOR, target);\n const res = spawn(command, args, { stdio: \"inherit\" });\n if (res.status !== 0 && res.status !== null) {\n logErr(`Editor exited with status ${res.status}.`);\n process.exit(1);\n }\n\n // Re-validate the saved file; surface diagnostics as warnings, don't hard-fail.\n const { diagnostics } = decodeSkaileManifest(readFileSync(target, \"utf-8\"));\n const errors = diagnostics.filter((d) => d.severity === \"error\");\n const warnings = diagnostics.filter((d) => d.severity !== \"error\");\n if (errors.length > 0) {\n for (const d of errors) logErr(`${d.code}: ${d.message}`);\n logWarn(\"Manifest has errors — fix them before `skaile source add` will consume it.\");\n } else if (warnings.length > 0) {\n for (const d of warnings) logWarn(`${d.code}: ${d.message}`);\n logOk(\"Saved (with warnings).\");\n } else {\n logOk(\"Saved.\");\n }\n}\n\n/**\n * Append the `manifest` sub-tree to a `source` command.\n *\n * Called from `makeSourceCommand()` in `source.ts`.\n */\nexport function addSourceManifestCommands(src: Command): void {\n // enablePositionalOptions so options on the leaf verb (`source manifest init\n // --publisher …`) route to that verb instead of being rejected by `manifest`.\n const manifest = src\n .command(\"manifest\")\n .description(\"Curated manifest lifecycle for a source\")\n .enablePositionalOptions();\n\n manifest\n .command(\"init <src>\")\n .description(\"Generate a curated manifest for a source (stored in the local store catalog)\")\n .option(\"-C, --project-dir <dir>\", \"Project directory\", process.cwd())\n .option(\"--publisher <name>\", \"Override the publisher (default: source's GitHub org)\")\n .option(\"--dev\", \"Include assets under the source's dev_paths\", false)\n .option(\"--force\", \"Overwrite an existing curated manifest\", false)\n .action((arg, opts) => runInit(arg, opts));\n\n manifest\n .command(\"edit <src>\")\n .description(\"Open the curated manifest in $EDITOR and re-validate on save\")\n .option(\"-C, --project-dir <dir>\", \"Project directory\", process.cwd())\n .action((arg, opts) => runEdit(arg, opts));\n\n manifest\n .command(\"rebuild <src>\")\n .description(\n \"Refresh a curated manifest after an upstream change (merge by default: \" +\n \"keeps curation, drops assets gone upstream, reports new ones without adding)\",\n )\n .option(\"-C, --project-dir <dir>\", \"Project directory\", process.cwd())\n .option(\"--publisher <name>\", \"Override the publisher (--overwrite only)\")\n .option(\"--dev\", \"Include assets under the source's dev_paths\", false)\n .option(\"--overwrite\", \"Discard curation and re-scan the full inventory\", false)\n .action((arg, opts) => runRebuild(arg, opts));\n\n manifest\n .command(\"verify <src>\")\n .description(\"Verify hashes, deps, and schema (read-only)\")\n .option(\"-C, --project-dir <dir>\", \"Project directory\", process.cwd())\n .option(\"--strict\", \"Fail on advisory checks (warnings force a nonzero exit)\", false)\n .action((arg, opts) => runVerify(arg, opts));\n\n manifest\n .command(\"publish <src>\")\n .description(\"Push the curated sidecar manifest and publish it to the store\")\n .option(\"-C, --project-dir <dir>\", \"Project directory\", process.cwd())\n .option(\"--as <namespace>\", \"Publisher namespace (default: your store username)\")\n .option(\"--sidecar-repo <url>\", \"Public GitHub repo you own to hold the curated manifest\")\n .option(\"--ref <gitref>\", \"Foreign source ref to ingest (branch/sha; default: main)\")\n .option(\"--dry-run\", \"Print the publish plan without pushing or calling the store\", false)\n .action(async (arg, opts) => {\n const { runPublish } = await import(\"./source-manifest-publish.ts\");\n await runPublish(arg, opts);\n });\n\n manifest\n .command(\"propose <src>\")\n .description(\"Open a PR to upstream with the sidecar manifest\")\n .action(() => notWired(\"propose\"));\n\n manifest\n .command(\"yank <src>\")\n .description(\"Retract the source's published assets from the store\")\n .option(\"-C, --project-dir <dir>\", \"Project directory\", process.cwd())\n .option(\"--asset <ref>\", \"Yank only the asset matching this ref/name\")\n .action(async (arg, opts) => {\n const { runYank } = await import(\"./source-manifest-publish.ts\");\n await runYank(arg, opts);\n });\n}\n","/**\n * `skaile source …` — manage github sources for the current project.\n *\n * A *source* is a third-party github repo of AI assets. The project's\n * `skaile.yaml` `sources:` array is the source of truth for which sources\n * this project uses. The clone itself lives at\n * `<cache root>/sources/<host>/<owner>/<repo>/` (`~/.skaile/cache` unless `SKAILE_HOME` or\n * `SKAILE_CACHE_DIR` moves it; machine-global cache, shared across projects, URL-keyed so\n * cross-org repos never collide), and the manifest is mirrored into `<skaile home>/index.db`\n * (machine-global manifest cache).\n *\n * @docLink cli/commands/source\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, renameSync, rmSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport {\n attachToBranch,\n findWorkspaceRoot,\n getGlobalCacheDir,\n globalCacheRoot,\n legacySourceCacheKey,\n type SourceEntry,\n sourceCacheKey,\n sourceShortName,\n WorkspaceYamlEditor,\n workspaceConfigFilename,\n} from \"@skaile/workspaces/core\";\nimport { curatedManifestOverlay, LocalCatalogSource } from \"@skaile/workspaces/library\";\nimport * as p from \"@clack/prompts\";\nimport { Command } from \"commander\";\nimport { logErr, logInfo, logOk, logWarn, S } from \"../helpers.ts\";\nimport { openLibraryManager } from \"../open-library.ts\";\nimport { getKindRegistry } from \"../open-registry.ts\";\nimport { addSourceManifestCommands } from \"./source-manifest.ts\";\n\n/**\n * Clone dir for one source cache key (`<host>/<owner>/<repo>`). Exported for the\n * cache-path regression test. Callers pass `sourceCacheKey(url)`.\n */\nexport function sourceClonePath(key: string): string {\n return path.join(getGlobalCacheDir(), key);\n}\n\nconst SKAILE_MANIFEST_FILENAME = \"skaile.manifest.yaml\";\nconst LEGACY_SOURCE_CONFIG_FILENAME = \".skaile-source.yaml\";\n\n/**\n * Whether a manifest-cache refresh actually failed to index something. Keyed on\n * `errors`, NOT on `assetsUpdated < assetsFound`: the discovery walk counts\n * presets (and other intentionally-not-cataloged kinds) toward `assetsFound` but\n * never upserts them, so a source shipping a `.preset.yaml` would otherwise read\n * as a partial failure — false `! N asset(s) failed to index` + exit 1 — with\n * zero real errors.\n */\nexport function indexingHadFailures(result: { errors: string[] }): boolean {\n return result.errors.length > 0;\n}\n\n/**\n * A clone that ships only the legacy `.skaile-source.yaml` (no\n * `skaile.manifest.yaml`) has its declared `publisher_default` silently ignored\n * — discovery only reads `skaile.manifest.yaml`, so publisher resolution falls\n * back to the first path segment. Surface a hint so the author can fix it.\n */\nexport function legacySourceConfigHint(dest: string): string | undefined {\n const hasLegacy = existsSync(path.join(dest, LEGACY_SOURCE_CONFIG_FILENAME));\n const hasManifest = existsSync(path.join(dest, SKAILE_MANIFEST_FILENAME));\n if (hasLegacy && !hasManifest) {\n return (\n `This source ships a legacy ${LEGACY_SOURCE_CONFIG_FILENAME} but no ` +\n `${SKAILE_MANIFEST_FILENAME}; its declared publisher is ignored and assets ` +\n `are published under their first path segment. Add a ${SKAILE_MANIFEST_FILENAME} ` +\n `(\\`skaile source manifest init\\`) to set the publisher and asset inventory.`\n );\n }\n return undefined;\n}\n\n/**\n * Normalize a `source add` argument into a clonable git URL. Full URLs and\n * scp-style (`git@host:…`) specs pass through unchanged; an `owner/repo`\n * shorthand and a bare repo name expand to GitHub over SSH — a bare name\n * defaults to the `skaile-ai` org (`git@github.com:skaile-ai/<name>.git`).\n */\nexport function normalizeSourceUrl(input: string): string {\n const s = input.trim();\n if (/^(?:https?|git|ssh|file):\\/\\//.test(s) || /^git@/.test(s)) return s;\n const repo = s.replace(/\\.git$/, \"\");\n if (/^[\\w.-]+\\/[\\w.-]+$/.test(repo)) return `git@github.com:${repo}.git`;\n if (/^[\\w.-]+$/.test(repo)) return `git@github.com:skaile-ai/${repo}.git`;\n return s;\n}\n\n/**\n * Match a stored source against a user-supplied key. Mirrors the shortcut\n * expansion `source add` applies (`normalizeSourceUrl`) so any form that `add`\n * accepted — bare name, `owner/repo`, `.git`-suffixed, full URL — also resolves\n * at `sync`/`show`/`remove` time, not just the raw stored URL or derived slug.\n */\nexport function sourceMatchesKey(entry: SourceEntry, key: string): boolean {\n if (entry.url === key) return true;\n if (sourceCacheKey(entry.url) === key || sourceShortName(entry.url) === key) return true;\n return entry.url === normalizeSourceUrl(key);\n}\n\n/**\n * Name a source in output: its repo short name, or its clone-cache key when\n * another source in the project shares that short name (two `skillz` repos of\n * different owners). The key is unique per URL and `source show`/`remove` accept it.\n */\nexport function sourceLabel(entry: SourceEntry, all: readonly SourceEntry[]): string {\n const short = sourceShortName(entry.url);\n const shared = all.some((s) => s.url !== entry.url && sourceShortName(s.url) === short);\n return shared ? sourceCacheKey(entry.url) : short;\n}\n\n/** Outcome of {@link resolveSource}. */\nexport type SourceResolution =\n | { kind: \"one\"; entry: SourceEntry }\n | { kind: \"ambiguous\"; entries: SourceEntry[] }\n | { kind: \"none\" };\n\n/**\n * Pick the one source `key` names. Exact forms win over names: the stored URL,\n * then the cache key, then the repo short name or a `source add` shortcut. A\n * name that several sources share (`skillz` from two owners) is `ambiguous`\n * instead of silently picking the first.\n */\nexport function resolveSource(sources: readonly SourceEntry[], key: string): SourceResolution {\n const tiers: ((s: SourceEntry) => boolean)[] = [\n (s) => s.url === key,\n (s) => sourceCacheKey(s.url) === key,\n (s) => sourceShortName(s.url) === key || s.url === normalizeSourceUrl(key),\n ];\n for (const tier of tiers) {\n const hits = sources.filter(tier);\n if (hits.length === 1) return { kind: \"one\", entry: hits[0] };\n if (hits.length > 1) return { kind: \"ambiguous\", entries: hits };\n }\n return { kind: \"none\" };\n}\n\nfunction exitAmbiguousSource(key: string, entries: readonly SourceEntry[]): never {\n logErr(`\"${key}\" matches ${entries.length} sources; pass the URL of the one you mean:`);\n for (const e of entries) console.error(` ${e.url}`);\n process.exit(1);\n}\n\n/**\n * git's stderr as one line: every line but the `hint:` advice and the\n * `From <url>` / ` * branch …` fetch progress, joined by spaces. Keeps the\n * cause (`fatal: '<path>' does not appear to be a git repository`).\n */\nfunction pullFailureReason(stderr: string): string {\n return stderr\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l !== \"\" && !/^(hint:|From |[*+=!-] )/.test(l))\n .join(\" \");\n}\n\n/**\n * Find an already-registered source that maps to the same cache key as `url`\n * but is stored under a *different* URL string (e.g. the `.git`-suffixed or\n * scp form of the same remote). Two such entries would fight over one clone\n * dir, so `source add` rejects the ambiguity. Returns the colliding entry, or\n * `undefined` when the URL is unique or only matches an exact-string duplicate\n * (which `setSource` updates in place).\n */\nexport function findCacheKeyCollision(\n sources: SourceEntry[],\n url: string,\n): SourceEntry | undefined {\n const key = sourceCacheKey(url);\n return sources.find((s) => s.url !== url && sourceCacheKey(s.url) === key);\n}\n\nfunction requireProjectYamlPath(): string {\n const root = findWorkspaceRoot(process.cwd());\n if (!root) {\n logErr(\n \"No skaile.yaml found in the current directory or any parent. \" + \"Run `skaile init` first.\",\n );\n process.exit(1);\n }\n return path.join(root, workspaceConfigFilename());\n}\n\nexport function readProjectSources(yamlPath: string): SourceEntry[] {\n if (!existsSync(yamlPath)) return [];\n try {\n return WorkspaceYamlEditor.load(yamlPath).getSources();\n } catch (err) {\n logErr(`Could not read ${yamlPath}: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n\n/**\n * Clone the source if its clone directory does not yet exist. When `force` is\n * set, the existing clone is replaced by a fresh checkout. Returns true when a\n * clone happened. The cache slug is derived from the URL.\n *\n * A `--force` re-clone moves the old clone aside first and only deletes it once\n * the fresh clone succeeds — so a failed re-clone restores the previous clone\n * rather than leaving the source registered with no cache behind it.\n */\nexport function ensureClone(entry: SourceEntry, opts: { force?: boolean } = {}): boolean {\n const dest = sourceClonePath(sourceCacheKey(entry.url));\n let backup: string | undefined;\n if (existsSync(dest)) {\n if (!opts.force) return false;\n backup = `${dest}.bak`;\n rmSync(backup, { recursive: true, force: true });\n renameSync(dest, backup);\n }\n mkdirSync(path.dirname(dest), { recursive: true });\n const args = [\"clone\", entry.url, dest];\n // `pin` may be a branch/tag; pass it as the clone branch when present.\n if (entry.pin) args.splice(1, 0, \"--branch\", entry.pin);\n const clone = spawnSync(\"git\", args, { stdio: \"inherit\" });\n if (clone.status !== 0) {\n if (backup) {\n rmSync(dest, { recursive: true, force: true });\n renameSync(backup, dest);\n }\n logErr(`git clone failed for ${entry.url}`);\n process.exit(1);\n }\n if (backup) rmSync(backup, { recursive: true, force: true });\n return true;\n}\n\n/**\n * Advance an existing clone with `git pull --ff-only`. `add` and\n * `install --locked` leave the shared clone on a detached HEAD at the locked\n * commit, where `git pull` refuses to run, so a detached clone is put back on\n * its branch first (the pin when it is a branch, else the remote's default).\n * An entry pinned to a tag or SHA has nothing to pull and counts as synced.\n * On failure `error` is one line: git's whole stderr minus `hint:` advice and fetch progress.\n */\nexport function pullSourceClone(\n dest: string,\n entry: SourceEntry,\n): { ok: true } | { ok: false; error: string } {\n if (!attachToBranch(dest, entry.pin) && entry.pin) return { ok: true };\n const pull = spawnSync(\"git\", [\"pull\", \"--ff-only\"], {\n cwd: dest,\n stdio: \"pipe\",\n encoding: \"utf8\",\n });\n if (pull.status === 0) return { ok: true };\n const reason = pullFailureReason(pull.stderr) || `git exited with status ${pull.status}`;\n return { ok: false, error: `git pull failed: ${reason}` };\n}\n\n/**\n * Library name for a new source row: the repo short name, or `<owner>-<repo>`\n * (then `<host>-<owner>-<repo>`) when another library already holds that name.\n * Rows are found by clone path, never by this name: `orgA/repo` and\n * `orgB/repo` share the short name `repo`.\n */\nfunction sourceLibraryName(url: string, libs: readonly { name: string }[]): string {\n const taken = new Set(libs.map((l) => l.name));\n // A repo may be named `my.repo`; `addLibrary` only accepts `[A-Za-z0-9_-]`\n // starting with a letter or digit, so every candidate is slugged first.\n const flat = (s: string) => s.replace(/[^A-Za-z0-9_-]+/g, \"-\").replace(/^[-_]+/, \"\") || \"source\";\n const short = flat(sourceShortName(url));\n if (!taken.has(short)) return short;\n const parts = sourceCacheKey(url).split(\"/\");\n const candidates =\n parts.length === 3\n ? [flat(`${parts[1]}-${parts[2]}`), flat(`${parts[0]}-${parts[1]}-${parts[2]}`)]\n : [];\n for (const c of candidates) if (!taken.has(c)) return c;\n let n = 2;\n while (taken.has(`${short}-${n}`)) n++;\n return `${short}-${n}`;\n}\n\n/**\n * Refresh the machine-global manifest cache for `entry` by running discovery\n * and upserting AssetDefinitions into `<skaile home>/index.db`. Creates the\n * libraries-table cache row if missing (ownership: reader = cache state).\n */\nasync function refreshManifestCache(\n entry: SourceEntry,\n includeDev = false,\n): Promise<{\n assetsFound: number;\n assetsUpdated: number;\n errors: string[];\n advisories: string[];\n}> {\n const { manager, library, close } = await openLibraryManager();\n try {\n const dest = sourceClonePath(sourceCacheKey(entry.url));\n const libs = await manager.listLibraries();\n const existing = libs.find((l) => path.resolve(l.path) === path.resolve(dest));\n // A clone made before the cache key gained its url hash sits at `<last segment>`.\n // Its library row is this source's: point it at the new clone instead of adding a\n // second row for the same source (`add` would warn \"exists in 2 libraries\").\n const legacyKey = legacySourceCacheKey(entry.url);\n const legacyDir = legacyKey ? path.resolve(sourceClonePath(legacyKey)) : undefined;\n const legacyRow =\n existing || !legacyDir\n ? undefined\n : libs.find((l) => path.resolve(l.path) === legacyDir && l.ownership === \"reader\");\n if (legacyRow && legacyDir) {\n await manager.updateLibrary(legacyRow.id, { path: dest });\n logInfo(\n `Moved the \"${legacyRow.name}\" library to the new clone ${dest}. ` +\n `The old clone ${legacyDir} is no longer used and can be deleted.`,\n );\n }\n const lib =\n existing ??\n legacyRow ??\n (await manager.addLibrary({\n name: sourceLibraryName(entry.url, libs),\n path: dest,\n backend: \"git\",\n backendConfig: { url: entry.url, branch: entry.pin ?? \"main\", authHint: \"ssh\" },\n ownership: \"reader\",\n }));\n // A `skaile source manifest init` curated manifest overrides the upstream repo's\n // raw glob discovery; `asset install` rescans with the same overlay.\n const catalog = new LocalCatalogSource(library, lib.id, dest, getKindRegistry(), {\n sidecarManifestFile: curatedManifestOverlay(entry.url),\n });\n const result = await catalog.sync({ includeDev });\n await library.syncSource(lib.id);\n return result;\n } finally {\n close();\n }\n}\n\n/**\n * Auto-sync hook for `skaile search` on an unsynced workspace. Clones/pulls and\n * re-indexes every source declared in the project's `skaile.yaml`, then returns\n * whether the manifest cache may have changed (caller re-queries on `true`).\n *\n * Unlike `source sync`, this degrades gracefully — a clone/pull/index failure is\n * logged and skipped (never `process.exit`) so a failed auto-sync falls back to\n * the \"run sync first\" hint rather than killing the search. Returns `false`\n * (silently, no announce) when no sources are declared. Callers must guard\n * air-gapped mode themselves — this always touches the network.\n */\nexport async function autoSyncForSearch(projectDir: string): Promise<boolean> {\n const root = findWorkspaceRoot(projectDir);\n if (!root) return false;\n if (readProjectSources(path.join(root, workspaceConfigFilename())).length === 0) return false;\n\n logInfo(\"sources not synced — syncing now…\");\n const { synced } = await syncProjectSources(projectDir);\n return synced > 0;\n}\n\n/**\n * Clone-or-pull every source declared in the project's `skaile.yaml`, then\n * refresh its manifest cache. Shared by `autoSyncForSearch` and `skaile update`\n * (the latter offers it behind a confirm) so a re-deploy can see upstream\n * commits — `update` re-deploys against the local source cache, which is\n * otherwise frozen at the commit captured when the source was first cloned.\n *\n * Graceful by design: a clone/pull/index failure for one source is logged and\n * skipped (never `process.exit`), so a single bad remote can't abort the run.\n * Existing clones are advanced with `git pull --ff-only` (no `--depth=1`, unlike\n * the installer's `pullRepo`, so it fast-forwards instead of tripping the\n * shallow-divergence path). Returns a count summary for the caller to report.\n */\nexport async function syncProjectSources(\n projectDir: string,\n opts: { dev?: boolean } = {},\n): Promise<{ total: number; synced: number; failed: number }> {\n const root = findWorkspaceRoot(projectDir) ?? projectDir;\n const sources = readProjectSources(path.join(root, workspaceConfigFilename()));\n let synced = 0;\n let failed = 0;\n for (const entry of sources) {\n const slug = sourceShortName(entry.url);\n const dest = sourceClonePath(sourceCacheKey(entry.url));\n try {\n // Quiet git — the sync is a preparatory step; keep progress bars out of\n // the foreground output (spinner / install result).\n if (!existsSync(dest)) {\n mkdirSync(path.dirname(dest), { recursive: true });\n const args = [\"clone\", entry.url, dest];\n if (entry.pin) args.splice(1, 0, \"--branch\", entry.pin);\n const clone = spawnSync(\"git\", args, { stdio: \"ignore\" });\n if (clone.status !== 0) {\n logWarn(`${slug}: git clone failed, skipping.`);\n failed++;\n continue;\n }\n } else {\n const pull = pullSourceClone(dest, entry);\n if (!pull.ok) {\n logErr(`${slug}: ${pull.error}`);\n failed++;\n continue;\n }\n }\n const result = await refreshManifestCache(entry, opts.dev);\n for (const err of result.errors) logWarn(`${slug}: ${err}`);\n for (const advisory of result.advisories) logInfo(`${slug}: ${advisory}`);\n synced++;\n } catch (err) {\n logWarn(`${slug}: sync failed — ${err instanceof Error ? err.message : String(err)}`);\n failed++;\n }\n }\n return { total: sources.length, synced, failed };\n}\n\n/**\n * Short names of the project's source clones that hold commits their upstream lacks.\n * `update --no-sync` still re-deploys from such a clone, so it reports them the way\n * `source sync` does. A clone without an upstream (detached at a pin) never counts.\n */\nexport function divergedSourceClones(projectDir: string): string[] {\n const root = findWorkspaceRoot(projectDir) ?? projectDir;\n const diverged: string[] = [];\n for (const entry of readProjectSources(path.join(root, workspaceConfigFilename()))) {\n const dest = sourceClonePath(sourceCacheKey(entry.url));\n if (!existsSync(dest)) continue;\n const ahead = spawnSync(\"git\", [\"-C\", dest, \"rev-list\", \"--count\", \"@{upstream}..HEAD\"], {\n stdio: \"pipe\",\n encoding: \"utf8\",\n });\n if (ahead.status === 0 && Number(ahead.stdout.trim()) > 0) {\n diverged.push(sourceShortName(entry.url));\n }\n }\n return diverged;\n}\n\n/** Remove the libraries-table cache row and (optionally) the clone bytes. */\nasync function dropManifestCache(url: string, purgeClone: boolean): Promise<void> {\n const dest = sourceClonePath(sourceCacheKey(url));\n const { manager, close } = await openLibraryManager();\n try {\n // By clone path, not short name: another org's repo of the same name keeps its row.\n const existing = (await manager.listLibraries()).find(\n (l) => path.resolve(l.path) === path.resolve(dest),\n );\n if (existing) {\n await manager.removeLibrary(existing.name, { purge: false });\n }\n } finally {\n close();\n }\n if (purgeClone) {\n const dest = sourceClonePath(sourceCacheKey(url));\n if (existsSync(dest)) rmSync(dest, { recursive: true, force: true });\n }\n}\n\nexport function makeSourceCommand(): Command {\n const cmd = new Command(\"source\").description(\n \"Manage github sources for the current project (recorded in skaile.yaml)\",\n );\n\n // ── source add ──────────────────────────────────────────────────────────\n cmd\n .command(\"add <source>\")\n .description(\n \"Clone a github repo and register it in this project's skaile.yaml. \" +\n \"<source> may be a full git URL, an owner/repo shorthand, or a bare \" +\n \"name (→ git@github.com:skaile-ai/<name>.git).\",\n )\n .option(\"--name <slug>\", \"[deprecated] no-op — the source entry stores only the URL\")\n .option(\"--pin <ref>\", \"Pin a branch, tag, or 40-char SHA\")\n .option(\"--branch <branch>\", \"[deprecated] alias for --pin\")\n .option(\"--force\", \"Remove an existing clone and re-clone\", false)\n .option(\"--dev\", \"Also index dev-only assets under the source's dev_paths\", false)\n .action(\n async (\n source: string,\n opts: {\n name?: string;\n pin?: string;\n branch?: string;\n force?: boolean;\n dev?: boolean;\n },\n ) => {\n const url = normalizeSourceUrl(source);\n const yamlPath = requireProjectYamlPath();\n\n // A different URL string that maps to the same cache key (e.g. the\n // `.git`-suffixed or scp form of an already-registered remote) would\n // fight over one clone dir. setSource only dedupes exact strings, so\n // reject the ambiguous collision here instead of silently shadowing.\n const collision = findCacheKeyCollision(readProjectSources(yamlPath), url);\n if (collision) {\n logErr(\n `\"${url}\" maps to the same cache key (${sourceCacheKey(url)}) as ` +\n `already-registered \"${collision.url}\". Remove that source first ` +\n `(skaile source remove) or re-use its exact URL to update it.`,\n );\n process.exitCode = 1;\n return;\n }\n\n if (opts.name) {\n logWarn(\n \"the --name flag is deprecated; the source entry now stores only the URL \" +\n \"(the cache slug is derived from it).\",\n );\n }\n const pin = opts.pin ?? opts.branch;\n const slug = sourceShortName(url);\n const entry: SourceEntry = { url };\n if (pin) entry.pin = pin;\n\n const dest = sourceClonePath(sourceCacheKey(url));\n const preexisting = existsSync(dest);\n // Clone/validate the repo BEFORE touching skaile.yaml — a failed clone\n // (repo not found, bad URL, network error) hard-exits in ensureClone, so\n // the entry is only ever recorded once the source is known-good.\n const cloned = ensureClone(entry, { force: opts.force });\n if (!cloned) {\n logOk(`Reusing cached clone at ${dest}`);\n } else if (preexisting) {\n logOk(`Re-cloned ${url} → ${dest}`);\n } else {\n logOk(`Cloned ${url} → ${dest}`);\n }\n\n const editor = WorkspaceYamlEditor.load(yamlPath);\n editor.setSource(entry);\n editor.save();\n\n const result = await refreshManifestCache(entry, opts.dev);\n const failed = indexingHadFailures(result);\n const indexedMsg = `Indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s) from \"${slug}\".`;\n if (failed) {\n logWarn(indexedMsg);\n } else {\n logOk(indexedMsg);\n }\n for (const err of result.errors) logWarn(err);\n for (const advisory of result.advisories) logInfo(advisory);\n\n const legacyHint = legacySourceConfigHint(dest);\n if (legacyHint) logWarn(legacyHint);\n\n const where = path.relative(process.cwd(), yamlPath);\n if (failed) {\n // The entry IS recorded in skaile.yaml, but indexing did not fully\n // succeed — don't present it as a clean success.\n logWarn(\n `Source \"${slug}\" registered in ${where}, but ${result.errors.length} ` +\n `asset(s) failed to index (see above). Fix the cause, then re-run ` +\n `\\`skaile source sync ${slug}\\`.`,\n );\n process.exitCode = 1;\n } else {\n logOk(`Source \"${slug}\" registered in ${where}.`);\n }\n },\n );\n\n // ── source list ─────────────────────────────────────────────────────────\n cmd\n .command(\"list\")\n .description(\"List sources registered in this project's skaile.yaml\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (opts: { json?: boolean }) => {\n const yamlPath = requireProjectYamlPath();\n const sources = readProjectSources(yamlPath);\n if (opts.json) return console.log(JSON.stringify(sources, null, 2));\n if (sources.length === 0) {\n logInfo(\"No sources in skaile.yaml. Run `skaile source add <git-url>` to register one.\");\n return;\n }\n console.log();\n console.log(S.heading(\" Sources\"));\n for (const s of sources) {\n const slug = sourceLabel(s, sources);\n const cached = existsSync(sourceClonePath(sourceCacheKey(s.url)))\n ? \"\"\n : S.warn(\" (not cached)\");\n console.log(` ${S.cmd(slug.padEnd(24))} ${S.dim(s.url)}${cached}`);\n }\n console.log(`\\n ${S.dim(`${sources.length} source(s)`)}\\n`);\n });\n\n // ── source show ─────────────────────────────────────────────────────────\n cmd\n .command(\"show <name-or-url>\")\n .description(\"Show details for a source (matched by URL or derived slug)\")\n .action(async (key: string) => {\n const yamlPath = requireProjectYamlPath();\n const all = readProjectSources(yamlPath);\n const resolved = resolveSource(all, key);\n if (resolved.kind === \"none\") {\n logErr(`No source matching \"${key}\" in ${yamlPath}.`);\n process.exit(1);\n }\n if (resolved.kind === \"ambiguous\") exitAmbiguousSource(key, resolved.entries);\n const entry = resolved.entry;\n const slug = sourceLabel(entry, all);\n const clonePath = sourceClonePath(sourceCacheKey(entry.url));\n console.log(\n JSON.stringify(\n {\n ...entry,\n slug,\n clonePath,\n cached: existsSync(clonePath),\n },\n null,\n 2,\n ),\n );\n });\n\n // ── source remove ───────────────────────────────────────────────────────\n cmd\n .command(\"remove <name-or-url>\")\n .description(\"Remove a source from this project's skaile.yaml (matched by URL or slug)\")\n .option(\n \"--purge\",\n `Also delete the cached clone from ${path.join(globalCacheRoot(), \"sources\")}${path.sep}`,\n false,\n )\n .action(async (key: string, opts: { purge: boolean }) => {\n const yamlPath = requireProjectYamlPath();\n const editor = WorkspaceYamlEditor.load(yamlPath);\n // Resolve to the stored URL (entries are keyed by url in the editor).\n const all = editor.getSources();\n const resolved = resolveSource(all, key);\n if (resolved.kind === \"none\") {\n logErr(`No source matching \"${key}\" in ${yamlPath}.`);\n process.exit(1);\n }\n if (resolved.kind === \"ambiguous\") exitAmbiguousSource(key, resolved.entries);\n const match = resolved.entry;\n const slug = sourceLabel(match, all);\n editor.removeSource(match.url);\n editor.save();\n await dropManifestCache(match.url, opts.purge);\n logOk(\n opts.purge\n ? `Removed source \"${slug}\" and purged its clone.`\n : `Removed source \"${slug}\" from skaile.yaml (clone left in ${path.join(globalCacheRoot(), \"sources\")} — pass --purge to remove it, or run \\`skaile cache clean\\`).`,\n );\n });\n\n // ── source sync ─────────────────────────────────────────────────────────\n cmd\n .command(\"sync [name]\")\n .description(\"Pull upstream changes and refresh the manifest cache\")\n .option(\"--dev\", \"Also index dev-only assets under each source's dev_paths\", false)\n .option(\"--all\", \"Sync every source without prompting\", false)\n .action(async (key: string | undefined, opts: { dev?: boolean; all?: boolean }) => {\n const yamlPath = requireProjectYamlPath();\n const sources = readProjectSources(yamlPath);\n if (sources.length === 0) {\n logInfo(\"No sources in skaile.yaml.\");\n return;\n }\n\n let targets: SourceEntry[];\n if (key) {\n targets = sources.filter((s) => sourceMatchesKey(s, key));\n if (targets.length === 0) {\n logInfo(`No source matching \"${key}\".`);\n return;\n }\n } else if (opts.all || sources.length === 1 || !process.stdin.isTTY) {\n // --all, a single source, or a non-interactive shell: sync everything.\n targets = sources;\n } else {\n const selected = await p.multiselect({\n message: \"Select sources to sync\",\n options: sources.map((s) => ({\n value: s.url,\n label: sourceShortName(s.url),\n hint: s.url,\n })),\n required: true,\n });\n if (p.isCancel(selected)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n const picked = new Set(selected as string[]);\n targets = sources.filter((s) => picked.has(s.url));\n }\n for (const entry of targets) {\n const slug = sourceLabel(entry, sources);\n const dest = sourceClonePath(sourceCacheKey(entry.url));\n if (!existsSync(dest)) {\n ensureClone(entry);\n logOk(`${slug}: cloned to ${dest}.`);\n } else {\n const pull = pullSourceClone(dest, entry);\n if (!pull.ok) {\n logErr(`${slug}: ${pull.error}`);\n process.exitCode = 1;\n continue;\n }\n }\n const result = await refreshManifestCache(entry, opts.dev);\n const failed = indexingHadFailures(result);\n const indexedMsg = `${slug}: indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s).`;\n if (failed) {\n logWarn(indexedMsg);\n process.exitCode = 1;\n } else {\n logOk(indexedMsg);\n }\n for (const err of result.errors) logWarn(`${slug}: ${err}`);\n for (const advisory of result.advisories) logInfo(`${slug}: ${advisory}`);\n const legacyHint = legacySourceConfigHint(dest);\n if (legacyHint) logWarn(`${slug}: ${legacyHint}`);\n }\n });\n\n // ── source patch / propose (stubs) ──────────────────────────────────────\n cmd\n .command(\"patch <ref>\")\n .description(\"Extract an asset for editing against the source\")\n .action((_ref: string) => {\n logErr(\n \"`skaile source patch` is scaffolded but not yet wired. \" +\n \"The patch flow lands in a follow-up PR.\",\n );\n process.exit(2);\n });\n\n cmd\n .command(\"propose <ref>\")\n .description(\"Open a PR with the patch against the source upstream\")\n .action((_ref: string) => {\n logErr(\n \"`skaile source propose` is scaffolded but not yet wired. \" +\n \"The propose flow lands in a follow-up PR.\",\n );\n process.exit(2);\n });\n\n // ── source manifest * ───────────────────────────────────────────────────\n addSourceManifestCommands(cmd);\n\n return cmd;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { getProviderPreset, registryCredentialEnv, providerCredentialEnvName, BUILTIN_DRIVER_CATALOG } from './chunk-AWQYXZVG.js';
1
+ import { getProviderPreset, registryCredentialEnv, providerCredentialEnvName, BUILTIN_DRIVER_CATALOG } from './chunk-HJ5MCB3L.js';
2
2
  import { mergeRegistries, resolveEntryBaseUrl, normalizeEntryBaseUrl, registryEntries, isEntryEnabled, parseModelRef } from './chunk-MJHSLODD.js';
3
3
 
4
4
  // bridge/src/provider-materialize/env-drivers.ts
@@ -137,5 +137,5 @@ function continueRoleBinding(session) {
137
137
  }
138
138
 
139
139
  export { bindSingleProviderEntry, continueRoleBinding, credentialsForEveryProvider, entryBaseUrl, entryModelIds, entrySurface, harnessModelSelector, harnessProviderName, isStockCatalogEndpoint, registryModelEntries, resolveEnvDriverSession, resolveRegistryBinding, selectableEntries, versionedAnthropicBaseUrl };
140
- //# sourceMappingURL=chunk-BJNUNQAW.js.map
141
- //# sourceMappingURL=chunk-BJNUNQAW.js.map
140
+ //# sourceMappingURL=chunk-ZGQTS3Y4.js.map
141
+ //# sourceMappingURL=chunk-ZGQTS3Y4.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../bridge/src/provider-materialize/env-drivers.ts"],"names":[],"mappings":"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","file":"chunk-BJNUNQAW.js","sourcesContent":["/**\n * Registry adapter for the **env-shaped CLI drivers** — Gemini, Qwen, OpenCode,\n * Goose and Continue (§2.3).\n *\n * These harnesses take their endpoint from the environment rather than from a\n * config file, so the adapter's job is three things: resolve which registry\n * entry the session's model selector names, refuse at start when that entry\n * speaks a wire surface the harness cannot, and hand the driver the\n * provider-side model id it must put on the command line.\n *\n * Two pluralities meet here (`BUILTIN_DRIVER_CATALOG.providerPlurality`):\n *\n * - `single` — Gemini and Qwen address exactly one endpoint. The bound entry\n * supplies the credential *and* the base URL, and a surface mismatch is\n * fatal: a Gemini CLI pointed at an `openai-completions` endpoint cannot\n * work, and failing at start names the surface instead of leaving the user\n * with an opaque error mid-turn.\n * - `credentials-n` — OpenCode, Goose and Continue accept every enabled\n * entry's credential at once and select one active model. The credential\n * fan-out is `registryCredentialEnv`; the active model is this module's\n * `<provider>/<model>` binding.\n *\n * Writing the per-endpoint config files those three need for *custom*\n * endpoints (`opencode.json`, Goose `custom_providers/*.json`, Continue\n * `config.yaml`) is the file half, and is deliberately not here.\n *\n * @see PROVIDER-CONFIG-PLAN.md §2.3\n */\n\nimport {\n type AIProviderLlmEntry,\n type AIProviderSurface,\n isEntryEnabled,\n type MergedAIProviderRegistry,\n mergeRegistries,\n normalizeEntryBaseUrl,\n parseModelRef,\n registryEntries,\n resolveEntryBaseUrl,\n} from \"@skaile/workspaces/core/provider-registry\";\nimport type { ModelEntry } from \"../models.js\";\nimport { getProviderPreset } from \"../provider-catalog.js\";\nimport { BUILTIN_DRIVER_CATALOG } from \"../registry.js\";\nimport type { AgentConfig } from \"../types.js\";\nimport { providerCredentialEnvName, registryCredentialEnv } from \"./credential-env.js\";\n\n/**\n * Everything a CLI driver needs to know about this session's AI providers,\n * resolved once from its {@link AgentConfig}.\n */\nexport interface EnvDriverSession {\n /** The merged registry this session may address. Empty when none was configured. */\n registry: MergedAIProviderRegistry;\n /**\n * Environment `credential.ref` lookups resolve against — the process\n * environment widened with `config.env`, which is where the session\n * boundary delivered every resolved `SKAILE_AIP_<ID>_KEY`.\n */\n lookupEnv: Record<string, string | undefined>;\n /** Model selector: `<providerId>/<modelId>`, a bare id, or `@role`. */\n modelRef?: string;\n /** Roles table an `@role` selector resolves through. */\n roles?: Record<string, string>;\n}\n\n/**\n * Resolve the session's providers once, from its {@link AgentConfig}.\n *\n * `config.env` is folded into `lookupEnv` rather than kept apart: it is part\n * of the session's environment, not an extra, and a credential or\n * `*_BASE_URL` delivered there must be visible exactly as the child will see\n * it.\n */\nexport function resolveEnvDriverSession(\n config: AgentConfig,\n processEnv: Record<string, string | undefined> = process.env,\n): EnvDriverSession {\n return {\n registry: config.registry ?? mergeRegistries([]),\n lookupEnv: { ...processEnv, ...config.env },\n ...(config.modelRef ? { modelRef: config.modelRef } : {}),\n ...(config.roles ? { roles: config.roles } : {}),\n };\n}\n\n/** One resolved endpoint + model — everything a driver needs to spawn. */\nexport interface RegistryModelBinding {\n /** Registry id of the selected entry. */\n providerId: string;\n /** The selected entry itself. */\n entry: AIProviderLlmEntry;\n /** Logical model id, after `@role` expansion and before `model_map`. */\n modelId?: string;\n /** Provider-side model id — what goes on the wire / command line. */\n providerModelId?: string;\n /** Wire protocol, from the entry or its preset. */\n surface?: AIProviderSurface;\n /** Resolved endpoint, from the entry, its transport params, or its preset. */\n baseUrl?: string;\n /**\n * The provider name the *harness* knows this endpoint by — a catalog preset\n * id for a stock endpoint, the registry id for anything custom. See\n * {@link harnessProviderName}.\n */\n harnessProviderId: string;\n /** Non-fatal notes from `parseModelRef` (dangling role, disabled provider). */\n warnings: string[];\n}\n\n/** The entry's wire surface: its own, else its preset's. */\nexport function entrySurface(entry: AIProviderLlmEntry): AIProviderSurface | undefined {\n if (entry.surface) return entry.surface;\n return entry.preset ? getProviderPreset(entry.preset)?.surface : undefined;\n}\n\n/**\n * The entry's endpoint: its literal or transport-derived URL, else its\n * preset's literal, in the canonical spelling for its surface\n * (`normalizeEntryBaseUrl`: an `anthropic-messages` endpoint is its host root,\n * so `https://api.anthropic.com/v1` reads as `https://api.anthropic.com`).\n * Transport templates that still carry `{param}` placeholders never come\n * back — `resolveEntryBaseUrl` withholds those, and a preset's template is not\n * a URL.\n *\n * Every adapter reads the endpoint here and only re-spells it for a client\n * that wants something else ({@link versionedAnthropicBaseUrl}).\n */\nexport function entryBaseUrl(entry: AIProviderLlmEntry): string | undefined {\n const resolved =\n resolveEntryBaseUrl(entry) ??\n (entry.preset ? getProviderPreset(entry.preset)?.base_url : undefined);\n return normalizeEntryBaseUrl(resolved, entrySurface(entry));\n}\n\n/**\n * An `anthropic-messages` endpoint spelled for a client that appends only\n * `/messages` — `@ai-sdk/anthropic` (OpenCode) and Continue — rather than\n * `/v1/messages` like the Claude CLI, the Anthropic SDK and Goose. `baseUrl`\n * must already be canonical ({@link entryBaseUrl}); every other surface passes\n * through unchanged.\n */\nexport function versionedAnthropicBaseUrl(\n baseUrl: string,\n surface: AIProviderSurface | undefined,\n): string {\n if (surface !== \"anthropic-messages\") return baseUrl;\n // Append to the path, not the string: a query or fragment stays at the end.\n try {\n const url = new URL(baseUrl);\n url.pathname = `${url.pathname.replace(/\\/+$/, \"\")}/v1`;\n return url.toString();\n } catch {\n return `${baseUrl}/v1`;\n }\n}\n\n/**\n * True when a `credentials-n` harness already knows this endpoint under its\n * own catalog name — the entry names a preset and did not move it somewhere\n * else. Both sides are compared canonically, so `https://api.anthropic.com/v1`\n * is still the `anthropic` preset's endpoint.\n *\n * The one rule both halves of §2.3 read: it decides the name the env half\n * puts on the command line ({@link harnessProviderName}) *and* whether the\n * file half has to describe the endpoint at all. Reading it twice is what\n * keeps `-m <name>/<model>` and the generated provider file talking about the\n * same thing.\n */\nexport function isStockCatalogEndpoint(entry: AIProviderLlmEntry): boolean {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset) return false;\n return entryBaseUrl(entry) === normalizeEntryBaseUrl(preset.base_url, entrySurface(entry));\n}\n\n/**\n * The provider name to give a `credentials-n` harness (`-m <name>/<model>`,\n * `GOOSE_PROVIDER`).\n *\n * A stock catalog endpoint is named by its preset, because that is the name\n * OpenCode's models.dev list and Goose's built-in provider table already use —\n * `prod-claude: {preset: anthropic}` is still Anthropic to them. An entry with\n * an endpoint of its own is named by its registry id: no built-in table knows\n * it, so the id is what its generated provider file is keyed by (the file half\n * of §2.3).\n */\nexport function harnessProviderName(providerId: string, entry: AIProviderLlmEntry): string {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset || !isStockCatalogEndpoint(entry)) return providerId;\n return preset.id;\n}\n\n/**\n * Enabled `llm`/`embed` entries, in registry order. Also the set the file\n * adapters render (`opencode-config.ts`, `goose-custom-providers.ts`,\n * `continue-config-yaml.ts`): the env half and the file half must agree on\n * which entries exist before they can agree on what to call them.\n */\nexport function selectableEntries(\n registry: MergedAIProviderRegistry,\n): Array<[string, AIProviderLlmEntry]> {\n return registryEntries(registry).filter(\n (pair): pair is [string, AIProviderLlmEntry] =>\n (pair[1].kind === \"llm\" || pair[1].kind === \"embed\") && isEntryEnabled(pair[1]),\n );\n}\n\n/**\n * The provider-side model ids an entry declares, as `[logicalId, providerId]`\n * pairs in declaration order: every `model_map` entry, plus every\n * `capabilities` key the map does not rename.\n */\nexport function entryModelIds(entry: AIProviderLlmEntry): Array<[string, string]> {\n const logicalIds = [\n ...Object.keys(entry.model_map ?? {}),\n ...Object.keys(entry.capabilities ?? {}).filter((id) => !(id in (entry.model_map ?? {}))),\n ];\n return logicalIds.map((id) => [id, entry.model_map?.[id] ?? id]);\n}\n\nfunction describeBinding(\n providerId: string,\n entry: AIProviderLlmEntry,\n modelId: string | undefined,\n providerModelId: string | undefined,\n warnings: string[],\n): RegistryModelBinding {\n const surface = entrySurface(entry);\n const baseUrl = entryBaseUrl(entry);\n return {\n providerId,\n entry,\n ...(modelId === undefined ? {} : { modelId }),\n ...(providerModelId === undefined ? {} : { providerModelId }),\n ...(surface ? { surface } : {}),\n ...(baseUrl ? { baseUrl } : {}),\n harnessProviderId: harnessProviderName(providerId, entry),\n warnings,\n };\n}\n\n/**\n * Resolve the session's endpoint + model.\n *\n * With no selector the first entry in registry order wins and the harness\n * keeps its own default model — exactly what an absent `model` meant before\n * the registry existed. Returns `undefined` when no entry can serve a model\n * (an empty, fully-disabled or voice-only registry).\n */\nexport function resolveRegistryBinding(\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const entries = selectableEntries(session.registry);\n if (entries.length === 0) return undefined;\n\n const selector = session.modelRef?.trim();\n if (!selector) {\n const [providerId, entry] = entries[0];\n return describeBinding(providerId, entry, undefined, undefined, []);\n }\n\n // A selector that is exactly an entry id names the endpoint and nothing\n // else: the harness keeps its own default model. `parseModelRef` would read\n // it as a bare *model* id and fall back to registry order.\n const named = entries.find(([id]) => id === selector);\n if (named) return describeBinding(named[0], named[1], undefined, undefined, []);\n\n const resolved = parseModelRef(selector, session.registry, session.roles);\n if (!resolved) return undefined;\n const match = entries.find(([id]) => id === resolved.providerId);\n if (!match) return undefined;\n return describeBinding(\n match[0],\n match[1],\n resolved.modelId,\n resolved.providerModelId,\n resolved.warnings,\n );\n}\n\n/**\n * Every credential a `credentials-n` harness may use: one variable per\n * enabled registry entry. OpenCode, Goose and Continue have always received\n * *all* of them, not just the selected endpoint's, because they route across\n * providers inside a single session.\n */\nexport function credentialsForEveryProvider(session: EnvDriverSession): Record<string, string> {\n return registryCredentialEnv(session.registry, { env: session.lookupEnv });\n}\n\n/**\n * Throw when the bound entry speaks a wire surface this driver cannot.\n *\n * The message names the offending surface and lists the ones the harness does\n * speak (`BUILTIN_DRIVER_CATALOG[driverId].surfaces`). An entry that declares\n * no surface and names no preset is not judged — there is nothing to compare.\n */\nexport function assertDriverSpeaksSurface(\n driverId: string,\n productName: string,\n binding: RegistryModelBinding,\n): void {\n const supported = BUILTIN_DRIVER_CATALOG[driverId]?.surfaces;\n if (!supported || supported.length === 0) return;\n const surface = binding.surface;\n if (!surface || supported.includes(surface)) return;\n throw new Error(\n `${productName} cannot speak the '${surface}' surface of AI provider entry ` +\n `'${binding.providerId}'. ${productName} speaks: ${supported.join(\", \")}. ` +\n `Point this session's model at an entry with one of those surfaces, ` +\n `or run it on a driver that speaks '${surface}'.`,\n );\n}\n\n/**\n * The models a `credentials-n` harness can be pointed at, straight from the\n * registry: every enabled entry's mapped ids, namespaced the way the harness\n * takes them (`-m <provider>/<model>`).\n *\n * These harnesses have no model-list endpoint of their own — OpenCode reads\n * models.dev, Goose and Continue read their config — so the registry is the\n * only list that describes *this* session's reachable models, and it needs no\n * network call to produce.\n */\nexport function registryModelEntries(session: EnvDriverSession): ModelEntry[] {\n const out: ModelEntry[] = [];\n const seen = new Set<string>();\n for (const [providerId, entry] of selectableEntries(session.registry)) {\n const harnessId = harnessProviderName(providerId, entry);\n const label = entry.label ?? providerId;\n for (const [logicalId, providerModelId] of entryModelIds(entry)) {\n const id = `${harnessId}/${providerModelId}`;\n if (seen.has(id)) continue;\n seen.add(id);\n out.push({ id, name: `${label} ${logicalId}` });\n }\n }\n return out;\n}\n\n/**\n * Resolve the binding and enforce the surface — what a `single`-plurality\n * driver does at start.\n *\n * The registry is authoritative: pointing the driver at an entry it cannot\n * speak throws rather than silently running somewhere else. `undefined` when\n * the session configured no endpoint at all, which leaves the driver on its\n * own native auth.\n */\nexport function bindSingleProviderEntry(\n driverId: string,\n productName: string,\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n assertDriverSpeaksSurface(driverId, productName, binding);\n return binding;\n}\n\n/**\n * The `<provider>/<model>` selector a `credentials-n` harness takes on its\n * command line (`opencode -m`). `undefined` when no model was selected — the\n * harness then uses its own default rather than being handed a bare provider.\n */\nexport function harnessModelSelector(binding: RegistryModelBinding): string | undefined {\n if (!binding.providerModelId) return undefined;\n return `${binding.harnessProviderId}/${binding.providerModelId}`;\n}\n\n/**\n * Continue's model selection is a **role binding**, not a flag: `cn` has no\n * `--model` option (only `--config <slug>`), and its `config.yaml` binds each\n * model to roles (`chat`, `edit`, `apply`, …). This is the binding for the\n * role a headless `cn -p` turn runs as, and the shape its generated\n * `config.yaml` is rendered from.\n *\n * `apiKeyEnv` is a variable *name*: the secret travels in the child\n * environment, never in a rendered config.\n */\nexport interface ContinueRoleBinding {\n /** Continue role this model serves. A headless prompt is a `chat` turn. */\n role: \"chat\";\n /** Registry id of the entry. */\n providerId: string;\n /** Provider name Continue knows the endpoint by. */\n provider: string;\n /** Provider-side model id. */\n model?: string;\n /** Endpoint, when the entry states one, spelled the way Continue's `apiBase` wants it. */\n apiBase?: string;\n /** Env var holding the credential — the name, never the value. */\n apiKeyEnv: string;\n}\n\n/**\n * Map the session's chosen endpoint onto the Continue role a headless turn\n * runs as. `undefined` when the session configured no endpoint — `cn` then\n * runs against whatever its own `config.yaml` / Hub login provides.\n */\nexport function continueRoleBinding(session: EnvDriverSession): ContinueRoleBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n return {\n role: \"chat\",\n providerId: binding.providerId,\n provider: binding.harnessProviderId,\n ...(binding.providerModelId ? { model: binding.providerModelId } : {}),\n ...(binding.baseUrl\n ? { apiBase: versionedAnthropicBaseUrl(binding.baseUrl, binding.surface) }\n : {}),\n apiKeyEnv: providerCredentialEnvName(binding.providerId),\n };\n}\n"]}
1
+ {"version":3,"sources":["../bridge/src/provider-materialize/env-drivers.ts"],"names":[],"mappings":"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","file":"chunk-ZGQTS3Y4.js","sourcesContent":["/**\n * Registry adapter for the **env-shaped CLI drivers** — Gemini, Qwen, OpenCode,\n * Goose and Continue (§2.3).\n *\n * These harnesses take their endpoint from the environment rather than from a\n * config file, so the adapter's job is three things: resolve which registry\n * entry the session's model selector names, refuse at start when that entry\n * speaks a wire surface the harness cannot, and hand the driver the\n * provider-side model id it must put on the command line.\n *\n * Two pluralities meet here (`BUILTIN_DRIVER_CATALOG.providerPlurality`):\n *\n * - `single` — Gemini and Qwen address exactly one endpoint. The bound entry\n * supplies the credential *and* the base URL, and a surface mismatch is\n * fatal: a Gemini CLI pointed at an `openai-completions` endpoint cannot\n * work, and failing at start names the surface instead of leaving the user\n * with an opaque error mid-turn.\n * - `credentials-n` — OpenCode, Goose and Continue accept every enabled\n * entry's credential at once and select one active model. The credential\n * fan-out is `registryCredentialEnv`; the active model is this module's\n * `<provider>/<model>` binding.\n *\n * Writing the per-endpoint config files those three need for *custom*\n * endpoints (`opencode.json`, Goose `custom_providers/*.json`, Continue\n * `config.yaml`) is the file half, and is deliberately not here.\n *\n * @see PROVIDER-CONFIG-PLAN.md §2.3\n */\n\nimport {\n type AIProviderLlmEntry,\n type AIProviderSurface,\n isEntryEnabled,\n type MergedAIProviderRegistry,\n mergeRegistries,\n normalizeEntryBaseUrl,\n parseModelRef,\n registryEntries,\n resolveEntryBaseUrl,\n} from \"@skaile/workspaces/core/provider-registry\";\nimport type { ModelEntry } from \"../models.js\";\nimport { getProviderPreset } from \"../provider-catalog.js\";\nimport { BUILTIN_DRIVER_CATALOG } from \"../registry.js\";\nimport type { AgentConfig } from \"../types.js\";\nimport { providerCredentialEnvName, registryCredentialEnv } from \"./credential-env.js\";\n\n/**\n * Everything a CLI driver needs to know about this session's AI providers,\n * resolved once from its {@link AgentConfig}.\n */\nexport interface EnvDriverSession {\n /** The merged registry this session may address. Empty when none was configured. */\n registry: MergedAIProviderRegistry;\n /**\n * Environment `credential.ref` lookups resolve against — the process\n * environment widened with `config.env`, which is where the session\n * boundary delivered every resolved `SKAILE_AIP_<ID>_KEY`.\n */\n lookupEnv: Record<string, string | undefined>;\n /** Model selector: `<providerId>/<modelId>`, a bare id, or `@role`. */\n modelRef?: string;\n /** Roles table an `@role` selector resolves through. */\n roles?: Record<string, string>;\n}\n\n/**\n * Resolve the session's providers once, from its {@link AgentConfig}.\n *\n * `config.env` is folded into `lookupEnv` rather than kept apart: it is part\n * of the session's environment, not an extra, and a credential or\n * `*_BASE_URL` delivered there must be visible exactly as the child will see\n * it.\n */\nexport function resolveEnvDriverSession(\n config: AgentConfig,\n processEnv: Record<string, string | undefined> = process.env,\n): EnvDriverSession {\n return {\n registry: config.registry ?? mergeRegistries([]),\n lookupEnv: { ...processEnv, ...config.env },\n ...(config.modelRef ? { modelRef: config.modelRef } : {}),\n ...(config.roles ? { roles: config.roles } : {}),\n };\n}\n\n/** One resolved endpoint + model — everything a driver needs to spawn. */\nexport interface RegistryModelBinding {\n /** Registry id of the selected entry. */\n providerId: string;\n /** The selected entry itself. */\n entry: AIProviderLlmEntry;\n /** Logical model id, after `@role` expansion and before `model_map`. */\n modelId?: string;\n /** Provider-side model id — what goes on the wire / command line. */\n providerModelId?: string;\n /** Wire protocol, from the entry or its preset. */\n surface?: AIProviderSurface;\n /** Resolved endpoint, from the entry, its transport params, or its preset. */\n baseUrl?: string;\n /**\n * The provider name the *harness* knows this endpoint by — a catalog preset\n * id for a stock endpoint, the registry id for anything custom. See\n * {@link harnessProviderName}.\n */\n harnessProviderId: string;\n /** Non-fatal notes from `parseModelRef` (dangling role, disabled provider). */\n warnings: string[];\n}\n\n/** The entry's wire surface: its own, else its preset's. */\nexport function entrySurface(entry: AIProviderLlmEntry): AIProviderSurface | undefined {\n if (entry.surface) return entry.surface;\n return entry.preset ? getProviderPreset(entry.preset)?.surface : undefined;\n}\n\n/**\n * The entry's endpoint: its literal or transport-derived URL, else its\n * preset's literal, in the canonical spelling for its surface\n * (`normalizeEntryBaseUrl`: an `anthropic-messages` endpoint is its host root,\n * so `https://api.anthropic.com/v1` reads as `https://api.anthropic.com`).\n * Transport templates that still carry `{param}` placeholders never come\n * back — `resolveEntryBaseUrl` withholds those, and a preset's template is not\n * a URL.\n *\n * Every adapter reads the endpoint here and only re-spells it for a client\n * that wants something else ({@link versionedAnthropicBaseUrl}).\n */\nexport function entryBaseUrl(entry: AIProviderLlmEntry): string | undefined {\n const resolved =\n resolveEntryBaseUrl(entry) ??\n (entry.preset ? getProviderPreset(entry.preset)?.base_url : undefined);\n return normalizeEntryBaseUrl(resolved, entrySurface(entry));\n}\n\n/**\n * An `anthropic-messages` endpoint spelled for a client that appends only\n * `/messages` — `@ai-sdk/anthropic` (OpenCode) and Continue — rather than\n * `/v1/messages` like the Claude CLI, the Anthropic SDK and Goose. `baseUrl`\n * must already be canonical ({@link entryBaseUrl}); every other surface passes\n * through unchanged.\n */\nexport function versionedAnthropicBaseUrl(\n baseUrl: string,\n surface: AIProviderSurface | undefined,\n): string {\n if (surface !== \"anthropic-messages\") return baseUrl;\n // Append to the path, not the string: a query or fragment stays at the end.\n try {\n const url = new URL(baseUrl);\n url.pathname = `${url.pathname.replace(/\\/+$/, \"\")}/v1`;\n return url.toString();\n } catch {\n return `${baseUrl}/v1`;\n }\n}\n\n/**\n * True when a `credentials-n` harness already knows this endpoint under its\n * own catalog name — the entry names a preset and did not move it somewhere\n * else. Both sides are compared canonically, so `https://api.anthropic.com/v1`\n * is still the `anthropic` preset's endpoint.\n *\n * The one rule both halves of §2.3 read: it decides the name the env half\n * puts on the command line ({@link harnessProviderName}) *and* whether the\n * file half has to describe the endpoint at all. Reading it twice is what\n * keeps `-m <name>/<model>` and the generated provider file talking about the\n * same thing.\n */\nexport function isStockCatalogEndpoint(entry: AIProviderLlmEntry): boolean {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset) return false;\n return entryBaseUrl(entry) === normalizeEntryBaseUrl(preset.base_url, entrySurface(entry));\n}\n\n/**\n * The provider name to give a `credentials-n` harness (`-m <name>/<model>`,\n * `GOOSE_PROVIDER`).\n *\n * A stock catalog endpoint is named by its preset, because that is the name\n * OpenCode's models.dev list and Goose's built-in provider table already use —\n * `prod-claude: {preset: anthropic}` is still Anthropic to them. An entry with\n * an endpoint of its own is named by its registry id: no built-in table knows\n * it, so the id is what its generated provider file is keyed by (the file half\n * of §2.3).\n */\nexport function harnessProviderName(providerId: string, entry: AIProviderLlmEntry): string {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset || !isStockCatalogEndpoint(entry)) return providerId;\n return preset.id;\n}\n\n/**\n * Enabled `llm`/`embed` entries, in registry order. Also the set the file\n * adapters render (`opencode-config.ts`, `goose-custom-providers.ts`,\n * `continue-config-yaml.ts`): the env half and the file half must agree on\n * which entries exist before they can agree on what to call them.\n */\nexport function selectableEntries(\n registry: MergedAIProviderRegistry,\n): Array<[string, AIProviderLlmEntry]> {\n return registryEntries(registry).filter(\n (pair): pair is [string, AIProviderLlmEntry] =>\n (pair[1].kind === \"llm\" || pair[1].kind === \"embed\") && isEntryEnabled(pair[1]),\n );\n}\n\n/**\n * The provider-side model ids an entry declares, as `[logicalId, providerId]`\n * pairs in declaration order: every `model_map` entry, plus every\n * `capabilities` key the map does not rename.\n */\nexport function entryModelIds(entry: AIProviderLlmEntry): Array<[string, string]> {\n const logicalIds = [\n ...Object.keys(entry.model_map ?? {}),\n ...Object.keys(entry.capabilities ?? {}).filter((id) => !(id in (entry.model_map ?? {}))),\n ];\n return logicalIds.map((id) => [id, entry.model_map?.[id] ?? id]);\n}\n\nfunction describeBinding(\n providerId: string,\n entry: AIProviderLlmEntry,\n modelId: string | undefined,\n providerModelId: string | undefined,\n warnings: string[],\n): RegistryModelBinding {\n const surface = entrySurface(entry);\n const baseUrl = entryBaseUrl(entry);\n return {\n providerId,\n entry,\n ...(modelId === undefined ? {} : { modelId }),\n ...(providerModelId === undefined ? {} : { providerModelId }),\n ...(surface ? { surface } : {}),\n ...(baseUrl ? { baseUrl } : {}),\n harnessProviderId: harnessProviderName(providerId, entry),\n warnings,\n };\n}\n\n/**\n * Resolve the session's endpoint + model.\n *\n * With no selector the first entry in registry order wins and the harness\n * keeps its own default model — exactly what an absent `model` meant before\n * the registry existed. Returns `undefined` when no entry can serve a model\n * (an empty, fully-disabled or voice-only registry).\n */\nexport function resolveRegistryBinding(\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const entries = selectableEntries(session.registry);\n if (entries.length === 0) return undefined;\n\n const selector = session.modelRef?.trim();\n if (!selector) {\n const [providerId, entry] = entries[0];\n return describeBinding(providerId, entry, undefined, undefined, []);\n }\n\n // A selector that is exactly an entry id names the endpoint and nothing\n // else: the harness keeps its own default model. `parseModelRef` would read\n // it as a bare *model* id and fall back to registry order.\n const named = entries.find(([id]) => id === selector);\n if (named) return describeBinding(named[0], named[1], undefined, undefined, []);\n\n const resolved = parseModelRef(selector, session.registry, session.roles);\n if (!resolved) return undefined;\n const match = entries.find(([id]) => id === resolved.providerId);\n if (!match) return undefined;\n return describeBinding(\n match[0],\n match[1],\n resolved.modelId,\n resolved.providerModelId,\n resolved.warnings,\n );\n}\n\n/**\n * Every credential a `credentials-n` harness may use: one variable per\n * enabled registry entry. OpenCode, Goose and Continue have always received\n * *all* of them, not just the selected endpoint's, because they route across\n * providers inside a single session.\n */\nexport function credentialsForEveryProvider(session: EnvDriverSession): Record<string, string> {\n return registryCredentialEnv(session.registry, { env: session.lookupEnv });\n}\n\n/**\n * Throw when the bound entry speaks a wire surface this driver cannot.\n *\n * The message names the offending surface and lists the ones the harness does\n * speak (`BUILTIN_DRIVER_CATALOG[driverId].surfaces`). An entry that declares\n * no surface and names no preset is not judged — there is nothing to compare.\n */\nexport function assertDriverSpeaksSurface(\n driverId: string,\n productName: string,\n binding: RegistryModelBinding,\n): void {\n const supported = BUILTIN_DRIVER_CATALOG[driverId]?.surfaces;\n if (!supported || supported.length === 0) return;\n const surface = binding.surface;\n if (!surface || supported.includes(surface)) return;\n throw new Error(\n `${productName} cannot speak the '${surface}' surface of AI provider entry ` +\n `'${binding.providerId}'. ${productName} speaks: ${supported.join(\", \")}. ` +\n `Point this session's model at an entry with one of those surfaces, ` +\n `or run it on a driver that speaks '${surface}'.`,\n );\n}\n\n/**\n * The models a `credentials-n` harness can be pointed at, straight from the\n * registry: every enabled entry's mapped ids, namespaced the way the harness\n * takes them (`-m <provider>/<model>`).\n *\n * These harnesses have no model-list endpoint of their own — OpenCode reads\n * models.dev, Goose and Continue read their config — so the registry is the\n * only list that describes *this* session's reachable models, and it needs no\n * network call to produce.\n */\nexport function registryModelEntries(session: EnvDriverSession): ModelEntry[] {\n const out: ModelEntry[] = [];\n const seen = new Set<string>();\n for (const [providerId, entry] of selectableEntries(session.registry)) {\n const harnessId = harnessProviderName(providerId, entry);\n const label = entry.label ?? providerId;\n for (const [logicalId, providerModelId] of entryModelIds(entry)) {\n const id = `${harnessId}/${providerModelId}`;\n if (seen.has(id)) continue;\n seen.add(id);\n out.push({ id, name: `${label} ${logicalId}` });\n }\n }\n return out;\n}\n\n/**\n * Resolve the binding and enforce the surface — what a `single`-plurality\n * driver does at start.\n *\n * The registry is authoritative: pointing the driver at an entry it cannot\n * speak throws rather than silently running somewhere else. `undefined` when\n * the session configured no endpoint at all, which leaves the driver on its\n * own native auth.\n */\nexport function bindSingleProviderEntry(\n driverId: string,\n productName: string,\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n assertDriverSpeaksSurface(driverId, productName, binding);\n return binding;\n}\n\n/**\n * The `<provider>/<model>` selector a `credentials-n` harness takes on its\n * command line (`opencode -m`). `undefined` when no model was selected — the\n * harness then uses its own default rather than being handed a bare provider.\n */\nexport function harnessModelSelector(binding: RegistryModelBinding): string | undefined {\n if (!binding.providerModelId) return undefined;\n return `${binding.harnessProviderId}/${binding.providerModelId}`;\n}\n\n/**\n * Continue's model selection is a **role binding**, not a flag: `cn` has no\n * `--model` option (only `--config <slug>`), and its `config.yaml` binds each\n * model to roles (`chat`, `edit`, `apply`, …). This is the binding for the\n * role a headless `cn -p` turn runs as, and the shape its generated\n * `config.yaml` is rendered from.\n *\n * `apiKeyEnv` is a variable *name*: the secret travels in the child\n * environment, never in a rendered config.\n */\nexport interface ContinueRoleBinding {\n /** Continue role this model serves. A headless prompt is a `chat` turn. */\n role: \"chat\";\n /** Registry id of the entry. */\n providerId: string;\n /** Provider name Continue knows the endpoint by. */\n provider: string;\n /** Provider-side model id. */\n model?: string;\n /** Endpoint, when the entry states one, spelled the way Continue's `apiBase` wants it. */\n apiBase?: string;\n /** Env var holding the credential — the name, never the value. */\n apiKeyEnv: string;\n}\n\n/**\n * Map the session's chosen endpoint onto the Continue role a headless turn\n * runs as. `undefined` when the session configured no endpoint — `cn` then\n * runs against whatever its own `config.yaml` / Hub login provides.\n */\nexport function continueRoleBinding(session: EnvDriverSession): ContinueRoleBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n return {\n role: \"chat\",\n providerId: binding.providerId,\n provider: binding.harnessProviderId,\n ...(binding.providerModelId ? { model: binding.providerModelId } : {}),\n ...(binding.baseUrl\n ? { apiBase: versionedAnthropicBaseUrl(binding.baseUrl, binding.surface) }\n : {}),\n apiKeyEnv: providerCredentialEnvName(binding.providerId),\n };\n}\n"]}