@skaile/workspaces 6.1.0 → 6.2.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 (381) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/{asset-feeds-HJFV7UPW.js → asset-feeds-KPKCE64E.js} +26 -26
  3. package/dist/{asset-feeds-HJFV7UPW.js.map → asset-feeds-KPKCE64E.js.map} +1 -1
  4. package/dist/asset-manager/catalog-deployer.js +10 -10
  5. package/dist/asset-manager/fragments.js +1 -1
  6. package/dist/asset-manager/index.js +18 -18
  7. package/dist/asset-manager/installer.js +13 -13
  8. package/dist/asset-manager/renderers.js +11 -11
  9. package/dist/asset-manager/src/index.d.ts +149 -16
  10. package/dist/asset-manager/src/index.d.ts.map +1 -1
  11. package/dist/asset-manager/src/installer.d.ts +9 -0
  12. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  13. package/dist/asset-manager/src/renderers.d.ts +7 -0
  14. package/dist/asset-manager/src/renderers.d.ts.map +1 -1
  15. package/dist/bridge/harnesses/claude-sdk.js +15 -15
  16. package/dist/bridge/harnesses/codex.js +24 -17
  17. package/dist/bridge/harnesses/codex.js.map +1 -1
  18. package/dist/bridge/harnesses/continue.js +14 -14
  19. package/dist/bridge/harnesses/echo.js +4 -4
  20. package/dist/bridge/harnesses/gemini.js +10 -10
  21. package/dist/bridge/harnesses/goose.js +14 -14
  22. package/dist/bridge/harnesses/omp.js +15 -8
  23. package/dist/bridge/harnesses/omp.js.map +1 -1
  24. package/dist/bridge/harnesses/opencode.js +14 -14
  25. package/dist/bridge/harnesses/qwen.js +10 -10
  26. package/dist/bridge/index.js +19 -19
  27. package/dist/bridge/src/harness-model-check.d.ts +15 -0
  28. package/dist/bridge/src/harness-model-check.d.ts.map +1 -1
  29. package/dist/bridge/src/harnesses/_subprocess-cli.d.ts.map +1 -1
  30. package/dist/bridge/src/harnesses/codex.d.ts.map +1 -1
  31. package/dist/bridge/src/harnesses/omp.d.ts.map +1 -1
  32. package/dist/bridge/src/index.d.ts +1 -1
  33. package/dist/bridge/src/index.d.ts.map +1 -1
  34. package/dist/bridge/src/runner-private-env.d.ts +7 -0
  35. package/dist/bridge/src/runner-private-env.d.ts.map +1 -1
  36. package/dist/{chunk-DIGFA7Z5.js → chunk-27SXN33H.js} +13 -5
  37. package/dist/chunk-27SXN33H.js.map +1 -0
  38. package/dist/{chunk-AITJ7ELM.js → chunk-2XM3ZH36.js} +59 -23
  39. package/dist/chunk-2XM3ZH36.js.map +1 -0
  40. package/dist/{chunk-KUQAJVYT.js → chunk-3HACK2Z7.js} +142 -28
  41. package/dist/chunk-3HACK2Z7.js.map +1 -0
  42. package/dist/{chunk-J72MO2WA.js → chunk-5JPW27BI.js} +10 -9
  43. package/dist/chunk-5JPW27BI.js.map +1 -0
  44. package/dist/{chunk-AATHJRKL.js → chunk-5LQ62LNT.js} +4 -4
  45. package/dist/{chunk-AATHJRKL.js.map → chunk-5LQ62LNT.js.map} +1 -1
  46. package/dist/{chunk-S2XHGWQC.js → chunk-6CYKTHNT.js} +44 -15
  47. package/dist/chunk-6CYKTHNT.js.map +1 -0
  48. package/dist/{chunk-XFIEVEU7.js → chunk-6OHZUUR7.js} +5 -4
  49. package/dist/chunk-6OHZUUR7.js.map +1 -0
  50. package/dist/{chunk-E572OHGY.js → chunk-76FLBODK.js} +4 -3
  51. package/dist/chunk-76FLBODK.js.map +1 -0
  52. package/dist/{chunk-HPMQRAIF.js → chunk-7DRFKAJZ.js} +7 -7
  53. package/dist/{chunk-HPMQRAIF.js.map → chunk-7DRFKAJZ.js.map} +1 -1
  54. package/dist/{chunk-EX3GLAL6.js → chunk-7H6XRCPG.js} +5 -5
  55. package/dist/{chunk-EX3GLAL6.js.map → chunk-7H6XRCPG.js.map} +1 -1
  56. package/dist/{chunk-4FVIT5DI.js → chunk-7Y6S4XLL.js} +3 -3
  57. package/dist/{chunk-4FVIT5DI.js.map → chunk-7Y6S4XLL.js.map} +1 -1
  58. package/dist/{chunk-RDTLPOPD.js → chunk-BEYNH2LS.js} +4 -4
  59. package/dist/{chunk-RDTLPOPD.js.map → chunk-BEYNH2LS.js.map} +1 -1
  60. package/dist/{chunk-GNZBFSRB.js → chunk-BOT64P3U.js} +4 -4
  61. package/dist/{chunk-GNZBFSRB.js.map → chunk-BOT64P3U.js.map} +1 -1
  62. package/dist/{chunk-VMVDAZLA.js → chunk-BRK5QZKI.js} +108 -19
  63. package/dist/chunk-BRK5QZKI.js.map +1 -0
  64. package/dist/{chunk-QSYQOTWN.js → chunk-BY5WIRCU.js} +58 -5
  65. package/dist/chunk-BY5WIRCU.js.map +1 -0
  66. package/dist/{chunk-Z7ZEZZB6.js → chunk-C5HFK34M.js} +3 -3
  67. package/dist/chunk-C5HFK34M.js.map +1 -0
  68. package/dist/{chunk-ABFPSVIS.js → chunk-COAFAYBS.js} +31 -7
  69. package/dist/chunk-COAFAYBS.js.map +1 -0
  70. package/dist/{chunk-YLLVSR2U.js → chunk-E5NQRHEB.js} +30 -7
  71. package/dist/chunk-E5NQRHEB.js.map +1 -0
  72. package/dist/{chunk-BFMYYNDT.js → chunk-F3D25RGM.js} +11 -3
  73. package/dist/chunk-F3D25RGM.js.map +1 -0
  74. package/dist/{chunk-QAKUD6QN.js → chunk-GF5JXQIZ.js} +3 -3
  75. package/dist/{chunk-QAKUD6QN.js.map → chunk-GF5JXQIZ.js.map} +1 -1
  76. package/dist/{chunk-ZFUZ5AKM.js → chunk-I7LC5TDY.js} +3 -3
  77. package/dist/{chunk-ZFUZ5AKM.js.map → chunk-I7LC5TDY.js.map} +1 -1
  78. package/dist/{chunk-NB7SYQYP.js → chunk-ICSGNT5P.js} +7 -7
  79. package/dist/{chunk-NB7SYQYP.js.map → chunk-ICSGNT5P.js.map} +1 -1
  80. package/dist/{chunk-CEKW3KXP.js → chunk-ITFCWMOY.js} +18 -15
  81. package/dist/chunk-ITFCWMOY.js.map +1 -0
  82. package/dist/{chunk-LSSYC5IC.js → chunk-IZQOO6MN.js} +2 -2
  83. package/dist/{chunk-LSSYC5IC.js.map → chunk-IZQOO6MN.js.map} +1 -1
  84. package/dist/{chunk-7LP7RCZI.js → chunk-JFLQICIU.js} +5 -5
  85. package/dist/{chunk-7LP7RCZI.js.map → chunk-JFLQICIU.js.map} +1 -1
  86. package/dist/{chunk-COYF6IG2.js → chunk-JJJ2G4K2.js} +5 -5
  87. package/dist/{chunk-COYF6IG2.js.map → chunk-JJJ2G4K2.js.map} +1 -1
  88. package/dist/{chunk-RHN5MRQO.js → chunk-JMIKGAUA.js} +27 -5
  89. package/dist/chunk-JMIKGAUA.js.map +1 -0
  90. package/dist/{chunk-DGTI65OC.js → chunk-K3R2UKG7.js} +17 -11
  91. package/dist/chunk-K3R2UKG7.js.map +1 -0
  92. package/dist/{chunk-3GMOPFWH.js → chunk-KB56WBQ3.js} +4 -4
  93. package/dist/{chunk-3GMOPFWH.js.map → chunk-KB56WBQ3.js.map} +1 -1
  94. package/dist/{chunk-ZHGKAZJ7.js → chunk-KJSC2ZD6.js} +56 -8
  95. package/dist/chunk-KJSC2ZD6.js.map +1 -0
  96. package/dist/{chunk-ZBHZLWV3.js → chunk-KPKGWXUJ.js} +4 -4
  97. package/dist/{chunk-ZBHZLWV3.js.map → chunk-KPKGWXUJ.js.map} +1 -1
  98. package/dist/{chunk-EJPMNDTP.js → chunk-KXJMQTOU.js} +3 -3
  99. package/dist/{chunk-EJPMNDTP.js.map → chunk-KXJMQTOU.js.map} +1 -1
  100. package/dist/{chunk-7HX6FNKL.js → chunk-LRBP3234.js} +41 -56
  101. package/dist/chunk-LRBP3234.js.map +1 -0
  102. package/dist/{chunk-FKQNBCDW.js → chunk-M4OG2YN4.js} +4 -4
  103. package/dist/{chunk-FKQNBCDW.js.map → chunk-M4OG2YN4.js.map} +1 -1
  104. package/dist/{chunk-UI745XC3.js → chunk-MAZ3UXJK.js} +13 -7
  105. package/dist/chunk-MAZ3UXJK.js.map +1 -0
  106. package/dist/{chunk-ASWTQQ7E.js → chunk-MM4YO3EL.js} +3 -3
  107. package/dist/{chunk-ASWTQQ7E.js.map → chunk-MM4YO3EL.js.map} +1 -1
  108. package/dist/{chunk-6YR4ALVX.js → chunk-OCQNUV4T.js} +7 -7
  109. package/dist/{chunk-6YR4ALVX.js.map → chunk-OCQNUV4T.js.map} +1 -1
  110. package/dist/{chunk-4MUDQCBP.js → chunk-PJJSBZZP.js} +3 -3
  111. package/dist/{chunk-4MUDQCBP.js.map → chunk-PJJSBZZP.js.map} +1 -1
  112. package/dist/{chunk-HWNK3F3X.js → chunk-PKBLJI23.js} +588 -76
  113. package/dist/chunk-PKBLJI23.js.map +1 -0
  114. package/dist/{chunk-NOA6EJXE.js → chunk-PKE3PXOK.js} +3 -3
  115. package/dist/{chunk-NOA6EJXE.js.map → chunk-PKE3PXOK.js.map} +1 -1
  116. package/dist/{chunk-AZ2H6R5I.js → chunk-PMWRM4EJ.js} +74 -39
  117. package/dist/chunk-PMWRM4EJ.js.map +1 -0
  118. package/dist/{chunk-VYVTEMAW.js → chunk-PNUM7GUY.js} +3 -3
  119. package/dist/{chunk-VYVTEMAW.js.map → chunk-PNUM7GUY.js.map} +1 -1
  120. package/dist/{chunk-X3YGUKCG.js → chunk-Q5RN4PWV.js} +3 -3
  121. package/dist/{chunk-X3YGUKCG.js.map → chunk-Q5RN4PWV.js.map} +1 -1
  122. package/dist/{chunk-BBBCJSSU.js → chunk-QIHL3YPL.js} +4 -4
  123. package/dist/{chunk-BBBCJSSU.js.map → chunk-QIHL3YPL.js.map} +1 -1
  124. package/dist/{chunk-HMISULVD.js → chunk-QK7AG5AV.js} +4 -4
  125. package/dist/{chunk-HMISULVD.js.map → chunk-QK7AG5AV.js.map} +1 -1
  126. package/dist/{chunk-ZDLUQLI6.js → chunk-QPWR3YMY.js} +15 -5
  127. package/dist/chunk-QPWR3YMY.js.map +1 -0
  128. package/dist/{chunk-SVTMNSPI.js → chunk-QXKUFROW.js} +5 -5
  129. package/dist/{chunk-SVTMNSPI.js.map → chunk-QXKUFROW.js.map} +1 -1
  130. package/dist/{chunk-5Y2KGB4H.js → chunk-RQMIZONH.js} +34 -9
  131. package/dist/chunk-RQMIZONH.js.map +1 -0
  132. package/dist/{chunk-LSI2IVFT.js → chunk-RXGPFAMN.js} +4 -3
  133. package/dist/chunk-RXGPFAMN.js.map +1 -0
  134. package/dist/{chunk-NUA33BYO.js → chunk-S2H3RBK7.js} +42 -15
  135. package/dist/chunk-S2H3RBK7.js.map +1 -0
  136. package/dist/{chunk-2LAPHLDH.js → chunk-SJNZ4WPA.js} +44 -35
  137. package/dist/chunk-SJNZ4WPA.js.map +1 -0
  138. package/dist/{chunk-QEULL4Q3.js → chunk-T2VBPVWZ.js} +77 -18
  139. package/dist/chunk-T2VBPVWZ.js.map +1 -0
  140. package/dist/{chunk-Z3VKUWAX.js → chunk-TSTRH4SM.js} +3 -3
  141. package/dist/{chunk-Z3VKUWAX.js.map → chunk-TSTRH4SM.js.map} +1 -1
  142. package/dist/{chunk-5J4NPGFM.js → chunk-TZERN27L.js} +5 -5
  143. package/dist/{chunk-5J4NPGFM.js.map → chunk-TZERN27L.js.map} +1 -1
  144. package/dist/{chunk-XGULGQA3.js → chunk-U673DB5U.js} +4 -4
  145. package/dist/{chunk-XGULGQA3.js.map → chunk-U673DB5U.js.map} +1 -1
  146. package/dist/{chunk-IRYKRKVQ.js → chunk-URCJIV7T.js} +3 -3
  147. package/dist/{chunk-IRYKRKVQ.js.map → chunk-URCJIV7T.js.map} +1 -1
  148. package/dist/{chunk-ADPM6AYF.js → chunk-VSX2G7LA.js} +3 -3
  149. package/dist/{chunk-ADPM6AYF.js.map → chunk-VSX2G7LA.js.map} +1 -1
  150. package/dist/{chunk-ILLTBKDJ.js → chunk-X37JUNEW.js} +4 -4
  151. package/dist/{chunk-ILLTBKDJ.js.map → chunk-X37JUNEW.js.map} +1 -1
  152. package/dist/{chunk-IHFGPHCT.js → chunk-Z3IRZBXB.js} +49 -25
  153. package/dist/chunk-Z3IRZBXB.js.map +1 -0
  154. package/dist/{chunk-ZAELRYKS.js → chunk-ZWJCRHP3.js} +3 -3
  155. package/dist/{chunk-ZAELRYKS.js.map → chunk-ZWJCRHP3.js.map} +1 -1
  156. package/dist/{claude-code-RE46FJXI.js → claude-code-BBMNVH2J.js} +5 -5
  157. package/dist/{claude-code-RE46FJXI.js.map → claude-code-BBMNVH2J.js.map} +1 -1
  158. package/dist/cli/index.js +348 -141
  159. package/dist/cli/index.js.map +1 -1
  160. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  161. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  162. package/dist/cli/src/commands/config.d.ts.map +1 -1
  163. package/dist/cli/src/commands/diff.d.ts.map +1 -1
  164. package/dist/cli/src/commands/harness.d.ts.map +1 -1
  165. package/dist/cli/src/commands/integration.d.ts.map +1 -1
  166. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  167. package/dist/cli/src/commands/library-index.d.ts +8 -1
  168. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  169. package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
  170. package/dist/cli/src/commands/outdated.d.ts.map +1 -1
  171. package/dist/cli/src/commands/plugin-registry-cmd.d.ts.map +1 -1
  172. package/dist/cli/src/commands/project.d.ts.map +1 -1
  173. package/dist/cli/src/commands/rebuild.d.ts.map +1 -1
  174. package/dist/cli/src/commands/run.d.ts.map +1 -1
  175. package/dist/cli/src/commands/serve-preflight.d.ts +31 -1
  176. package/dist/cli/src/commands/serve-preflight.d.ts.map +1 -1
  177. package/dist/cli/src/commands/serve.d.ts +10 -0
  178. package/dist/cli/src/commands/serve.d.ts.map +1 -1
  179. package/dist/cli/src/commands/source-manifest-publish.d.ts.map +1 -1
  180. package/dist/cli/src/commands/source-manifest.d.ts +19 -7
  181. package/dist/cli/src/commands/source-manifest.d.ts.map +1 -1
  182. package/dist/cli/src/commands/validate-instances.d.ts.map +1 -1
  183. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  184. package/dist/cli/src/commands/why.d.ts.map +1 -1
  185. package/dist/cli/src/config-checks.d.ts +23 -5
  186. package/dist/cli/src/config-checks.d.ts.map +1 -1
  187. package/dist/cli/src/harness-error.d.ts +12 -1
  188. package/dist/cli/src/harness-error.d.ts.map +1 -1
  189. package/dist/cli/src/helpers.d.ts +18 -8
  190. package/dist/cli/src/helpers.d.ts.map +1 -1
  191. package/dist/cli/src/plugin-store/index.d.ts +10 -1
  192. package/dist/cli/src/plugin-store/index.d.ts.map +1 -1
  193. package/dist/cli/src/plugin-store/spec.d.ts +8 -0
  194. package/dist/cli/src/plugin-store/spec.d.ts.map +1 -1
  195. package/dist/cli/src/skill-checks.d.ts +2 -2
  196. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  197. package/dist/connectors/config.js +5 -5
  198. package/dist/connectors/index.js +22 -22
  199. package/dist/connectors/src/connector-manager.d.ts.map +1 -1
  200. package/dist/connectors-47EM6C2P.js +48 -0
  201. package/dist/{connectors-7THEF7YA.js.map → connectors-47EM6C2P.js.map} +1 -1
  202. package/dist/core/framework.js +1 -1
  203. package/dist/core/index.js +9 -9
  204. package/dist/core/manifest.js +2 -2
  205. package/dist/core/models.js +1 -1
  206. package/dist/core/provider-registry-credentials.js +2 -2
  207. package/dist/core/provider-registry.js +1 -1
  208. package/dist/core/publish-manifest.js +3 -3
  209. package/dist/core/ref.js +1 -1
  210. package/dist/core/runtime-assets.js +5 -5
  211. package/dist/core/src/framework.d.ts +5 -3
  212. package/dist/core/src/framework.d.ts.map +1 -1
  213. package/dist/core/src/index.d.ts +2 -1
  214. package/dist/core/src/index.d.ts.map +1 -1
  215. package/dist/core/src/lock.d.ts +12 -0
  216. package/dist/core/src/lock.d.ts.map +1 -1
  217. package/dist/core/src/manifest.d.ts +15 -0
  218. package/dist/core/src/manifest.d.ts.map +1 -1
  219. package/dist/core/src/models.d.ts +7 -0
  220. package/dist/core/src/models.d.ts.map +1 -1
  221. package/dist/core/src/provider-registry.d.ts +6 -0
  222. package/dist/core/src/provider-registry.d.ts.map +1 -1
  223. package/dist/core/src/workspace-config.d.ts +10 -1
  224. package/dist/core/src/workspace-config.d.ts.map +1 -1
  225. package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
  226. package/dist/core/workspace-config.js +4 -4
  227. package/dist/deploy/index.js +9 -9
  228. package/dist/discovery/index.js +5 -5
  229. package/dist/discovery/src/parse-manifest.d.ts.map +1 -1
  230. package/dist/{ensure-sources-IH7CHSJF.js → ensure-sources-K5EFNC3L.js} +35 -21
  231. package/dist/ensure-sources-K5EFNC3L.js.map +1 -0
  232. package/dist/factory-assets/connectors/box.js +22 -22
  233. package/dist/factory-assets/connectors/deploy.js +22 -22
  234. package/dist/factory-assets/connectors/devserver.js +22 -22
  235. package/dist/factory-assets/connectors/flow/adapter.js +22 -22
  236. package/dist/factory-assets/connectors/flow/engine.js +10 -10
  237. package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
  238. package/dist/factory-assets/connectors/flow/run-flow.js +24 -24
  239. package/dist/factory-assets/connectors/flow.js +22 -22
  240. package/dist/factory-assets/connectors/git.js +22 -22
  241. package/dist/factory-assets/connectors/gmail.js +22 -22
  242. package/dist/factory-assets/connectors/googledrive.js +22 -22
  243. package/dist/factory-assets/connectors/local.js +22 -22
  244. package/dist/factory-assets/connectors/mattermost.js +22 -22
  245. package/dist/factory-assets/connectors/memory.js +22 -22
  246. package/dist/factory-assets/connectors/minio.js +22 -22
  247. package/dist/factory-assets/connectors/postgres.js +22 -22
  248. package/dist/factory-assets/connectors/s3.js +22 -22
  249. package/dist/factory-assets/connectors/sharepoint.js +22 -22
  250. package/dist/factory-assets/connectors/sqlite.js +22 -22
  251. package/dist/factory-assets/connectors/static-server.js +22 -22
  252. package/dist/factory-assets/connectors/tunnel.js +22 -22
  253. package/dist/factory-assets/connectors/webdav.js +22 -22
  254. package/dist/factory-assets/connectors/xstate-store.js +22 -22
  255. package/dist/factory-assets/connectors/xstate.js +22 -22
  256. package/dist/flows-KLBNSKLO.js +26 -0
  257. package/dist/{flows-4JZQ3XFK.js.map → flows-KLBNSKLO.js.map} +1 -1
  258. package/dist/helpers-LUSV2ICC.js +52 -0
  259. package/dist/{helpers-JNMK3FC2.js.map → helpers-LUSV2ICC.js.map} +1 -1
  260. package/dist/library/index.js +14 -14
  261. package/dist/library/install.js +5 -5
  262. package/dist/library/src/index.d.ts +1 -1
  263. package/dist/library/src/index.d.ts.map +1 -1
  264. package/dist/library/src/install/index.d.ts +1 -1
  265. package/dist/library/src/install/index.d.ts.map +1 -1
  266. package/dist/library/src/install/install-from-manifest.d.ts +13 -0
  267. package/dist/library/src/install/install-from-manifest.d.ts.map +1 -1
  268. package/dist/library/src/install/source-fetch-github.d.ts.map +1 -1
  269. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  270. package/dist/library/src/remote/remote-catalog-source.d.ts +3 -1
  271. package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
  272. package/dist/library/src/remote/rest-catalog-source.d.ts +3 -2
  273. package/dist/library/src/remote/rest-catalog-source.d.ts.map +1 -1
  274. package/dist/{library-publish-I3UWXAHI.js → library-publish-XMRCKRNR.js} +54 -55
  275. package/dist/library-publish-XMRCKRNR.js.map +1 -0
  276. package/dist/model-endpoint/index.js +12 -12
  277. package/dist/model-endpoint/src/openai-chat.d.ts +7 -2
  278. package/dist/model-endpoint/src/openai-chat.d.ts.map +1 -1
  279. package/dist/model-endpoint/src/openai-shared.d.ts +8 -0
  280. package/dist/model-endpoint/src/openai-shared.d.ts.map +1 -1
  281. package/dist/model-endpoint/src/server.d.ts.map +1 -1
  282. package/dist/model-endpoint/src/types.d.ts +1 -1
  283. package/dist/model-endpoint/src/types.d.ts.map +1 -1
  284. package/dist/model-endpoint/src/usage-cost.d.ts +23 -0
  285. package/dist/model-endpoint/src/usage-cost.d.ts.map +1 -0
  286. package/dist/open-library-XBR46DJL.js +56 -0
  287. package/dist/{open-library-NKKUJLWA.js.map → open-library-XBR46DJL.js.map} +1 -1
  288. package/dist/open-registry-W562DCDL.js +32 -0
  289. package/dist/{open-registry-BYAXSHUI.js.map → open-registry-W562DCDL.js.map} +1 -1
  290. package/dist/paths-2AZXB3QL.js +22 -0
  291. package/dist/{paths-UKWE35XS.js.map → paths-2AZXB3QL.js.map} +1 -1
  292. package/dist/plugin-store-36SIL4TV.js +23 -0
  293. package/dist/{plugin-store-ABE35NRX.js.map → plugin-store-36SIL4TV.js.map} +1 -1
  294. package/dist/project-D7GN7WLS.js +86 -0
  295. package/dist/{project-BIPK47JK.js.map → project-D7GN7WLS.js.map} +1 -1
  296. package/dist/resolver/index.js +10 -10
  297. package/dist/runner/index.js +39 -39
  298. package/dist/runner/src/capability-roundtrip.d.ts +7 -6
  299. package/dist/runner/src/capability-roundtrip.d.ts.map +1 -1
  300. package/dist/runner/src/serve.d.ts +6 -5
  301. package/dist/runner/src/serve.d.ts.map +1 -1
  302. package/dist/sdk/asset-manager.js +18 -18
  303. package/dist/sdk/bridge.js +19 -19
  304. package/dist/sdk/core.js +9 -9
  305. package/dist/sdk/flow.js +10 -10
  306. package/dist/sdk/index.js +39 -39
  307. package/dist/sdk/resolver.js +10 -10
  308. package/dist/sdk/runner.js +39 -39
  309. package/dist/sdk/transport/ws/server.js +10 -10
  310. package/dist/sdk/transport/ws.js +10 -10
  311. package/dist/sdk/transport.js +10 -10
  312. package/dist/{serve-preflight-FLTIBTEX.js → serve-preflight-CGA5G3AE.js} +63 -35
  313. package/dist/serve-preflight-CGA5G3AE.js.map +1 -0
  314. package/dist/{setup-AG6NFHSN.js → setup-IBDNJAOU.js} +31 -31
  315. package/dist/{setup-AG6NFHSN.js.map → setup-IBDNJAOU.js.map} +1 -1
  316. package/dist/skills-CTTO7SZK.js +26 -0
  317. package/dist/{skills-UQYUHVKO.js.map → skills-CTTO7SZK.js.map} +1 -1
  318. package/dist/source-2DJ5KNOI.js +85 -0
  319. package/dist/{source-ASEHI2XS.js.map → source-2DJ5KNOI.js.map} +1 -1
  320. package/dist/source-fetch-github-RWHV4I5Z.js +4 -0
  321. package/dist/{source-fetch-github-ST4MFL3D.js.map → source-fetch-github-RWHV4I5Z.js.map} +1 -1
  322. package/dist/{source-manifest-publish-IEVV3W6J.js → source-manifest-publish-IYWUMUCY.js} +54 -56
  323. package/dist/source-manifest-publish-IYWUMUCY.js.map +1 -0
  324. package/dist/transport/index.js +10 -10
  325. package/dist/transport/ws/server.js +10 -10
  326. package/dist/transport/ws.js +10 -10
  327. package/dist/tui/index.js +47 -40
  328. package/dist/tui/index.js.map +1 -1
  329. package/dist/tui/src/repl.d.ts.map +1 -1
  330. package/dist/types/manifests.js +1 -1
  331. package/dist/types/src/manifests/index.d.ts +1 -1
  332. package/dist/types/src/manifests/index.d.ts.map +1 -1
  333. package/dist/types/src/manifests/scaffold-body.d.ts +2 -0
  334. package/dist/types/src/manifests/scaffold-body.d.ts.map +1 -1
  335. package/dist/workspace-plugin/adapters/mcp.js +29 -29
  336. package/dist/workspace-plugin/adapters/omp.js +15 -15
  337. package/dist/workspace-plugin/index.js +2 -2
  338. package/package.json +1 -1
  339. package/dist/chunk-2LAPHLDH.js.map +0 -1
  340. package/dist/chunk-5Y2KGB4H.js.map +0 -1
  341. package/dist/chunk-7HX6FNKL.js.map +0 -1
  342. package/dist/chunk-ABFPSVIS.js.map +0 -1
  343. package/dist/chunk-AITJ7ELM.js.map +0 -1
  344. package/dist/chunk-AZ2H6R5I.js.map +0 -1
  345. package/dist/chunk-BFMYYNDT.js.map +0 -1
  346. package/dist/chunk-CEKW3KXP.js.map +0 -1
  347. package/dist/chunk-DGTI65OC.js.map +0 -1
  348. package/dist/chunk-DIGFA7Z5.js.map +0 -1
  349. package/dist/chunk-E572OHGY.js.map +0 -1
  350. package/dist/chunk-HWNK3F3X.js.map +0 -1
  351. package/dist/chunk-IHFGPHCT.js.map +0 -1
  352. package/dist/chunk-J72MO2WA.js.map +0 -1
  353. package/dist/chunk-KUQAJVYT.js.map +0 -1
  354. package/dist/chunk-LSI2IVFT.js.map +0 -1
  355. package/dist/chunk-NUA33BYO.js.map +0 -1
  356. package/dist/chunk-QEULL4Q3.js.map +0 -1
  357. package/dist/chunk-QSYQOTWN.js.map +0 -1
  358. package/dist/chunk-RHN5MRQO.js.map +0 -1
  359. package/dist/chunk-S2XHGWQC.js.map +0 -1
  360. package/dist/chunk-UI745XC3.js.map +0 -1
  361. package/dist/chunk-VMVDAZLA.js.map +0 -1
  362. package/dist/chunk-XFIEVEU7.js.map +0 -1
  363. package/dist/chunk-YLLVSR2U.js.map +0 -1
  364. package/dist/chunk-Z7ZEZZB6.js.map +0 -1
  365. package/dist/chunk-ZDLUQLI6.js.map +0 -1
  366. package/dist/chunk-ZHGKAZJ7.js.map +0 -1
  367. package/dist/connectors-7THEF7YA.js +0 -48
  368. package/dist/ensure-sources-IH7CHSJF.js.map +0 -1
  369. package/dist/flows-4JZQ3XFK.js +0 -26
  370. package/dist/helpers-JNMK3FC2.js +0 -38
  371. package/dist/library-publish-I3UWXAHI.js.map +0 -1
  372. package/dist/open-library-NKKUJLWA.js +0 -42
  373. package/dist/open-registry-BYAXSHUI.js +0 -32
  374. package/dist/paths-UKWE35XS.js +0 -22
  375. package/dist/plugin-store-ABE35NRX.js +0 -23
  376. package/dist/project-BIPK47JK.js +0 -86
  377. package/dist/serve-preflight-FLTIBTEX.js.map +0 -1
  378. package/dist/skills-UQYUHVKO.js +0 -26
  379. package/dist/source-ASEHI2XS.js +0 -85
  380. package/dist/source-fetch-github-ST4MFL3D.js +0 -4
  381. package/dist/source-manifest-publish-IEVV3W6J.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../bridge/src/codex/config-toml.ts"],"names":["stringifyToml"],"mappings":"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","file":"chunk-XGULGQA3.js","sourcesContent":["/**\n * Codex's `config.toml` adapter — the AI provider registry materialized into\n * the only provider surface the Codex CLI reads (plan §2.3, codex rows).\n *\n * Codex is a **file-shaped** harness: it takes its endpoints from\n * `$CODEX_HOME/config.toml`, never from per-request options. Both codex modes\n * therefore get a session-private `CODEX_HOME` holding a rendered document:\n *\n * - every addressable registry entry becomes `[model_providers.<id>]` with\n * `base_url`, `env_key`, `wire_api`, `query_params` and `http_headers`\n * mapping 1:1 onto the entry's `base_url`, `credential`, `surface`,\n * `query_params` and `headers`;\n * - `model_provider` and `model` at the top level name the selected entry.\n *\n * The rendered file never contains a credential **value** — `env_key` holds\n * the *name* of the per-entry variable (`SKAILE_AIP_<ID>_KEY`, minted by\n * {@link providerCredentialEnvName}), and the value rides in the child\n * environment. An `oauth` entry has no env carrier at all: it gets\n * `requires_openai_auth`, which routes codex to its own auth manager.\n *\n * **Surface coverage.** Codex names the wire protocol `wire_api` and, as of\n * codex-cli 0.154, accepts exactly one value: `responses`. `chat` was removed\n * (\"`wire_api = \\\"chat\\\"` is no longer supported\", openai/codex#7782), and an\n * unknown value fails the *whole* document at load time — one unaddressable\n * entry would take the rest of the registry down with it. Entries whose\n * surface codex cannot speak (`openai-completions`, `anthropic-messages`,\n * `bedrock-converse-stream`, `google-*`) are therefore left out and reported\n * in {@link CodexConfigBuild.skipped} for the harness to log.\n *\n * @docLink packages/bridge/harnesses#codex-harness\n */\n\nimport { createHash } from \"node:crypto\";\nimport { mkdirSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { globalSkaileDir } from \"@skaile/workspaces/core\";\nimport {\n type AIProviderEntry,\n type AIProviderLlmEntry,\n type AIProviderRegistry,\n type AIProviderSurface,\n isEntryEnabled,\n type MergedAIProviderRegistry,\n parseModelRef,\n registryEntries,\n type ResolvedModelRef,\n resolveEntryBaseUrl,\n} from \"@skaile/workspaces/core/provider-registry\";\nimport { stringify as stringifyToml } from \"smol-toml\";\nimport { getProviderPreset } from \"../provider-catalog.js\";\nimport { providerCredentialEnvName } from \"../provider-materialize/credential-env.js\";\n\n/**\n * `surface` → codex `wire_api`. Only the responses-flavoured surfaces have a\n * codex spelling; see the module docstring for why `openai-completions` is\n * absent rather than mapped to the removed `chat` value.\n */\nconst CODEX_WIRE_API: Partial<Record<AIProviderSurface, string>> = {\n \"openai-codex-responses\": \"responses\",\n \"openai-responses\": \"responses\",\n \"azure-openai-responses\": \"responses\",\n};\n\n/**\n * Provider ids codex reserves for its own built-ins. A `[model_providers.<id>]`\n * table under one of them fails the whole document (\"model_providers contains\n * reserved built-in provider IDs\"), so such an entry is rendered under\n * {@link codexProviderTableId}.\n */\nconst CODEX_RESERVED_PROVIDER_IDS: ReadonlySet<string> = new Set([\"openai\", \"ollama\", \"lmstudio\"]);\n\n/**\n * The `[model_providers.<id>]` table name for a registry entry: the entry id,\n * or `skaile-<id>` when codex reserves that id (the `openai` preset).\n */\nexport function codexProviderTableId(id: string): string {\n return CODEX_RESERVED_PROVIDER_IDS.has(id) ? `skaile-${id}` : id;\n}\n\n/** Credential kinds whose value the adapter hands over in an env var. */\nconst ENV_DELIVERED_CREDENTIALS: Record<string, true> = {\n api_key_header: true,\n bearer: true,\n command: true,\n};\n\n/** One `[model_providers.<id>]` table, in codex's own vocabulary. */\nexport interface CodexModelProviderTable {\n /** Display name. Codex rejects a provider table without one. */\n name: string;\n base_url?: string;\n /** Name of the variable carrying the credential — never the credential. */\n env_key?: string;\n wire_api?: string;\n /** Routes codex to its own auth manager (ChatGPT subscription / stored key). */\n requires_openai_auth?: boolean;\n query_params?: Record<string, string>;\n http_headers?: Record<string, string>;\n}\n\n/** The subset of codex's `config.toml` this adapter owns. */\nexport interface CodexConfigDocument {\n /** Table id the session addresses (see {@link codexProviderTableId}); absent when nothing rendered. */\n model_provider?: string;\n /** Provider-side model id. */\n model?: string;\n model_providers: Record<string, CodexModelProviderTable>;\n}\n\n/** An entry codex cannot address, and why. */\nexport interface CodexSkippedEntry {\n id: string;\n reason: string;\n}\n\n/** Result of {@link buildCodexConfigDocument}. */\nexport interface CodexConfigBuild {\n document: CodexConfigDocument;\n /** Selected registry entry id (not the table id), when it rendered. */\n providerId?: string;\n /** Provider-side model id of the selection, when the selector named one. */\n model?: string;\n /**\n * Entries left out of the document. Non-fatal: codex keeps its built-in\n * providers, so a session whose selection was skipped behaves exactly as it\n * did before the registry existed.\n */\n skipped: CodexSkippedEntry[];\n /** Notes from `modelRef` resolution (dangling role, disabled provider, …). */\n warnings: string[];\n /**\n * Set when the selector named an entry codex cannot address: the session\n * must stop with `reason`, not fall back to codex's built-in providers.\n */\n unaddressable?: { id: string; reason: string };\n}\n\n/**\n * Whether the session's selector named the entry `selected` resolved to, rather\n * than reaching it by registry order alone.\n */\nfunction selectionNamesEntry(\n input: CodexConfigInput,\n selected: ResolvedModelRef,\n registry: AIProviderRegistry | MergedAIProviderRegistry,\n): boolean {\n if (selected.role && selected.modelId !== undefined) return true;\n const selector = input.modelRef?.trim() || input.model?.trim() || \"\";\n if (selector.startsWith(`${selected.providerId}/`)) return true;\n const entry = registryEntries(registry).find(([id]) => id === selected.providerId)?.[1] as\n | AIProviderLlmEntry\n | undefined;\n const modelId = selected.modelId;\n return (\n modelId !== undefined &&\n (entry?.model_map?.[modelId] !== undefined || entry?.capabilities?.[modelId] !== undefined)\n );\n}\n\n/** Inputs {@link buildCodexConfigDocument} reads off an `AgentConfig`. */\nexport interface CodexConfigInput {\n registry?: AIProviderRegistry | MergedAIProviderRegistry;\n /** `\"<providerId>/<modelId>\"`, a bare model id, or `\"@role\"`. */\n modelRef?: string;\n /** Legacy model field, used as the selector when `modelRef` is absent. */\n model?: string;\n /** Roles table (`skaile.yaml`), consulted for an `@role` selector. */\n roles?: Record<string, string>;\n}\n\n/**\n * Render one entry as a codex provider table, or explain why codex cannot\n * address it.\n */\nexport function renderCodexProviderTable(\n id: string,\n entry: AIProviderEntry,\n): { table: CodexModelProviderTable } | { skipped: string } {\n if (!isEntryEnabled(entry)) return { skipped: \"entry is disabled\" };\n if (entry.kind !== \"llm\" && entry.kind !== \"embed\")\n return { skipped: `kind '${entry.kind}' is not a model endpoint` };\n const llm = entry as AIProviderLlmEntry;\n // `surface` and `base_url` may live on the catalog preset the entry names —\n // the catalog layer fills them during a merge, but an entry handed straight\n // to a harness has not necessarily been through one.\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n const surface = llm.surface ?? preset?.surface;\n const wireApi = surface ? CODEX_WIRE_API[surface] : undefined;\n if (!wireApi)\n return {\n skipped: surface\n ? `codex has no wire_api for surface '${surface}'`\n : \"entry declares no surface\",\n };\n const credentialKind = entry.credential?.kind;\n const table: CodexModelProviderTable = { name: entry.label ?? id };\n const baseUrl = resolveEntryBaseUrl(entry) ?? preset?.base_url;\n if (baseUrl) table.base_url = baseUrl;\n if (credentialKind && ENV_DELIVERED_CREDENTIALS[credentialKind])\n table.env_key = providerCredentialEnvName(id);\n table.wire_api = wireApi;\n if (credentialKind === \"oauth\") table.requires_openai_auth = true;\n if (llm.query_params && Object.keys(llm.query_params).length > 0)\n table.query_params = { ...llm.query_params };\n if (entry.headers && Object.keys(entry.headers).length > 0)\n table.http_headers = { ...entry.headers };\n return { table };\n}\n\n/**\n * Build the document for a session: every addressable entry, plus the\n * selection when it resolved to one of them.\n */\nexport function buildCodexConfigDocument(input: CodexConfigInput): CodexConfigBuild {\n const document: CodexConfigDocument = { model_providers: {} };\n const skipped: CodexSkippedEntry[] = [];\n const entries = input.registry ? registryEntries(input.registry) : [];\n for (const [id, entry] of entries) {\n const rendered = renderCodexProviderTable(id, entry);\n if (\"skipped\" in rendered) skipped.push({ id, reason: rendered.skipped });\n else document.model_providers[codexProviderTableId(id)] = rendered.table;\n }\n\n if (!input.registry) return { document, skipped, warnings: [] };\n // An empty selector resolves the same way a bare one does — first entry in\n // registry order. A session that configured an endpoint and named no model\n // still means that endpoint, not codex's built-in default.\n const selected = parseModelRef(\n input.modelRef?.trim() || input.model?.trim() || \"\",\n input.registry,\n input.roles,\n );\n if (!selected) return { document, skipped, warnings: [] };\n const warnings = selected.warnings;\n const tableId = codexProviderTableId(selected.providerId);\n if (!document.model_providers[tableId]) {\n // A selector that names the entry (`ollama/llama3`, a role or a model its\n // `model_map` lists) and cannot be rendered must not fall through to\n // codex's built-in OpenAI: the prompt would go to a provider the user did\n // not pick. A bare model id that matched no entry only landed on the first\n // entry by registry order, so codex's own providers stay the right answer.\n const reason = skipped.find((s) => s.id === selected.providerId)?.reason;\n if (reason && selectionNamesEntry(input, selected, input.registry)) {\n return {\n document,\n skipped,\n warnings,\n unaddressable: { id: selected.providerId, reason },\n };\n }\n return { document, skipped, warnings };\n }\n document.model_provider = tableId;\n if (selected.providerModelId) document.model = selected.providerModelId;\n return {\n document,\n providerId: selected.providerId,\n ...(selected.providerModelId ? { model: selected.providerModelId } : {}),\n skipped,\n warnings,\n };\n}\n\n/** Serialize a document to TOML. Deterministic: registry order throughout. */\nexport function renderCodexConfigToml(document: CodexConfigDocument): string {\n const ordered: Record<string, unknown> = {};\n if (document.model_provider) ordered.model_provider = document.model_provider;\n if (document.model) ordered.model = document.model;\n ordered.model_providers = document.model_providers;\n return `${stringifyToml(ordered)}\\n`;\n}\n\n/**\n * The session-private codex home.\n *\n * Deliberately outside `cwd`: codex's `workspace-write` sandbox makes the\n * working tree writable by the model, and a config home inside it would let a\n * turn rewrite its own `base_url`. `$SKAILE_HOME` (honoured by\n * {@link globalSkaileDir}) relocates the whole tree, which is also the test\n * seam.\n */\nexport function codexSessionHome(config: { cwd: string; sessionId?: string }): string {\n const key =\n config.sessionId && /^[A-Za-z0-9._-]{1,128}$/.test(config.sessionId)\n ? config.sessionId\n : createHash(\"sha256\")\n .update(config.sessionId ?? config.cwd)\n .digest(\"hex\")\n .slice(0, 32);\n return join(globalSkaileDir(), \"codex\", key);\n}\n\n/**\n * Write `<home>/config.toml`, creating the home always. Atomic: a\n * partially written document would fail codex's config load for the whole\n * session.\n *\n * A document with no provider tables says nothing codex does not already\n * know, so nothing is written and a file left by an earlier render is\n * removed — a session that no longer carries a registry must not keep\n * answering to the one it used to have.\n *\n * @returns the absolute path written, or `undefined` when there was nothing\n * to render.\n */\nexport function writeCodexConfigToml(\n home: string,\n document: CodexConfigDocument,\n): string | undefined {\n const path = join(home, \"config.toml\");\n // codex exits when CODEX_HOME names a directory that does not exist, so the\n // home exists before the early return too.\n mkdirSync(home, { recursive: true, mode: 0o700 });\n if (Object.keys(document.model_providers).length === 0) {\n rmSync(path, { force: true });\n return undefined;\n }\n const temporary = join(home, \"config.toml.new\");\n rmSync(temporary, { force: true });\n writeFileSync(temporary, renderCodexConfigToml(document), { mode: 0o600, flag: \"wx\" });\n renameSync(temporary, path);\n return path;\n}\n"]}
