@skaile/workspaces 5.19.0 → 6.1.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 +56 -0
- package/README.md +8 -8
- package/dist/app-sdk/index.js +1 -1
- package/dist/{asset-feeds-QGLI3AXI.js → asset-feeds-HJFV7UPW.js} +32 -24
- package/dist/asset-feeds-HJFV7UPW.js.map +1 -0
- package/dist/asset-manager/catalog-deployer.js +12 -12
- package/dist/asset-manager/index.js +19 -19
- package/dist/asset-manager/installer.js +14 -14
- package/dist/asset-manager/renderers.js +13 -13
- package/dist/asset-manager/src/index.d.ts +214 -27
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/install-agent.d.ts +2 -2
- package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
- package/dist/asset-manager/src/install-instances.d.ts +8 -8
- package/dist/asset-manager/src/install-instances.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts +34 -3
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/asset-manager/src/mcp-config.d.ts +35 -14
- package/dist/asset-manager/src/mcp-config.d.ts.map +1 -1
- package/dist/asset-manager/src/renderers.d.ts +12 -12
- package/dist/asset-manager/src/renderers.d.ts.map +1 -1
- package/dist/bridge/codex-app-server.js +2 -2
- package/dist/bridge/harnesses/claude-sdk.d.ts +2 -0
- package/dist/bridge/{drivers → harnesses}/claude-sdk.js +69 -73
- package/dist/bridge/harnesses/claude-sdk.js.map +1 -0
- package/dist/bridge/{drivers/gemini.d.ts → harnesses/codex.d.ts} +1 -1
- package/dist/bridge/{drivers → harnesses}/codex.js +53 -53
- package/dist/bridge/harnesses/codex.js.map +1 -0
- package/dist/bridge/{drivers/claude-sdk.d.ts → harnesses/continue.d.ts} +1 -1
- package/dist/bridge/{drivers → harnesses}/continue.js +30 -30
- package/dist/bridge/harnesses/continue.js.map +1 -0
- package/dist/bridge/{drivers → harnesses}/echo.d.ts +1 -1
- package/dist/bridge/{drivers → harnesses}/echo.js +27 -27
- package/dist/bridge/harnesses/echo.js.map +1 -0
- package/dist/bridge/{drivers/continue.d.ts → harnesses/gemini.d.ts} +1 -1
- package/dist/bridge/harnesses/gemini.js +18 -0
- package/dist/bridge/{drivers → harnesses}/goose.d.ts +1 -1
- package/dist/bridge/{drivers → harnesses}/goose.js +30 -30
- package/dist/bridge/harnesses/goose.js.map +1 -0
- package/dist/bridge/{drivers → harnesses}/omp.d.ts +1 -1
- package/dist/bridge/{drivers → harnesses}/omp.js +31 -31
- package/dist/bridge/harnesses/omp.js.map +1 -0
- package/dist/bridge/{drivers → harnesses}/opencode.d.ts +1 -1
- package/dist/bridge/{drivers → harnesses}/opencode.js +31 -31
- package/dist/bridge/harnesses/opencode.js.map +1 -0
- package/dist/bridge/{drivers → harnesses}/qwen.d.ts +1 -1
- package/dist/bridge/{drivers → harnesses}/qwen.js +20 -20
- package/dist/bridge/harnesses/qwen.js.map +1 -0
- package/dist/bridge/index.js +25 -25
- package/dist/bridge/src/agent-exec.d.ts +2 -2
- package/dist/bridge/src/agent-transcript.d.ts +1 -1
- package/dist/bridge/src/agent-transcript.d.ts.map +1 -1
- package/dist/bridge/src/approval-card.d.ts +3 -3
- package/dist/bridge/src/capability-dispatch.d.ts +5 -5
- package/dist/bridge/src/claude-sdk-surface.d.ts +17 -0
- package/dist/bridge/src/claude-sdk-surface.d.ts.map +1 -0
- package/dist/bridge/src/cloud.d.ts +4 -4
- package/dist/bridge/src/codex/config-toml.d.ts +3 -3
- package/dist/bridge/src/codex/friendly-error.d.ts +1 -1
- package/dist/bridge/src/codex/friendly-error.d.ts.map +1 -1
- package/dist/bridge/src/codex/{managed-driver.d.ts → managed-harness.d.ts} +5 -5
- package/dist/bridge/src/codex/managed-harness.d.ts.map +1 -0
- package/dist/bridge/src/codex/native-approvals.d.ts +1 -1
- package/dist/bridge/src/codex/native-approvals.d.ts.map +1 -1
- package/dist/bridge/src/error-classifier.d.ts +7 -7
- package/dist/bridge/src/{driver-capabilities.d.ts → harness-capabilities.d.ts} +18 -18
- package/dist/bridge/src/harness-capabilities.d.ts.map +1 -0
- package/dist/bridge/src/harness-model-check.d.ts +40 -0
- package/dist/bridge/src/harness-model-check.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/_subprocess-cli.d.ts +8 -8
- package/dist/bridge/src/harnesses/_subprocess-cli.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/claude-context-usage.d.ts +5 -5
- package/dist/bridge/src/harnesses/claude-context-usage.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/claude-sdk.d.ts +27 -27
- package/dist/bridge/src/harnesses/claude-sdk.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/claude-self-turns.d.ts +5 -5
- package/dist/bridge/src/harnesses/claude-self-turns.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/claude-tool-allowlist.d.ts +4 -4
- package/dist/bridge/src/harnesses/claude-tool-allowlist.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/codex.d.ts +14 -14
- package/dist/bridge/src/harnesses/codex.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/continue.d.ts +12 -12
- package/dist/bridge/src/harnesses/continue.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/echo.d.ts +16 -16
- package/dist/bridge/src/harnesses/echo.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/flow-script.d.ts +9 -9
- package/dist/bridge/src/harnesses/flow-script.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/gemini.d.ts +15 -15
- package/dist/bridge/src/harnesses/gemini.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/goose.d.ts +10 -10
- package/dist/bridge/src/harnesses/goose.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/omp-models-yml.d.ts +12 -12
- package/dist/bridge/src/harnesses/omp-models-yml.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/omp.d.ts +23 -23
- package/dist/bridge/src/harnesses/omp.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/opencode.d.ts +11 -11
- package/dist/bridge/src/harnesses/opencode.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/qwen.d.ts +12 -12
- package/dist/bridge/src/harnesses/qwen.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/recovery-policy.d.ts +4 -4
- package/dist/bridge/src/harnesses/recovery-policy.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/resume-probe.d.ts +3 -3
- package/dist/bridge/src/harnesses/resume-probe.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/sanitize-assistant-text.d.ts +1 -1
- package/dist/bridge/src/harnesses/sanitize-assistant-text.d.ts.map +1 -0
- package/dist/bridge/src/{drivers → harnesses}/scrub-transcript.d.ts +1 -1
- package/dist/bridge/src/harnesses/scrub-transcript.d.ts.map +1 -0
- package/dist/bridge/src/index.d.ts +5 -4
- package/dist/bridge/src/index.d.ts.map +1 -1
- package/dist/bridge/src/logger.d.ts +4 -4
- package/dist/bridge/src/models.d.ts +1 -1
- package/dist/bridge/src/normalizer.d.ts +5 -3
- package/dist/bridge/src/normalizer.d.ts.map +1 -1
- package/dist/bridge/src/provider-materialize/continue-config-yaml.d.ts +5 -5
- package/dist/bridge/src/provider-materialize/continue-config-yaml.d.ts.map +1 -1
- package/dist/bridge/src/provider-materialize/credential-env.d.ts +3 -3
- package/dist/bridge/src/provider-materialize/{env-drivers.d.ts → env-harnesses.d.ts} +19 -19
- package/dist/bridge/src/provider-materialize/env-harnesses.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/goose-custom-providers.d.ts +5 -5
- package/dist/bridge/src/provider-materialize/goose-custom-providers.d.ts.map +1 -1
- package/dist/bridge/src/provider-materialize/opencode-config.d.ts +7 -7
- package/dist/bridge/src/provider-materialize/opencode-config.d.ts.map +1 -1
- package/dist/bridge/src/provider-materialize/session-config-home.d.ts +5 -5
- package/dist/bridge/src/provider-materialize/session-config-home.d.ts.map +1 -1
- package/dist/bridge/src/provider-registry-derive.d.ts +4 -4
- package/dist/bridge/src/provider-registry-derive.d.ts.map +1 -1
- package/dist/bridge/src/reconfigure-ledger.d.ts +8 -8
- package/dist/bridge/src/reconfigure-ledger.d.ts.map +1 -1
- package/dist/bridge/src/registry.d.ts +34 -41
- package/dist/bridge/src/registry.d.ts.map +1 -1
- package/dist/bridge/src/runner-private-env.d.ts +2 -2
- package/dist/bridge/src/runtime.d.ts +11 -11
- package/dist/bridge/src/runtime.d.ts.map +1 -1
- package/dist/bridge/src/types.d.ts +158 -158
- package/dist/bridge/src/types.d.ts.map +1 -1
- package/dist/{chunk-7NT4F6SR.js → chunk-2LAPHLDH.js} +587 -521
- package/dist/chunk-2LAPHLDH.js.map +1 -0
- package/dist/{chunk-25ZVWL2R.js → chunk-3GMOPFWH.js} +4 -4
- package/dist/{chunk-25ZVWL2R.js.map → chunk-3GMOPFWH.js.map} +1 -1
- package/dist/{chunk-X5YPJV4N.js → chunk-3MWQKQUB.js} +2 -2
- package/dist/{chunk-X5YPJV4N.js.map → chunk-3MWQKQUB.js.map} +1 -1
- package/dist/{chunk-EPBKISS5.js → chunk-3TG2NV2F.js} +2 -2
- package/dist/chunk-3TG2NV2F.js.map +1 -0
- package/dist/{chunk-L2AMXONH.js → chunk-3X7VTCPG.js} +2 -2
- package/dist/chunk-3X7VTCPG.js.map +1 -0
- package/dist/{chunk-VIM3PWZM.js → chunk-4FVIT5DI.js} +3 -3
- package/dist/{chunk-VIM3PWZM.js.map → chunk-4FVIT5DI.js.map} +1 -1
- package/dist/{chunk-IF6IA3PZ.js → chunk-4MUDQCBP.js} +4 -4
- package/dist/{chunk-IF6IA3PZ.js.map → chunk-4MUDQCBP.js.map} +1 -1
- package/dist/{chunk-MKRWN7XP.js → chunk-5J4NPGFM.js} +5 -5
- package/dist/chunk-5J4NPGFM.js.map +1 -0
- package/dist/{chunk-5TBFN46Z.js → chunk-5KRMNUL4.js} +4 -4
- package/dist/chunk-5KRMNUL4.js.map +1 -0
- package/dist/{chunk-7SCS64BG.js → chunk-5Y2KGB4H.js} +109 -74
- package/dist/chunk-5Y2KGB4H.js.map +1 -0
- package/dist/{chunk-YIF2IJUA.js → chunk-6GWSDPBP.js} +3 -3
- package/dist/{chunk-YIF2IJUA.js.map → chunk-6GWSDPBP.js.map} +1 -1
- package/dist/{chunk-WST6UITC.js → chunk-6YR4ALVX.js} +17 -17
- package/dist/chunk-6YR4ALVX.js.map +1 -0
- package/dist/{chunk-YROR332M.js → chunk-7DN6JKP2.js} +2 -2
- package/dist/chunk-7DN6JKP2.js.map +1 -0
- package/dist/{chunk-IZCR27MU.js → chunk-7EKQDY2T.js} +3 -3
- package/dist/chunk-7EKQDY2T.js.map +1 -0
- package/dist/chunk-7HX6FNKL.js +317 -0
- package/dist/chunk-7HX6FNKL.js.map +1 -0
- package/dist/{chunk-COJIL7G4.js → chunk-7LP7RCZI.js} +7 -7
- package/dist/chunk-7LP7RCZI.js.map +1 -0
- package/dist/{chunk-2PBSAH3Z.js → chunk-AATHJRKL.js} +4 -4
- package/dist/{chunk-2PBSAH3Z.js.map → chunk-AATHJRKL.js.map} +1 -1
- package/dist/{chunk-C7WBGSBV.js → chunk-ABFPSVIS.js} +10 -10
- package/dist/chunk-ABFPSVIS.js.map +1 -0
- package/dist/{chunk-ICSCSM5D.js → chunk-ADPM6AYF.js} +3 -3
- package/dist/{chunk-ICSCSM5D.js.map → chunk-ADPM6AYF.js.map} +1 -1
- package/dist/{chunk-WOIRYY5L.js → chunk-AITJ7ELM.js} +141 -27
- package/dist/chunk-AITJ7ELM.js.map +1 -0
- package/dist/{chunk-HU5HVKY7.js → chunk-ASWTQQ7E.js} +4 -4
- package/dist/{chunk-HU5HVKY7.js.map → chunk-ASWTQQ7E.js.map} +1 -1
- package/dist/{chunk-RO6VOM6Z.js → chunk-AZ2H6R5I.js} +51 -25
- package/dist/chunk-AZ2H6R5I.js.map +1 -0
- package/dist/{chunk-I7TWVK6N.js → chunk-BBBCJSSU.js} +4 -4
- package/dist/{chunk-I7TWVK6N.js.map → chunk-BBBCJSSU.js.map} +1 -1
- package/dist/{chunk-AJ7EGIFR.js → chunk-BIRW3HOG.js} +3 -3
- package/dist/chunk-BIRW3HOG.js.map +1 -0
- package/dist/{chunk-FPHNJE4M.js → chunk-CEKW3KXP.js} +91 -30
- package/dist/chunk-CEKW3KXP.js.map +1 -0
- package/dist/{chunk-F6AA42GW.js → chunk-COYF6IG2.js} +5 -5
- package/dist/{chunk-F6AA42GW.js.map → chunk-COYF6IG2.js.map} +1 -1
- package/dist/{chunk-HT35SQZD.js → chunk-DGTI65OC.js} +30 -30
- package/dist/chunk-DGTI65OC.js.map +1 -0
- package/dist/{chunk-W4Q6CKJ5.js → chunk-DIGFA7Z5.js} +11 -11
- package/dist/chunk-DIGFA7Z5.js.map +1 -0
- package/dist/{chunk-335ENCCS.js → chunk-E572OHGY.js} +2 -2
- package/dist/{chunk-335ENCCS.js.map → chunk-E572OHGY.js.map} +1 -1
- package/dist/{chunk-Y5MBW5EU.js → chunk-EJPMNDTP.js} +3 -3
- package/dist/{chunk-Y5MBW5EU.js.map → chunk-EJPMNDTP.js.map} +1 -1
- package/dist/chunk-EX3GLAL6.js +31 -0
- package/dist/chunk-EX3GLAL6.js.map +1 -0
- package/dist/{chunk-XWOPZW26.js → chunk-FKQNBCDW.js} +38 -38
- package/dist/chunk-FKQNBCDW.js.map +1 -0
- package/dist/{chunk-6E6PKKAD.js → chunk-G5SUWZEU.js} +18 -8
- package/dist/chunk-G5SUWZEU.js.map +1 -0
- package/dist/{chunk-2GXSSZAM.js → chunk-GNZBFSRB.js} +12 -12
- package/dist/chunk-GNZBFSRB.js.map +1 -0
- package/dist/{chunk-PYJS5K7V.js → chunk-HMISULVD.js} +5 -5
- package/dist/{chunk-PYJS5K7V.js.map → chunk-HMISULVD.js.map} +1 -1
- package/dist/{chunk-IP2IPMEH.js → chunk-HPMQRAIF.js} +18 -18
- package/dist/chunk-HPMQRAIF.js.map +1 -0
- package/dist/{chunk-MRHVPQNO.js → chunk-HWNK3F3X.js} +1015 -189
- package/dist/chunk-HWNK3F3X.js.map +1 -0
- package/dist/{chunk-ZQSOJH6I.js → chunk-IHFGPHCT.js} +141 -341
- package/dist/chunk-IHFGPHCT.js.map +1 -0
- package/dist/{chunk-CQJH4G2K.js → chunk-ILLTBKDJ.js} +101 -102
- package/dist/chunk-ILLTBKDJ.js.map +1 -0
- package/dist/{chunk-FKU57Q5Q.js → chunk-IRYKRKVQ.js} +3 -3
- package/dist/{chunk-FKU57Q5Q.js.map → chunk-IRYKRKVQ.js.map} +1 -1
- package/dist/{chunk-J24CY3PF.js → chunk-J72MO2WA.js} +39 -39
- package/dist/chunk-J72MO2WA.js.map +1 -0
- package/dist/{chunk-Y56YIT6J.js → chunk-JCPD4QRM.js} +4 -4
- package/dist/chunk-JCPD4QRM.js.map +1 -0
- package/dist/{chunk-X3RMRJNR.js → chunk-JRN5QF4C.js} +8 -3
- package/dist/chunk-JRN5QF4C.js.map +1 -0
- package/dist/{chunk-K4O6L3WH.js → chunk-KNY356I3.js} +3 -3
- package/dist/{chunk-K4O6L3WH.js.map → chunk-KNY356I3.js.map} +1 -1
- package/dist/{chunk-XJVBUDDJ.js → chunk-KUQAJVYT.js} +8 -8
- package/dist/chunk-KUQAJVYT.js.map +1 -0
- package/dist/{chunk-4ZTPYIBE.js → chunk-KW37WNXY.js} +12 -12
- package/dist/chunk-KW37WNXY.js.map +1 -0
- package/dist/{chunk-MJHSLODD.js → chunk-LSI2IVFT.js} +2 -2
- package/dist/chunk-LSI2IVFT.js.map +1 -0
- package/dist/{chunk-WDXZA7QW.js → chunk-LSSYC5IC.js} +2 -2
- package/dist/{chunk-WDXZA7QW.js.map → chunk-LSSYC5IC.js.map} +1 -1
- package/dist/{chunk-WG6V4ISA.js → chunk-NB7SYQYP.js} +7 -7
- package/dist/{chunk-WG6V4ISA.js.map → chunk-NB7SYQYP.js.map} +1 -1
- package/dist/{chunk-EAZECHPM.js → chunk-NBAGV6L2.js} +5 -5
- package/dist/chunk-NBAGV6L2.js.map +1 -0
- package/dist/{chunk-JTOWA6RS.js → chunk-NUA33BYO.js} +181 -64
- package/dist/chunk-NUA33BYO.js.map +1 -0
- package/dist/{chunk-A6SMCEEE.js → chunk-QAKUD6QN.js} +11 -11
- package/dist/{chunk-A6SMCEEE.js.map → chunk-QAKUD6QN.js.map} +1 -1
- package/dist/{chunk-QG6GHTRM.js → chunk-QEULL4Q3.js} +8 -8
- package/dist/chunk-QEULL4Q3.js.map +1 -0
- package/dist/{chunk-ZX4KRWRB.js → chunk-QSYQOTWN.js} +4 -4
- package/dist/{chunk-ZX4KRWRB.js.map → chunk-QSYQOTWN.js.map} +1 -1
- package/dist/{chunk-X4ZZTHU3.js → chunk-RDTLPOPD.js} +4 -4
- package/dist/{chunk-X4ZZTHU3.js.map → chunk-RDTLPOPD.js.map} +1 -1
- package/dist/{chunk-GOCWM7FN.js → chunk-RHN5MRQO.js} +21 -4
- package/dist/chunk-RHN5MRQO.js.map +1 -0
- package/dist/{chunk-XM6T2AZ2.js → chunk-S2XHGWQC.js} +162 -124
- package/dist/chunk-S2XHGWQC.js.map +1 -0
- package/dist/{chunk-VJ7NU7GD.js → chunk-SVTMNSPI.js} +23 -6
- package/dist/chunk-SVTMNSPI.js.map +1 -0
- package/dist/{chunk-I37INEWE.js → chunk-UI745XC3.js} +10 -23
- package/dist/chunk-UI745XC3.js.map +1 -0
- package/dist/{chunk-N46LQR46.js → chunk-VMVDAZLA.js} +53 -30
- package/dist/chunk-VMVDAZLA.js.map +1 -0
- package/dist/{chunk-IG5LZ3WU.js → chunk-VTETQCR6.js} +10 -10
- package/dist/chunk-VTETQCR6.js.map +1 -0
- package/dist/{chunk-EFLKSMCO.js → chunk-VUJXZDCY.js} +5 -5
- package/dist/{chunk-EFLKSMCO.js.map → chunk-VUJXZDCY.js.map} +1 -1
- package/dist/{chunk-H6UVIKQ2.js → chunk-VYVTEMAW.js} +3 -3
- package/dist/{chunk-H6UVIKQ2.js.map → chunk-VYVTEMAW.js.map} +1 -1
- package/dist/{chunk-M3WPBTGJ.js → chunk-WD3L5QSU.js} +2 -2
- package/dist/{chunk-M3WPBTGJ.js.map → chunk-WD3L5QSU.js.map} +1 -1
- package/dist/{chunk-R6O6YWU7.js → chunk-WYZXSJBK.js} +3 -3
- package/dist/{chunk-R6O6YWU7.js.map → chunk-WYZXSJBK.js.map} +1 -1
- package/dist/{chunk-R4I3VBSS.js → chunk-X3YGUKCG.js} +5 -5
- package/dist/{chunk-R4I3VBSS.js.map → chunk-X3YGUKCG.js.map} +1 -1
- package/dist/{chunk-RPZVHXQ3.js → chunk-XFIEVEU7.js} +4 -4
- package/dist/chunk-XFIEVEU7.js.map +1 -0
- package/dist/{chunk-VSZWNUZC.js → chunk-XGULGQA3.js} +4 -4
- package/dist/chunk-XGULGQA3.js.map +1 -0
- package/dist/{chunk-Q6E6FM7P.js → chunk-XKNXPLKR.js} +6 -6
- package/dist/{chunk-Q6E6FM7P.js.map → chunk-XKNXPLKR.js.map} +1 -1
- package/dist/{chunk-7XSAW5OC.js → chunk-YLLVSR2U.js} +4 -4
- package/dist/{chunk-7XSAW5OC.js.map → chunk-YLLVSR2U.js.map} +1 -1
- package/dist/{chunk-6Z5KTFJT.js → chunk-Z3VKUWAX.js} +3 -3
- package/dist/{chunk-6Z5KTFJT.js.map → chunk-Z3VKUWAX.js.map} +1 -1
- package/dist/{chunk-5BEFNLOR.js → chunk-Z7ZEZZB6.js} +8 -8
- package/dist/chunk-Z7ZEZZB6.js.map +1 -0
- package/dist/{chunk-2LSDMJI2.js → chunk-ZAELRYKS.js} +4 -4
- package/dist/{chunk-2LSDMJI2.js.map → chunk-ZAELRYKS.js.map} +1 -1
- package/dist/{chunk-UQ33Y4DM.js → chunk-ZBHZLWV3.js} +4 -4
- package/dist/{chunk-UQ33Y4DM.js.map → chunk-ZBHZLWV3.js.map} +1 -1
- package/dist/{chunk-TIIXG3PN.js → chunk-ZDLUQLI6.js} +4 -4
- package/dist/{chunk-TIIXG3PN.js.map → chunk-ZDLUQLI6.js.map} +1 -1
- package/dist/{chunk-PHRNUTSG.js → chunk-ZFUZ5AKM.js} +4 -4
- package/dist/{chunk-PHRNUTSG.js.map → chunk-ZFUZ5AKM.js.map} +1 -1
- package/dist/{chunk-V257LUBM.js → chunk-ZHGKAZJ7.js} +251 -26
- package/dist/chunk-ZHGKAZJ7.js.map +1 -0
- package/dist/claude-code-RE46FJXI.js +10 -0
- package/dist/{claude-code-2PU7TITZ.js.map → claude-code-RE46FJXI.js.map} +1 -1
- package/dist/cli/index.js +1066 -647
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/agent-pins.d.ts +11 -0
- package/dist/cli/src/agent-pins.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +4 -4
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/complete-resolvers.d.ts.map +1 -1
- package/dist/cli/src/commands/config.d.ts +2 -2
- 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 +24 -0
- package/dist/cli/src/commands/harness.d.ts.map +1 -0
- package/dist/cli/src/commands/integration.d.ts +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 +20 -2
- package/dist/cli/src/commands/library-index.d.ts.map +1 -1
- package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-files.d.ts +14 -0
- package/dist/cli/src/commands/migrate-files.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-harness.d.ts +49 -0
- package/dist/cli/src/commands/migrate-harness.d.ts.map +1 -0
- package/dist/cli/src/commands/migrate.d.ts +4 -2
- package/dist/cli/src/commands/migrate.d.ts.map +1 -1
- package/dist/cli/src/commands/plugin/types.d.ts +1 -6
- package/dist/cli/src/commands/plugin/types.d.ts.map +1 -1
- package/dist/cli/src/commands/plugin-registry-cmd.d.ts +1 -1
- package/dist/cli/src/commands/preset-export.d.ts +1 -1
- package/dist/cli/src/commands/project.d.ts +20 -2
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/run.d.ts +2 -2
- package/dist/cli/src/commands/run.d.ts.map +1 -1
- package/dist/cli/src/commands/serve-preflight.d.ts +11 -11
- package/dist/cli/src/commands/serve-preflight.d.ts.map +1 -1
- package/dist/cli/src/commands/serve.d.ts +1 -1
- package/dist/cli/src/commands/serve.d.ts.map +1 -1
- package/dist/cli/src/commands/session-logs/local-query.d.ts +2 -0
- package/dist/cli/src/commands/session-logs/local-query.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts +9 -2
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/store.d.ts.map +1 -1
- package/dist/cli/src/commands/update.d.ts.map +1 -1
- package/dist/cli/src/commands/validate.d.ts.map +1 -1
- package/dist/cli/src/config-checks.d.ts +37 -0
- package/dist/cli/src/config-checks.d.ts.map +1 -0
- package/dist/cli/src/harness-error.d.ts +47 -0
- package/dist/cli/src/harness-error.d.ts.map +1 -0
- package/dist/cli/src/helpers.d.ts +5 -5
- package/dist/cli/src/helpers.d.ts.map +1 -1
- package/dist/cli/src/plugin-store/index.d.ts +2 -2
- package/dist/cli/src/setup.d.ts +3 -3
- package/dist/cli/src/setup.d.ts.map +1 -1
- package/dist/cli/src/skill-checks.d.ts +27 -0
- package/dist/cli/src/skill-checks.d.ts.map +1 -1
- package/dist/cli/src/store-addable.d.ts +11 -0
- package/dist/cli/src/store-addable.d.ts.map +1 -1
- package/dist/connectors/config.js +6 -6
- package/dist/connectors/index.js +31 -31
- package/dist/connectors/src/connector-prompt.d.ts +5 -5
- package/dist/connectors/src/connector-registry.d.ts +1 -1
- package/dist/connectors-7THEF7YA.js +48 -0
- package/dist/{connectors-RBGZ3M7G.js.map → connectors-7THEF7YA.js.map} +1 -1
- package/dist/connectors-shared/index.js +2 -2
- package/dist/core/framework.js +1 -1
- package/dist/{bridge/drivers/codex.d.ts → core/harness-targets.d.ts} +1 -1
- package/dist/core/harness-targets.js +4 -0
- package/dist/core/harness-targets.js.map +1 -0
- package/dist/core/index.js +11 -11
- 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 +6 -6
- package/dist/core/src/agent-instances.d.ts.map +1 -1
- package/dist/core/src/asset-roots.d.ts +2 -2
- package/dist/core/src/config-key-diagnostics.d.ts +9 -0
- package/dist/core/src/config-key-diagnostics.d.ts.map +1 -0
- package/dist/core/src/framework.d.ts +21 -21
- package/dist/core/src/framework.d.ts.map +1 -1
- package/dist/core/src/{driver-sdk.d.ts → harness-sdk.d.ts} +9 -9
- package/dist/core/src/harness-sdk.d.ts.map +1 -0
- package/dist/core/src/harness-targets.d.ts +71 -0
- package/dist/core/src/harness-targets.d.ts.map +1 -0
- package/dist/core/src/index.d.ts +8 -8
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +10 -0
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +8 -0
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/provider-registry.d.ts +2 -2
- package/dist/core/src/settings.d.ts +17 -16
- package/dist/core/src/settings.d.ts.map +1 -1
- package/dist/core/src/store.d.ts +12 -12
- package/dist/core/src/store.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +39 -21
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/src/workspace-yaml-editor.d.ts +10 -3
- package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
- package/dist/core/store.js +2 -2
- package/dist/core/workspace-config.js +5 -5
- package/dist/deploy/index.js +12 -12
- package/dist/discovery/index.js +5 -5
- package/dist/discovery/src/builtin-providers.d.ts.map +1 -1
- package/dist/discovery/src/parse-manifest.d.ts.map +1 -1
- package/dist/{ensure-sources-GKVLE6L5.js → ensure-sources-IH7CHSJF.js} +22 -22
- package/dist/{ensure-sources-GKVLE6L5.js.map → ensure-sources-IH7CHSJF.js.map} +1 -1
- package/dist/factory-assets/connectors/box.js +31 -31
- package/dist/factory-assets/connectors/deploy.js +31 -31
- package/dist/factory-assets/connectors/devserver.js +31 -31
- package/dist/factory-assets/connectors/flow/CONNECTOR.md +5 -5
- package/dist/factory-assets/connectors/flow/adapter.d.ts +3 -3
- package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/adapter.js +31 -31
- package/dist/factory-assets/connectors/flow/contract/normalize.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/contract.js +1 -1
- package/dist/factory-assets/connectors/flow/engine/types.d.ts +1 -1
- package/dist/factory-assets/connectors/flow/engine.js +13 -13
- package/dist/factory-assets/connectors/flow/inline-sub-flow-host.d.ts +2 -2
- package/dist/factory-assets/connectors/flow/inline-sub-flow-host.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/orchestrator-turn.d.ts +4 -4
- package/dist/factory-assets/connectors/flow/orchestrator-turn.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/prompt-fragments.d.ts +1 -1
- package/dist/factory-assets/connectors/flow/prompt-fragments.js +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.d.ts +12 -12
- package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.js +33 -33
- package/dist/factory-assets/connectors/flow/sub-flow-runner.d.ts +1 -1
- package/dist/factory-assets/connectors/flow/sub-flow-runner.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/subprompt-runner.d.ts +22 -22
- package/dist/factory-assets/connectors/flow/subprompt-runner.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow.js +31 -31
- package/dist/factory-assets/connectors/git.js +31 -31
- package/dist/factory-assets/connectors/gmail.js +31 -31
- package/dist/factory-assets/connectors/googledrive.js +31 -31
- package/dist/factory-assets/connectors/local.js +31 -31
- package/dist/factory-assets/connectors/mattermost.js +31 -31
- package/dist/factory-assets/connectors/memory.js +31 -31
- package/dist/factory-assets/connectors/minio.js +31 -31
- package/dist/factory-assets/connectors/postgres.js +31 -31
- package/dist/factory-assets/connectors/s3.js +31 -31
- package/dist/factory-assets/connectors/sharepoint.js +31 -31
- package/dist/factory-assets/connectors/sqlite.js +31 -31
- package/dist/factory-assets/connectors/static-server.js +31 -31
- package/dist/factory-assets/connectors/tunnel.js +31 -31
- package/dist/factory-assets/connectors/webdav.js +31 -31
- package/dist/factory-assets/connectors/xstate-store.js +31 -31
- package/dist/factory-assets/connectors/xstate.js +31 -31
- package/dist/factory-assets/skills/authoring-skaile-assets/SKILL.md +1 -1
- package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +2 -2
- package/dist/factory-assets/skills/authoring-skaile-manifests/references/dependency-standard.md +3 -3
- package/dist/factory-assets/skills/skaile-manage-workspace/SKILL.md +1 -1
- package/dist/flows-4JZQ3XFK.js +26 -0
- package/dist/{flows-W2FB7WIM.js.map → flows-4JZQ3XFK.js.map} +1 -1
- package/dist/{helpers-34QNVIGB.js → helpers-JNMK3FC2.js} +22 -22
- package/dist/{helpers-34QNVIGB.js.map → helpers-JNMK3FC2.js.map} +1 -1
- package/dist/library/index.js +15 -15
- package/dist/library/install.js +4 -4
- package/dist/library/src/index.d.ts +1 -1
- package/dist/library/src/index.d.ts.map +1 -1
- package/dist/library/src/local/library-dir.d.ts +22 -5
- package/dist/library/src/local/library-dir.d.ts.map +1 -1
- package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
- package/dist/library/src/remote/remote-catalog-source.d.ts +6 -0
- package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
- package/dist/{library-publish-RUQTKTJU.js → library-publish-I3UWXAHI.js} +69 -67
- package/dist/library-publish-I3UWXAHI.js.map +1 -0
- package/dist/model-endpoint/index.js +15 -15
- package/dist/model-endpoint/src/resolve.d.ts +1 -1
- package/dist/open-library-NKKUJLWA.js +42 -0
- package/dist/{open-library-PVTIUQUF.js.map → open-library-NKKUJLWA.js.map} +1 -1
- package/dist/open-registry-BYAXSHUI.js +32 -0
- package/dist/{open-registry-SOIS3TA2.js.map → open-registry-BYAXSHUI.js.map} +1 -1
- package/dist/paths-UKWE35XS.js +22 -0
- package/dist/{paths-JLNX7Y4X.js.map → paths-UKWE35XS.js.map} +1 -1
- package/dist/plugin-registry/index.js +1 -1
- package/dist/plugin-registry/src/context.d.ts +3 -3
- package/dist/plugin-registry/src/context.d.ts.map +1 -1
- package/dist/plugin-registry/src/deploy-handle.d.ts +1 -1
- package/dist/plugin-registry/src/index.d.ts +2 -2
- package/dist/plugin-registry/src/index.d.ts.map +1 -1
- package/dist/plugin-registry/src/internal.d.ts.map +1 -1
- package/dist/plugin-registry/src/registry.d.ts +3 -3
- package/dist/plugin-registry/src/registry.d.ts.map +1 -1
- package/dist/plugin-registry/src/targets.d.ts +9 -9
- package/dist/plugin-registry/src/targets.d.ts.map +1 -1
- package/dist/plugin-store-ABE35NRX.js +23 -0
- package/dist/{plugin-store-G2GWAHSD.js.map → plugin-store-ABE35NRX.js.map} +1 -1
- package/dist/plugins/src/asset-kind-provider.d.ts +1 -1
- package/dist/project-BIPK47JK.js +86 -0
- package/dist/{project-EX47PUBN.js.map → project-BIPK47JK.js.map} +1 -1
- package/dist/resolver/index.js +12 -12
- package/dist/runner/index.js +50 -50
- package/dist/runner/src/agent.d.ts +3 -3
- package/dist/runner/src/agent.d.ts.map +1 -1
- package/dist/runner/src/agents/in-process-host.d.ts +1 -1
- package/dist/runner/src/agents/instances.d.ts +1 -1
- package/dist/runner/src/agents/instances.d.ts.map +1 -1
- package/dist/runner/src/agents/run-controller.d.ts +7 -7
- package/dist/runner/src/agents/run-controller.d.ts.map +1 -1
- package/dist/runner/src/agents/standalone-surface.d.ts +2 -2
- package/dist/runner/src/agents/standalone-surface.d.ts.map +1 -1
- package/dist/runner/src/ai-provider-switch.d.ts +7 -7
- package/dist/runner/src/assistant-home.d.ts +1 -1
- package/dist/runner/src/capability-registry.d.ts +2 -2
- package/dist/runner/src/coalesced-restart.d.ts +2 -2
- package/dist/runner/src/compaction/context-window.d.ts +8 -8
- package/dist/runner/src/compaction/context-window.d.ts.map +1 -1
- package/dist/runner/src/compaction/orchestrator.d.ts +24 -24
- package/dist/runner/src/compaction/orchestrator.d.ts.map +1 -1
- package/dist/runner/src/compaction-gate.d.ts +30 -30
- package/dist/runner/src/compaction-gate.d.ts.map +1 -1
- package/dist/runner/src/composition/content-source.d.ts.map +1 -1
- package/dist/runner/src/composition/dry-run.d.ts +2 -2
- package/dist/runner/src/composition/dry-run.d.ts.map +1 -1
- package/dist/runner/src/composition/errors.d.ts +16 -1
- package/dist/runner/src/composition/errors.d.ts.map +1 -1
- package/dist/runner/src/composition/resolve-instance.d.ts +2 -2
- package/dist/runner/src/composition/resolve.d.ts +1 -1
- package/dist/runner/src/config.d.ts +3 -3
- package/dist/runner/src/config.d.ts.map +1 -1
- package/dist/runner/src/context-usage/collector.d.ts +15 -15
- package/dist/runner/src/context-usage/collector.d.ts.map +1 -1
- package/dist/runner/src/context-usage/compose.d.ts +6 -6
- package/dist/runner/src/context-usage/compose.d.ts.map +1 -1
- package/dist/runner/src/context-usage/estimator.d.ts +1 -1
- package/dist/runner/src/context-usage/index.d.ts +1 -1
- package/dist/runner/src/context-usage/index.d.ts.map +1 -1
- package/dist/runner/src/context-usage/transcript-tracker.d.ts +2 -2
- package/dist/runner/src/context-usage/transcript-tracker.d.ts.map +1 -1
- package/dist/runner/src/credential-notice.d.ts +4 -4
- package/dist/runner/src/credential-notice.d.ts.map +1 -1
- package/dist/runner/src/credential-rotated.d.ts +1 -1
- package/dist/runner/src/final-text.d.ts +1 -1
- package/dist/runner/src/{driver-swap-gate.d.ts → harness-swap-gate.d.ts} +21 -21
- package/dist/runner/src/harness-swap-gate.d.ts.map +1 -0
- package/dist/runner/src/late-mcp-rebuild.d.ts +6 -6
- package/dist/runner/src/late-mcp-rebuild.d.ts.map +1 -1
- package/dist/runner/src/lifecycle-handler.d.ts +1 -1
- package/dist/runner/src/lifecycle-handler.d.ts.map +1 -1
- package/dist/runner/src/manifest.d.ts +1 -1
- package/dist/runner/src/mcp-runtime-handlers.d.ts +6 -6
- package/dist/runner/src/mcp-runtime-handlers.d.ts.map +1 -1
- package/dist/runner/src/model-endpoint-discovery.d.ts +1 -1
- package/dist/runner/src/pending-turns.d.ts +3 -3
- package/dist/runner/src/platform-blocks.d.ts +5 -5
- package/dist/runner/src/platform-blocks.d.ts.map +1 -1
- package/dist/runner/src/prompt-turn-queue.d.ts +1 -1
- package/dist/runner/src/provider-quota-forwarder.d.ts +1 -1
- package/dist/runner/src/provider-quota-forwarder.d.ts.map +1 -1
- package/dist/runner/src/reconfigure-handler.d.ts +14 -14
- package/dist/runner/src/reconfigure-handler.d.ts.map +1 -1
- package/dist/runner/src/resource-handler.d.ts +1 -1
- package/dist/runner/src/resources.d.ts +5 -5
- package/dist/runner/src/resources.d.ts.map +1 -1
- package/dist/runner/src/runner-capabilities.d.ts +7 -7
- package/dist/runner/src/runtime-session-emit.d.ts +5 -5
- package/dist/runner/src/runtime-session-emit.d.ts.map +1 -1
- package/dist/runner/src/s3-presign-client.d.ts +1 -1
- package/dist/runner/src/serve-credentials.d.ts +7 -7
- package/dist/runner/src/serve-credentials.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts +46 -34
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts +41 -41
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/runner/src/session-capability-wiring.d.ts +9 -9
- package/dist/runner/src/session-capability-wiring.d.ts.map +1 -1
- package/dist/runner/src/session-stimulus.d.ts +1 -1
- package/dist/runner/src/session.d.ts +5 -5
- package/dist/runner/src/session.d.ts.map +1 -1
- package/dist/runner/src/skill-staging.d.ts +16 -16
- package/dist/runner/src/skill-staging.d.ts.map +1 -1
- package/dist/runner/src/turn-end-contract.d.ts +5 -5
- package/dist/runner/src/turn-end-contract.d.ts.map +1 -1
- package/dist/runner/src/turn-scheduler.d.ts +22 -22
- package/dist/runner/src/turn-scheduler.d.ts.map +1 -1
- package/dist/runner/src/turn-status-replay.d.ts +1 -1
- package/dist/runner/src/usage-limit-turn-hold.d.ts +1 -1
- package/dist/sdk/asset-manager.js +19 -19
- package/dist/sdk/bridge.js +25 -25
- package/dist/sdk/core.js +11 -11
- package/dist/sdk/flow.js +13 -13
- package/dist/sdk/index.js +54 -54
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.js +12 -12
- package/dist/sdk/runner.js +50 -50
- package/dist/sdk/session.js +2 -2
- package/dist/sdk/src/agent-session.d.ts +1 -1
- package/dist/sdk/src/local-runtime.d.ts +1 -1
- package/dist/sdk/src/local-runtime.d.ts.map +1 -1
- package/dist/sdk/src/types.d.ts +1 -1
- package/dist/sdk/src/types.d.ts.map +1 -1
- package/dist/sdk/store.js +2 -2
- package/dist/sdk/transport/ws/server.js +12 -12
- package/dist/sdk/transport/ws.js +12 -12
- package/dist/sdk/transport.js +12 -12
- package/dist/sdk/types.js +1 -1
- package/dist/serve-preflight-FLTIBTEX.js +107 -0
- package/dist/serve-preflight-FLTIBTEX.js.map +1 -0
- package/dist/session/index.js +2 -2
- package/dist/session/src/dispatcher.d.ts +2 -2
- package/dist/sessions-2Q7SSYPT.js +5 -0
- package/dist/{sessions-DICDEONJ.js.map → sessions-2Q7SSYPT.js.map} +1 -1
- package/dist/{setup-AFZQNGKA.js → setup-AG6NFHSN.js} +52 -52
- package/dist/setup-AG6NFHSN.js.map +1 -0
- package/dist/skills-UQYUHVKO.js +26 -0
- package/dist/{skills-YYYC6D5X.js.map → skills-UQYUHVKO.js.map} +1 -1
- package/dist/source-ASEHI2XS.js +85 -0
- package/dist/{source-DGPCT5IC.js.map → source-ASEHI2XS.js.map} +1 -1
- package/dist/{source-manifest-publish-AGJ63JF2.js → source-manifest-publish-IEVV3W6J.js} +62 -62
- package/dist/{source-manifest-publish-AGJ63JF2.js.map → source-manifest-publish-IEVV3W6J.js.map} +1 -1
- package/dist/store/index.js +2 -2
- package/dist/store/src/store.d.ts +3 -3
- package/dist/store/src/store.d.ts.map +1 -1
- package/dist/transport/index.js +12 -12
- package/dist/transport/ws/server.js +12 -12
- package/dist/transport/ws.js +12 -12
- package/dist/tui/index.js +70 -70
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/src/repl-session.d.ts +5 -5
- package/dist/tui/src/repl.d.ts +5 -5
- package/dist/tui/src/repl.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/manifests.js +1 -1
- package/dist/types/src/agent-lifecycle.d.ts +1 -1
- package/dist/types/src/agent-lifecycle.d.ts.map +1 -1
- package/dist/types/src/ask-slots.d.ts +1 -1
- package/dist/types/src/capabilities.d.ts +1 -1
- package/dist/types/src/context-usage.d.ts +22 -22
- package/dist/types/src/context-usage.d.ts.map +1 -1
- package/dist/types/src/events.d.ts +49 -49
- package/dist/types/src/events.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/install-manifest.d.ts +1 -1
- package/dist/types/src/install-manifest.d.ts.map +1 -1
- package/dist/types/src/lifecycle.d.ts +6 -6
- package/dist/types/src/lifecycle.d.ts.map +1 -1
- package/dist/types/src/logging.d.ts +1 -1
- package/dist/types/src/manifests/agent.d.ts +3 -3
- package/dist/types/src/protocol.d.ts +4 -4
- package/dist/types/src/runtime.d.ts +38 -38
- package/dist/types/src/runtime.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +22 -11
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/validator-DRHMJ457.js +5 -0
- package/dist/{validator-FA2PFW6N.js.map → validator-DRHMJ457.js.map} +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +41 -41
- package/dist/workspace-plugin/adapters/omp.js +26 -26
- package/dist/workspace-plugin/adapters/omp.js.map +1 -1
- package/dist/workspace-plugin/index.js +3 -3
- package/dist/workspace-plugin/src/plugin.d.ts +5 -5
- package/dist/workspace-plugin/src/plugin.d.ts.map +1 -1
- package/dist/workspace-plugin/src/tools/flows.d.ts +1 -1
- package/dist/workspace-plugin/src/tools/validator.d.ts +6 -6
- package/dist/workspace-plugin/src/tools/validator.d.ts.map +1 -1
- package/dist/workspace-plugin/src/types.d.ts +2 -2
- package/dist/workspace-plugin/src/types.d.ts.map +1 -1
- package/package.json +59 -59
- package/dist/asset-feeds-QGLI3AXI.js.map +0 -1
- package/dist/bridge/drivers/claude-sdk.js.map +0 -1
- package/dist/bridge/drivers/codex.js.map +0 -1
- package/dist/bridge/drivers/continue.js.map +0 -1
- package/dist/bridge/drivers/echo.js.map +0 -1
- package/dist/bridge/drivers/gemini.js +0 -18
- package/dist/bridge/drivers/goose.js.map +0 -1
- package/dist/bridge/drivers/omp.js.map +0 -1
- package/dist/bridge/drivers/opencode.js.map +0 -1
- package/dist/bridge/drivers/qwen.js.map +0 -1
- package/dist/bridge/src/codex/managed-driver.d.ts.map +0 -1
- package/dist/bridge/src/driver-capabilities.d.ts.map +0 -1
- package/dist/bridge/src/driver-model-check.d.ts +0 -25
- package/dist/bridge/src/driver-model-check.d.ts.map +0 -1
- package/dist/bridge/src/drivers/_subprocess-cli.d.ts.map +0 -1
- package/dist/bridge/src/drivers/claude-context-usage.d.ts.map +0 -1
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +0 -1
- package/dist/bridge/src/drivers/claude-self-turns.d.ts.map +0 -1
- package/dist/bridge/src/drivers/claude-tool-allowlist.d.ts.map +0 -1
- package/dist/bridge/src/drivers/codex.d.ts.map +0 -1
- package/dist/bridge/src/drivers/continue.d.ts.map +0 -1
- package/dist/bridge/src/drivers/echo.d.ts.map +0 -1
- package/dist/bridge/src/drivers/flow-script.d.ts.map +0 -1
- package/dist/bridge/src/drivers/gemini.d.ts.map +0 -1
- package/dist/bridge/src/drivers/goose.d.ts.map +0 -1
- package/dist/bridge/src/drivers/omp-models-yml.d.ts.map +0 -1
- package/dist/bridge/src/drivers/omp.d.ts.map +0 -1
- package/dist/bridge/src/drivers/opencode.d.ts.map +0 -1
- package/dist/bridge/src/drivers/qwen.d.ts.map +0 -1
- package/dist/bridge/src/drivers/recovery-policy.d.ts.map +0 -1
- package/dist/bridge/src/drivers/resume-probe.d.ts.map +0 -1
- package/dist/bridge/src/drivers/sanitize-assistant-text.d.ts.map +0 -1
- package/dist/bridge/src/drivers/scrub-transcript.d.ts.map +0 -1
- package/dist/bridge/src/provider-materialize/env-drivers.d.ts.map +0 -1
- package/dist/chunk-2GXSSZAM.js.map +0 -1
- package/dist/chunk-4ZTPYIBE.js.map +0 -1
- package/dist/chunk-5BEFNLOR.js.map +0 -1
- package/dist/chunk-5TBFN46Z.js.map +0 -1
- package/dist/chunk-6E6PKKAD.js.map +0 -1
- package/dist/chunk-7NT4F6SR.js.map +0 -1
- package/dist/chunk-7SCS64BG.js.map +0 -1
- package/dist/chunk-AJ7EGIFR.js.map +0 -1
- package/dist/chunk-C7WBGSBV.js.map +0 -1
- package/dist/chunk-COJIL7G4.js.map +0 -1
- package/dist/chunk-CQJH4G2K.js.map +0 -1
- package/dist/chunk-EAZECHPM.js.map +0 -1
- package/dist/chunk-EPBKISS5.js.map +0 -1
- package/dist/chunk-FPHNJE4M.js.map +0 -1
- package/dist/chunk-GOCWM7FN.js.map +0 -1
- package/dist/chunk-HT35SQZD.js.map +0 -1
- package/dist/chunk-I37INEWE.js.map +0 -1
- package/dist/chunk-IG5LZ3WU.js.map +0 -1
- package/dist/chunk-IP2IPMEH.js.map +0 -1
- package/dist/chunk-IZCR27MU.js.map +0 -1
- package/dist/chunk-J24CY3PF.js.map +0 -1
- package/dist/chunk-JTOWA6RS.js.map +0 -1
- package/dist/chunk-L2AMXONH.js.map +0 -1
- package/dist/chunk-MJHSLODD.js.map +0 -1
- package/dist/chunk-MKRWN7XP.js.map +0 -1
- package/dist/chunk-MRHVPQNO.js.map +0 -1
- package/dist/chunk-N46LQR46.js.map +0 -1
- package/dist/chunk-PUK7TQT4.js +0 -13
- package/dist/chunk-PUK7TQT4.js.map +0 -1
- package/dist/chunk-QG6GHTRM.js.map +0 -1
- package/dist/chunk-RO6VOM6Z.js.map +0 -1
- package/dist/chunk-RPZVHXQ3.js.map +0 -1
- package/dist/chunk-V257LUBM.js.map +0 -1
- package/dist/chunk-VJ7NU7GD.js.map +0 -1
- package/dist/chunk-VSZWNUZC.js.map +0 -1
- package/dist/chunk-W4Q6CKJ5.js.map +0 -1
- package/dist/chunk-WOIRYY5L.js.map +0 -1
- package/dist/chunk-WST6UITC.js.map +0 -1
- package/dist/chunk-X3RMRJNR.js.map +0 -1
- package/dist/chunk-XJVBUDDJ.js.map +0 -1
- package/dist/chunk-XM6T2AZ2.js.map +0 -1
- package/dist/chunk-XWOPZW26.js.map +0 -1
- package/dist/chunk-Y56YIT6J.js.map +0 -1
- package/dist/chunk-YROR332M.js.map +0 -1
- package/dist/chunk-ZQSOJH6I.js.map +0 -1
- package/dist/claude-code-2PU7TITZ.js +0 -10
- package/dist/cli/src/driver-error.d.ts +0 -28
- package/dist/cli/src/driver-error.d.ts.map +0 -1
- package/dist/connectors-RBGZ3M7G.js +0 -48
- package/dist/core/driver-targets.d.ts +0 -2
- package/dist/core/driver-targets.js +0 -4
- package/dist/core/driver-targets.js.map +0 -1
- package/dist/core/src/driver-sdk.d.ts.map +0 -1
- package/dist/core/src/driver-targets.d.ts +0 -71
- package/dist/core/src/driver-targets.d.ts.map +0 -1
- package/dist/flows-W2FB7WIM.js +0 -26
- package/dist/library-publish-RUQTKTJU.js.map +0 -1
- package/dist/open-library-PVTIUQUF.js +0 -42
- package/dist/open-registry-SOIS3TA2.js +0 -32
- package/dist/paths-JLNX7Y4X.js +0 -22
- package/dist/plugin-store-G2GWAHSD.js +0 -23
- package/dist/project-EX47PUBN.js +0 -84
- package/dist/runner/src/driver-swap-gate.d.ts.map +0 -1
- package/dist/serve-preflight-QXRKGOI5.js +0 -108
- package/dist/serve-preflight-QXRKGOI5.js.map +0 -1
- package/dist/sessions-DICDEONJ.js +0 -5
- package/dist/setup-AFZQNGKA.js.map +0 -1
- package/dist/skills-YYYC6D5X.js +0 -26
- package/dist/source-DGPCT5IC.js +0 -85
- package/dist/validator-FA2PFW6N.js +0 -5
- /package/dist/bridge/{drivers → harnesses}/gemini.js.map +0 -0
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import { unregisteredLibraryNames, renamedLibraryName, resolveConfig, RemoteCatalogSource, OfflineError, describeCatalogError, CatalogHttpError, scanUnlistedAssets, missingRootAssets, storeManifestFile, missingLibraryDirMessage, filesEntryPaths } from './chunk-
|
|
2
|
-
import { SEMVER_RE, invalidSemverMessage, flowFileNameError, readManifestSourceConfig, discoverAssetsInTree, isManifestMode } from './chunk-
|
|
3
|
-
import { parseFlowDefinition } from './chunk-
|
|
4
|
-
import { installTargetOf, readKeptLegacyCopies, writeKeptLegacyCopies, canonicalEntryRef, diffDeployedAgent, deployedAssetDrift, assertNoLibrarySymlinks, deployAll, removeAsset, createScaffold, installAgent } from './chunk-
|
|
1
|
+
import { unregisteredLibraryNames, renamedLibraryName, resolveConfig, RemoteCatalogSource, OfflineError, describeCatalogError, CatalogHttpError, scanUnlistedAssets, missingRootAssets, storeManifestFile, missingLibraryDirMessage, filesEntryPaths, lastLibraryName } from './chunk-S2XHGWQC.js';
|
|
2
|
+
import { SEMVER_RE, invalidSemverMessage, flowFileNameError, computeDeterministicHash, readManifestSourceConfig, discoverAssetsInTree, isManifestMode } from './chunk-UI745XC3.js';
|
|
3
|
+
import { parseFlowDefinition } from './chunk-JRN5QF4C.js';
|
|
4
|
+
import { installTargetOf, readKeptLegacyCopies, writeKeptLegacyCopies, canonicalEntryRef, diffDeployedAgent, deployedAssetDrift, assertNoLibrarySymlinks, deployAll, removeAsset, sourceComposedFiles, cachedComposedFiles, createScaffold, installAgent } from './chunk-NUA33BYO.js';
|
|
5
5
|
import { appendHistory, getRecentHistory, clearHistory } from './chunk-KTBKW2FI.js';
|
|
6
6
|
import { commitChanges } from './chunk-UQ6LFBPZ.js';
|
|
7
|
-
import {
|
|
8
|
-
import { isScaffoldBody, isScaffoldDescription } from './chunk-
|
|
9
|
-
import {
|
|
10
|
-
import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-
|
|
11
|
-
import { deployedBase, isDeployed, deployedPaths, deployedDir } from './chunk-
|
|
12
|
-
import { resolveSkWorkspaceConfig, effectiveAgentInstances, loadMcpServerDeclarations, resolveGlobalHarnesses, resolveGlobalSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, matchPin, buildProvenanceIndex, coerceVersion, sourceShortName, readLinks, isCommitOnRemote, resolveAll, agentSourceCacheDir, ensureRepo, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus,
|
|
7
|
+
import { harnessTargetSupportsAgents, CODEX_IDENTITY_DIR } from './chunk-ABFPSVIS.js';
|
|
8
|
+
import { isScaffoldBody, isScaffoldDescription } from './chunk-E572OHGY.js';
|
|
9
|
+
import { resolveConfiguredHarnessName, GLOBAL_INSTALL_DIR_NAME, resolveLibraryDir, buildLibraryLockEntries, writeLock, computeHash, buildLockFile, readLock, assertLockHashes, verifyLock, mergeLockFile, resyncLockSources, extractForPatch, generatePatch, savePatch, applyPatch, LOCK_SCHEMA_VERSION } from './chunk-VMVDAZLA.js';
|
|
10
|
+
import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-ZDLUQLI6.js';
|
|
11
|
+
import { deployedBase, isDeployed, deployedPaths, deployedDir } from './chunk-5KRMNUL4.js';
|
|
12
|
+
import { resolveSkWorkspaceConfig, effectiveAgentInstances, mcpDeclarationFromMdContent, loadMcpServerDeclarations, resolveGlobalHarnesses, resolveGlobalSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, matchPin, buildProvenanceIndex, coerceVersion, sourceShortName, readLinks, isCommitOnRemote, findWorkspaceRoot, resolveAll, agentSourceCacheDir, ensureRepo, resolveAgentDefinitionDir, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus, resolveAsset, MAX_PRESET_DEPTH, PresetDepthError, DEFAULT_AGENT_INSTANCE_ID } from './chunk-ZHGKAZJ7.js';
|
|
13
13
|
import { globalSkaileDir, globalCacheRoot, migrateLegacyDir } from './chunk-L5VSIPQD.js';
|
|
14
|
-
import {
|
|
15
|
-
import { loadSkPublishManifest,
|
|
16
|
-
import { scanDirectory, parseFrontmatter, parseRequires, dedupeRequirements, readAssetBody } from './chunk-
|
|
17
|
-
import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName, depToStr, parseDep } from './chunk-
|
|
14
|
+
import { HARNESS_TARGETS, SUPPORTED_HARNESSES } from './chunk-VTETQCR6.js';
|
|
15
|
+
import { listAssetFiles, loadSkPublishManifest, decodeSkaileManifest, isNonAssetDir, isNonAssetFile } from './chunk-ZBHZLWV3.js';
|
|
16
|
+
import { scanDirectory, parseFrontmatter, parseRequires, dedupeRequirements, readAssetBody } from './chunk-RHN5MRQO.js';
|
|
17
|
+
import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName, depToStr, parseDep } from './chunk-LSSYC5IC.js';
|
|
18
18
|
import { spawnSync } from 'child_process';
|
|
19
|
-
import { existsSync, rmSync, readFileSync, readdirSync, lstatSync,
|
|
19
|
+
import { existsSync, rmSync, readFileSync, writeFileSync, readdirSync, lstatSync, statSync, unlinkSync, mkdirSync } from 'fs';
|
|
20
|
+
import { homedir } from 'os';
|
|
20
21
|
import path, { resolve, dirname, sep, join, relative, posix } from 'path';
|
|
21
22
|
import { gt } from 'semver';
|
|
22
23
|
import { parse, stringify } from 'yaml';
|
|
@@ -40,8 +41,8 @@ function writeLedger(projectDir, ledger) {
|
|
|
40
41
|
writeFileSync(p, `${JSON.stringify(ledger, null, 2)}
|
|
41
42
|
`, "utf-8");
|
|
42
43
|
}
|
|
43
|
-
function renderedInstanceFiles(projectDir,
|
|
44
|
-
const recorded = readLedger(projectDir).targets[
|
|
44
|
+
function renderedInstanceFiles(projectDir, harness) {
|
|
45
|
+
const recorded = readLedger(projectDir).targets[harness];
|
|
45
46
|
if (!recorded) return [];
|
|
46
47
|
let instances;
|
|
47
48
|
try {
|
|
@@ -51,11 +52,11 @@ function renderedInstanceFiles(projectDir, driverTarget) {
|
|
|
51
52
|
}
|
|
52
53
|
return Object.entries(instances).filter(([id]) => recorded[id]?.length).map(([id, instance]) => ({ id, ref: instance.ref, files: recorded[id] }));
|
|
53
54
|
}
|
|
54
|
-
function instanceRenderedAgentNames(projectDir,
|
|
55
|
+
function instanceRenderedAgentNames(projectDir, harness) {
|
|
55
56
|
const names = /* @__PURE__ */ new Set();
|
|
56
|
-
if (!
|
|
57
|
-
const agentDir = resolve(deployedBase("agent",
|
|
58
|
-
for (const files of Object.values(readLedger(projectDir).targets[
|
|
57
|
+
if (!harnessTargetSupportsAgents(harness)) return names;
|
|
58
|
+
const agentDir = resolve(deployedBase("agent", harness, false, projectDir));
|
|
59
|
+
for (const files of Object.values(readLedger(projectDir).targets[harness] ?? {})) {
|
|
59
60
|
for (const rel of files) {
|
|
60
61
|
const abs = resolve(projectDir, rel);
|
|
61
62
|
if (!abs.startsWith(agentDir + sep)) continue;
|
|
@@ -80,8 +81,8 @@ function bindInstance(projectDir, id, instance) {
|
|
|
80
81
|
}
|
|
81
82
|
return { srcDir, errors };
|
|
82
83
|
}
|
|
83
|
-
function unboundAgentInstances(projectDir,
|
|
84
|
-
if (!
|
|
84
|
+
function unboundAgentInstances(projectDir, harness) {
|
|
85
|
+
if (!harnessTargetSupportsAgents(harness)) return [];
|
|
85
86
|
let instances;
|
|
86
87
|
try {
|
|
87
88
|
instances = effectiveAgentInstances(resolveSkWorkspaceConfig(projectDir));
|
|
@@ -96,16 +97,16 @@ function unboundAgentInstances(projectDir, driverTarget) {
|
|
|
96
97
|
return out;
|
|
97
98
|
}
|
|
98
99
|
function removeAgentInstanceRenderings(opts) {
|
|
99
|
-
const { projectDir,
|
|
100
|
-
if (!
|
|
100
|
+
const { projectDir, harness, ids } = opts;
|
|
101
|
+
if (!harnessTargetSupportsAgents(harness) || ids.length === 0) return [];
|
|
101
102
|
const ledger = readLedger(projectDir);
|
|
102
|
-
const previous = ledger.targets[
|
|
103
|
+
const previous = ledger.targets[harness];
|
|
103
104
|
if (!previous) return [];
|
|
104
105
|
const gone = new Set(ids);
|
|
105
106
|
const claimed = new Set(
|
|
106
107
|
Object.entries(previous).filter(([id]) => !gone.has(id)).flatMap(([, files]) => files)
|
|
107
108
|
);
|
|
108
|
-
const agentDeployDir = deployedBase("agent",
|
|
109
|
+
const agentDeployDir = deployedBase("agent", harness, false, projectDir);
|
|
109
110
|
const removable = [resolve(agentDeployDir), resolve(dirname(agentDeployDir), CODEX_IDENTITY_DIR)];
|
|
110
111
|
const root = resolve(projectDir);
|
|
111
112
|
const removed = [];
|
|
@@ -120,28 +121,28 @@ function removeAgentInstanceRenderings(opts) {
|
|
|
120
121
|
}
|
|
121
122
|
const owned = Object.fromEntries(Object.entries(previous).filter(([id]) => !gone.has(id)));
|
|
122
123
|
const nextTargets = { ...ledger.targets };
|
|
123
|
-
if (Object.keys(owned).length > 0) nextTargets[
|
|
124
|
-
else delete nextTargets[
|
|
124
|
+
if (Object.keys(owned).length > 0) nextTargets[harness] = owned;
|
|
125
|
+
else delete nextTargets[harness];
|
|
125
126
|
if (JSON.stringify(nextTargets) !== JSON.stringify(ledger.targets)) {
|
|
126
127
|
writeLedger(projectDir, { version: 1, targets: nextTargets });
|
|
127
128
|
}
|
|
128
129
|
return removed;
|
|
129
130
|
}
|
|
130
131
|
function installAgentInstances(opts) {
|
|
131
|
-
const { projectDir,
|
|
132
|
+
const { projectDir, harness, log } = opts;
|
|
132
133
|
const result = {
|
|
133
134
|
instances: [],
|
|
134
135
|
removed: [],
|
|
135
136
|
warnings: [],
|
|
136
137
|
errors: []
|
|
137
138
|
};
|
|
138
|
-
if (!
|
|
139
|
+
if (!harnessTargetSupportsAgents(harness)) return result;
|
|
139
140
|
const wsConfig = opts.wsConfig ?? resolveSkWorkspaceConfig(projectDir);
|
|
140
141
|
const instances = effectiveAgentInstances(wsConfig);
|
|
141
|
-
const agentDeployDir = deployedBase("agent",
|
|
142
|
-
const skillsRelDir =
|
|
142
|
+
const agentDeployDir = deployedBase("agent", harness, false, projectDir);
|
|
143
|
+
const skillsRelDir = HARNESS_TARGETS[harness]?.local.skill ?? "";
|
|
143
144
|
const ledger = readLedger(projectDir);
|
|
144
|
-
const previous = ledger.targets[
|
|
145
|
+
const previous = ledger.targets[harness] ?? {};
|
|
145
146
|
const owned = {};
|
|
146
147
|
for (const [id, instance] of Object.entries(instances)) {
|
|
147
148
|
const { srcDir, errors } = bindInstance(projectDir, id, instance);
|
|
@@ -154,7 +155,7 @@ function installAgentInstances(opts) {
|
|
|
154
155
|
srcDir,
|
|
155
156
|
agentDeployDir,
|
|
156
157
|
projectDir,
|
|
157
|
-
|
|
158
|
+
harness,
|
|
158
159
|
skillsRelDir,
|
|
159
160
|
id,
|
|
160
161
|
/* includeSubAgents */
|
|
@@ -180,8 +181,8 @@ function installAgentInstances(opts) {
|
|
|
180
181
|
result.removed.push(rel);
|
|
181
182
|
}
|
|
182
183
|
const nextTargets = { ...ledger.targets };
|
|
183
|
-
if (Object.keys(owned).length > 0) nextTargets[
|
|
184
|
-
else delete nextTargets[
|
|
184
|
+
if (Object.keys(owned).length > 0) nextTargets[harness] = owned;
|
|
185
|
+
else delete nextTargets[harness];
|
|
185
186
|
if (JSON.stringify(nextTargets) !== JSON.stringify(ledger.targets)) {
|
|
186
187
|
writeLedger(projectDir, { version: 1, targets: nextTargets });
|
|
187
188
|
}
|
|
@@ -497,12 +498,12 @@ function canonicalJson(value) {
|
|
|
497
498
|
function entryHash(entry) {
|
|
498
499
|
return createHash("sha256").update(canonicalJson(entry)).digest("hex");
|
|
499
500
|
}
|
|
500
|
-
async function mcpServerDrift(projectDir,
|
|
501
|
-
const relConfig = TARGET_MCP_CONFIG[
|
|
501
|
+
async function mcpServerDrift(projectDir, harnessTarget, opts = {}) {
|
|
502
|
+
const relConfig = TARGET_MCP_CONFIG[harnessTarget];
|
|
502
503
|
if (!relConfig) return [];
|
|
503
504
|
const declarations = opts.declarations ?? await loadMcpServerDeclarations(projectDir);
|
|
504
|
-
const skippedNow = await readNotedSkips(projectDir,
|
|
505
|
-
const ledger = await readManaged(projectDir,
|
|
505
|
+
const skippedNow = await readNotedSkips(projectDir, harnessTarget);
|
|
506
|
+
const ledger = await readManaged(projectDir, harnessTarget);
|
|
506
507
|
const managed = new Set(ledger.ids);
|
|
507
508
|
let servers = {};
|
|
508
509
|
try {
|
|
@@ -595,13 +596,21 @@ function requiredFieldsAdvice(id, keys) {
|
|
|
595
596
|
const setting = keys.map((k) => `${k}: env:${k}`).join(", ");
|
|
596
597
|
return `needs ${keys.join(", ")} (required): set it with an mcp_servers entry (id: ${id}, env: ${setting}) in skaile.yaml and export the variable, then run skaile install`;
|
|
597
598
|
}
|
|
598
|
-
function
|
|
599
|
-
|
|
599
|
+
function mcpNotRunnableReason(mdContent, name) {
|
|
600
|
+
try {
|
|
601
|
+
const decl = mcpDeclarationFromMdContent(mdContent, name);
|
|
602
|
+
return decl ? skipReason(decl) : void 0;
|
|
603
|
+
} catch {
|
|
604
|
+
return void 0;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
function mcpConfigFileOf(harnessTarget) {
|
|
608
|
+
return TARGET_MCP_CONFIG[harnessTarget];
|
|
600
609
|
}
|
|
601
|
-
async function mcpRenderedFootprint(projectDir,
|
|
602
|
-
const relConfig = TARGET_MCP_CONFIG[
|
|
610
|
+
async function mcpRenderedFootprint(projectDir, harnessTarget, name) {
|
|
611
|
+
const relConfig = TARGET_MCP_CONFIG[harnessTarget];
|
|
603
612
|
if (!relConfig) return void 0;
|
|
604
|
-
const ledger = await readManaged(projectDir,
|
|
613
|
+
const ledger = await readManaged(projectDir, harnessTarget);
|
|
605
614
|
if (!ledger.ids.includes(name)) return void 0;
|
|
606
615
|
const dir = payloadDir(projectDir, name);
|
|
607
616
|
let hasPayload = false;
|
|
@@ -616,15 +625,47 @@ async function mcpRenderedFootprint(projectDir, driverTarget, name) {
|
|
|
616
625
|
...dir && hasPayload ? { payloadDir: `${path.relative(projectDir, dir).split(path.sep).join("/")}/` } : {}
|
|
617
626
|
};
|
|
618
627
|
}
|
|
619
|
-
async function
|
|
628
|
+
async function mcpCommittedRenderIntact(projectDir, harnessTarget, name) {
|
|
629
|
+
const relConfig = TARGET_MCP_CONFIG[harnessTarget];
|
|
630
|
+
if (!relConfig) return false;
|
|
631
|
+
if ((await readNotedSkips(projectDir, harnessTarget))[name] !== void 0) return true;
|
|
632
|
+
let ledger;
|
|
633
|
+
let servers;
|
|
634
|
+
try {
|
|
635
|
+
ledger = await readManaged(projectDir, harnessTarget);
|
|
636
|
+
const file = await readJsonStrict(path.join(projectDir, relConfig));
|
|
637
|
+
servers = file?.mcpServers ?? {};
|
|
638
|
+
} catch {
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
if (!Object.hasOwn(servers, name)) return false;
|
|
642
|
+
const entry = servers[name];
|
|
643
|
+
const recorded = ledger.ids.includes(name) ? ledger.rendered[name] : void 0;
|
|
644
|
+
if (recorded !== void 0 && entryHash(entry) !== recorded) return false;
|
|
645
|
+
const e = entry ?? {};
|
|
646
|
+
const strings = [e.command, ...Array.isArray(e.args) ? e.args : []].filter(
|
|
647
|
+
(v) => typeof v === "string"
|
|
648
|
+
);
|
|
649
|
+
for (const v of strings) {
|
|
650
|
+
const at = v.indexOf(".skaile/assets/");
|
|
651
|
+
if (at < 0) continue;
|
|
652
|
+
try {
|
|
653
|
+
await fs.stat(path.join(projectDir, v.slice(at)));
|
|
654
|
+
} catch {
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
return true;
|
|
659
|
+
}
|
|
660
|
+
async function renderMcpServerConfig(projectDir, harnessTarget, opts) {
|
|
620
661
|
const warn = opts?.warn ?? ((m) => console.warn(`skaile: ${m}`));
|
|
621
|
-
const relConfig = TARGET_MCP_CONFIG[
|
|
662
|
+
const relConfig = TARGET_MCP_CONFIG[harnessTarget];
|
|
622
663
|
if (!relConfig) return { written: false, servers: [], removed: [], skipped: [] };
|
|
623
664
|
const configPath = path.join(projectDir, relConfig);
|
|
624
665
|
const declarations = await loadMcpServerDeclarations(projectDir);
|
|
625
666
|
const skipped = [];
|
|
626
667
|
const renderable = /* @__PURE__ */ new Map();
|
|
627
|
-
const noted = await readNotedSkips(projectDir,
|
|
668
|
+
const noted = await readNotedSkips(projectDir, harnessTarget);
|
|
628
669
|
for (const decl of declarations) {
|
|
629
670
|
const reason = skipReason(decl) ?? await ensurePayload(projectDir, decl, opts?.fetchPayload ?? defaultFetchPayload);
|
|
630
671
|
if (reason) {
|
|
@@ -636,8 +677,8 @@ async function renderMcpServerConfig(projectDir, driverTarget, opts) {
|
|
|
636
677
|
}
|
|
637
678
|
renderable.set(decl.id, buildEntry(decl));
|
|
638
679
|
}
|
|
639
|
-
await writeNotedSkips(projectDir,
|
|
640
|
-
const ledger = await readManaged(projectDir,
|
|
680
|
+
await writeNotedSkips(projectDir, harnessTarget, noted, skipped);
|
|
681
|
+
const ledger = await readManaged(projectDir, harnessTarget);
|
|
641
682
|
const managedIds = ledger.ids;
|
|
642
683
|
const existingFile = await readJsonStrict(configPath);
|
|
643
684
|
if (renderable.size === 0 && managedIds.length === 0 && !existingFile) {
|
|
@@ -660,7 +701,7 @@ async function renderMcpServerConfig(projectDir, driverTarget, opts) {
|
|
|
660
701
|
}
|
|
661
702
|
const rendered = Object.fromEntries(owned.map((id) => [id, entryHash(next[id])]));
|
|
662
703
|
const ledgerStale = JSON.stringify(owned) !== JSON.stringify(managedIds) || canonicalJson(rendered) !== canonicalJson(ledger.rendered);
|
|
663
|
-
if (ledgerStale) await writeManaged(projectDir,
|
|
704
|
+
if (ledgerStale) await writeManaged(projectDir, harnessTarget, { ids: owned, rendered });
|
|
664
705
|
if (Object.keys(next).length === 0 && !existingFile) {
|
|
665
706
|
return { path: configPath, written: false, servers: owned, removed, skipped };
|
|
666
707
|
}
|
|
@@ -839,6 +880,16 @@ function libraryDiskHashes(libPath, cache, registry) {
|
|
|
839
880
|
}
|
|
840
881
|
return hashes;
|
|
841
882
|
}
|
|
883
|
+
function repoManifestVersion(repoDir) {
|
|
884
|
+
try {
|
|
885
|
+
const { manifest } = decodeSkaileManifest(
|
|
886
|
+
readFileSync(join(repoDir, "skaile.manifest.yaml"), "utf8")
|
|
887
|
+
);
|
|
888
|
+
return manifest.version || void 0;
|
|
889
|
+
} catch {
|
|
890
|
+
return void 0;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
842
893
|
function manifestFileHasAssetsArray(libPath) {
|
|
843
894
|
try {
|
|
844
895
|
const doc = parse(readFileSync(join(libPath, "skaile.manifest.yaml"), "utf8"));
|
|
@@ -847,6 +898,10 @@ function manifestFileHasAssetsArray(libPath) {
|
|
|
847
898
|
return false;
|
|
848
899
|
}
|
|
849
900
|
}
|
|
901
|
+
var libraryAssetCheck;
|
|
902
|
+
function setLibraryAssetCheck(check) {
|
|
903
|
+
libraryAssetCheck = check;
|
|
904
|
+
}
|
|
850
905
|
function isUnlistedLibraryAsset(entry, libPath) {
|
|
851
906
|
const manifest = loadSkPublishManifest(libPath);
|
|
852
907
|
const listed = manifest?.assets ?? [];
|
|
@@ -1117,7 +1172,9 @@ function relockedRefs(prev, next) {
|
|
|
1117
1172
|
e.library?.version ?? "",
|
|
1118
1173
|
e.library && !e.library.installed ? e.library.name : "",
|
|
1119
1174
|
e.library?.sha256 ?? e.sha256,
|
|
1120
|
-
key.includes("#0.0.0-sha.") ? "" : e.source?.commit ?? ""
|
|
1175
|
+
key.includes("#0.0.0-sha.") ? "" : e.source?.commit ?? "",
|
|
1176
|
+
// The `../` compose folders are part of the lock: `update` moving them is a re-lock.
|
|
1177
|
+
(e.composed ?? []).map((f) => `${f.path}:${f.sha256}`).join("\n")
|
|
1121
1178
|
].join("\0");
|
|
1122
1179
|
const out = [];
|
|
1123
1180
|
for (const [key, entry] of Object.entries(next.assets)) {
|
|
@@ -1152,9 +1209,13 @@ function libraryMoves(prev, next) {
|
|
|
1152
1209
|
}
|
|
1153
1210
|
return out;
|
|
1154
1211
|
}
|
|
1212
|
+
function unregisteredLibraryName(origin) {
|
|
1213
|
+
return lastLibraryName(origin.name) ?? origin.name;
|
|
1214
|
+
}
|
|
1155
1215
|
function unregisteredLibraryFix(origin, ref) {
|
|
1156
|
-
const
|
|
1157
|
-
|
|
1216
|
+
const name = unregisteredLibraryName(origin);
|
|
1217
|
+
const register = origin.url ? `\`skaile library init ${name} --git ${origin.url}\` (no registered library has the remote ${origin.url} either)` : `\`skaile library init ${name} --path <dir>\``;
|
|
1218
|
+
return `register library "${name}" again with ${register}, or drop the dependency with \`skaile remove ${ref}\``;
|
|
1158
1219
|
}
|
|
1159
1220
|
function declaredNoHolderReason(ref) {
|
|
1160
1221
|
return `is declared but no library or source holds it \u2014 register the library that holds it with \`skaile library init <name> --path <dir>\`, or drop it with \`skaile remove ${ref.split("#")[0]}\``;
|
|
@@ -1180,7 +1241,7 @@ function libraryCollisionSummary(all) {
|
|
|
1180
1241
|
return `${all.length} assets exist in several libraries (${libraries.join(", ")}); using ${usedText.join(", ")}. Highest version wins; an equal version goes to the default library, then by name. ` + (differing.length > 0 ? `Same version, different bytes for: ${differing.join(", ")}. ` : "") + "Pin a version (<ref>#<version>) to choose another; `--verbose` lists each asset.";
|
|
1181
1242
|
}
|
|
1182
1243
|
function lockedLibraryProblem(lookup, origin, ref) {
|
|
1183
|
-
return lookup.state === "dir-missing" ? missingLibraryDirMessage({ name: origin.name, path: lookup.path }) : `library "${origin
|
|
1244
|
+
return lookup.state === "dir-missing" ? missingLibraryDirMessage({ name: origin.name, path: lookup.path }) : `library "${unregisteredLibraryName(origin)}" is not registered \u2014 renamed or removed? ${unregisteredLibraryFix(origin, ref)}`;
|
|
1184
1245
|
}
|
|
1185
1246
|
function gapIdentity(ref) {
|
|
1186
1247
|
const p = parseRefTolerant(ref);
|
|
@@ -1293,7 +1354,7 @@ function decodeEntryHarnesses(value) {
|
|
|
1293
1354
|
for (const [key, list] of Object.entries(value)) {
|
|
1294
1355
|
if (!Array.isArray(list)) continue;
|
|
1295
1356
|
const valid = list.filter(
|
|
1296
|
-
(h) =>
|
|
1357
|
+
(h) => SUPPORTED_HARNESSES.includes(h)
|
|
1297
1358
|
);
|
|
1298
1359
|
if (valid.length > 0) out[key] = [...new Set(valid)];
|
|
1299
1360
|
}
|
|
@@ -1302,8 +1363,8 @@ function decodeEntryHarnesses(value) {
|
|
|
1302
1363
|
var AssetManager = class {
|
|
1303
1364
|
/** Resolved absolute path to the workspace root. */
|
|
1304
1365
|
projectDir;
|
|
1305
|
-
/**
|
|
1306
|
-
|
|
1366
|
+
/** Harness all deploy operations target (a `HarnessName`). */
|
|
1367
|
+
harness;
|
|
1307
1368
|
/** Whether this instance operates in global-install mode. */
|
|
1308
1369
|
global;
|
|
1309
1370
|
/** Asset-kind registry shared with the host (one instance per process). */
|
|
@@ -1344,7 +1405,7 @@ var AssetManager = class {
|
|
|
1344
1405
|
this.projectDir = resolve(opts.projectDir);
|
|
1345
1406
|
this.global = opts.global ?? false;
|
|
1346
1407
|
this.registry = opts.registry;
|
|
1347
|
-
this.
|
|
1408
|
+
this.harness = opts.harness ?? (this.global ? void 0 : resolveConfiguredHarnessName(this.projectDir)) ?? "claude-code";
|
|
1348
1409
|
this.harnessesOverride = opts.harnesses ?? opts.backends;
|
|
1349
1410
|
this.injectedStoreFetcher = opts.storeFetcher;
|
|
1350
1411
|
this.injectedAssetFetcher = opts.assetFetcher;
|
|
@@ -1369,7 +1430,7 @@ var AssetManager = class {
|
|
|
1369
1430
|
/**
|
|
1370
1431
|
* Root for this manager's **state** — config SSOT, lock, cache, history.
|
|
1371
1432
|
* `~/.skaile` in global mode (the cross-harness SSOT), else the project dir.
|
|
1372
|
-
* Deploy dirs are unaffected; they come from `
|
|
1433
|
+
* Deploy dirs are unaffected; they come from `HARNESS_TARGETS[target]`.
|
|
1373
1434
|
*/
|
|
1374
1435
|
get stateRoot() {
|
|
1375
1436
|
return this.global ? globalSkaileDir() : this.projectDir;
|
|
@@ -1379,11 +1440,11 @@ var AssetManager = class {
|
|
|
1379
1440
|
* filter), else the explicit `global_harnesses:` of `~/.skaile/skaile.yaml`, else every harness
|
|
1380
1441
|
* whose root dir exists under `~` plus the harness the project is configured for (a project on
|
|
1381
1442
|
* a harness whose dir does not exist yet still gets its user-scope assets). In project mode
|
|
1382
|
-
* this is exactly `[
|
|
1443
|
+
* this is exactly `[harness]`, so the shared fan-out loop degenerates to the
|
|
1383
1444
|
* single-target path.
|
|
1384
1445
|
*/
|
|
1385
1446
|
targetHarnesses() {
|
|
1386
|
-
if (!this.global) return [this.
|
|
1447
|
+
if (!this.global) return [this.harness];
|
|
1387
1448
|
if (this.harnessesOverride && this.harnessesOverride.length > 0) return this.harnessesOverride;
|
|
1388
1449
|
return this.defaultGlobalHarnesses();
|
|
1389
1450
|
}
|
|
@@ -1391,7 +1452,7 @@ var AssetManager = class {
|
|
|
1391
1452
|
defaultGlobalHarnesses() {
|
|
1392
1453
|
const resolved = resolveGlobalHarnesses();
|
|
1393
1454
|
if (resolveGlobalSkWorkspaceConfig().global_harnesses?.length) return resolved;
|
|
1394
|
-
const configured =
|
|
1455
|
+
const configured = resolveConfiguredHarnessName(this.projectDir);
|
|
1395
1456
|
return configured && !resolved.includes(configured) ? [...resolved, configured] : resolved;
|
|
1396
1457
|
}
|
|
1397
1458
|
/**
|
|
@@ -1429,6 +1490,43 @@ var AssetManager = class {
|
|
|
1429
1490
|
return !recorded || recorded.includes(target);
|
|
1430
1491
|
});
|
|
1431
1492
|
}
|
|
1493
|
+
/**
|
|
1494
|
+
* A 5.12.0 global record has no `global_asset_harnesses:` key, yet `add --global --harness`
|
|
1495
|
+
* wrote one copy only. On the first global `install`, an entry with exactly one existing copy
|
|
1496
|
+
* among several default harnesses is that harness's subset (OQ6): record it, so the install
|
|
1497
|
+
* does not fan the asset out to harnesses the user never asked for (p1442). A copy under the
|
|
1498
|
+
* 5.12.0 omp folder (`~/.omp/skills`) counts as an omp copy. Nothing is inferred once the key
|
|
1499
|
+
* exists (an entry without a row then means "every harness"), with one default harness, or
|
|
1500
|
+
* with no copy yet. Global mode only; returns the rows written.
|
|
1501
|
+
*/
|
|
1502
|
+
inferLegacyHarnessSubsets(entries) {
|
|
1503
|
+
if (!this.global) return [];
|
|
1504
|
+
const configPath = join(this.stateRoot, "skaile.yaml");
|
|
1505
|
+
if (!existsSync(configPath)) return [];
|
|
1506
|
+
let raw;
|
|
1507
|
+
try {
|
|
1508
|
+
raw = parse(readFileSync(configPath, "utf8"));
|
|
1509
|
+
} catch {
|
|
1510
|
+
return [];
|
|
1511
|
+
}
|
|
1512
|
+
if (!raw || typeof raw !== "object" || ENTRY_HARNESSES_KEY in raw) return [];
|
|
1513
|
+
const all = this.defaultGlobalHarnesses();
|
|
1514
|
+
if (all.length < 2) return [];
|
|
1515
|
+
const rows = [];
|
|
1516
|
+
for (const e of entries) {
|
|
1517
|
+
const component = this.installTarget(e.kind);
|
|
1518
|
+
if (!component || !e.name) continue;
|
|
1519
|
+
const holding = all.filter(
|
|
1520
|
+
(h) => isDeployed(component, e.name, h, true) || h === "omp" && legacyOmpPaths(component, e.name).length > 0
|
|
1521
|
+
);
|
|
1522
|
+
if (holding.length !== 1) continue;
|
|
1523
|
+
const publisher = e.publisher?.replace(/^@/, "");
|
|
1524
|
+
const ref = `${e.kind}:${publisher ? `@${publisher}/` : ""}${e.name}`;
|
|
1525
|
+
if (this.setEntryHarnessRow(raw, ref, holding)) rows.push({ ref, harnesses: holding });
|
|
1526
|
+
}
|
|
1527
|
+
if (rows.length > 0) writeFileSync(configPath, stringify(raw, { lineWidth: 120 }));
|
|
1528
|
+
return rows;
|
|
1529
|
+
}
|
|
1432
1530
|
/**
|
|
1433
1531
|
* Set (or, with `harnesses` undefined, clear) the harness row of `ref` in the parsed
|
|
1434
1532
|
* `~/.skaile/skaile.yaml` `raw`. Returns whether `raw` changed.
|
|
@@ -1520,7 +1618,7 @@ var AssetManager = class {
|
|
|
1520
1618
|
return this.legacyCopiesRemoved.splice(0);
|
|
1521
1619
|
}
|
|
1522
1620
|
/**
|
|
1523
|
-
* The harnesses `add` / `install` deploy into: `[
|
|
1621
|
+
* The harnesses `add` / `install` deploy into: `[harness]` for a project, the global
|
|
1524
1622
|
* harness set (see {@link AssetManager.targetHarnesses}) for a global manager.
|
|
1525
1623
|
*/
|
|
1526
1624
|
deployTargets() {
|
|
@@ -1554,18 +1652,38 @@ var AssetManager = class {
|
|
|
1554
1652
|
get patchDir() {
|
|
1555
1653
|
return join(this.projectDir, ".skaile", "patches");
|
|
1556
1654
|
}
|
|
1557
|
-
/** Deploy options for one harness. In global mode, `
|
|
1558
|
-
* fan-out target (not the constructor's `
|
|
1559
|
-
deployOptsFor(target, link, onSecretFile) {
|
|
1655
|
+
/** Deploy options for one harness. In global mode, `harness` is the
|
|
1656
|
+
* fan-out target (not the constructor's `harness`, which is project-only). */
|
|
1657
|
+
deployOptsFor(target, link, onSecretFile, composed) {
|
|
1658
|
+
const records = this.global ? void 0 : this.composedRecords();
|
|
1560
1659
|
return {
|
|
1561
1660
|
registry: this.registry,
|
|
1562
|
-
|
|
1661
|
+
harness: target,
|
|
1563
1662
|
global: this.global,
|
|
1564
1663
|
cwd: this.projectDir,
|
|
1565
1664
|
link: link === true,
|
|
1566
|
-
...onSecretFile ? { onSecretFile: (entry, p) => onSecretFile(canonicalEntryRef(entry), p) } : {}
|
|
1665
|
+
...onSecretFile ? { onSecretFile: (entry, p) => onSecretFile(canonicalEntryRef(entry), p) } : {},
|
|
1666
|
+
...records ? { lockedComposed: (agent) => records.get(agent) } : {},
|
|
1667
|
+
...composed ? {
|
|
1668
|
+
refreshComposed: composed.refresh,
|
|
1669
|
+
onComposedDrift: (entry, ref) => composed.onDrift(canonicalEntryRef(entry), ref)
|
|
1670
|
+
} : {}
|
|
1567
1671
|
};
|
|
1568
1672
|
}
|
|
1673
|
+
/** Agent name → the `../` compose folder files its lock entry records (`LockEntry.composed`). */
|
|
1674
|
+
composedRecords() {
|
|
1675
|
+
const out = /* @__PURE__ */ new Map();
|
|
1676
|
+
for (const [key, entry] of Object.entries(this.tryReadLock()?.assets ?? {})) {
|
|
1677
|
+
if (!entry.composed?.length) continue;
|
|
1678
|
+
const { name } = parseCanonicalLockKey(key);
|
|
1679
|
+
if (name) out.set(name, entry.composed);
|
|
1680
|
+
}
|
|
1681
|
+
return out;
|
|
1682
|
+
}
|
|
1683
|
+
/** `install`'s `Missing:` line for a `../` compose folder the library moved past the lock. */
|
|
1684
|
+
composedDriftLine(agentRef, composeRef) {
|
|
1685
|
+
return `${agentRef} (composes ${composeRef}: the library's copy changed since the lock; \`skaile update\` moves the lock to it)`;
|
|
1686
|
+
}
|
|
1569
1687
|
/**
|
|
1570
1688
|
* Names of the `mcp-server` assets the lock holds (the declaration ids, unscoped); a missing
|
|
1571
1689
|
* `.mcp.json` entry of one counts as drift even before skaile owned it.
|
|
@@ -1588,7 +1706,7 @@ var AssetManager = class {
|
|
|
1588
1706
|
if (locked.size === 0) return [];
|
|
1589
1707
|
let rows;
|
|
1590
1708
|
try {
|
|
1591
|
-
rows = await mcpServerDrift(this.projectDir, this.
|
|
1709
|
+
rows = await mcpServerDrift(this.projectDir, this.harness, { locked });
|
|
1592
1710
|
} catch {
|
|
1593
1711
|
return [];
|
|
1594
1712
|
}
|
|
@@ -1616,13 +1734,9 @@ var AssetManager = class {
|
|
|
1616
1734
|
*/
|
|
1617
1735
|
async mcpRenderFootprint(name) {
|
|
1618
1736
|
if (this.global) return void 0;
|
|
1619
|
-
const file = mcpConfigFileOf(this.
|
|
1737
|
+
const file = mcpConfigFileOf(this.harness);
|
|
1620
1738
|
if (!file) return void 0;
|
|
1621
|
-
const footprint = await mcpRenderedFootprint(
|
|
1622
|
-
this.projectDir,
|
|
1623
|
-
this.driverTarget,
|
|
1624
|
-
unscopedName(name)
|
|
1625
|
-
);
|
|
1739
|
+
const footprint = await mcpRenderedFootprint(this.projectDir, this.harness, unscopedName(name));
|
|
1626
1740
|
return footprint ? { ...footprint, written: true } : { file, written: false };
|
|
1627
1741
|
}
|
|
1628
1742
|
/**
|
|
@@ -1634,11 +1748,11 @@ var AssetManager = class {
|
|
|
1634
1748
|
*/
|
|
1635
1749
|
async mcpPendingRender() {
|
|
1636
1750
|
if (this.global) return [];
|
|
1637
|
-
const file = mcpConfigFileOf(this.
|
|
1751
|
+
const file = mcpConfigFileOf(this.harness);
|
|
1638
1752
|
if (!file) return [];
|
|
1639
1753
|
let rows;
|
|
1640
1754
|
try {
|
|
1641
|
-
rows = await mcpServerDrift(this.projectDir, this.
|
|
1755
|
+
rows = await mcpServerDrift(this.projectDir, this.harness, {
|
|
1642
1756
|
locked: this.lockedMcpNames()
|
|
1643
1757
|
});
|
|
1644
1758
|
} catch {
|
|
@@ -1652,7 +1766,7 @@ var AssetManager = class {
|
|
|
1652
1766
|
});
|
|
1653
1767
|
}
|
|
1654
1768
|
/**
|
|
1655
|
-
* Render the project's declared MCP servers into the
|
|
1769
|
+
* Render the project's declared MCP servers into the harness target's own
|
|
1656
1770
|
* native MCP config (`<project>/.mcp.json` for `claude-code`), so the coding
|
|
1657
1771
|
* agent sees the same servers skaile's agent loop wires up.
|
|
1658
1772
|
*
|
|
@@ -1665,14 +1779,14 @@ var AssetManager = class {
|
|
|
1665
1779
|
* removed) because they had drifted from the declaration: `install` names them, as it does
|
|
1666
1780
|
* a restored skill file.
|
|
1667
1781
|
*/
|
|
1668
|
-
async
|
|
1782
|
+
async renderHarnessMcpConfig() {
|
|
1669
1783
|
if (this.global) return [];
|
|
1670
1784
|
const before = await this.mcpDriftRows();
|
|
1671
1785
|
try {
|
|
1672
|
-
await renderMcpServerConfig(this.projectDir, this.
|
|
1786
|
+
await renderMcpServerConfig(this.projectDir, this.harness);
|
|
1673
1787
|
} catch (err) {
|
|
1674
1788
|
console.warn(
|
|
1675
|
-
`skaile: could not render MCP config for ${this.
|
|
1789
|
+
`skaile: could not render MCP config for ${this.harness}: ${err instanceof Error ? err.message : String(err)}`
|
|
1676
1790
|
);
|
|
1677
1791
|
return [];
|
|
1678
1792
|
}
|
|
@@ -1696,7 +1810,7 @@ var AssetManager = class {
|
|
|
1696
1810
|
return restored;
|
|
1697
1811
|
}
|
|
1698
1812
|
/**
|
|
1699
|
-
* Render every agent instance of `skaile.yaml` into the
|
|
1813
|
+
* Render every agent instance of `skaile.yaml` into the harness target's native
|
|
1700
1814
|
* agent files (`.claude/agents/<id>.md`, …) and prune the renderings of
|
|
1701
1815
|
* instances that left the config. Runs after the skills deploy, so composed
|
|
1702
1816
|
* skills resolve. Project scope only. An instance whose `ref` resolves to no agent is
|
|
@@ -1707,10 +1821,10 @@ var AssetManager = class {
|
|
|
1707
1821
|
try {
|
|
1708
1822
|
const result = installAgentInstances({
|
|
1709
1823
|
projectDir: this.projectDir,
|
|
1710
|
-
|
|
1824
|
+
harness: this.harness
|
|
1711
1825
|
});
|
|
1712
1826
|
const details = [];
|
|
1713
|
-
for (const u of unboundAgentInstances(this.projectDir, this.
|
|
1827
|
+
for (const u of unboundAgentInstances(this.projectDir, this.harness)) {
|
|
1714
1828
|
if (!u.ref.startsWith("agent:")) continue;
|
|
1715
1829
|
const at = result.errors.findIndex((e) => e.startsWith(`agent instance "${u.id}":`));
|
|
1716
1830
|
if (at < 0) continue;
|
|
@@ -1727,7 +1841,7 @@ var AssetManager = class {
|
|
|
1727
1841
|
};
|
|
1728
1842
|
} catch (err) {
|
|
1729
1843
|
console.warn(
|
|
1730
|
-
`skaile: could not render agent instances for ${this.
|
|
1844
|
+
`skaile: could not render agent instances for ${this.harness}: ${err instanceof Error ? err.message : String(err)}`
|
|
1731
1845
|
);
|
|
1732
1846
|
return {};
|
|
1733
1847
|
}
|
|
@@ -1770,6 +1884,15 @@ var AssetManager = class {
|
|
|
1770
1884
|
for (const [slug, decl] of Object.entries(repositories)) {
|
|
1771
1885
|
const localPath = this.resolveRepoDir(decl, slug);
|
|
1772
1886
|
if (!localPath || !existsSync(localPath)) continue;
|
|
1887
|
+
if (decl.url && normalizeRepoUrl(decl.url) !== normalizeRepoUrl(FACTORY_SOURCE_URL) && !existsSync(join(localPath, ".git"))) {
|
|
1888
|
+
this.reportSourceError(
|
|
1889
|
+
{ localPath, sourceUrl: decl.url, commit: "" },
|
|
1890
|
+
new Error(
|
|
1891
|
+
`${decl.url}: its clone ${localPath} is not a git repository, so git pull fails - run \`skaile source sync\` to clone it again`
|
|
1892
|
+
)
|
|
1893
|
+
);
|
|
1894
|
+
continue;
|
|
1895
|
+
}
|
|
1773
1896
|
const commit = getRepoCommit(localPath) ?? "0".repeat(40);
|
|
1774
1897
|
clones.push({
|
|
1775
1898
|
localPath,
|
|
@@ -2093,6 +2216,33 @@ var AssetManager = class {
|
|
|
2093
2216
|
if (!scan) return [];
|
|
2094
2217
|
return [...scan.byKey.values()].flat();
|
|
2095
2218
|
}
|
|
2219
|
+
/**
|
|
2220
|
+
* The version `add` deploys for each asset of a source clone registered as a `reader`
|
|
2221
|
+
* library, when its file declares none: the repo commit pseudo-version (p855). `search`
|
|
2222
|
+
* reads this where no project is in scope, so it lists what `add` locks, not the index
|
|
2223
|
+
* default.
|
|
2224
|
+
*
|
|
2225
|
+
* @returns `<library>\0<kind>:@<publisher>/<name>` -> version; only assets that declare none.
|
|
2226
|
+
*/
|
|
2227
|
+
async sourceAssetVersions() {
|
|
2228
|
+
const out = /* @__PURE__ */ new Map();
|
|
2229
|
+
const scan = await this.scanLibraries();
|
|
2230
|
+
if (!scan) return out;
|
|
2231
|
+
const snap = await this.loadLibraryIndex();
|
|
2232
|
+
for (const [key, candidates] of scan.byKey) {
|
|
2233
|
+
for (const c of candidates) {
|
|
2234
|
+
if (c.entry.version) continue;
|
|
2235
|
+
const lib = snap?.libraries.find((l) => l.name === c.library);
|
|
2236
|
+
if (lib?.ownership !== "reader" || !("url" in lib.backendConfig)) continue;
|
|
2237
|
+
const manifestVersion = repoManifestVersion(lib.path);
|
|
2238
|
+
const commit = getRepoCommit(lib.path);
|
|
2239
|
+
if (manifestVersion) out.set(`${c.library}\0${key}`, manifestVersion);
|
|
2240
|
+
else if (commit)
|
|
2241
|
+
out.set(`${c.library}\0${key}`, `${PSEUDO_VERSION_PREFIX}${commit.slice(0, 7)}`);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
return out;
|
|
2245
|
+
}
|
|
2096
2246
|
/**
|
|
2097
2247
|
* Every origin that holds `ref` (`kind:@publisher/name`) with the version it holds, in
|
|
2098
2248
|
* the order `add <ref>` prefers them, so the first row is the one `add` deploys: the
|
|
@@ -2486,7 +2636,7 @@ var AssetManager = class {
|
|
|
2486
2636
|
const slot = `${component}/${a.name}`;
|
|
2487
2637
|
const prior = seen.get(slot);
|
|
2488
2638
|
if (prior && differs(prior, a)) {
|
|
2489
|
-
const dir2 = deployedDir(component, a.name, this.
|
|
2639
|
+
const dir2 = deployedDir(component, a.name, this.harness, this.global, this.projectDir);
|
|
2490
2640
|
throw new Error(
|
|
2491
2641
|
`${refOf(prior)} and ${refOf(a)} both deploy to ${shown(dir2)} \u2014 keep only one of them`
|
|
2492
2642
|
);
|
|
@@ -2558,7 +2708,7 @@ var AssetManager = class {
|
|
|
2558
2708
|
}
|
|
2559
2709
|
const drift = deployedAssetDrift(entry, {
|
|
2560
2710
|
registry: this.registry,
|
|
2561
|
-
|
|
2711
|
+
harness: target,
|
|
2562
2712
|
global: this.global,
|
|
2563
2713
|
cwd: this.projectDir
|
|
2564
2714
|
});
|
|
@@ -2602,7 +2752,14 @@ var AssetManager = class {
|
|
|
2602
2752
|
if (!existsSync(indexPath)) return null;
|
|
2603
2753
|
const index = new LocalIndex({ indexPath });
|
|
2604
2754
|
try {
|
|
2605
|
-
|
|
2755
|
+
const libraries = await index.listSources();
|
|
2756
|
+
const defs = await index.listAssetDefs();
|
|
2757
|
+
const hidden = this.undeclaredSourceClones(libraries);
|
|
2758
|
+
if (hidden.size === 0) return { libraries, defs };
|
|
2759
|
+
return {
|
|
2760
|
+
libraries: libraries.filter((l) => !hidden.has(l.id)),
|
|
2761
|
+
defs: defs.filter((d) => !d.libraryId || !hidden.has(d.libraryId))
|
|
2762
|
+
};
|
|
2606
2763
|
} finally {
|
|
2607
2764
|
index.close();
|
|
2608
2765
|
}
|
|
@@ -2610,6 +2767,32 @@ var AssetManager = class {
|
|
|
2610
2767
|
return null;
|
|
2611
2768
|
}
|
|
2612
2769
|
}
|
|
2770
|
+
/**
|
|
2771
|
+
* Ids of the registered libraries that are the clone of a source this project does not
|
|
2772
|
+
* declare. `source add` registers the clone as a machine-wide reader library so `search`
|
|
2773
|
+
* and the indexer can read it, but a `sources:` clone belongs to the projects that declare
|
|
2774
|
+
* it (OQ12, p321): another project neither resolves it, nor ties with it by name, nor has
|
|
2775
|
+
* `update` re-pin its locked assets to it. A reader library the user registered by hand
|
|
2776
|
+
* (`library init --reader --git`) lives outside the sources cache and is never hidden.
|
|
2777
|
+
*/
|
|
2778
|
+
undeclaredSourceClones(libraries) {
|
|
2779
|
+
const hidden = /* @__PURE__ */ new Set();
|
|
2780
|
+
if (!this.global && !findWorkspaceRoot(this.projectDir)) return hidden;
|
|
2781
|
+
let declared;
|
|
2782
|
+
try {
|
|
2783
|
+
declared = new Set(this.loadConfig().sources.map((s) => sourceCacheKey(s.url)));
|
|
2784
|
+
} catch {
|
|
2785
|
+
return hidden;
|
|
2786
|
+
}
|
|
2787
|
+
const cloneRoots = [join(globalCacheRoot(), "sources"), this.reposDir].map((d) => resolve(d));
|
|
2788
|
+
for (const l of libraries) {
|
|
2789
|
+
if (l.ownership !== "reader" || !("url" in l.backendConfig)) continue;
|
|
2790
|
+
const at = resolve(l.path);
|
|
2791
|
+
if (!cloneRoots.some((root) => at.startsWith(root + sep))) continue;
|
|
2792
|
+
if (!declared.has(sourceCacheKey(l.backendConfig.url))) hidden.add(l.id);
|
|
2793
|
+
}
|
|
2794
|
+
return hidden;
|
|
2795
|
+
}
|
|
2613
2796
|
/**
|
|
2614
2797
|
* Library-origin lock entries for the assets {@link resolveLibraryEntries}
|
|
2615
2798
|
* matched. The locked version is the one actually deployed: the on-disk
|
|
@@ -2741,7 +2924,7 @@ var AssetManager = class {
|
|
|
2741
2924
|
const lookup = this.lockedLibrary(e.library, snap, { kind, publisher, name });
|
|
2742
2925
|
if (lookup.state === "ok") continue;
|
|
2743
2926
|
const component = this.installTarget(kind);
|
|
2744
|
-
const deployed = component !== void 0 && isDeployed(component, name, this.
|
|
2927
|
+
const deployed = component !== void 0 && isDeployed(component, name, this.harness, this.global, this.projectDir);
|
|
2745
2928
|
const problem = lockedLibraryProblem(lookup, e.library, `${kind}:@${publisher}/${name}`);
|
|
2746
2929
|
const kept = deployed ? "the deployed copy and its lock entry are kept" : "its lock entry is kept; no deployed copy exists";
|
|
2747
2930
|
lines.push(`${ref} (${problem}; ${kept})`);
|
|
@@ -2753,14 +2936,19 @@ var AssetManager = class {
|
|
|
2753
2936
|
* `install --locked`. An entry is restored only when its library is still
|
|
2754
2937
|
* registered/on disk, still holds the asset, and still offers the locked
|
|
2755
2938
|
* version; anything else is reported in `missing` with the reason.
|
|
2939
|
+
*
|
|
2940
|
+
* @param opts.storeFallback - `install --locked` only: an entry whose library is not registered
|
|
2941
|
+
* here is restored from a store that serves the locked sha256 (OQ15, p1490). Reads such as
|
|
2942
|
+
* the drift check never ask a store.
|
|
2756
2943
|
*/
|
|
2757
|
-
async restoreLibraryLockEntries(lock) {
|
|
2944
|
+
async restoreLibraryLockEntries(lock, opts) {
|
|
2758
2945
|
const entries = [];
|
|
2759
2946
|
const missing = [];
|
|
2947
|
+
const viaStore = [];
|
|
2760
2948
|
const locked = Object.entries(lock.assets).filter(
|
|
2761
2949
|
([, e]) => e.library !== void 0 && !e.library.installed
|
|
2762
2950
|
);
|
|
2763
|
-
if (locked.length === 0) return { entries, missing };
|
|
2951
|
+
if (locked.length === 0) return { entries, missing, viaStore };
|
|
2764
2952
|
const snap = await this.loadLibraryIndex();
|
|
2765
2953
|
const diskHashes = /* @__PURE__ */ new Map();
|
|
2766
2954
|
const fileSets = /* @__PURE__ */ new Map();
|
|
@@ -2773,6 +2961,12 @@ var AssetManager = class {
|
|
|
2773
2961
|
}
|
|
2774
2962
|
const lookup = this.lockedLibrary(origin, snap, { kind, publisher, name });
|
|
2775
2963
|
if (lookup.state !== "ok") {
|
|
2964
|
+
const fallback = lookup.state === "unregistered" && opts?.storeFallback ? await this.storeEntryForLockedLibraryAsset(publisher, kind, name, origin) : null;
|
|
2965
|
+
if (fallback) {
|
|
2966
|
+
entries.push(fallback);
|
|
2967
|
+
viaStore.push(ref);
|
|
2968
|
+
continue;
|
|
2969
|
+
}
|
|
2776
2970
|
missing.push(
|
|
2777
2971
|
`${ref} (${lockedLibraryProblem(lookup, origin, `${kind}:@${publisher}/${name}`)})`
|
|
2778
2972
|
);
|
|
@@ -2795,7 +2989,7 @@ var AssetManager = class {
|
|
|
2795
2989
|
const component = this.installTarget(kind);
|
|
2796
2990
|
const newer = gt(coerceVersion(current), coerceVersion(origin.version));
|
|
2797
2991
|
const comparable = !isPseudoVersion(current) && !isPseudoVersion(origin.version);
|
|
2798
|
-
const intact = (newer || comparable) && (component === void 0 || isDeployed(component, name, this.
|
|
2992
|
+
const intact = (newer || comparable) && (component === void 0 || isDeployed(component, name, this.harness, this.global, this.projectDir));
|
|
2799
2993
|
if (!intact) {
|
|
2800
2994
|
missing.push(
|
|
2801
2995
|
`${ref} (library "${lookup.name}" is at ${current}, locked ${origin.version}${newer || comparable ? "; `skaile update` moves the lock to it" : ""})`
|
|
@@ -2815,27 +3009,76 @@ var AssetManager = class {
|
|
|
2815
3009
|
found.version = sameVersion ? origin.version : current;
|
|
2816
3010
|
entries.push(withLibraryFiles(found, libPath, fileSets, this.registry));
|
|
2817
3011
|
}
|
|
2818
|
-
return { entries, missing };
|
|
3012
|
+
return { entries, missing, viaStore };
|
|
3013
|
+
}
|
|
3014
|
+
/**
|
|
3015
|
+
* The store's copy of a library-origin lock entry whose library is not registered here: a
|
|
3016
|
+
* store (project `stores:` or the global catalog) that serves `kind:@publisher/name#version`
|
|
3017
|
+
* under the very sha256 the lock recorded holds the same bytes. The entry is fetched and
|
|
3018
|
+
* verified like any store asset; the lock stays as it is. `null` when the lock has no hash,
|
|
3019
|
+
* no store answers, or the hash differs (OQ15, p1490).
|
|
3020
|
+
*/
|
|
3021
|
+
async storeEntryForLockedLibraryAsset(publisher, kind, name, origin) {
|
|
3022
|
+
if (!origin.sha256 || !origin.version || isPseudoVersion(origin.version)) return null;
|
|
3023
|
+
const { repositories, stores: projectStores } = this.loadConfig();
|
|
3024
|
+
const stores = [...projectStores, ...await this.globalStoreFallback(projectStores)];
|
|
3025
|
+
const fetcher = this.storeFetcherFor(stores);
|
|
3026
|
+
if (!fetcher) return null;
|
|
3027
|
+
for (const store of stores) {
|
|
3028
|
+
try {
|
|
3029
|
+
const m = await fetcher.getInstallManifest(
|
|
3030
|
+
store.url,
|
|
3031
|
+
`${kind}:@${publisher}/${name}#${origin.version}`
|
|
3032
|
+
);
|
|
3033
|
+
if (!m || m.sha256 !== origin.sha256) continue;
|
|
3034
|
+
const [entry] = await this.buildCatalogEntries(
|
|
3035
|
+
[
|
|
3036
|
+
{
|
|
3037
|
+
publisher,
|
|
3038
|
+
kind,
|
|
3039
|
+
name,
|
|
3040
|
+
version: origin.version,
|
|
3041
|
+
sourceUrl: m.sourceUrl,
|
|
3042
|
+
commit: m.commit,
|
|
3043
|
+
files: m.files,
|
|
3044
|
+
sha256: m.sha256,
|
|
3045
|
+
...m.deps?.length ? { deps: m.deps, storeRequires: m.deps } : {}
|
|
3046
|
+
}
|
|
3047
|
+
],
|
|
3048
|
+
repositories
|
|
3049
|
+
);
|
|
3050
|
+
if (entry) return entry;
|
|
3051
|
+
} catch (err) {
|
|
3052
|
+
this.noteStoreFailure(store.url, err);
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
return null;
|
|
2819
3056
|
}
|
|
2820
3057
|
/**
|
|
2821
3058
|
* Whether a deployed copy exists for the lock entries `install` kept for the unresolved
|
|
2822
|
-
* `ref`. A kind with no install target has
|
|
3059
|
+
* `ref`. A kind with no install target has none, except an `mcp-server`: its copy is the
|
|
3060
|
+
* `.mcp.json` entry skaile wrote and the payload that entry points into (p792).
|
|
2823
3061
|
*/
|
|
2824
|
-
keptCopyDeployed(kept, ref) {
|
|
3062
|
+
async keptCopyDeployed(kept, ref) {
|
|
2825
3063
|
const want = parseRefTolerant(ref.split(" ")[0] ?? ref);
|
|
2826
3064
|
if (!want) return false;
|
|
2827
|
-
|
|
3065
|
+
for (const key of Object.keys(kept.assets)) {
|
|
2828
3066
|
const id = parseCanonicalLockKey(key);
|
|
2829
|
-
if (id.kind !== want.kind || id.name !== want.name)
|
|
2830
|
-
if (want.publisher && id.publisher !== want.publisher)
|
|
3067
|
+
if (id.kind !== want.kind || id.name !== want.name) continue;
|
|
3068
|
+
if (want.publisher && id.publisher !== want.publisher) continue;
|
|
2831
3069
|
const component = this.installTarget(id.kind);
|
|
2832
|
-
|
|
2833
|
-
|
|
3070
|
+
if (component !== void 0) {
|
|
3071
|
+
if (isDeployed(component, id.name, this.harness, this.global, this.projectDir)) return true;
|
|
3072
|
+
} else if (id.kind === "mcp-server" && !this.global && await mcpCommittedRenderIntact(this.projectDir, this.harness, id.name)) {
|
|
3073
|
+
return true;
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
return false;
|
|
2834
3077
|
}
|
|
2835
3078
|
/** Whether the deployed copy of a library asset is on disk; a kind with no install target has none to check. */
|
|
2836
3079
|
lockedCopyDeployed(kind, name) {
|
|
2837
3080
|
const component = this.installTarget(kind);
|
|
2838
|
-
return component === void 0 || isDeployed(component, name, this.
|
|
3081
|
+
return component === void 0 || isDeployed(component, name, this.harness, this.global, this.projectDir);
|
|
2839
3082
|
}
|
|
2840
3083
|
/**
|
|
2841
3084
|
* The library-origin lock entries `install` keeps when the library holds a newer version:
|
|
@@ -2953,6 +3196,24 @@ var AssetManager = class {
|
|
|
2953
3196
|
lockedRefsNamed(kind, name) {
|
|
2954
3197
|
return Object.keys(this.tryReadLock()?.assets ?? {}).map(parseCanonicalLockKey).filter((id) => id.kind === kind && id.name === name).map((id) => id.publisher ? `${kind}:@${id.publisher}/${name}` : `${kind}:${name}`);
|
|
2955
3198
|
}
|
|
3199
|
+
/**
|
|
3200
|
+
* The library a library-origin lock entry of `kind` and `name` (and `publisher`, when given)
|
|
3201
|
+
* resolves to on this machine, or `undefined` when the lock holds no such entry, it is not
|
|
3202
|
+
* from a library, or its library is not here. `info` prints it next to `source:`.
|
|
3203
|
+
*/
|
|
3204
|
+
async lockedLibraryOf(kind, name, publisher) {
|
|
3205
|
+
const bare = publisher?.replace(/^@/, "");
|
|
3206
|
+
const names = await this.lockedLibraryNames();
|
|
3207
|
+
for (const [key, entry] of Object.entries(this.tryReadLock()?.assets ?? {})) {
|
|
3208
|
+
if (!entry.library || entry.library.installed) continue;
|
|
3209
|
+
const id = parseCanonicalLockKey(key);
|
|
3210
|
+
if (id.kind !== kind || id.name !== name || !id.publisher) continue;
|
|
3211
|
+
if (bare && id.publisher !== bare) continue;
|
|
3212
|
+
const lib = names.get(`${kind}:${id.publisher}/${name}`);
|
|
3213
|
+
if (lib) return lib;
|
|
3214
|
+
}
|
|
3215
|
+
return void 0;
|
|
3216
|
+
}
|
|
2956
3217
|
/**
|
|
2957
3218
|
* Where each library-origin lock entry of this project resolves on this machine: identity
|
|
2958
3219
|
* `kind:publisher/name` (no scope sigil, no version) → the name the locked library is
|
|
@@ -2995,6 +3256,88 @@ var AssetManager = class {
|
|
|
2995
3256
|
}
|
|
2996
3257
|
return { libraries: await this.lockedLibraryNames(), shas };
|
|
2997
3258
|
}
|
|
3259
|
+
/**
|
|
3260
|
+
* Canonical refs of the locked source assets that share a source URL with `resolved` but
|
|
3261
|
+
* are locked at another commit than the one `resolved` carries for it. Assets in `resolved`
|
|
3262
|
+
* and library-origin entries are skipped.
|
|
3263
|
+
*/
|
|
3264
|
+
staleSourceSiblingRefs(resolved, declared = []) {
|
|
3265
|
+
const pinOf = /* @__PURE__ */ new Map();
|
|
3266
|
+
for (const d of declared) {
|
|
3267
|
+
const id = refIdentity(d);
|
|
3268
|
+
const pin = parseAssetRefLoose(d)?.pin;
|
|
3269
|
+
if (id !== null && pin) pinOf.set(id.replace(/^@/, ""), pin);
|
|
3270
|
+
}
|
|
3271
|
+
const commitOf = /* @__PURE__ */ new Map();
|
|
3272
|
+
const held = /* @__PURE__ */ new Set();
|
|
3273
|
+
for (const c of resolved) {
|
|
3274
|
+
if (!c.sourceUrl || !c.commit) continue;
|
|
3275
|
+
commitOf.set(normalizeRepoUrl(c.sourceUrl), c.commit);
|
|
3276
|
+
held.add(`${c.publisher.replace(/^@/, "")}/${c.kind}:${c.name}`);
|
|
3277
|
+
}
|
|
3278
|
+
const out = [];
|
|
3279
|
+
for (const [key, entry] of Object.entries(this.tryReadLock()?.assets ?? {})) {
|
|
3280
|
+
const src = entry.source;
|
|
3281
|
+
if (!src?.url || entry.library) continue;
|
|
3282
|
+
const commit = commitOf.get(normalizeRepoUrl(src.url));
|
|
3283
|
+
if (!commit || src.commit === commit) continue;
|
|
3284
|
+
const { publisher, kind, name } = parseCanonicalLockKey(key);
|
|
3285
|
+
if (!publisher || !kind || !name || held.has(`${publisher}/${kind}:${name}`)) continue;
|
|
3286
|
+
const pin = pinOf.get(`${publisher}/${kind}:${name}`);
|
|
3287
|
+
out.push(`${kind}:@${publisher}/${name}${pin ? `#${pin}` : ""}`);
|
|
3288
|
+
}
|
|
3289
|
+
return out;
|
|
3290
|
+
}
|
|
3291
|
+
/**
|
|
3292
|
+
* The lock entries that came from a source or the store (a `source:`, no `library:`), by
|
|
3293
|
+
* identity `<publisher>/<kind>:<name>` -> locked version. The lock's origin
|
|
3294
|
+
* wins: a library registered later that holds the same ref does not take such an asset
|
|
3295
|
+
* (`update`, `install`, `add`; OQ15, p1490).
|
|
3296
|
+
*/
|
|
3297
|
+
lockedOriginVersions() {
|
|
3298
|
+
const out = /* @__PURE__ */ new Map();
|
|
3299
|
+
for (const [key, e] of Object.entries(this.tryReadLock()?.assets ?? {})) {
|
|
3300
|
+
if (!e.source || e.library) continue;
|
|
3301
|
+
const { publisher, kind, name, version } = parseCanonicalLockKey(key);
|
|
3302
|
+
if (publisher && kind && name) out.set(`${publisher}/${kind}:${name}`, version ?? "");
|
|
3303
|
+
}
|
|
3304
|
+
return out;
|
|
3305
|
+
}
|
|
3306
|
+
/**
|
|
3307
|
+
* Say which registered library holds a ref the lock keeps on its source or the store: the
|
|
3308
|
+
* candidate that lost, with the way to switch (p1490). Printed once per `add`.
|
|
3309
|
+
*/
|
|
3310
|
+
async noteLosingLibraries(refs) {
|
|
3311
|
+
const lock = this.tryReadLock();
|
|
3312
|
+
for (const ref of refs) {
|
|
3313
|
+
const plain = ref.split("#")[0] ?? ref;
|
|
3314
|
+
let hit;
|
|
3315
|
+
try {
|
|
3316
|
+
hit = await this.resolveLibraryEntries([plain], { quiet: true });
|
|
3317
|
+
} catch {
|
|
3318
|
+
continue;
|
|
3319
|
+
}
|
|
3320
|
+
const entry = hit.entries[0];
|
|
3321
|
+
const library = entry ? hit.libraryOf.get(entry) : void 0;
|
|
3322
|
+
if (!entry || !library) continue;
|
|
3323
|
+
const canonical = canonicalEntryRef(entry);
|
|
3324
|
+
const plainCanonical = canonical.split("#")[0] ?? canonical;
|
|
3325
|
+
const lockedUrl = Object.entries(lock?.assets ?? {}).find(([k, e]) => {
|
|
3326
|
+
const id = parseCanonicalLockKey(k);
|
|
3327
|
+
return e.source && !e.library && `${id.kind}:@${id.publisher}/${id.name}` === plainCanonical;
|
|
3328
|
+
})?.[1].source?.url;
|
|
3329
|
+
if (lockedUrl) {
|
|
3330
|
+
const ownClone = (await this.loadLibraryIndex())?.libraries.some(
|
|
3331
|
+
(l) => l.name === library && l.ownership === "reader" && "url" in l.backendConfig && sourceCacheKey(l.backendConfig.url) === sourceCacheKey(lockedUrl)
|
|
3332
|
+
);
|
|
3333
|
+
if (ownClone) continue;
|
|
3334
|
+
}
|
|
3335
|
+
this.emitLibraryCollision(
|
|
3336
|
+
`${plainCanonical} is locked from ${lockedUrl ?? "its source"}, which wins; library "${library}" also holds it${entry.version ? ` (${entry.version})` : ""} and is not used. To switch, run \`skaile remove ${plainCanonical}\`, then \`skaile add ${plainCanonical}\`.`,
|
|
3337
|
+
[plainCanonical]
|
|
3338
|
+
);
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
2998
3341
|
// ── Store fetch-then-deploy ────────────────────────────────────────────
|
|
2999
3342
|
/** A candidate's stable identity key (`<publisher>/<kind>:<name>@<version>`). */
|
|
3000
3343
|
candidateKey(c) {
|
|
@@ -3154,10 +3497,19 @@ var AssetManager = class {
|
|
|
3154
3497
|
fresh.push(ref);
|
|
3155
3498
|
}
|
|
3156
3499
|
if (fresh.length === 0) break;
|
|
3500
|
+
const keepsOrigin = (ref) => {
|
|
3501
|
+
const id = refIdentity(ref);
|
|
3502
|
+
const locked = id !== null ? opts.lockedOrigin?.get(id) : void 0;
|
|
3503
|
+
if (locked === void 0) return false;
|
|
3504
|
+
const pin = ref.includes("#") ? ref.slice(ref.indexOf("#") + 1).trim() : void 0;
|
|
3505
|
+
return !pin || locked === "" || matchPin(pin, locked);
|
|
3506
|
+
};
|
|
3507
|
+
const originKept = fresh.filter(keepsOrigin);
|
|
3508
|
+
if (opts.warnCollisions && originKept.length > 0) await this.noteLosingLibraries(originKept);
|
|
3157
3509
|
const libraryTried = new Set(
|
|
3158
3510
|
fresh.filter((ref) => {
|
|
3159
3511
|
const id = refIdentity(ref);
|
|
3160
|
-
return id !== null && (opts.provenanceIndex.get(id)?.length ?? 0) === 0;
|
|
3512
|
+
return id !== null && (opts.provenanceIndex.get(id)?.length ?? 0) === 0 && !keepsOrigin(ref);
|
|
3161
3513
|
})
|
|
3162
3514
|
);
|
|
3163
3515
|
const hit = await this.resolveLibraryEntries([...libraryTried], {
|
|
@@ -3185,7 +3537,7 @@ var AssetManager = class {
|
|
|
3185
3537
|
}
|
|
3186
3538
|
presets.push(...r.presets);
|
|
3187
3539
|
const hit2 = await this.resolveLibraryEntries(
|
|
3188
|
-
r.missing.filter((m) => !libraryTried.has(m)),
|
|
3540
|
+
r.missing.filter((m) => !libraryTried.has(m) && !keepsOrigin(m)),
|
|
3189
3541
|
{
|
|
3190
3542
|
quiet: !opts.warnCollisions,
|
|
3191
3543
|
lockedLibraries: opts.lockedLibraries,
|
|
@@ -3488,7 +3840,8 @@ var AssetManager = class {
|
|
|
3488
3840
|
};
|
|
3489
3841
|
}
|
|
3490
3842
|
const orphans = await this.orphanedSourceGaps(
|
|
3491
|
-
await this.declaredLockKeys(lockForLibraries, dependencies)
|
|
3843
|
+
await this.declaredLockKeys(lockForLibraries, dependencies),
|
|
3844
|
+
true
|
|
3492
3845
|
);
|
|
3493
3846
|
if (orphans.size > 0) {
|
|
3494
3847
|
return {
|
|
@@ -3531,6 +3884,7 @@ var AssetManager = class {
|
|
|
3531
3884
|
// library holding the same ref does not move a locked asset. `update` re-resolves.
|
|
3532
3885
|
...opts?.moveLibraries ? { preferLocked: await this.lockedPreference() } : { lockedLibraries: await this.lockedLibraryNames() },
|
|
3533
3886
|
...keepLocked ? { keepLocked } : {},
|
|
3887
|
+
lockedOrigin: this.lockedOriginVersions(),
|
|
3534
3888
|
readStoreRequires: true
|
|
3535
3889
|
});
|
|
3536
3890
|
this.assertNoFolderCollision([...resolved, ...lib.entries.map((e) => this.entryIdentity(e))]);
|
|
@@ -3574,7 +3928,7 @@ var AssetManager = class {
|
|
|
3574
3928
|
const missingHints = await this.publisherChangeHints(stillMissing);
|
|
3575
3929
|
const prevLock = this.tryReadLock();
|
|
3576
3930
|
const kept = keptLockEntries(prevLock, stillMissing);
|
|
3577
|
-
const storeNotChecked = this.storeNotCheckedRefs(
|
|
3931
|
+
const storeNotChecked = await this.storeNotCheckedRefs(
|
|
3578
3932
|
kept,
|
|
3579
3933
|
sources.map((s) => s.url)
|
|
3580
3934
|
);
|
|
@@ -3582,7 +3936,7 @@ var AssetManager = class {
|
|
|
3582
3936
|
for (const ref of /* @__PURE__ */ new Set([...kept.refs, ...fixes.keys()])) {
|
|
3583
3937
|
const fix = fixes.get(ref);
|
|
3584
3938
|
const notes = [
|
|
3585
|
-
kept.refs.has(ref) ? this.keptCopyDeployed(kept, ref) ? "the deployed copy and its lock entry are kept" : "its lock entry is kept; no deployed copy exists" : void 0,
|
|
3939
|
+
kept.refs.has(ref) ? await this.keptCopyDeployed(kept, ref) ? "the deployed copy and its lock entry are kept" : "its lock entry is kept; no deployed copy exists" : void 0,
|
|
3586
3940
|
fix
|
|
3587
3941
|
].filter((n) => n !== void 0);
|
|
3588
3942
|
missingHints[ref] = `${fix ? "" : missingHints[ref] ?? ""} (${notes.join("; ")})`;
|
|
@@ -3601,12 +3955,24 @@ var AssetManager = class {
|
|
|
3601
3955
|
const entries = [...await this.buildCatalogEntries(resolved, repositories), ...lib.entries];
|
|
3602
3956
|
assertFlowsLoad(entries, "installed");
|
|
3603
3957
|
assertNoLibrarySymlinks(entries, this.registry, repositories, opts?.link === true);
|
|
3958
|
+
const forceCommand = opts?.moveLibraries === true ? "skaile update --force" : "skaile install --force";
|
|
3604
3959
|
if (!opts?.force) {
|
|
3605
3960
|
await this.assertNoHandEditsPruned(
|
|
3606
3961
|
resolved,
|
|
3607
|
-
/* @__PURE__ */ new Set([...Object.keys(libraryLock), ...Object.keys(kept.assets)])
|
|
3962
|
+
/* @__PURE__ */ new Set([...Object.keys(libraryLock), ...Object.keys(kept.assets)]),
|
|
3963
|
+
forceCommand
|
|
3608
3964
|
);
|
|
3609
3965
|
}
|
|
3966
|
+
const relockRemoved = await this.relockDeletions(
|
|
3967
|
+
entries,
|
|
3968
|
+
prevLock,
|
|
3969
|
+
withKeptLockEntries(freshLock, kept),
|
|
3970
|
+
opts?.force === true,
|
|
3971
|
+
forceCommand,
|
|
3972
|
+
lib.libraryOf
|
|
3973
|
+
);
|
|
3974
|
+
if (!opts?.force) this.assertNoUnrecordedAgentOverwrite(entries, prevLock, forceCommand);
|
|
3975
|
+
const inferredHarnesses = this.inferLegacyHarnessSubsets(entries);
|
|
3610
3976
|
const { removed, replaced } = this.reconcileRemovedAssets(
|
|
3611
3977
|
resolved,
|
|
3612
3978
|
/* @__PURE__ */ new Set([...Object.keys(libraryLock), ...Object.keys(kept.assets)])
|
|
@@ -3614,6 +3980,7 @@ var AssetManager = class {
|
|
|
3614
3980
|
const copyDrift = await this.lockedCopyDrift();
|
|
3615
3981
|
const missingCopies = await this.incompleteDeploys();
|
|
3616
3982
|
const unrecordedAgents = this.unrecordedAgentFiles(prevLock);
|
|
3983
|
+
const composedDrift = /* @__PURE__ */ new Set();
|
|
3617
3984
|
const deployed = [
|
|
3618
3985
|
...new Set(
|
|
3619
3986
|
this.targetHarnesses().flatMap(
|
|
@@ -3621,22 +3988,32 @@ var AssetManager = class {
|
|
|
3621
3988
|
this.entriesForHarness(entries, t),
|
|
3622
3989
|
repositories,
|
|
3623
3990
|
patches,
|
|
3624
|
-
this.deployOptsFor(t, opts?.link
|
|
3991
|
+
this.deployOptsFor(t, opts?.link, void 0, {
|
|
3992
|
+
refresh: opts?.moveLibraries === true,
|
|
3993
|
+
onDrift: (ref, composeRef) => composedDrift.add(this.composedDriftLine(ref, composeRef))
|
|
3994
|
+
})
|
|
3625
3995
|
)
|
|
3626
3996
|
)
|
|
3627
3997
|
)
|
|
3628
3998
|
];
|
|
3629
3999
|
this.sweepLegacyOmpCopies(entries);
|
|
3630
|
-
const mcpRestored = await this.
|
|
4000
|
+
const mcpRestored = await this.renderHarnessMcpConfig();
|
|
3631
4001
|
const agentRender = await this.renderAgentInstances();
|
|
3632
|
-
const restored = [
|
|
4002
|
+
const restored = [
|
|
4003
|
+
...this.restoredCopies(copyDrift, deployed, missingCopies),
|
|
4004
|
+
...relockRemoved,
|
|
4005
|
+
...mcpRestored
|
|
4006
|
+
];
|
|
3633
4007
|
const rewritten = this.rewrittenAgentFiles(unrecordedAgents);
|
|
3634
4008
|
const lockWanted = resolved.length > 0 || lib.entries.length > 0 || existsSync(this.lockPath);
|
|
3635
4009
|
let lockWritten = false;
|
|
3636
4010
|
let relocked = [];
|
|
3637
4011
|
let moved = [];
|
|
3638
4012
|
if (lockWanted) {
|
|
3639
|
-
const lockData = this.withRenderedAgents(
|
|
4013
|
+
const lockData = this.withRenderedAgents(
|
|
4014
|
+
withKeptLockEntries(freshLock, kept),
|
|
4015
|
+
opts?.moveLibraries ? void 0 : prevLock
|
|
4016
|
+
);
|
|
3640
4017
|
moved = libraryMoves(prevLock, libraryLock);
|
|
3641
4018
|
const movedRefs = new Set(moved.map((m) => m.ref));
|
|
3642
4019
|
relocked = relockedRefs(prevLock, lockData).filter((k) => !movedRefs.has(k.split("#")[0]));
|
|
@@ -3652,12 +4029,17 @@ var AssetManager = class {
|
|
|
3652
4029
|
return {
|
|
3653
4030
|
deployed,
|
|
3654
4031
|
removed,
|
|
3655
|
-
missing: [
|
|
4032
|
+
missing: [
|
|
4033
|
+
...reportedMissing,
|
|
4034
|
+
...versionBlocked.filter((b) => !reportedMissing.includes(b)),
|
|
4035
|
+
...composedDrift
|
|
4036
|
+
],
|
|
3656
4037
|
...placeholderBodies.length > 0 ? { placeholderBodies } : {},
|
|
3657
4038
|
...placeholderDescriptions.length > 0 ? { placeholderDescriptions } : {},
|
|
3658
4039
|
...storeNotChecked.length > 0 ? { storeNotChecked } : {},
|
|
3659
4040
|
...Object.keys(missingHints).length > 0 ? { missingHints } : {},
|
|
3660
4041
|
...relocked.length > 0 ? { relocked } : {},
|
|
4042
|
+
...inferredHarnesses.length > 0 ? { inferredHarnesses } : {},
|
|
3661
4043
|
...moved.length > 0 ? { moved } : {},
|
|
3662
4044
|
...replaced.length > 0 ? { replaced } : {},
|
|
3663
4045
|
...restored.length > 0 ? { restored } : {},
|
|
@@ -3678,7 +4060,7 @@ var AssetManager = class {
|
|
|
3678
4060
|
* @param declaredSourceUrls - The `sources:` URLs of `skaile.yaml`; a lock entry from one of
|
|
3679
4061
|
* them is that source's, not the store's.
|
|
3680
4062
|
*/
|
|
3681
|
-
storeNotCheckedRefs(kept, declaredSourceUrls) {
|
|
4063
|
+
async storeNotCheckedRefs(kept, declaredSourceUrls) {
|
|
3682
4064
|
const skipped = this.catalogUrlOverride === "";
|
|
3683
4065
|
if (!skipped && this.storeFailures.size === 0) return [];
|
|
3684
4066
|
const declared = new Set(declaredSourceUrls.map(normalizeRepoUrl));
|
|
@@ -3689,7 +4071,7 @@ var AssetManager = class {
|
|
|
3689
4071
|
const entry = kept.assets[key];
|
|
3690
4072
|
return entry !== void 0 && !entry.library && entry.source !== void 0 && !declared.has(normalizeRepoUrl(entry.source.url));
|
|
3691
4073
|
});
|
|
3692
|
-
if (!fromStore || !this.keptCopyDeployed(kept, ref)) continue;
|
|
4074
|
+
if (!fromStore || !await this.keptCopyDeployed(kept, ref)) continue;
|
|
3693
4075
|
if (skipped && this.storeFailures.size === 0) {
|
|
3694
4076
|
out.push({ ref, reason: "skipped", detail: "--no-catalog: the store was not asked" });
|
|
3695
4077
|
continue;
|
|
@@ -3745,7 +4127,7 @@ var AssetManager = class {
|
|
|
3745
4127
|
const locked = this.lockedRequirementsOf(id);
|
|
3746
4128
|
const withLocked = (scanned) => [.../* @__PURE__ */ new Set([...scanned, ...locked])];
|
|
3747
4129
|
const keptAgent = kind === "agent" && !this.global ? join(agentSourceCacheDir(this.projectDir), name) : null;
|
|
3748
|
-
const dir = keptAgent && existsSync(keptAgent) ? keptAgent : deployedDir(component, name, this.
|
|
4130
|
+
const dir = keptAgent && existsSync(keptAgent) ? keptAgent : deployedDir(component, name, this.harness, this.global, this.projectDir);
|
|
3749
4131
|
if (!existsSync(dir)) return withLocked([]);
|
|
3750
4132
|
try {
|
|
3751
4133
|
const scanned = await scanDirectory(dir, publisher ?? "", { knownKinds: this.knownKinds });
|
|
@@ -3835,7 +4217,7 @@ var AssetManager = class {
|
|
|
3835
4217
|
* other version taking its place) whose deployed folder holds hand edits: the files that differ
|
|
3836
4218
|
* from the lock are named, nothing is removed, and `--force` prunes anyway (OQ6).
|
|
3837
4219
|
*/
|
|
3838
|
-
async assertNoHandEditsPruned(resolved, keep) {
|
|
4220
|
+
async assertNoHandEditsPruned(resolved, keep, forceCommand) {
|
|
3839
4221
|
const oldLock = this.tryReadLock();
|
|
3840
4222
|
if (!oldLock) return;
|
|
3841
4223
|
const resolvedRefs = [
|
|
@@ -3867,7 +4249,158 @@ var AssetManager = class {
|
|
|
3867
4249
|
throw new Error(
|
|
3868
4250
|
`Not pruned: skaile.yaml no longer declares ${lines.length === 1 ? "an asset" : "assets"} whose deployed copy holds your edits:
|
|
3869
4251
|
${lines.join("\n ")}
|
|
3870
|
-
Nothing was changed. Declare it again to keep it, or run \`
|
|
4252
|
+
Nothing was changed. Declare it again to keep it, or run \`${forceCommand}\` to prune it with its edits.`
|
|
4253
|
+
);
|
|
4254
|
+
}
|
|
4255
|
+
/**
|
|
4256
|
+
* Report (and, without `force`, guard) the files a re-lock deletes from a deployed copy
|
|
4257
|
+
* (OQ5, p1441): the asset is locked already and its library or source now holds other content
|
|
4258
|
+
* (`next` re-locks it), and the deployed folder holds files the new content does not ship. The
|
|
4259
|
+
* deploy clears them. Two cases:
|
|
4260
|
+
* - the deployed copy still equals what `prevLock` recorded (per-file sha256 for a source
|
|
4261
|
+
* or store asset, the library hash for a library asset): the new version dropped those
|
|
4262
|
+
* files, nobody edited them, so they are deleted and come back as `removed` rows (an
|
|
4263
|
+
* `install`/`update` prints `Removed <file> (not part of <ref>)`), without a refusal;
|
|
4264
|
+
* - the copy diverged (a file the previous content did not ship, an edited file, or no hash
|
|
4265
|
+
* to compare): without `force` this throws one error naming the files and changes nothing.
|
|
4266
|
+
* A source or store asset names only the files the previous content did not ship (or that
|
|
4267
|
+
* were edited); a library asset records no file list, so it names every file to delete.
|
|
4268
|
+
*
|
|
4269
|
+
* @param entries - The catalog entries about to be deployed.
|
|
4270
|
+
* @param next - The lock the run is about to write (or merge).
|
|
4271
|
+
* @param libraryOf - The library each library-origin entry came from.
|
|
4272
|
+
*/
|
|
4273
|
+
async relockDeletions(entries, prevLock, next, force, forceCommand, libraryOf) {
|
|
4274
|
+
if (!prevLock) return [];
|
|
4275
|
+
const relocked = relockedRefs(prevLock, next).map((key) => ({
|
|
4276
|
+
key,
|
|
4277
|
+
id: parseCanonicalLockKey(key)
|
|
4278
|
+
}));
|
|
4279
|
+
if (relocked.length === 0) return [];
|
|
4280
|
+
const shown = (p) => (this.global ? p : relative(this.projectDir, p)).split(sep).join("/");
|
|
4281
|
+
let snap;
|
|
4282
|
+
const rows = [];
|
|
4283
|
+
const refused = [];
|
|
4284
|
+
for (const e of entries) {
|
|
4285
|
+
const hit = relocked.find(({ id }) => id.kind === e.kind && id.name === e.name);
|
|
4286
|
+
const component = hit ? this.installTarget(e.kind) : void 0;
|
|
4287
|
+
if (!hit || !component) continue;
|
|
4288
|
+
const prevEntry = Object.entries(prevLock.assets).find(([k]) => {
|
|
4289
|
+
const o = parseCanonicalLockKey(k);
|
|
4290
|
+
return o.kind === hit.id.kind && o.name === hit.id.name && o.publisher === hit.id.publisher;
|
|
4291
|
+
})?.[1];
|
|
4292
|
+
const removed = [];
|
|
4293
|
+
const blocked = [];
|
|
4294
|
+
for (const t of this.targetHarnesses()) {
|
|
4295
|
+
const drift = deployedAssetDrift(e, this.deployOptsFor(t));
|
|
4296
|
+
if (!drift || drift.extra.length === 0) continue;
|
|
4297
|
+
const dir = deployedDir(component, e.name, t, this.global, this.projectDir);
|
|
4298
|
+
const files = drift.extra;
|
|
4299
|
+
let untouched;
|
|
4300
|
+
if (prevEntry && prevEntry.files.length > 0) {
|
|
4301
|
+
const locked = new Map(
|
|
4302
|
+
lockedAssetFiles(e.kind, prevEntry.files).map((f) => [f.rel, f.sha256])
|
|
4303
|
+
);
|
|
4304
|
+
untouched = files.filter((rel) => {
|
|
4305
|
+
const want = locked.get(rel);
|
|
4306
|
+
if (want === void 0) return false;
|
|
4307
|
+
try {
|
|
4308
|
+
return computeHash(join(dir, rel)) === want;
|
|
4309
|
+
} catch {
|
|
4310
|
+
return false;
|
|
4311
|
+
}
|
|
4312
|
+
});
|
|
4313
|
+
} else if (prevEntry?.library?.sha256 && !prevEntry.library.installed) {
|
|
4314
|
+
const libName = libraryOf.get(e);
|
|
4315
|
+
snap ??= await this.loadLibraryIndex();
|
|
4316
|
+
const libPath = libName ? this.libraryPath({ name: libName }, snap) : null;
|
|
4317
|
+
if (libPath) {
|
|
4318
|
+
const assetRoot = statSync(e.source).isDirectory() ? e.source : dirname(e.source);
|
|
4319
|
+
const hash = computeDeterministicHash(
|
|
4320
|
+
dir,
|
|
4321
|
+
listAssetFiles(dir),
|
|
4322
|
+
posix.normalize(relative(libPath, assetRoot).split(sep).join("/"))
|
|
4323
|
+
);
|
|
4324
|
+
if (hash === prevEntry.library.sha256) untouched = [...files];
|
|
4325
|
+
}
|
|
4326
|
+
}
|
|
4327
|
+
const own = new Set(untouched ?? []);
|
|
4328
|
+
for (const f of files) (own.has(f) ? removed : blocked).push(shown(join(dir, f)));
|
|
4329
|
+
}
|
|
4330
|
+
if (removed.length > 0) rows.push({ ref: hit.key, restored: [], removed });
|
|
4331
|
+
if (blocked.length > 0) refused.push({ ref: hit.key, restored: [], removed: blocked });
|
|
4332
|
+
}
|
|
4333
|
+
if (refused.length === 0 || force) return [...rows, ...refused];
|
|
4334
|
+
const lines = refused.map((r) => `${r.ref} (${r.removed.join(", ")})`);
|
|
4335
|
+
throw new Error(
|
|
4336
|
+
`Not re-locked: the deployed copy of ${refused.length === 1 ? "an asset" : "assets"} holds files its locked content did not ship or that were edited, and the deploy would delete them:
|
|
4337
|
+
${lines.join("\n ")}
|
|
4338
|
+
Nothing was changed. Copy what you need, or run \`${forceCommand}\` to delete them.`
|
|
4339
|
+
);
|
|
4340
|
+
}
|
|
4341
|
+
/**
|
|
4342
|
+
* Stop `install` from overwriting a hand-edited rendered agent file that no lock entry
|
|
4343
|
+
* records (OQ5, p1440): the lock is gone (or never held the agent), so nothing tells an edit
|
|
4344
|
+
* from a stale render, and the deploy would replace the file without a word. Checks the file
|
|
4345
|
+
* named after each agent about to be deployed and the file of each agent instance whose bound
|
|
4346
|
+
* agent has no lock entry. Throws one error naming each file that exists and differs from its
|
|
4347
|
+
* render and changes nothing; `--force` (the caller skips this check) overwrites. A file that
|
|
4348
|
+
* equals its render is not an edit. Project mode only.
|
|
4349
|
+
*/
|
|
4350
|
+
assertNoUnrecordedAgentOverwrite(entries, prevLock, forceCommand) {
|
|
4351
|
+
if (this.global) return;
|
|
4352
|
+
const lockedAgents = new Set(
|
|
4353
|
+
Object.keys(prevLock?.assets ?? {}).map(parseCanonicalLockKey).filter((k) => k.kind && this.installTarget(k.kind) === "agent").map((k) => k.name)
|
|
4354
|
+
);
|
|
4355
|
+
const opts = this.deployOptsFor(this.harness);
|
|
4356
|
+
const lines = /* @__PURE__ */ new Set();
|
|
4357
|
+
const collect = (diff, what) => {
|
|
4358
|
+
if (!diff) return;
|
|
4359
|
+
for (const m of diff.matchAll(/^--- (.+?)\t/gm)) {
|
|
4360
|
+
const abs = m[1];
|
|
4361
|
+
if (!existsSync(abs)) continue;
|
|
4362
|
+
lines.add(
|
|
4363
|
+
`${relative(this.projectDir, abs).split(sep).join("/")} (${what} differs from its render)`
|
|
4364
|
+
);
|
|
4365
|
+
}
|
|
4366
|
+
};
|
|
4367
|
+
for (const e of entries) {
|
|
4368
|
+
if (this.installTarget(e.kind) !== "agent" || lockedAgents.has(e.name)) continue;
|
|
4369
|
+
try {
|
|
4370
|
+
collect(diffDeployedAgent(e, opts), `agent ${e.name}`);
|
|
4371
|
+
} catch {
|
|
4372
|
+
}
|
|
4373
|
+
}
|
|
4374
|
+
let instances = {};
|
|
4375
|
+
try {
|
|
4376
|
+
instances = effectiveAgentInstances(resolveSkWorkspaceConfig(this.projectDir));
|
|
4377
|
+
} catch {
|
|
4378
|
+
}
|
|
4379
|
+
for (const [id, config] of Object.entries(instances)) {
|
|
4380
|
+
if (!config.ref.startsWith("agent:")) continue;
|
|
4381
|
+
const bound = parseRefTolerant(config.ref);
|
|
4382
|
+
if (bound?.kind === "agent" && lockedAgents.has(bound.name)) continue;
|
|
4383
|
+
try {
|
|
4384
|
+
const srcDir = resolveAgentDefinitionDir(this.projectDir, config.ref);
|
|
4385
|
+
if (srcDir === void 0) continue;
|
|
4386
|
+
const entry = {
|
|
4387
|
+
kind: "agent",
|
|
4388
|
+
name: id,
|
|
4389
|
+
description: "",
|
|
4390
|
+
source: srcDir,
|
|
4391
|
+
version: "",
|
|
4392
|
+
requires: [],
|
|
4393
|
+
dependencies: []
|
|
4394
|
+
};
|
|
4395
|
+
collect(diffDeployedAgent(entry, opts, { id, srcDir, config }), `agent instance ${id}`);
|
|
4396
|
+
} catch {
|
|
4397
|
+
}
|
|
4398
|
+
}
|
|
4399
|
+
if (lines.size === 0) return;
|
|
4400
|
+
throw new Error(
|
|
4401
|
+
`Not deployed: the deploy would overwrite ${lines.size === 1 ? "a rendered agent file" : "rendered agent files"} that no lock entry records:
|
|
4402
|
+
${[...lines].join("\n ")}
|
|
4403
|
+
Nothing was changed. Move your edits away, or run \`${forceCommand}\` to overwrite the file.`
|
|
3871
4404
|
);
|
|
3872
4405
|
}
|
|
3873
4406
|
/**
|
|
@@ -4095,7 +4628,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4095
4628
|
}
|
|
4096
4629
|
assertLockHashes(lock);
|
|
4097
4630
|
this.assertNoFolderCollision(Object.keys(lock.assets).map(parseCanonicalLockKey));
|
|
4098
|
-
const orphaned = [...(await this.orphanedSourceGaps()).values()];
|
|
4631
|
+
const orphaned = [...(await this.orphanedSourceGaps(void 0, true)).values()];
|
|
4099
4632
|
if (orphaned.length > 0) {
|
|
4100
4633
|
throw new Error(
|
|
4101
4634
|
`Lock file verification failed:
|
|
@@ -4170,12 +4703,14 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4170
4703
|
throw new Error(`Lock file verification failed:
|
|
4171
4704
|
${reason}`);
|
|
4172
4705
|
}
|
|
4173
|
-
const library = await this.restoreLibraryLockEntries(lock);
|
|
4706
|
+
const library = await this.restoreLibraryLockEntries(lock, { storeFallback: true });
|
|
4174
4707
|
assertFlowsLoad([...resolved, ...library.entries], "installed");
|
|
4175
4708
|
assertNoLibrarySymlinks([...resolved, ...library.entries], this.registry, repositories);
|
|
4709
|
+
const inferredHarnesses = this.inferLegacyHarnessSubsets([...resolved, ...library.entries]);
|
|
4176
4710
|
const copyDrift = await this.lockedCopyDrift();
|
|
4177
4711
|
const missingCopies = await this.incompleteDeploys();
|
|
4178
4712
|
const unrecordedAgents = this.unrecordedAgentFiles(lock);
|
|
4713
|
+
const composedDrift = /* @__PURE__ */ new Set();
|
|
4179
4714
|
const deployed = [
|
|
4180
4715
|
...new Set(
|
|
4181
4716
|
this.targetHarnesses().flatMap(
|
|
@@ -4183,13 +4718,16 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4183
4718
|
this.entriesForHarness([...resolved, ...library.entries], t),
|
|
4184
4719
|
repositories,
|
|
4185
4720
|
patches,
|
|
4186
|
-
this.deployOptsFor(t
|
|
4721
|
+
this.deployOptsFor(t, void 0, void 0, {
|
|
4722
|
+
refresh: false,
|
|
4723
|
+
onDrift: (ref, composeRef) => composedDrift.add(this.composedDriftLine(ref, composeRef))
|
|
4724
|
+
})
|
|
4187
4725
|
)
|
|
4188
4726
|
)
|
|
4189
4727
|
)
|
|
4190
4728
|
];
|
|
4191
4729
|
this.sweepLegacyOmpCopies([...resolved, ...library.entries]);
|
|
4192
|
-
const mcpRestored = await this.
|
|
4730
|
+
const mcpRestored = await this.renderHarnessMcpConfig();
|
|
4193
4731
|
const agentRender = await this.renderAgentInstances();
|
|
4194
4732
|
const restored = [...this.restoredCopies(copyDrift, deployed, missingCopies), ...mcpRestored];
|
|
4195
4733
|
const rewritten = this.rewrittenAgentFiles(unrecordedAgents);
|
|
@@ -4201,6 +4739,8 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4201
4739
|
);
|
|
4202
4740
|
const gaps = (await this.projectState()).gaps.filter((g) => {
|
|
4203
4741
|
if (g.type === "agent") return false;
|
|
4742
|
+
if (g.unreadableSource) return false;
|
|
4743
|
+
if (g.type === "library" && library.viaStore.includes(g.ref)) return false;
|
|
4204
4744
|
const p = parseRefTolerant(g.ref);
|
|
4205
4745
|
return !(p && alreadyMissing.has(`${p.kind}:${p.name}`));
|
|
4206
4746
|
}).map((g) => g.message);
|
|
@@ -4209,10 +4749,11 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4209
4749
|
return {
|
|
4210
4750
|
deployed,
|
|
4211
4751
|
removed: [],
|
|
4212
|
-
missing: [...library.missing, ...gaps],
|
|
4752
|
+
missing: [...library.missing, ...gaps, ...composedDrift],
|
|
4213
4753
|
...placeholderBodies.length > 0 ? { placeholderBodies } : {},
|
|
4214
4754
|
...placeholderDescriptions.length > 0 ? { placeholderDescriptions } : {},
|
|
4215
4755
|
lockWritten: false,
|
|
4756
|
+
...inferredHarnesses.length > 0 ? { inferredHarnesses } : {},
|
|
4216
4757
|
...restored.length > 0 ? { restored } : {},
|
|
4217
4758
|
...rewritten.length > 0 ? { rewritten } : {},
|
|
4218
4759
|
...agentRender
|
|
@@ -4240,6 +4781,72 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4240
4781
|
}
|
|
4241
4782
|
return [...found].sort((a, b) => gt(coerceVersion(a), coerceVersion(b)) ? -1 : 1);
|
|
4242
4783
|
}
|
|
4784
|
+
/**
|
|
4785
|
+
* The refs of the other kinds that a source or a library holds under the same publisher and
|
|
4786
|
+
* name as `parsed` (`agent:@pub/captain` for a `@pub/captain` that is no skill), for the
|
|
4787
|
+
* `Did you mean` of an `add` that missed.
|
|
4788
|
+
*/
|
|
4789
|
+
async otherKindRefs(parsed) {
|
|
4790
|
+
if (!parsed.publisher) return [];
|
|
4791
|
+
const publisher = parsed.publisher.replace(/^@/, "");
|
|
4792
|
+
const found = [];
|
|
4793
|
+
for (const kind of [...this.knownKinds].sort()) {
|
|
4794
|
+
if (kind === parsed.kind) continue;
|
|
4795
|
+
const candidate = `${kind}:@${publisher}/${parsed.name}`;
|
|
4796
|
+
try {
|
|
4797
|
+
if (await this.info(candidate) !== null) found.push(candidate);
|
|
4798
|
+
} catch {
|
|
4799
|
+
}
|
|
4800
|
+
}
|
|
4801
|
+
return found;
|
|
4802
|
+
}
|
|
4803
|
+
/**
|
|
4804
|
+
* What `add` would deploy for the resolved candidates and library entries, without touching
|
|
4805
|
+
* the project: one item per asset with its origin, version, deploy folders and files.
|
|
4806
|
+
*/
|
|
4807
|
+
planAddItems(resolved, lib, stores, parsed) {
|
|
4808
|
+
const storeUrls = new Set(stores.map((s) => normalizeRepoUrl(s.url)));
|
|
4809
|
+
const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);
|
|
4810
|
+
const folders = (kind, name) => {
|
|
4811
|
+
const component = this.installTarget(kind);
|
|
4812
|
+
if (!component) return [];
|
|
4813
|
+
return this.targetHarnesses().map((t) => {
|
|
4814
|
+
const dir = deployedDir(component, name, t, this.global, this.projectDir);
|
|
4815
|
+
const rel = relative(this.projectDir, dir);
|
|
4816
|
+
const shown = this.global || rel.startsWith("..") ? dir.replace(homedir(), "~") : `${rel}${dir.endsWith(sep) ? sep : ""}`;
|
|
4817
|
+
return shown;
|
|
4818
|
+
});
|
|
4819
|
+
};
|
|
4820
|
+
const asked = (kind, name, publisher) => kind === parsed.kind && name === parsed.name && (!parsed.publisher || (publisher ?? "").replace(/^@/, "") === parsed.publisher.replace(/^@/, ""));
|
|
4821
|
+
const items = [];
|
|
4822
|
+
for (const c of resolved) {
|
|
4823
|
+
const url = normalizeRepoUrl(c.sourceUrl);
|
|
4824
|
+
items.push({
|
|
4825
|
+
ref: assetRefToStr({
|
|
4826
|
+
kind: c.kind,
|
|
4827
|
+
name: c.name,
|
|
4828
|
+
publisher: c.publisher.replace(/^@/, "")
|
|
4829
|
+
}),
|
|
4830
|
+
version: c.version,
|
|
4831
|
+
origin: storeUrls.has(url) ? `store ${c.sourceUrl}` : url === factoryUrl ? "factory" : `source ${sourceShortName(c.sourceUrl)}`,
|
|
4832
|
+
requested: asked(c.kind, c.name, c.publisher),
|
|
4833
|
+
folders: folders(c.kind, c.name),
|
|
4834
|
+
files: c.files.map((f) => f.path)
|
|
4835
|
+
});
|
|
4836
|
+
}
|
|
4837
|
+
for (const e of lib.entries) {
|
|
4838
|
+
const id = this.entryIdentity(e);
|
|
4839
|
+
items.push({
|
|
4840
|
+
ref: canonicalEntryRef(e),
|
|
4841
|
+
version: e.version ?? "",
|
|
4842
|
+
origin: `library ${lib.libraryOf.get(e) ?? ""}`.trim(),
|
|
4843
|
+
requested: asked(e.kind, e.name, id.publisher),
|
|
4844
|
+
folders: folders(e.kind, e.name),
|
|
4845
|
+
files: [...e.files ?? []]
|
|
4846
|
+
});
|
|
4847
|
+
}
|
|
4848
|
+
return items.sort((a, b) => Number(b.requested) - Number(a.requested));
|
|
4849
|
+
}
|
|
4243
4850
|
/**
|
|
4244
4851
|
* Parse the ref `add` was given. A ref the grammar rejects fails with the parser's message
|
|
4245
4852
|
* minus its manifest-migration advice (it points at a skill that is not for `add`), and:
|
|
@@ -4257,7 +4864,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4257
4864
|
const plain = err.message.endsWith(advice) ? err.message.slice(0, -advice.length) : err.message;
|
|
4258
4865
|
if (plain.startsWith("publisher required")) {
|
|
4259
4866
|
const matches = await this.resolvableMatches(ref, repositories, sources);
|
|
4260
|
-
const hint = matches.length === 0 ? "" : matches.length === 1 ? ` Did you mean ${matches[0]}?` : ` Did you mean one of: ${matches.join(", ")}?`;
|
|
4867
|
+
const hint = matches.length === 0 ? ` Find the publisher with \`skaile store search ${ref.trim().replace(/^[^:@/#\s]+:/, "").replace(/#.*$/, "")}\`.` : matches.length === 1 ? ` Did you mean ${matches[0]}?` : ` Did you mean one of: ${matches.join(", ")}?`;
|
|
4261
4868
|
throw new Error(`${plain}${hint}`);
|
|
4262
4869
|
}
|
|
4263
4870
|
const pinned = /^(.*\/[^@#/]+)@([^@#/]+)$/.exec(ref.trim());
|
|
@@ -4338,6 +4945,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4338
4945
|
stores,
|
|
4339
4946
|
declaredRefs: dependencies,
|
|
4340
4947
|
warnCollisions: true,
|
|
4948
|
+
lockedOrigin: this.lockedOriginVersions(),
|
|
4341
4949
|
readStoreRequires: true,
|
|
4342
4950
|
...opts?.preferLockedLibrary ? { preferLocked: await this.lockedPreference() } : {}
|
|
4343
4951
|
});
|
|
@@ -4381,8 +4989,9 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4381
4989
|
);
|
|
4382
4990
|
}
|
|
4383
4991
|
const available = await this.availableVersions(parsed, stores);
|
|
4992
|
+
const otherKinds = /^[^@/#\s]+:/.test(ref.trim()) ? [] : await this.otherKindRefs(parsed);
|
|
4384
4993
|
throw new Error(
|
|
4385
|
-
`Asset not found: ${ref}${(await this.publisherChangeHints([ref]))[ref] ?? ""}${missing.length ? ` (missing: ${missing.join(", ")})` : ""}${available.length ? `; ${parsed.name} has version(s): ${available.join(", ")}` : ""}`
|
|
4994
|
+
`Asset not found: ${ref}${(await this.publisherChangeHints([ref]))[ref] ?? ""}${missing.length ? ` (missing: ${missing.join(", ")})` : ""}${available.length ? `; ${parsed.name} has version(s): ${available.join(", ")}` : ""}` + (otherKinds.length === 0 ? "" : otherKinds.length === 1 ? `. Did you mean ${otherKinds[0]}?` : `. Did you mean one of: ${otherKinds.join(", ")}?`)
|
|
4386
4995
|
);
|
|
4387
4996
|
}
|
|
4388
4997
|
if (parsed.kind === "preset" && missing.length > 0) {
|
|
@@ -4405,6 +5014,62 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4405
5014
|
)
|
|
4406
5015
|
);
|
|
4407
5016
|
}
|
|
5017
|
+
const problems = origin && libPath && !(e.kind === "flow" && flowLoadError(e) !== void 0) ? libraryAssetCheck?.({ kind: e.kind, name: e.name, source: e.source }, libPath) ?? [] : [];
|
|
5018
|
+
if (problems.length > 0) {
|
|
5019
|
+
throw new Error(
|
|
5020
|
+
`${canonicalEntryRef(e)} in library "${origin}" fails the checks of \`skaile validate\` - nothing was added:
|
|
5021
|
+
${problems.map((l) => ` ${l}`).join("\n")}
|
|
5022
|
+
Fix the asset, then run \`skaile library index ${origin}\` and add it again.`
|
|
5023
|
+
);
|
|
5024
|
+
}
|
|
5025
|
+
}
|
|
5026
|
+
}
|
|
5027
|
+
if (libraryAssetCheck) {
|
|
5028
|
+
for (const c of resolved) {
|
|
5029
|
+
const decl = Object.entries(repositories).find(([, d]) => d.url === c.sourceUrl);
|
|
5030
|
+
const cloneDir = decl ? this.resolveRepoDir(decl[1], decl[0]) : null;
|
|
5031
|
+
const entry = cloneDir ? this.candidateToCatalogEntry(c, repositories) : null;
|
|
5032
|
+
if (!cloneDir || !entry) continue;
|
|
5033
|
+
if (entry.kind === "flow" && flowLoadError(entry) !== void 0) continue;
|
|
5034
|
+
const problems = libraryAssetCheck(
|
|
5035
|
+
{ kind: entry.kind, name: entry.name, source: entry.source },
|
|
5036
|
+
cloneDir
|
|
5037
|
+
);
|
|
5038
|
+
if (problems.length > 0) {
|
|
5039
|
+
throw new Error(
|
|
5040
|
+
`${canonicalEntryRef(entry)} from source ${c.sourceUrl} fails the checks of \`skaile validate\` - nothing was added:
|
|
5041
|
+
${problems.map((l) => ` ${l}`).join("\n")}
|
|
5042
|
+
Fix the asset in the source repo, then run \`skaile source sync\` and add it again.`
|
|
5043
|
+
);
|
|
5044
|
+
}
|
|
5045
|
+
}
|
|
5046
|
+
}
|
|
5047
|
+
const staleSiblings = this.staleSourceSiblingRefs(resolved, dependencies);
|
|
5048
|
+
if (staleSiblings.length > 0) {
|
|
5049
|
+
const siblings = await this.resolveLibraryFirst(staleSiblings, {
|
|
5050
|
+
provenanceIndex,
|
|
5051
|
+
overrides,
|
|
5052
|
+
stores,
|
|
5053
|
+
declaredRefs: dependencies,
|
|
5054
|
+
lockedOrigin: this.lockedOriginVersions(),
|
|
5055
|
+
readStoreRequires: true
|
|
5056
|
+
});
|
|
5057
|
+
for (const sib of staleSiblings) {
|
|
5058
|
+
const pin = parseAssetRefLoose(sib)?.pin;
|
|
5059
|
+
if (!pin) continue;
|
|
5060
|
+
const id = refIdentity(sib.replace(/#.*$/, ""));
|
|
5061
|
+
const kept = siblings.resolved.some(
|
|
5062
|
+
(c) => `${c.publisher.replace(/^@/, "")}/${c.kind}:${c.name}` === id?.replace(/^@/, "") && matchPin(pin, c.version ?? "")
|
|
5063
|
+
);
|
|
5064
|
+
if (!kept) {
|
|
5065
|
+
throw new Error(
|
|
5066
|
+
`${sib.replace(/#.*$/, "")} is pinned to ${pin} in skaile.yaml, but its source moved on and no longer holds ${pin}, so adding ${ref} would break the lock - nothing was added. Change the pin in skaile.yaml, or drop the pinned asset, then add again.`
|
|
5067
|
+
);
|
|
5068
|
+
}
|
|
5069
|
+
}
|
|
5070
|
+
const held = new Set(resolved.map((c) => this.candidateKey(c)));
|
|
5071
|
+
for (const c of siblings.resolved) {
|
|
5072
|
+
if (!held.has(this.candidateKey(c))) resolved.push(c);
|
|
4408
5073
|
}
|
|
4409
5074
|
}
|
|
4410
5075
|
this.assertSourceCommitsPublished(resolved, repositories);
|
|
@@ -4441,6 +5106,11 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4441
5106
|
`${ref.split("#")[0]} requires ${missing.join(", ")} (not found \u2014 ${REGISTER_HOLDER}, or remove the requirement from the asset's manifest) \u2014 nothing was added`
|
|
4442
5107
|
);
|
|
4443
5108
|
}
|
|
5109
|
+
if (opts?.dryRun) {
|
|
5110
|
+
const plan = this.planAddItems(resolved, lib, stores, parsed);
|
|
5111
|
+
opts.onPlan?.(plan);
|
|
5112
|
+
return [];
|
|
5113
|
+
}
|
|
4444
5114
|
const entries = [...await this.buildCatalogEntries(resolved, repositories), ...lib.entries];
|
|
4445
5115
|
assertFlowsLoad(entries, "added");
|
|
4446
5116
|
assertNoLibrarySymlinks(entries, this.registry, repositories, opts?.link === true);
|
|
@@ -4463,7 +5133,11 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4463
5133
|
this.entriesForHarness(entries, t),
|
|
4464
5134
|
repositories,
|
|
4465
5135
|
patches,
|
|
4466
|
-
this.deployOptsFor(t, opts?.link, opts?.onSecretFile
|
|
5136
|
+
this.deployOptsFor(t, opts?.link, opts?.onSecretFile, {
|
|
5137
|
+
refresh: true,
|
|
5138
|
+
onDrift: () => {
|
|
5139
|
+
}
|
|
5140
|
+
})
|
|
4467
5141
|
)
|
|
4468
5142
|
)
|
|
4469
5143
|
)
|
|
@@ -4484,7 +5158,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4484
5158
|
opts?.onPlaceholderDescription?.(placeholder);
|
|
4485
5159
|
}
|
|
4486
5160
|
this.addDependencyToConfig(ref);
|
|
4487
|
-
await this.
|
|
5161
|
+
await this.renderHarnessMcpConfig();
|
|
4488
5162
|
await this.renderAgentInstances();
|
|
4489
5163
|
if (resolved.length > 0 || lib.entries.length > 0) {
|
|
4490
5164
|
const libraryLock = await this.libraryLockEntries(lib);
|
|
@@ -4751,7 +5425,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4751
5425
|
* Removes only `ref` itself; use {@link removeWithDependencies} to also drop the
|
|
4752
5426
|
* dependencies it leaves orphaned.
|
|
4753
5427
|
*
|
|
4754
|
-
* Deliberately does NOT re-render the
|
|
5428
|
+
* Deliberately does NOT re-render the harness target's MCP config: the render
|
|
4755
5429
|
* step is async (the declaration resolver is), and making this synchronous
|
|
4756
5430
|
* method async would break every external caller. {@link removeWithDependencies}
|
|
4757
5431
|
* (what `skaile remove` runs) does re-render it; a caller of this method gets the
|
|
@@ -4820,14 +5494,22 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4820
5494
|
}
|
|
4821
5495
|
const kept = [];
|
|
4822
5496
|
const ownedBy = [];
|
|
5497
|
+
const mcpPublishers = target.kind === "mcp-server" && !this.global ? [
|
|
5498
|
+
.../* @__PURE__ */ new Set([
|
|
5499
|
+
...this.lockHolders("mcp-server", target.name).map((h) => h.publisher),
|
|
5500
|
+
target.publisher?.replace(/^@/, "")
|
|
5501
|
+
])
|
|
5502
|
+
].filter((p) => !!p) : [];
|
|
4823
5503
|
const changed = this.removeResolved(target, { force: opts?.force, kept, ownedBy });
|
|
5504
|
+
const droppedSettings = changed && mcpPublishers.length > 0 ? this.dropRemovedMcpServerSettings(target.name, mcpPublishers) : [];
|
|
4824
5505
|
const keptNote = {
|
|
4825
5506
|
...kept.length > 0 ? { kept } : {},
|
|
4826
|
-
...ownedBy.length > 0 ? { ownedBy } : {}
|
|
5507
|
+
...ownedBy.length > 0 ? { ownedBy } : {},
|
|
5508
|
+
...droppedSettings.length > 0 ? { droppedSettings } : {}
|
|
4827
5509
|
};
|
|
4828
5510
|
const pruned = changed && requiredRefs.length > 0 ? await this.pruneOrphans(requiredRefs) : [];
|
|
4829
5511
|
if (changed && (target.kind === "mcp-server" || pruned.some((r) => r.startsWith("mcp-server:")))) {
|
|
4830
|
-
await this.
|
|
5512
|
+
await this.renderHarnessMcpConfig();
|
|
4831
5513
|
}
|
|
4832
5514
|
return { changed, pruned, ...keptNote };
|
|
4833
5515
|
}
|
|
@@ -4991,6 +5673,40 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
4991
5673
|
}
|
|
4992
5674
|
return changed;
|
|
4993
5675
|
}
|
|
5676
|
+
/**
|
|
5677
|
+
* After an `mcp-server` asset left the project: drop what would keep it rendered. Its staged
|
|
5678
|
+
* store bytes under `.skaile/cache/store/<publisher>/mcp-server/<name>/` go (an `mcp_servers:`
|
|
5679
|
+
* entry of the same id would otherwise keep loading them), and so does an `mcp_servers:` entry
|
|
5680
|
+
* that only sets values for it: `env` and the like, with no `command`, `url` or recipe of its
|
|
5681
|
+
* own. An entry that can run alone is the user's own server and stays.
|
|
5682
|
+
*
|
|
5683
|
+
* @returns The dropped `mcp_servers` entries, as `mcp_servers entry "<id>"`.
|
|
5684
|
+
*/
|
|
5685
|
+
dropRemovedMcpServerSettings(name, publishers) {
|
|
5686
|
+
for (const publisher of publishers) {
|
|
5687
|
+
rmSync(join(this.storeCacheDir, publisher, "mcp-server", name), {
|
|
5688
|
+
recursive: true,
|
|
5689
|
+
force: true
|
|
5690
|
+
});
|
|
5691
|
+
}
|
|
5692
|
+
const configPath = join(this.stateRoot, "skaile.yaml");
|
|
5693
|
+
if (!existsSync(configPath)) return [];
|
|
5694
|
+
const raw = parse(readFileSync(configPath, "utf8")) ?? {};
|
|
5695
|
+
if (!Array.isArray(raw.mcp_servers)) return [];
|
|
5696
|
+
const dropped = [];
|
|
5697
|
+
const standalone = ["command", "url", "recipe", "launcher"];
|
|
5698
|
+
raw.mcp_servers = raw.mcp_servers.filter((entry) => {
|
|
5699
|
+
const e = entry;
|
|
5700
|
+
if (!e || typeof e.id !== "string" || unscopedName(e.id) !== name) return true;
|
|
5701
|
+
if (standalone.some((k) => e[k] !== void 0 && e[k] !== null)) return true;
|
|
5702
|
+
dropped.push(`mcp_servers entry "${e.id}"`);
|
|
5703
|
+
return false;
|
|
5704
|
+
});
|
|
5705
|
+
if (dropped.length === 0) return [];
|
|
5706
|
+
if (raw.mcp_servers.length === 0) delete raw.mcp_servers;
|
|
5707
|
+
writeFileSync(configPath, stringify(raw, { lineWidth: 120 }));
|
|
5708
|
+
return dropped;
|
|
5709
|
+
}
|
|
4994
5710
|
/**
|
|
4995
5711
|
* After `remove --global --harness X`: the harnesses outside `X` that still hold a copy of the
|
|
4996
5712
|
* asset, or `undefined` when none does (or this is not a harness-limited global remove).
|
|
@@ -5162,7 +5878,11 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5162
5878
|
}
|
|
5163
5879
|
}
|
|
5164
5880
|
if (best) return best;
|
|
5165
|
-
const
|
|
5881
|
+
const lockedLibraries = await this.lockedLibraryNames();
|
|
5882
|
+
const lib = await this.resolveLibraryEntries([ref], {
|
|
5883
|
+
quiet: true,
|
|
5884
|
+
...lockedLibraries.size > 0 ? { lockedLibraries } : {}
|
|
5885
|
+
});
|
|
5166
5886
|
return lib.entries[0] ?? null;
|
|
5167
5887
|
}
|
|
5168
5888
|
/**
|
|
@@ -5184,7 +5904,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5184
5904
|
const seen = /* @__PURE__ */ new Set();
|
|
5185
5905
|
for (const k of kinds) {
|
|
5186
5906
|
try {
|
|
5187
|
-
const base = deployedBase(k, this.
|
|
5907
|
+
const base = deployedBase(k, this.harness, this.global, this.projectDir);
|
|
5188
5908
|
if (!existsSync(base)) continue;
|
|
5189
5909
|
for (const item of readdirSync(base, { withFileTypes: true })) {
|
|
5190
5910
|
let name;
|
|
@@ -5226,7 +5946,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5226
5946
|
* @returns One {@link LegacyDeployedAsset} per stale copy, sorted by kind then name.
|
|
5227
5947
|
*/
|
|
5228
5948
|
listLegacyClaudeDeployed() {
|
|
5229
|
-
if (this.global || this.
|
|
5949
|
+
if (this.global || this.harness === "claude-code") return [];
|
|
5230
5950
|
const tracked = /* @__PURE__ */ new Map();
|
|
5231
5951
|
const track = (kind, name) => {
|
|
5232
5952
|
const component = kind ? this.installTarget(kind) : void 0;
|
|
@@ -5254,7 +5974,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5254
5974
|
const out = [];
|
|
5255
5975
|
for (const { kind, name, component: k } of tracked.values()) {
|
|
5256
5976
|
const legacy = deployedDir(k, name, "claude-code", false, this.projectDir);
|
|
5257
|
-
if (legacy === deployedDir(k, name, this.
|
|
5977
|
+
if (legacy === deployedDir(k, name, this.harness, false, this.projectDir)) continue;
|
|
5258
5978
|
const found = deployedPaths(k, name, "claude-code", false, this.projectDir).find((p) => {
|
|
5259
5979
|
try {
|
|
5260
5980
|
lstatSync(p);
|
|
@@ -5329,9 +6049,13 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5329
6049
|
state = "declared";
|
|
5330
6050
|
} else if (parsed.kind === "mcp-server") {
|
|
5331
6051
|
const wired = await wiredMcpNames();
|
|
5332
|
-
const isWired = wired.has(parsed.name) || wired.has(unscopedName(parsed.name))
|
|
6052
|
+
const isWired = wired.has(parsed.name) || wired.has(unscopedName(parsed.name)) || !this.global && await mcpCommittedRenderIntact(
|
|
6053
|
+
this.projectDir,
|
|
6054
|
+
this.harness,
|
|
6055
|
+
unscopedName(parsed.name)
|
|
6056
|
+
);
|
|
5333
6057
|
const skippedReason = Object.entries(
|
|
5334
|
-
await readSkippedMcpServers(this.projectDir, this.
|
|
6058
|
+
await readSkippedMcpServers(this.projectDir, this.harness)
|
|
5335
6059
|
).find(([id]) => id === parsed.name || unscopedName(id) === parsed.name)?.[1];
|
|
5336
6060
|
const drifted = (await this.mcpDriftRows()).some(
|
|
5337
6061
|
(r) => unscopedName(r.drift.id) === unscopedName(parsed.name) && r.drift.missing.length + r.drift.modified.length + r.drift.extra.length > 0
|
|
@@ -5350,7 +6074,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5350
6074
|
const onDisk = isDeployed(
|
|
5351
6075
|
component,
|
|
5352
6076
|
parsed.name,
|
|
5353
|
-
this.
|
|
6077
|
+
this.harness,
|
|
5354
6078
|
this.global,
|
|
5355
6079
|
this.projectDir
|
|
5356
6080
|
);
|
|
@@ -5388,7 +6112,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5388
6112
|
async mcpNotices() {
|
|
5389
6113
|
if (this.global) return [];
|
|
5390
6114
|
const out = [];
|
|
5391
|
-
const skipped = await readSkippedMcpServers(this.projectDir, this.
|
|
6115
|
+
const skipped = await readSkippedMcpServers(this.projectDir, this.harness);
|
|
5392
6116
|
for (const [id, reason] of Object.entries(skipped)) {
|
|
5393
6117
|
out.push({ id, kind: "skipped", reason, text: `MCP server "${id}" is skipped: ${reason}` });
|
|
5394
6118
|
}
|
|
@@ -5433,10 +6157,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5433
6157
|
const component = kind ? this.installTarget(kind) : void 0;
|
|
5434
6158
|
if (!publisher || !kind || !name || !component || component === "agent") continue;
|
|
5435
6159
|
if (patches[`${kind}:${name}`]) continue;
|
|
5436
|
-
const dest = join(
|
|
5437
|
-
deployedBase(component, this.driverTarget, this.global, this.projectDir),
|
|
5438
|
-
name
|
|
5439
|
-
);
|
|
6160
|
+
const dest = join(deployedBase(component, this.harness, this.global, this.projectDir), name);
|
|
5440
6161
|
if (!existsSync(dest) || lstatSync(dest).isSymbolicLink()) continue;
|
|
5441
6162
|
const missing = lockedAssetFiles(kind, entry.files).map((f) => f.rel).filter((rel) => !existsSync(join(dest, rel)));
|
|
5442
6163
|
if (missing.length > 0) out.push({ ref: `${kind}:@${publisher}/${name}`, missing });
|
|
@@ -5453,7 +6174,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5453
6174
|
const component = this.installTarget(entry.kind);
|
|
5454
6175
|
if (!entry.files || !component || component === "agent") continue;
|
|
5455
6176
|
const dest = join(
|
|
5456
|
-
deployedBase(component, this.
|
|
6177
|
+
deployedBase(component, this.harness, this.global, this.projectDir),
|
|
5457
6178
|
entry.name
|
|
5458
6179
|
);
|
|
5459
6180
|
if (!existsSync(dest)) continue;
|
|
@@ -5531,7 +6252,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5531
6252
|
const repoStatuses = this.buildRepoStatuses(repositories);
|
|
5532
6253
|
const lockByKindName = indexLockByKindName(lock);
|
|
5533
6254
|
const entries = [];
|
|
5534
|
-
const instanceFiles = this.global ? /* @__PURE__ */ new Set() : instanceRenderedAgentNames(this.projectDir, this.
|
|
6255
|
+
const instanceFiles = this.global ? /* @__PURE__ */ new Set() : instanceRenderedAgentNames(this.projectDir, this.harness);
|
|
5535
6256
|
for (const d of deployed) {
|
|
5536
6257
|
const lockEntry = lockByKindName.get(`${d.kind}:${d.name}`);
|
|
5537
6258
|
if (!lockEntry && d.kind === "agent" && instanceFiles.has(d.name)) continue;
|
|
@@ -5677,11 +6398,12 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5677
6398
|
if (!lock) return [];
|
|
5678
6399
|
const bare = (s) => s.includes("#") ? s.slice(0, s.indexOf("#")) : s;
|
|
5679
6400
|
const asked = parseRefTolerant(ref);
|
|
6401
|
+
const askedPublisher = asked?.publisher?.replace(/^@/, "");
|
|
5680
6402
|
const matchesIdentity = (k) => {
|
|
5681
6403
|
if (bare(k) === bare(ref)) return true;
|
|
5682
|
-
if (!asked
|
|
6404
|
+
if (!asked) return false;
|
|
5683
6405
|
const locked = parseCanonicalLockKey(k);
|
|
5684
|
-
return locked.kind === asked.kind && locked.name === asked.name;
|
|
6406
|
+
return locked.kind === asked.kind && locked.name === asked.name && (!askedPublisher || locked.publisher === askedPublisher);
|
|
5685
6407
|
};
|
|
5686
6408
|
const key = lock.assets[ref] ? ref : Object.keys(lock.assets).find(matchesIdentity);
|
|
5687
6409
|
if (!key) return asked?.kind === "preset" ? this.whyPreset(lock, asked) : [];
|
|
@@ -5817,6 +6539,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5817
6539
|
const libraryAssets = Object.entries(lock.assets).filter(
|
|
5818
6540
|
([, e]) => e.library && !e.library.installed
|
|
5819
6541
|
);
|
|
6542
|
+
const declaredPins = this.declaredPinsByIdentity();
|
|
5820
6543
|
if (libraryAssets.length > 0) {
|
|
5821
6544
|
const snap = await this.loadLibraryIndex();
|
|
5822
6545
|
const diskHashes = /* @__PURE__ */ new Map();
|
|
@@ -5842,6 +6565,8 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5842
6565
|
{ kind, publisher, name },
|
|
5843
6566
|
found.version
|
|
5844
6567
|
);
|
|
6568
|
+
const declaredPin = declaredPins.get(`${kind}:${publisher}/${name}`);
|
|
6569
|
+
if (declaredPin && diskVersion && !matchPin(declaredPin, diskVersion)) continue;
|
|
5845
6570
|
if (diskVersion && !isPseudoVersion(diskVersion) && gt(coerceVersion(diskVersion), coerceVersion(origin.version))) {
|
|
5846
6571
|
result.push({
|
|
5847
6572
|
kind,
|
|
@@ -5880,6 +6605,26 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5880
6605
|
library: lookup.name,
|
|
5881
6606
|
contentChanged: true
|
|
5882
6607
|
});
|
|
6608
|
+
continue;
|
|
6609
|
+
}
|
|
6610
|
+
}
|
|
6611
|
+
if (entry.composed && kind === "agent") {
|
|
6612
|
+
const srcDir = statSync(found.source).isDirectory() ? found.source : dirname(found.source);
|
|
6613
|
+
const now = new Map(
|
|
6614
|
+
sourceComposedFiles(srcDir, name, this.projectDir).map((f) => [f.path, f.sha256])
|
|
6615
|
+
);
|
|
6616
|
+
const locked = new Map(entry.composed.map((f) => [f.path, f.sha256]));
|
|
6617
|
+
const same = now.size === locked.size && [...now].every(([f, h]) => locked.get(f) === h);
|
|
6618
|
+
if (!same) {
|
|
6619
|
+
result.push({
|
|
6620
|
+
kind,
|
|
6621
|
+
name,
|
|
6622
|
+
publisher,
|
|
6623
|
+
currentVersion: origin.version,
|
|
6624
|
+
behind: 0,
|
|
6625
|
+
library: lookup.name,
|
|
6626
|
+
contentChanged: true
|
|
6627
|
+
});
|
|
5883
6628
|
}
|
|
5884
6629
|
}
|
|
5885
6630
|
}
|
|
@@ -5889,6 +6634,23 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5889
6634
|
await this.addPinnedRows(lock, result);
|
|
5890
6635
|
return this.addLockGapRows(result);
|
|
5891
6636
|
}
|
|
6637
|
+
/**
|
|
6638
|
+
* The `#pin` of every publisher-qualified `skaile.yaml` dependency, keyed `kind:publisher/name`
|
|
6639
|
+
* (no scope sigil). `update` honours it, so `outdated` must not list a move it keeps.
|
|
6640
|
+
*/
|
|
6641
|
+
declaredPinsByIdentity() {
|
|
6642
|
+
const pins = /* @__PURE__ */ new Map();
|
|
6643
|
+
for (const dep of this.loadConfig().dependencies) {
|
|
6644
|
+
try {
|
|
6645
|
+
const p = parseAssetRef(dep);
|
|
6646
|
+
if (p.pin && p.publisher) {
|
|
6647
|
+
pins.set(`${p.kind}:${p.publisher.replace(/^@/, "")}/${p.name}`, p.pin);
|
|
6648
|
+
}
|
|
6649
|
+
} catch {
|
|
6650
|
+
}
|
|
6651
|
+
}
|
|
6652
|
+
return pins;
|
|
6653
|
+
}
|
|
5892
6654
|
/**
|
|
5893
6655
|
* List a locked asset whose `skaile.yaml` ref carries a `#version` pin while a source, a
|
|
5894
6656
|
* library or a store holds a newer one: `locked 0.7.0 -> 0.9.0 (pinned)`. The pin is the
|
|
@@ -5993,20 +6755,20 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
5993
6755
|
async addLibraryMoves(libraryAssets, rows) {
|
|
5994
6756
|
const refs = [];
|
|
5995
6757
|
const lockedIn = /* @__PURE__ */ new Map();
|
|
6758
|
+
const declaredPins = this.declaredPinsByIdentity();
|
|
5996
6759
|
for (const [key, entry] of libraryAssets) {
|
|
5997
6760
|
const { publisher, kind, name } = parseCanonicalLockKey(key);
|
|
5998
6761
|
if (!publisher || !kind || !name || !entry.library) continue;
|
|
5999
6762
|
const ref = `${kind}:@${publisher}/${name}`;
|
|
6000
|
-
|
|
6763
|
+
const pin = declaredPins.get(`${kind}:${publisher}/${name}`);
|
|
6764
|
+
refs.push(pin ? `${ref}#${pin}` : ref);
|
|
6001
6765
|
lockedIn.set(ref, { name: entry.library.name, key });
|
|
6002
6766
|
}
|
|
6003
6767
|
if (refs.length === 0) return;
|
|
6004
6768
|
let res;
|
|
6769
|
+
const preferLocked = await this.lockedPreference();
|
|
6005
6770
|
try {
|
|
6006
|
-
res = await this.resolveLibraryEntries(refs, {
|
|
6007
|
-
quiet: true,
|
|
6008
|
-
preferLocked: await this.lockedPreference()
|
|
6009
|
-
});
|
|
6771
|
+
res = await this.resolveLibraryEntries(refs, { quiet: true, preferLocked });
|
|
6010
6772
|
} catch {
|
|
6011
6773
|
return;
|
|
6012
6774
|
}
|
|
@@ -6016,9 +6778,11 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6016
6778
|
const ref = `${e.kind}:@${publisher}/${e.name}`;
|
|
6017
6779
|
const from = lockedIn.get(ref);
|
|
6018
6780
|
if (!to || !from || from.name === to) continue;
|
|
6781
|
+
const renamedOnly = preferLocked.libraries.get(`${e.kind}:${publisher}/${e.name}`) === to;
|
|
6019
6782
|
const row = rows.find(
|
|
6020
6783
|
(r) => r.kind === e.kind && r.name === e.name && r.publisher.replace(/^@/, "") === publisher
|
|
6021
6784
|
);
|
|
6785
|
+
if (renamedOnly && !row) continue;
|
|
6022
6786
|
if (row) {
|
|
6023
6787
|
row.library = from.name;
|
|
6024
6788
|
row.movesTo = to;
|
|
@@ -6150,7 +6914,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6150
6914
|
(r) => unscopedName(r.drift.id) === unscopedName(parsed.name)
|
|
6151
6915
|
);
|
|
6152
6916
|
if (!row) return { status: "identical" };
|
|
6153
|
-
const fileSetDiffers = row.drift.extra.length > 0 || row.drift.missing.
|
|
6917
|
+
const fileSetDiffers = row.drift.extra.length > 0 || row.drift.missing.length > 0;
|
|
6154
6918
|
return {
|
|
6155
6919
|
status: "differs",
|
|
6156
6920
|
diff: mcpDriftDiff(row.drift),
|
|
@@ -6171,7 +6935,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6171
6935
|
if (parsed.kind === "preset" && this.presetRecorded(parsed)) return { status: "no-files" };
|
|
6172
6936
|
if (!component) return { status: "not-deployed" };
|
|
6173
6937
|
if (component === "agent") {
|
|
6174
|
-
const opts = this.deployOptsFor(this.
|
|
6938
|
+
const opts = this.deployOptsFor(this.harness);
|
|
6175
6939
|
const parts = [diffDeployedAgent(entry, opts)];
|
|
6176
6940
|
for (const inst of this.instancesBoundTo(parsed)) {
|
|
6177
6941
|
parts.push(diffDeployedAgent(entry, opts, inst));
|
|
@@ -6181,7 +6945,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6181
6945
|
return diff === "" ? { status: "identical" } : { status: "differs", diff };
|
|
6182
6946
|
}
|
|
6183
6947
|
const deployedPath = join(
|
|
6184
|
-
deployedBase(component, this.
|
|
6948
|
+
deployedBase(component, this.harness, this.global, this.projectDir),
|
|
6185
6949
|
parsed.name
|
|
6186
6950
|
);
|
|
6187
6951
|
if (!existsSync(deployedPath)) return { status: "not-deployed" };
|
|
@@ -6248,7 +7012,8 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6248
7012
|
provenanceIndex,
|
|
6249
7013
|
overrides,
|
|
6250
7014
|
stores,
|
|
6251
|
-
declaredRefs: dependencies
|
|
7015
|
+
declaredRefs: dependencies,
|
|
7016
|
+
lockedOrigin: this.lockedOriginVersions()
|
|
6252
7017
|
});
|
|
6253
7018
|
this.assertSourceCommitsPublished(resolved, repositories);
|
|
6254
7019
|
const libraryLock = await this.libraryLockEntries(lib);
|
|
@@ -6257,6 +7022,8 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6257
7022
|
for (const [key, entry] of Object.entries(lockData.assets)) {
|
|
6258
7023
|
const rendered = prior?.assets[key]?.rendered;
|
|
6259
7024
|
if (rendered) entry.rendered = rendered;
|
|
7025
|
+
const composed = prior?.assets[key]?.composed;
|
|
7026
|
+
if (composed) entry.composed = composed;
|
|
6260
7027
|
}
|
|
6261
7028
|
writeLock(this.lockPath, lockData);
|
|
6262
7029
|
return lockData;
|
|
@@ -6404,7 +7171,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6404
7171
|
const dep = memberIdentity(depToStr(req));
|
|
6405
7172
|
if (!dep) continue;
|
|
6406
7173
|
const depComponent = this.installTarget(dep.kind);
|
|
6407
|
-
if (depComponent && !isDeployed(depComponent, dep.name, this.
|
|
7174
|
+
if (depComponent && !isDeployed(depComponent, dep.name, this.harness, this.global, this.projectDir)) {
|
|
6408
7175
|
const inRepos = await resolveAsset({ kind: dep.kind, name: dep.name }, repositories, this.reposDir, {
|
|
6409
7176
|
knownKinds: this.knownKinds
|
|
6410
7177
|
}) !== null;
|
|
@@ -6616,10 +7383,11 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6616
7383
|
ref: s.url,
|
|
6617
7384
|
reason,
|
|
6618
7385
|
message: `source ${s.url} ${reason}`,
|
|
6619
|
-
manualFix: true
|
|
7386
|
+
manualFix: true,
|
|
7387
|
+
unreadableSource: true
|
|
6620
7388
|
});
|
|
6621
7389
|
}
|
|
6622
|
-
for (const u of unboundAgentInstances(this.projectDir, this.
|
|
7390
|
+
for (const u of unboundAgentInstances(this.projectDir, this.harness)) {
|
|
6623
7391
|
const reason = u.ref.startsWith("agent:") ? await this.unboundAgentReason(u.id, u.ref) : `is bound by agent instance "${u.id}" but resolves to no agent.yaml \u2014 fix the path, or drop the binding from skaile.yaml`;
|
|
6624
7392
|
gaps.push({
|
|
6625
7393
|
type: "agent",
|
|
@@ -6842,7 +7610,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6842
7610
|
continue;
|
|
6843
7611
|
}
|
|
6844
7612
|
if (lookup.state === "unregistered") {
|
|
6845
|
-
const reason2 = `is locked, but library "${origin
|
|
7613
|
+
const reason2 = `is locked, but library "${unregisteredLibraryName(origin)}" is not registered (renamed or removed?) \u2014 ${unregisteredLibraryFix(origin, ref)}`;
|
|
6846
7614
|
gaps.push({ type: "library", ref, reason: reason2, message: `${ref} ${reason2}`, manualFix: true });
|
|
6847
7615
|
continue;
|
|
6848
7616
|
}
|
|
@@ -6862,12 +7630,15 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6862
7630
|
* The locked source assets whose source is no longer in `skaile.yaml` `sources:` (`source
|
|
6863
7631
|
* remove`, a hand edit), keyed by lock key. ONE sentence for it: `check`, `doctor`, `outdated`,
|
|
6864
7632
|
* `install`, `install --locked` and `update` all say it (p1062), and none re-clones the source.
|
|
6865
|
-
* A
|
|
6866
|
-
*
|
|
7633
|
+
* A GitHub lock entry that no source declares counts as store-supplied only when a store
|
|
7634
|
+
* lists the ref (OQ3): a configured store alone proves nothing, as it may never have held
|
|
7635
|
+
* the asset. `check`, `doctor` and `outdated` read the store's cached catalog and never touch
|
|
7636
|
+
* the network; `install` and `update` (`online`) ask the store itself.
|
|
6867
7637
|
*
|
|
6868
7638
|
* @param inScope - Only these lock keys count (`install` prunes an undeclared entry as usual).
|
|
7639
|
+
* @param online - Ask the stores when the cached catalog does not list the ref.
|
|
6869
7640
|
*/
|
|
6870
|
-
async orphanedSourceGaps(inScope) {
|
|
7641
|
+
async orphanedSourceGaps(inScope, online = false) {
|
|
6871
7642
|
const out = /* @__PURE__ */ new Map();
|
|
6872
7643
|
let config;
|
|
6873
7644
|
try {
|
|
@@ -6875,7 +7646,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6875
7646
|
} catch {
|
|
6876
7647
|
return out;
|
|
6877
7648
|
}
|
|
6878
|
-
const
|
|
7649
|
+
const stores = [...config.stores, ...await this.globalStoreFallback(config.stores, false)];
|
|
6879
7650
|
const registered = new Set(config.sources.map((s) => sourceCacheKey(s.url)));
|
|
6880
7651
|
for (const [key, entry] of Object.entries(this.tryReadLock()?.assets ?? {})) {
|
|
6881
7652
|
const url = entry.source?.url;
|
|
@@ -6885,13 +7656,38 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6885
7656
|
const { publisher, kind, name } = parseCanonicalLockKey(key);
|
|
6886
7657
|
if (!publisher || !kind || !name) continue;
|
|
6887
7658
|
if (registered.has(sourceCacheKey(url))) continue;
|
|
6888
|
-
if (storeBacked && GITHUB_REPO_URL.test(url)) continue;
|
|
6889
7659
|
const ref = `${kind}:@${publisher}/${name}`;
|
|
7660
|
+
if (GITHUB_REPO_URL.test(url) && await this.storeListsRef(stores, ref, online)) continue;
|
|
6890
7661
|
const reason = `is locked, but its source ${url} is not in skaile.yaml sources: any more \u2014 register it again with \`skaile source add ${url}\`, or drop the dependency with \`skaile remove ${ref}\``;
|
|
6891
7662
|
out.set(key, { type: "source", ref, reason, message: `${ref} ${reason}`, manualFix: true });
|
|
6892
7663
|
}
|
|
6893
7664
|
return out;
|
|
6894
7665
|
}
|
|
7666
|
+
/**
|
|
7667
|
+
* `true` when one of `stores` lists `ref` (a canonical lock key): its cached catalog holds it
|
|
7668
|
+
* or, with `online`, the store answers for it. An injected store fetcher is the store client
|
|
7669
|
+
* itself, so it is asked either way. A store an online install cannot ask (unreachable,
|
|
7670
|
+
* air-gapped, `--no-catalog`) may hold the ref; `check` never asks, so a store lists only what
|
|
7671
|
+
* its cached catalog holds.
|
|
7672
|
+
*/
|
|
7673
|
+
async storeListsRef(stores, ref, online) {
|
|
7674
|
+
for (const store of stores) {
|
|
7675
|
+
try {
|
|
7676
|
+
if (this.injectedStoreFetcher) {
|
|
7677
|
+
if (await this.injectedStoreFetcher.getInstallManifest(store.url, ref)) return true;
|
|
7678
|
+
continue;
|
|
7679
|
+
}
|
|
7680
|
+
const remote = this.remoteStore(store.url);
|
|
7681
|
+
if (remote.holdsCached(ref)) return true;
|
|
7682
|
+
if (!online) continue;
|
|
7683
|
+
if (this.catalogUrlOverride === "") return true;
|
|
7684
|
+
if (await remote.resolve(ref)) return true;
|
|
7685
|
+
} catch {
|
|
7686
|
+
if (online) return true;
|
|
7687
|
+
}
|
|
7688
|
+
}
|
|
7689
|
+
return false;
|
|
7690
|
+
}
|
|
6895
7691
|
/**
|
|
6896
7692
|
* Locked source assets whose source cannot supply them any more: the source is no longer in
|
|
6897
7693
|
* `skaile.yaml` `sources:` (`source remove`, a hand edit), or it is there but now publishes
|
|
@@ -6948,8 +7744,12 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6948
7744
|
* rendering occupies and their sha256. Call it after the deploy, so the bytes hashed are the
|
|
6949
7745
|
* ones `install` just wrote; {@link lockedCopyDrift} compares later edits with them.
|
|
6950
7746
|
* Entries that carry a record (kept from an earlier lock) are left as they are.
|
|
7747
|
+
*
|
|
7748
|
+
* @param keepComposedOf - The lock an `install` read: an agent whose `../` compose folder is
|
|
7749
|
+
* not in the cache keeps that lock's `composed:` record. Omitted by `update` and `add`,
|
|
7750
|
+
* which copy the library's current bytes.
|
|
6951
7751
|
*/
|
|
6952
|
-
withRenderedAgents(lock) {
|
|
7752
|
+
withRenderedAgents(lock, keepComposedOf) {
|
|
6953
7753
|
if (this.global) return lock;
|
|
6954
7754
|
for (const [key, entry] of Object.entries(lock.assets)) {
|
|
6955
7755
|
if (entry.rendered || entry.library?.installed) continue;
|
|
@@ -6958,6 +7758,18 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6958
7758
|
const rendered = this.renderedAgentFiles(name);
|
|
6959
7759
|
if (rendered.length > 0) entry.rendered = rendered;
|
|
6960
7760
|
}
|
|
7761
|
+
for (const [key, entry] of Object.entries(lock.assets)) {
|
|
7762
|
+
if (entry.library?.installed) continue;
|
|
7763
|
+
const { kind, name } = parseCanonicalLockKey(key);
|
|
7764
|
+
if (!kind || !name || this.installTarget(kind) !== "agent") continue;
|
|
7765
|
+
const composed = cachedComposedFiles(name, this.projectDir);
|
|
7766
|
+
if (composed.length > 0) entry.composed = composed;
|
|
7767
|
+
else {
|
|
7768
|
+
const earlier = keepComposedOf?.assets[key]?.composed;
|
|
7769
|
+
if (earlier?.length) entry.composed = earlier;
|
|
7770
|
+
else delete entry.composed;
|
|
7771
|
+
}
|
|
7772
|
+
}
|
|
6961
7773
|
return this.withInstanceRenderings(lock);
|
|
6962
7774
|
}
|
|
6963
7775
|
/**
|
|
@@ -6983,7 +7795,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
6983
7795
|
ownFiles.set(key, new Set(this.renderedAgentFiles(name).map((f) => f.path)));
|
|
6984
7796
|
}
|
|
6985
7797
|
const instanceFiles = /* @__PURE__ */ new Map();
|
|
6986
|
-
for (const instance of renderedInstanceFiles(this.projectDir, this.
|
|
7798
|
+
for (const instance of renderedInstanceFiles(this.projectDir, this.harness)) {
|
|
6987
7799
|
const want = parseRefTolerant(instance.ref);
|
|
6988
7800
|
if (!want || want.kind !== "agent") continue;
|
|
6989
7801
|
const wantPublisher = want.publisher?.replace(/^@/, "");
|
|
@@ -7038,12 +7850,12 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7038
7850
|
/** The files of one agent's rendering for the active harness, project-relative, with sha256. */
|
|
7039
7851
|
renderedAgentFiles(name) {
|
|
7040
7852
|
const out = [];
|
|
7041
|
-
for (const path2 of deployedPaths("agent", name, this.
|
|
7853
|
+
for (const path2 of deployedPaths("agent", name, this.harness, false, this.projectDir)) {
|
|
7042
7854
|
this.hashTree(path2, out);
|
|
7043
7855
|
}
|
|
7044
7856
|
this.hashTree(
|
|
7045
7857
|
join(
|
|
7046
|
-
dirname(deployedBase("agent", this.
|
|
7858
|
+
dirname(deployedBase("agent", this.harness, false, this.projectDir)),
|
|
7047
7859
|
CODEX_IDENTITY_DIR,
|
|
7048
7860
|
`${name}.md`
|
|
7049
7861
|
),
|
|
@@ -7110,7 +7922,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7110
7922
|
if (!kind || !name || !component) continue;
|
|
7111
7923
|
const dir = relative(
|
|
7112
7924
|
this.projectDir,
|
|
7113
|
-
deployedDir(component, name, this.
|
|
7925
|
+
deployedDir(component, name, this.harness, this.global, this.projectDir)
|
|
7114
7926
|
).split(sep).join("/");
|
|
7115
7927
|
out.push({
|
|
7116
7928
|
ref: d.key,
|
|
@@ -7127,7 +7939,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7127
7939
|
if (!kind || !name || !component) continue;
|
|
7128
7940
|
const dir = relative(
|
|
7129
7941
|
this.projectDir,
|
|
7130
|
-
deployedDir(component, name, this.
|
|
7942
|
+
deployedDir(component, name, this.harness, this.global, this.projectDir)
|
|
7131
7943
|
).split(sep).join("/");
|
|
7132
7944
|
const files = inc.missing.map((f) => `${dir}/${f}`);
|
|
7133
7945
|
const row = out.find((r) => r.ref.split("#")[0] === bare);
|
|
@@ -7161,7 +7973,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7161
7973
|
const out = [];
|
|
7162
7974
|
const deployOpts = {
|
|
7163
7975
|
registry: this.registry,
|
|
7164
|
-
|
|
7976
|
+
harness: this.harness,
|
|
7165
7977
|
global: this.global,
|
|
7166
7978
|
cwd: this.projectDir
|
|
7167
7979
|
};
|
|
@@ -7185,7 +7997,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7185
7997
|
const component = kind ? this.installTarget(kind) : void 0;
|
|
7186
7998
|
if (!kind || !name || !component || component === "agent") continue;
|
|
7187
7999
|
if (patches[`${kind}:${name}`]) continue;
|
|
7188
|
-
const dest = deployedDir(component, name, this.
|
|
8000
|
+
const dest = deployedDir(component, name, this.harness, this.global, this.projectDir);
|
|
7189
8001
|
try {
|
|
7190
8002
|
const deployed = lstatSync(dest);
|
|
7191
8003
|
if (deployed.isSymbolicLink() || !deployed.isDirectory()) continue;
|
|
@@ -7213,12 +8025,13 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7213
8025
|
out.push({ ref: refOf(key), key, modified, extra, library: false });
|
|
7214
8026
|
}
|
|
7215
8027
|
for (const [key, entry] of Object.entries(lock.assets)) {
|
|
7216
|
-
|
|
8028
|
+
const recorded = [...entry.rendered ?? [], ...entry.composed ?? []];
|
|
8029
|
+
if (recorded.length === 0 || entry.library?.installed) continue;
|
|
7217
8030
|
const { kind, name } = parseCanonicalLockKey(key);
|
|
7218
8031
|
if (!kind || !name || this.installTarget(kind) !== "agent") continue;
|
|
7219
8032
|
if (patches[`${kind}:${name}`]) continue;
|
|
7220
8033
|
const modified = [];
|
|
7221
|
-
for (const f of
|
|
8034
|
+
for (const f of recorded) {
|
|
7222
8035
|
const file = join(this.projectDir, f.path);
|
|
7223
8036
|
if (!existsSync(file)) continue;
|
|
7224
8037
|
try {
|
|
@@ -7229,7 +8042,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7229
8042
|
}
|
|
7230
8043
|
if (modified.length > 0) {
|
|
7231
8044
|
const instanceOf = /* @__PURE__ */ new Map();
|
|
7232
|
-
for (const inst of renderedInstanceFiles(this.projectDir, this.
|
|
8045
|
+
for (const inst of renderedInstanceFiles(this.projectDir, this.harness)) {
|
|
7233
8046
|
for (const f of inst.files) if (modified.includes(f)) instanceOf.set(f, inst.id);
|
|
7234
8047
|
}
|
|
7235
8048
|
out.push({
|
|
@@ -7239,7 +8052,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7239
8052
|
extra: [],
|
|
7240
8053
|
library: false,
|
|
7241
8054
|
rendered: true,
|
|
7242
|
-
lockedSha: new Map(
|
|
8055
|
+
lockedSha: new Map(recorded.map((f) => [f.path, f.sha256])),
|
|
7243
8056
|
instanceOf
|
|
7244
8057
|
});
|
|
7245
8058
|
}
|
|
@@ -7259,7 +8072,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7259
8072
|
const { publisher, kind, name } = parseCanonicalLockKey(key);
|
|
7260
8073
|
const component = kind ? this.installTarget(kind) : void 0;
|
|
7261
8074
|
if (!kind || !name || !component || named.has(`${kind}:${name}`)) continue;
|
|
7262
|
-
if (isDeployed(component, name, this.
|
|
8075
|
+
if (isDeployed(component, name, this.harness, this.global, this.projectDir)) {
|
|
7263
8076
|
const renderedGone = component === "agent" && !this.global && (entry.rendered ?? []).some((f) => !existsSync(join(this.projectDir, f.path)));
|
|
7264
8077
|
if (!renderedGone) continue;
|
|
7265
8078
|
}
|
|
@@ -7267,7 +8080,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7267
8080
|
const dangling = deployedPaths(
|
|
7268
8081
|
component,
|
|
7269
8082
|
name,
|
|
7270
|
-
this.
|
|
8083
|
+
this.harness,
|
|
7271
8084
|
this.global,
|
|
7272
8085
|
this.projectDir
|
|
7273
8086
|
).find((p) => isSymlink(p) && !existsSync(p));
|
|
@@ -7352,10 +8165,23 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7352
8165
|
({ id }) => id.kind === want.kind && id.name === want.name && (!want.publisher || id.publisher === want.publisher)
|
|
7353
8166
|
);
|
|
7354
8167
|
if (held.length > 0 && !held.some(({ id }) => !id.version || matchPin(want.pin, id.version))) {
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
8168
|
+
const lockHolds = held.map((h) => h.key).join(", ");
|
|
8169
|
+
const pinned = await this.info(d.ref);
|
|
8170
|
+
const pinHeld = pinned !== null && matchPin(want.pin, pinned.version ?? "");
|
|
8171
|
+
if (!pinHeld && this.loadConfig().stores.length === 0) {
|
|
8172
|
+
const plainRef = d.ref.split("#")[0] ?? d.ref;
|
|
8173
|
+
const other = pinned ?? await this.info(plainRef);
|
|
8174
|
+
gap = {
|
|
8175
|
+
type: "pin",
|
|
8176
|
+
reason: `is pinned in skaile.yaml but the lock holds ${lockHolds}, and no library or source holds ${want.pin}${other?.version ? ` (${want.name} has version(s): ${other.version})` : ""} \u2014 change the pin in skaile.yaml`,
|
|
8177
|
+
manualFix: true
|
|
8178
|
+
};
|
|
8179
|
+
} else {
|
|
8180
|
+
gap = {
|
|
8181
|
+
type: "pin",
|
|
8182
|
+
reason: `is pinned in skaile.yaml but the lock holds ${lockHolds} \u2014 run \`skaile install\``
|
|
8183
|
+
};
|
|
8184
|
+
}
|
|
7359
8185
|
}
|
|
7360
8186
|
}
|
|
7361
8187
|
if (gap) gaps.push({ ...gap, ref: d.ref, message: `${d.ref} ${gap.reason}` });
|
|
@@ -7585,7 +8411,7 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7585
8411
|
for (const dest of deployedPaths(
|
|
7586
8412
|
component,
|
|
7587
8413
|
name,
|
|
7588
|
-
this.
|
|
8414
|
+
this.harness,
|
|
7589
8415
|
this.global,
|
|
7590
8416
|
this.projectDir
|
|
7591
8417
|
)) {
|
|
@@ -7806,8 +8632,8 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7806
8632
|
}
|
|
7807
8633
|
if (ids.length === 0) return false;
|
|
7808
8634
|
writeFileSync(configPath, stringify(raw, { lineWidth: 120 }));
|
|
7809
|
-
for (const
|
|
7810
|
-
removeAgentInstanceRenderings({ projectDir: this.projectDir,
|
|
8635
|
+
for (const harness of this.targetHarnesses()) {
|
|
8636
|
+
removeAgentInstanceRenderings({ projectDir: this.projectDir, harness, ids });
|
|
7811
8637
|
}
|
|
7812
8638
|
return true;
|
|
7813
8639
|
}
|
|
@@ -7828,6 +8654,6 @@ Nothing was changed. Declare it again to keep it, or run \`skaile install --forc
|
|
|
7828
8654
|
}
|
|
7829
8655
|
};
|
|
7830
8656
|
|
|
7831
|
-
export { AssetManager, FACTORY_SOURCE_URL, LibraryEntryError, MissingManifestError, installAgentInstances, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, softDepName };
|
|
7832
|
-
//# sourceMappingURL=chunk-
|
|
7833
|
-
//# sourceMappingURL=chunk-
|
|
8657
|
+
export { AssetManager, FACTORY_SOURCE_URL, LibraryEntryError, MissingManifestError, installAgentInstances, mcpNotRunnableReason, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, setLibraryAssetCheck, softDepName };
|
|
8658
|
+
//# sourceMappingURL=chunk-HWNK3F3X.js.map
|
|
8659
|
+
//# sourceMappingURL=chunk-HWNK3F3X.js.map
|