@skaile/workspaces 6.1.0 → 6.3.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.
- package/CHANGELOG.md +57 -0
- package/dist/ai-sdk.d.ts +2 -0
- package/dist/ai-sdk.js +111 -0
- package/dist/ai-sdk.js.map +1 -0
- package/dist/{asset-feeds-HJFV7UPW.js → asset-feeds-3YO2352Y.js} +26 -26
- package/dist/{asset-feeds-HJFV7UPW.js.map → asset-feeds-3YO2352Y.js.map} +1 -1
- package/dist/asset-manager/catalog-deployer.js +10 -10
- package/dist/asset-manager/fragments.js +1 -1
- package/dist/asset-manager/index.js +18 -18
- package/dist/asset-manager/installer.js +13 -13
- package/dist/asset-manager/renderers.js +11 -11
- package/dist/asset-manager/src/index.d.ts +149 -16
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts +9 -0
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/asset-manager/src/renderers.d.ts +7 -0
- package/dist/asset-manager/src/renderers.d.ts.map +1 -1
- package/dist/bridge/harnesses/claude-sdk.js +16 -15
- package/dist/bridge/harnesses/claude-sdk.js.map +1 -1
- package/dist/bridge/harnesses/codex.js +25 -17
- package/dist/bridge/harnesses/codex.js.map +1 -1
- package/dist/bridge/harnesses/continue.js +15 -14
- package/dist/bridge/harnesses/continue.js.map +1 -1
- package/dist/bridge/harnesses/echo.js +5 -4
- package/dist/bridge/harnesses/echo.js.map +1 -1
- package/dist/bridge/harnesses/gemini.js +11 -10
- package/dist/bridge/harnesses/goose.js +15 -14
- package/dist/bridge/harnesses/goose.js.map +1 -1
- package/dist/bridge/harnesses/omp.js +16 -8
- package/dist/bridge/harnesses/omp.js.map +1 -1
- package/dist/bridge/harnesses/opencode.js +15 -14
- package/dist/bridge/harnesses/opencode.js.map +1 -1
- package/dist/bridge/harnesses/qwen.js +11 -10
- package/dist/bridge/harnesses/qwen.js.map +1 -1
- package/dist/bridge/index.js +21 -19
- package/dist/bridge/src/ai-sdk.d.ts +46 -0
- package/dist/bridge/src/ai-sdk.d.ts.map +1 -0
- package/dist/bridge/src/harness-model-check.d.ts +15 -0
- package/dist/bridge/src/harness-model-check.d.ts.map +1 -1
- package/dist/bridge/src/harnesses/_subprocess-cli.d.ts.map +1 -1
- package/dist/bridge/src/harnesses/codex.d.ts.map +1 -1
- package/dist/bridge/src/harnesses/omp.d.ts.map +1 -1
- package/dist/bridge/src/index.d.ts +2 -1
- package/dist/bridge/src/index.d.ts.map +1 -1
- package/dist/bridge/src/provider-registry-load.d.ts +30 -0
- package/dist/bridge/src/provider-registry-load.d.ts.map +1 -0
- package/dist/bridge/src/runner-private-env.d.ts +7 -0
- package/dist/bridge/src/runner-private-env.d.ts.map +1 -1
- package/dist/{chunk-SVTMNSPI.js → chunk-2TFKXSB5.js} +5 -5
- package/dist/{chunk-SVTMNSPI.js.map → chunk-2TFKXSB5.js.map} +1 -1
- package/dist/{chunk-NB7SYQYP.js → chunk-32FYVSSW.js} +9 -28
- package/dist/chunk-32FYVSSW.js.map +1 -0
- package/dist/{chunk-QAKUD6QN.js → chunk-4QRJBY2P.js} +3 -3
- package/dist/{chunk-QAKUD6QN.js.map → chunk-4QRJBY2P.js.map} +1 -1
- package/dist/{chunk-XFIEVEU7.js → chunk-6OHZUUR7.js} +5 -4
- package/dist/chunk-6OHZUUR7.js.map +1 -0
- package/dist/{chunk-ILLTBKDJ.js → chunk-6UP2EDFN.js} +4 -313
- package/dist/chunk-6UP2EDFN.js.map +1 -0
- package/dist/{chunk-ZDLUQLI6.js → chunk-6WH2WE4B.js} +15 -5
- package/dist/chunk-6WH2WE4B.js.map +1 -0
- package/dist/{chunk-HPMQRAIF.js → chunk-72NT2TJU.js} +8 -7
- package/dist/chunk-72NT2TJU.js.map +1 -0
- package/dist/{chunk-E572OHGY.js → chunk-76FLBODK.js} +4 -3
- package/dist/chunk-76FLBODK.js.map +1 -0
- package/dist/{chunk-5Y2KGB4H.js → chunk-7MV3NHPT.js} +35 -9
- package/dist/chunk-7MV3NHPT.js.map +1 -0
- package/dist/{chunk-QEULL4Q3.js → chunk-7QG2WRSN.js} +77 -18
- package/dist/chunk-7QG2WRSN.js.map +1 -0
- package/dist/{chunk-6YR4ALVX.js → chunk-7RH6E332.js} +7 -7
- package/dist/{chunk-6YR4ALVX.js.map → chunk-7RH6E332.js.map} +1 -1
- package/dist/{chunk-BBBCJSSU.js → chunk-7TSNR5H5.js} +4 -4
- package/dist/{chunk-BBBCJSSU.js.map → chunk-7TSNR5H5.js.map} +1 -1
- package/dist/{chunk-3GMOPFWH.js → chunk-AMJ6KEV7.js} +4 -4
- package/dist/{chunk-3GMOPFWH.js.map → chunk-AMJ6KEV7.js.map} +1 -1
- package/dist/{chunk-X3YGUKCG.js → chunk-BPTWWKGF.js} +3 -3
- package/dist/{chunk-X3YGUKCG.js.map → chunk-BPTWWKGF.js.map} +1 -1
- package/dist/{chunk-Z7ZEZZB6.js → chunk-C5HFK34M.js} +3 -3
- package/dist/chunk-C5HFK34M.js.map +1 -0
- package/dist/{chunk-EJPMNDTP.js → chunk-COUJOTAJ.js} +3 -3
- package/dist/{chunk-EJPMNDTP.js.map → chunk-COUJOTAJ.js.map} +1 -1
- package/dist/{chunk-J72MO2WA.js → chunk-DU26AVK2.js} +10 -9
- package/dist/chunk-DU26AVK2.js.map +1 -0
- package/dist/{chunk-YLLVSR2U.js → chunk-E5NQRHEB.js} +30 -7
- package/dist/chunk-E5NQRHEB.js.map +1 -0
- package/dist/{chunk-XGULGQA3.js → chunk-ELSGFI3I.js} +5 -4
- package/dist/chunk-ELSGFI3I.js.map +1 -0
- package/dist/{chunk-IHFGPHCT.js → chunk-EQNIBBB6.js} +49 -25
- package/dist/chunk-EQNIBBB6.js.map +1 -0
- package/dist/{chunk-BFMYYNDT.js → chunk-F3D25RGM.js} +11 -3
- package/dist/chunk-F3D25RGM.js.map +1 -0
- package/dist/{chunk-GNZBFSRB.js → chunk-H622YULS.js} +5 -4
- package/dist/chunk-H622YULS.js.map +1 -0
- package/dist/{chunk-FKQNBCDW.js → chunk-HDVLBEEX.js} +4 -4
- package/dist/{chunk-FKQNBCDW.js.map → chunk-HDVLBEEX.js.map} +1 -1
- package/dist/{chunk-AATHJRKL.js → chunk-HGOJEVHY.js} +4 -4
- package/dist/{chunk-AATHJRKL.js.map → chunk-HGOJEVHY.js.map} +1 -1
- package/dist/{chunk-CEKW3KXP.js → chunk-HH2H2ZV7.js} +18 -15
- package/dist/chunk-HH2H2ZV7.js.map +1 -0
- package/dist/{chunk-ZFUZ5AKM.js → chunk-HTGTNN2B.js} +3 -3
- package/dist/{chunk-ZFUZ5AKM.js.map → chunk-HTGTNN2B.js.map} +1 -1
- package/dist/{chunk-LSSYC5IC.js → chunk-IZQOO6MN.js} +2 -2
- package/dist/{chunk-LSSYC5IC.js.map → chunk-IZQOO6MN.js.map} +1 -1
- package/dist/{chunk-VMVDAZLA.js → chunk-J5JRGBKK.js} +108 -19
- package/dist/chunk-J5JRGBKK.js.map +1 -0
- package/dist/{chunk-7LP7RCZI.js → chunk-JGH7NB47.js} +5 -5
- package/dist/{chunk-7LP7RCZI.js.map → chunk-JGH7NB47.js.map} +1 -1
- package/dist/{chunk-RHN5MRQO.js → chunk-JMIKGAUA.js} +27 -5
- package/dist/chunk-JMIKGAUA.js.map +1 -0
- package/dist/{chunk-HWNK3F3X.js → chunk-KGHYXXXV.js} +588 -76
- package/dist/chunk-KGHYXXXV.js.map +1 -0
- package/dist/{chunk-7HX6FNKL.js → chunk-KIPCBIFJ.js} +41 -56
- package/dist/chunk-KIPCBIFJ.js.map +1 -0
- package/dist/{chunk-ZBHZLWV3.js → chunk-KPKGWXUJ.js} +4 -4
- package/dist/{chunk-ZBHZLWV3.js.map → chunk-KPKGWXUJ.js.map} +1 -1
- package/dist/{chunk-ABFPSVIS.js → chunk-LD6O6QKU.js} +31 -7
- package/dist/chunk-LD6O6QKU.js.map +1 -0
- package/dist/{chunk-AZ2H6R5I.js → chunk-LEJQAX7G.js} +74 -39
- package/dist/chunk-LEJQAX7G.js.map +1 -0
- package/dist/{chunk-ZAELRYKS.js → chunk-MD3FUZS3.js} +3 -3
- package/dist/{chunk-ZAELRYKS.js.map → chunk-MD3FUZS3.js.map} +1 -1
- package/dist/{chunk-NUA33BYO.js → chunk-MYXFR27L.js} +42 -15
- package/dist/chunk-MYXFR27L.js.map +1 -0
- package/dist/{chunk-KUQAJVYT.js → chunk-PHAMYCZH.js} +142 -28
- package/dist/chunk-PHAMYCZH.js.map +1 -0
- package/dist/{chunk-NOA6EJXE.js → chunk-PKE3PXOK.js} +3 -3
- package/dist/{chunk-NOA6EJXE.js.map → chunk-PKE3PXOK.js.map} +1 -1
- package/dist/{chunk-RDTLPOPD.js → chunk-PL52CI4U.js} +4 -4
- package/dist/{chunk-RDTLPOPD.js.map → chunk-PL52CI4U.js.map} +1 -1
- package/dist/{chunk-VYVTEMAW.js → chunk-PNUM7GUY.js} +3 -3
- package/dist/{chunk-VYVTEMAW.js.map → chunk-PNUM7GUY.js.map} +1 -1
- package/dist/{chunk-DIGFA7Z5.js → chunk-Q7CU5GQO.js} +13 -5
- package/dist/chunk-Q7CU5GQO.js.map +1 -0
- package/dist/chunk-QFFMFZIR.js +32 -0
- package/dist/chunk-QFFMFZIR.js.map +1 -0
- package/dist/{chunk-HMISULVD.js → chunk-QK7AG5AV.js} +4 -4
- package/dist/{chunk-HMISULVD.js.map → chunk-QK7AG5AV.js.map} +1 -1
- package/dist/{chunk-2LAPHLDH.js → chunk-QTLUZUF2.js} +45 -35
- package/dist/chunk-QTLUZUF2.js.map +1 -0
- package/dist/{chunk-4MUDQCBP.js → chunk-RFQONXET.js} +3 -3
- package/dist/{chunk-4MUDQCBP.js.map → chunk-RFQONXET.js.map} +1 -1
- package/dist/{chunk-AITJ7ELM.js → chunk-ROVZCGTN.js} +59 -23
- package/dist/chunk-ROVZCGTN.js.map +1 -0
- package/dist/{chunk-LSI2IVFT.js → chunk-RXGPFAMN.js} +4 -3
- package/dist/chunk-RXGPFAMN.js.map +1 -0
- package/dist/chunk-S6KZHPR4.js +315 -0
- package/dist/chunk-S6KZHPR4.js.map +1 -0
- package/dist/{chunk-EX3GLAL6.js → chunk-TGV2EWGL.js} +5 -5
- package/dist/{chunk-EX3GLAL6.js.map → chunk-TGV2EWGL.js.map} +1 -1
- package/dist/{chunk-QSYQOTWN.js → chunk-TO5SSMRI.js} +58 -5
- package/dist/chunk-TO5SSMRI.js.map +1 -0
- package/dist/{chunk-Z3VKUWAX.js → chunk-TSTRH4SM.js} +3 -3
- package/dist/{chunk-Z3VKUWAX.js.map → chunk-TSTRH4SM.js.map} +1 -1
- package/dist/{chunk-5J4NPGFM.js → chunk-U3SXCVR7.js} +5 -5
- package/dist/{chunk-5J4NPGFM.js.map → chunk-U3SXCVR7.js.map} +1 -1
- package/dist/{chunk-IRYKRKVQ.js → chunk-URCJIV7T.js} +3 -3
- package/dist/{chunk-IRYKRKVQ.js.map → chunk-URCJIV7T.js.map} +1 -1
- package/dist/{chunk-ASWTQQ7E.js → chunk-V5BPDB4J.js} +3 -3
- package/dist/{chunk-ASWTQQ7E.js.map → chunk-V5BPDB4J.js.map} +1 -1
- package/dist/{chunk-ADPM6AYF.js → chunk-VSX2G7LA.js} +3 -3
- package/dist/{chunk-ADPM6AYF.js.map → chunk-VSX2G7LA.js.map} +1 -1
- package/dist/{chunk-4FVIT5DI.js → chunk-VUWRGMT6.js} +3 -3
- package/dist/{chunk-4FVIT5DI.js.map → chunk-VUWRGMT6.js.map} +1 -1
- package/dist/{chunk-ZHGKAZJ7.js → chunk-XBQTXGY4.js} +56 -8
- package/dist/chunk-XBQTXGY4.js.map +1 -0
- package/dist/{chunk-UI745XC3.js → chunk-XEVFSDIF.js} +13 -7
- package/dist/chunk-XEVFSDIF.js.map +1 -0
- package/dist/{chunk-S2XHGWQC.js → chunk-Y3I4KGLX.js} +44 -15
- package/dist/chunk-Y3I4KGLX.js.map +1 -0
- package/dist/{chunk-COYF6IG2.js → chunk-YW4ASEUP.js} +5 -5
- package/dist/{chunk-COYF6IG2.js.map → chunk-YW4ASEUP.js.map} +1 -1
- package/dist/{chunk-DGTI65OC.js → chunk-ZEH4WFEG.js} +17 -11
- package/dist/chunk-ZEH4WFEG.js.map +1 -0
- package/dist/{claude-code-RE46FJXI.js → claude-code-EUKDGOOO.js} +5 -5
- package/dist/{claude-code-RE46FJXI.js.map → claude-code-EUKDGOOO.js.map} +1 -1
- package/dist/cli/index.js +350 -141
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/config.d.ts.map +1 -1
- package/dist/cli/src/commands/diff.d.ts.map +1 -1
- package/dist/cli/src/commands/harness.d.ts.map +1 -1
- package/dist/cli/src/commands/integration.d.ts.map +1 -1
- package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/library-index.d.ts +8 -1
- package/dist/cli/src/commands/library-index.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
- package/dist/cli/src/commands/outdated.d.ts.map +1 -1
- package/dist/cli/src/commands/plugin-registry-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/providers.d.ts.map +1 -1
- package/dist/cli/src/commands/rebuild.d.ts.map +1 -1
- package/dist/cli/src/commands/run.d.ts.map +1 -1
- package/dist/cli/src/commands/serve-preflight.d.ts +31 -1
- package/dist/cli/src/commands/serve-preflight.d.ts.map +1 -1
- package/dist/cli/src/commands/serve.d.ts +10 -0
- package/dist/cli/src/commands/serve.d.ts.map +1 -1
- package/dist/cli/src/commands/source-manifest-publish.d.ts.map +1 -1
- package/dist/cli/src/commands/source-manifest.d.ts +19 -7
- package/dist/cli/src/commands/source-manifest.d.ts.map +1 -1
- package/dist/cli/src/commands/validate-instances.d.ts.map +1 -1
- package/dist/cli/src/commands/validate.d.ts.map +1 -1
- package/dist/cli/src/commands/why.d.ts.map +1 -1
- package/dist/cli/src/config-checks.d.ts +23 -5
- package/dist/cli/src/config-checks.d.ts.map +1 -1
- package/dist/cli/src/harness-error.d.ts +12 -1
- package/dist/cli/src/harness-error.d.ts.map +1 -1
- package/dist/cli/src/helpers.d.ts +18 -8
- package/dist/cli/src/helpers.d.ts.map +1 -1
- package/dist/cli/src/plugin-store/index.d.ts +10 -1
- package/dist/cli/src/plugin-store/index.d.ts.map +1 -1
- package/dist/cli/src/plugin-store/spec.d.ts +8 -0
- package/dist/cli/src/plugin-store/spec.d.ts.map +1 -1
- package/dist/cli/src/skill-checks.d.ts +2 -2
- package/dist/cli/src/skill-checks.d.ts.map +1 -1
- package/dist/connectors/config.js +5 -5
- package/dist/connectors/index.js +24 -22
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/connectors-XYPE2DCQ.js +50 -0
- package/dist/{connectors-7THEF7YA.js.map → connectors-XYPE2DCQ.js.map} +1 -1
- package/dist/core/framework.js +1 -1
- package/dist/core/index.js +9 -9
- package/dist/core/manifest.js +2 -2
- package/dist/core/models.js +1 -1
- package/dist/core/provider-registry-credentials.js +2 -2
- package/dist/core/provider-registry.js +1 -1
- package/dist/core/publish-manifest.js +3 -3
- package/dist/core/ref.js +1 -1
- package/dist/core/runtime-assets.js +5 -5
- package/dist/core/src/framework.d.ts +5 -3
- package/dist/core/src/framework.d.ts.map +1 -1
- package/dist/core/src/index.d.ts +2 -1
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/lock.d.ts +12 -0
- package/dist/core/src/lock.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +15 -0
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +7 -0
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/provider-registry.d.ts +6 -0
- package/dist/core/src/provider-registry.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +10 -1
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
- package/dist/core/workspace-config.js +4 -4
- package/dist/deploy/index.js +9 -9
- package/dist/discovery/index.js +5 -5
- package/dist/discovery/src/parse-manifest.d.ts.map +1 -1
- package/dist/{ensure-sources-IH7CHSJF.js → ensure-sources-IN3VKHUA.js} +37 -21
- package/dist/ensure-sources-IN3VKHUA.js.map +1 -0
- package/dist/factory-assets/connectors/box.js +24 -22
- package/dist/factory-assets/connectors/deploy.js +24 -22
- package/dist/factory-assets/connectors/devserver.js +24 -22
- package/dist/factory-assets/connectors/flow/adapter.js +24 -22
- package/dist/factory-assets/connectors/flow/engine.js +10 -10
- package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.js +26 -24
- package/dist/factory-assets/connectors/flow.js +24 -22
- package/dist/factory-assets/connectors/git.js +24 -22
- package/dist/factory-assets/connectors/gmail.js +24 -22
- package/dist/factory-assets/connectors/googledrive.js +24 -22
- package/dist/factory-assets/connectors/local.js +24 -22
- package/dist/factory-assets/connectors/mattermost.js +24 -22
- package/dist/factory-assets/connectors/memory.js +24 -22
- package/dist/factory-assets/connectors/minio.js +24 -22
- package/dist/factory-assets/connectors/postgres.js +24 -22
- package/dist/factory-assets/connectors/s3.js +24 -22
- package/dist/factory-assets/connectors/sharepoint.js +24 -22
- package/dist/factory-assets/connectors/sqlite.js +24 -22
- package/dist/factory-assets/connectors/static-server.js +24 -22
- package/dist/factory-assets/connectors/tunnel.js +24 -22
- package/dist/factory-assets/connectors/webdav.js +24 -22
- package/dist/factory-assets/connectors/xstate-store.js +24 -22
- package/dist/factory-assets/connectors/xstate.js +24 -22
- package/dist/flows-QAO63TDV.js +26 -0
- package/dist/{flows-4JZQ3XFK.js.map → flows-QAO63TDV.js.map} +1 -1
- package/dist/helpers-HDVGCF3M.js +54 -0
- package/dist/{helpers-JNMK3FC2.js.map → helpers-HDVGCF3M.js.map} +1 -1
- package/dist/library/index.js +14 -14
- package/dist/library/install.js +5 -5
- package/dist/library/src/index.d.ts +1 -1
- package/dist/library/src/index.d.ts.map +1 -1
- package/dist/library/src/install/index.d.ts +1 -1
- package/dist/library/src/install/index.d.ts.map +1 -1
- package/dist/library/src/install/install-from-manifest.d.ts +13 -0
- package/dist/library/src/install/install-from-manifest.d.ts.map +1 -1
- package/dist/library/src/install/source-fetch-github.d.ts.map +1 -1
- package/dist/library/src/manifest-writer.d.ts.map +1 -1
- package/dist/library/src/remote/remote-catalog-source.d.ts +3 -1
- package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
- package/dist/library/src/remote/rest-catalog-source.d.ts +3 -2
- package/dist/library/src/remote/rest-catalog-source.d.ts.map +1 -1
- package/dist/{library-publish-I3UWXAHI.js → library-publish-62OWCNB5.js} +56 -55
- package/dist/library-publish-62OWCNB5.js.map +1 -0
- package/dist/model-endpoint/index.js +13 -12
- package/dist/model-endpoint/src/openai-chat.d.ts +7 -2
- package/dist/model-endpoint/src/openai-chat.d.ts.map +1 -1
- package/dist/model-endpoint/src/openai-shared.d.ts +8 -0
- package/dist/model-endpoint/src/openai-shared.d.ts.map +1 -1
- package/dist/model-endpoint/src/server.d.ts.map +1 -1
- package/dist/model-endpoint/src/types.d.ts +1 -1
- package/dist/model-endpoint/src/types.d.ts.map +1 -1
- package/dist/model-endpoint/src/usage-cost.d.ts +23 -0
- package/dist/model-endpoint/src/usage-cost.d.ts.map +1 -0
- package/dist/open-library-TZ7OSDEJ.js +58 -0
- package/dist/{open-library-NKKUJLWA.js.map → open-library-TZ7OSDEJ.js.map} +1 -1
- package/dist/open-registry-RLZKTJG3.js +32 -0
- package/dist/{open-registry-BYAXSHUI.js.map → open-registry-RLZKTJG3.js.map} +1 -1
- package/dist/paths-D6LBQETQ.js +22 -0
- package/dist/{paths-UKWE35XS.js.map → paths-D6LBQETQ.js.map} +1 -1
- package/dist/plugin-store-A5J4TLCH.js +23 -0
- package/dist/{plugin-store-ABE35NRX.js.map → plugin-store-A5J4TLCH.js.map} +1 -1
- package/dist/project-4AVRES3M.js +88 -0
- package/dist/{project-BIPK47JK.js.map → project-4AVRES3M.js.map} +1 -1
- package/dist/resolver/index.js +10 -10
- package/dist/runner/index.js +41 -39
- package/dist/runner/src/capability-roundtrip.d.ts +7 -6
- package/dist/runner/src/capability-roundtrip.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts +6 -5
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +18 -18
- package/dist/sdk/bridge.js +21 -19
- package/dist/sdk/core.js +9 -9
- package/dist/sdk/flow.js +10 -10
- package/dist/sdk/index.js +41 -39
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.js +10 -10
- package/dist/sdk/runner.js +41 -39
- package/dist/sdk/transport/ws/server.js +10 -10
- package/dist/sdk/transport/ws.js +10 -10
- package/dist/sdk/transport.js +10 -10
- package/dist/{serve-preflight-FLTIBTEX.js → serve-preflight-H2AYMGJ6.js} +65 -35
- package/dist/serve-preflight-H2AYMGJ6.js.map +1 -0
- package/dist/{setup-AG6NFHSN.js → setup-NSPQD4V4.js} +33 -31
- package/dist/setup-NSPQD4V4.js.map +1 -0
- package/dist/skills-B533SRVZ.js +26 -0
- package/dist/{skills-UQYUHVKO.js.map → skills-B533SRVZ.js.map} +1 -1
- package/dist/source-VTECABUO.js +87 -0
- package/dist/{source-ASEHI2XS.js.map → source-VTECABUO.js.map} +1 -1
- package/dist/source-fetch-github-RWHV4I5Z.js +4 -0
- package/dist/{source-fetch-github-ST4MFL3D.js.map → source-fetch-github-RWHV4I5Z.js.map} +1 -1
- package/dist/{source-manifest-publish-IEVV3W6J.js → source-manifest-publish-YORI42MN.js} +56 -56
- package/dist/source-manifest-publish-YORI42MN.js.map +1 -0
- package/dist/transport/index.js +10 -10
- package/dist/transport/ws/server.js +10 -10
- package/dist/transport/ws.js +10 -10
- package/dist/tui/index.js +49 -40
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/src/repl.d.ts.map +1 -1
- package/dist/types/manifests.js +1 -1
- package/dist/types/src/manifests/index.d.ts +1 -1
- package/dist/types/src/manifests/index.d.ts.map +1 -1
- package/dist/types/src/manifests/scaffold-body.d.ts +2 -0
- package/dist/types/src/manifests/scaffold-body.d.ts.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +31 -29
- package/dist/workspace-plugin/adapters/omp.js +15 -15
- package/dist/workspace-plugin/index.js +2 -2
- package/package.json +27 -1
- package/dist/chunk-2LAPHLDH.js.map +0 -1
- package/dist/chunk-5Y2KGB4H.js.map +0 -1
- package/dist/chunk-7HX6FNKL.js.map +0 -1
- package/dist/chunk-ABFPSVIS.js.map +0 -1
- package/dist/chunk-AITJ7ELM.js.map +0 -1
- package/dist/chunk-AZ2H6R5I.js.map +0 -1
- package/dist/chunk-BFMYYNDT.js.map +0 -1
- package/dist/chunk-CEKW3KXP.js.map +0 -1
- package/dist/chunk-DGTI65OC.js.map +0 -1
- package/dist/chunk-DIGFA7Z5.js.map +0 -1
- package/dist/chunk-E572OHGY.js.map +0 -1
- package/dist/chunk-GNZBFSRB.js.map +0 -1
- package/dist/chunk-HPMQRAIF.js.map +0 -1
- package/dist/chunk-HWNK3F3X.js.map +0 -1
- package/dist/chunk-IHFGPHCT.js.map +0 -1
- package/dist/chunk-ILLTBKDJ.js.map +0 -1
- package/dist/chunk-J72MO2WA.js.map +0 -1
- package/dist/chunk-KUQAJVYT.js.map +0 -1
- package/dist/chunk-LSI2IVFT.js.map +0 -1
- package/dist/chunk-NB7SYQYP.js.map +0 -1
- package/dist/chunk-NUA33BYO.js.map +0 -1
- package/dist/chunk-QEULL4Q3.js.map +0 -1
- package/dist/chunk-QSYQOTWN.js.map +0 -1
- package/dist/chunk-RHN5MRQO.js.map +0 -1
- package/dist/chunk-S2XHGWQC.js.map +0 -1
- package/dist/chunk-UI745XC3.js.map +0 -1
- package/dist/chunk-VMVDAZLA.js.map +0 -1
- package/dist/chunk-XFIEVEU7.js.map +0 -1
- package/dist/chunk-XGULGQA3.js.map +0 -1
- package/dist/chunk-YLLVSR2U.js.map +0 -1
- package/dist/chunk-Z7ZEZZB6.js.map +0 -1
- package/dist/chunk-ZDLUQLI6.js.map +0 -1
- package/dist/chunk-ZHGKAZJ7.js.map +0 -1
- package/dist/connectors-7THEF7YA.js +0 -48
- package/dist/ensure-sources-IH7CHSJF.js.map +0 -1
- package/dist/flows-4JZQ3XFK.js +0 -26
- package/dist/helpers-JNMK3FC2.js +0 -38
- package/dist/library-publish-I3UWXAHI.js.map +0 -1
- package/dist/open-library-NKKUJLWA.js +0 -42
- package/dist/open-registry-BYAXSHUI.js +0 -32
- package/dist/paths-UKWE35XS.js +0 -22
- package/dist/plugin-store-ABE35NRX.js +0 -23
- package/dist/project-BIPK47JK.js +0 -86
- package/dist/serve-preflight-FLTIBTEX.js.map +0 -1
- package/dist/setup-AG6NFHSN.js.map +0 -1
- package/dist/skills-UQYUHVKO.js +0 -26
- package/dist/source-ASEHI2XS.js +0 -85
- package/dist/source-fetch-github-ST4MFL3D.js +0 -4
- package/dist/source-manifest-publish-IEVV3W6J.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { withFsDeadline, tryWithFsDeadline, walkDir } from './chunk-
|
|
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-
|
|
333
|
-
//# sourceMappingURL=chunk-
|
|
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 { buildClaudePluginFiles } from './chunk-
|
|
1
|
+
import { buildClaudePluginFiles } from './chunk-4QRJBY2P.js';
|
|
2
2
|
import { createHash } from 'crypto';
|
|
3
3
|
import { existsSync } from 'fs';
|
|
4
4
|
import fs from 'fs/promises';
|
|
@@ -281,5 +281,5 @@ async function status(projectDir) {
|
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
export { disable, enable, install, refreshPluginSkills, status, uninstall };
|
|
284
|
-
//# sourceMappingURL=chunk-
|
|
285
|
-
//# sourceMappingURL=chunk-
|
|
284
|
+
//# sourceMappingURL=chunk-V5BPDB4J.js.map
|
|
285
|
+
//# sourceMappingURL=chunk-V5BPDB4J.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cli/src/commands/plugin/claude-code.ts"],"names":["disabled","next","updated","list"],"mappings":"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","file":"chunk-ASWTQQ7E.js","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { buildClaudePluginFiles } from \"@skaile/workspaces/workspace-plugin\";\nimport type { HarnessStatus, InstallResult, ToggleResult, UninstallResult } from \"./types.ts\";\n\nconst SKAILE_MCP_NAME = \"skaile-workspace\";\n\nconst MCP_SERVER_ENTRY = {\n command: \"skaile\",\n args: [\"mcp-server\"],\n env: {} as Record<string, string>,\n};\n\ninterface ClaudeSettings {\n plugins?: string[];\n enabledPlugins?: string[];\n disabledPlugins?: string[];\n disabledMcpjsonServers?: string[];\n [k: string]: unknown;\n}\n\ninterface ClaudeMcpFile {\n mcpServers?: Record<string, unknown>;\n [k: string]: unknown;\n}\n\n/**\n * Project-scope MCP file. Claude Code reads `<project>/.mcp.json`; the\n * `.claude/mcp.json` that earlier versions wrote is never read (`claude mcp\n * list` reported \"No MCP servers configured\").\n */\nfunction mcpFilePath(projectDir: string): string {\n return path.join(projectDir, \".mcp.json\");\n}\n\n/** The dead `.claude/mcp.json` of earlier versions; entries in it are removed. */\nfunction legacyMcpFilePath(projectDir: string): string {\n return path.join(projectDir, \".claude\", \"mcp.json\");\n}\n\n/**\n * Drop the skaile entry from an MCP file, deleting the file when nothing is\n * left. Returns whether the file changed.\n */\nasync function removeSkaileMcpEntry(mcpPath: string): Promise<boolean> {\n const mcp = await readJsonStrict<ClaudeMcpFile>(mcpPath);\n if (!mcp?.mcpServers || !(SKAILE_MCP_NAME in mcp.mcpServers)) return false;\n const { [SKAILE_MCP_NAME]: _removed, ...rest } = mcp.mcpServers;\n const updated: ClaudeMcpFile = { ...mcp, mcpServers: rest };\n if (Object.keys(rest).length === 0) delete updated.mcpServers;\n if (Object.keys(updated).length === 0) await fs.unlink(mcpPath);\n else await writeJson(mcpPath, updated);\n return true;\n}\n\n/** Absolute path to the generated Claude Code plugin directory. */\nfunction pluginDir(projectDir: string): string {\n return path.join(projectDir, \".claude\", \"plugins\", \"skaile\");\n}\n\nasync function readJsonStrict<T>(p: string): Promise<T | null> {\n let raw: string;\n try {\n raw = await fs.readFile(p, \"utf-8\");\n } catch {\n return null;\n }\n try {\n return JSON.parse(raw) as T;\n } catch (e: unknown) {\n throw new Error(\n `cannot parse ${p}: ${e instanceof Error ? e.message : String(e)}; please fix or remove`,\n );\n }\n}\n\nasync function writeJson(p: string, value: unknown): Promise<void> {\n await fs.mkdir(path.dirname(p), { recursive: true });\n await fs.writeFile(p, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\n/** Skill folders that are never copied into the plugin: bytecode and dependency trees. */\nconst SKIPPED_IN_SKILL = new Set([\"__pycache__\", \"node_modules\", \".DS_Store\"]);\n\n/**\n * The project's installed skills, name to source folder: the folders with a `SKILL.md` that\n * `skaile add` deployed to `.claude/skills/`, and any under `.skaile/skills/` (the folder an\n * earlier release read; it wins over a deployed copy of the same name).\n */\nasync function installedSkillSources(projectDir: string): Promise<Map<string, string>> {\n const sources = new Map<string, string>();\n for (const root of [\n path.join(projectDir, \".claude\", \"skills\"),\n path.join(projectDir, \".skaile\", \"skills\"),\n ]) {\n for (const name of await fs.readdir(root).catch(() => [] as string[])) {\n const from = path.join(root, name);\n if (existsSync(path.join(from, \"SKILL.md\"))) sources.set(name, from);\n }\n }\n return sources;\n}\n\n/**\n * Fill the plugin's `skills/` with the project's installed skills (p1190). A skill the project\n * no longer has is removed from the plugin, so a repeated install matches the project. A linked\n * skill is copied as files.\n */\nasync function copyInstalledSkills(projectDir: string, skillsDir: string): Promise<void> {\n for (const entry of await fs.readdir(skillsDir).catch(() => [] as string[])) {\n if (entry !== \".gitkeep\")\n await fs.rm(path.join(skillsDir, entry), { recursive: true, force: true });\n }\n for (const [name, from] of await installedSkillSources(projectDir)) {\n await fs.cp(from, path.join(skillsDir, name), {\n recursive: true,\n dereference: true,\n filter: (src) => !SKIPPED_IN_SKILL.has(path.basename(src)),\n });\n }\n}\n\n/** Relative file path to content hash of everything the plugin copy would hold for `dir`. */\nasync function skillDigest(dir: string, rel = \"\"): Promise<string[]> {\n const out: string[] = [];\n for (const entry of (await fs.readdir(path.join(dir, rel)).catch(() => [] as string[])).sort()) {\n if (SKIPPED_IN_SKILL.has(entry)) continue;\n const relPath = path.join(rel, entry);\n const stat = await fs.stat(path.join(dir, relPath)).catch(() => undefined);\n if (!stat) continue;\n if (stat.isDirectory()) out.push(...(await skillDigest(dir, relPath)));\n else {\n const hash = createHash(\"sha256\")\n .update(await fs.readFile(path.join(dir, relPath)))\n .digest(\"hex\");\n out.push(`${relPath}:${hash}`);\n }\n }\n return out;\n}\n\n/**\n * True when the `--full` plugin's `skills/` copy differs from what `copyInstalledSkills` would\n * write now: a skill added, removed or changed since the copy was made (p1350).\n */\nasync function pluginSkillsStale(projectDir: string): Promise<boolean> {\n const skillsDir = path.join(pluginDir(projectDir), \"skills\");\n const expected = await installedSkillSources(projectDir);\n const actual = (await fs.readdir(skillsDir).catch(() => [] as string[])).filter(\n (n) => n !== \".gitkeep\",\n );\n if (actual.length !== expected.size || actual.some((n) => !expected.has(n))) return true;\n for (const [name, from] of expected) {\n const [want, have] = await Promise.all([\n skillDigest(from),\n skillDigest(path.join(skillsDir, name)),\n ]);\n if (want.join(\"\\n\") !== have.join(\"\\n\")) return true;\n }\n return false;\n}\n\n/**\n * Bring the `--full` plugin's skills copy up to date after `add`, `remove`, `install` or\n * `update` changed the project's skills (p1350). Does nothing when the plugin is not installed\n * (the MCP method has no copy) or the copy is current. Returns whether it rewrote the copy.\n */\nexport async function refreshPluginSkills(projectDir: string): Promise<boolean> {\n if ((await detectInstall(projectDir))?.method !== \"plugin\") return false;\n if (!(await pluginSkillsStale(projectDir))) return false;\n await copyInstalledSkills(projectDir, path.join(pluginDir(projectDir), \"skills\"));\n return true;\n}\n\n// ── install ────────────────────────────────────────────────────────────────\n\n/**\n * Install the skaile integration for Claude Code.\n *\n * Two modes:\n * - **mcp** (default) — write project-root `.mcp.json` pointing at `skaile mcp-server`.\n * - **full** (`opts.full`) — generate the `.claude/plugins/skaile/` directory\n * (MCP + lifecycle hooks) and register it in `.claude/settings.json`.\n */\nexport async function install(\n projectDir: string,\n opts?: { full?: boolean },\n): Promise<InstallResult> {\n return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);\n}\n\nasync function installMcp(projectDir: string): Promise<InstallResult> {\n const mcpPath = mcpFilePath(projectDir);\n const existing = (await readJsonStrict<ClaudeMcpFile>(mcpPath)) ?? {};\n const mcpServers = { ...(existing.mcpServers ?? {}) };\n const previous = mcpServers[SKAILE_MCP_NAME];\n const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);\n let warning: string | undefined;\n if (previous && !matches) {\n warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path.relative(projectDir, mcpPath)}`;\n }\n mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;\n await writeJson(mcpPath, { ...existing, mcpServers });\n const migrated = await removeSkaileMcpEntry(legacyMcpFilePath(projectDir));\n return { changed: !matches || migrated, method: \"mcp\", warning };\n}\n\n/**\n * Unlink `p` when it is a symlink (never what it points at), so the install below writes into\n * a real folder of its own instead of through the link into the user's files (`skills/ ->\n * ../../skills` would otherwise have its target cleared).\n */\nasync function dropSymlink(p: string): Promise<void> {\n const stat = await fs.lstat(p).catch(() => undefined);\n if (stat?.isSymbolicLink()) await fs.unlink(p);\n}\n\nasync function installFullPlugin(projectDir: string): Promise<InstallResult> {\n const dir = pluginDir(projectDir);\n await dropSymlink(dir);\n await dropSymlink(path.join(dir, \"skills\"));\n\n // Generate the plugin directory from the in-memory file map.\n for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {\n const dest = path.join(dir, rel);\n await fs.mkdir(path.dirname(dest), { recursive: true });\n await fs.writeFile(dest, content);\n }\n\n await copyInstalledSkills(projectDir, path.join(dir, \"skills\"));\n\n // Register the generated dir in .claude/settings.json#plugins[].\n const settingsPath = path.join(projectDir, \".claude\", \"settings.json\");\n const settings = (await readJsonStrict<ClaudeSettings>(settingsPath)) ?? {};\n const plugins = settings.plugins ?? [];\n if (!plugins.includes(dir)) plugins.push(dir);\n await writeJson(settingsPath, { ...settings, plugins });\n\n return { changed: true, method: \"plugin\" };\n}\n\n// ── uninstall ──────────────────────────────────────────────────────────────\n\nexport async function uninstall(projectDir: string): Promise<UninstallResult> {\n const settingsPath = path.join(projectDir, \".claude\", \"settings.json\");\n const mcpPath = mcpFilePath(projectDir);\n const dir = pluginDir(projectDir);\n const rel = (p: string): string => path.relative(projectDir, p);\n\n /** Project-relative paths the uninstall changed or deleted, in the order it touched them. */\n const files: string[] = [];\n\n // Remove the generated plugin dir from plugins[] if registered.\n const settings = await readJsonStrict<ClaudeSettings>(settingsPath);\n if (settings && Array.isArray(settings.plugins)) {\n const next = settings.plugins.filter((p) => p !== dir);\n if (next.length !== settings.plugins.length) {\n files.push(rel(settingsPath));\n const updated: ClaudeSettings = { ...settings, plugins: next };\n if (next.length === 0) delete updated.plugins;\n // A settings file that held only the skaile plugin is left empty: delete it.\n if (Object.keys(updated).length === 0) await fs.unlink(settingsPath);\n else await writeJson(settingsPath, updated);\n }\n }\n\n // Delete the generated plugin directory.\n if (existsSync(dir)) {\n await fs.rm(dir, { recursive: true, force: true });\n files.push(rel(dir));\n }\n\n // Remove from .mcp.json — and from the legacy .claude/mcp.json — if present.\n if (await removeSkaileMcpEntry(mcpPath)) files.push(rel(mcpPath));\n const legacyPath = legacyMcpFilePath(projectDir);\n if (await removeSkaileMcpEntry(legacyPath)) files.push(rel(legacyPath));\n\n // Leave no empty `.claude/` or `.claude/plugins/` behind.\n for (const emptyDir of [path.dirname(dir), path.join(projectDir, \".claude\")]) {\n await fs.rmdir(emptyDir).catch(() => undefined);\n }\n\n return { changed: files.length > 0, files };\n}\n\n// ── enable / disable ───────────────────────────────────────────────────────\n\nasync function detectInstall(\n projectDir: string,\n): Promise<{ method: \"plugin\" | \"mcp\"; pluginPath?: string } | null> {\n const dir = pluginDir(projectDir);\n const settings = await readJsonStrict<ClaudeSettings>(\n path.join(projectDir, \".claude\", \"settings.json\"),\n );\n if (\n existsSync(path.join(dir, \".claude-plugin\", \"plugin.json\")) &&\n settings?.plugins?.includes(dir)\n ) {\n return { method: \"plugin\", pluginPath: dir };\n }\n\n const mcp = await readJsonStrict<ClaudeMcpFile>(mcpFilePath(projectDir));\n if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {\n return { method: \"mcp\" };\n }\n return null;\n}\n\nexport async function enable(projectDir: string): Promise<ToggleResult> {\n const detected = await detectInstall(projectDir);\n if (!detected) throw new Error(\"plugin not installed for claude-code\");\n\n const settingsPath = path.join(projectDir, \".claude\", \"settings.json\");\n const settings = (await readJsonStrict<ClaudeSettings>(settingsPath)) ?? {};\n\n if (detected.method === \"plugin\") {\n const disabled = settings.disabledPlugins ?? [];\n const next = disabled.filter((p) => p !== detected.pluginPath);\n if (next.length === disabled.length) return { changed: false };\n const updated: ClaudeSettings = { ...settings, disabledPlugins: next };\n if (next.length === 0) delete updated.disabledPlugins;\n await writeJson(settingsPath, updated);\n return { changed: true };\n }\n\n const disabled = settings.disabledMcpjsonServers ?? [];\n const next = disabled.filter((n) => n !== SKAILE_MCP_NAME);\n if (next.length === disabled.length) return { changed: false };\n const updated: ClaudeSettings = { ...settings, disabledMcpjsonServers: next };\n if (next.length === 0) delete updated.disabledMcpjsonServers;\n await writeJson(settingsPath, updated);\n return { changed: true };\n}\n\nexport async function disable(projectDir: string): Promise<ToggleResult> {\n const detected = await detectInstall(projectDir);\n if (!detected) throw new Error(\"plugin not installed for claude-code\");\n\n const settingsPath = path.join(projectDir, \".claude\", \"settings.json\");\n const settings = (await readJsonStrict<ClaudeSettings>(settingsPath)) ?? {};\n\n if (detected.method === \"plugin\") {\n const list = settings.disabledPlugins ?? [];\n if (list.includes(detected.pluginPath as string)) return { changed: false };\n await writeJson(settingsPath, {\n ...settings,\n disabledPlugins: [...list, detected.pluginPath as string],\n });\n return { changed: true };\n }\n\n const list = settings.disabledMcpjsonServers ?? [];\n if (list.includes(SKAILE_MCP_NAME)) return { changed: false };\n await writeJson(settingsPath, {\n ...settings,\n disabledMcpjsonServers: [...list, SKAILE_MCP_NAME],\n });\n return { changed: true };\n}\n\n// ── status ─────────────────────────────────────────────────────────────────\n\nexport async function status(projectDir: string): Promise<HarnessStatus> {\n const settingsPath = path.join(projectDir, \".claude\", \"settings.json\");\n const mcpPath = mcpFilePath(projectDir);\n const dir = pluginDir(projectDir);\n const settings = await readJsonStrict<ClaudeSettings>(settingsPath);\n const mcp = await readJsonStrict<ClaudeMcpFile>(mcpPath);\n\n const pluginInstalled = !!(\n existsSync(path.join(dir, \".claude-plugin\", \"plugin.json\")) && settings?.plugins?.includes(dir)\n );\n const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);\n\n if (!pluginInstalled && !mcpInstalled) {\n return {\n harness: \"claude-code\",\n installed: \"no\",\n enabled: \"n/a\",\n method: \"—\",\n location: \"—\",\n };\n }\n\n if (pluginInstalled) {\n const disabled = settings?.disabledPlugins?.includes(dir) ?? false;\n // The plugin's skills are a copy; `add`, `remove`, `install` and `update` refresh it, but a\n // skill changed by hand since is not in it (p1350).\n const stale = await pluginSkillsStale(projectDir);\n return {\n harness: \"claude-code\",\n installed: \"yes\",\n enabled: disabled ? \"no\" : \"yes\",\n method: \"plugin\",\n location: path.relative(projectDir, dir),\n ...(stale\n ? {\n detail:\n \"the skills copy is stale: run skaile integration install --harness claude-code --full\",\n }\n : {}),\n };\n }\n\n const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;\n return {\n harness: \"claude-code\",\n installed: \"yes\",\n enabled: disabled ? \"no\" : \"yes\",\n method: \"mcp\",\n location: path.relative(projectDir, mcpPath),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../cli/src/commands/plugin/claude-code.ts"],"names":["disabled","next","updated","list"],"mappings":"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","file":"chunk-V5BPDB4J.js","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { buildClaudePluginFiles } from \"@skaile/workspaces/workspace-plugin\";\nimport type { HarnessStatus, InstallResult, ToggleResult, UninstallResult } from \"./types.ts\";\n\nconst SKAILE_MCP_NAME = \"skaile-workspace\";\n\nconst MCP_SERVER_ENTRY = {\n command: \"skaile\",\n args: [\"mcp-server\"],\n env: {} as Record<string, string>,\n};\n\ninterface ClaudeSettings {\n plugins?: string[];\n enabledPlugins?: string[];\n disabledPlugins?: string[];\n disabledMcpjsonServers?: string[];\n [k: string]: unknown;\n}\n\ninterface ClaudeMcpFile {\n mcpServers?: Record<string, unknown>;\n [k: string]: unknown;\n}\n\n/**\n * Project-scope MCP file. Claude Code reads `<project>/.mcp.json`; the\n * `.claude/mcp.json` that earlier versions wrote is never read (`claude mcp\n * list` reported \"No MCP servers configured\").\n */\nfunction mcpFilePath(projectDir: string): string {\n return path.join(projectDir, \".mcp.json\");\n}\n\n/** The dead `.claude/mcp.json` of earlier versions; entries in it are removed. */\nfunction legacyMcpFilePath(projectDir: string): string {\n return path.join(projectDir, \".claude\", \"mcp.json\");\n}\n\n/**\n * Drop the skaile entry from an MCP file, deleting the file when nothing is\n * left. Returns whether the file changed.\n */\nasync function removeSkaileMcpEntry(mcpPath: string): Promise<boolean> {\n const mcp = await readJsonStrict<ClaudeMcpFile>(mcpPath);\n if (!mcp?.mcpServers || !(SKAILE_MCP_NAME in mcp.mcpServers)) return false;\n const { [SKAILE_MCP_NAME]: _removed, ...rest } = mcp.mcpServers;\n const updated: ClaudeMcpFile = { ...mcp, mcpServers: rest };\n if (Object.keys(rest).length === 0) delete updated.mcpServers;\n if (Object.keys(updated).length === 0) await fs.unlink(mcpPath);\n else await writeJson(mcpPath, updated);\n return true;\n}\n\n/** Absolute path to the generated Claude Code plugin directory. */\nfunction pluginDir(projectDir: string): string {\n return path.join(projectDir, \".claude\", \"plugins\", \"skaile\");\n}\n\nasync function readJsonStrict<T>(p: string): Promise<T | null> {\n let raw: string;\n try {\n raw = await fs.readFile(p, \"utf-8\");\n } catch {\n return null;\n }\n try {\n return JSON.parse(raw) as T;\n } catch (e: unknown) {\n throw new Error(\n `cannot parse ${p}: ${e instanceof Error ? e.message : String(e)}; please fix or remove`,\n );\n }\n}\n\nasync function writeJson(p: string, value: unknown): Promise<void> {\n await fs.mkdir(path.dirname(p), { recursive: true });\n await fs.writeFile(p, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\n/** Skill folders that are never copied into the plugin: bytecode and dependency trees. */\nconst SKIPPED_IN_SKILL = new Set([\"__pycache__\", \"node_modules\", \".DS_Store\"]);\n\n/**\n * The project's installed skills, name to source folder: the folders with a `SKILL.md` that\n * `skaile add` deployed to `.claude/skills/`, and any under `.skaile/skills/` (the folder an\n * earlier release read; it wins over a deployed copy of the same name).\n */\nasync function installedSkillSources(projectDir: string): Promise<Map<string, string>> {\n const sources = new Map<string, string>();\n for (const root of [\n path.join(projectDir, \".claude\", \"skills\"),\n path.join(projectDir, \".skaile\", \"skills\"),\n ]) {\n for (const name of await fs.readdir(root).catch(() => [] as string[])) {\n const from = path.join(root, name);\n if (existsSync(path.join(from, \"SKILL.md\"))) sources.set(name, from);\n }\n }\n return sources;\n}\n\n/**\n * Fill the plugin's `skills/` with the project's installed skills (p1190). A skill the project\n * no longer has is removed from the plugin, so a repeated install matches the project. A linked\n * skill is copied as files.\n */\nasync function copyInstalledSkills(projectDir: string, skillsDir: string): Promise<void> {\n for (const entry of await fs.readdir(skillsDir).catch(() => [] as string[])) {\n if (entry !== \".gitkeep\")\n await fs.rm(path.join(skillsDir, entry), { recursive: true, force: true });\n }\n for (const [name, from] of await installedSkillSources(projectDir)) {\n await fs.cp(from, path.join(skillsDir, name), {\n recursive: true,\n dereference: true,\n filter: (src) => !SKIPPED_IN_SKILL.has(path.basename(src)),\n });\n }\n}\n\n/** Relative file path to content hash of everything the plugin copy would hold for `dir`. */\nasync function skillDigest(dir: string, rel = \"\"): Promise<string[]> {\n const out: string[] = [];\n for (const entry of (await fs.readdir(path.join(dir, rel)).catch(() => [] as string[])).sort()) {\n if (SKIPPED_IN_SKILL.has(entry)) continue;\n const relPath = path.join(rel, entry);\n const stat = await fs.stat(path.join(dir, relPath)).catch(() => undefined);\n if (!stat) continue;\n if (stat.isDirectory()) out.push(...(await skillDigest(dir, relPath)));\n else {\n const hash = createHash(\"sha256\")\n .update(await fs.readFile(path.join(dir, relPath)))\n .digest(\"hex\");\n out.push(`${relPath}:${hash}`);\n }\n }\n return out;\n}\n\n/**\n * True when the `--full` plugin's `skills/` copy differs from what `copyInstalledSkills` would\n * write now: a skill added, removed or changed since the copy was made (p1350).\n */\nasync function pluginSkillsStale(projectDir: string): Promise<boolean> {\n const skillsDir = path.join(pluginDir(projectDir), \"skills\");\n const expected = await installedSkillSources(projectDir);\n const actual = (await fs.readdir(skillsDir).catch(() => [] as string[])).filter(\n (n) => n !== \".gitkeep\",\n );\n if (actual.length !== expected.size || actual.some((n) => !expected.has(n))) return true;\n for (const [name, from] of expected) {\n const [want, have] = await Promise.all([\n skillDigest(from),\n skillDigest(path.join(skillsDir, name)),\n ]);\n if (want.join(\"\\n\") !== have.join(\"\\n\")) return true;\n }\n return false;\n}\n\n/**\n * Bring the `--full` plugin's skills copy up to date after `add`, `remove`, `install` or\n * `update` changed the project's skills (p1350). Does nothing when the plugin is not installed\n * (the MCP method has no copy) or the copy is current. Returns whether it rewrote the copy.\n */\nexport async function refreshPluginSkills(projectDir: string): Promise<boolean> {\n if ((await detectInstall(projectDir))?.method !== \"plugin\") return false;\n if (!(await pluginSkillsStale(projectDir))) return false;\n await copyInstalledSkills(projectDir, path.join(pluginDir(projectDir), \"skills\"));\n return true;\n}\n\n// ── install ────────────────────────────────────────────────────────────────\n\n/**\n * Install the skaile integration for Claude Code.\n *\n * Two modes:\n * - **mcp** (default) — write project-root `.mcp.json` pointing at `skaile mcp-server`.\n * - **full** (`opts.full`) — generate the `.claude/plugins/skaile/` directory\n * (MCP + lifecycle hooks) and register it in `.claude/settings.json`.\n */\nexport async function install(\n projectDir: string,\n opts?: { full?: boolean },\n): Promise<InstallResult> {\n return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);\n}\n\nasync function installMcp(projectDir: string): Promise<InstallResult> {\n const mcpPath = mcpFilePath(projectDir);\n const existing = (await readJsonStrict<ClaudeMcpFile>(mcpPath)) ?? {};\n const mcpServers = { ...(existing.mcpServers ?? {}) };\n const previous = mcpServers[SKAILE_MCP_NAME];\n const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);\n let warning: string | undefined;\n if (previous && !matches) {\n warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path.relative(projectDir, mcpPath)}`;\n }\n mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;\n await writeJson(mcpPath, { ...existing, mcpServers });\n const migrated = await removeSkaileMcpEntry(legacyMcpFilePath(projectDir));\n return { changed: !matches || migrated, method: \"mcp\", warning };\n}\n\n/**\n * Unlink `p` when it is a symlink (never what it points at), so the install below writes into\n * a real folder of its own instead of through the link into the user's files (`skills/ ->\n * ../../skills` would otherwise have its target cleared).\n */\nasync function dropSymlink(p: string): Promise<void> {\n const stat = await fs.lstat(p).catch(() => undefined);\n if (stat?.isSymbolicLink()) await fs.unlink(p);\n}\n\nasync function installFullPlugin(projectDir: string): Promise<InstallResult> {\n const dir = pluginDir(projectDir);\n await dropSymlink(dir);\n await dropSymlink(path.join(dir, \"skills\"));\n\n // Generate the plugin directory from the in-memory file map.\n for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {\n const dest = path.join(dir, rel);\n await fs.mkdir(path.dirname(dest), { recursive: true });\n await fs.writeFile(dest, content);\n }\n\n await copyInstalledSkills(projectDir, path.join(dir, \"skills\"));\n\n // Register the generated dir in .claude/settings.json#plugins[].\n const settingsPath = path.join(projectDir, \".claude\", \"settings.json\");\n const settings = (await readJsonStrict<ClaudeSettings>(settingsPath)) ?? {};\n const plugins = settings.plugins ?? [];\n if (!plugins.includes(dir)) plugins.push(dir);\n await writeJson(settingsPath, { ...settings, plugins });\n\n return { changed: true, method: \"plugin\" };\n}\n\n// ── uninstall ──────────────────────────────────────────────────────────────\n\nexport async function uninstall(projectDir: string): Promise<UninstallResult> {\n const settingsPath = path.join(projectDir, \".claude\", \"settings.json\");\n const mcpPath = mcpFilePath(projectDir);\n const dir = pluginDir(projectDir);\n const rel = (p: string): string => path.relative(projectDir, p);\n\n /** Project-relative paths the uninstall changed or deleted, in the order it touched them. */\n const files: string[] = [];\n\n // Remove the generated plugin dir from plugins[] if registered.\n const settings = await readJsonStrict<ClaudeSettings>(settingsPath);\n if (settings && Array.isArray(settings.plugins)) {\n const next = settings.plugins.filter((p) => p !== dir);\n if (next.length !== settings.plugins.length) {\n files.push(rel(settingsPath));\n const updated: ClaudeSettings = { ...settings, plugins: next };\n if (next.length === 0) delete updated.plugins;\n // A settings file that held only the skaile plugin is left empty: delete it.\n if (Object.keys(updated).length === 0) await fs.unlink(settingsPath);\n else await writeJson(settingsPath, updated);\n }\n }\n\n // Delete the generated plugin directory.\n if (existsSync(dir)) {\n await fs.rm(dir, { recursive: true, force: true });\n files.push(rel(dir));\n }\n\n // Remove from .mcp.json — and from the legacy .claude/mcp.json — if present.\n if (await removeSkaileMcpEntry(mcpPath)) files.push(rel(mcpPath));\n const legacyPath = legacyMcpFilePath(projectDir);\n if (await removeSkaileMcpEntry(legacyPath)) files.push(rel(legacyPath));\n\n // Leave no empty `.claude/` or `.claude/plugins/` behind.\n for (const emptyDir of [path.dirname(dir), path.join(projectDir, \".claude\")]) {\n await fs.rmdir(emptyDir).catch(() => undefined);\n }\n\n return { changed: files.length > 0, files };\n}\n\n// ── enable / disable ───────────────────────────────────────────────────────\n\nasync function detectInstall(\n projectDir: string,\n): Promise<{ method: \"plugin\" | \"mcp\"; pluginPath?: string } | null> {\n const dir = pluginDir(projectDir);\n const settings = await readJsonStrict<ClaudeSettings>(\n path.join(projectDir, \".claude\", \"settings.json\"),\n );\n if (\n existsSync(path.join(dir, \".claude-plugin\", \"plugin.json\")) &&\n settings?.plugins?.includes(dir)\n ) {\n return { method: \"plugin\", pluginPath: dir };\n }\n\n const mcp = await readJsonStrict<ClaudeMcpFile>(mcpFilePath(projectDir));\n if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {\n return { method: \"mcp\" };\n }\n return null;\n}\n\nexport async function enable(projectDir: string): Promise<ToggleResult> {\n const detected = await detectInstall(projectDir);\n if (!detected) throw new Error(\"plugin not installed for claude-code\");\n\n const settingsPath = path.join(projectDir, \".claude\", \"settings.json\");\n const settings = (await readJsonStrict<ClaudeSettings>(settingsPath)) ?? {};\n\n if (detected.method === \"plugin\") {\n const disabled = settings.disabledPlugins ?? [];\n const next = disabled.filter((p) => p !== detected.pluginPath);\n if (next.length === disabled.length) return { changed: false };\n const updated: ClaudeSettings = { ...settings, disabledPlugins: next };\n if (next.length === 0) delete updated.disabledPlugins;\n await writeJson(settingsPath, updated);\n return { changed: true };\n }\n\n const disabled = settings.disabledMcpjsonServers ?? [];\n const next = disabled.filter((n) => n !== SKAILE_MCP_NAME);\n if (next.length === disabled.length) return { changed: false };\n const updated: ClaudeSettings = { ...settings, disabledMcpjsonServers: next };\n if (next.length === 0) delete updated.disabledMcpjsonServers;\n await writeJson(settingsPath, updated);\n return { changed: true };\n}\n\nexport async function disable(projectDir: string): Promise<ToggleResult> {\n const detected = await detectInstall(projectDir);\n if (!detected) throw new Error(\"plugin not installed for claude-code\");\n\n const settingsPath = path.join(projectDir, \".claude\", \"settings.json\");\n const settings = (await readJsonStrict<ClaudeSettings>(settingsPath)) ?? {};\n\n if (detected.method === \"plugin\") {\n const list = settings.disabledPlugins ?? [];\n if (list.includes(detected.pluginPath as string)) return { changed: false };\n await writeJson(settingsPath, {\n ...settings,\n disabledPlugins: [...list, detected.pluginPath as string],\n });\n return { changed: true };\n }\n\n const list = settings.disabledMcpjsonServers ?? [];\n if (list.includes(SKAILE_MCP_NAME)) return { changed: false };\n await writeJson(settingsPath, {\n ...settings,\n disabledMcpjsonServers: [...list, SKAILE_MCP_NAME],\n });\n return { changed: true };\n}\n\n// ── status ─────────────────────────────────────────────────────────────────\n\nexport async function status(projectDir: string): Promise<HarnessStatus> {\n const settingsPath = path.join(projectDir, \".claude\", \"settings.json\");\n const mcpPath = mcpFilePath(projectDir);\n const dir = pluginDir(projectDir);\n const settings = await readJsonStrict<ClaudeSettings>(settingsPath);\n const mcp = await readJsonStrict<ClaudeMcpFile>(mcpPath);\n\n const pluginInstalled = !!(\n existsSync(path.join(dir, \".claude-plugin\", \"plugin.json\")) && settings?.plugins?.includes(dir)\n );\n const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);\n\n if (!pluginInstalled && !mcpInstalled) {\n return {\n harness: \"claude-code\",\n installed: \"no\",\n enabled: \"n/a\",\n method: \"—\",\n location: \"—\",\n };\n }\n\n if (pluginInstalled) {\n const disabled = settings?.disabledPlugins?.includes(dir) ?? false;\n // The plugin's skills are a copy; `add`, `remove`, `install` and `update` refresh it, but a\n // skill changed by hand since is not in it (p1350).\n const stale = await pluginSkillsStale(projectDir);\n return {\n harness: \"claude-code\",\n installed: \"yes\",\n enabled: disabled ? \"no\" : \"yes\",\n method: \"plugin\",\n location: path.relative(projectDir, dir),\n ...(stale\n ? {\n detail:\n \"the skills copy is stale: run skaile integration install --harness claude-code --full\",\n }\n : {}),\n };\n }\n\n const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;\n return {\n harness: \"claude-code\",\n installed: \"yes\",\n enabled: disabled ? \"no\" : \"yes\",\n method: \"mcp\",\n location: path.relative(projectDir, mcpPath),\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseCredentialRef } from './chunk-
|
|
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-
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
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,4 +1,4 @@
|
|
|
1
|
-
import { getStoreConfig, getStoreToken, storeFetch } from './chunk-
|
|
1
|
+
import { getStoreConfig, getStoreToken, storeFetch } from './chunk-AMJ6KEV7.js';
|
|
2
2
|
|
|
3
3
|
// cli/src/store-publisher.ts
|
|
4
4
|
function makeHttpPublisherClient(config = getStoreConfig(), timeoutMs = 2e4) {
|
|
@@ -25,5 +25,5 @@ function makeHttpPublisherClient(config = getStoreConfig(), timeoutMs = 2e4) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export { makeHttpPublisherClient };
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
28
|
+
//# sourceMappingURL=chunk-VUWRGMT6.js.map
|
|
29
|
+
//# sourceMappingURL=chunk-VUWRGMT6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cli/src/store-publisher.ts"],"names":[],"mappings":";;;AA+FO,SAAS,uBAAA,CACd,MAAA,GAAsB,cAAA,EAAe,EACrC,YAAY,GAAA,EACK;AAGjB,EAAA,MAAM,IAAA,GAAO,OACX,IAAA,EACA,IAAA,KACe;AACf,IAAA,MAAM,GAAA,GAAM,MAAM,aAAA,EAAc;AAChC,IAAA,OAAO,UAAA,CAAc,EAAE,GAAG,MAAA,EAAQ,GAAA,EAAI,EAAG,IAAA,EAAM,EAAE,SAAA,EAAW,GAAG,IAAA,EAAM,CAAA;AAAA,EACvE,CAAA;AACA,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,MAAM,IAAA,CAAK,YAAY,CAAA;AAAA,IAC3B,UAAA,EAAY,CAAC,IAAA,KAAS,IAAA,CAAK,mBAAmB,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,CAAA;AAAA,IACtE,WAAA,EAAa,MAAM,IAAA,CAAK,iBAAiB,CAAA;AAAA,IACzC,UAAA,EAAY,CAAC,EAAA,KAAO,IAAA,CAAK,CAAA,gBAAA,EAAmB,EAAE,CAAA,KAAA,CAAA,EAAS,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,IAAI,CAAA;AAAA,IACnF,QAAQ,CAAC,KAAA,KAAU,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAK,CAAA,CAAE,CAAA;AAAA,IAC/C,kBAAkB,CAAC,EAAA,KAAO,IAAA,CAAK,CAAA,gBAAA,EAAmB,EAAE,CAAA,WAAA,CAAa,CAAA;AAAA,IACjE,cAAc,CAAC,EAAA,KAAO,IAAA,CAAK,CAAA,eAAA,EAAkB,EAAE,CAAA,QAAA,CAAU,CAAA;AAAA,IACzD,YAAA,EAAc,CAAC,EAAA,EAAI,IAAA,EAAM,WACvB,IAAA,CAAK,CAAA,eAAA,EAAkB,EAAE,CAAA,QAAA,CAAA,EAAY;AAAA,MACnC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA;AAAA,MACA,GAAI,SAAS,EAAE,MAAA,EAAQ,EAAE,MAAA,EAAQ,GAAA,EAAI,EAAE,GAAI;AAAC,KAC7C,CAAA;AAAA,IACH,cAAA,EAAgB,CAAC,EAAA,KAAO,IAAA,CAAK,CAAA,eAAA,EAAkB,EAAE,CAAA,UAAA,CAAA,EAAc,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,IAAI,CAAA;AAAA,IAC3F,qBAAA,EAAuB,CAAC,EAAA,KACtB,IAAA,CAAK,sBAAsB,kBAAA,CAAmB,EAAE,CAAC,CAAA,aAAA,CAAe;AAAA,GACpE;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../cli/src/store-publisher.ts"],"names":[],"mappings":";;;AA+FO,SAAS,uBAAA,CACd,MAAA,GAAsB,cAAA,EAAe,EACrC,YAAY,GAAA,EACK;AAGjB,EAAA,MAAM,IAAA,GAAO,OACX,IAAA,EACA,IAAA,KACe;AACf,IAAA,MAAM,GAAA,GAAM,MAAM,aAAA,EAAc;AAChC,IAAA,OAAO,UAAA,CAAc,EAAE,GAAG,MAAA,EAAQ,GAAA,EAAI,EAAG,IAAA,EAAM,EAAE,SAAA,EAAW,GAAG,IAAA,EAAM,CAAA;AAAA,EACvE,CAAA;AACA,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,MAAM,IAAA,CAAK,YAAY,CAAA;AAAA,IAC3B,UAAA,EAAY,CAAC,IAAA,KAAS,IAAA,CAAK,mBAAmB,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,CAAA;AAAA,IACtE,WAAA,EAAa,MAAM,IAAA,CAAK,iBAAiB,CAAA;AAAA,IACzC,UAAA,EAAY,CAAC,EAAA,KAAO,IAAA,CAAK,CAAA,gBAAA,EAAmB,EAAE,CAAA,KAAA,CAAA,EAAS,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,IAAI,CAAA;AAAA,IACnF,QAAQ,CAAC,KAAA,KAAU,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAK,CAAA,CAAE,CAAA;AAAA,IAC/C,kBAAkB,CAAC,EAAA,KAAO,IAAA,CAAK,CAAA,gBAAA,EAAmB,EAAE,CAAA,WAAA,CAAa,CAAA;AAAA,IACjE,cAAc,CAAC,EAAA,KAAO,IAAA,CAAK,CAAA,eAAA,EAAkB,EAAE,CAAA,QAAA,CAAU,CAAA;AAAA,IACzD,YAAA,EAAc,CAAC,EAAA,EAAI,IAAA,EAAM,WACvB,IAAA,CAAK,CAAA,eAAA,EAAkB,EAAE,CAAA,QAAA,CAAA,EAAY;AAAA,MACnC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA;AAAA,MACA,GAAI,SAAS,EAAE,MAAA,EAAQ,EAAE,MAAA,EAAQ,GAAA,EAAI,EAAE,GAAI;AAAC,KAC7C,CAAA;AAAA,IACH,cAAA,EAAgB,CAAC,EAAA,KAAO,IAAA,CAAK,CAAA,eAAA,EAAkB,EAAE,CAAA,UAAA,CAAA,EAAc,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,IAAI,CAAA;AAAA,IAC3F,qBAAA,EAAuB,CAAC,EAAA,KACtB,IAAA,CAAK,sBAAsB,kBAAA,CAAmB,EAAE,CAAC,CAAA,aAAA,CAAe;AAAA,GACpE;AACF","file":"chunk-VUWRGMT6.js","sourcesContent":["/**\n * Typed REST client for the AI Asset Store **publisher** surface — the\n * curator-publish flow (`skaile source manifest publish` / `yank`). Thin\n * wrappers over {@link storeFetch}; every method maps 1:1 to an `/api/v1/…`\n * endpoint. The {@link PublisherClient} interface is injectable so the\n * orchestration in `commands/source-manifest-publish.ts` can be unit-tested\n * against a fake without a live store.\n *\n * @docLink cli/dev-guide#store-publisher\n */\n\nimport { getStoreConfig, getStoreToken, type StoreConfig, storeFetch } from \"./store-client.ts\";\n\n/**\n * The publisher REST surface used by the curator-publish flow. Kept minimal —\n * only the endpoints `runPublish` / `runYank` actually call. Response shapes\n * are narrowed to the fields the orchestration reads (the server returns more).\n */\nexport interface PublisherClient {\n /**\n * Identity of the caller. `username` is the Keycloak login (personal-tier\n * namespace); `githubLogin` is the verified GitHub handle when connected —\n * the namespace to publish under when it differs from the login.\n */\n me(): Promise<{ username: string; githubLogin?: string | null }>;\n /** Register (or re-register) a source; returns the created/existing row id. */\n sourcesAdd(body: {\n url: string;\n ref: string;\n sidecarUrl?: string;\n sidecarRef?: string;\n /**\n * Target publisher namespace (the manifest's `publisher`). When it differs\n * from the caller's login username, the store resolves the CLAIMED Publisher\n * for it (the store must already have the claim). Omitted → the store\n * defaults to `@<username>` (personal).\n */\n namespace?: string;\n }): Promise<{ id: string }>;\n /** List sources — used to recover an id when `sourcesAdd` rejects a dup url. */\n sourcesList(): Promise<Array<{ id: string; url: string }>>;\n /** Kick off a source sync; returns the async job id to poll. */\n sourceSync(id: string): Promise<{ jobId: string }>;\n /** Poll a job's terminal status + per-item results. */\n jobGet(\n jobId: string,\n ): Promise<{ status: string; items?: Array<{ label: string; status: string; error?: string }> }>;\n /** Discovered publishable candidates for a synced source. */\n sourceCandidates(id: string): Promise<\n Array<{\n id: string;\n name: string;\n version: string;\n kind: string;\n published: boolean;\n assetRoot: string;\n }>\n >;\n /** Per-asset preview — the discovered file set + resolved candidate metadata. */\n assetPreview(id: string): Promise<{\n discoveredFiles: string[];\n candidate: { name: string; version: string; kind: string; publisherNamespace: string };\n }>;\n /**\n * Publish one asset. `dryRun` returns the would-be `{ manifest }` without\n * launching a job; the normal path returns `{ jobId }`.\n */\n assetPublish(\n id: string,\n body: { ref: string; files: string[] },\n dryRun?: boolean,\n ): Promise<{ jobId?: string; manifest?: unknown }>;\n /** Retract a published asset. Response body is ignored. */\n assetUnpublish(id: string): Promise<unknown>;\n /**\n * Read-only \"can I publish under `@<ns>` right now, and if not, what's the\n * path?\" probe. Backs the `publish --dry-run` namespace status line; its\n * `message` is store-authored and meant to be surfaced verbatim.\n */\n namespaceAvailability(ns: string): Promise<{\n namespace: string;\n status: \"owned-by-you\" | \"claimable-by-you\" | \"reserved\" | \"available\";\n claimMethod?: string;\n message: string;\n }>;\n}\n\n/**\n * Construct the real HTTP-backed {@link PublisherClient}. Every call carries a\n * longer timeout than the default store client because publish/sync trigger\n * server-side clone work.\n *\n * @param config - Store connection config; defaults to {@link getStoreConfig}.\n * @param timeoutMs - Per-request abort timeout (default 20s).\n */\nexport function makeHttpPublisherClient(\n config: StoreConfig = getStoreConfig(),\n timeoutMs = 20_000,\n): PublisherClient {\n // Acquire a fresh Keycloak token per call (device-flow session in\n // ~/.skaile/auth.json, refreshed on demand) rather than a static config.jwt.\n const call = async <T>(\n path: string,\n opts?: { method?: string; body?: unknown; params?: Record<string, string> },\n ): Promise<T> => {\n const jwt = await getStoreToken();\n return storeFetch<T>({ ...config, jwt }, path, { timeoutMs, ...opts });\n };\n return {\n me: () => call(\"/api/v1/me\"),\n sourcesAdd: (body) => call(\"/api/v1/sources\", { method: \"POST\", body }),\n sourcesList: () => call(\"/api/v1/sources\"),\n sourceSync: (id) => call(`/api/v1/sources/${id}/sync`, { method: \"POST\", body: {} }),\n jobGet: (jobId) => call(`/api/v1/jobs/${jobId}`),\n sourceCandidates: (id) => call(`/api/v1/sources/${id}/candidates`),\n assetPreview: (id) => call(`/api/v1/assets/${id}/preview`),\n assetPublish: (id, body, dryRun) =>\n call(`/api/v1/assets/${id}/publish`, {\n method: \"POST\",\n body,\n ...(dryRun ? { params: { dryRun: \"1\" } } : {}),\n }),\n assetUnpublish: (id) => call(`/api/v1/assets/${id}/unpublish`, { method: \"POST\", body: {} }),\n namespaceAvailability: (ns) =>\n call(`/api/v1/namespaces/${encodeURIComponent(ns)}/availability`),\n };\n}\n"]}
|