@skaile/workspaces 5.7.0 → 5.9.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 +120 -0
- package/dist/app-sdk/index.js +1 -1
- package/dist/{asset-feeds-K36CR52Q.js → asset-feeds-XMKKUUK6.js} +54 -30
- package/dist/asset-feeds-XMKKUUK6.js.map +1 -0
- package/dist/asset-manager/catalog-deployer.js +9 -9
- package/dist/asset-manager/index.js +15 -15
- package/dist/asset-manager/installer.js +11 -11
- package/dist/asset-manager/renderers.js +10 -10
- package/dist/asset-manager/src/index.d.ts +268 -24
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/install-agent.d.ts +11 -0
- package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts +2 -2
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/bridge/drivers/claude-sdk.js +301 -212
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +92 -66
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/continue.js +14 -15
- package/dist/bridge/drivers/continue.js.map +1 -1
- package/dist/bridge/drivers/echo.js +4 -4
- package/dist/bridge/drivers/gemini.js +8 -8
- package/dist/bridge/drivers/goose.js +14 -15
- package/dist/bridge/drivers/goose.js.map +1 -1
- package/dist/bridge/drivers/omp.js +70 -104
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/drivers/opencode.js +14 -15
- package/dist/bridge/drivers/opencode.js.map +1 -1
- package/dist/bridge/drivers/qwen.js +8 -8
- package/dist/bridge/index.js +16 -17
- package/dist/bridge/src/codex/managed-driver.d.ts +13 -10
- package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
- package/dist/bridge/src/drivers/_subprocess-cli.d.ts +12 -2
- package/dist/bridge/src/drivers/_subprocess-cli.d.ts.map +1 -1
- package/dist/bridge/src/drivers/claude-sdk.d.ts +67 -62
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/claude-tool-allowlist.d.ts +43 -0
- package/dist/bridge/src/drivers/claude-tool-allowlist.d.ts.map +1 -0
- package/dist/bridge/src/drivers/codex.d.ts +26 -10
- package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
- package/dist/bridge/src/drivers/continue.d.ts +2 -2
- package/dist/bridge/src/drivers/continue.d.ts.map +1 -1
- package/dist/bridge/src/drivers/gemini.d.ts +2 -2
- package/dist/bridge/src/drivers/gemini.d.ts.map +1 -1
- package/dist/bridge/src/drivers/goose.d.ts +2 -2
- package/dist/bridge/src/drivers/goose.d.ts.map +1 -1
- package/dist/bridge/src/drivers/omp.d.ts +24 -35
- package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
- package/dist/bridge/src/drivers/opencode.d.ts +2 -2
- package/dist/bridge/src/drivers/opencode.d.ts.map +1 -1
- package/dist/bridge/src/drivers/recovery-policy.d.ts +79 -0
- package/dist/bridge/src/drivers/recovery-policy.d.ts.map +1 -0
- package/dist/bridge/src/index.d.ts +1 -0
- package/dist/bridge/src/index.d.ts.map +1 -1
- package/dist/bridge/src/reconfigure-ledger.d.ts +117 -0
- package/dist/bridge/src/reconfigure-ledger.d.ts.map +1 -0
- package/dist/bridge/src/types.d.ts +77 -7
- package/dist/bridge/src/types.d.ts.map +1 -1
- package/dist/{chunk-WIEC3ZE4.js → chunk-2FRUUDZY.js} +5 -5
- package/dist/{chunk-WIEC3ZE4.js.map → chunk-2FRUUDZY.js.map} +1 -1
- package/dist/{chunk-NARITJS2.js → chunk-2H73V6XR.js} +3 -3
- package/dist/{chunk-NARITJS2.js.map → chunk-2H73V6XR.js.map} +1 -1
- package/dist/{chunk-O4Z7MAW7.js → chunk-2LWYNQK7.js} +3 -3
- package/dist/{chunk-O4Z7MAW7.js.map → chunk-2LWYNQK7.js.map} +1 -1
- package/dist/{chunk-OOLT6HGP.js → chunk-36AFURKZ.js} +7 -7
- package/dist/{chunk-OOLT6HGP.js.map → chunk-36AFURKZ.js.map} +1 -1
- package/dist/{chunk-DFFD4BFG.js → chunk-4MQS7CAF.js} +174 -86
- package/dist/chunk-4MQS7CAF.js.map +1 -0
- package/dist/{chunk-RNPHRRLG.js → chunk-4PTSR4UU.js} +3 -3
- package/dist/{chunk-RNPHRRLG.js.map → chunk-4PTSR4UU.js.map} +1 -1
- package/dist/{chunk-BTK7ECLH.js → chunk-5NNNV76P.js} +41 -8
- package/dist/chunk-5NNNV76P.js.map +1 -0
- package/dist/{chunk-IZLQ4GDO.js → chunk-7AI3Q5AQ.js} +43 -21
- package/dist/chunk-7AI3Q5AQ.js.map +1 -0
- package/dist/{chunk-NFGRW3L7.js → chunk-7RGTAEG6.js} +3 -3
- package/dist/{chunk-NFGRW3L7.js.map → chunk-7RGTAEG6.js.map} +1 -1
- package/dist/{chunk-XBSQ4KMC.js → chunk-B4X2N7JQ.js} +205 -3
- package/dist/chunk-B4X2N7JQ.js.map +1 -0
- package/dist/{chunk-FRHE7FFB.js → chunk-B6GIW55K.js} +5 -3
- package/dist/chunk-B6GIW55K.js.map +1 -0
- package/dist/{chunk-RVIZQ5XD.js → chunk-BTE2V4IW.js} +3 -3
- package/dist/{chunk-RVIZQ5XD.js.map → chunk-BTE2V4IW.js.map} +1 -1
- package/dist/{chunk-EB4XN3KE.js → chunk-CGT45WN7.js} +3 -3
- package/dist/{chunk-EB4XN3KE.js.map → chunk-CGT45WN7.js.map} +1 -1
- package/dist/{chunk-FAP63KV7.js → chunk-CKQEIY43.js} +4 -4
- package/dist/{chunk-FAP63KV7.js.map → chunk-CKQEIY43.js.map} +1 -1
- package/dist/{chunk-NWQB7UTY.js → chunk-DNZYOKOJ.js} +3 -3
- package/dist/{chunk-NWQB7UTY.js.map → chunk-DNZYOKOJ.js.map} +1 -1
- package/dist/{chunk-AVCUPPG6.js → chunk-EF7NPDDU.js} +4 -4
- package/dist/{chunk-AVCUPPG6.js.map → chunk-EF7NPDDU.js.map} +1 -1
- package/dist/chunk-EPBKISS5.js +84 -0
- package/dist/chunk-EPBKISS5.js.map +1 -0
- package/dist/{chunk-DMLDYFDS.js → chunk-F4NJDSR7.js} +9 -5
- package/dist/chunk-F4NJDSR7.js.map +1 -0
- package/dist/{chunk-PSA6ONFB.js → chunk-FVJK4QWM.js} +4 -4
- package/dist/{chunk-PSA6ONFB.js.map → chunk-FVJK4QWM.js.map} +1 -1
- package/dist/{chunk-KNWCFEWU.js → chunk-FYXZRVID.js} +20 -7
- package/dist/{chunk-KNWCFEWU.js.map → chunk-FYXZRVID.js.map} +1 -1
- package/dist/{chunk-LBQ4BBX4.js → chunk-FZNG4V4J.js} +16 -30
- package/dist/chunk-FZNG4V4J.js.map +1 -0
- package/dist/{chunk-SWO25LTO.js → chunk-GB7WDMH2.js} +4 -4
- package/dist/{chunk-SWO25LTO.js.map → chunk-GB7WDMH2.js.map} +1 -1
- package/dist/{chunk-EU3Q5AQ4.js → chunk-GKMZ6THE.js} +23 -32
- package/dist/chunk-GKMZ6THE.js.map +1 -0
- package/dist/{chunk-TTPSDC2G.js → chunk-GTILM2CI.js} +34 -13
- package/dist/chunk-GTILM2CI.js.map +1 -0
- package/dist/{chunk-LXY4BUA3.js → chunk-GXLQLPE5.js} +9 -5
- package/dist/chunk-GXLQLPE5.js.map +1 -0
- package/dist/{chunk-D5HOETOB.js → chunk-IMKSM5NL.js} +981 -126
- package/dist/chunk-IMKSM5NL.js.map +1 -0
- package/dist/{chunk-6UFFKMVC.js → chunk-IR33D6EP.js} +6 -6
- package/dist/{chunk-6UFFKMVC.js.map → chunk-IR33D6EP.js.map} +1 -1
- package/dist/{chunk-CT6NQSA4.js → chunk-ISHJITXJ.js} +3 -3
- package/dist/{chunk-CT6NQSA4.js.map → chunk-ISHJITXJ.js.map} +1 -1
- package/dist/chunk-IZCR27MU.js +60 -0
- package/dist/chunk-IZCR27MU.js.map +1 -0
- package/dist/{chunk-GWXFSLBK.js → chunk-J7U3PIOE.js} +4 -4
- package/dist/{chunk-GWXFSLBK.js.map → chunk-J7U3PIOE.js.map} +1 -1
- package/dist/{chunk-LCU5U5IW.js → chunk-JAKOMFC6.js} +67 -19
- package/dist/chunk-JAKOMFC6.js.map +1 -0
- package/dist/{chunk-THEJJBOU.js → chunk-JZ5EHBPI.js} +3 -3
- package/dist/{chunk-THEJJBOU.js.map → chunk-JZ5EHBPI.js.map} +1 -1
- package/dist/{chunk-BWZF2ZIF.js → chunk-K3CVFRVS.js} +3 -3
- package/dist/{chunk-BWZF2ZIF.js.map → chunk-K3CVFRVS.js.map} +1 -1
- package/dist/{chunk-VOOI7B2L.js → chunk-LAMCXQGA.js} +241 -73
- package/dist/chunk-LAMCXQGA.js.map +1 -0
- package/dist/{chunk-37FTLYFP.js → chunk-LNFKL23K.js} +3 -3
- package/dist/{chunk-37FTLYFP.js.map → chunk-LNFKL23K.js.map} +1 -1
- package/dist/{chunk-XUUYAS3Z.js → chunk-M3WPBTGJ.js} +3 -3
- package/dist/{chunk-XUUYAS3Z.js.map → chunk-M3WPBTGJ.js.map} +1 -1
- package/dist/{chunk-QZLWJETK.js → chunk-MGGFBZWA.js} +3 -3
- package/dist/{chunk-QZLWJETK.js.map → chunk-MGGFBZWA.js.map} +1 -1
- package/dist/{chunk-34C42MJX.js → chunk-MR5HBOUF.js} +5 -5
- package/dist/{chunk-34C42MJX.js.map → chunk-MR5HBOUF.js.map} +1 -1
- package/dist/{chunk-QCI6D7E4.js → chunk-NUELZWCF.js} +266 -170
- package/dist/chunk-NUELZWCF.js.map +1 -0
- package/dist/{chunk-GIC3G5YG.js → chunk-P67WJVP4.js} +7 -13
- package/dist/chunk-P67WJVP4.js.map +1 -0
- package/dist/{chunk-G67BOI2J.js → chunk-PMECEZK3.js} +15 -9
- package/dist/chunk-PMECEZK3.js.map +1 -0
- package/dist/{chunk-OKGUDNDT.js → chunk-Q6E6FM7P.js} +35 -33
- package/dist/chunk-Q6E6FM7P.js.map +1 -0
- package/dist/{chunk-CWM3MYGX.js → chunk-QVEKLSEH.js} +8 -9
- package/dist/chunk-QVEKLSEH.js.map +1 -0
- package/dist/{chunk-O7VPNKYN.js → chunk-QVNRCDTV.js} +23 -7
- package/dist/chunk-QVNRCDTV.js.map +1 -0
- package/dist/{chunk-UX3K4RKE.js → chunk-S53LOR7B.js} +3 -3
- package/dist/{chunk-UX3K4RKE.js.map → chunk-S53LOR7B.js.map} +1 -1
- package/dist/{chunk-53MSCGR2.js → chunk-SCOT677Q.js} +5 -5
- package/dist/{chunk-53MSCGR2.js.map → chunk-SCOT677Q.js.map} +1 -1
- package/dist/{chunk-SZWRPEF7.js → chunk-TTRYE6AC.js} +39 -29
- package/dist/chunk-TTRYE6AC.js.map +1 -0
- package/dist/{chunk-KM7XWC4Y.js → chunk-UAROCOXF.js} +3 -3
- package/dist/{chunk-KM7XWC4Y.js.map → chunk-UAROCOXF.js.map} +1 -1
- package/dist/{chunk-MKLBK7HI.js → chunk-UM7RIAHO.js} +17 -13
- package/dist/chunk-UM7RIAHO.js.map +1 -0
- package/dist/{chunk-JMKB7IB4.js → chunk-UMVKJM4Q.js} +4 -4
- package/dist/chunk-UMVKJM4Q.js.map +1 -0
- package/dist/{chunk-JLSCA5T5.js → chunk-UO7WPLDY.js} +3 -3
- package/dist/{chunk-JLSCA5T5.js.map → chunk-UO7WPLDY.js.map} +1 -1
- package/dist/{chunk-HCYS7GFP.js → chunk-V2DXZYBB.js} +3 -3
- package/dist/{chunk-HCYS7GFP.js.map → chunk-V2DXZYBB.js.map} +1 -1
- package/dist/{chunk-47ZD34KB.js → chunk-VMKMFS2Q.js} +28 -7
- package/dist/chunk-VMKMFS2Q.js.map +1 -0
- package/dist/{chunk-IUUYRXT6.js → chunk-W5DWWE4Y.js} +4 -4
- package/dist/{chunk-IUUYRXT6.js.map → chunk-W5DWWE4Y.js.map} +1 -1
- package/dist/{chunk-FK6HPLQA.js → chunk-X4BAYGMT.js} +3 -3
- package/dist/{chunk-FK6HPLQA.js.map → chunk-X4BAYGMT.js.map} +1 -1
- package/dist/{chunk-OJ4N4T4H.js → chunk-XDVR7QIT.js} +20 -6
- package/dist/chunk-XDVR7QIT.js.map +1 -0
- package/dist/{chunk-7FJQT3GT.js → chunk-Y4N2NUZD.js} +4 -4
- package/dist/{chunk-7FJQT3GT.js.map → chunk-Y4N2NUZD.js.map} +1 -1
- package/dist/{chunk-6VRJH4MR.js → chunk-Y7QA2OLD.js} +6 -6
- package/dist/{chunk-6VRJH4MR.js.map → chunk-Y7QA2OLD.js.map} +1 -1
- package/dist/{chunk-74EEFB52.js → chunk-YSHVQGUS.js} +115 -27
- package/dist/chunk-YSHVQGUS.js.map +1 -0
- package/dist/{chunk-6C654TFI.js → chunk-ZAOGFXDO.js} +36 -8
- package/dist/chunk-ZAOGFXDO.js.map +1 -0
- package/dist/{chunk-N6FBTXQ5.js → chunk-ZTBAYUDY.js} +2 -2
- package/dist/{chunk-N6FBTXQ5.js.map → chunk-ZTBAYUDY.js.map} +1 -1
- package/dist/cli/index.js +373 -188
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/asset-feeds.d.ts +5 -2
- package/dist/cli/src/asset-feeds.d.ts.map +1 -1
- package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +15 -2
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/library-index.d.ts +8 -0
- 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/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/outdated.d.ts +7 -2
- package/dist/cli/src/commands/outdated.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts +2 -0
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/publish-core.d.ts +10 -1
- package/dist/cli/src/commands/publish-core.d.ts.map +1 -1
- package/dist/cli/src/commands/session.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts +14 -0
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/tree.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/flow-discovery.d.ts +8 -5
- package/dist/cli/src/flow-discovery.d.ts.map +1 -1
- package/dist/cli/src/open-library.d.ts +0 -11
- package/dist/cli/src/open-library.d.ts.map +1 -1
- package/dist/cli/src/skill-checks.d.ts +11 -2
- package/dist/cli/src/skill-checks.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/src/client.d.ts +10 -3
- package/dist/client/src/client.d.ts.map +1 -1
- package/dist/connectors/config.js +5 -5
- package/dist/connectors/index.js +25 -26
- package/dist/connectors/src/access-policy.d.ts +33 -0
- package/dist/connectors/src/access-policy.d.ts.map +1 -0
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/connectors/src/index.d.ts +2 -0
- package/dist/connectors/src/index.d.ts.map +1 -1
- package/dist/connectors-C7UQ73BK.js +44 -0
- package/dist/{connectors-SSOTIDHT.js.map → connectors-C7UQ73BK.js.map} +1 -1
- package/dist/connectors-shared/index.js +2 -2
- package/dist/core/index.js +8 -8
- package/dist/core/logging.js +1 -1
- package/dist/core/manifest.js +2 -2
- package/dist/core/models.js +1 -1
- package/dist/core/publish-manifest.js +2 -2
- package/dist/core/ref.js +1 -1
- package/dist/core/runtime-assets.js +5 -5
- package/dist/core/src/index.d.ts +3 -3
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/logging/config.d.ts +9 -1
- package/dist/core/src/logging/config.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +11 -1
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +14 -6
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts +41 -6
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/store.d.ts +16 -2
- package/dist/core/src/store.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +10 -1
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/store.js +1 -1
- package/dist/core/workspace-config.js +4 -4
- package/dist/deploy/index.js +8 -8
- package/dist/discovery/index.js +5 -5
- package/dist/{ensure-sources-277VI7R3.js → ensure-sources-SRC2DVR5.js} +18 -18
- package/dist/{ensure-sources-277VI7R3.js.map → ensure-sources-SRC2DVR5.js.map} +1 -1
- package/dist/factory-assets/connectors/box.js +25 -26
- package/dist/factory-assets/connectors/deploy.js +25 -26
- package/dist/factory-assets/connectors/devserver.js +25 -26
- package/dist/factory-assets/connectors/flow/adapter.d.ts +6 -0
- package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/adapter.js +25 -26
- package/dist/factory-assets/connectors/flow/contract/expression.d.ts +3 -0
- package/dist/factory-assets/connectors/flow/contract/expression.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/contract/output-fields.d.ts +1 -1
- package/dist/factory-assets/connectors/flow/contract/output-fields.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/contract/schema.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/contract.js +4 -4
- package/dist/factory-assets/connectors/flow/engine/flow-output.d.ts +4 -3
- package/dist/factory-assets/connectors/flow/engine/flow-output.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/engine/output-schema.d.ts +6 -1
- package/dist/factory-assets/connectors/flow/engine/output-schema.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/engine.js +12 -12
- package/dist/factory-assets/connectors/flow/inline-sub-flow-host.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/prompt-fragments.js +3 -3
- package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.js +27 -28
- package/dist/factory-assets/connectors/flow.js +25 -26
- package/dist/factory-assets/connectors/git/config.d.ts.map +1 -1
- package/dist/factory-assets/connectors/git.js +25 -26
- package/dist/factory-assets/connectors/gmail.js +25 -26
- package/dist/factory-assets/connectors/googledrive.js +25 -26
- package/dist/factory-assets/connectors/local.js +25 -26
- package/dist/factory-assets/connectors/mattermost.js +25 -26
- package/dist/factory-assets/connectors/memory.js +25 -26
- package/dist/factory-assets/connectors/minio.js +25 -26
- package/dist/factory-assets/connectors/postgres.js +25 -26
- package/dist/factory-assets/connectors/s3.js +25 -26
- package/dist/factory-assets/connectors/sharepoint.js +25 -26
- package/dist/factory-assets/connectors/sqlite.js +25 -26
- package/dist/factory-assets/connectors/static-server.js +25 -26
- package/dist/factory-assets/connectors/tunnel.js +25 -26
- package/dist/factory-assets/connectors/webdav.js +25 -26
- package/dist/factory-assets/connectors/xstate-store.js +25 -26
- package/dist/factory-assets/connectors/xstate.js +25 -26
- package/dist/factory-assets/skills/skaile-author-asset/SKILL.md +10 -7
- package/dist/{flows-J2UEU2QM.js → flows-CBYRSAGS.js} +13 -13
- package/dist/{flows-J2UEU2QM.js.map → flows-CBYRSAGS.js.map} +1 -1
- package/dist/{helpers-KC5O7CML.js → helpers-XAEKCZKT.js} +18 -18
- package/dist/{helpers-KC5O7CML.js.map → helpers-XAEKCZKT.js.map} +1 -1
- package/dist/library/index.js +12 -12
- package/dist/library/install.js +3 -3
- package/dist/library/src/index.d.ts +3 -1
- package/dist/library/src/index.d.ts.map +1 -1
- package/dist/library/src/local/scan-authoring-libraries.d.ts +43 -0
- package/dist/library/src/local/scan-authoring-libraries.d.ts.map +1 -0
- package/dist/library/src/manifest-writer.d.ts +26 -3
- package/dist/library/src/manifest-writer.d.ts.map +1 -1
- package/dist/library/src/sync/git-driver.d.ts.map +1 -1
- package/dist/{library-publish-FGXF5TJO.js → library-publish-VJSWMOLH.js} +73 -37
- package/dist/library-publish-VJSWMOLH.js.map +1 -0
- package/dist/open-library-DB2PNL2X.js +40 -0
- package/dist/{open-library-P3D337NH.js.map → open-library-DB2PNL2X.js.map} +1 -1
- package/dist/open-registry-ZUZJ7MS7.js +32 -0
- package/dist/{open-registry-Z3P2X2AB.js.map → open-registry-ZUZJ7MS7.js.map} +1 -1
- package/dist/paths-FQ64OLJG.js +22 -0
- package/dist/{paths-JKEKXM52.js.map → paths-FQ64OLJG.js.map} +1 -1
- package/dist/{plugin-store-WI4MZJLP.js → plugin-store-MPAMD5OT.js} +10 -10
- package/dist/{plugin-store-WI4MZJLP.js.map → plugin-store-MPAMD5OT.js.map} +1 -1
- package/dist/project-I6NX3NFB.js +41 -0
- package/dist/{project-WFUDVYNN.js.map → project-I6NX3NFB.js.map} +1 -1
- package/dist/resolver/index.js +9 -9
- package/dist/runner/index.js +40 -41
- package/dist/runner/src/context-usage/compose.d.ts.map +1 -1
- package/dist/runner/src/logging-bootstrap.d.ts +6 -0
- package/dist/runner/src/logging-bootstrap.d.ts.map +1 -1
- package/dist/runner/src/platform-blocks.d.ts +55 -0
- package/dist/runner/src/platform-blocks.d.ts.map +1 -0
- package/dist/runner/src/reconfigure-handler.d.ts +38 -17
- package/dist/runner/src/reconfigure-handler.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/runner/src/session-capability-wiring.d.ts +0 -2
- package/dist/runner/src/session-capability-wiring.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +15 -15
- package/dist/sdk/bridge.js +16 -17
- package/dist/sdk/client.js +1 -1
- package/dist/sdk/core.js +8 -8
- package/dist/sdk/flow.js +12 -12
- package/dist/sdk/index.js +69 -46
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.js +9 -9
- package/dist/sdk/runner.js +40 -41
- package/dist/sdk/session.js +2 -2
- package/dist/sdk/src/agent-session.d.ts +8 -0
- package/dist/sdk/src/agent-session.d.ts.map +1 -1
- package/dist/sdk/store.js +2 -1
- package/dist/sdk/types.js +1 -1
- package/dist/session/index.js +2 -2
- package/dist/session/src/dispatcher.d.ts +25 -4
- package/dist/session/src/dispatcher.d.ts.map +1 -1
- package/dist/session/src/index.d.ts +1 -1
- package/dist/session/src/index.d.ts.map +1 -1
- package/dist/{setup-RAMLTORM.js → setup-B7JUHYJW.js} +26 -27
- package/dist/setup-B7JUHYJW.js.map +1 -0
- package/dist/skills-TVO26Y4V.js +26 -0
- package/dist/{skills-EOHZ2DZ4.js.map → skills-TVO26Y4V.js.map} +1 -1
- package/dist/source-PJBMDCKX.js +41 -0
- package/dist/{source-FYVSFYEI.js.map → source-PJBMDCKX.js.map} +1 -1
- package/dist/{source-manifest-publish-4FPIPPLV.js → source-manifest-publish-LLJWXGID.js} +27 -27
- package/dist/{source-manifest-publish-4FPIPPLV.js.map → source-manifest-publish-LLJWXGID.js.map} +1 -1
- package/dist/store/index.js +2 -1
- package/dist/store/src/store.d.ts +8 -5
- package/dist/store/src/store.d.ts.map +1 -1
- package/dist/tui/index.js +40 -41
- package/dist/tui/index.js.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/manifests.js +1 -1
- package/dist/types/src/ask-slots.d.ts +68 -0
- package/dist/types/src/ask-slots.d.ts.map +1 -0
- package/dist/types/src/delivery.d.ts.map +1 -1
- package/dist/types/src/events.d.ts +30 -2
- package/dist/types/src/events.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +3 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/manifests/index.d.ts +1 -1
- package/dist/types/src/manifests/index.d.ts.map +1 -1
- package/dist/types/src/manifests/preset.d.ts +4 -0
- package/dist/types/src/manifests/preset.d.ts.map +1 -1
- package/dist/types/src/protocol.d.ts +43 -1
- package/dist/types/src/protocol.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +28 -1
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +32 -33
- package/dist/workspace-plugin/adapters/omp.js +14 -14
- package/dist/workspace-plugin/index.js +2 -2
- package/package.json +1 -1
- package/dist/asset-feeds-K36CR52Q.js.map +0 -1
- package/dist/chunk-47ZD34KB.js.map +0 -1
- package/dist/chunk-6C654TFI.js.map +0 -1
- package/dist/chunk-74EEFB52.js.map +0 -1
- package/dist/chunk-BTK7ECLH.js.map +0 -1
- package/dist/chunk-CWM3MYGX.js.map +0 -1
- package/dist/chunk-D5HOETOB.js.map +0 -1
- package/dist/chunk-DFFD4BFG.js.map +0 -1
- package/dist/chunk-DMLDYFDS.js.map +0 -1
- package/dist/chunk-EINLFFP6.js +0 -59
- package/dist/chunk-EINLFFP6.js.map +0 -1
- package/dist/chunk-EU3Q5AQ4.js.map +0 -1
- package/dist/chunk-FRHE7FFB.js.map +0 -1
- package/dist/chunk-G67BOI2J.js.map +0 -1
- package/dist/chunk-GIC3G5YG.js.map +0 -1
- package/dist/chunk-IZLQ4GDO.js.map +0 -1
- package/dist/chunk-JMKB7IB4.js.map +0 -1
- package/dist/chunk-LBQ4BBX4.js.map +0 -1
- package/dist/chunk-LCU5U5IW.js.map +0 -1
- package/dist/chunk-LXY4BUA3.js.map +0 -1
- package/dist/chunk-MKLBK7HI.js.map +0 -1
- package/dist/chunk-O7VPNKYN.js.map +0 -1
- package/dist/chunk-OJ4N4T4H.js.map +0 -1
- package/dist/chunk-OKGUDNDT.js.map +0 -1
- package/dist/chunk-QCI6D7E4.js.map +0 -1
- package/dist/chunk-SZWRPEF7.js.map +0 -1
- package/dist/chunk-TTPSDC2G.js.map +0 -1
- package/dist/chunk-VOOI7B2L.js.map +0 -1
- package/dist/chunk-XBSQ4KMC.js.map +0 -1
- package/dist/connectors-SSOTIDHT.js +0 -45
- package/dist/library-publish-FGXF5TJO.js.map +0 -1
- package/dist/open-library-P3D337NH.js +0 -40
- package/dist/open-registry-Z3P2X2AB.js +0 -32
- package/dist/paths-JKEKXM52.js +0 -22
- package/dist/project-WFUDVYNN.js +0 -41
- package/dist/setup-RAMLTORM.js.map +0 -1
- package/dist/skills-EOHZ2DZ4.js +0 -26
- package/dist/source-FYVSFYEI.js +0 -41
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../core/src/fs-deadline.ts","../core/src/manifest.ts"],"names":[],"mappings":"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","file":"chunk-GTILM2CI.js","sourcesContent":["/**\n * Deadline guards for filesystem work that can land on a network mount.\n *\n * Inside the agent container `/skaile/workspace` **is** an rclone FUSE mount\n * (SharePoint / OneDrive / WebDAV). When the host rclone process wedges, a\n * filesystem call against that path parks in an uninterruptible kernel wait.\n * A **synchronous** call there stops the entire single-threaded event loop —\n * the whole `skaile serve` process stops serving, and the platform reads the\n * session as dead or idle. A hang is not an error, so `try/catch` never fires.\n *\n * Two rules follow, and both matter:\n *\n * 1. **Never touch a mount synchronously.** Async `node:fs/promises` keeps the\n * loop free, so a wedged mount degrades to one stuck request instead of a\n * dead session. This is the actual fix.\n * 2. **Bound the wait.** {@link withFsDeadline} converts an unbounded wait into\n * a bounded failure so the requester gets an error rather than nothing.\n *\n * `withFsDeadline` does **not** cancel the underlying operation — Node cannot\n * abort a syscall already in the kernel. The losing promise stays pending until\n * the mount recovers or the process exits. That is acceptable precisely because\n * rule 1 holds: a pending promise costs one handle, not the event loop.\n *\n * Modelled on `connectors/src/fleet-utils.ts` (`ensureFleetMounted`), which\n * already does async-stat-with-deadline correctly.\n */\n\n/** Default deadline for a single filesystem operation on a possibly-networked mount. */\nexport const DEFAULT_FS_DEADLINE_MS = 15_000;\n\n/**\n * Env override for {@link DEFAULT_FS_DEADLINE_MS}, in milliseconds.\n *\n * A cloud-backed mount over a slow link can legitimately need longer than the\n * default; operators raise this rather than patching call sites.\n */\nexport const FS_DEADLINE_ENV_VAR = \"SKAILE_FS_DEADLINE_MS\";\n\n/**\n * Thrown when a filesystem operation misses its deadline.\n *\n * Distinct from a plain `Error` so callers can tell \"the mount is wedged\" apart\n * from \"the file does not exist\" and surface the right message to the frontend.\n */\nexport class FsDeadlineError extends Error {\n readonly timeoutMs: number;\n readonly operation: string;\n\n constructor(operation: string, timeoutMs: number) {\n super(\n `filesystem operation \"${operation}\" exceeded ${timeoutMs}ms — the mount may be unresponsive`,\n );\n this.name = \"FsDeadlineError\";\n this.operation = operation;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Resolve the effective filesystem deadline.\n *\n * Reads {@link FS_DEADLINE_ENV_VAR} on every call rather than caching it: the\n * runner mutates `process.env` while wiring a session, so a module-load-time\n * snapshot would pin the value set before configuration ran.\n *\n * @param fallback - Deadline to use when the env var is absent or unusable.\n * @returns The deadline in milliseconds.\n */\nexport function fsDeadlineMs(fallback: number = DEFAULT_FS_DEADLINE_MS): number {\n const raw = process.env[FS_DEADLINE_ENV_VAR];\n if (raw === undefined) return fallback;\n const parsed = Number.parseInt(raw, 10);\n // A non-positive or non-numeric override would disable the guard entirely,\n // which is exactly the failure mode this module exists to prevent.\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n}\n\n/**\n * Run an async filesystem operation under a deadline.\n *\n * @param operation - Short label used in the timeout message (e.g. `\"readdir /skaile/workspace\"`).\n * @param fn - Thunk performing the operation. Called immediately.\n * @param timeoutMs - Deadline override; defaults to {@link fsDeadlineMs}.\n * @returns The operation's result.\n * @throws {FsDeadlineError} when the deadline elapses first.\n * @throws Whatever `fn` rejects with, unchanged, when it loses no race.\n * @docLink packages/core/api-reference#with-fs-deadline\n */\nexport async function withFsDeadline<T>(\n operation: string,\n fn: () => Promise<T>,\n timeoutMs: number = fsDeadlineMs(),\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n fn(),\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => reject(new FsDeadlineError(operation, timeoutMs)), timeoutMs);\n // Never hold the process open on the guard alone — without unref a\n // pending deadline would keep `skaile serve` alive after shutdown.\n timer.unref?.();\n }),\n ]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\n/**\n * Run an async filesystem operation under a deadline, mapping every failure to\n * `fallback`.\n *\n * For best-effort probes that previously used `existsSync` — a missing file, an\n * unreadable file, and a wedged mount are all \"nothing usable here\", and the\n * caller has no better move than to continue without it.\n *\n * @param operation - Short label used in the timeout message.\n * @param fn - Thunk performing the operation.\n * @param fallback - Value returned when `fn` rejects or the deadline elapses.\n * @param timeoutMs - Deadline override; defaults to {@link fsDeadlineMs}.\n */\nexport async function tryWithFsDeadline<T>(\n operation: string,\n fn: () => Promise<T>,\n fallback: T,\n timeoutMs: number = fsDeadlineMs(),\n): Promise<T> {\n try {\n return await withFsDeadline(operation, fn, timeoutMs);\n } catch {\n return fallback;\n }\n}\n","/**\n * Manifest parsing — reads SKILL.md, AGENT.md, agent.yaml, CONTRACT.md,\n * CONNECTOR.md, *.prompt.md, *.flow.yaml, *.preset.yaml files and\n * produces CatalogEntry objects.\n * Used by @skaile/asset-manager for on-demand repo scanning.\n *\n * **All filesystem access here is async and bounded** (issue #454). A repo root\n * can resolve onto the rclone FUSE mount at `/skaile/workspace` — either\n * directly (a `sources[].path` pointing into the workspace) or indirectly, since\n * the walk follows symlinks and an off-mount tree can link into one. A\n * synchronous `readdirSync`/`statSync`/`readFileSync` there parks the whole\n * `skaile serve` event loop in an uninterruptible kernel wait, and a hang is not\n * an error so `try/catch` never fires. Every call goes through\n * {@link withFsDeadline}/{@link tryWithFsDeadline}, and the walk itself is\n * bounded by depth, entry count, a wall-clock budget, and an ancestor-inode set.\n */\n\nimport type { Dirent } from \"node:fs\";\nimport { opendir, readFile, stat } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport { parse } from \"yaml\";\nimport { fsDeadlineMs, tryWithFsDeadline, withFsDeadline } from \"./fs-deadline.js\";\nimport { createLogger } from \"./logging/create-logger.js\";\nimport type { AssetKind, CatalogEntry, Dependency } from \"./models.js\";\nimport { isValidAssetName, parseDep, slugifyAssetName } from \"./models.js\";\nimport type { Diagnostic } from \"./workspace-config.js\";\n\n// ── Bounded manifest I/O ──────────────────────────────────────────────────────\n\n/**\n * Read one manifest file under a deadline.\n *\n * @param filePath - Absolute path to the manifest.\n * @param timeoutMs - Per-operation deadline; defaults to {@link fsDeadlineMs}.\n * @throws {import(\"./fs-deadline.js\").FsDeadlineError} when the read outlives the deadline.\n */\nfunction readManifestFile(filePath: string, timeoutMs?: number): Promise<string> {\n return withFsDeadline(`readFile ${filePath}`, () => readFile(filePath, \"utf8\"), timeoutMs);\n}\n\n/**\n * Read one manifest file under a deadline, degrading an unreadable/slow file to\n * an empty document. Mirrors the pre-#454 `try { readFileSync } catch {}` shape\n * of the YAML parsers: a file we cannot read yields `{}` metadata rather than\n * aborting the caller.\n */\nfunction readManifestFileOrEmpty(filePath: string, timeoutMs?: number): Promise<string> {\n return tryWithFsDeadline(`readFile ${filePath}`, () => readFile(filePath, \"utf8\"), \"\", timeoutMs);\n}\n\n// ── Frontmatter helpers ───────────────────────────────────────────────────────\n\n/**\n * Result of parsing YAML frontmatter from a markdown file.\n * @docLink packages/core/concepts#frontmatter-result\n */\nexport interface FrontmatterResult {\n /** Parsed YAML data. Empty object if no frontmatter block is present. */\n data: Record<string, unknown>;\n /** Markdown body below the frontmatter block (trimmed). */\n body: string;\n}\n\n/**\n * Parse YAML frontmatter from a markdown file (`---` delimited).\n * Returns `{ data: {}, body: text }` when no frontmatter block is present.\n *\n * @param text - Raw file contents\n * @returns Parsed frontmatter data and the remaining body text\n * @docLink packages/core/concepts#parse-frontmatter\n */\nexport function parseFrontmatter(text: string): FrontmatterResult {\n const m = text.match(/^---\\s*\\n([\\s\\S]*?)\\n---/);\n if (!m) return { data: {}, body: text.trim() };\n try {\n const data = (parse(m[1]!) as Record<string, unknown>) ?? {};\n const body = text.slice(m[0].length).trim();\n return { data, body };\n } catch {\n return { data: {}, body: text.trim() };\n }\n}\n\n/** Extract version from frontmatter, checking both top-level and metadata.version. */\nfunction extractVersion(meta: Record<string, unknown>): string {\n return String(\n meta.version ?? (meta.metadata as Record<string, unknown> | undefined)?.version ?? \"\",\n );\n}\n\n/**\n * Parse the `requires:` field from manifest frontmatter into typed `Dependency` objects.\n * Accepts a comma-separated string or an array of `\"kind:name\"` strings. Reads from either\n * the root or `metadata.requires` (matching `extractVersion`'s dual-location behavior) so\n * skill authors can follow the agentskills.io convention of placing skaile extensions under\n * `metadata:` while remaining backward-compatible with root-level declarations.\n *\n * @param meta - Parsed frontmatter data object\n * @returns Array of `Dependency` objects (empty when `requires` is absent)\n * @docLink packages/core/concepts#parse-requires\n */\nexport function parseRequires(meta: Record<string, unknown>): Dependency[] {\n const raw = meta.requires ?? (meta.metadata as Record<string, unknown> | undefined)?.requires;\n if (!raw) return [];\n const list =\n typeof raw === \"string\"\n ? raw.split(\",\").map((s) => s.trim())\n : Array.isArray(raw)\n ? (raw as string[])\n : [];\n return list.filter(Boolean).map(parseDep);\n}\n\n// ── agent.yaml composes → requires ─────────────────────────────────────────────\n\n/**\n * Collect the catalog refs of an `agent.yaml` `composes[]` list as requires so\n * `skaile install` pulls them automatically. Local paths (`.`/`/`) and\n * `library://` instance refs are skipped — not catalog assets. A ref without a\n * `kind:` prefix takes the item's `kind`; the publisher scope, `@version` and\n * `#pin` are stripped so only `kind:name` is tracked.\n */\nfunction collectComposeRefs(raw: unknown, out: Dependency[]): void {\n if (!Array.isArray(raw)) return;\n for (const item of raw) {\n if (typeof item !== \"object\" || item === null) continue;\n const { kind: itemKind, ref } = item as Record<string, unknown>;\n if (typeof ref !== \"string\" || !ref) continue;\n if (ref.startsWith(\".\") || ref.startsWith(\"/\") || ref.includes(\"://\")) continue;\n if (typeof itemKind !== \"string\" || !itemKind) continue;\n const normalized = ref.includes(\":\") ? ref : `${itemKind}:${ref}`;\n const colonIdx = normalized.indexOf(\":\");\n const kind = normalized.slice(0, colonIdx).trim();\n let rest = normalized.slice(colonIdx + 1).trim();\n const hashIdx = rest.indexOf(\"#\");\n if (hashIdx !== -1) rest = rest.slice(0, hashIdx).trim();\n if (rest.startsWith(\"@\")) {\n // Scoped form @publisher/name → name is the segment after the slash.\n const slashIdx = rest.indexOf(\"/\");\n rest = slashIdx !== -1 ? rest.slice(slashIdx + 1).trim() : \"\";\n }\n // A trailing `@<version>` range (`name@^1`) is not part of the name.\n const atIdx = rest.indexOf(\"@\");\n const name = atIdx !== -1 ? rest.slice(0, atIdx).trim() : rest;\n if (name) out.push({ kind, name });\n }\n}\n\n// ── Manifest parsers ──────────────────────────────────────────────────────────\n\n/**\n * Thrown when a `SKILL.md`-style manifest declares a `type:` that is not a\n * registered asset kind. The kind registry is the only authority on kinds, so an\n * unregistered `type:` is reported (see {@link manifestKindDiagnostic}) instead\n * of being silently catalogued as a skill.\n */\nexport class ManifestKindError extends Error {\n constructor(\n readonly filePath: string,\n readonly kind: string,\n ) {\n super(`${filePath}: unknown asset kind \"${kind}\" in frontmatter \\`type:\\``);\n this.name = \"ManifestKindError\";\n }\n}\n\n/** Convert a {@link ManifestKindError} into the `unknown_asset_kind` error diagnostic. */\nexport function manifestKindDiagnostic(err: ManifestKindError): Diagnostic {\n return {\n code: \"unknown_asset_kind\",\n severity: \"error\",\n message: `${err.filePath}: asset kind \"${err.kind}\" is not registered`,\n path: err.filePath,\n };\n}\n\n/**\n * Parse a `SKILL.md` file into a `CatalogEntry`.\n * The `kind` field defaults to `\"skill\"` but can be overridden via the `type:`\n * frontmatter key to any registered kind. Falls back to the parent directory name\n * when `name:` is absent.\n *\n * Async since #454 — the file may live on the FUSE workspace mount.\n *\n * @param filePath - Absolute path to the `SKILL.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @param knownKinds - Registered asset kinds (`registry.getAllKinds()`); a `type:` outside it throws\n * @returns Populated `CatalogEntry` with kind, name, description, version, and requires\n * @throws {ManifestKindError} when `type:` names an unregistered kind\n * @docLink packages/core/concepts#from-skill-md\n */\nexport async function fromSkillMd(\n filePath: string,\n repoName: string,\n knownKinds: ReadonlySet<string>,\n): Promise<CatalogEntry> {\n return fromSkillMdContent(await readManifestFile(filePath), repoName, filePath, knownKinds);\n}\n\n/** Pure {@link fromSkillMd} core over already-read content (no I/O). */\nfunction fromSkillMdContent(\n content: string,\n repoName: string,\n filePath: string,\n knownKinds: ReadonlySet<string>,\n): CatalogEntry {\n const { data: meta } = parseFrontmatter(content);\n // An absent `type:` is the SKILL.md default; an explicit one must be registered.\n const kind = meta.type === undefined ? \"skill\" : String(meta.type);\n if (meta.type !== undefined && !knownKinds.has(kind)) throw new ManifestKindError(filePath, kind);\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind,\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse an `AGENT.md` file into a `CatalogEntry` with `kind: \"agent\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * Async since #454 — the file may live on the FUSE workspace mount.\n *\n * @param filePath - Absolute path to the `AGENT.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"agent\"`\n * @docLink packages/core/concepts#from-agent-md\n */\nexport async function fromAgentMd(filePath: string, repoName: string): Promise<CatalogEntry> {\n return fromAgentMdContent(await readManifestFile(filePath), repoName, filePath);\n}\n\n/** Pure {@link fromAgentMd} core over already-read content (no I/O). */\nfunction fromAgentMdContent(content: string, repoName: string, filePath: string): CatalogEntry {\n const { data: meta } = parseFrontmatter(content);\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"agent\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse an `agent.yaml` file into a `CatalogEntry` with `kind: \"agent\"`.\n * `requires` lists the catalog refs of `composes[]` (local paths and `library://`\n * instances excluded). The deprecated 0.1 fields (`skills`, `requires`, `persona`,\n * …) are not read; `skaile validate` reports them.\n *\n * Async since #454 — the file may live on the FUSE workspace mount.\n *\n * @param filePath - Absolute path to the `agent.yaml` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"agent\"` and full dependency graph\n * @docLink packages/core/concepts#from-agent-yaml\n */\nexport async function fromAgentYaml(filePath: string, repoName: string): Promise<CatalogEntry> {\n return fromAgentYamlContent(await readManifestFileOrEmpty(filePath), repoName, filePath);\n}\n\n/** Pure {@link fromAgentYaml} core over already-read content (no I/O). */\nfunction fromAgentYamlContent(content: string, repoName: string, filePath: string): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(content) as Record<string, unknown>) ?? {};\n } catch {}\n\n const requires: Dependency[] = [];\n collectComposeRefs(meta.composes, requires);\n\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"agent\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires,\n dependencies: [],\n };\n}\n\n/**\n * Parse a `*.prompt.md` file into a `CatalogEntry` with `kind: \"prompt\"`.\n * The name defaults to the filename stem (without the `.prompt.md` suffix)\n * when no `name:` frontmatter key is present.\n *\n * Async since #454 — the file may live on the FUSE workspace mount.\n *\n * @param filePath - Absolute path to the `.prompt.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"prompt\"`\n * @docLink packages/core/concepts#from-prompt-md\n */\nexport async function fromPromptMd(filePath: string, repoName: string): Promise<CatalogEntry> {\n return fromPromptMdContent(await readManifestFile(filePath), repoName, filePath);\n}\n\n/** Pure {@link fromPromptMd} core over already-read content (no I/O). */\nfunction fromPromptMdContent(content: string, repoName: string, filePath: string): CatalogEntry {\n const { data: meta } = parseFrontmatter(content);\n const name = String(meta.name ?? basename(filePath).replace(/\\.prompt\\.md$/, \"\"));\n return {\n name,\n kind: \"prompt\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse a `*.flow.yaml` or `*.flow.json` file into a `CatalogEntry` with `kind: \"flow\"`.\n * The name resolves from `name:` or `id:` frontmatter, falling back to the filename stem.\n *\n * Async since #454 — the file may live on the FUSE workspace mount.\n *\n * @param filePath - Absolute path to the flow definition file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"flow\"`\n * @docLink packages/core/concepts#from-flow-yaml\n */\nexport async function fromFlowYaml(filePath: string, repoName: string): Promise<CatalogEntry> {\n return fromFlowYamlContent(await readManifestFileOrEmpty(filePath), repoName, filePath);\n}\n\n/** Pure {@link fromFlowYaml} core over already-read content (no I/O). */\nfunction fromFlowYamlContent(content: string, repoName: string, filePath: string): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(content) as Record<string, unknown>) ?? {};\n } catch {}\n\n const stem = basename(filePath)\n .replace(/\\.flow\\.yaml$/, \"\")\n .replace(/\\.flow\\.json$/, \"\");\n return {\n name: String(meta.name ?? meta.id ?? stem),\n kind: \"flow\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Split a preset's `items[]` into the asset refs a dependency expansion installs\n * and the instance items it cannot: `library://` instance refs, `#item` cross\n * references, items that prompt for `placeholders`, and `connector:`/`mcp:` items\n * with an `id` (those become `skaile.yaml` declarations through\n * `skaile preset apply`). Refs are kept verbatim — publisher/pin qualifiers\n * preserved, nested `preset:` refs included.\n *\n * @param items - The raw `items` value of a parsed preset manifest.\n * @returns Deduped asset refs plus the count of skipped instance items.\n * @docLink packages/core/concepts#preset-item-refs\n */\nexport function presetItemRefs(items: unknown): { refs: string[]; skipped: number } {\n const refs = new Set<string>();\n let skipped = 0;\n if (!Array.isArray(items)) return { refs: [], skipped };\n for (const raw of items) {\n if (raw === null || typeof raw !== \"object\") continue;\n const item = raw as Record<string, unknown>;\n const ref = typeof item.ref === \"string\" ? item.ref.trim() : \"\";\n if (!ref) continue;\n const hasPlaceholders = Array.isArray(item.placeholders) && item.placeholders.length > 0;\n const declaresInstance =\n typeof item.id === \"string\" && (ref.startsWith(\"connector:\") || ref.startsWith(\"mcp:\"));\n if (\n ref.startsWith(\"library://\") ||\n ref.startsWith(\"#\") ||\n hasPlaceholders ||\n declaresInstance\n ) {\n skipped++;\n continue;\n }\n refs.add(ref);\n }\n return { refs: [...refs], skipped };\n}\n\n/**\n * Parse a `*.preset.yaml` file into a `CatalogEntry` with `kind: \"preset\"`.\n * `dependencies` carries the asset refs of its items (see {@link presetItemRefs}).\n *\n * Async since #454 — the file may live on the FUSE workspace mount.\n *\n * @param filePath - Absolute path to the preset YAML file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"preset\"`\n * @docLink packages/core/concepts#from-preset-yaml\n */\nexport async function fromPresetYaml(filePath: string, repoName: string): Promise<CatalogEntry> {\n return fromPresetYamlContent(await readManifestFileOrEmpty(filePath), repoName, filePath);\n}\n\n/** Pure {@link fromPresetYaml} core over already-read content (no I/O). */\nfunction fromPresetYamlContent(content: string, repoName: string, filePath: string): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(content) as Record<string, unknown>) ?? {};\n } catch {}\n\n const { refs, skipped } = presetItemRefs(meta.items);\n return {\n name: String(meta.name ?? basename(filePath).replace(/\\.preset\\.yaml$/, \"\")),\n kind: \"preset\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires: [],\n dependencies: refs,\n ...(skipped > 0 ? { skippedItems: skipped } : {}),\n };\n}\n\n/**\n * Extract an asset's raw transitive dependency ref strings from its manifest\n * file, kept verbatim (publisher/pin qualifiers preserved, comments dropped by\n * the parser): a `*.preset.yaml`'s asset items (see {@link presetItemRefs}) or the\n * union of a `*.flow.{yaml,json}`'s top-level `requires` / `dependencies`. Unlike\n * {@link parseRequires}, refs are returned as-is — the resolver needs the full\n * `kind:@<publisher>/name[#pin]` form, not a publisher-stripped {@link Dependency}.\n *\n * Async since #454 — the file may live on the FUSE workspace mount.\n *\n * @param filePath - Absolute path to a `.preset.yaml` or `.flow.{yaml,json}`.\n * @returns Deduped `refs` (`[]` on parse failure or no deps) and the count of\n * preset instance items that are not expanded.\n * @docLink packages/core/concepts#asset-dep-refs\n */\nexport async function assetDepRefs(filePath: string): Promise<{ refs: string[]; skipped: number }> {\n return assetDepRefsFromContent(await readManifestFileOrEmpty(filePath), filePath);\n}\n\n/** Pure {@link assetDepRefs} core over already-read content (no I/O). */\nfunction assetDepRefsFromContent(\n content: string,\n filePath: string,\n): { refs: string[]; skipped: number } {\n // YAML is a JSON superset, so `parse` reads `.flow.json` too.\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(content) as Record<string, unknown>) ?? {};\n } catch {\n return { refs: [], skipped: 0 };\n }\n if (filePath.endsWith(\".preset.yaml\")) return presetItemRefs(meta.items);\n const out: string[] = [];\n const collect = (v: unknown) => {\n if (Array.isArray(v))\n for (const x of v) if (typeof x === \"string\" && x.trim()) out.push(x.trim());\n };\n collect(meta.requires);\n collect((meta.metadata as Record<string, unknown> | undefined)?.requires);\n collect(meta.dependencies);\n return { refs: [...new Set(out)], skipped: 0 };\n}\n\n/**\n * Parse a `CONTRACT.md` file into a `CatalogEntry` with `kind: \"contract\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * Async since #454 — the file may live on the FUSE workspace mount.\n *\n * @param filePath - Absolute path to the `CONTRACT.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"contract\"`\n * @docLink packages/core/concepts#from-contract-md\n */\nexport async function fromContractMd(filePath: string, repoName: string): Promise<CatalogEntry> {\n return fromContractMdContent(await readManifestFile(filePath), repoName, filePath);\n}\n\n/** Pure {@link fromContractMd} core over already-read content (no I/O). */\nfunction fromContractMdContent(content: string, repoName: string, filePath: string): CatalogEntry {\n const { data: meta } = parseFrontmatter(content);\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"contract\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse an `MCP.md` file into a `CatalogEntry` with `kind: \"mcp-server\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * Frontmatter fields (catalog identity):\n * - `name` — server name (default: parent dir name)\n * - `description` — short description\n * - `version` — semver\n * - `keywords` — array of discovery tags\n *\n * Frontmatter fields (runtime defaults, stored in `metadata`):\n * - `transport` — \"stdio\" | \"sse\" | \"http\" (default: \"stdio\")\n * - `command` — command to execute (stdio)\n * - `args` — command arguments (stdio)\n * - `env` — environment variables (stdio)\n * - `url` — server URL (sse/http)\n * - `headers` — HTTP headers (sse/http)\n *\n * When `mcp:name` appears in `skaile.yaml` `dependencies`, the runner reads\n * these defaults from `metadata` to build a `McpServerDeclaration` without\n * requiring verbose inline config.\n *\n * Async since #454 — the file may live on the FUSE workspace mount.\n *\n * @param filePath - Absolute path to the `MCP.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"mcp-server\"`\n * @docLink packages/core/concepts#from-mcp-server-md\n */\nexport async function fromMcpServerMd(filePath: string, repoName: string): Promise<CatalogEntry> {\n return fromMcpServerMdContent(await readManifestFile(filePath), repoName, filePath);\n}\n\n/**\n * Parse pre-read MCP.md content into a `CatalogEntry`.\n * Callers that already hold the file content (e.g. to avoid a second read) use\n * this directly; `fromMcpServerMd` is a thin wrapper that reads then delegates here.\n *\n * @param content - UTF-8 content of the `MCP.md` file\n * @param repoName - Repository name used as the `publisher` field of the entry\n * @param filePath - Absolute path (used as `source` and for name fallback)\n * @returns Populated `CatalogEntry` with kind `\"mcp-server\"`\n */\nexport function fromMcpServerMdContent(\n content: string,\n repoName: string,\n filePath: string,\n): CatalogEntry {\n const { data: meta } = parseFrontmatter(content);\n\n // Extract runtime defaults into metadata\n const metadata: Record<string, unknown> = {};\n if (meta.transport) metadata.transport = String(meta.transport);\n if (meta.command) metadata.command = String(meta.command);\n if (Array.isArray(meta.args)) metadata.args = meta.args.map(String);\n if (meta.env && typeof meta.env === \"object\" && !Array.isArray(meta.env)) {\n metadata.env = meta.env as Record<string, string>;\n }\n if (meta.url) metadata.url = String(meta.url);\n if (typeof meta.ca === \"string\") metadata.ca = meta.ca;\n if (meta.headers && typeof meta.headers === \"object\" && !Array.isArray(meta.headers)) {\n metadata.headers = meta.headers as Record<string, string>;\n }\n if (meta.recipe && typeof meta.recipe === \"object\" && !Array.isArray(meta.recipe)) {\n metadata.recipe = meta.recipe;\n }\n\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"mcp-server\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n };\n}\n\n/**\n * Parse a `knowledge.yaml` file into a `CatalogEntry` with `kind: \"knowledge\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * Async since #454 — the file may live on the FUSE workspace mount.\n *\n * @param filePath - Absolute path to the `knowledge.yaml` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"knowledge\"`\n * @docLink packages/core/concepts#from-knowledge-yaml\n */\nexport async function fromKnowledgeYaml(filePath: string, repoName: string): Promise<CatalogEntry> {\n return fromKnowledgeYamlContent(await readManifestFileOrEmpty(filePath), repoName, filePath);\n}\n\n/** Pure {@link fromKnowledgeYaml} core over already-read content (no I/O). */\nfunction fromKnowledgeYamlContent(\n content: string,\n repoName: string,\n filePath: string,\n): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(content) as Record<string, unknown>) ?? {};\n } catch {}\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"knowledge\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse a `CONNECTOR.md` file into a `CatalogEntry` with `kind: \"connector\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * Frontmatter fields (catalog identity):\n * - `name` — connector name (default: parent dir name)\n * - `description` — short description\n * - `version` — semver\n *\n * Frontmatter fields (runtime defaults, stored in `metadata`):\n * - `entry` — adapter entry point (default: \"./adapter.ts\")\n * - `npm_deps` — npm dependencies required by the adapter\n * - `fields` — configuration fields the adapter expects\n * - `health_check` — whether to run a health check on connect\n *\n * The markdown body (below the frontmatter) is stored in `metadata.body`\n * so the runner can inject the connector's skill description into the\n * system prompt when `expose_as_skill` is enabled.\n *\n * Async since #454 — the file may live on the FUSE workspace mount.\n *\n * @param filePath - Absolute path to the `CONNECTOR.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"connector\"`\n * @docLink packages/core/concepts#from-connector-md\n */\nexport async function fromConnectorMd(filePath: string, repoName: string): Promise<CatalogEntry> {\n return fromConnectorMdContent(await readManifestFile(filePath), repoName, filePath);\n}\n\n/** Pure {@link fromConnectorMd} core over already-read content (no I/O). */\nfunction fromConnectorMdContent(content: string, repoName: string, filePath: string): CatalogEntry {\n const { data: meta, body } = parseFrontmatter(content);\n const name = String(meta.name ?? basename(dirname(filePath)));\n return {\n name,\n kind: \"connector\" as AssetKind,\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n metadata: {\n entry: meta.entry ?? \"./adapter.ts\",\n npm_deps: meta.npm_deps ?? {},\n fields: meta.fields ?? [],\n health_check: meta.health_check ?? null,\n body,\n },\n };\n}\n\n// ── Recursive walker ──────────────────────────────────────────────────────────\n\ninterface WalkEntry {\n path: string;\n name: string;\n}\n\n/** Default maximum directory nesting the walk descends into. */\nexport const DEFAULT_WALK_MAX_DEPTH = 32;\n\n/** Default maximum number of directory entries a single walk may examine. */\nexport const DEFAULT_WALK_MAX_ENTRIES = 50_000;\n\n/** Default wall-clock budget for one whole walk / scan pass, in milliseconds. */\nexport const DEFAULT_WALK_BUDGET_MS = 60_000;\n\n/** Env override for {@link DEFAULT_WALK_MAX_DEPTH}. */\nexport const WALK_MAX_DEPTH_ENV_VAR = \"SKAILE_SCAN_MAX_DEPTH\";\n\n/** Env override for {@link DEFAULT_WALK_MAX_ENTRIES}. */\nexport const WALK_MAX_ENTRIES_ENV_VAR = \"SKAILE_SCAN_MAX_ENTRIES\";\n\n/** Env override for {@link DEFAULT_WALK_BUDGET_MS}. */\nexport const WALK_BUDGET_MS_ENV_VAR = \"SKAILE_SCAN_DEADLINE_MS\";\n\n/** Read a positive-integer env override, falling back when absent or unusable. */\nfunction envInt(name: string, fallback: number): number {\n const raw = process.env[name];\n if (raw === undefined) return fallback;\n const parsed = Number.parseInt(raw, 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n}\n\n/**\n * Why a walk stopped early. Every one of these means the returned entries are a\n * **partial** view of the tree — never present a truncated walk as complete.\n *\n * @docLink packages/core/concepts#walk-dir\n */\nexport interface WalkTruncation {\n reason: \"depth\" | \"entries\" | \"budget\" | \"cycle\" | \"unreadable\";\n /** Directory (or symlink) at which the bound was hit. */\n path: string;\n /** The bound that was hit, when the reason has a numeric limit. */\n limit?: number;\n}\n\n/**\n * Bounds for {@link walkDir} / {@link scanDirectory}.\n *\n * @docLink packages/core/concepts#walk-dir\n */\nexport interface WalkOptions {\n /** Maximum nesting depth below the root. Default {@link DEFAULT_WALK_MAX_DEPTH}. */\n maxDepth?: number;\n /** Maximum directory entries examined across the whole walk. Default {@link DEFAULT_WALK_MAX_ENTRIES}. */\n maxEntries?: number;\n /**\n * Wall-clock budget for the whole walk. Default {@link DEFAULT_WALK_BUDGET_MS}.\n * The check is inclusive, so `0` yields no entries at all.\n */\n budgetMs?: number;\n /** Per-`opendir`/`stat`/`readFile` deadline. Default {@link fsDeadlineMs}. */\n opTimeoutMs?: number;\n /**\n * Called once per distinct truncation reason. Defaults to a `warn` on the\n * core logger — override to route the signal somewhere the caller can act on.\n */\n onTruncate?: (info: WalkTruncation) => void;\n}\n\n/**\n * Options for {@link scanDirectory}: the walk bounds plus the registered kind set\n * (`new Set(registry.getAllKinds())`) that typed frontmatter is checked against.\n */\nexport interface ScanOptions extends WalkOptions {\n /** Registered asset kinds; a `SKILL.md` `type:` outside it is reported, not catalogued. */\n knownKinds: ReadonlySet<string>;\n /** Sink for scan diagnostics (`unknown_asset_kind`). Defaults to a `warn` on the core logger. */\n onDiagnostic?: (diagnostic: Diagnostic) => void;\n /**\n * Return every asset found instead of one per `kind:name`. The default keeps the\n * alphabetically later source path, which hides a second directory holding the\n * same asset; a caller that must report such duplicates (`library index`) sets this.\n */\n keepDuplicates?: boolean;\n}\n\n/** Mutable bookkeeping threaded through one walk. */\ninterface WalkState {\n maxDepth: number;\n maxEntries: number;\n opTimeoutMs: number | undefined;\n deadlineAt: number;\n examined: number;\n /**\n * `dev:ino` of the directories on the **current path from the root** — an\n * ancestor stack, not an ever-visited set. Re-entering an ancestor is a cycle;\n * re-reaching a directory off the current path is a diamond, and must be walked.\n */\n ancestors: Set<string>;\n reported: Set<WalkTruncation[\"reason\"]>;\n onTruncate: (info: WalkTruncation) => void;\n}\n\nlet walkLogger: ReturnType<typeof createLogger> | undefined;\n\n/** Default truncation sink — a structured warning naming the bound that was hit. */\nfunction warnTruncation(info: WalkTruncation): void {\n walkLogger ??= createLogger({ kind: \"runner\", subkind: \"asset-scan\" });\n walkLogger.warn(`asset scan truncated (${info.reason}) — results are incomplete`, {\n ...info,\n });\n}\n\n/** Default diagnostic sink for {@link scanDirectory}. */\nfunction warnDiagnostic(d: Diagnostic): void {\n walkLogger ??= createLogger({ kind: \"runner\", subkind: \"asset-scan\" });\n walkLogger.warn(d.message, { code: d.code, path: d.path });\n}\n\n/** Record a truncation once per reason so a wide tree does not spam the log. */\nfunction truncate(state: WalkState, info: WalkTruncation): void {\n if (state.reported.has(info.reason)) return;\n state.reported.add(info.reason);\n state.onTruncate(info);\n}\n\n/**\n * Stable identity (`dev:ino`) of the directory `path` resolves to, or `null`\n * when it cannot be stat'ed within the deadline. Used to terminate symlink\n * cycles — the pre-#454 walker recursed forever on `a/link -> a`.\n */\nasync function dirIdentity(path: string, timeoutMs: number | undefined): Promise<string | null> {\n const st = await tryWithFsDeadline(`stat ${path}`, () => stat(path), null, timeoutMs);\n return st ? `${st.dev}:${st.ino}` : null;\n}\n\n/**\n * Read one directory's entries under a deadline, capped at the walk's remaining\n * entry budget. Uses `opendir` rather than `readdir` so a pathological directory\n * streams instead of materialising in full; entries are collected and sorted\n * because the `scanDirectory` dedup rule (\"alphabetically later source wins\")\n * depends on a deterministic per-level order.\n */\nasync function readDirEntries(\n dir: string,\n state: WalkState,\n): Promise<{ entries: Dirent[]; capped: boolean } | null> {\n const remaining = state.maxEntries - state.examined;\n if (remaining <= 0) return { entries: [], capped: true };\n try {\n return await withFsDeadline(\n `opendir ${dir}`,\n async () => {\n const handle = await opendir(dir);\n const entries: Dirent[] = [];\n let capped = false;\n for await (const e of handle) {\n // Stop *before* keeping the over-budget entry, so `capped` means \"an\n // entry was actually dropped\". Breaking after the push instead marked\n // a directory of exactly `remaining` entries as truncated — and since\n // `truncate()` reports once per reason for the whole walk, that\n // spurious first report swallowed a later genuine one.\n if (entries.length >= remaining) {\n capped = true;\n break;\n }\n entries.push(e);\n }\n entries.sort((a, b) => (a.name < b.name ? -1 : 1));\n return { entries, capped };\n },\n state.opTimeoutMs,\n );\n } catch {\n // Unreadable (permissions, vanished mid-walk) or the mount missed its\n // deadline. Either way this subtree contributes nothing; keep walking.\n truncate(state, { reason: \"unreadable\", path: dir });\n return null;\n }\n}\n\n/**\n * Recursively yield every file entry under `dir`, sorted alphabetically at each\n * level. Skips `.git` and `node_modules` directories and follows symlinks\n * (resolving to the stat target). `node_modules` is excluded because Bun's\n * `node_modules/.bun/...` layout contains symlink farms that form cycles when\n * packages reference each other transitively.\n *\n * **Async and bounded since #454.** A repo root can resolve onto the rclone FUSE\n * mount, where the previous synchronous `readdirSync`/`statSync` walk parked the\n * whole event loop. Four bounds now hold, and hitting any of them reports a\n * {@link WalkTruncation} — a truncated walk is never presented as a complete one:\n *\n * - **depth** ({@link WalkOptions.maxDepth}) — also the backstop for a cycle no\n * inode check can see, e.g. a bind mount of the root inside itself.\n * - **entry count** ({@link WalkOptions.maxEntries}) — total directory entries\n * examined, so an enormous tree cannot run unbounded.\n * - **wall-clock budget** ({@link WalkOptions.budgetMs}) — a wedged mount that\n * times out one operation at a time cannot add up to an unbounded scan.\n * - **ancestor inodes** — the `dev:ino` of every directory on the path from the\n * root is held while its subtree is walked, so `a/link -> a` terminates\n * instead of recursing forever. Two sibling symlinks onto one shared\n * directory are a diamond, not a cycle: both are walked, at the price of\n * visiting the shared subtree twice — bounded by the entry and time budgets.\n *\n * @param dir - Absolute path to the directory to walk\n * @param options - Bounds and truncation sink; see {@link WalkOptions}\n * @docLink packages/core/concepts#walk-dir\n */\nexport async function* walkDir(dir: string, options: WalkOptions = {}): AsyncGenerator<WalkEntry> {\n const state: WalkState = {\n maxDepth: options.maxDepth ?? envInt(WALK_MAX_DEPTH_ENV_VAR, DEFAULT_WALK_MAX_DEPTH),\n maxEntries: options.maxEntries ?? envInt(WALK_MAX_ENTRIES_ENV_VAR, DEFAULT_WALK_MAX_ENTRIES),\n opTimeoutMs: options.opTimeoutMs,\n deadlineAt:\n Date.now() + (options.budgetMs ?? envInt(WALK_BUDGET_MS_ENV_VAR, DEFAULT_WALK_BUDGET_MS)),\n examined: 0,\n ancestors: new Set<string>(),\n reported: new Set<WalkTruncation[\"reason\"]>(),\n onTruncate: options.onTruncate ?? warnTruncation,\n };\n // The root is an ancestor of everything, so it is seeded here and never\n // popped — a self-referential `root/link -> root` is caught on first descent.\n const rootId = await dirIdentity(dir, state.opTimeoutMs);\n if (rootId) state.ancestors.add(rootId);\n yield* walkFrom(dir, 0, state);\n}\n\nasync function* walkFrom(dir: string, depth: number, state: WalkState): AsyncGenerator<WalkEntry> {\n if (depth > state.maxDepth) {\n truncate(state, { reason: \"depth\", path: dir, limit: state.maxDepth });\n return;\n }\n if (Date.now() >= state.deadlineAt) {\n truncate(state, { reason: \"budget\", path: dir });\n return;\n }\n\n const read = await readDirEntries(dir, state);\n if (!read) return;\n if (read.capped) truncate(state, { reason: \"entries\", path: dir, limit: state.maxEntries });\n\n for (const e of read.entries) {\n if (state.examined >= state.maxEntries) {\n truncate(state, { reason: \"entries\", path: dir, limit: state.maxEntries });\n return;\n }\n if (Date.now() >= state.deadlineAt) {\n truncate(state, { reason: \"budget\", path: dir });\n return;\n }\n state.examined++;\n const full = join(dir, e.name);\n\n if (e.isSymbolicLink()) {\n // A symlink is the only way a cycle can enter this walk, so identity is\n // resolved here and nowhere else — one extra stat per link, none per\n // ordinary directory.\n const st = await tryWithFsDeadline(`stat ${full}`, () => stat(full), null, state.opTimeoutMs);\n if (!st) continue;\n if (st.isDirectory()) {\n if (e.name === \".git\" || e.name === \"node_modules\") continue;\n const id = `${st.dev}:${st.ino}`;\n // Only an *ancestor* is a cycle. A target already walked elsewhere in\n // the tree is a diamond (`a/link -> shared`, `b/link -> shared`) and\n // dropping it would silently lose that subtree from the scan.\n if (state.ancestors.has(id)) {\n truncate(state, { reason: \"cycle\", path: full });\n continue;\n }\n state.ancestors.add(id);\n try {\n yield* walkFrom(full, depth + 1, state);\n } finally {\n // finally, not a trailing delete: an early `return` from the bounds\n // checks — or an abandoned consumer — would otherwise leave the\n // ancestor stack holding a directory the walk has already left.\n state.ancestors.delete(id);\n }\n } else {\n yield { path: full, name: e.name };\n }\n } else if (e.isDirectory()) {\n if (e.name !== \".git\" && e.name !== \"node_modules\") yield* walkFrom(full, depth + 1, state);\n } else if (e.isFile()) {\n yield { path: full, name: e.name };\n }\n }\n}\n\n// ── Public scanner ────────────────────────────────────────────────────────────\n\n/**\n * Coerce a scanned entry's `name` to a canonical asset name in place. When the\n * raw name is already canonical this is a no-op; otherwise the original is stashed\n * on `metadata.displayName` (only when not already set) so callers keep the pretty\n * label for display while identity uses the slug. A name that slugifies to empty\n * is left untouched — `parseAssetRef` will reject it downstream with its full hint.\n */\nfunction normalizeEntryName(e: CatalogEntry): void {\n if (isValidAssetName(e.name)) return;\n let slug: string;\n try {\n slug = slugifyAssetName(e.name);\n } catch {\n return;\n }\n const original = e.name;\n e.name = slug;\n if (e.metadata?.displayName === undefined) {\n e.metadata = { ...e.metadata, displayName: original };\n }\n}\n\n/**\n * Build a `CatalogEntry` from an already-read manifest, dispatching on filename.\n * Returns `null` when the filename is not a recognized manifest.\n */\nfunction entryFromManifest(\n name: string,\n content: string,\n filePath: string,\n repoName: string,\n knownKinds: ReadonlySet<string>,\n): CatalogEntry | null {\n if (name === \"SKILL.md\") return fromSkillMdContent(content, repoName, filePath, knownKinds);\n if (name === \"AGENT.md\") return fromAgentMdContent(content, repoName, filePath);\n if (name === \"agent.yaml\") return fromAgentYamlContent(content, repoName, filePath);\n if (name === \"CONTRACT.md\") return fromContractMdContent(content, repoName, filePath);\n if (name === \"MCP.md\") return fromMcpServerMdContent(content, repoName, filePath);\n if (name === \"CONNECTOR.md\") return fromConnectorMdContent(content, repoName, filePath);\n if (name === \"knowledge.yaml\") return fromKnowledgeYamlContent(content, repoName, filePath);\n if (name.endsWith(\".prompt.md\")) return fromPromptMdContent(content, repoName, filePath);\n if (name.endsWith(\".preset.yaml\")) return fromPresetYamlContent(content, repoName, filePath);\n if (name.endsWith(\".flow.yaml\") || name.endsWith(\".flow.json\"))\n return fromFlowYamlContent(content, repoName, filePath);\n return null;\n}\n\n/** Filenames {@link scanDirectory} recognises as asset manifests. */\nfunction isManifestName(name: string): boolean {\n return (\n name === \"SKILL.md\" ||\n name === \"AGENT.md\" ||\n name === \"agent.yaml\" ||\n name === \"CONTRACT.md\" ||\n name === \"MCP.md\" ||\n name === \"CONNECTOR.md\" ||\n name === \"knowledge.yaml\" ||\n name.endsWith(\".prompt.md\") ||\n name.endsWith(\".preset.yaml\") ||\n name.endsWith(\".flow.yaml\") ||\n name.endsWith(\".flow.json\")\n );\n}\n\n/** Per-asset values a `skaile.manifest.yaml` `assets[]` entry overrides on the scanned entry. */\ninterface ManifestAssetOverride {\n publisher?: string;\n dependencies: string[];\n}\n\n/**\n * Per-asset overrides declared in `<root>/skaile.manifest.yaml` `assets[]` (`publisher`,\n * `dependencies`), keyed `kind:name`. Empty when the manifest is absent, unreadable within\n * the deadline, or not valid YAML — a scan never fails on it.\n */\nasync function readManifestAssetOverrides(\n root: string,\n opTimeoutMs: number,\n): Promise<Record<string, ManifestAssetOverride>> {\n const out: Record<string, ManifestAssetOverride> = {};\n const file = join(root, \"skaile.manifest.yaml\");\n const content = await tryWithFsDeadline(\n `readFile ${file}`,\n () => readFile(file, \"utf8\"),\n null,\n opTimeoutMs,\n );\n if (content === null) return out;\n let doc: unknown;\n try {\n doc = parse(content);\n } catch {\n return out;\n }\n const assets = (doc as { assets?: unknown } | null)?.assets;\n if (!Array.isArray(assets)) return out;\n for (const a of assets) {\n const { kind, name, publisher, dependencies } = (a ?? {}) as Record<string, unknown>;\n if (typeof kind !== \"string\" || typeof name !== \"string\") continue;\n const override: ManifestAssetOverride = {\n dependencies: Array.isArray(dependencies)\n ? dependencies.filter((d): d is string => typeof d === \"string\" && d.trim().length > 0)\n : [],\n };\n const bare = typeof publisher === \"string\" ? publisher.trim().replace(/^@/, \"\") : \"\";\n if (bare) override.publisher = bare;\n if (override.publisher || override.dependencies.length > 0) out[`${kind}:${name}`] = override;\n }\n return out;\n}\n\n/**\n * Fold a manifest entry's `dependencies` into `entry.requires`: the manifest field is the\n * author-declared requirement list of the entry (same meaning as `requires`), so every\n * consumer of the scanned entry (`add`, `install`, `info`, `check`, `doctor`) sees it.\n * An already-declared requirement (same kind, publisher and name) is not repeated.\n */\nfunction mergeManifestDependencies(entry: CatalogEntry, dependencies: readonly string[]): void {\n const idOf = (d: Dependency) => `${d.kind}:@${d.publisher ?? \"\"}/${d.name}`;\n const seen = new Set(entry.requires.map(idOf));\n for (const raw of dependencies) {\n const dep = parseDep(raw);\n if (seen.has(idOf(dep))) continue;\n seen.add(idOf(dep));\n entry.requires.push(dep);\n }\n}\n\n/**\n * Walk `root` recursively and return a `CatalogEntry` for every recognized asset manifest found.\n *\n * Recognized filenames: `SKILL.md`, `AGENT.md`, `agent.yaml`, `CONTRACT.md`, `MCP.md`,\n * `CONNECTOR.md`, `knowledge.yaml`, `*.prompt.md`, `*.preset.yaml`, `*.flow.yaml`, `*.flow.json`.\n *\n * When two entries share the same `kind:name` key, the one with the alphabetically\n * later source path wins (consistent with catalog precedence rules), unless\n * {@link ScanOptions.keepDuplicates} asks for every copy.\n *\n * **Async and bounded since #454.** `root` can resolve onto the rclone FUSE mount\n * (a `sources[].path` under `/skaile/workspace`), and the walk follows symlinks, so\n * even an off-mount root can descend into one. Every `opendir`/`stat`/`readFile`\n * is deadline-bounded and the walk is capped by depth, entry count, a wall-clock\n * budget, and an ancestor-inode set — see {@link walkDir}. Hitting any bound reports\n * a {@link WalkTruncation} through {@link WalkOptions.onTruncate} (a `warn` by\n * default); the returned array is then a **partial** scan, never a complete one.\n *\n * A manifest that cannot be read within its deadline is skipped rather than\n * failing the whole scan — one unreachable file must not cost the whole catalog.\n *\n * **Per-asset publisher.** When `root` holds a `skaile.manifest.yaml` whose `assets[]`\n * entry names a `publisher` for a scanned `kind`/`name`, that publisher replaces\n * `repoName` on the produced entry — the same identity the library index and\n * `library create --publisher` write, so `kind:@<publisher>/<name>` resolves.\n *\n * **Per-asset dependencies.** The same entry's `dependencies` (`kind:@<publisher>/name[#pin]`)\n * are appended to the produced entry's `requires`, next to the file's own `requires`.\n *\n * @param root - Absolute path to the directory tree to scan\n * @param repoName - Publisher attached to every produced entry without a per-asset override\n * @param options - Walk bounds and truncation sink; see {@link WalkOptions}\n * @returns Array of deduplicated `CatalogEntry` objects, one per manifest file\n * @docLink packages/core/concepts#scan-directory\n */\nexport async function scanDirectory(\n root: string,\n repoName: string,\n options: ScanOptions,\n): Promise<CatalogEntry[]> {\n const entries = new Map<string, CatalogEntry>();\n const copies: CatalogEntry[] = [];\n const onTruncate = options.onTruncate ?? warnTruncation;\n const reported = new Set<WalkTruncation[\"reason\"]>();\n const relay = (info: WalkTruncation) => {\n reported.add(info.reason);\n onTruncate(info);\n };\n const opTimeoutMs = options.opTimeoutMs ?? fsDeadlineMs();\n const manifestOverrides = await readManifestAssetOverrides(root, opTimeoutMs);\n\n function add(e: CatalogEntry): void {\n // Boundary normalization: a third-party source we don't control may name an\n // asset with a human-styled identity (\"Complex App\"). Slugify it to a\n // canonical name so the ref it produces parses, preserving the original on\n // `metadata.displayName` for display. No-op for already-canonical names.\n normalizeEntryName(e);\n const key = `${e.kind}:${e.name}`;\n const override = manifestOverrides[key];\n if (override?.publisher) e.publisher = override.publisher;\n if (override) mergeManifestDependencies(e, override.dependencies);\n if (options.keepDuplicates) {\n copies.push(e);\n return;\n }\n const existing = entries.get(key);\n if (!existing) {\n entries.set(key, e);\n return;\n }\n // Among duplicates, alphabetically later source path wins\n if (e.source > existing.source) entries.set(key, e);\n }\n\n for await (const { path: filePath, name } of walkDir(root, {\n ...options,\n opTimeoutMs,\n onTruncate: relay,\n })) {\n if (!isManifestName(name)) continue;\n const content = await tryWithFsDeadline(\n `readFile ${filePath}`,\n () => readFile(filePath, \"utf8\"),\n null,\n opTimeoutMs,\n );\n if (content === null) {\n // Unreadable or past its deadline — the catalog loses this asset, not the\n // whole scan. Reported once so a wedged mount is visible in the logs.\n if (!reported.has(\"unreadable\")) relay({ reason: \"unreadable\", path: filePath });\n continue;\n }\n try {\n const entry = entryFromManifest(name, content, filePath, repoName, options.knownKinds);\n if (entry) add(entry);\n } catch (err) {\n if (err instanceof ManifestKindError) {\n (options.onDiagnostic ?? warnDiagnostic)(manifestKindDiagnostic(err));\n }\n }\n }\n\n return options.keepDuplicates ? copies : [...entries.values()];\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { S, logErr, logWarn, logOk, logInfo } from './chunk-
|
|
2
|
-
import { globalSettingsPath, mapLegacyFields } from './chunk-
|
|
1
|
+
import { S, logErr, logWarn, logOk, logInfo } from './chunk-JZ5EHBPI.js';
|
|
2
|
+
import { globalSettingsPath, mapLegacyFields } from './chunk-36AFURKZ.js';
|
|
3
3
|
import { globalSkaileDir } from './chunk-L5VSIPQD.js';
|
|
4
|
+
import { SKAILE_MANIFEST_FILENAME } from './chunk-BTE2V4IW.js';
|
|
4
5
|
import { rmSync, existsSync, readFileSync, mkdirSync, writeFileSync, chmodSync } from 'fs';
|
|
5
6
|
import { randomBytes, createHash } from 'crypto';
|
|
6
7
|
import { join, dirname } from 'path';
|
|
@@ -275,6 +276,9 @@ function assetEntryRef(asset, manifest) {
|
|
|
275
276
|
const ns = assetNamespace(asset, manifest);
|
|
276
277
|
return ns ? refFor(asset.kind, ns, asset.name) : `${asset.kind}:${asset.name}`;
|
|
277
278
|
}
|
|
279
|
+
function manifestVersionMismatchMessage(entryRef, entryVersion, relFile, fileVersion) {
|
|
280
|
+
return `${SKAILE_MANIFEST_FILENAME} [assets] \u2014 ${entryRef}: manifest version ${entryVersion} differs from ${relFile} (${fileVersion}). The file is the source of truth: bump the version there, then run \`skaile library index <library>\`.`;
|
|
281
|
+
}
|
|
278
282
|
function manifestNamespaces(manifest, assetName) {
|
|
279
283
|
const out = /* @__PURE__ */ new Set();
|
|
280
284
|
for (const a of manifest.assets ?? []) {
|
|
@@ -383,6 +387,6 @@ async function publishToStore(opts) {
|
|
|
383
387
|
return { published };
|
|
384
388
|
}
|
|
385
389
|
|
|
386
|
-
export { assetEntryRef, assetNamespace, bareName, deviceLogin, formatNamespaceAvailability, getStoreConfig, getStoreIdentity, getStoreToken, hasStoredAuth, isStoreAuthenticated, loadStoreAuthConfig, logout, manifestNamespaces, plannedRefs, preflightNamespace, publishToStore, refFor, storeFetch };
|
|
387
|
-
//# sourceMappingURL=chunk-
|
|
388
|
-
//# sourceMappingURL=chunk-
|
|
390
|
+
export { assetEntryRef, assetNamespace, bareName, deviceLogin, formatNamespaceAvailability, getStoreConfig, getStoreIdentity, getStoreToken, hasStoredAuth, isStoreAuthenticated, loadStoreAuthConfig, logout, manifestNamespaces, manifestVersionMismatchMessage, plannedRefs, preflightNamespace, publishToStore, refFor, storeFetch };
|
|
391
|
+
//# sourceMappingURL=chunk-GXLQLPE5.js.map
|
|
392
|
+
//# sourceMappingURL=chunk-GXLQLPE5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../cli/src/store-auth.ts","../cli/src/store-client.ts","../cli/src/commands/publish-core.ts"],"names":["readFileSync"],"mappings":";;;;;;;;AAsBA,SAAS,YAAA,GAAwD;AAC/D,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,EAAE,CAAA,CAAE,SAAS,WAAW,CAAA;AACrD,EAAA,MAAM,SAAA,GAAY,WAAW,QAAQ,CAAA,CAAE,OAAO,QAAQ,CAAA,CAAE,OAAO,WAAW,CAAA;AAC1E,EAAA,OAAO,EAAE,UAAU,SAAA,EAAU;AAC/B;AAUA,SAAS,kBAAkB,GAAA,EAAqB;AAC9C,EAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC/B;AAQO,SAAS,mBAAA,GAAuC;AACrD,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,iBAAA,CAAkB,OAAA,CAAQ,GAAA,CAAI,uBAAuB,wBAAwB,CAAA;AAAA,IAC1F,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,kBAAA,IAAsB,cAAA;AAAA,IACzC,QAAA,EAAU,OAAA,CAAQ,GAAA,CAAI,uBAAA,IAA2B,kBAAA;AAAA,IACjD,UAAU,OAAA,CAAQ,GAAA,CAAI,oBAAoB,IAAA,CAAK,eAAA,IAAmB,WAAW;AAAA,GAC/E;AACF;AAGA,SAAS,KAAK,MAAA,EAAgE;AAC5E,EAAA,MAAM,OAAO,CAAA,EAAG,MAAA,CAAO,WAAW,CAAA,QAAA,EAAW,OAAO,KAAK,CAAA,wBAAA,CAAA;AACzD,EAAA,OAAO,EAAE,YAAY,CAAA,EAAG,IAAI,gBAAgB,KAAA,EAAO,CAAA,EAAG,IAAI,CAAA,MAAA,CAAA,EAAS;AACrE;AA2BA,IAAM,gBAAA,GAAmB,GAAA;AAUzB,SAAS,SAAS,MAAA,EAA4C;AAC5D,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,aAAa,MAAA,CAAO,QAAA,EAAU,OAAO,CAAC,CAAA;AAEhE,IAAA,IAAI,MAAA,IAAU,OAAO,MAAA,CAAO,YAAA,KAAiB,UAAU,OAAO,MAAA;AAC9D,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AASO,SAAS,gBAAA,CACd,MAAA,GAA0B,mBAAA,EAAoB,EACM;AACpD,EAAA,MAAM,IAAA,GAAO,SAAS,MAAM,CAAA;AAC5B,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,IAAI;AACF,IAAA,MAAM,UAAU,IAAA,CAAK,YAAA,CAAa,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAC9C,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,IAAA,CAAK,SAAS,WAAW,CAAA,CAAE,QAAA,CAAS,OAAO,CAAC,CAAA;AAC3E,IAAA,MAAM,WACJ,OAAO,IAAA,CAAK,kBAAA,KAAuB,QAAA,GAAW,KAAK,kBAAA,GAAqB,KAAA,CAAA;AAC1E,IAAA,MAAM,cAAc,OAAO,IAAA,CAAK,YAAA,KAAiB,QAAA,GAAW,KAAK,YAAA,GAAe,KAAA,CAAA;AAChF,IAAA,OAAO,QAAA,IAAY,WAAA,GAAc,EAAE,QAAA,EAAU,aAAY,GAAI,IAAA;AAAA,EAC/D,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,SAAS,SAAA,CAAU,QAAyB,IAAA,EAAwB;AAClE,EAAA,SAAA,CAAU,QAAQ,MAAA,CAAO,QAAQ,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AACvD,EAAA,aAAA,CAAc,MAAA,CAAO,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,IAAA,EAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AAC7E,EAAA,SAAA,CAAU,MAAA,CAAO,UAAU,GAAK,CAAA;AAClC;AAGO,SAAS,OAAO,MAAA,EAA+B;AACpD,EAAA,IAAI;AACF,IAAA,MAAA,CAAO,OAAO,QAAQ,CAAA;AAAA,EACxB,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAGO,SAAS,cAAc,MAAA,EAAkC;AAC9D,EAAA,OAAO,QAAA,CAAS,MAAM,CAAA,KAAM,IAAA;AAC9B;AAEA,SAAS,cAAc,KAAA,EAAkC;AACvD,EAAA,OAAO;AAAA,IACL,cAAc,KAAA,CAAM,YAAA;AAAA,IACpB,eAAe,KAAA,CAAM,aAAA;AAAA,IACrB,YAAY,IAAA,CAAK,GAAA,MAAS,KAAA,CAAM,UAAA,IAAc,OAAO,GAAA,GAAO;AAAA,GAC9D;AACF;AAEA,IAAM,YAAA,GAAe,CAAC,EAAA,KAA8B,IAAI,OAAA,CAAQ,CAAC,CAAA,KAAM,UAAA,CAAW,CAAA,EAAG,EAAE,CAAC,CAAA;AAExF,SAAS,aAAA,CAAc,KAAa,QAAA,EAAwB;AAC1D,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,IACb;AAAA;;AAAA,IAAA,EAA8B,GAAG;;AAAA,oBAAA,EAA2B,QAAQ;;AAAA;AAAA;AAAA,GACtE;AACF;AAMA,eAAsB,WAAA,CACpB,MAAA,EACA,IAAA,GAAiB,EAAC,EACG;AACrB,EAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,KAAA;AACpC,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,YAAA;AAC5B,EAAA,MAAM,QAAA,GAAW,KAAK,QAAA,IAAY,aAAA;AAClC,EAAA,MAAM,SAAA,GAAY,KAAK,MAAM,CAAA;AAC7B,EAAA,MAAM,OAAO,YAAA,EAAa;AAE1B,EAAA,MAAM,SAAA,GAAY,MAAM,SAAA,CAAU,SAAA,CAAU,UAAA,EAAY;AAAA,IACtD,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,IAC/D,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,MACxB,WAAW,MAAA,CAAO,QAAA;AAAA,MAClB,KAAA,EAAO,gBAAA;AAAA,MACP,gBAAgB,IAAA,CAAK,SAAA;AAAA,MACrB,qBAAA,EAAuB;AAAA,KACxB;AAAA,GACF,CAAA;AACD,EAAA,IAAI,CAAC,UAAU,EAAA,EAAI;AACjB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,wCAAwC,SAAA,CAAU,MAAM,MAAM,MAAM,SAAA,CAAU,MAAM,CAAA;AAAA,KACtF;AAAA,EACF;AACA,EAAA,MAAM,MAAA,GAAU,MAAM,SAAA,CAAU,IAAA,EAAK;AAErC,EAAA,QAAA,CAAS,MAAA,CAAO,yBAAA,IAA6B,MAAA,CAAO,gBAAA,EAAkB,OAAO,SAAS,CAAA;AAEtF,EAAA,MAAM,UAAA,GAAA,CAAc,MAAA,CAAO,QAAA,IAAY,CAAA,IAAK,GAAA;AAC5C,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,OAAO,UAAA,GAAa,GAAA;AAClD,EAAA,IAAI,MAAA,GAAS,UAAA;AAEb,EAAA,OAAO,IAAA,CAAK,GAAA,EAAI,GAAI,QAAA,EAAU;AAC5B,IAAA,MAAM,MAAM,MAAM,CAAA;AAClB,IAAA,MAAM,QAAA,GAAW,MAAM,SAAA,CAAU,SAAA,CAAU,KAAA,EAAO;AAAA,MAChD,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,MAC/D,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,QACxB,UAAA,EAAY,8CAAA;AAAA,QACZ,aAAa,MAAA,CAAO,WAAA;AAAA,QACpB,WAAW,MAAA,CAAO,QAAA;AAAA,QAClB,eAAe,IAAA,CAAK;AAAA,OACrB;AAAA,KACF,CAAA;AACD,IAAA,MAAM,KAAA,GAAS,MAAM,QAAA,CAAS,IAAA,EAAK;AACnC,IAAA,IAAI,SAAS,EAAA,EAAI;AACf,MAAA,MAAM,MAAA,GAAS,cAAc,KAAK,CAAA;AAClC,MAAA,SAAA,CAAU,QAAQ,MAAM,CAAA;AACxB,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,KAAA,CAAM,UAAU,uBAAA,EAAyB;AAC7C,IAAA,IAAI,KAAA,CAAM,UAAU,WAAA,EAAa;AAC/B,MAAA,MAAA,IAAU,GAAA;AACV,MAAA;AAAA,IACF;AACA,IAAA,MAAM,IAAI,MAAM,CAAA,gBAAA,EAAmB,KAAA,CAAM,qBAAqB,KAAA,CAAM,KAAA,IAAS,eAAe,CAAA,CAAE,CAAA;AAAA,EAChG;AACA,EAAA,MAAM,IAAI,MAAM,oCAAoC,CAAA;AACtD;AAGA,eAAe,OAAA,CACb,MAAA,EACA,YAAA,EACA,SAAA,EACqB;AACrB,EAAA,MAAM,MAAM,MAAM,SAAA,CAAU,IAAA,CAAK,MAAM,EAAE,KAAA,EAAO;AAAA,IAC9C,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,IAC/D,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,MACxB,UAAA,EAAY,eAAA;AAAA,MACZ,aAAA,EAAe,YAAA;AAAA,MACf,WAAW,MAAA,CAAO;AAAA,KACnB;AAAA,GACF,CAAA;AACD,EAAA,MAAM,KAAA,GAAS,MAAM,GAAA,CAAI,IAAA,EAAK;AAC9B,EAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,yBAAyB,KAAA,CAAM,iBAAA,IAAqB,KAAA,CAAM,KAAA,IAAS,IAAI,MAAM,CAAA;AAAA,KAC/E;AAAA,EACF;AACA,EAAA,MAAM,MAAA,GAAS,cAAc,KAAK,CAAA;AAClC,EAAA,SAAA,CAAU,QAAQ,MAAM,CAAA;AACxB,EAAA,OAAO,MAAA;AACT;AAMA,eAAsB,cAAA,CACpB,MAAA,EACA,IAAA,GAAiB,EAAC,EACD;AACjB,EAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,KAAA;AACpC,EAAA,MAAM,IAAA,GAAO,SAAS,MAAM,CAAA;AAC5B,EAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAC3E,EAAA,IAAI,KAAK,GAAA,EAAI,GAAI,IAAA,CAAK,UAAA,SAAmB,IAAA,CAAK,YAAA;AAC9C,EAAA,IAAI,CAAC,IAAA,CAAK,aAAA,EAAe,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAC3F,EAAA,IAAI;AACF,IAAA,OAAA,CAAQ,MAAM,OAAA,CAAQ,MAAA,EAAQ,IAAA,CAAK,aAAA,EAAe,SAAS,CAAA,EAAG,YAAA;AAAA,EAChE,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,MAAM,qEAAqE,CAAA;AAAA,EACvF;AACF;;;AC9PO,SAAS,cAAA,GAA8B;AAC5C,EAAA,MAAM,eAAe,kBAAA,EAAmB;AACxC,EAAA,IAAI,WAAgC,EAAC;AACrC,EAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,gBAAgB,IAAA,CAAK,KAAA,CAAMA,aAAa,YAAA,EAAc,OAAO,CAAC,CAAC,CAAA;AAAA,IAC5E,CAAA,CAAA,MAAQ;AACN,MAAA,QAAA,GAAW,EAAC;AAAA,IACd;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,QAAA,CAAS,QAAA,IAAY,OAAA,CAAQ,IAAI,gBAAA,IAAoB,0BAAA;AAAA,IAC1D,GAAA,EAAK;AAAA,GACP;AACF;AAOO,SAAS,cAAc,IAAA,EAAkC;AAC9D,EAAA,OAAO,cAAA,CAAe,mBAAA,EAAoB,EAAG,IAAI,CAAA;AACnD;AAaA,eAAsB,UAAA,CACpB,MAAA,EACA,IAAA,EACA,IAAA,EAOY;AACZ,EAAA,IAAI,GAAA,GAAM,CAAA,EAAG,MAAA,CAAO,GAAG,GAAG,IAAI,CAAA,CAAA;AAC9B,EAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,IAAA,MAAM,EAAA,GAAK,IAAI,eAAA,CAAgB,IAAA,CAAK,MAAM,CAAA;AAC1C,IAAA,GAAA,IAAO,IAAI,EAAE,CAAA,CAAA;AAAA,EACf;AAEA,EAAA,MAAM,OAAA,GAAkC;AAAA,IACtC,cAAA,EAAgB,kBAAA;AAAA,IAChB,MAAA,EAAQ,kBAAA;AAAA,IACR,GAAI,IAAA,EAAM,OAAA,IAAW;AAAC,GACxB;AACA,EAAA,IAAI,OAAO,GAAA,EAAK;AACd,IAAA,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,MAAA,CAAO,GAAG,CAAA,CAAA;AAAA,EAC9C;AAEA,EAAA,MAAM,SAAA,GAAyB;AAAA,IAC7B,MAAA,EAAQ,MAAM,MAAA,IAAU,KAAA;AAAA,IACxB;AAAA,GACF;AACA,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,SAAA,CAAU,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,OAAA,GAAU,WAAW,MAAM,UAAA,CAAW,OAAM,EAAG,IAAA,EAAM,aAAa,IAAK,CAAA;AAC7E,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,GAAG,SAAA,EAAW,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AACxE,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,OAAO,EAAE,KAAA,EAAO,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,IAAG,CAAE,CAAA;AAI3E,MAAA,MAAM,CAAA,GAAI,IAAA;AACV,MAAA,MAAM,IAAI,MAAM,CAAA,CAAE,OAAA,IAAW,EAAE,KAAA,IAAS,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,IAC1E;AACA,IAAA,OAAO,IAAI,IAAA,EAAK;AAAA,EAClB,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,OAAO,CAAA;AAAA,EACtB;AACF;AASO,SAAS,oBAAA,GAAgC;AAC9C,EAAA,OAAO,aAAA,CAAc,qBAAqB,CAAA;AAC5C;;;ACjGO,SAAS,4BAA4B,CAAA,EAGjC;AACT,EAAA,QAAQ,EAAE,MAAA;AAAQ,IAChB,KAAK,cAAA;AAAA,IACL,KAAK,WAAA;AACH,MAAA,OAAO,GAAG,CAAA,CAAE,EAAA,CAAG,QAAG,CAAC,CAAA,CAAA,EAAI,EAAE,OAAO,CAAA,CAAA;AAAA,IAClC,KAAK,kBAAA;AACH,MAAA,OAAO,GAAG,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,EAAI,EAAE,OAAO,CAAA,CAAA;AAAA,IACpC;AACE,MAAA,OAAO,GAAG,CAAA,CAAE,GAAA,CAAI,QAAG,CAAC,CAAA,CAAA,EAAI,EAAE,OAAO,CAAA,CAAA;AAAA;AAEvC;AAYA,eAAsB,kBAAA,CACpB,QACA,SAAA,EAC4C;AAC5C,EAAA,IAAI,CAAA;AACJ,EAAA,IAAI;AACF,IAAA,CAAA,GAAI,MAAM,MAAA,CAAO,qBAAA,CAAsB,SAAS,CAAA;AAAA,EAClD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,EACpB;AACA,EAAA,QAAQ,EAAE,MAAA;AAAQ,IAChB,KAAK,cAAA;AAAA,IACL,KAAK,WAAA;AACH,MAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,IACpB,KAAK,kBAAA;AACH,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,OAAA,EACE,CAAA,CAAA,EAAI,SAAS,CAAA,mDAAA,EACV,CAAA,CAAE,WAAA,GAAc,CAAA,EAAA,EAAK,CAAA,CAAE,WAAW,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,eAAA,EAAkB,EAAE,OAAO,CAAA;AAAA,OAC5E;AAAA,IACF;AACE,MAAA,OAAO,EAAE,IAAI,KAAA,EAAO,OAAA,EAAS,yBAAyB,SAAS,CAAA,QAAA,EAAM,CAAA,CAAE,OAAO,CAAA,CAAA,EAAG;AAAA;AAEvF;AAaO,SAAS,yBAAA,CACd,YACA,QAAA,EACK;AACL,EAAA,MAAM,SAAS,IAAI,GAAA,CAAA,CAAK,QAAA,CAAS,MAAA,IAAU,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,GAAG,CAAA,CAAE,IAAI,IAAI,CAAA,CAAE,IAAI,EAAE,CAAC,CAAA;AAChF,EAAA,OAAO,UAAA,CAAW,MAAA,CAAO,CAAC,CAAA,KAAM,MAAA,CAAO,GAAA,CAAI,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,EAAE,CAAC,CAAA;AACnE;AAGO,SAAS,MAAA,CAAO,IAAA,EAAc,SAAA,EAAmB,IAAA,EAAc,OAAA,EAA0B;AAC9F,EAAA,MAAM,OAAO,CAAA,EAAG,IAAI,CAAA,EAAA,EAAK,SAAS,IAAI,IAAI,CAAA,CAAA;AAC1C,EAAA,OAAO,OAAA,GAAU,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,GAAK,IAAA;AAC1C;AAGA,IAAM,eAAA,GAAkB,sBAAA;AAQjB,SAAS,cAAA,CACd,OACA,QAAA,EACoB;AACpB,EAAA,OAAO,KAAA,CAAM,aAAa,QAAA,CAAS,SAAA;AACrC;AAOO,SAAS,aAAA,CACd,OACA,QAAA,EACQ;AACR,EAAA,MAAM,EAAA,GAAK,cAAA,CAAe,KAAA,EAAO,QAAQ,CAAA;AACzC,EAAA,OAAO,EAAA,GAAK,MAAA,CAAO,KAAA,CAAM,IAAA,EAAM,EAAA,EAAI,KAAA,CAAM,IAAI,CAAA,GAAI,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,MAAM,IAAI,CAAA,CAAA;AAC9E;AAUO,SAAS,8BAAA,CACd,QAAA,EACA,YAAA,EACA,OAAA,EACA,WAAA,EACQ;AACR,EAAA,OACE,CAAA,EAAG,wBAAwB,CAAA,iBAAA,EAAe,QAAQ,sBAAsB,YAAY,CAAA,cAAA,EACpE,OAAO,CAAA,EAAA,EAAK,WAAW,CAAA,wGAAA,CAAA;AAG3C;AAQO,SAAS,kBAAA,CAAmB,UAA6B,SAAA,EAA8B;AAC5F,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAY;AAC5B,EAAA,KAAA,MAAW,CAAA,IAAK,QAAA,CAAS,MAAA,IAAU,EAAC,EAAG;AACrC,IAAA,IAAI,SAAA,IAAa,CAAA,CAAE,IAAA,KAAS,SAAA,EAAW;AACvC,IAAA,MAAM,EAAA,GAAK,cAAA,CAAe,CAAA,EAAG,QAAQ,CAAA;AACrC,IAAA,IAAI,EAAA,EAAI,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAAA,EACpB;AACA,EAAA,IAAI,GAAA,CAAI,SAAS,CAAA,IAAK,QAAA,CAAS,WAAW,GAAA,CAAI,GAAA,CAAI,SAAS,SAAS,CAAA;AACpE,EAAA,OAAO,CAAC,GAAG,GAAG,CAAA;AAChB;AAMO,SAAS,WAAA,CAAY,UAA6B,SAAA,EAA8B;AACrF,EAAA,OAAA,CAAQ,QAAA,CAAS,MAAA,IAAU,EAAC,EACzB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,SAAA,IAAa,CAAA,CAAE,IAAA,KAAS,SAAS,CAAA,CAChD,GAAA;AAAA,IAAI,CAAC,CAAA,KACJ,MAAA;AAAA,MACE,CAAA,CAAE,IAAA;AAAA,MACF,cAAA,CAAe,CAAA,EAAG,QAAQ,CAAA,IAAK,eAAA;AAAA,MAC/B,CAAA,CAAE,IAAA;AAAA,MACF,CAAA,CAAE,WAAW,QAAA,CAAS;AAAA;AACxB,GACF;AACJ;AAGO,SAAS,SAAS,GAAA,EAAqB;AAC5C,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,GAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,GAAI,CAAC,CAAA,GAAI,GAAA;AACxE,EAAA,MAAM,UAAA,GAAa,SAAA,CAAU,QAAA,CAAS,GAAG,CAAA,GACrC,SAAA,CAAU,KAAA,CAAM,SAAA,CAAU,OAAA,CAAQ,GAAG,CAAA,GAAI,CAAC,CAAA,GAC1C,SAAA;AACJ,EAAA,OAAO,UAAA,CAAW,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA;AAChC;AAOA,eAAsB,QACpB,MAAA,EACA,KAAA,EACA,UAAA,GAAa,IAAA,EACb,YAAY,GAAA,EACmF;AAC/F,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAC9B,EAAA,IAAI,GAAA,GAAM,MAAM,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AACnC,EAAA,OAAO,IAAI,MAAA,KAAW,SAAA,IAAa,IAAA,CAAK,GAAA,KAAQ,QAAA,EAAU;AACxD,IAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,MAAM,UAAA,CAAW,CAAA,EAAG,UAAU,CAAC,CAAA;AAClD,IAAA,GAAA,GAAM,MAAM,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAAA,EACjC;AACA,EAAA,OAAO,GAAA;AACT;AAOO,SAAS,iBAAiB,GAAA,EAAuB;AACtD,EAAA,MAAM,GAAA,GAAA,CAAO,eAAe,KAAA,GAAQ,GAAA,CAAI,UAAU,MAAA,CAAO,GAAG,GAAG,WAAA,EAAY;AAC3E,EAAA,OAAO,qEAAA,CAAsE,KAAK,GAAG,CAAA;AACvF;AAcA,eAAsB,eAAe,IAAA,EAOA;AACnC,EAAA,MAAM,EAAE,WAAW,GAAA,EAAK,OAAA,EAAS,UAAU,SAAA,EAAW,MAAA,EAAQ,KAAI,GAAI,IAAA;AAEtE,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,UAAA,CAAW;AAAA,MACjC,GAAA,EAAK,SAAA;AAAA,MACL,GAAA;AAAA,MACA,GAAI,OAAA,GAAU,EAAE,UAAA,EAAY,OAAA,CAAQ,KAAK,UAAA,EAAY,OAAA,CAAQ,GAAA,EAAI,GAAI,EAAC;AAAA;AAAA;AAAA;AAAA,MAItE,GAAI,SAAS,SAAA,GAAY,EAAE,WAAW,QAAA,CAAS,SAAA,KAAc;AAAC,KAC/D,CAAA;AACD,IAAA,QAAA,GAAW,KAAA,CAAM,EAAA;AAAA,EACnB,SAAS,GAAA,EAAK;AAGZ,IAAA,IAAI,CAAC,gBAAA,CAAiB,GAAG,CAAA,EAAG,MAAM,GAAA;AAClC,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,WAAA,EAAY;AACnC,IAAA,MAAM,QAAQ,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,SAAS,CAAA;AAClD,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,OAAA,EAAU,SAAS,CAAA,qDAAA,EACd,GAAA,YAAe,QAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,OACvD;AAAA,IACF;AACA,IAAA,QAAA,GAAW,KAAA,CAAM,EAAA;AAAA,EACnB;AAEA,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,GAAA,CAAI,WAAW,QAAQ,CAAA;AAC/C,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAK,CAAA;AACpC,EAAA,IAAI,GAAA,CAAI,MAAA,KAAW,QAAA,IAAY,GAAA,CAAI,WAAW,WAAA,EAAa;AACzD,IAAA,MAAM,MAAA,GAAA,CAAU,GAAA,CAAI,KAAA,IAAS,EAAC,EAAG,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,QAAQ,CAAA;AACpE,IAAA,KAAA,MAAW,CAAA,IAAK,MAAA,EAAQ,MAAA,CAAO,CAAA,MAAA,EAAS,CAAA,CAAE,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,KAAA,IAAS,QAAQ,CAAA,CAAE,CAAA;AACzE,IAAA,MAAA,CAAO,CAAA,YAAA,EAAe,GAAA,CAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AACnC,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAGA,EAAA,IAAI,GAAA,CAAI,WAAW,SAAA,EAAW;AAC5B,IAAA,MAAA,CAAO,sFAAiF,CAAA;AACxF,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,IAAI,aAAa,yBAAA,CAA0B,MAAM,IAAI,gBAAA,CAAiB,QAAQ,GAAG,QAAQ,CAAA;AACzF,EAAA,IAAI,SAAA,eAAwB,UAAA,CAAW,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,SAAS,CAAA;AACzE,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,IAAA,OAAA,CAAQ,wEAAmE,CAAA;AAC3E,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,YAAA,CAAa,EAAE,EAAE,CAAA;AAC3C,MAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,YAAA,CAAa,CAAA,CAAE,EAAA,EAAI,EAAE,GAAA,EAAK,KAAA,EAAO,OAAA,CAAQ,eAAA,EAAiB,CAAA;AAGhF,MAAA,IAAI,IAAI,KAAA,EAAO;AACb,QAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,GAAA,EAAK,IAAI,KAAK,CAAA;AAC3C,QAAA,IAAI,MAAA,CAAO,WAAW,WAAA,EAAa;AACjC,UAAA,MAAM,QAAQ,MAAA,CAAO,KAAA,IAAS,EAAC,EAC5B,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,QAAQ,CAAA,CACnC,IAAI,CAAC,CAAA,KAAM,EAAE,KAAK,CAAA,CAClB,OAAO,OAAO,CAAA;AACjB,UAAA,OAAA;AAAA,YACE,cAAc,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,kBAAA,EAAqB,MAAA,CAAO,MAAM,CAAA,CAAA,CAAA,IAC7D,KAAK,MAAA,GAAS,CAAA,EAAA,EAAK,KAAK,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GAAK,EAAA;AAAA,WAC5C;AACA,UAAA;AAAA,QACF;AAAA,MACF;AACA,MAAA,SAAA,CAAU,IAAA,CAAK,MAAA,CAAO,CAAA,CAAE,IAAA,EAAM,OAAA,CAAQ,SAAA,CAAU,kBAAA,EAAoB,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,OAAO,CAAC,CAAA;AAAA,IACxF,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA;AAAA,QACE,CAAA,kBAAA,EAAqB,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,OAC5F;AAAA,IACF;AAAA,EACF;AAEA,EAAA,KAAA,CAAM,CAAA,UAAA,EAAa,SAAA,CAAU,MAAM,CAAA,UAAA,CAAY,CAAA;AAC/C,EAAA,KAAA,MAAW,CAAA,IAAK,SAAA,EAAW,OAAA,CAAQ,CAAA,EAAA,EAAK,CAAC,CAAA,CAAE,CAAA;AAC3C,EAAA,OAAO,EAAE,SAAA,EAAU;AACrB","file":"chunk-GXLQLPE5.js","sourcesContent":["/**\n * Keycloak Device Authorization Grant (RFC 8628) for the store CLI: a public\n * device-flow client (`skaile-store-cli`) issues a plain realm JWT the store's\n * `AuthGuard` accepts — a CLI can't use the storefront's confidential browser\n * client. Tokens cache at `~/.skaile/auth.json` (0600, shared with `store/cli`);\n * `getAccessToken` refreshes transparently. All targets are env-overridable.\n *\n * @docLink cli/dev-guide#store-auth\n */\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { chmodSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { globalSkaileDir } from \"@skaile/workspaces/core\";\n\n/**\n * A PKCE (RFC 7636) `code_verifier` + its S256 `code_challenge`. Keycloak\n * enforces PKCE on the `skaile-store-cli` device flow (the device-authorization\n * request 400s with \"Missing parameter: code_challenge_method\" otherwise), so\n * every `deviceLogin` mints a fresh pair: the challenge goes on the device-auth\n * request, the verifier on the matching token poll. `base64url` (no padding)\n * per the spec.\n */\nfunction makePkcePair(): { verifier: string; challenge: string } {\n const verifier = randomBytes(32).toString(\"base64url\");\n const challenge = createHash(\"sha256\").update(verifier).digest(\"base64url\");\n return { verifier, challenge };\n}\n\n/** Resolved auth targets — every field has a prod default, all env-overridable. */\nexport interface StoreAuthConfig {\n keycloakUrl: string;\n realm: string;\n clientId: string;\n authFile: string;\n}\n\nfunction trimTrailingSlash(url: string): string {\n return url.replace(/\\/+$/, \"\");\n}\n\n/**\n * Load the auth config. Defaults target the production store\n * (`auth.skaile.ai`, realm `skaile-store`, public client `skaile-store-cli`);\n * override with `SKAILE_KEYCLOAK_URL` / `SKAILE_STORE_REALM` /\n * `SKAILE_STORE_CLI_CLIENT` / `SKAILE_AUTH_FILE` for dev or a preview deploy.\n */\nexport function loadStoreAuthConfig(): StoreAuthConfig {\n return {\n keycloakUrl: trimTrailingSlash(process.env.SKAILE_KEYCLOAK_URL ?? \"https://auth.skaile.ai\"),\n realm: process.env.SKAILE_STORE_REALM ?? \"skaile-store\",\n clientId: process.env.SKAILE_STORE_CLI_CLIENT ?? \"skaile-store-cli\",\n authFile: process.env.SKAILE_AUTH_FILE ?? join(globalSkaileDir(), \"auth.json\"),\n };\n}\n\n/** Keycloak OIDC endpoints derived from the realm base. */\nfunction oidc(config: StoreAuthConfig): { deviceAuth: string; token: string } {\n const base = `${config.keycloakUrl}/realms/${config.realm}/protocol/openid-connect`;\n return { deviceAuth: `${base}/auth/device`, token: `${base}/token` };\n}\n\nexport interface StoredAuth {\n access_token: string;\n refresh_token?: string;\n /** Epoch ms when the access token expires (with a safety margin already applied). */\n expires_at: number;\n}\n\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n error?: string;\n error_description?: string;\n}\n\ninterface DeviceAuthResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete?: string;\n interval?: number;\n expires_in: number;\n}\n\n/** Refresh this many ms before real expiry so an in-flight call never 401s. */\nconst EXPIRY_MARGIN_MS = 30_000;\n\n/** Injectable seams so the poll loop is unit-testable without real time or network. */\nexport interface AuthDeps {\n fetchImpl?: typeof fetch;\n sleep?: (ms: number) => Promise<void>;\n /** Called once with the verification URL + user code (default: write to stderr). */\n onPrompt?: (url: string, userCode: string) => void;\n}\n\nfunction readAuth(config: StoreAuthConfig): StoredAuth | null {\n try {\n const parsed = JSON.parse(readFileSync(config.authFile, \"utf-8\"));\n // Reject a corrupt / hand-edited file rather than treat it as a session.\n if (parsed && typeof parsed.access_token === \"string\") return parsed as StoredAuth;\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * The caller's store identity, decoded LOCALLY from the cached token's JWT\n * payload (no network, no signature check — this is an author-side hint, not an\n * authorization decision). Returns `null` when not signed in or the token is\n * unreadable. `githubLogin` is the verified GitHub handle (the preferred\n * publisher namespace); `username` is the Keycloak `preferred_username`.\n */\nexport function getStoreIdentity(\n config: StoreAuthConfig = loadStoreAuthConfig(),\n): { username?: string; githubLogin?: string } | null {\n const auth = readAuth(config);\n if (!auth) return null;\n try {\n const payload = auth.access_token.split(\".\")[1];\n const json = JSON.parse(Buffer.from(payload, \"base64url\").toString(\"utf-8\"));\n const username =\n typeof json.preferred_username === \"string\" ? json.preferred_username : undefined;\n const githubLogin = typeof json.github_login === \"string\" ? json.github_login : undefined;\n return username || githubLogin ? { username, githubLogin } : null;\n } catch {\n return null;\n }\n}\n\nfunction writeAuth(config: StoreAuthConfig, auth: StoredAuth): void {\n mkdirSync(dirname(config.authFile), { recursive: true });\n writeFileSync(config.authFile, JSON.stringify(auth, null, 2), { mode: 0o600 });\n chmodSync(config.authFile, 0o600);\n}\n\n/** Remove the cached session (sign out). */\nexport function logout(config: StoreAuthConfig): void {\n try {\n rmSync(config.authFile);\n } catch {\n // already absent — nothing to do\n }\n}\n\n/** True when a cached, well-formed session exists (validity/refresh resolved on use). */\nexport function hasStoredAuth(config: StoreAuthConfig): boolean {\n return readAuth(config) !== null;\n}\n\nfunction tokenToStored(token: TokenResponse): StoredAuth {\n return {\n access_token: token.access_token,\n refresh_token: token.refresh_token,\n expires_at: Date.now() + (token.expires_in ?? 300) * 1000 - EXPIRY_MARGIN_MS,\n };\n}\n\nconst defaultSleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\n\nfunction defaultPrompt(url: string, userCode: string): void {\n process.stderr.write(\n `\\nTo sign in, open:\\n\\n ${url}\\n\\nand enter the code: ${userCode}\\n\\nWaiting for approval…\\n`,\n );\n}\n\n/**\n * Run the device flow to completion, persisting tokens on success. Prints the\n * verification URL + user code for the operator to approve in a browser.\n */\nexport async function deviceLogin(\n config: StoreAuthConfig,\n deps: AuthDeps = {},\n): Promise<StoredAuth> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const sleep = deps.sleep ?? defaultSleep;\n const onPrompt = deps.onPrompt ?? defaultPrompt;\n const endpoints = oidc(config);\n const pkce = makePkcePair();\n\n const deviceRes = await fetchImpl(endpoints.deviceAuth, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n client_id: config.clientId,\n scope: \"openid profile\",\n code_challenge: pkce.challenge,\n code_challenge_method: \"S256\",\n }),\n });\n if (!deviceRes.ok) {\n throw new Error(\n `Device authorization request failed (${deviceRes.status}): ${await deviceRes.text()}`,\n );\n }\n const device = (await deviceRes.json()) as DeviceAuthResponse;\n\n onPrompt(device.verification_uri_complete ?? device.verification_uri, device.user_code);\n\n const intervalMs = (device.interval ?? 5) * 1000;\n const deadline = Date.now() + device.expires_in * 1000;\n let waitMs = intervalMs;\n\n while (Date.now() < deadline) {\n await sleep(waitMs);\n const tokenRes = await fetchImpl(endpoints.token, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n device_code: device.device_code,\n client_id: config.clientId,\n code_verifier: pkce.verifier,\n }),\n });\n const token = (await tokenRes.json()) as TokenResponse;\n if (tokenRes.ok) {\n const stored = tokenToStored(token);\n writeAuth(config, stored);\n return stored;\n }\n // RFC 8628 §3.5 pending / slow-down handling.\n if (token.error === \"authorization_pending\") continue;\n if (token.error === \"slow_down\") {\n waitMs += 5_000;\n continue;\n }\n throw new Error(`Sign-in failed: ${token.error_description ?? token.error ?? \"unknown error\"}`);\n }\n throw new Error(\"Sign-in timed out before approval.\");\n}\n\n/** Exchange a refresh token for a fresh access token; persist on success. */\nasync function refresh(\n config: StoreAuthConfig,\n refreshToken: string,\n fetchImpl: typeof fetch,\n): Promise<StoredAuth> {\n const res = await fetchImpl(oidc(config).token, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: config.clientId,\n }),\n });\n const token = (await res.json()) as TokenResponse;\n if (!res.ok) {\n throw new Error(\n `Token refresh failed: ${token.error_description ?? token.error ?? res.status}`,\n );\n }\n const stored = tokenToStored(token);\n writeAuth(config, stored);\n return stored;\n}\n\n/**\n * Return a valid access token, refreshing if it is expired (or about to). Throws\n * a clear \"run `skaile store login`\" error when there is no usable session.\n */\nexport async function getAccessToken(\n config: StoreAuthConfig,\n deps: AuthDeps = {},\n): Promise<string> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const auth = readAuth(config);\n if (!auth) throw new Error(\"Not signed in. Run `skaile store login` first.\");\n if (Date.now() < auth.expires_at) return auth.access_token;\n if (!auth.refresh_token) throw new Error(\"Session expired. Run `skaile store login` again.\");\n try {\n return (await refresh(config, auth.refresh_token, fetchImpl)).access_token;\n } catch {\n throw new Error(\"Session expired and refresh failed. Run `skaile store login` again.\");\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { globalSettingsPath, mapLegacyFields } from \"@skaile/workspaces/core\";\nimport { type AuthDeps, getAccessToken, hasStoredAuth, loadStoreAuthConfig } from \"./store-auth.ts\";\n\n/**\n * Connection configuration for the AI Asset Store API. `jwt` is normally left\n * null here and filled per-call by the caller from {@link getStoreToken} (the\n * device-flow session); it stays on the type for the `{ ...config, jwt }` spread.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport interface StoreConfig {\n url: string;\n jwt: string | null;\n}\n\n/**\n * Read the store API base URL (settings `storeUrl` → `SKAILE_STORE_URL` →\n * default). Auth is not read here — it lives in the device-flow session; see\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function getStoreConfig(): StoreConfig {\n const settingsPath = globalSettingsPath();\n let settings: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n settings = mapLegacyFields(JSON.parse(readFileSync(settingsPath, \"utf-8\")));\n } catch {\n settings = {};\n }\n }\n return {\n url: settings.storeUrl ?? process.env.SKAILE_STORE_URL ?? \"https://api.skaile.store\",\n jwt: null,\n };\n}\n\n/**\n * Return a valid store access token (Keycloak device-flow session, refreshed if\n * needed). Throws a \"run `skaile store login`\" error when there is no session.\n * This is the auth source for every `/api/v1/*` publisher call.\n */\nexport function getStoreToken(deps?: AuthDeps): Promise<string> {\n return getAccessToken(loadStoreAuthConfig(), deps);\n}\n\n/**\n * Make an authenticated HTTP request to the store REST API.\n *\n * @param config - Store connection config (URL + auth token).\n * @param path - API path (e.g. `/api/assets`).\n * @param opts - Optional method, body, query params, extra headers, and\n * `timeoutMs` (default 1500). Publisher calls pass a longer timeout because\n * they trigger server-side clone/sync work.\n * @returns Parsed JSON response body.\n * @docLink cli/dev-guide#store-client\n */\nexport async function storeFetch<T = any>(\n config: StoreConfig,\n path: string,\n opts?: {\n method?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n timeoutMs?: number;\n },\n): Promise<T> {\n let url = `${config.url}${path}`;\n if (opts?.params) {\n const sp = new URLSearchParams(opts.params);\n url += `?${sp}`;\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(opts?.headers ?? {}),\n };\n if (config.jwt) {\n headers.Authorization = `Bearer ${config.jwt}`;\n }\n\n const fetchOpts: RequestInit = {\n method: opts?.method ?? \"GET\",\n headers,\n };\n if (opts?.body) {\n fetchOpts.body = JSON.stringify(opts.body);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts?.timeoutMs ?? 1_500);\n try {\n const res = await fetch(url, { ...fetchOpts, signal: controller.signal });\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));\n // Prefer the store's human-readable `message` (e.g. \"Namespace '@x' is\n // reserved … Sign in with GitHub to claim it\") over the bare `error` code\n // (`UNPROCESSABLE_CONTENT`) — the message is the actionable part.\n const b = body as { message?: string; error?: string };\n throw new Error(b.message ?? b.error ?? `Store API error: ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Return `true` when a store session exists (a Keycloak device-flow token cached\n * at `~/.skaile/auth.json`). Validity/refresh is resolved on use via\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function isStoreAuthenticated(): boolean {\n return hasStoredAuth(loadStoreAuthConfig());\n}\n","/**\n * Shared store-interaction core for the two publish front-ends — the curator\n * sidecar flow (`source manifest publish`) and the first-party library flow\n * (`library publish`). Both differ only in their git side-effects + how they\n * resolve the source repo; the store orchestration below (register → sync →\n * candidates → per-asset preview+publish) is identical.\n *\n * The store REST surface is reached through the injectable {@link PublisherClient}\n * so the orchestration stays unit/integration-testable without a live store.\n *\n * @docLink cli/commands/source#manifest-publish\n */\n\nimport { SKAILE_MANIFEST_FILENAME, type SkPublishManifest } from \"@skaile/workspaces/core\";\nimport { logErr, logInfo, logOk, logWarn, S } from \"../helpers.ts\";\nimport type { PublisherClient } from \"../store-publisher.ts\";\n\n/**\n * One-line rendering of a namespace-availability probe for a `--dry-run` plan.\n * The `message` is store-authored (identical to what a real publish would echo)\n * — we only prepend a status glyph so the reader sees green/amber/red at a\n * glance without the CLI re-deriving any authorization logic.\n */\nexport function formatNamespaceAvailability(a: {\n status: \"owned-by-you\" | \"claimable-by-you\" | \"reserved\" | \"available\";\n message: string;\n}): string {\n switch (a.status) {\n case \"owned-by-you\":\n case \"available\":\n return `${S.ok(\"✓\")} ${a.message}`;\n case \"claimable-by-you\":\n return `${S.warn(\"!\")} ${a.message}`;\n default:\n return `${S.err(\"✗\")} ${a.message}`;\n }\n}\n\n/**\n * Preflight the target namespace against the store's availability probe BEFORE a\n * publish does any irreversible work (a public git push). Returns `{ ok: false }`\n * with a guided message for `reserved` (not yours) and `claimable-by-you` (must\n * claim first) — the two states a real publish would reject — so the caller can\n * abort with actionable guidance instead of a raw 422 after pushing bytes.\n *\n * The probe is advisory: any failure (offline, older store) returns `{ ok: true }`\n * so the store stays the authority and a valid publish is never blocked.\n */\nexport async function preflightNamespace(\n client: PublisherClient,\n namespace: string,\n): Promise<{ ok: boolean; message?: string }> {\n let a: Awaited<ReturnType<PublisherClient[\"namespaceAvailability\"]>>;\n try {\n a = await client.namespaceAvailability(namespace);\n } catch {\n return { ok: true };\n }\n switch (a.status) {\n case \"owned-by-you\":\n case \"available\":\n return { ok: true };\n case \"claimable-by-you\":\n return {\n ok: false,\n message:\n `@${namespace} isn't yours yet — claim it in the store first` +\n `${a.claimMethod ? ` (${a.claimMethod})` : \"\"}, then re-run. ${a.message}`,\n };\n default: // reserved, or any unrecognized future status (fail safe → block)\n return { ok: false, message: `Cannot publish under @${namespace} — ${a.message}` };\n }\n}\n\n/** One candidate row shape the matcher operates on (kind + name are the key). */\ninterface CandidateLike {\n kind: string;\n name: string;\n}\n\n/**\n * Keep only candidates whose `(kind, name)` pair is declared in the manifest.\n * The backend may merge extra assets from the base repo into the candidate\n * list; a publish only touches what the manifest curated/declared.\n */\nexport function matchCandidatesToManifest<T extends CandidateLike>(\n candidates: T[],\n manifest: SkPublishManifest,\n): T[] {\n const wanted = new Set((manifest.assets ?? []).map((a) => `${a.kind}:${a.name}`));\n return candidates.filter((c) => wanted.has(`${c.kind}:${c.name}`));\n}\n\n/** A canonical ref string `kind:@publisher/name[#version]` for reporting. */\nexport function refFor(kind: string, publisher: string, name: string, version?: string): string {\n const base = `${kind}:@${publisher}/${name}`;\n return version ? `${base}#${version}` : base;\n}\n\n/** Placeholder namespace shown when neither the asset nor the manifest names a publisher. */\nconst UNSET_NAMESPACE = \"<manifest publisher>\";\n\n/**\n * The publisher namespace one manifest asset publishes under:\n * `assets[].publisher` first, else the manifest's top-level `publisher` —\n * the same priority discovery applies when it indexes the asset. `undefined`\n * when neither is declared.\n */\nexport function assetNamespace(\n asset: { publisher?: string },\n manifest: SkPublishManifest,\n): string | undefined {\n return asset.publisher ?? manifest.publisher;\n}\n\n/**\n * The version-less canonical ref of one manifest asset for messages:\n * `kind:@<publisher>/<name>` (`assets[].publisher ?? publisher`), or the bare\n * `kind:name` when the manifest declares no namespace.\n */\nexport function assetEntryRef(\n asset: { kind: string; name: string; publisher?: string },\n manifest: SkPublishManifest,\n): string {\n const ns = assetNamespace(asset, manifest);\n return ns ? refFor(asset.kind, ns, asset.name) : `${asset.kind}:${asset.name}`;\n}\n\n/**\n * The warning `skaile validate` and the publish plan print when a manifest\n * entry's `version` differs from the one in the asset's own file. The file is\n * the source of truth; `skaile library index` rewrites the entry from it.\n *\n * @param entryRef - {@link assetEntryRef} of the entry.\n * @param relFile - the asset file, relative to the library root (posix).\n */\nexport function manifestVersionMismatchMessage(\n entryRef: string,\n entryVersion: string,\n relFile: string,\n fileVersion: string,\n): string {\n return (\n `${SKAILE_MANIFEST_FILENAME} [assets] — ${entryRef}: manifest version ${entryVersion} ` +\n `differs from ${relFile} (${fileVersion}). The file is the source of truth: ` +\n \"bump the version there, then run `skaile library index <library>`.\"\n );\n}\n\n/**\n * Every distinct namespace the manifest's assets (optionally narrowed to\n * `assetName`) publish under, in first-seen order. A manifest whose assets\n * carry no namespace at all falls back to its top-level `publisher` so an\n * empty inventory still reports the namespace it would claim.\n */\nexport function manifestNamespaces(manifest: SkPublishManifest, assetName?: string): string[] {\n const out = new Set<string>();\n for (const a of manifest.assets ?? []) {\n if (assetName && a.name !== assetName) continue;\n const ns = assetNamespace(a, manifest);\n if (ns) out.add(ns);\n }\n if (out.size === 0 && manifest.publisher) out.add(manifest.publisher);\n return [...out];\n}\n\n/**\n * The canonical refs a publish would produce, one per manifest asset (optionally\n * narrowed to `assetName`), each under its own `assets[].publisher ?? publisher`.\n */\nexport function plannedRefs(manifest: SkPublishManifest, assetName?: string): string[] {\n return (manifest.assets ?? [])\n .filter((a) => !assetName || a.name === assetName)\n .map((a) =>\n refFor(\n a.kind,\n assetNamespace(a, manifest) ?? UNSET_NAMESPACE,\n a.name,\n a.version ?? manifest.version,\n ),\n );\n}\n\n/** The bare asset name from a `kind:@publisher/name#version` ref or a plain name. */\nexport function bareName(ref: string): string {\n const afterKind = ref.includes(\":\") ? ref.slice(ref.indexOf(\":\") + 1) : ref;\n const afterScope = afterKind.includes(\"/\")\n ? afterKind.slice(afterKind.indexOf(\"/\") + 1)\n : afterKind;\n return afterScope.split(\"#\")[0];\n}\n\n/**\n * Poll a job until it leaves `running` or the deadline passes. Returns the last\n * observed state — the caller MUST treat a still-`running` result as a timeout\n * (not success), since it means the deadline was hit before the job finished.\n */\nexport async function pollJob(\n client: PublisherClient,\n jobId: string,\n intervalMs = 1_500,\n timeoutMs = 60_000,\n): Promise<{ status: string; items?: Array<{ label: string; status: string; error?: string }> }> {\n const deadline = Date.now() + timeoutMs;\n let job = await client.jobGet(jobId);\n while (job.status === \"running\" && Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, intervalMs));\n job = await client.jobGet(jobId);\n }\n return job;\n}\n\n/**\n * True when a `sourcesAdd` rejection is a duplicate-URL conflict (the source is\n * already registered) — the only error the publish flow recovers from by looking\n * the existing row up. Every other failure (auth, 5xx, network) must propagate.\n */\nexport function isDupSourceError(err: unknown): boolean {\n const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();\n return /\\b409\\b|conflict|duplicate|already exists|already registered|unique/.test(msg);\n}\n\n/**\n * Register + sync the source, then publish its curated/declared candidates —\n * the store-side steps shared by both publish front-ends. Git side-effects (the\n * sidecar push, or the library commit+push) happen in the caller *before* this;\n * this function is purely store interaction.\n *\n * The sidecar front-end passes `sidecar` (so `sourcesAdd` carries the sidecar\n * pin); the library front-end omits it (the source repo IS the manifest host).\n * `assetName`, when set, narrows publication to the single candidate of that\n * name. Fatal store states (`sourcesAdd` non-dup failure) surface; sync failures\n * and empty candidate sets `process.exit(1)` with the same messages as before.\n */\nexport async function publishToStore(opts: {\n sourceUrl: string;\n ref: string;\n sidecar?: { url: string; ref: string };\n manifest: SkPublishManifest;\n assetName?: string;\n client: PublisherClient;\n}): Promise<{ published: string[] }> {\n const { sourceUrl, ref, sidecar, manifest, assetName, client: pub } = opts;\n\n let sourceId: string;\n try {\n const added = await pub.sourcesAdd({\n url: sourceUrl,\n ref,\n ...(sidecar ? { sidecarUrl: sidecar.url, sidecarRef: sidecar.ref } : {}),\n // Publish under the manifest's declared namespace; the store resolves a\n // claimed Publisher when it differs from the caller's login, else defaults\n // to `@<username>`. Omitted when the manifest carries no publisher.\n ...(manifest.publisher ? { namespace: manifest.publisher } : {}),\n });\n sourceId = added.id;\n } catch (err) {\n // Only a duplicate-url conflict is recoverable (source already registered);\n // auth/5xx/network failures must surface, not silently reuse a stale row.\n if (!isDupSourceError(err)) throw err;\n const rows = await pub.sourcesList();\n const found = rows.find((r) => r.url === sourceUrl);\n if (!found) {\n throw new Error(\n `Source ${sourceUrl} looked already-registered but no owned row matched: ` +\n `${err instanceof Error ? err.message : String(err)}`,\n );\n }\n sourceId = found.id;\n }\n\n const { jobId } = await pub.sourceSync(sourceId);\n const job = await pollJob(pub, jobId);\n if (job.status === \"failed\" || job.status === \"cancelled\") {\n const failed = (job.items ?? []).filter((i) => i.status === \"failed\");\n for (const i of failed) logErr(`sync: ${i.label}: ${i.error ?? \"failed\"}`);\n logErr(`Source sync ${job.status}.`);\n process.exit(1);\n }\n // A still-`running` job means the poll deadline was hit — do NOT proceed on an\n // unfinished sync (it would read incomplete candidates).\n if (job.status === \"running\") {\n logErr(\"Source sync timed out before completing — re-run `publish`, or check the store.\");\n process.exit(1);\n }\n\n let candidates = matchCandidatesToManifest(await pub.sourceCandidates(sourceId), manifest);\n if (assetName) candidates = candidates.filter((c) => c.name === assetName);\n if (candidates.length === 0) {\n logWarn(\"No candidates discovered — check the manifest and the source ref.\");\n process.exit(1);\n }\n\n const published: string[] = [];\n for (const c of candidates) {\n try {\n const preview = await pub.assetPreview(c.id);\n const res = await pub.assetPublish(c.id, { ref, files: preview.discoveredFiles });\n // Publish is async — wait for the job so we only report refs that actually\n // landed, not ones whose import is still in flight or about to fail.\n if (res.jobId) {\n const pubJob = await pollJob(pub, res.jobId);\n if (pubJob.status !== \"succeeded\") {\n const errs = (pubJob.items ?? [])\n .filter((i) => i.status === \"failed\")\n .map((i) => i.error)\n .filter(Boolean);\n logWarn(\n `Publish of ${c.kind}:${c.name} did not succeed (${pubJob.status})` +\n (errs.length ? `: ${errs.join(\"; \")}` : \"\"),\n );\n continue;\n }\n }\n published.push(refFor(c.kind, preview.candidate.publisherNamespace, c.name, c.version));\n } catch (err) {\n logWarn(\n `Failed to publish ${c.kind}:${c.name}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n logOk(`Published ${published.length} asset(s):`);\n for (const r of published) logInfo(` ${r}`);\n return { published };\n}\n"]}
|