1
+ {"version":3,"sources":["../bridge/src/codex/config-toml.ts"],"names":["stringifyToml"],"mappings":"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","file":"chunk-U673DB5U.js","sourcesContent":["/**\n * Codex's `config.toml` adapter — the AI provider registry materialized into\n * the only provider surface the Codex CLI reads (plan §2.3, codex rows).\n *\n * Codex is a **file-shaped** harness: it takes its endpoints from\n * `$CODEX_HOME/config.toml`, never from per-request options. Both codex modes\n * therefore get a session-private `CODEX_HOME` holding a rendered document:\n *\n * - every addressable registry entry becomes `[model_providers.<id>]` with\n * `base_url`, `env_key`, `wire_api`, `query_params` and `http_headers`\n * mapping 1:1 onto the entry's `base_url`, `credential`, `surface`,\n * `query_params` and `headers`;\n * - `model_provider` and `model` at the top level name the selected entry.\n *\n * The rendered file never contains a credential **value** — `env_key` holds\n * the *name* of the per-entry variable (`SKAILE_AIP_<ID>_KEY`, minted by\n * {@link providerCredentialEnvName}), and the value rides in the child\n * environment. An `oauth` entry has no env carrier at all: it gets\n * `requires_openai_auth`, which routes codex to its own auth manager.\n *\n * **Surface coverage.** Codex names the wire protocol `wire_api` and, as of\n * codex-cli 0.154, accepts exactly one value: `responses`. `chat` was removed\n * (\"`wire_api = \\\"chat\\\"` is no longer supported\", openai/codex#7782), and an\n * unknown value fails the *whole* document at load time — one unaddressable\n * entry would take the rest of the registry down with it. Entries whose\n * surface codex cannot speak (`openai-completions`, `anthropic-messages`,\n * `bedrock-converse-stream`, `google-*`) are therefore left out and reported\n * in {@link CodexConfigBuild.skipped} for the harness to log.\n *\n * @docLink packages/bridge/harnesses#codex-harness\n */\n\nimport { createHash } from \"node:crypto\";\nimport { mkdirSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { globalSkaileDir } from \"@skaile/workspaces/core\";\nimport {\n type AIProviderEntry,\n type AIProviderLlmEntry,\n type AIProviderRegistry,\n type AIProviderSurface,\n isEntryEnabled,\n type MergedAIProviderRegistry,\n parseModelRef,\n registryEntries,\n type ResolvedModelRef,\n resolveEntryBaseUrl,\n} from \"@skaile/workspaces/core/provider-registry\";\nimport { stringify as stringifyToml } from \"smol-toml\";\nimport { getProviderPreset } from \"../provider-catalog.js\";\nimport { providerCredentialEnvName } from \"../provider-materialize/credential-env.js\";\n\n/**\n * `surface` → codex `wire_api`. Only the responses-flavoured surfaces have a\n * codex spelling; see the module docstring for why `openai-completions` is\n * absent rather than mapped to the removed `chat` value.\n */\nconst CODEX_WIRE_API: Partial<Record<AIProviderSurface, string>> = {\n \"openai-codex-responses\": \"responses\",\n \"openai-responses\": \"responses\",\n \"azure-openai-responses\": \"responses\",\n};\n\n/**\n * Provider ids codex reserves for its own built-ins. A `[model_providers.<id>]`\n * table under one of them fails the whole document (\"model_providers contains\n * reserved built-in provider IDs\"), so such an entry is rendered under\n * {@link codexProviderTableId}.\n */\nconst CODEX_RESERVED_PROVIDER_IDS: ReadonlySet<string> = new Set([\"openai\", \"ollama\", \"lmstudio\"]);\n\n/**\n * The `[model_providers.<id>]` table name for a registry entry: the entry id,\n * or `skaile-<id>` when codex reserves that id (the `openai` preset).\n */\nexport function codexProviderTableId(id: string): string {\n return CODEX_RESERVED_PROVIDER_IDS.has(id) ? `skaile-${id}` : id;\n}\n\n/** Credential kinds whose value the adapter hands over in an env var. */\nconst ENV_DELIVERED_CREDENTIALS: Record<string, true> = {\n api_key_header: true,\n bearer: true,\n command: true,\n};\n\n/** One `[model_providers.<id>]` table, in codex's own vocabulary. */\nexport interface CodexModelProviderTable {\n /** Display name. Codex rejects a provider table without one. */\n name: string;\n base_url?: string;\n /** Name of the variable carrying the credential — never the credential. */\n env_key?: string;\n wire_api?: string;\n /** Routes codex to its own auth manager (ChatGPT subscription / stored key). */\n requires_openai_auth?: boolean;\n query_params?: Record<string, string>;\n http_headers?: Record<string, string>;\n}\n\n/** The subset of codex's `config.toml` this adapter owns. */\nexport interface CodexConfigDocument {\n /** Table id the session addresses (see {@link codexProviderTableId}); absent when nothing rendered. */\n model_provider?: string;\n /** Provider-side model id. */\n model?: string;\n model_providers: Record<string, CodexModelProviderTable>;\n}\n\n/** An entry codex cannot address, and why. */\nexport interface CodexSkippedEntry {\n id: string;\n reason: string;\n}\n\n/** Result of {@link buildCodexConfigDocument}. */\nexport interface CodexConfigBuild {\n document: CodexConfigDocument;\n /** Selected registry entry id (not the table id), when it rendered. */\n providerId?: string;\n /** Provider-side model id of the selection, when the selector named one. */\n model?: string;\n /**\n * Entries left out of the document. Non-fatal: codex keeps its built-in\n * providers, so a session whose selection was skipped behaves exactly as it\n * did before the registry existed.\n */\n skipped: CodexSkippedEntry[];\n /** Notes from `modelRef` resolution (dangling role, disabled provider, …). */\n warnings: string[];\n /**\n * Set when the selector named an entry codex cannot address: the session\n * must stop with `reason`, not fall back to codex's built-in providers.\n */\n unaddressable?: { id: string; reason: string };\n}\n\n/**\n * Whether the session's selector named the entry `selected` resolved to, rather\n * than reaching it by registry order alone.\n */\nfunction selectionNamesEntry(\n input: CodexConfigInput,\n selected: ResolvedModelRef,\n registry: AIProviderRegistry | MergedAIProviderRegistry,\n): boolean {\n if (selected.role && selected.modelId !== undefined) return true;\n const selector = input.modelRef?.trim() || input.model?.trim() || \"\";\n if (selector.startsWith(`${selected.providerId}/`)) return true;\n const entry = registryEntries(registry).find(([id]) => id === selected.providerId)?.[1] as\n | AIProviderLlmEntry\n | undefined;\n const modelId = selected.modelId;\n return (\n modelId !== undefined &&\n (entry?.model_map?.[modelId] !== undefined || entry?.capabilities?.[modelId] !== undefined)\n );\n}\n\n/** Inputs {@link buildCodexConfigDocument} reads off an `AgentConfig`. */\nexport interface CodexConfigInput {\n registry?: AIProviderRegistry | MergedAIProviderRegistry;\n /** `\"<providerId>/<modelId>\"`, a bare model id, or `\"@role\"`. */\n modelRef?: string;\n /** Legacy model field, used as the selector when `modelRef` is absent. */\n model?: string;\n /** Roles table (`skaile.yaml`), consulted for an `@role` selector. */\n roles?: Record<string, string>;\n}\n\n/**\n * Render one entry as a codex provider table, or explain why codex cannot\n * address it.\n */\nexport function renderCodexProviderTable(\n id: string,\n entry: AIProviderEntry,\n): { table: CodexModelProviderTable } | { skipped: string } {\n if (!isEntryEnabled(entry)) return { skipped: \"entry is disabled\" };\n if (entry.kind !== \"llm\" && entry.kind !== \"embed\")\n return { skipped: `kind '${entry.kind}' is not a model endpoint` };\n const llm = entry as AIProviderLlmEntry;\n // `surface` and `base_url` may live on the catalog preset the entry names —\n // the catalog layer fills them during a merge, but an entry handed straight\n // to a harness has not necessarily been through one.\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n const surface = llm.surface ?? preset?.surface;\n const wireApi = surface ? CODEX_WIRE_API[surface] : undefined;\n if (!wireApi)\n return {\n skipped: surface\n ? `codex has no wire_api for surface '${surface}'`\n : \"entry declares no surface\",\n };\n const credentialKind = entry.credential?.kind;\n const table: CodexModelProviderTable = { name: entry.label ?? id };\n const baseUrl = resolveEntryBaseUrl(entry) ?? preset?.base_url;\n if (baseUrl) table.base_url = baseUrl;\n if (credentialKind && ENV_DELIVERED_CREDENTIALS[credentialKind])\n table.env_key = providerCredentialEnvName(id);\n table.wire_api = wireApi;\n if (credentialKind === \"oauth\") table.requires_openai_auth = true;\n if (llm.query_params && Object.keys(llm.query_params).length > 0)\n table.query_params = { ...llm.query_params };\n if (entry.headers && Object.keys(entry.headers).length > 0)\n table.http_headers = { ...entry.headers };\n return { table };\n}\n\n/**\n * Build the document for a session: every addressable entry, plus the\n * selection when it resolved to one of them.\n */\nexport function buildCodexConfigDocument(input: CodexConfigInput): CodexConfigBuild {\n const document: CodexConfigDocument = { model_providers: {} };\n const skipped: CodexSkippedEntry[] = [];\n const entries = input.registry ? registryEntries(input.registry) : [];\n for (const [id, entry] of entries) {\n const rendered = renderCodexProviderTable(id, entry);\n if (\"skipped\" in rendered) skipped.push({ id, reason: rendered.skipped });\n else document.model_providers[codexProviderTableId(id)] = rendered.table;\n }\n\n if (!input.registry) return { document, skipped, warnings: [] };\n // An empty selector resolves the same way a bare one does — first entry in\n // registry order. A session that configured an endpoint and named no model\n // still means that endpoint, not codex's built-in default.\n const selected = parseModelRef(\n input.modelRef?.trim() || input.model?.trim() || \"\",\n input.registry,\n input.roles,\n );\n if (!selected) return { document, skipped, warnings: [] };\n const warnings = selected.warnings;\n const tableId = codexProviderTableId(selected.providerId);\n if (!document.model_providers[tableId]) {\n // A selector that names the entry (`ollama/llama3`, a role or a model its\n // `model_map` lists) and cannot be rendered must not fall through to\n // codex's built-in OpenAI: the prompt would go to a provider the user did\n // not pick. A bare model id that matched no entry only landed on the first\n // entry by registry order, so codex's own providers stay the right answer.\n const reason = skipped.find((s) => s.id === selected.providerId)?.reason;\n if (reason && selectionNamesEntry(input, selected, input.registry)) {\n return {\n document,\n skipped,\n warnings,\n unaddressable: { id: selected.providerId, reason },\n };\n }\n return { document, skipped, warnings };\n }\n document.model_provider = tableId;\n if (selected.providerModelId) document.model = selected.providerModelId;\n return {\n document,\n providerId: selected.providerId,\n ...(selected.providerModelId ? { model: selected.providerModelId } : {}),\n skipped,\n warnings,\n };\n}\n\n/** Serialize a document to TOML. Deterministic: registry order throughout. */\nexport function renderCodexConfigToml(document: CodexConfigDocument): string {\n const ordered: Record<string, unknown> = {};\n if (document.model_provider) ordered.model_provider = document.model_provider;\n if (document.model) ordered.model = document.model;\n ordered.model_providers = document.model_providers;\n return `${stringifyToml(ordered)}\\n`;\n}\n\n/**\n * The session-private codex home.\n *\n * Deliberately outside `cwd`: codex's `workspace-write` sandbox makes the\n * working tree writable by the model, and a config home inside it would let a\n * turn rewrite its own `base_url`. `$SKAILE_HOME` (honoured by\n * {@link globalSkaileDir}) relocates the whole tree, which is also the test\n * seam.\n */\nexport function codexSessionHome(config: { cwd: string; sessionId?: string }): string {\n const key =\n config.sessionId && /^[A-Za-z0-9._-]{1,128}$/.test(config.sessionId)\n ? config.sessionId\n : createHash(\"sha256\")\n .update(config.sessionId ?? config.cwd)\n .digest(\"hex\")\n .slice(0, 32);\n return join(globalSkaileDir(), \"codex\", key);\n}\n\n/**\n * Write `<home>/config.toml`, creating the home always. Atomic: a\n * partially written document would fail codex's config load for the whole\n * session.\n *\n * A document with no provider tables says nothing codex does not already\n * know, so nothing is written and a file left by an earlier render is\n * removed — a session that no longer carries a registry must not keep\n * answering to the one it used to have.\n *\n * @returns the absolute path written, or `undefined` when there was nothing\n * to render.\n */\nexport function writeCodexConfigToml(\n home: string,\n document: CodexConfigDocument,\n): string | undefined {\n const path = join(home, \"config.toml\");\n // codex exits when CODEX_HOME names a directory that does not exist, so the\n // home exists before the early return too.\n mkdirSync(home, { recursive: true, mode: 0o700 });\n if (Object.keys(document.model_providers).length === 0) {\n rmSync(path, { force: true });\n return undefined;\n }\n const temporary = join(home, \"config.toml.new\");\n rmSync(temporary, { force: true });\n writeFileSync(temporary, renderCodexConfigToml(document), { mode: 0o600, flag: \"wx\" });\n renameSync(temporary, path);\n return path;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { withFsDeadline, tryWithFsDeadline, walkDir } from './chunk-RHN5MRQO.js';
1
+ import { withFsDeadline, tryWithFsDeadline, walkDir } from './chunk-JMIKGAUA.js';
2
2
  import { createLogger } from './chunk-BOFL7GIF.js';
3
3
  import { parse } from 'yaml';
4
4
  import { readFile, stat } from 'fs/promises';
@@ -329,5 +329,5 @@ function validateFlowVersions(nodes, skillVersions) {
329
329
  }
330
330
 
331
331
  export { buildRequiresPreamble, parseCompactionDirectives, parseSkillFrontmatter, parseSkillRequirements, validateConnectorRequirements, validateFlowVersions, validateRequirements };
332
- //# sourceMappingURL=chunk-IRYKRKVQ.js.map
333
- //# sourceMappingURL=chunk-IRYKRKVQ.js.map
332
+ //# sourceMappingURL=chunk-URCJIV7T.js.map
333
+ //# sourceMappingURL=chunk-URCJIV7T.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../resolver/src/parser.ts","../resolver/src/preamble.ts","../resolver/src/validator.ts","../resolver/src/version.ts"],"names":["parseYaml"],"mappings":"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","file":"chunk-IRYKRKVQ.js","sourcesContent":["import { parse as parseYaml } from \"yaml\";\nimport type { ConnectorRequirement, InputField, SkillRequirements } from \"./types.js\";\n\n/**\n * Extract YAML frontmatter from a SKILL.md string.\n *\n * Frontmatter is delimited by leading `---` fences. Returns the parsed object,\n * or an empty object `{}` if no frontmatter block is found or if the YAML is malformed.\n * Errors are silently swallowed — callers should treat an empty result as \"no requirements\".\n *\n * @param content - Raw SKILL.md file content (full string, including `---` fences)\n * @returns Parsed frontmatter object, or `{}` on absence or parse failure\n *\n * @docLink packages/resolver/api-reference#parseskill-frontmatter\n */\nexport function parseSkillFrontmatter(content: string): Record<string, any> {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return {};\n try {\n return parseYaml(match[1]!) ?? {};\n } catch {\n return {};\n }\n}\n\n/**\n * Parse skill requirements from raw SKILL.md content into a `SkillRequirements` object.\n *\n * Supports two frontmatter formats:\n * 1. **New format** — `metadata.prerequisites` with explicit\n * `files`, `inputs_required`, `inputs_optional`, `reads`, `produces`, and `resources` arrays.\n * 2. **Legacy format** — `metadata.user_inputs.dialog[]` array, automatically promoted to\n * `inputs_required` / `inputs_optional` based on each entry's `required` flag.\n *\n * Returns empty requirements `{ files: [], inputs_required: [], inputs_optional: [], reads: [], produces: [], resources: [] }`\n * when no recognisable prerequisites section is found.\n *\n * @param content - Raw SKILL.md file content (full string, including `---` fences)\n * @returns Structured `SkillRequirements` (never throws)\n *\n * @docLink packages/resolver/api-reference#parseskill-requirements\n */\nexport function parseSkillRequirements(content: string): SkillRequirements {\n const fm = parseSkillFrontmatter(content);\n const meta = fm.metadata ?? {};\n const prerequisites = meta.prerequisites ?? {};\n\n const empty: SkillRequirements = {\n files: [],\n inputs_required: [],\n inputs_optional: [],\n reads: [],\n produces: [],\n resources: [],\n connectors: [],\n };\n\n // New format: metadata.prerequisites\n if (\n prerequisites.files ||\n prerequisites.inputs_required ||\n prerequisites.inputs_optional ||\n prerequisites.reads ||\n prerequisites.produces ||\n prerequisites.resources ||\n prerequisites.connectors\n ) {\n return {\n files: (prerequisites.files ?? []).map((f: any) => ({\n path: f.path,\n gate: f.gate ?? \"hard\",\n description: f.description ?? \"\",\n ...(f.min_entries != null ? { min_entries: f.min_entries } : {}),\n })),\n inputs_required: (prerequisites.inputs_required ?? []).map(normalizeInputField(true)),\n inputs_optional: (prerequisites.inputs_optional ?? []).map(normalizeInputField(false)),\n reads: (prerequisites.reads ?? []).map((r: any) => ({\n path: r.path,\n description: r.description ?? \"\",\n })),\n produces: (prerequisites.produces ?? []).map((p: any) => ({\n path: p.path,\n description: p.description ?? \"\",\n })),\n resources: (prerequisites.resources ?? []).map((r: any) => ({\n id: r.id,\n ...(r.operations ? { operations: r.operations } : {}),\n optional: r.optional ?? false,\n ...(r.description ? { description: r.description } : {}),\n })),\n connectors: parseConnectorRequirements(prerequisites.connectors),\n };\n }\n\n // Legacy format: metadata.user_inputs.dialog[]\n const dialog = meta.user_inputs?.dialog;\n if (Array.isArray(dialog)) {\n const required: InputField[] = [];\n const optional: InputField[] = [];\n for (const d of dialog) {\n const field = normalizeInputField(d.required ?? false)(d);\n if (d.required) required.push(field);\n else optional.push(field);\n }\n return { ...empty, inputs_required: required, inputs_optional: optional, resources: [] };\n }\n\n return empty;\n}\n\n/**\n * Extract compaction directives from a SKILL.md markdown body.\n *\n * Scans the markdown body (not frontmatter) for a `## Compaction Directives` section\n * and returns each bullet point as a trimmed string. Compaction directives are hints\n * the agent uses to summarise context when the conversation history grows long.\n * Returns an empty array when the section is absent.\n *\n * @param content - Raw SKILL.md file content (full string including frontmatter and body)\n * @returns Array of directive strings extracted from the bullet list, or `[]` if none found\n *\n * @docLink packages/resolver/api-reference#parse-compaction-directives\n */\nexport function parseCompactionDirectives(content: string): string[] {\n const headerIdx = content.search(/^## Compaction Directives/m);\n if (headerIdx === -1) return [];\n\n // Header on the last line (no trailing newline) → no body to scan.\n const newlineIdx = content.indexOf(\"\\n\", headerIdx);\n if (newlineIdx === -1) return [];\n const bodyStart = newlineIdx + 1;\n const rest = content.slice(bodyStart);\n const nextSection = rest.search(/^##\\s/m);\n const sectionBody = nextSection === -1 ? rest : rest.slice(0, nextSection);\n\n const bullets: string[] = [];\n for (const line of sectionBody.split(\"\\n\")) {\n const match = line.match(/^\\s*[-*]\\s+(.+)/);\n if (match) bullets.push(match[1].trim());\n }\n return bullets;\n}\n\nfunction normalizeInputField(defaultRequired: boolean) {\n return (d: any): InputField => ({\n // UserInputSchema permits `key` or `id`; `prompt` is the legacy label alias.\n id: d.id ?? d.key,\n label: d.label ?? d.prompt ?? d.id ?? d.key,\n type: d.type ?? \"text\",\n required: d.required ?? defaultRequired,\n ...(d.options ? { options: d.options } : {}),\n ...(d.default != null ? { default: d.default } : {}),\n ...(d.hint ? { hint: d.hint } : {}),\n ...(d.schema ? { schema: d.schema } : {}),\n });\n}\n\nfunction parseConnectorRequirements(raw: unknown): ConnectorRequirement[] {\n if (!Array.isArray(raw)) return [];\n return raw\n .filter((c): c is Record<string, unknown> => typeof c === \"object\" && c !== null)\n .map((c) => ({\n driver: String(c.driver ?? \"\"),\n ...(c.access === \"read-write\"\n ? { access: \"read-write\" as const }\n : { access: \"read-only\" as const }),\n }))\n .filter((c) => c.driver.length > 0);\n}\n","import type { SkillRequirements } from \"./types.js\";\n\n/**\n * Generate a DSL-format preamble from skill requirements.\n *\n * The preamble is prepended to the skill prompt when the skill runs standalone\n * (without an orchestrator), giving the agent an explicit checklist of what to\n * verify before starting work. Each section maps to a requirement category:\n *\n * - `REQUIRES` — file/directory gates (`hard:` or `soft:` prefix)\n * - `INPUT` — user input fields, with a pointer to `input.json` if `skillId` is provided\n * - `READS` — informational read sources (not gated)\n * - `WRITES` — files the skill will produce\n * - `RESOURCE` — runtime resource dependencies\n *\n * Sections with no entries are omitted. Returns an empty string when all\n * requirement arrays are empty.\n *\n * @param requirements - Parsed requirements (output of `parseSkillRequirements`)\n * @param skillId - Optional skill identifier; when provided, the INPUT section includes\n * the canonical `input.json` path so the agent knows where to read collected values\n * @returns Multi-section DSL string, or `\"\"` if there are no requirements to list\n *\n * @example\n * ```ts\n * const preamble = buildRequiresPreamble(requirements, \"cf_overview\");\n * const fullPrompt = preamble ? `${preamble}\\n\\n${skillBody}` : skillBody;\n * ```\n *\n * @docLink packages/resolver/api-reference#build-requires-preamble\n */\nexport function buildRequiresPreamble(requirements: SkillRequirements, skillId?: string): string {\n const sections: string[] = [];\n\n pushSection(sections, buildRequiresSection(requirements));\n pushSection(sections, buildInputSection(requirements, skillId));\n pushSection(sections, buildReadsSection(requirements));\n pushSection(sections, buildWritesSection(requirements));\n pushSection(sections, buildResourceSection(requirements));\n\n return sections.join(\"\\n\\n\");\n}\n\n/** Append a section to the list when it produced output. */\nfunction pushSection(sections: string[], section: string | null): void {\n if (section !== null) sections.push(section);\n}\n\n/** REQUIRES section (file gates). Returns `null` when there are no file gates. */\nfunction buildRequiresSection(requirements: SkillRequirements): string | null {\n if (requirements.files.length === 0) return null;\n const lines = [\"REQUIRES\"];\n for (const f of requirements.files) {\n const prefix = f.gate === \"hard\" ? \"hard\" : \"soft\";\n lines.push(` ${prefix}: ${f.path} — ${f.description}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** INPUT section (user inputs). Returns `null` when there are no inputs. */\nfunction buildInputSection(requirements: SkillRequirements, skillId?: string): string | null {\n const allInputs = [...requirements.inputs_required, ...requirements.inputs_optional];\n if (allInputs.length === 0) return null;\n const lines = [\"INPUT\"];\n if (skillId) {\n lines.push(` Read from: _concept/_grounding/${skillId}/input.json`);\n lines.push(\n ` If input.json is missing, ask the user for the following values and write the file:`,\n );\n }\n for (const input of allInputs) {\n const req = input.required ? \"(required)\" : \"(optional)\";\n const opts = input.options ? ` [${input.options.join(\" | \")}]` : \"\";\n const def = input.default != null ? ` default: ${input.default}` : \"\";\n lines.push(` - ${input.id}: ${input.label} ${req}${opts}${def}`);\n if (input.hint) lines.push(` hint: ${input.hint}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** READS section. Returns `null` when there are no read sources. */\nfunction buildReadsSection(requirements: SkillRequirements): string | null {\n if (requirements.reads.length === 0) return null;\n const lines = [\"READS\"];\n for (const r of requirements.reads) {\n lines.push(` ? ${r.path} — ${r.description}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** WRITES section (produces). Returns `null` when there is nothing produced. */\nfunction buildWritesSection(requirements: SkillRequirements): string | null {\n if (requirements.produces.length === 0) return null;\n const lines = [\"WRITES\"];\n for (const p of requirements.produces) {\n lines.push(` ${p.path} — ${p.description}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** RESOURCE section. Returns `null` when there are no resources. */\nfunction buildResourceSection(requirements: SkillRequirements): string | null {\n if (!requirements.resources || requirements.resources.length === 0) return null;\n const lines = [\"RESOURCE\"];\n for (const r of requirements.resources) {\n const req = r.optional ? \"(optional)\" : \"(required)\";\n const ops = r.operations ? ` ops: [${r.operations.join(\", \")}]` : \"\";\n lines.push(` ${r.id} ${req}${ops}`);\n if (r.description) lines.push(` — ${r.description}`);\n }\n return lines.join(\"\\n\");\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n tryWithFsDeadline,\n walkDir,\n type WalkTruncation,\n withFsDeadline,\n} from \"@skaile/workspaces/core\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\nimport type {\n ConnectorRequirement,\n FileCheck,\n InputCheck,\n NodeOverrides,\n ReadCheck,\n RequirementsReport,\n ResourceCheck,\n SkillInputFile,\n SkillRequirements,\n} from \"./types.js\";\n\nlet validatorLogger: ReturnType<typeof createLogger> | undefined;\n\nfunction log(): ReturnType<typeof createLogger> {\n validatorLogger ??= createLogger({ kind: \"runner\", subkind: \"skill-requirements\" });\n return validatorLogger;\n}\n\n/** Best-effort existence probe. A missing path, an unreadable one, and an\n * unresponsive mount are all \"not usable here\" for a requirement check. */\nasync function pathExists(target: string): Promise<boolean> {\n return tryWithFsDeadline(\n `stat ${target}`,\n async () => {\n await stat(target);\n return true;\n },\n false,\n );\n}\n\n/**\n * Validate skill requirements against the filesystem and collected inputs.\n *\n * File checks resolve paths relative to `projectDir`. Hard-gate files that are absent\n * set `satisfied: false` on the returned report; soft-gate misses are recorded but do not block.\n * Input checks read `_concept/_grounding/{skillId}/input.json`; missing files are treated as\n * no inputs collected. Resource checks are always recorded as `available: true` — actual\n * availability must be confirmed by the runner's `ResourceManager`.\n *\n * **Async and bounded since #454.** `projectDir` reaches this function straight\n * from the agent — `workspace_check_skill_requirements` takes `target_dir` as a\n * tool argument — so it can be `/skaile/workspace`, the rclone FUSE mount. Every\n * probe is now awaited and deadline-bounded, and the `min_entries` count walks\n * through the bounded {@link walkDir}, so a wedged mount or a symlink cycle\n * costs one failed tool call instead of the whole `skaile serve` event loop.\n *\n * @param skillId - Canonical skill identifier, used to locate `input.json`\n * @param requirements - Parsed requirements from SKILL.md (`parseSkillRequirements` output)\n * @param projectDir - Absolute path to the project root directory\n * @param overrides - Optional overrides (SDK only; a v2 flow file cannot carry them); paths in `skip_checks` are treated as present\n * @param producesIndex - Maps file paths to the skill ID that produces them, enabling \"produced by\" hints in the report\n * @returns `RequirementsReport` with per-check results and an overall `satisfied` flag\n *\n * @docLink packages/resolver/api-reference#validate-requirements\n */\nexport async function validateRequirements(\n skillId: string,\n requirements: SkillRequirements,\n projectDir: string,\n overrides?: NodeOverrides,\n producesIndex?: Map<string, string>,\n): Promise<RequirementsReport> {\n const skipSet = new Set(overrides?.skip_checks ?? []);\n\n // Check files. Serial on purpose: `projectDir` may be one network mount, and\n // fanning every probe out concurrently multiplies the queue depth on exactly\n // the resource that is already the bottleneck.\n const files: FileCheck[] = [];\n for (const req of requirements.files) {\n if (skipSet.has(req.path)) {\n files.push({ path: req.path, gate: req.gate, exists: true, description: req.description });\n continue;\n }\n\n const fullPath = path.join(projectDir, req.path);\n const check: FileCheck = {\n path: req.path,\n gate: req.gate,\n exists: false,\n description: req.description,\n producedBy: producesIndex?.get(req.path),\n };\n\n if (req.min_entries != null) {\n const counted = await checkDirectoryMinEntries(fullPath, req.min_entries);\n check.exists = counted.satisfied;\n if (counted.truncated) check.truncated = true;\n } else {\n check.exists = await pathExists(fullPath);\n }\n\n files.push(check);\n }\n\n // Check inputs — look for _concept/_grounding/{skillId}/input.json\n const inputFile = path.join(projectDir, \"_concept\", \"_grounding\", skillId, \"input.json\");\n let collectedValues: Record<string, any> = {};\n try {\n const raw = await withFsDeadline(`readFile ${inputFile}`, () => readFile(inputFile, \"utf-8\"));\n const parsed = JSON.parse(raw) as SkillInputFile;\n collectedValues = parsed.values ?? {};\n } catch {\n // No input file — all inputs are missing\n }\n\n const allInputs = [\n ...requirements.inputs_required.map((f) => ({ field: f, required: true })),\n ...requirements.inputs_optional.map((f) => ({ field: f, required: false })),\n ];\n\n const inputs: InputCheck[] = allInputs.map(({ field, required }) => ({\n id: field.id,\n required,\n present: field.id in collectedValues,\n field,\n }));\n\n // Check reads (informational only)\n const reads: ReadCheck[] = [];\n for (const r of requirements.reads) {\n reads.push({\n path: r.path,\n exists: await pathExists(path.join(projectDir, r.path)),\n description: r.description,\n });\n }\n\n // Check resources (validated at a higher level if a ResourceManager is available;\n // here we just record them in the report with unknown status)\n const resources: ResourceCheck[] = (requirements.resources ?? []).map((r) => ({\n id: r.id,\n available: true, // Actual availability checked by runner with ResourceManager\n missingOps: [],\n optional: r.optional ?? false,\n }));\n\n // Satisfaction: all hard file gates pass AND all required inputs present\n const hardFilesSatisfied = files.filter((f) => f.gate === \"hard\").every((f) => f.exists);\n\n const requiredInputsSatisfied = inputs.filter((i) => i.required).every((i) => i.present);\n\n const requiredResourcesSatisfied = resources.filter((r) => !r.optional).every((r) => r.available);\n\n return {\n skillId,\n satisfied: hardFilesSatisfied && requiredInputsSatisfied && requiredResourcesSatisfied,\n files,\n inputs,\n reads,\n resources,\n };\n}\n\n/**\n * A warning produced by `validateConnectorRequirements` when a skill's declared\n * connector requirement is not satisfied by the connectors in skaile.yaml.\n * Each warning covers either a missing driver or an insufficient access level.\n *\n * @docLink packages/resolver/api-reference#connector-validation-warning\n */\nexport interface ConnectorValidationWarning {\n /** Driver name that triggered the warning. */\n driver: string;\n /** Human-readable explanation of the gap, including a remediation command where applicable. */\n message: string;\n}\n\n/** Minimal structural type accepted by validateConnectorRequirements. Compatible with both\n * ConnectorDeclaration shapes in @skaile/workspaces/core and @skaile/workspaces/connectors. */\ninterface AvailableConnector {\n driver: string;\n access?: \"read-only\" | \"read-write\";\n}\n\n/**\n * Check that all connector requirements declared in a skill's SKILL.md are\n * satisfied by the connectors declared in skaile.yaml.\n *\n * Returns one warning per gap — either a missing driver or an insufficient\n * access level. This is a pre-flight advisory; no runtime enforcement is done.\n *\n * @param requirements - Connector requirements from `parseSkillRequirements().connectors`\n * @param available - Connector declarations from `skaile.yaml` (via `loadConnectorDeclarations`)\n * @returns Array of warnings — one per gap. Empty array when all requirements are satisfied.\n *\n * @docLink packages/resolver/api-reference#validate-connector-requirements\n */\nexport function validateConnectorRequirements(\n requirements: ConnectorRequirement[],\n available: AvailableConnector[],\n): ConnectorValidationWarning[] {\n const warnings: ConnectorValidationWarning[] = [];\n\n for (const req of requirements) {\n const matches = available.filter((a) => a.driver === req.driver);\n\n if (matches.length === 0) {\n warnings.push({\n driver: req.driver,\n message:\n `Skill requires connector driver \"${req.driver}\" but none is declared in skaile.yaml. ` +\n `Run: skaile connector add ${req.driver}`,\n });\n continue;\n }\n\n if (req.access === \"read-write\") {\n const hasReadWrite = matches.some((m) => (m.access ?? \"read-only\") === \"read-write\");\n if (!hasReadWrite) {\n warnings.push({\n driver: req.driver,\n message:\n `Skill requires \"${req.driver}\" with read-write access, but all declared instances ` +\n `are read-only. Update access in skaile.yaml.`,\n });\n }\n }\n }\n\n return warnings;\n}\n\n/**\n * Does `dirPath` hold at least `minEntries` files, counted recursively?\n *\n * `truncated` is set when a walk bound was hit *and* the count still fell\n * short: the number is then a floor, not the truth, so `satisfied: false` is\n * \"we could not prove it\" rather than \"there are not enough files\". Reaching\n * `minEntries` short-circuits the walk, so the common case never pays for the\n * whole tree and a bound hit after that point is irrelevant.\n */\nasync function checkDirectoryMinEntries(\n dirPath: string,\n minEntries: number,\n): Promise<{ satisfied: boolean; truncated: boolean }> {\n const st = await tryWithFsDeadline(`stat ${dirPath}`, () => stat(dirPath), null);\n if (!st?.isDirectory()) return { satisfied: false, truncated: false };\n\n const { count, truncation } = await countFilesRecursive(dirPath, minEntries);\n const satisfied = count >= minEntries;\n if (!satisfied && truncation) {\n log().warn(\"min_entries count truncated — result is a lower bound, not the file count\", {\n dirPath,\n minEntries,\n count,\n ...truncation,\n });\n }\n return { satisfied, truncated: !satisfied && truncation !== undefined };\n}\n\n/**\n * Count files under `dirPath`, stopping at `limit`.\n *\n * Delegates to core's {@link walkDir} rather than recursing here: `dirPath` is\n * agent-supplied and can be a network mount, so the walk needs the deadline per\n * `opendir`, the depth / entry / wall-clock bounds, and the visited-inode cycle\n * guard that walker already owns. The pre-#454 `readdirSync` recursion had none\n * of them and recursed forever on `a/link -> a`.\n *\n * Inheriting `walkDir` also inherits its skip list: `.git` and `node_modules`\n * no longer count toward `min_entries`, which is what a prerequisite like\n * \"at least 3 feature files\" meant in the first place.\n */\nasync function countFilesRecursive(\n dirPath: string,\n limit: number,\n): Promise<{ count: number; truncation?: WalkTruncation }> {\n let count = 0;\n let truncation: WalkTruncation | undefined;\n for await (const _entry of walkDir(dirPath, {\n onTruncate: (info) => {\n truncation ??= info;\n },\n })) {\n count++;\n // Enough is enough — no reason to keep walking a large tree (or a wedged\n // mount) once the requirement is already met.\n if (count >= limit) return { count };\n }\n return { count, truncation };\n}\n","import { satisfies, valid, validRange } from \"semver\";\n\n/**\n * Result of a single flow-node version pin check.\n * Returned in the array produced by `validateFlowVersions()` for every\n * node that declares a `requestedVersion`.\n *\n * @docLink packages/resolver/api-reference#version-check\n */\nexport interface VersionCheck {\n /** Flow node identifier. */\n nodeId: string;\n /** Canonical skill identifier. */\n skillId: string;\n /** Semver range from the flow node (e.g. \"^1.0.0\") */\n requested: string;\n /** Version from the skill's frontmatter */\n actual: string;\n /** Whether `actual` satisfies the `requested` semver range. */\n satisfied: boolean;\n}\n\n/**\n * Minimal descriptor for a flow node that optionally pins a skill version.\n * Passed as input to `validateFlowVersions()`. Nodes without `requestedVersion`\n * are skipped during version checking.\n *\n * @docLink packages/resolver/api-reference#flow-version-node\n */\nexport interface FlowVersionNode {\n /** Flow node identifier. */\n nodeId: string;\n /** Canonical skill identifier referenced by this node. */\n skillId: string;\n /** Optional semver range the node requires (e.g. `\"^1.2.0\"`). Omit to skip version checking. */\n requestedVersion?: string;\n}\n\n/**\n * Validate flow node version pins against discovered skill versions.\n *\n * Only checks nodes that declare a `requestedVersion`. Nodes without a\n * version pin are skipped entirely (no entry is produced for those nodes).\n * A check is marked `satisfied: false` when the range is invalid, the actual\n * version string is not valid semver, or the version does not satisfy the range.\n *\n * @param nodes - Flow nodes to check; only those with `requestedVersion` are evaluated\n * @param skillVersions - Map from skill ID to the semver version string in its frontmatter\n * @returns Array of `VersionCheck` results, one per node that declared a version pin\n *\n * @docLink packages/resolver/api-reference#validate-flow-versions\n */\nexport function validateFlowVersions(\n nodes: FlowVersionNode[],\n skillVersions: Map<string, string>,\n): VersionCheck[] {\n const checks: VersionCheck[] = [];\n\n for (const node of nodes) {\n if (!node.requestedVersion) continue;\n\n const actual = skillVersions.get(node.skillId) ?? \"\";\n const requested = node.requestedVersion;\n\n // Invalid range or missing/invalid actual version → not satisfied\n const rangeValid = validRange(requested) !== null;\n const actualValid = actual !== \"\" && valid(actual) !== null;\n const isSatisfied = rangeValid && actualValid && satisfies(actual, requested);\n\n checks.push({\n nodeId: node.nodeId,\n skillId: node.skillId,\n requested,\n actual,\n satisfied: isSatisfied,\n });\n }\n\n return checks;\n}\n"]}
1
+ {"version":3,"sources":["../resolver/src/parser.ts","../resolver/src/preamble.ts","../resolver/src/validator.ts","../resolver/src/version.ts"],"names":["parseYaml"],"mappings":"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","file":"chunk-URCJIV7T.js","sourcesContent":["import { parse as parseYaml } from \"yaml\";\nimport type { ConnectorRequirement, InputField, SkillRequirements } from \"./types.js\";\n\n/**\n * Extract YAML frontmatter from a SKILL.md string.\n *\n * Frontmatter is delimited by leading `---` fences. Returns the parsed object,\n * or an empty object `{}` if no frontmatter block is found or if the YAML is malformed.\n * Errors are silently swallowed — callers should treat an empty result as \"no requirements\".\n *\n * @param content - Raw SKILL.md file content (full string, including `---` fences)\n * @returns Parsed frontmatter object, or `{}` on absence or parse failure\n *\n * @docLink packages/resolver/api-reference#parseskill-frontmatter\n */\nexport function parseSkillFrontmatter(content: string): Record<string, any> {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return {};\n try {\n return parseYaml(match[1]!) ?? {};\n } catch {\n return {};\n }\n}\n\n/**\n * Parse skill requirements from raw SKILL.md content into a `SkillRequirements` object.\n *\n * Supports two frontmatter formats:\n * 1. **New format** — `metadata.prerequisites` with explicit\n * `files`, `inputs_required`, `inputs_optional`, `reads`, `produces`, and `resources` arrays.\n * 2. **Legacy format** — `metadata.user_inputs.dialog[]` array, automatically promoted to\n * `inputs_required` / `inputs_optional` based on each entry's `required` flag.\n *\n * Returns empty requirements `{ files: [], inputs_required: [], inputs_optional: [], reads: [], produces: [], resources: [] }`\n * when no recognisable prerequisites section is found.\n *\n * @param content - Raw SKILL.md file content (full string, including `---` fences)\n * @returns Structured `SkillRequirements` (never throws)\n *\n * @docLink packages/resolver/api-reference#parseskill-requirements\n */\nexport function parseSkillRequirements(content: string): SkillRequirements {\n const fm = parseSkillFrontmatter(content);\n const meta = fm.metadata ?? {};\n const prerequisites = meta.prerequisites ?? {};\n\n const empty: SkillRequirements = {\n files: [],\n inputs_required: [],\n inputs_optional: [],\n reads: [],\n produces: [],\n resources: [],\n connectors: [],\n };\n\n // New format: metadata.prerequisites\n if (\n prerequisites.files ||\n prerequisites.inputs_required ||\n prerequisites.inputs_optional ||\n prerequisites.reads ||\n prerequisites.produces ||\n prerequisites.resources ||\n prerequisites.connectors\n ) {\n return {\n files: (prerequisites.files ?? []).map((f: any) => ({\n path: f.path,\n gate: f.gate ?? \"hard\",\n description: f.description ?? \"\",\n ...(f.min_entries != null ? { min_entries: f.min_entries } : {}),\n })),\n inputs_required: (prerequisites.inputs_required ?? []).map(normalizeInputField(true)),\n inputs_optional: (prerequisites.inputs_optional ?? []).map(normalizeInputField(false)),\n reads: (prerequisites.reads ?? []).map((r: any) => ({\n path: r.path,\n description: r.description ?? \"\",\n })),\n produces: (prerequisites.produces ?? []).map((p: any) => ({\n path: p.path,\n description: p.description ?? \"\",\n })),\n resources: (prerequisites.resources ?? []).map((r: any) => ({\n id: r.id,\n ...(r.operations ? { operations: r.operations } : {}),\n optional: r.optional ?? false,\n ...(r.description ? { description: r.description } : {}),\n })),\n connectors: parseConnectorRequirements(prerequisites.connectors),\n };\n }\n\n // Legacy format: metadata.user_inputs.dialog[]\n const dialog = meta.user_inputs?.dialog;\n if (Array.isArray(dialog)) {\n const required: InputField[] = [];\n const optional: InputField[] = [];\n for (const d of dialog) {\n const field = normalizeInputField(d.required ?? false)(d);\n if (d.required) required.push(field);\n else optional.push(field);\n }\n return { ...empty, inputs_required: required, inputs_optional: optional, resources: [] };\n }\n\n return empty;\n}\n\n/**\n * Extract compaction directives from a SKILL.md markdown body.\n *\n * Scans the markdown body (not frontmatter) for a `## Compaction Directives` section\n * and returns each bullet point as a trimmed string. Compaction directives are hints\n * the agent uses to summarise context when the conversation history grows long.\n * Returns an empty array when the section is absent.\n *\n * @param content - Raw SKILL.md file content (full string including frontmatter and body)\n * @returns Array of directive strings extracted from the bullet list, or `[]` if none found\n *\n * @docLink packages/resolver/api-reference#parse-compaction-directives\n */\nexport function parseCompactionDirectives(content: string): string[] {\n const headerIdx = content.search(/^## Compaction Directives/m);\n if (headerIdx === -1) return [];\n\n // Header on the last line (no trailing newline) → no body to scan.\n const newlineIdx = content.indexOf(\"\\n\", headerIdx);\n if (newlineIdx === -1) return [];\n const bodyStart = newlineIdx + 1;\n const rest = content.slice(bodyStart);\n const nextSection = rest.search(/^##\\s/m);\n const sectionBody = nextSection === -1 ? rest : rest.slice(0, nextSection);\n\n const bullets: string[] = [];\n for (const line of sectionBody.split(\"\\n\")) {\n const match = line.match(/^\\s*[-*]\\s+(.+)/);\n if (match) bullets.push(match[1].trim());\n }\n return bullets;\n}\n\nfunction normalizeInputField(defaultRequired: boolean) {\n return (d: any): InputField => ({\n // UserInputSchema permits `key` or `id`; `prompt` is the legacy label alias.\n id: d.id ?? d.key,\n label: d.label ?? d.prompt ?? d.id ?? d.key,\n type: d.type ?? \"text\",\n required: d.required ?? defaultRequired,\n ...(d.options ? { options: d.options } : {}),\n ...(d.default != null ? { default: d.default } : {}),\n ...(d.hint ? { hint: d.hint } : {}),\n ...(d.schema ? { schema: d.schema } : {}),\n });\n}\n\nfunction parseConnectorRequirements(raw: unknown): ConnectorRequirement[] {\n if (!Array.isArray(raw)) return [];\n return raw\n .filter((c): c is Record<string, unknown> => typeof c === \"object\" && c !== null)\n .map((c) => ({\n driver: String(c.driver ?? \"\"),\n ...(c.access === \"read-write\"\n ? { access: \"read-write\" as const }\n : { access: \"read-only\" as const }),\n }))\n .filter((c) => c.driver.length > 0);\n}\n","import type { SkillRequirements } from \"./types.js\";\n\n/**\n * Generate a DSL-format preamble from skill requirements.\n *\n * The preamble is prepended to the skill prompt when the skill runs standalone\n * (without an orchestrator), giving the agent an explicit checklist of what to\n * verify before starting work. Each section maps to a requirement category:\n *\n * - `REQUIRES` — file/directory gates (`hard:` or `soft:` prefix)\n * - `INPUT` — user input fields, with a pointer to `input.json` if `skillId` is provided\n * - `READS` — informational read sources (not gated)\n * - `WRITES` — files the skill will produce\n * - `RESOURCE` — runtime resource dependencies\n *\n * Sections with no entries are omitted. Returns an empty string when all\n * requirement arrays are empty.\n *\n * @param requirements - Parsed requirements (output of `parseSkillRequirements`)\n * @param skillId - Optional skill identifier; when provided, the INPUT section includes\n * the canonical `input.json` path so the agent knows where to read collected values\n * @returns Multi-section DSL string, or `\"\"` if there are no requirements to list\n *\n * @example\n * ```ts\n * const preamble = buildRequiresPreamble(requirements, \"cf_overview\");\n * const fullPrompt = preamble ? `${preamble}\\n\\n${skillBody}` : skillBody;\n * ```\n *\n * @docLink packages/resolver/api-reference#build-requires-preamble\n */\nexport function buildRequiresPreamble(requirements: SkillRequirements, skillId?: string): string {\n const sections: string[] = [];\n\n pushSection(sections, buildRequiresSection(requirements));\n pushSection(sections, buildInputSection(requirements, skillId));\n pushSection(sections, buildReadsSection(requirements));\n pushSection(sections, buildWritesSection(requirements));\n pushSection(sections, buildResourceSection(requirements));\n\n return sections.join(\"\\n\\n\");\n}\n\n/** Append a section to the list when it produced output. */\nfunction pushSection(sections: string[], section: string | null): void {\n if (section !== null) sections.push(section);\n}\n\n/** REQUIRES section (file gates). Returns `null` when there are no file gates. */\nfunction buildRequiresSection(requirements: SkillRequirements): string | null {\n if (requirements.files.length === 0) return null;\n const lines = [\"REQUIRES\"];\n for (const f of requirements.files) {\n const prefix = f.gate === \"hard\" ? \"hard\" : \"soft\";\n lines.push(` ${prefix}: ${f.path} — ${f.description}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** INPUT section (user inputs). Returns `null` when there are no inputs. */\nfunction buildInputSection(requirements: SkillRequirements, skillId?: string): string | null {\n const allInputs = [...requirements.inputs_required, ...requirements.inputs_optional];\n if (allInputs.length === 0) return null;\n const lines = [\"INPUT\"];\n if (skillId) {\n lines.push(` Read from: _concept/_grounding/${skillId}/input.json`);\n lines.push(\n ` If input.json is missing, ask the user for the following values and write the file:`,\n );\n }\n for (const input of allInputs) {\n const req = input.required ? \"(required)\" : \"(optional)\";\n const opts = input.options ? ` [${input.options.join(\" | \")}]` : \"\";\n const def = input.default != null ? ` default: ${input.default}` : \"\";\n lines.push(` - ${input.id}: ${input.label} ${req}${opts}${def}`);\n if (input.hint) lines.push(` hint: ${input.hint}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** READS section. Returns `null` when there are no read sources. */\nfunction buildReadsSection(requirements: SkillRequirements): string | null {\n if (requirements.reads.length === 0) return null;\n const lines = [\"READS\"];\n for (const r of requirements.reads) {\n lines.push(` ? ${r.path} — ${r.description}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** WRITES section (produces). Returns `null` when there is nothing produced. */\nfunction buildWritesSection(requirements: SkillRequirements): string | null {\n if (requirements.produces.length === 0) return null;\n const lines = [\"WRITES\"];\n for (const p of requirements.produces) {\n lines.push(` ${p.path} — ${p.description}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** RESOURCE section. Returns `null` when there are no resources. */\nfunction buildResourceSection(requirements: SkillRequirements): string | null {\n if (!requirements.resources || requirements.resources.length === 0) return null;\n const lines = [\"RESOURCE\"];\n for (const r of requirements.resources) {\n const req = r.optional ? \"(optional)\" : \"(required)\";\n const ops = r.operations ? ` ops: [${r.operations.join(\", \")}]` : \"\";\n lines.push(` ${r.id} ${req}${ops}`);\n if (r.description) lines.push(` — ${r.description}`);\n }\n return lines.join(\"\\n\");\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n tryWithFsDeadline,\n walkDir,\n type WalkTruncation,\n withFsDeadline,\n} from \"@skaile/workspaces/core\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\nimport type {\n ConnectorRequirement,\n FileCheck,\n InputCheck,\n NodeOverrides,\n ReadCheck,\n RequirementsReport,\n ResourceCheck,\n SkillInputFile,\n SkillRequirements,\n} from \"./types.js\";\n\nlet validatorLogger: ReturnType<typeof createLogger> | undefined;\n\nfunction log(): ReturnType<typeof createLogger> {\n validatorLogger ??= createLogger({ kind: \"runner\", subkind: \"skill-requirements\" });\n return validatorLogger;\n}\n\n/** Best-effort existence probe. A missing path, an unreadable one, and an\n * unresponsive mount are all \"not usable here\" for a requirement check. */\nasync function pathExists(target: string): Promise<boolean> {\n return tryWithFsDeadline(\n `stat ${target}`,\n async () => {\n await stat(target);\n return true;\n },\n false,\n );\n}\n\n/**\n * Validate skill requirements against the filesystem and collected inputs.\n *\n * File checks resolve paths relative to `projectDir`. Hard-gate files that are absent\n * set `satisfied: false` on the returned report; soft-gate misses are recorded but do not block.\n * Input checks read `_concept/_grounding/{skillId}/input.json`; missing files are treated as\n * no inputs collected. Resource checks are always recorded as `available: true` — actual\n * availability must be confirmed by the runner's `ResourceManager`.\n *\n * **Async and bounded since #454.** `projectDir` reaches this function straight\n * from the agent — `workspace_check_skill_requirements` takes `target_dir` as a\n * tool argument — so it can be `/skaile/workspace`, the rclone FUSE mount. Every\n * probe is now awaited and deadline-bounded, and the `min_entries` count walks\n * through the bounded {@link walkDir}, so a wedged mount or a symlink cycle\n * costs one failed tool call instead of the whole `skaile serve` event loop.\n *\n * @param skillId - Canonical skill identifier, used to locate `input.json`\n * @param requirements - Parsed requirements from SKILL.md (`parseSkillRequirements` output)\n * @param projectDir - Absolute path to the project root directory\n * @param overrides - Optional overrides (SDK only; a v2 flow file cannot carry them); paths in `skip_checks` are treated as present\n * @param producesIndex - Maps file paths to the skill ID that produces them, enabling \"produced by\" hints in the report\n * @returns `RequirementsReport` with per-check results and an overall `satisfied` flag\n *\n * @docLink packages/resolver/api-reference#validate-requirements\n */\nexport async function validateRequirements(\n skillId: string,\n requirements: SkillRequirements,\n projectDir: string,\n overrides?: NodeOverrides,\n producesIndex?: Map<string, string>,\n): Promise<RequirementsReport> {\n const skipSet = new Set(overrides?.skip_checks ?? []);\n\n // Check files. Serial on purpose: `projectDir` may be one network mount, and\n // fanning every probe out concurrently multiplies the queue depth on exactly\n // the resource that is already the bottleneck.\n const files: FileCheck[] = [];\n for (const req of requirements.files) {\n if (skipSet.has(req.path)) {\n files.push({ path: req.path, gate: req.gate, exists: true, description: req.description });\n continue;\n }\n\n const fullPath = path.join(projectDir, req.path);\n const check: FileCheck = {\n path: req.path,\n gate: req.gate,\n exists: false,\n description: req.description,\n producedBy: producesIndex?.get(req.path),\n };\n\n if (req.min_entries != null) {\n const counted = await checkDirectoryMinEntries(fullPath, req.min_entries);\n check.exists = counted.satisfied;\n if (counted.truncated) check.truncated = true;\n } else {\n check.exists = await pathExists(fullPath);\n }\n\n files.push(check);\n }\n\n // Check inputs — look for _concept/_grounding/{skillId}/input.json\n const inputFile = path.join(projectDir, \"_concept\", \"_grounding\", skillId, \"input.json\");\n let collectedValues: Record<string, any> = {};\n try {\n const raw = await withFsDeadline(`readFile ${inputFile}`, () => readFile(inputFile, \"utf-8\"));\n const parsed = JSON.parse(raw) as SkillInputFile;\n collectedValues = parsed.values ?? {};\n } catch {\n // No input file — all inputs are missing\n }\n\n const allInputs = [\n ...requirements.inputs_required.map((f) => ({ field: f, required: true })),\n ...requirements.inputs_optional.map((f) => ({ field: f, required: false })),\n ];\n\n const inputs: InputCheck[] = allInputs.map(({ field, required }) => ({\n id: field.id,\n required,\n present: field.id in collectedValues,\n field,\n }));\n\n // Check reads (informational only)\n const reads: ReadCheck[] = [];\n for (const r of requirements.reads) {\n reads.push({\n path: r.path,\n exists: await pathExists(path.join(projectDir, r.path)),\n description: r.description,\n });\n }\n\n // Check resources (validated at a higher level if a ResourceManager is available;\n // here we just record them in the report with unknown status)\n const resources: ResourceCheck[] = (requirements.resources ?? []).map((r) => ({\n id: r.id,\n available: true, // Actual availability checked by runner with ResourceManager\n missingOps: [],\n optional: r.optional ?? false,\n }));\n\n // Satisfaction: all hard file gates pass AND all required inputs present\n const hardFilesSatisfied = files.filter((f) => f.gate === \"hard\").every((f) => f.exists);\n\n const requiredInputsSatisfied = inputs.filter((i) => i.required).every((i) => i.present);\n\n const requiredResourcesSatisfied = resources.filter((r) => !r.optional).every((r) => r.available);\n\n return {\n skillId,\n satisfied: hardFilesSatisfied && requiredInputsSatisfied && requiredResourcesSatisfied,\n files,\n inputs,\n reads,\n resources,\n };\n}\n\n/**\n * A warning produced by `validateConnectorRequirements` when a skill's declared\n * connector requirement is not satisfied by the connectors in skaile.yaml.\n * Each warning covers either a missing driver or an insufficient access level.\n *\n * @docLink packages/resolver/api-reference#connector-validation-warning\n */\nexport interface ConnectorValidationWarning {\n /** Driver name that triggered the warning. */\n driver: string;\n /** Human-readable explanation of the gap, including a remediation command where applicable. */\n message: string;\n}\n\n/** Minimal structural type accepted by validateConnectorRequirements. Compatible with both\n * ConnectorDeclaration shapes in @skaile/workspaces/core and @skaile/workspaces/connectors. */\ninterface AvailableConnector {\n driver: string;\n access?: \"read-only\" | \"read-write\";\n}\n\n/**\n * Check that all connector requirements declared in a skill's SKILL.md are\n * satisfied by the connectors declared in skaile.yaml.\n *\n * Returns one warning per gap — either a missing driver or an insufficient\n * access level. This is a pre-flight advisory; no runtime enforcement is done.\n *\n * @param requirements - Connector requirements from `parseSkillRequirements().connectors`\n * @param available - Connector declarations from `skaile.yaml` (via `loadConnectorDeclarations`)\n * @returns Array of warnings — one per gap. Empty array when all requirements are satisfied.\n *\n * @docLink packages/resolver/api-reference#validate-connector-requirements\n */\nexport function validateConnectorRequirements(\n requirements: ConnectorRequirement[],\n available: AvailableConnector[],\n): ConnectorValidationWarning[] {\n const warnings: ConnectorValidationWarning[] = [];\n\n for (const req of requirements) {\n const matches = available.filter((a) => a.driver === req.driver);\n\n if (matches.length === 0) {\n warnings.push({\n driver: req.driver,\n message:\n `Skill requires connector driver \"${req.driver}\" but none is declared in skaile.yaml. ` +\n `Run: skaile connector add ${req.driver}`,\n });\n continue;\n }\n\n if (req.access === \"read-write\") {\n const hasReadWrite = matches.some((m) => (m.access ?? \"read-only\") === \"read-write\");\n if (!hasReadWrite) {\n warnings.push({\n driver: req.driver,\n message:\n `Skill requires \"${req.driver}\" with read-write access, but all declared instances ` +\n `are read-only. Update access in skaile.yaml.`,\n });\n }\n }\n }\n\n return warnings;\n}\n\n/**\n * Does `dirPath` hold at least `minEntries` files, counted recursively?\n *\n * `truncated` is set when a walk bound was hit *and* the count still fell\n * short: the number is then a floor, not the truth, so `satisfied: false` is\n * \"we could not prove it\" rather than \"there are not enough files\". Reaching\n * `minEntries` short-circuits the walk, so the common case never pays for the\n * whole tree and a bound hit after that point is irrelevant.\n */\nasync function checkDirectoryMinEntries(\n dirPath: string,\n minEntries: number,\n): Promise<{ satisfied: boolean; truncated: boolean }> {\n const st = await tryWithFsDeadline(`stat ${dirPath}`, () => stat(dirPath), null);\n if (!st?.isDirectory()) return { satisfied: false, truncated: false };\n\n const { count, truncation } = await countFilesRecursive(dirPath, minEntries);\n const satisfied = count >= minEntries;\n if (!satisfied && truncation) {\n log().warn(\"min_entries count truncated — result is a lower bound, not the file count\", {\n dirPath,\n minEntries,\n count,\n ...truncation,\n });\n }\n return { satisfied, truncated: !satisfied && truncation !== undefined };\n}\n\n/**\n * Count files under `dirPath`, stopping at `limit`.\n *\n * Delegates to core's {@link walkDir} rather than recursing here: `dirPath` is\n * agent-supplied and can be a network mount, so the walk needs the deadline per\n * `opendir`, the depth / entry / wall-clock bounds, and the visited-inode cycle\n * guard that walker already owns. The pre-#454 `readdirSync` recursion had none\n * of them and recursed forever on `a/link -> a`.\n *\n * Inheriting `walkDir` also inherits its skip list: `.git` and `node_modules`\n * no longer count toward `min_entries`, which is what a prerequisite like\n * \"at least 3 feature files\" meant in the first place.\n */\nasync function countFilesRecursive(\n dirPath: string,\n limit: number,\n): Promise<{ count: number; truncation?: WalkTruncation }> {\n let count = 0;\n let truncation: WalkTruncation | undefined;\n for await (const _entry of walkDir(dirPath, {\n onTruncate: (info) => {\n truncation ??= info;\n },\n })) {\n count++;\n // Enough is enough — no reason to keep walking a large tree (or a wedged\n // mount) once the requirement is already met.\n if (count >= limit) return { count };\n }\n return { count, truncation };\n}\n","import { satisfies, valid, validRange } from \"semver\";\n\n/**\n * Result of a single flow-node version pin check.\n * Returned in the array produced by `validateFlowVersions()` for every\n * node that declares a `requestedVersion`.\n *\n * @docLink packages/resolver/api-reference#version-check\n */\nexport interface VersionCheck {\n /** Flow node identifier. */\n nodeId: string;\n /** Canonical skill identifier. */\n skillId: string;\n /** Semver range from the flow node (e.g. \"^1.0.0\") */\n requested: string;\n /** Version from the skill's frontmatter */\n actual: string;\n /** Whether `actual` satisfies the `requested` semver range. */\n satisfied: boolean;\n}\n\n/**\n * Minimal descriptor for a flow node that optionally pins a skill version.\n * Passed as input to `validateFlowVersions()`. Nodes without `requestedVersion`\n * are skipped during version checking.\n *\n * @docLink packages/resolver/api-reference#flow-version-node\n */\nexport interface FlowVersionNode {\n /** Flow node identifier. */\n nodeId: string;\n /** Canonical skill identifier referenced by this node. */\n skillId: string;\n /** Optional semver range the node requires (e.g. `\"^1.2.0\"`). Omit to skip version checking. */\n requestedVersion?: string;\n}\n\n/**\n * Validate flow node version pins against discovered skill versions.\n *\n * Only checks nodes that declare a `requestedVersion`. Nodes without a\n * version pin are skipped entirely (no entry is produced for those nodes).\n * A check is marked `satisfied: false` when the range is invalid, the actual\n * version string is not valid semver, or the version does not satisfy the range.\n *\n * @param nodes - Flow nodes to check; only those with `requestedVersion` are evaluated\n * @param skillVersions - Map from skill ID to the semver version string in its frontmatter\n * @returns Array of `VersionCheck` results, one per node that declared a version pin\n *\n * @docLink packages/resolver/api-reference#validate-flow-versions\n */\nexport function validateFlowVersions(\n nodes: FlowVersionNode[],\n skillVersions: Map<string, string>,\n): VersionCheck[] {\n const checks: VersionCheck[] = [];\n\n for (const node of nodes) {\n if (!node.requestedVersion) continue;\n\n const actual = skillVersions.get(node.skillId) ?? \"\";\n const requested = node.requestedVersion;\n\n // Invalid range or missing/invalid actual version → not satisfied\n const rangeValid = validRange(requested) !== null;\n const actualValid = actual !== \"\" && valid(actual) !== null;\n const isSatisfied = rangeValid && actualValid && satisfies(actual, requested);\n\n checks.push({\n nodeId: node.nodeId,\n skillId: node.skillId,\n requested,\n actual,\n satisfied: isSatisfied,\n });\n }\n\n return checks;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { parseCredentialRef } from './chunk-LSI2IVFT.js';
1
+ import { parseCredentialRef } from './chunk-RXGPFAMN.js';
2
2
  import { spawn, spawnSync } from 'child_process';
3
3
  import { constants } from 'os';
4
4
  import { Readable } from 'stream';
@@ -138,5 +138,5 @@ function resolveCredential(entry, options = {}) {
138
138
  }
139
139
 
140
140
  export { __resetCredentialCommandCache, portableSpawn, portableSpawnSync, resolveCredential };
141
- //# sourceMappingURL=chunk-ADPM6AYF.js.map
142
- //# sourceMappingURL=chunk-ADPM6AYF.js.map
141
+ //# sourceMappingURL=chunk-VSX2G7LA.js.map
142
+ //# sourceMappingURL=chunk-VSX2G7LA.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../core/src/subprocess.ts","../core/src/provider-registry-credentials.ts"],"names":[],"mappings":"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","file":"chunk-ADPM6AYF.js","sourcesContent":["/**\n * Runtime-portable subprocess spawning.\n *\n * `node:child_process` is implemented by both Node and Bun, so it is the\n * portable choice — no runtime detection needed (unlike embedded SQLite,\n * which has no shared API; see `logging/sinks/sqlite-runtime.ts`).\n *\n * These helpers wrap `node:child_process` to present a `Bun.Subprocess`-shaped\n * result — web `ReadableStream` stdio plus an `exited` promise — so call sites\n * migrated off `Bun.spawn` keep their stream-reading code unchanged.\n */\nimport { spawn, spawnSync } from \"node:child_process\";\nimport { constants } from \"node:os\";\nimport { Readable } from \"node:stream\";\n\nexport interface PortableSpawnOptions {\n cwd?: string;\n env?: Record<string, string | undefined>;\n detached?: boolean;\n}\n\n/**\n * Options for {@link portableSpawnSync}.\n *\n * `timeoutMs` is **required**, and deliberately so. A synchronous spawn blocks\n * the single-threaded event loop until the child exits; if the child stalls —\n * classically on a wedged network/FUSE mount reachable from `cwd` — the whole\n * process stops serving. An unbounded `spawnSync` is therefore not a call that\n * should be expressible, so the deadline is part of the type rather than an\n * optional extra a caller can forget.\n */\nexport interface PortableSpawnSyncOptions extends PortableSpawnOptions {\n /** Wall-clock limit for the child, in milliseconds. Must be > 0. */\n timeoutMs: number;\n}\n\n/** A spawned process with stdout/stderr piped. Mirrors the shape of `Bun.Subprocess`. */\nexport interface PortableSubprocess {\n /** OS process id, or -1 if the process failed to spawn. */\n readonly pid: number;\n readonly stdout: ReadableStream<Uint8Array>;\n readonly stderr: ReadableStream<Uint8Array>;\n /**\n * Resolves with the exit code once the process closes. Signal termination\n * uses the conventional `128 + signal number`; spawn errors or unknown\n * signals use `-1`.\n */\n readonly exited: Promise<number>;\n kill(signal?: number | NodeJS.Signals): void;\n}\n\nexport interface PortableSpawnSyncResult {\n /** Exit code; -1 when the process did not exit cleanly. */\n exitCode: number;\n stdout: string;\n stderr: string;\n /**\n * `true` when the child was killed for exceeding\n * {@link PortableSpawnSyncOptions.timeoutMs}. Lets a caller tell \"the command\n * failed\" apart from \"the command never finished\", which are different\n * operational events.\n */\n timedOut: boolean;\n}\n\n/**\n * Spawn a subprocess with stdout/stderr piped. Works under Node and Bun.\n *\n * @param cmd - Command and arguments, e.g. `[\"docker\", \"ps\"]`.\n */\nexport function portableSpawn(cmd: string[], opts: PortableSpawnOptions = {}): PortableSubprocess {\n const [bin, ...args] = cmd;\n if (!bin) throw new Error(\"portableSpawn: empty command\");\n const child = spawn(bin, args, {\n cwd: opts.cwd,\n env: opts.env ?? process.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: opts.detached,\n });\n const exited = new Promise<number>((resolve) => {\n child.on(\"close\", (code, signal) => {\n if (code !== null) {\n resolve(code);\n return;\n }\n const signalNumber = signal ? constants.signals[signal] : undefined;\n resolve(signalNumber === undefined ? -1 : 128 + signalNumber);\n });\n child.on(\"error\", () => resolve(-1));\n });\n return {\n pid: child.pid ?? -1,\n stdout: Readable.toWeb(child.stdout as Readable) as unknown as ReadableStream<Uint8Array>,\n stderr: Readable.toWeb(child.stderr as Readable) as unknown as ReadableStream<Uint8Array>,\n exited,\n kill: (signal) => {\n if (opts.detached && child.pid) {\n try {\n process.kill(-child.pid, signal);\n return;\n } catch {\n /* fall back to killing the direct child */\n }\n }\n child.kill(signal);\n },\n };\n}\n\n/**\n * Run a subprocess to completion synchronously, capturing stdout/stderr as\n * UTF-8 strings. Works under Node and Bun.\n *\n * Blocks the event loop for the child's whole lifetime, so `opts.timeoutMs`\n * is required — see {@link PortableSpawnSyncOptions}. Prefer\n * {@link portableSpawn} wherever an async call is possible; only reach for this\n * when the caller genuinely cannot await (process teardown, CLI entry points).\n *\n * The child is killed with `SIGKILL` rather than `SIGTERM` on expiry: a process\n * blocked in an uninterruptible kernel wait (`D` state, e.g. a dead FUSE\n * connection) never runs a `SIGTERM` handler, so a graceful signal would leave\n * the deadline unenforced.\n *\n * @param cmd - Command and arguments, e.g. `[\"docker\", \"info\"]`.\n * @param opts - Spawn options; `timeoutMs` is mandatory.\n */\nexport function portableSpawnSync(\n cmd: string[],\n opts: PortableSpawnSyncOptions,\n): PortableSpawnSyncResult {\n const [bin, ...args] = cmd;\n if (!bin) throw new Error(\"portableSpawnSync: empty command\");\n if (!(opts.timeoutMs > 0)) {\n throw new Error(`portableSpawnSync: timeoutMs must be > 0 (got ${opts.timeoutMs})`);\n }\n const result = spawnSync(bin, args, {\n cwd: opts.cwd,\n env: opts.env ?? process.env,\n encoding: \"utf8\",\n timeout: opts.timeoutMs,\n killSignal: \"SIGKILL\",\n });\n // Node reports the expiry as `error.code === \"ETIMEDOUT\"`; Bun surfaces the\n // same case as a SIGKILL with no status, so accept either signal.\n const timedOut =\n (result.error as NodeJS.ErrnoException | undefined)?.code === \"ETIMEDOUT\" ||\n (result.status === null && result.signal === \"SIGKILL\");\n let stderr = result.stderr ?? \"\";\n if (timedOut) {\n // Surface the reason on the channel every caller already inspects — an\n // exitCode of -1 alone reads as \"command failed\" and hides the stall.\n stderr += `${stderr.endsWith(\"\\n\") || stderr === \"\" ? \"\" : \"\\n\"}${bin}: timed out after ${opts.timeoutMs}ms\\n`;\n }\n return {\n exitCode: result.status ?? -1,\n stdout: result.stdout ?? \"\",\n stderr,\n timedOut,\n };\n}\n","/**\n * Credential resolution for registry entries (§1.4).\n *\n * Split from `provider-registry.ts` deliberately: resolving a `cmd:` reference\n * spawns a process and `env:` reads `process.env`, so this module depends on\n * Node. The schema module must stay dependency-free because browser bundles\n * (`@skaile/workspace-bridge-react`) reach the registry *types* through\n * `@skaile/workspaces/types`, and a `node:child_process` import in that graph\n * breaks their typecheck.\n *\n * @see PROVIDER-CONFIG-PLAN.md §1.4\n */\n\nimport type { AIProviderCredentialKind, AIProviderEntry } from \"./provider-registry.js\";\nimport { parseCredentialRef } from \"./provider-registry.js\";\nimport { portableSpawnSync } from \"./subprocess.js\";\n\n/** Options for {@link resolveCredential}. */\nexport interface ResolveCredentialOptions {\n /** Environment `env:` refs read from; defaults to `process.env`. */\n env?: Record<string, string | undefined>;\n /**\n * Control-plane secrets, keyed by config id (a `platform:<configId>` ref) —\n * the `secrets` map that rides alongside `session_init`.\n */\n secrets?: Record<string, string>;\n /** Run `cmd:` references. Default `true`; the platform sets it `false`. */\n allowCommand?: boolean;\n}\n\n/** Outcome of {@link resolveCredential}. Never carries the secret in `error`. */\nexport interface ResolvedAIProviderCredential {\n kind: AIProviderCredentialKind;\n /** The secret, when one was produced. */\n value?: string;\n /** Where the value came from; `ambient` means the transport's own chain signs. */\n source: \"env\" | \"cmd\" | \"platform\" | \"keyring\" | \"ambient\" | \"none\";\n /** Why there is no value. Secret-free. */\n error?: string;\n}\n\n/** `cmd:` results are cached per process, matching omp's `!cmd` semantics. */\nconst commandCache = new Map<string, string>();\n\n/** Test seam — drops the memoized `cmd:` results. */\nexport function __resetCredentialCommandCache(): void {\n commandCache.clear();\n}\n\nconst COMMAND_TIMEOUT_MS = 10_000;\n\n/**\n * Resolve an entry's credential to a value (§1.4).\n *\n * `env:` reads the environment, `cmd:` runs a shell (10 s, trimmed stdout,\n * cached per process), `platform:` reads the injected secrets map. `keyring:`\n * is a reserved grammar slot: it validates but does not resolve, and says so.\n *\n * `sigv4`, `google_adc` and `azure_entra` entries without a ref resolve to\n * `source: \"ambient\"` with no value — the AWS/Google/Azure SDK chain signs the\n * request, there is nothing for this function to hand over.\n */\nexport function resolveCredential(\n entry: AIProviderEntry,\n options: ResolveCredentialOptions = {},\n): ResolvedAIProviderCredential {\n const credential = entry.credential;\n if (!credential || credential.kind === \"none\") {\n return { kind: credential?.kind ?? \"none\", source: \"none\" };\n }\n const kind = credential.kind;\n if (!credential.ref) {\n if (kind === \"sigv4\" || kind === \"google_adc\" || kind === \"azure_entra\") {\n return { kind, source: \"ambient\" };\n }\n return { kind, source: \"none\", error: `credential.ref is missing for kind '${kind}'` };\n }\n\n const parsed = parseCredentialRef(credential.ref);\n if (!parsed) {\n return { kind, source: \"none\", error: \"credential.ref is not a valid reference\" };\n }\n\n switch (parsed.form) {\n case \"env\": {\n const env = options.env ?? process.env;\n const value = env[parsed.name];\n if (!value) {\n return { kind, source: \"env\", error: `environment variable ${parsed.name} is not set` };\n }\n return { kind, source: \"env\", value };\n }\n case \"platform\": {\n const value = options.secrets?.[parsed.configId];\n if (!value) {\n return {\n kind,\n source: \"platform\",\n error: `no control-plane secret was injected for '${parsed.configId}'`,\n };\n }\n return { kind, source: \"platform\", value };\n }\n case \"cmd\": {\n if (options.allowCommand === false) {\n return { kind, source: \"cmd\", error: \"cmd: references are not permitted in this context\" };\n }\n const cached = commandCache.get(parsed.command);\n if (cached !== undefined) return { kind, source: \"cmd\", value: cached };\n const argv =\n process.platform === \"win32\"\n ? [\"cmd\", \"/c\", parsed.command]\n : [\"/bin/sh\", \"-c\", parsed.command];\n const result = portableSpawnSync(argv, { timeoutMs: COMMAND_TIMEOUT_MS });\n if (result.timedOut) {\n return { kind, source: \"cmd\", error: `credential command timed out after 10s` };\n }\n if (result.exitCode !== 0) {\n return { kind, source: \"cmd\", error: `credential command exited ${result.exitCode}` };\n }\n const value = result.stdout.trim();\n if (!value) return { kind, source: \"cmd\", error: \"credential command produced no output\" };\n commandCache.set(parsed.command, value);\n return { kind, source: \"cmd\", value };\n }\n case \"keyring\":\n return {\n kind,\n source: \"keyring\",\n error:\n `keyring references are a reserved grammar slot — ` +\n `no OS keychain backend ships yet (use env: or cmd:)`,\n };\n }\n}\n"]}
1
+ {"version":3,"sources":["../core/src/subprocess.ts","../core/src/provider-registry-credentials.ts"],"names":[],"mappings":"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","file":"chunk-VSX2G7LA.js","sourcesContent":["/**\n * Runtime-portable subprocess spawning.\n *\n * `node:child_process` is implemented by both Node and Bun, so it is the\n * portable choice — no runtime detection needed (unlike embedded SQLite,\n * which has no shared API; see `logging/sinks/sqlite-runtime.ts`).\n *\n * These helpers wrap `node:child_process` to present a `Bun.Subprocess`-shaped\n * result — web `ReadableStream` stdio plus an `exited` promise — so call sites\n * migrated off `Bun.spawn` keep their stream-reading code unchanged.\n */\nimport { spawn, spawnSync } from \"node:child_process\";\nimport { constants } from \"node:os\";\nimport { Readable } from \"node:stream\";\n\nexport interface PortableSpawnOptions {\n cwd?: string;\n env?: Record<string, string | undefined>;\n detached?: boolean;\n}\n\n/**\n * Options for {@link portableSpawnSync}.\n *\n * `timeoutMs` is **required**, and deliberately so. A synchronous spawn blocks\n * the single-threaded event loop until the child exits; if the child stalls —\n * classically on a wedged network/FUSE mount reachable from `cwd` — the whole\n * process stops serving. An unbounded `spawnSync` is therefore not a call that\n * should be expressible, so the deadline is part of the type rather than an\n * optional extra a caller can forget.\n */\nexport interface PortableSpawnSyncOptions extends PortableSpawnOptions {\n /** Wall-clock limit for the child, in milliseconds. Must be > 0. */\n timeoutMs: number;\n}\n\n/** A spawned process with stdout/stderr piped. Mirrors the shape of `Bun.Subprocess`. */\nexport interface PortableSubprocess {\n /** OS process id, or -1 if the process failed to spawn. */\n readonly pid: number;\n readonly stdout: ReadableStream<Uint8Array>;\n readonly stderr: ReadableStream<Uint8Array>;\n /**\n * Resolves with the exit code once the process closes. Signal termination\n * uses the conventional `128 + signal number`; spawn errors or unknown\n * signals use `-1`.\n */\n readonly exited: Promise<number>;\n kill(signal?: number | NodeJS.Signals): void;\n}\n\nexport interface PortableSpawnSyncResult {\n /** Exit code; -1 when the process did not exit cleanly. */\n exitCode: number;\n stdout: string;\n stderr: string;\n /**\n * `true` when the child was killed for exceeding\n * {@link PortableSpawnSyncOptions.timeoutMs}. Lets a caller tell \"the command\n * failed\" apart from \"the command never finished\", which are different\n * operational events.\n */\n timedOut: boolean;\n}\n\n/**\n * Spawn a subprocess with stdout/stderr piped. Works under Node and Bun.\n *\n * @param cmd - Command and arguments, e.g. `[\"docker\", \"ps\"]`.\n */\nexport function portableSpawn(cmd: string[], opts: PortableSpawnOptions = {}): PortableSubprocess {\n const [bin, ...args] = cmd;\n if (!bin) throw new Error(\"portableSpawn: empty command\");\n const child = spawn(bin, args, {\n cwd: opts.cwd,\n env: opts.env ?? process.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: opts.detached,\n });\n const exited = new Promise<number>((resolve) => {\n child.on(\"close\", (code, signal) => {\n if (code !== null) {\n resolve(code);\n return;\n }\n const signalNumber = signal ? constants.signals[signal] : undefined;\n resolve(signalNumber === undefined ? -1 : 128 + signalNumber);\n });\n child.on(\"error\", () => resolve(-1));\n });\n return {\n pid: child.pid ?? -1,\n stdout: Readable.toWeb(child.stdout as Readable) as unknown as ReadableStream<Uint8Array>,\n stderr: Readable.toWeb(child.stderr as Readable) as unknown as ReadableStream<Uint8Array>,\n exited,\n kill: (signal) => {\n if (opts.detached && child.pid) {\n try {\n process.kill(-child.pid, signal);\n return;\n } catch {\n /* fall back to killing the direct child */\n }\n }\n child.kill(signal);\n },\n };\n}\n\n/**\n * Run a subprocess to completion synchronously, capturing stdout/stderr as\n * UTF-8 strings. Works under Node and Bun.\n *\n * Blocks the event loop for the child's whole lifetime, so `opts.timeoutMs`\n * is required — see {@link PortableSpawnSyncOptions}. Prefer\n * {@link portableSpawn} wherever an async call is possible; only reach for this\n * when the caller genuinely cannot await (process teardown, CLI entry points).\n *\n * The child is killed with `SIGKILL` rather than `SIGTERM` on expiry: a process\n * blocked in an uninterruptible kernel wait (`D` state, e.g. a dead FUSE\n * connection) never runs a `SIGTERM` handler, so a graceful signal would leave\n * the deadline unenforced.\n *\n * @param cmd - Command and arguments, e.g. `[\"docker\", \"info\"]`.\n * @param opts - Spawn options; `timeoutMs` is mandatory.\n */\nexport function portableSpawnSync(\n cmd: string[],\n opts: PortableSpawnSyncOptions,\n): PortableSpawnSyncResult {\n const [bin, ...args] = cmd;\n if (!bin) throw new Error(\"portableSpawnSync: empty command\");\n if (!(opts.timeoutMs > 0)) {\n throw new Error(`portableSpawnSync: timeoutMs must be > 0 (got ${opts.timeoutMs})`);\n }\n const result = spawnSync(bin, args, {\n cwd: opts.cwd,\n env: opts.env ?? process.env,\n encoding: \"utf8\",\n timeout: opts.timeoutMs,\n killSignal: \"SIGKILL\",\n });\n // Node reports the expiry as `error.code === \"ETIMEDOUT\"`; Bun surfaces the\n // same case as a SIGKILL with no status, so accept either signal.\n const timedOut =\n (result.error as NodeJS.ErrnoException | undefined)?.code === \"ETIMEDOUT\" ||\n (result.status === null && result.signal === \"SIGKILL\");\n let stderr = result.stderr ?? \"\";\n if (timedOut) {\n // Surface the reason on the channel every caller already inspects — an\n // exitCode of -1 alone reads as \"command failed\" and hides the stall.\n stderr += `${stderr.endsWith(\"\\n\") || stderr === \"\" ? \"\" : \"\\n\"}${bin}: timed out after ${opts.timeoutMs}ms\\n`;\n }\n return {\n exitCode: result.status ?? -1,\n stdout: result.stdout ?? \"\",\n stderr,\n timedOut,\n };\n}\n","/**\n * Credential resolution for registry entries (§1.4).\n *\n * Split from `provider-registry.ts` deliberately: resolving a `cmd:` reference\n * spawns a process and `env:` reads `process.env`, so this module depends on\n * Node. The schema module must stay dependency-free because browser bundles\n * (`@skaile/workspace-bridge-react`) reach the registry *types* through\n * `@skaile/workspaces/types`, and a `node:child_process` import in that graph\n * breaks their typecheck.\n *\n * @see PROVIDER-CONFIG-PLAN.md §1.4\n */\n\nimport type { AIProviderCredentialKind, AIProviderEntry } from \"./provider-registry.js\";\nimport { parseCredentialRef } from \"./provider-registry.js\";\nimport { portableSpawnSync } from \"./subprocess.js\";\n\n/** Options for {@link resolveCredential}. */\nexport interface ResolveCredentialOptions {\n /** Environment `env:` refs read from; defaults to `process.env`. */\n env?: Record<string, string | undefined>;\n /**\n * Control-plane secrets, keyed by config id (a `platform:<configId>` ref) —\n * the `secrets` map that rides alongside `session_init`.\n */\n secrets?: Record<string, string>;\n /** Run `cmd:` references. Default `true`; the platform sets it `false`. */\n allowCommand?: boolean;\n}\n\n/** Outcome of {@link resolveCredential}. Never carries the secret in `error`. */\nexport interface ResolvedAIProviderCredential {\n kind: AIProviderCredentialKind;\n /** The secret, when one was produced. */\n value?: string;\n /** Where the value came from; `ambient` means the transport's own chain signs. */\n source: \"env\" | \"cmd\" | \"platform\" | \"keyring\" | \"ambient\" | \"none\";\n /** Why there is no value. Secret-free. */\n error?: string;\n}\n\n/** `cmd:` results are cached per process, matching omp's `!cmd` semantics. */\nconst commandCache = new Map<string, string>();\n\n/** Test seam — drops the memoized `cmd:` results. */\nexport function __resetCredentialCommandCache(): void {\n commandCache.clear();\n}\n\nconst COMMAND_TIMEOUT_MS = 10_000;\n\n/**\n * Resolve an entry's credential to a value (§1.4).\n *\n * `env:` reads the environment, `cmd:` runs a shell (10 s, trimmed stdout,\n * cached per process), `platform:` reads the injected secrets map. `keyring:`\n * is a reserved grammar slot: it validates but does not resolve, and says so.\n *\n * `sigv4`, `google_adc` and `azure_entra` entries without a ref resolve to\n * `source: \"ambient\"` with no value — the AWS/Google/Azure SDK chain signs the\n * request, there is nothing for this function to hand over.\n */\nexport function resolveCredential(\n entry: AIProviderEntry,\n options: ResolveCredentialOptions = {},\n): ResolvedAIProviderCredential {\n const credential = entry.credential;\n if (!credential || credential.kind === \"none\") {\n return { kind: credential?.kind ?? \"none\", source: \"none\" };\n }\n const kind = credential.kind;\n if (!credential.ref) {\n if (kind === \"sigv4\" || kind === \"google_adc\" || kind === \"azure_entra\") {\n return { kind, source: \"ambient\" };\n }\n return { kind, source: \"none\", error: `credential.ref is missing for kind '${kind}'` };\n }\n\n const parsed = parseCredentialRef(credential.ref);\n if (!parsed) {\n return { kind, source: \"none\", error: \"credential.ref is not a valid reference\" };\n }\n\n switch (parsed.form) {\n case \"env\": {\n const env = options.env ?? process.env;\n const value = env[parsed.name];\n if (!value) {\n return { kind, source: \"env\", error: `environment variable ${parsed.name} is not set` };\n }\n return { kind, source: \"env\", value };\n }\n case \"platform\": {\n const value = options.secrets?.[parsed.configId];\n if (!value) {\n return {\n kind,\n source: \"platform\",\n error: `no control-plane secret was injected for '${parsed.configId}'`,\n };\n }\n return { kind, source: \"platform\", value };\n }\n case \"cmd\": {\n if (options.allowCommand === false) {\n return { kind, source: \"cmd\", error: \"cmd: references are not permitted in this context\" };\n }\n const cached = commandCache.get(parsed.command);\n if (cached !== undefined) return { kind, source: \"cmd\", value: cached };\n const argv =\n process.platform === \"win32\"\n ? [\"cmd\", \"/c\", parsed.command]\n : [\"/bin/sh\", \"-c\", parsed.command];\n const result = portableSpawnSync(argv, { timeoutMs: COMMAND_TIMEOUT_MS });\n if (result.timedOut) {\n return { kind, source: \"cmd\", error: `credential command timed out after 10s` };\n }\n if (result.exitCode !== 0) {\n return { kind, source: \"cmd\", error: `credential command exited ${result.exitCode}` };\n }\n const value = result.stdout.trim();\n if (!value) return { kind, source: \"cmd\", error: \"credential command produced no output\" };\n commandCache.set(parsed.command, value);\n return { kind, source: \"cmd\", value };\n }\n case \"keyring\":\n return {\n kind,\n source: \"keyring\",\n error:\n `keyring references are a reserved grammar slot — ` +\n `no OS keychain backend ships yet (use env: or cmd:)`,\n };\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { pluginRegistry } from './chunk-G5SUWZEU.js';
2
- import { resolveCredential } from './chunk-ADPM6AYF.js';
3
- import { AI_PROVIDER_BASE_URL_TEMPLATES, resolveEntryBaseUrl, parseCredentialRef, registryEntries, isEntryEnabled } from './chunk-LSI2IVFT.js';
2
+ import { resolveCredential } from './chunk-VSX2G7LA.js';
3
+ import { AI_PROVIDER_BASE_URL_TEMPLATES, resolveEntryBaseUrl, parseCredentialRef, registryEntries, isEntryEnabled } from './chunk-RXGPFAMN.js';
4
4
 
5
5
  // bridge/src/harness-capabilities.ts
6
6
  var GENERIC_HARNESS_CAPABILITIES = {
@@ -662,5 +662,5 @@ async function listModelsForHarness(harnessId, registry, options) {
662
662
  }
663
663
 
664
664
  export { AI_PROVIDER_PRESETS, BUILTIN_HARNESS_CATALOG, PROVIDER_CREDENTIAL_ENV_PREFIX, PROVIDER_CREDENTIAL_ENV_SUFFIX, buildCredentialHeaders, catalogLayer, conventionalCredentialEnvName, createHarness, entryCredentialEnv, entryCredentialValue, expandPreset, getProviderPreset, harnessCapabilities, listHarnesses, listModelsForHarness, listProviderPresets, presetBaseUrl, probeProviderEntry, providerCredentialEnvName, registerBuiltinHarnesses, registryCredentialEnv, resolveEntryCredential, resolvePresetBaseUrl, resolveProbeUrl, supportsLiveToolUpdates, unresolvedProviderCredentials };
665
- //# sourceMappingURL=chunk-ILLTBKDJ.js.map
666
- //# sourceMappingURL=chunk-ILLTBKDJ.js.map
665
+ //# sourceMappingURL=chunk-X37JUNEW.js.map
666
+ //# sourceMappingURL=chunk-X37JUNEW.js.map