@skaile/workspaces 5.9.0 → 5.11.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 +145 -0
- package/README.md +12 -0
- package/dist/{asset-feeds-XMKKUUK6.js → asset-feeds-CXGQIDFR.js} +19 -19
- package/dist/{asset-feeds-XMKKUUK6.js.map → asset-feeds-CXGQIDFR.js.map} +1 -1
- package/dist/asset-manager/catalog-deployer.js +8 -8
- package/dist/asset-manager/index.js +14 -14
- package/dist/asset-manager/installer.js +10 -10
- package/dist/asset-manager/renderers.js +9 -9
- package/dist/asset-manager/src/index.d.ts +400 -35
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/install-agent.d.ts +3 -1
- package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
- package/dist/asset-manager/src/install-instances.d.ts +31 -1
- package/dist/asset-manager/src/install-instances.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts +43 -3
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/asset-manager/src/renderers.d.ts +4 -5
- package/dist/asset-manager/src/renderers.d.ts.map +1 -1
- package/dist/bridge/drivers/claude-sdk.js +11 -11
- package/dist/bridge/drivers/codex.js +11 -11
- package/dist/bridge/drivers/continue.js +10 -10
- package/dist/bridge/drivers/echo.js +2 -2
- package/dist/bridge/drivers/gemini.js +7 -7
- package/dist/bridge/drivers/goose.js +10 -10
- package/dist/bridge/drivers/omp.js +19 -3
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/drivers/opencode.js +10 -10
- package/dist/bridge/drivers/qwen.js +7 -7
- package/dist/bridge/index.js +12 -12
- package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
- package/dist/{chunk-4MQS7CAF.js → chunk-2F5AWQX5.js} +437 -175
- package/dist/chunk-2F5AWQX5.js.map +1 -0
- package/dist/{chunk-UM7RIAHO.js → chunk-3SM2DL2T.js} +8 -8
- package/dist/{chunk-UM7RIAHO.js.map → chunk-3SM2DL2T.js.map} +1 -1
- package/dist/{chunk-5NNNV76P.js → chunk-47U4GZ4M.js} +2 -2
- package/dist/{chunk-5NNNV76P.js.map → chunk-47U4GZ4M.js.map} +1 -1
- package/dist/{chunk-TTRYE6AC.js → chunk-4A4OD24G.js} +9 -9
- package/dist/{chunk-TTRYE6AC.js.map → chunk-4A4OD24G.js.map} +1 -1
- package/dist/{chunk-ZTBAYUDY.js → chunk-6O2X3GPW.js} +2 -2
- package/dist/{chunk-ZTBAYUDY.js.map → chunk-6O2X3GPW.js.map} +1 -1
- package/dist/{chunk-JAKOMFC6.js → chunk-ALEYHUC5.js} +114 -46
- package/dist/chunk-ALEYHUC5.js.map +1 -0
- package/dist/{chunk-QVNRCDTV.js → chunk-BNMZVPYA.js} +7 -7
- package/dist/chunk-BNMZVPYA.js.map +1 -0
- package/dist/{chunk-2FRUUDZY.js → chunk-CAHB6MHA.js} +5 -5
- package/dist/{chunk-2FRUUDZY.js.map → chunk-CAHB6MHA.js.map} +1 -1
- package/dist/{chunk-GKMZ6THE.js → chunk-CJERAGFY.js} +44 -33
- package/dist/chunk-CJERAGFY.js.map +1 -0
- package/dist/{chunk-CKQEIY43.js → chunk-COH6FQAG.js} +4 -4
- package/dist/{chunk-CKQEIY43.js.map → chunk-COH6FQAG.js.map} +1 -1
- package/dist/{chunk-UO7WPLDY.js → chunk-CPWLNZGJ.js} +3 -3
- package/dist/{chunk-UO7WPLDY.js.map → chunk-CPWLNZGJ.js.map} +1 -1
- package/dist/{chunk-MGGFBZWA.js → chunk-D3B36CYC.js} +4 -3
- package/dist/chunk-D3B36CYC.js.map +1 -0
- package/dist/{chunk-UMVKJM4Q.js → chunk-DALV4HHP.js} +18 -3
- package/dist/chunk-DALV4HHP.js.map +1 -0
- package/dist/{chunk-IMKSM5NL.js → chunk-DZMNFCWB.js} +1447 -199
- package/dist/chunk-DZMNFCWB.js.map +1 -0
- package/dist/{chunk-GB7WDMH2.js → chunk-EDYHEMJA.js} +4 -4
- package/dist/{chunk-GB7WDMH2.js.map → chunk-EDYHEMJA.js.map} +1 -1
- package/dist/{chunk-YSHVQGUS.js → chunk-FH7W6TJ4.js} +164 -41
- package/dist/chunk-FH7W6TJ4.js.map +1 -0
- package/dist/{chunk-W5DWWE4Y.js → chunk-G4FFOV3N.js} +4 -4
- package/dist/{chunk-W5DWWE4Y.js.map → chunk-G4FFOV3N.js.map} +1 -1
- package/dist/{chunk-2LWYNQK7.js → chunk-GCHPUTA3.js} +3 -3
- package/dist/{chunk-2LWYNQK7.js.map → chunk-GCHPUTA3.js.map} +1 -1
- package/dist/{chunk-JZ5EHBPI.js → chunk-GV4DZ6MT.js} +20 -4
- package/dist/chunk-GV4DZ6MT.js.map +1 -0
- package/dist/{chunk-S53LOR7B.js → chunk-HCEVNYSH.js} +3 -3
- package/dist/{chunk-S53LOR7B.js.map → chunk-HCEVNYSH.js.map} +1 -1
- package/dist/{chunk-EF7NPDDU.js → chunk-HZXUXHIV.js} +31 -17
- package/dist/chunk-HZXUXHIV.js.map +1 -0
- package/dist/{chunk-IR33D6EP.js → chunk-IER3KIPH.js} +5 -5
- package/dist/{chunk-IR33D6EP.js.map → chunk-IER3KIPH.js.map} +1 -1
- package/dist/{chunk-Y7QA2OLD.js → chunk-J4RBUFGM.js} +22 -20
- package/dist/chunk-J4RBUFGM.js.map +1 -0
- package/dist/{chunk-J7U3PIOE.js → chunk-M3B6EIJD.js} +4 -4
- package/dist/{chunk-J7U3PIOE.js.map → chunk-M3B6EIJD.js.map} +1 -1
- package/dist/{chunk-DNZYOKOJ.js → chunk-MZG34MBZ.js} +3 -3
- package/dist/{chunk-DNZYOKOJ.js.map → chunk-MZG34MBZ.js.map} +1 -1
- package/dist/{chunk-V2DXZYBB.js → chunk-NWDSLXOX.js} +3 -3
- package/dist/{chunk-V2DXZYBB.js.map → chunk-NWDSLXOX.js.map} +1 -1
- package/dist/{chunk-36AFURKZ.js → chunk-PBBPZYVG.js} +61 -12
- package/dist/chunk-PBBPZYVG.js.map +1 -0
- package/dist/{chunk-P67WJVP4.js → chunk-PQFHMQHQ.js} +10 -9
- package/dist/chunk-PQFHMQHQ.js.map +1 -0
- package/dist/{chunk-UAROCOXF.js → chunk-QVFAS5IO.js} +3 -3
- package/dist/{chunk-UAROCOXF.js.map → chunk-QVFAS5IO.js.map} +1 -1
- package/dist/{chunk-K3CVFRVS.js → chunk-QZNJOHN6.js} +3 -3
- package/dist/{chunk-K3CVFRVS.js.map → chunk-QZNJOHN6.js.map} +1 -1
- package/dist/{chunk-FVJK4QWM.js → chunk-R7NHYEJF.js} +4 -4
- package/dist/{chunk-FVJK4QWM.js.map → chunk-R7NHYEJF.js.map} +1 -1
- package/dist/{chunk-GXLQLPE5.js → chunk-RYYLMBA2.js} +5 -5
- package/dist/{chunk-GXLQLPE5.js.map → chunk-RYYLMBA2.js.map} +1 -1
- package/dist/{chunk-Y4N2NUZD.js → chunk-S3O3GKB7.js} +4 -4
- package/dist/{chunk-Y4N2NUZD.js.map → chunk-S3O3GKB7.js.map} +1 -1
- package/dist/{chunk-GTILM2CI.js → chunk-SBSA3IQA.js} +43 -12
- package/dist/chunk-SBSA3IQA.js.map +1 -0
- package/dist/{chunk-4PTSR4UU.js → chunk-T42WRQ4O.js} +3 -3
- package/dist/{chunk-4PTSR4UU.js.map → chunk-T42WRQ4O.js.map} +1 -1
- package/dist/{chunk-MR5HBOUF.js → chunk-T7CTHHG7.js} +3 -3
- package/dist/{chunk-MR5HBOUF.js.map → chunk-T7CTHHG7.js.map} +1 -1
- package/dist/{chunk-FZNG4V4J.js → chunk-TCHRMVTO.js} +4 -4
- package/dist/{chunk-FZNG4V4J.js.map → chunk-TCHRMVTO.js.map} +1 -1
- package/dist/{chunk-LAMCXQGA.js → chunk-VLTQGE2E.js} +75 -25
- package/dist/chunk-VLTQGE2E.js.map +1 -0
- package/dist/{chunk-7AI3Q5AQ.js → chunk-WSBKB4CJ.js} +71 -24
- package/dist/chunk-WSBKB4CJ.js.map +1 -0
- package/dist/{chunk-CGT45WN7.js → chunk-X77SUM4P.js} +3 -3
- package/dist/{chunk-CGT45WN7.js.map → chunk-X77SUM4P.js.map} +1 -1
- package/dist/{chunk-SCOT677Q.js → chunk-XDKH7XSA.js} +5 -5
- package/dist/{chunk-SCOT677Q.js.map → chunk-XDKH7XSA.js.map} +1 -1
- package/dist/{chunk-QVEKLSEH.js → chunk-XUSALIEI.js} +6 -6
- package/dist/{chunk-QVEKLSEH.js.map → chunk-XUSALIEI.js.map} +1 -1
- package/dist/{chunk-FYXZRVID.js → chunk-Y3HTGHJC.js} +3 -3
- package/dist/{chunk-FYXZRVID.js.map → chunk-Y3HTGHJC.js.map} +1 -1
- package/dist/chunk-YOH2L76X.js +505 -0
- package/dist/chunk-YOH2L76X.js.map +1 -0
- package/dist/{chunk-B6GIW55K.js → chunk-ZCAJZ4B2.js} +7 -4
- package/dist/chunk-ZCAJZ4B2.js.map +1 -0
- package/dist/{chunk-BTE2V4IW.js → chunk-ZPWTOUTK.js} +76 -7
- package/dist/{chunk-BTE2V4IW.js.map → chunk-ZPWTOUTK.js.map} +1 -1
- package/dist/cli/index.js +1034 -794
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +8 -5
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/diff.d.ts +4 -2
- package/dist/cli/src/commands/diff.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 +34 -2
- package/dist/cli/src/commands/library-index.d.ts.map +1 -1
- package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
- package/dist/cli/src/commands/manage.d.ts +12 -5
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
- package/dist/cli/src/commands/outdated.d.ts +7 -5
- package/dist/cli/src/commands/outdated.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts +13 -8
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/run.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts +30 -1
- package/dist/cli/src/commands/source.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/commands/why.d.ts +1 -0
- package/dist/cli/src/commands/why.d.ts.map +1 -1
- package/dist/cli/src/helpers.d.ts +12 -0
- package/dist/cli/src/helpers.d.ts.map +1 -1
- package/dist/cli/src/skill-checks.d.ts +57 -4
- package/dist/cli/src/skill-checks.d.ts.map +1 -1
- package/dist/connectors/config.js +5 -5
- package/dist/connectors/index.js +16 -16
- package/dist/{connectors-C7UQ73BK.js → connectors-4QWAKPHB.js} +19 -19
- package/dist/{connectors-C7UQ73BK.js.map → connectors-4QWAKPHB.js.map} +1 -1
- package/dist/core/index.js +7 -7
- 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 +2 -1
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/lock.d.ts +6 -2
- package/dist/core/src/lock.d.ts.map +1 -1
- package/dist/core/src/logging/sinks/sqlite-runtime.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +22 -6
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/publish-manifest.d.ts +29 -3
- package/dist/core/src/publish-manifest.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/requirements.d.ts +26 -0
- package/dist/core/src/requirements.d.ts.map +1 -0
- package/dist/core/src/walker.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +22 -1
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/src/workspace-yaml-editor.d.ts +4 -1
- package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
- package/dist/core/workspace-config.js +4 -4
- package/dist/deploy/index.js +7 -7
- package/dist/discovery/index.js +5 -5
- package/dist/discovery/src/builtin-providers.d.ts.map +1 -1
- package/dist/discovery/src/discover-manifest.d.ts.map +1 -1
- package/dist/discovery/src/discover.d.ts.map +1 -1
- package/dist/discovery/src/source-config.d.ts.map +1 -1
- package/dist/discovery/src/tree-entries.d.ts.map +1 -1
- package/dist/{ensure-sources-SRC2DVR5.js → ensure-sources-2RONZKCU.js} +17 -17
- package/dist/{ensure-sources-SRC2DVR5.js.map → ensure-sources-2RONZKCU.js.map} +1 -1
- package/dist/factory-assets/connectors/box.js +16 -16
- package/dist/factory-assets/connectors/deploy.js +16 -16
- package/dist/factory-assets/connectors/devserver.js +16 -16
- package/dist/factory-assets/connectors/flow/adapter.js +16 -16
- package/dist/factory-assets/connectors/flow/contract/normalize.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/contract.js +1 -1
- package/dist/factory-assets/connectors/flow/engine.js +9 -9
- package/dist/factory-assets/connectors/flow/run-flow.js +18 -18
- package/dist/factory-assets/connectors/flow.js +16 -16
- package/dist/factory-assets/connectors/git.js +16 -16
- package/dist/factory-assets/connectors/gmail.js +16 -16
- package/dist/factory-assets/connectors/googledrive.js +16 -16
- package/dist/factory-assets/connectors/local.js +16 -16
- package/dist/factory-assets/connectors/mattermost.js +16 -16
- package/dist/factory-assets/connectors/memory.js +16 -16
- package/dist/factory-assets/connectors/minio.js +16 -16
- package/dist/factory-assets/connectors/postgres.js +16 -16
- package/dist/factory-assets/connectors/s3.js +16 -16
- package/dist/factory-assets/connectors/sharepoint.js +16 -16
- package/dist/factory-assets/connectors/sqlite.js +16 -16
- package/dist/factory-assets/connectors/static-server.js +16 -16
- package/dist/factory-assets/connectors/tunnel.js +16 -16
- package/dist/factory-assets/connectors/webdav.js +16 -16
- package/dist/factory-assets/connectors/xstate-store.js +16 -16
- package/dist/factory-assets/connectors/xstate.js +16 -16
- package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +9 -3
- package/dist/factory-assets/skills/authoring-skaile-manifests/references/dependency-standard.md +4 -2
- package/dist/{flows-CBYRSAGS.js → flows-EQF2CH4U.js} +12 -12
- package/dist/{flows-CBYRSAGS.js.map → flows-EQF2CH4U.js.map} +1 -1
- package/dist/{helpers-XAEKCZKT.js → helpers-CFK6YP6R.js} +17 -17
- package/dist/{helpers-XAEKCZKT.js.map → helpers-CFK6YP6R.js.map} +1 -1
- package/dist/library/index.js +11 -11
- package/dist/library/install.js +3 -3
- package/dist/library/src/index.d.ts +2 -1
- package/dist/library/src/index.d.ts.map +1 -1
- package/dist/library/src/local/library-dir.d.ts +68 -0
- package/dist/library/src/local/library-dir.d.ts.map +1 -0
- package/dist/library/src/local/library-manager.d.ts +10 -1
- package/dist/library/src/local/library-manager.d.ts.map +1 -1
- package/dist/library/src/local/library.d.ts +2 -2
- package/dist/library/src/local/library.d.ts.map +1 -1
- package/dist/library/src/local/local-catalog-source.d.ts +9 -0
- package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
- package/dist/library/src/manifest-writer.d.ts +55 -4
- package/dist/library/src/manifest-writer.d.ts.map +1 -1
- package/dist/library/src/remote/cache.d.ts +18 -1
- package/dist/library/src/remote/cache.d.ts.map +1 -1
- package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
- package/dist/library/src/remote/rest-catalog-source.d.ts.map +1 -1
- package/dist/library/src/sync/git-driver.d.ts +7 -6
- package/dist/library/src/sync/git-driver.d.ts.map +1 -1
- package/dist/{library-publish-VJSWMOLH.js → library-publish-53UTB3MB.js} +151 -42
- package/dist/library-publish-53UTB3MB.js.map +1 -0
- package/dist/open-library-BOSPJVID.js +40 -0
- package/dist/{open-library-DB2PNL2X.js.map → open-library-BOSPJVID.js.map} +1 -1
- package/dist/open-registry-4FI7HKET.js +32 -0
- package/dist/{open-registry-ZUZJ7MS7.js.map → open-registry-4FI7HKET.js.map} +1 -1
- package/dist/paths-SUS4S4YT.js +22 -0
- package/dist/{paths-FQ64OLJG.js.map → paths-SUS4S4YT.js.map} +1 -1
- package/dist/{plugin-store-MPAMD5OT.js → plugin-store-AGQDMING.js} +9 -9
- package/dist/{plugin-store-MPAMD5OT.js.map → plugin-store-AGQDMING.js.map} +1 -1
- package/dist/project-I55A4O2T.js +41 -0
- package/dist/{project-I6NX3NFB.js.map → project-I55A4O2T.js.map} +1 -1
- package/dist/resolver/index.js +8 -8
- package/dist/runner/index.js +30 -30
- package/dist/runner/src/agent.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/usage-limit-turn-hold.d.ts +51 -0
- package/dist/runner/src/usage-limit-turn-hold.d.ts.map +1 -0
- package/dist/sdk/asset-manager.js +14 -14
- package/dist/sdk/bridge.js +12 -12
- package/dist/sdk/core.js +7 -7
- package/dist/sdk/flow.js +9 -9
- package/dist/sdk/index.js +30 -30
- package/dist/sdk/resolver.js +8 -8
- package/dist/sdk/runner.js +30 -30
- package/dist/{setup-B7JUHYJW.js → setup-7DQJKHUI.js} +22 -22
- package/dist/{setup-B7JUHYJW.js.map → setup-7DQJKHUI.js.map} +1 -1
- package/dist/{skills-TVO26Y4V.js → skills-NUEN5NDX.js} +13 -13
- package/dist/{skills-TVO26Y4V.js.map → skills-NUEN5NDX.js.map} +1 -1
- package/dist/source-G2LV5LVD.js +41 -0
- package/dist/{source-PJBMDCKX.js.map → source-G2LV5LVD.js.map} +1 -1
- package/dist/{source-manifest-publish-LLJWXGID.js → source-manifest-publish-6RM7SWLZ.js} +24 -24
- package/dist/{source-manifest-publish-LLJWXGID.js.map → source-manifest-publish-6RM7SWLZ.js.map} +1 -1
- package/dist/tui/index.js +61 -41
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/src/repl.d.ts.map +1 -1
- package/dist/types/manifests.js +1 -1
- package/dist/types/src/manifests/agent.d.ts +2 -0
- package/dist/types/src/manifests/agent.d.ts.map +1 -1
- package/dist/types/src/manifests/contract.d.ts +2 -0
- package/dist/types/src/manifests/contract.d.ts.map +1 -1
- package/dist/types/src/manifests/index.d.ts +3 -3
- package/dist/types/src/manifests/index.d.ts.map +1 -1
- package/dist/types/src/manifests/preset.d.ts +1 -1
- package/dist/types/src/manifests/prompt.d.ts +2 -0
- package/dist/types/src/manifests/prompt.d.ts.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +23 -23
- package/dist/workspace-plugin/adapters/omp.js +14 -14
- package/dist/workspace-plugin/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-36AFURKZ.js.map +0 -1
- package/dist/chunk-4MQS7CAF.js.map +0 -1
- package/dist/chunk-7AI3Q5AQ.js.map +0 -1
- package/dist/chunk-B6GIW55K.js.map +0 -1
- package/dist/chunk-EF7NPDDU.js.map +0 -1
- package/dist/chunk-GKMZ6THE.js.map +0 -1
- package/dist/chunk-GTILM2CI.js.map +0 -1
- package/dist/chunk-IMKSM5NL.js.map +0 -1
- package/dist/chunk-JAKOMFC6.js.map +0 -1
- package/dist/chunk-JZ5EHBPI.js.map +0 -1
- package/dist/chunk-LAMCXQGA.js.map +0 -1
- package/dist/chunk-MGGFBZWA.js.map +0 -1
- package/dist/chunk-P67WJVP4.js.map +0 -1
- package/dist/chunk-QVNRCDTV.js.map +0 -1
- package/dist/chunk-UMVKJM4Q.js.map +0 -1
- package/dist/chunk-Y7QA2OLD.js.map +0 -1
- package/dist/chunk-YSHVQGUS.js.map +0 -1
- package/dist/chunk-ZAOGFXDO.js +0 -112
- package/dist/chunk-ZAOGFXDO.js.map +0 -1
- package/dist/library-publish-VJSWMOLH.js.map +0 -1
- package/dist/open-library-DB2PNL2X.js +0 -40
- package/dist/open-registry-ZUZJ7MS7.js +0 -32
- package/dist/paths-FQ64OLJG.js +0 -22
- package/dist/project-I6NX3NFB.js +0 -41
- package/dist/source-PJBMDCKX.js +0 -41
package/dist/cli/index.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-
|
|
3
|
-
import { makeSourceCommand, syncProjectSources } from '../chunk-
|
|
4
|
-
import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportRelocked, REF_HINT, reportInstalledSoftDeps } from '../chunk-
|
|
2
|
+
import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-XDKH7XSA.js';
|
|
3
|
+
import { makeSourceCommand, syncProjectSources, divergedSourceClones } from '../chunk-WSBKB4CJ.js';
|
|
4
|
+
import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportReplaced, reportRelocked, reportMoved, REF_HINT, reportInstalledSoftDeps } from '../chunk-CJERAGFY.js';
|
|
5
5
|
import { createSpinner } from '../chunk-NESV47MF.js';
|
|
6
|
-
import { AI_RESOURCES } from '../chunk-
|
|
7
|
-
import { findAssetManifestFile, declaredVersion, readAssetBody,
|
|
8
|
-
import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, assetEntryRef, manifestVersionMismatchMessage
|
|
9
|
-
import { openCatalogSource, LocalCatalogDisabledError, openLibraryManager, openLibrary } from '../chunk-
|
|
10
|
-
import { logErr, S, logOk, logInfo, logWarn, TARGET_DEFAULT_HINT, deferredWarnings, warnLegacyClaudeCopies, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth, KIND_COL_WIDTH } from '../chunk-
|
|
11
|
-
import { getKindRegistry, getKnownKinds } from '../chunk-
|
|
6
|
+
import { AI_RESOURCES } from '../chunk-S3O3GKB7.js';
|
|
7
|
+
import { unresolvedManifestDependencies, warnIgnoredDomainFiles, warnLegacyBundleFiles, removedDomainOption, rejectRemovedDomainOption, resolveLibraryPublisherDetailed, warnLibraryNameFallback, indexLibrary, requireValidPublisherOrExit, exitOnManifestPublisherProblems, registerLibraryAsset, DOMAIN_REMOVED_HINT, manifestPublisherProblems, manifestRequiresProblems, findAssetManifestFile, declaredVersion, checkAssetFile, duplicateAssetMessage, readAssetBody, checkAsset, invalidSemverText } from '../chunk-YOH2L76X.js';
|
|
8
|
+
import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, assetEntryRef, manifestVersionMismatchMessage } from '../chunk-RYYLMBA2.js';
|
|
9
|
+
import { openCatalogSource, LocalCatalogDisabledError, openLibraryManager, openLibrary } from '../chunk-PQFHMQHQ.js';
|
|
10
|
+
import { logErr, S, logOk, logInfo, logWarn, TARGET_DEFAULT_HINT, requireProjectConfig, deferredWarnings, warnLegacyClaudeCopies, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth, KIND_COL_WIDTH } from '../chunk-GV4DZ6MT.js';
|
|
11
|
+
import { getKindRegistry, getKnownKinds } from '../chunk-CAHB6MHA.js';
|
|
12
12
|
import { LocalSecretsProvider } from '../chunk-ILFGVSTJ.js';
|
|
13
|
-
import { runAgentChat, isCompositionError, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, hashAgentFiles, createCompositionContentSource, compileComposition, instanceForSession, resolveAgentInstance, describeComposition, MarkdownStreamer } from '../chunk-
|
|
14
|
-
import { buildClaudePluginFiles } from '../chunk-
|
|
15
|
-
import '../chunk-
|
|
16
|
-
import '../chunk-
|
|
13
|
+
import { runAgentChat, isCompositionError, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, hashAgentFiles, createCompositionContentSource, compileComposition, instanceForSession, resolveAgentInstance, describeComposition, MarkdownStreamer } from '../chunk-VLTQGE2E.js';
|
|
14
|
+
import { buildClaudePluginFiles } from '../chunk-6O2X3GPW.js';
|
|
15
|
+
import '../chunk-IER3KIPH.js';
|
|
16
|
+
import '../chunk-QVFAS5IO.js';
|
|
17
17
|
import '../chunk-R6O6YWU7.js';
|
|
18
|
-
import '../chunk-
|
|
19
|
-
import '../chunk-
|
|
18
|
+
import '../chunk-G4FFOV3N.js';
|
|
19
|
+
import '../chunk-T42WRQ4O.js';
|
|
20
20
|
import '../chunk-4ZTPYIBE.js';
|
|
21
|
-
import '../chunk-
|
|
21
|
+
import '../chunk-MZG34MBZ.js';
|
|
22
22
|
import '../chunk-X5YPJV4N.js';
|
|
23
23
|
import '../chunk-O7SG5PC2.js';
|
|
24
24
|
import '../chunk-7QBNJTTQ.js';
|
|
@@ -26,77 +26,77 @@ import '../chunk-OBYKJB4U.js';
|
|
|
26
26
|
import '../chunk-5LKOAX7I.js';
|
|
27
27
|
import '../chunk-32NA4TVC.js';
|
|
28
28
|
import '../chunk-W3UDISS2.js';
|
|
29
|
-
import '../chunk-
|
|
30
|
-
import { runFlow, resumeFlow } from '../chunk-
|
|
29
|
+
import '../chunk-NWDSLXOX.js';
|
|
30
|
+
import { runFlow, resumeFlow } from '../chunk-3SM2DL2T.js';
|
|
31
31
|
import '../chunk-4R6DROGN.js';
|
|
32
|
-
import { validateFlowVersions
|
|
33
|
-
import '../chunk-
|
|
32
|
+
import { validateFlowVersions } from '../chunk-X77SUM4P.js';
|
|
33
|
+
import '../chunk-GCHPUTA3.js';
|
|
34
34
|
import '../chunk-ISHJITXJ.js';
|
|
35
|
-
import '../chunk-
|
|
35
|
+
import '../chunk-4A4OD24G.js';
|
|
36
36
|
import '../chunk-X4BAYGMT.js';
|
|
37
|
-
import '../chunk-
|
|
38
|
-
import '../chunk-
|
|
39
|
-
import '../chunk-
|
|
37
|
+
import '../chunk-R7NHYEJF.js';
|
|
38
|
+
import '../chunk-T7CTHHG7.js';
|
|
39
|
+
import '../chunk-HCEVNYSH.js';
|
|
40
40
|
import '../chunk-LOO5CB5M.js';
|
|
41
41
|
import '../chunk-2H73V6XR.js';
|
|
42
|
-
import '../chunk-
|
|
42
|
+
import '../chunk-M3B6EIJD.js';
|
|
43
43
|
import '../chunk-B4X2N7JQ.js';
|
|
44
44
|
import '../chunk-YROR332M.js';
|
|
45
|
-
import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-
|
|
45
|
+
import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-47U4GZ4M.js';
|
|
46
46
|
import '../chunk-6E6PKKAD.js';
|
|
47
47
|
import '../chunk-IFGTRL2I.js';
|
|
48
|
-
import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-
|
|
48
|
+
import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-TCHRMVTO.js';
|
|
49
49
|
import '../chunk-LNFKL23K.js';
|
|
50
|
-
import '../chunk-
|
|
50
|
+
import '../chunk-D3B36CYC.js';
|
|
51
51
|
import '../chunk-M3WPBTGJ.js';
|
|
52
52
|
import { nodeLabel, nodeSkillAsset, nodeIsInert, nodeIsOptional, nodeRunKind, flowSkillVersionPins } from '../chunk-7RGTAEG6.js';
|
|
53
53
|
import '../chunk-NUELZWCF.js';
|
|
54
54
|
import '../chunk-F4NJDSR7.js';
|
|
55
|
-
import { AssetManager, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-
|
|
56
|
-
import { cloneOrInitGitRepo, trackOriginBranch, stampManifestPublisher, ensureGitRepo, conflictingAssetRoot, setManifestPublisher, LIBRARY_OWNERSHIPS, isGitRepo, assertManifestEditable, installLibraryAsset, missingRootAssets, assertValidLibraryName,
|
|
57
|
-
import { parseManifestFile,
|
|
58
|
-
import '../chunk-
|
|
55
|
+
import { AssetManager, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-DZMNFCWB.js';
|
|
56
|
+
import { libraryDirMissing, missingLibraryDirMessage, cloneOrInitGitRepo, trackOriginBranch, stampManifestPublisher, ensureGitRepo, conflictingAssetRoot, setManifestPublisher, LIBRARY_OWNERSHIPS, isGitRepo, assertManifestEditable, installLibraryAsset, missingRootAssets, assertValidLibraryName, syncManifestWithDisk, getStoreManifestsDir, getDefaultValue, isSecretPlaceholder } from '../chunk-2F5AWQX5.js';
|
|
57
|
+
import { parseManifestFile, SEMVER_RE } from '../chunk-J4RBUFGM.js';
|
|
58
|
+
import '../chunk-COH6FQAG.js';
|
|
59
59
|
import '../chunk-R7FOF242.js';
|
|
60
60
|
import '../chunk-3TXEJN4W.js';
|
|
61
|
-
import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-
|
|
61
|
+
import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-FH7W6TJ4.js';
|
|
62
62
|
import '../chunk-CGYEHQOX.js';
|
|
63
63
|
import '../chunk-KTBKW2FI.js';
|
|
64
64
|
import '../chunk-UQ6LFBPZ.js';
|
|
65
|
-
import '../chunk-
|
|
66
|
-
import { effectiveComposes, validatePreset, composeSlotDiagnostics, agentDeprecationDiagnostics, validateAgent, SLOT_ID_PATTERN } from '../chunk-
|
|
67
|
-
import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, readLock, aiResourceRoots, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-
|
|
65
|
+
import '../chunk-HZXUXHIV.js';
|
|
66
|
+
import { effectiveComposes, validatePreset, composeSlotDiagnostics, agentDeprecationDiagnostics, validateAgent, SLOT_ID_PATTERN } from '../chunk-ZCAJZ4B2.js';
|
|
67
|
+
import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, readLock, aiResourceRoots, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-PBBPZYVG.js';
|
|
68
68
|
import '../chunk-4GY63JU6.js';
|
|
69
|
-
import { factoryAssetRoots } from '../chunk-
|
|
69
|
+
import { factoryAssetRoots } from '../chunk-EDYHEMJA.js';
|
|
70
70
|
import '../chunk-PMECEZK3.js';
|
|
71
71
|
import { DEFAULT_DRIVER_ID, DRIVER_DEFAULTS } from '../chunk-5BEFNLOR.js';
|
|
72
72
|
import { findKindDirs } from '../chunk-A2ULN3KX.js';
|
|
73
|
-
import { sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, resolveSkWorkspaceConfig, matchPin, coerceVersion, loadSkWorkspaceConfig, normalizeAgentInstances, agentInstanceDiagnostics, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-
|
|
73
|
+
import { SourceEntryError, sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, resolveSkWorkspaceConfig, matchPin, coerceVersion, loadSkWorkspaceConfig, normalizeAgentInstances, agentInstanceDiagnostics, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-ALEYHUC5.js';
|
|
74
74
|
import { globalCacheRoot, globalSkaileDir, userConfigPath } from '../chunk-L5VSIPQD.js';
|
|
75
75
|
import { SUPPORTED_DRIVER_TARGETS, driverTargetForDriver } from '../chunk-CPSIPIX7.js';
|
|
76
|
-
import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest, loadSkPublishManifest, encodeSkaileManifest } from '../chunk-
|
|
76
|
+
import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest, loadSkPublishManifest, encodeSkaileManifest } from '../chunk-ZPWTOUTK.js';
|
|
77
77
|
import { pluginTitle } from '../chunk-RVRB27AN.js';
|
|
78
|
-
import { parseFrontmatter, scanDirectory } from '../chunk-
|
|
79
|
-
import { parseAssetRef, isValidPublisher, PUBLISHER_HINT, isValidAssetName, ASSET_NAME_HINT, slugifyAssetName, parseAssetRefLoose, assetRefToStr } from '../chunk-
|
|
78
|
+
import { dedupeRequirements, parseFrontmatter, scanDirectory } from '../chunk-SBSA3IQA.js';
|
|
79
|
+
import { parseAssetRef, isValidPublisher, PUBLISHER_HINT, isValidAssetName, ASSET_NAME_HINT, slugifyAssetName, parseAssetRefLoose, assetRefToStr } from '../chunk-BNMZVPYA.js';
|
|
80
80
|
import { portableSpawn, portableSpawnSync } from '../chunk-ICSCSM5D.js';
|
|
81
|
-
import { openSqlite } from '../chunk-
|
|
81
|
+
import { openSqlite } from '../chunk-DALV4HHP.js';
|
|
82
82
|
import { parseModelRef, resolveEntryBaseUrl } from '../chunk-MJHSLODD.js';
|
|
83
83
|
import '../chunk-C3CAXQMA.js';
|
|
84
84
|
import '../chunk-BOFL7GIF.js';
|
|
85
85
|
import '../chunk-NSBPE2FW.js';
|
|
86
|
-
import * as
|
|
87
|
-
import
|
|
88
|
-
import * as
|
|
89
|
-
import
|
|
86
|
+
import * as fs8 from 'fs';
|
|
87
|
+
import fs8__default, { readFileSync, existsSync, mkdirSync, writeFileSync, lstatSync, rmSync, readdirSync, statSync } from 'fs';
|
|
88
|
+
import * as path18 from 'path';
|
|
89
|
+
import path18__default, { resolve, join } from 'path';
|
|
90
90
|
import { fileURLToPath } from 'url';
|
|
91
91
|
import { Help, Command, Option } from 'commander';
|
|
92
92
|
import { rcompare } from 'semver';
|
|
93
93
|
import * as p4 from '@clack/prompts';
|
|
94
94
|
import pc5 from 'picocolors';
|
|
95
|
-
import { parse, stringify, parseDocument, isMap, isScalar, isSeq } from 'yaml';
|
|
96
95
|
import * as os from 'os';
|
|
96
|
+
import { parse, stringify, parseDocument, isMap, isScalar, isSeq } from 'yaml';
|
|
97
97
|
import * as readline from 'readline';
|
|
98
98
|
import { createInterface } from 'readline';
|
|
99
|
-
import
|
|
99
|
+
import fs5 from 'fs/promises';
|
|
100
100
|
import { parse as parse$1, stringify as stringify$1 } from 'smol-toml';
|
|
101
101
|
import { execSync, spawnSync, execFileSync } from 'child_process';
|
|
102
102
|
import * as readline2 from 'readline/promises';
|
|
@@ -175,7 +175,7 @@ async function runSearch(kind, query, opts) {
|
|
|
175
175
|
const showLocal = !opts.store;
|
|
176
176
|
const showStore = !opts.local;
|
|
177
177
|
const { resolveConfig } = await import('../library/index.js');
|
|
178
|
-
const airGapped = resolveConfig({ projectDir:
|
|
178
|
+
const airGapped = resolveConfig({ projectDir: path18__default.resolve(opts.projectDir) }).catalog.cache_ttl === 0;
|
|
179
179
|
if (showLocal) {
|
|
180
180
|
await searchLocal(query, kind, opts, showStore, airGapped);
|
|
181
181
|
}
|
|
@@ -184,11 +184,14 @@ async function runSearch(kind, query, opts) {
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
async function searchIndex(query, kind) {
|
|
187
|
-
const { openLibrary: openLibrary2 } = await import('../open-library-
|
|
187
|
+
const { openLibrary: openLibrary2 } = await import('../open-library-BOSPJVID.js');
|
|
188
188
|
const library = await openLibrary2();
|
|
189
189
|
try {
|
|
190
|
-
const
|
|
191
|
-
const
|
|
190
|
+
const { libraryDirMissing: libraryDirMissing2 } = await import('../library/index.js');
|
|
191
|
+
const sources = await library.listSources();
|
|
192
|
+
const gone = new Set(sources.filter(libraryDirMissing2).map((l) => l.id));
|
|
193
|
+
const defs = (await library.listAssetDefs(kind ? { kind } : {})).filter((d) => !d.libraryId || !gone.has(d.libraryId));
|
|
194
|
+
const libraryNames = new Map(sources.map((l) => [l.id, l.name]));
|
|
192
195
|
let entries = defs.map(
|
|
193
196
|
(d) => ({
|
|
194
197
|
name: d.name,
|
|
@@ -218,7 +221,7 @@ async function searchIndex(query, kind) {
|
|
|
218
221
|
}
|
|
219
222
|
}
|
|
220
223
|
async function searchFactory(projectDir, query, kind) {
|
|
221
|
-
const prefixes = factoryAssetRoots().map((r) => r.endsWith(
|
|
224
|
+
const prefixes = factoryAssetRoots().map((r) => r.endsWith(path18__default.sep) ? r : r + path18__default.sep);
|
|
222
225
|
const isFactoryPath = (p6) => prefixes.some((fp) => p6 === fp.slice(0, -1) || p6.startsWith(fp));
|
|
223
226
|
try {
|
|
224
227
|
const entries = await new AssetManager({ registry: getKindRegistry(), projectDir }).search(
|
|
@@ -269,12 +272,70 @@ async function expandLibraryCopies(entries, projectDir) {
|
|
|
269
272
|
}
|
|
270
273
|
return out;
|
|
271
274
|
}
|
|
275
|
+
function originAtVersion(o) {
|
|
276
|
+
return `${describeOrigin(o)}${o.version ? ` v${o.version}` : ""}`;
|
|
277
|
+
}
|
|
278
|
+
async function competingOriginsOf(am2, target) {
|
|
279
|
+
let ref;
|
|
280
|
+
if (typeof target === "string") {
|
|
281
|
+
if (target.includes("#")) return void 0;
|
|
282
|
+
ref = target;
|
|
283
|
+
} else {
|
|
284
|
+
const publisher = (target.canonicalRef ? parseRefTolerant(target.canonicalRef)?.publisher : void 0) ?? target.publisher;
|
|
285
|
+
if (!publisher) return void 0;
|
|
286
|
+
ref = `${target.kind}:@${publisher}/${target.name}`;
|
|
287
|
+
}
|
|
288
|
+
try {
|
|
289
|
+
const origins = await am2.refOrigins(ref);
|
|
290
|
+
return new Set(origins.map((o) => o.version)).size > 1 ? origins : void 0;
|
|
291
|
+
} catch {
|
|
292
|
+
return void 0;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function describeOrigin(o) {
|
|
296
|
+
return o.kind === "factory" ? "factory" : `${o.kind} ${o.label}`;
|
|
297
|
+
}
|
|
298
|
+
async function expandCompetingOrigins(entries, projectDir) {
|
|
299
|
+
if (entries.length === 0) return entries;
|
|
300
|
+
let competing;
|
|
301
|
+
try {
|
|
302
|
+
competing = await new AssetManager({
|
|
303
|
+
registry: getKindRegistry(),
|
|
304
|
+
projectDir
|
|
305
|
+
}).competingOrigins();
|
|
306
|
+
} catch {
|
|
307
|
+
return entries;
|
|
308
|
+
}
|
|
309
|
+
if (competing.size === 0) return entries;
|
|
310
|
+
const out = [];
|
|
311
|
+
const expanded = /* @__PURE__ */ new Set();
|
|
312
|
+
for (const e of entries) {
|
|
313
|
+
const key = entryDedupKey(e);
|
|
314
|
+
const origins = competing.get(key);
|
|
315
|
+
if (!origins) {
|
|
316
|
+
out.push(e);
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
if (expanded.has(key)) continue;
|
|
320
|
+
expanded.add(key);
|
|
321
|
+
origins.forEach((o, i) => {
|
|
322
|
+
out.push({
|
|
323
|
+
...e,
|
|
324
|
+
version: o.version,
|
|
325
|
+
description: o.description || e.description,
|
|
326
|
+
library: describeOrigin(o),
|
|
327
|
+
usedByAdd: i === 0
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
return out;
|
|
332
|
+
}
|
|
272
333
|
async function searchLocal(query, kind, opts, showStore, airGapped) {
|
|
273
|
-
const projectDir =
|
|
334
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
274
335
|
const factory = await searchFactory(projectDir, query, kind);
|
|
275
336
|
let entries = unionEntries(await searchIndex(query, kind), factory);
|
|
276
337
|
if (entries.length === 0 && !query && !kind && !airGapped) {
|
|
277
|
-
const { autoSyncForSearch } = await import('../source-
|
|
338
|
+
const { autoSyncForSearch } = await import('../source-G2LV5LVD.js');
|
|
278
339
|
if (await autoSyncForSearch(projectDir)) {
|
|
279
340
|
entries = unionEntries(await searchIndex(query, kind), factory);
|
|
280
341
|
}
|
|
@@ -291,7 +352,9 @@ async function searchLocal(query, kind, opts, showStore, airGapped) {
|
|
|
291
352
|
console.log(`
|
|
292
353
|
${S.heading("Local:")}`);
|
|
293
354
|
}
|
|
294
|
-
printLocalEntries(
|
|
355
|
+
printLocalEntries(
|
|
356
|
+
await expandCompetingOrigins(await expandLibraryCopies(entries, projectDir), projectDir)
|
|
357
|
+
);
|
|
295
358
|
}
|
|
296
359
|
var MIN_LOCAL_DESCRIPTION_WIDTH = 10;
|
|
297
360
|
function layoutLocalTable(rows, width, style = {}) {
|
|
@@ -392,9 +455,9 @@ async function searchStore(query, kind, opts, airGapped) {
|
|
|
392
455
|
logInfo("air-gapped (cache_ttl: 0) \u2014 local sources only");
|
|
393
456
|
return;
|
|
394
457
|
}
|
|
395
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-
|
|
458
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-BOSPJVID.js');
|
|
396
459
|
try {
|
|
397
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
460
|
+
const remote = await openCatalogSource2({ projectDir: path18__default.resolve(opts.projectDir) });
|
|
398
461
|
const assets = await remote.listAssets(kind ? { kind } : {});
|
|
399
462
|
const results = filterCatalogAssets(assets, query);
|
|
400
463
|
if (results.length > 0) {
|
|
@@ -515,10 +578,11 @@ function makeAddCommand() {
|
|
|
515
578
|
process.exit(1);
|
|
516
579
|
}
|
|
517
580
|
const harnesses = parseHarnessFilter(opts.harness);
|
|
581
|
+
if (!opts.global && harnesses === void 0) requireProjectConfig(opts.projectDir);
|
|
518
582
|
const warnings = deferredWarnings();
|
|
519
583
|
const am2 = new AssetManager({
|
|
520
584
|
registry: getKindRegistry(),
|
|
521
|
-
projectDir:
|
|
585
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
522
586
|
global: opts.global || harnesses !== void 0,
|
|
523
587
|
harnesses,
|
|
524
588
|
driverTarget: opts.target,
|
|
@@ -529,11 +593,28 @@ function makeAddCommand() {
|
|
|
529
593
|
try {
|
|
530
594
|
const libraryOf = /* @__PURE__ */ new Map();
|
|
531
595
|
let presets = [];
|
|
596
|
+
const skippedLinks = /* @__PURE__ */ new Set();
|
|
597
|
+
const skippedEnv = /* @__PURE__ */ new Set();
|
|
532
598
|
const added = await am2.add(ref, {
|
|
533
599
|
link: opts.link,
|
|
534
600
|
onLibraryOrigin: (deployedRef, library) => libraryOf.set(deployedRef, library),
|
|
601
|
+
onLibraryMoved: (m) => warnings.push(`${m.ref} moved from ${m.from} to ${m.to}`),
|
|
535
602
|
onPresets: (expanded) => {
|
|
536
603
|
presets = expanded;
|
|
604
|
+
},
|
|
605
|
+
// One line per dropped link, however many harnesses the asset is deployed into.
|
|
606
|
+
onSkippedSymlink: (_assetRef, linkPath) => {
|
|
607
|
+
if (skippedLinks.has(linkPath)) return;
|
|
608
|
+
skippedLinks.add(linkPath);
|
|
609
|
+
warnings.push(`skipped symlink ${linkPath}`);
|
|
610
|
+
},
|
|
611
|
+
// A `.env` in an asset root is never deployed or hashed: say so once per file.
|
|
612
|
+
onEnvFile: (_assetRef, envPath) => {
|
|
613
|
+
if (skippedEnv.has(envPath)) return;
|
|
614
|
+
skippedEnv.add(envPath);
|
|
615
|
+
warnings.push(
|
|
616
|
+
`${envPath} is a .env file: it is not deployed or hashed with the asset. Keep secrets out of an asset root`
|
|
617
|
+
);
|
|
537
618
|
}
|
|
538
619
|
});
|
|
539
620
|
spinner.stop("Done");
|
|
@@ -564,6 +645,15 @@ function makeAddCommand() {
|
|
|
564
645
|
logOk(library ? `${a} (library ${library})` : a);
|
|
565
646
|
}
|
|
566
647
|
}
|
|
648
|
+
const addOrigins = await competingOriginsOf(am2, ref);
|
|
649
|
+
if (addOrigins) {
|
|
650
|
+
const [first, ...rest] = addOrigins;
|
|
651
|
+
logInfo(
|
|
652
|
+
S.dim(
|
|
653
|
+
`${ref} is held at different versions; used ${originAtVersion(first)} (also ${rest.map(originAtVersion).join(", ")})`
|
|
654
|
+
)
|
|
655
|
+
);
|
|
656
|
+
}
|
|
567
657
|
await reportPresetMembership(am2, ref, (line) => logInfo(S.dim(line)));
|
|
568
658
|
} catch (err2) {
|
|
569
659
|
spinner.stop("Failed");
|
|
@@ -577,23 +667,33 @@ function makeRemoveCommand() {
|
|
|
577
667
|
return new Command("remove").description("Remove from skaile.yaml + undeploy").argument("<ref>", "Asset reference (kind:@publisher/name, or kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Remove from ~/.skaile/skaile.yaml + undeploy from every global harness").option(
|
|
578
668
|
"--harness <ids>",
|
|
579
669
|
"Comma-separated global harnesses to undeploy from (default: all resolved); implies --global"
|
|
580
|
-
).option("--target <agent>", `Driver target (${TARGET_DEFAULT_HINT})`).option("--no-soft-deps", "skip the orphaned-soft-dep prompt (don't remove, don't report)").action(async (ref, opts) => {
|
|
670
|
+
).option("--target <agent>", `Driver target (${TARGET_DEFAULT_HINT})`).option("--force", "Remove even when another installed asset requires it").option("--no-soft-deps", "skip the orphaned-soft-dep prompt (don't remove, don't report)").action(async (ref, opts) => {
|
|
581
671
|
const harnesses = parseHarnessFilter(opts.harness);
|
|
672
|
+
if (!opts.global && harnesses === void 0)
|
|
673
|
+
requireProjectConfig(opts.projectDir, { allowMissing: true });
|
|
582
674
|
const am2 = new AssetManager({
|
|
583
675
|
registry: getKindRegistry(),
|
|
584
|
-
projectDir:
|
|
676
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
585
677
|
global: opts.global || harnesses !== void 0,
|
|
586
678
|
harnesses,
|
|
587
679
|
driverTarget: opts.target
|
|
588
680
|
});
|
|
589
681
|
let result;
|
|
590
682
|
try {
|
|
591
|
-
result = await am2.removeWithDependencies(ref);
|
|
683
|
+
result = await am2.removeWithDependencies(ref, { force: opts.force === true });
|
|
592
684
|
} catch (err2) {
|
|
593
685
|
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
594
686
|
process.exitCode = 1;
|
|
595
687
|
return;
|
|
596
688
|
}
|
|
689
|
+
if (result.blocked) {
|
|
690
|
+
logWarn(`${result.blocked.ref} is required by ${result.blocked.requiredBy.join(", ")}`);
|
|
691
|
+
logInfo(
|
|
692
|
+
`Nothing removed. Remove ${result.blocked.requiredBy.length === 1 ? "that asset" : "those assets"} first, or run \`skaile remove ${ref} --force\`.`
|
|
693
|
+
);
|
|
694
|
+
process.exitCode = 1;
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
597
697
|
if (!result.changed) {
|
|
598
698
|
logErr(`Not deployed or declared: ${ref}`);
|
|
599
699
|
process.exitCode = 1;
|
|
@@ -635,7 +735,7 @@ function makeListCommand() {
|
|
|
635
735
|
}
|
|
636
736
|
const am2 = new AssetManager({
|
|
637
737
|
registry: getKindRegistry(),
|
|
638
|
-
projectDir:
|
|
738
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
639
739
|
driverTarget: opts.target
|
|
640
740
|
});
|
|
641
741
|
let declared;
|
|
@@ -683,7 +783,7 @@ function makeListCommand() {
|
|
|
683
783
|
function runGlobalList(kind, opts, harnesses) {
|
|
684
784
|
const am2 = new AssetManager({
|
|
685
785
|
registry: getKindRegistry(),
|
|
686
|
-
projectDir:
|
|
786
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
687
787
|
global: true,
|
|
688
788
|
harnesses
|
|
689
789
|
});
|
|
@@ -756,7 +856,7 @@ async function resolveInfoEntry(am2, ref, opts) {
|
|
|
756
856
|
return { entry: match ?? deployed };
|
|
757
857
|
}
|
|
758
858
|
const lookup = opts.storeLookup ?? (async (filter) => {
|
|
759
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
859
|
+
const { resolveCatalogSource } = await import('../open-library-BOSPJVID.js');
|
|
760
860
|
const { source, close } = await resolveCatalogSource({ projectDir: opts.projectDir });
|
|
761
861
|
try {
|
|
762
862
|
return await source.listAssets(filter);
|
|
@@ -772,7 +872,7 @@ async function resolveInfoEntry(am2, ref, opts) {
|
|
|
772
872
|
);
|
|
773
873
|
return { entry: hit ? catalogAssetToEntry(hit) : null };
|
|
774
874
|
} catch (err2) {
|
|
775
|
-
const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-
|
|
875
|
+
const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-BOSPJVID.js');
|
|
776
876
|
const storeNote = err2 instanceof Error ? err2.message : String(err2);
|
|
777
877
|
const disabled = err2 instanceof LocalCatalogDisabledError2 || /catalog\.url/i.test(storeNote);
|
|
778
878
|
return { entry: null, storeNote, ...disabled ? { storeDisabled: true } : {} };
|
|
@@ -788,7 +888,7 @@ function infoNotFoundHint(ref, lookup) {
|
|
|
788
888
|
}
|
|
789
889
|
function makeInfoCommand() {
|
|
790
890
|
return new Command("info").description("Show asset metadata, deps, deploy status").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
791
|
-
const projectDir =
|
|
891
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
792
892
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
|
|
793
893
|
const lookup = await resolveInfoEntry(am2, ref, { projectDir });
|
|
794
894
|
const entry = lookup.entry;
|
|
@@ -805,9 +905,20 @@ function makeInfoCommand() {
|
|
|
805
905
|
if (entry.description) console.log(` description: ${entry.description}`);
|
|
806
906
|
if (entry.publisher) console.log(` repository: ${S.dim(entry.publisher)}`);
|
|
807
907
|
console.log(` source: ${S.dim(entry.source)}`);
|
|
808
|
-
|
|
908
|
+
const infoOrigins = await competingOriginsOf(am2, entry);
|
|
909
|
+
if (infoOrigins) {
|
|
910
|
+
const [first, ...rest] = infoOrigins;
|
|
911
|
+
console.log(
|
|
912
|
+
` origin: ${describeOrigin(first)} (used by add; also ${rest.map(originAtVersion).join(", ")})`
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
const ownPublisher = (entry.canonicalRef ? parseRefTolerant(entry.canonicalRef)?.publisher : void 0) ?? entry.publisher;
|
|
916
|
+
const requirements = dedupeRequirements(entry.requires, ownPublisher).map(
|
|
917
|
+
(d) => d.publisher || !ownPublisher ? d : { ...d, publisher: ownPublisher }
|
|
918
|
+
);
|
|
919
|
+
if (requirements.length) {
|
|
809
920
|
console.log(` requires:`);
|
|
810
|
-
for (const d of
|
|
921
|
+
for (const d of requirements) {
|
|
811
922
|
const scope = d.publisher ? `@${d.publisher}/` : "";
|
|
812
923
|
console.log(` ${S.dim("\xB7")} ${kindColor(d.kind)}:${scope}${d.name}`);
|
|
813
924
|
}
|
|
@@ -826,7 +937,7 @@ function makeCreateCommand() {
|
|
|
826
937
|
new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...SCAFFOLD_KINDS])
|
|
827
938
|
).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
|
|
828
939
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
|
|
829
|
-
const destDir = opts.dir ?
|
|
940
|
+
const destDir = opts.dir ? path18__default.resolve(opts.dir) : process.cwd();
|
|
830
941
|
const result = am2.create(name, opts.kind, destDir);
|
|
831
942
|
if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
|
|
832
943
|
else {
|
|
@@ -837,213 +948,56 @@ function makeCreateCommand() {
|
|
|
837
948
|
}
|
|
838
949
|
function makeDoctorCommand() {
|
|
839
950
|
return new Command("doctor").description("Scan for missing dependency chains").argument("[name]", "Check a specific asset (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (name, opts) => {
|
|
951
|
+
requireProjectConfig(opts.projectDir);
|
|
840
952
|
const am2 = new AssetManager({
|
|
841
953
|
registry: getKindRegistry(),
|
|
842
|
-
projectDir:
|
|
954
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
843
955
|
});
|
|
844
|
-
const
|
|
845
|
-
if (
|
|
956
|
+
const { gaps } = await am2.projectState();
|
|
957
|
+
if (gaps.length === 0) {
|
|
846
958
|
logOk("No missing dependencies.");
|
|
847
959
|
return;
|
|
848
960
|
}
|
|
849
|
-
|
|
850
|
-
const
|
|
851
|
-
|
|
852
|
-
logErr(
|
|
853
|
-
`${i.assetKind}:${i.assetName}: locked, but no source or library provides it \u2014 ${i.fix ?? "run skaile install"}`
|
|
854
|
-
);
|
|
855
|
-
}
|
|
961
|
+
process.exitCode = 1;
|
|
962
|
+
for (const g of gaps) if (g.type !== "requires") logErr(g.message);
|
|
963
|
+
const missing = gaps.filter((g) => g.type === "requires" && g.asset !== void 0);
|
|
856
964
|
if (missing.length === 0) return;
|
|
857
|
-
const assetW = Math.max(5, ...missing.map((
|
|
858
|
-
const depW = Math.max(11, ...missing.map((
|
|
965
|
+
const assetW = Math.max(5, ...missing.map((g) => (g.asset ?? "").length));
|
|
966
|
+
const depW = Math.max(11, ...missing.map((g) => g.ref.length));
|
|
859
967
|
console.log();
|
|
860
968
|
console.log(
|
|
861
969
|
` ${S.dim("ASSET".padEnd(assetW))} ${S.dim("MISSING DEP".padEnd(depW))} ${S.dim("IN REPOS")}`
|
|
862
970
|
);
|
|
863
971
|
console.log(` ${S.rule(assetW + depW + 15)}`);
|
|
864
|
-
for (const
|
|
865
|
-
const asset =
|
|
866
|
-
const
|
|
867
|
-
|
|
868
|
-
console.log(` ${asset.padEnd(assetW)} ${dep.padEnd(depW)} ${status4}`);
|
|
972
|
+
for (const g of missing) {
|
|
973
|
+
const asset = g.asset ?? "";
|
|
974
|
+
const status4 = g.manualFix ? S.err("not found") : S.warn("fixable");
|
|
975
|
+
console.log(` ${asset.padEnd(assetW)} ${g.ref.padEnd(depW)} ${status4}`);
|
|
869
976
|
}
|
|
870
977
|
console.log();
|
|
871
978
|
});
|
|
872
979
|
}
|
|
873
|
-
function manifestRequiresProblems(dir) {
|
|
874
|
-
const file = path23.join(dir, "skaile.manifest.yaml");
|
|
875
|
-
let doc;
|
|
876
|
-
try {
|
|
877
|
-
doc = parse(fs9.readFileSync(file, "utf-8"));
|
|
878
|
-
} catch {
|
|
879
|
-
return [];
|
|
880
|
-
}
|
|
881
|
-
const assets = doc?.assets;
|
|
882
|
-
if (!Array.isArray(assets)) return [];
|
|
883
|
-
const problems = [];
|
|
884
|
-
for (const a of assets) {
|
|
885
|
-
if (!a || typeof a !== "object") continue;
|
|
886
|
-
const { kind, name, dependencies } = a;
|
|
887
|
-
if (!Array.isArray(dependencies)) continue;
|
|
888
|
-
const entries = dependencies.map((d) => typeof d === "string" ? d : String(d));
|
|
889
|
-
for (const message of requiresSyntaxErrors(entries)) {
|
|
890
|
-
problems.push({
|
|
891
|
-
asset: `${String(kind)}:${String(name)}`,
|
|
892
|
-
message: `ManifestRequiresError: ${message}`
|
|
893
|
-
});
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
return problems;
|
|
897
|
-
}
|
|
898
|
-
async function indexLibrary(lib, index, opts = {}) {
|
|
899
|
-
const { LocalCatalogSource } = await import('../library/index.js');
|
|
900
|
-
const own = index ?? await openLibrary();
|
|
901
|
-
try {
|
|
902
|
-
const source = new LocalCatalogSource(own, lib.id, lib.path, getKindRegistry());
|
|
903
|
-
const res = await source.sync({ exclude: opts.exclude });
|
|
904
|
-
return {
|
|
905
|
-
assetsFound: res.assetsFound,
|
|
906
|
-
assetsUpdated: res.assetsUpdated,
|
|
907
|
-
errors: res.errors
|
|
908
|
-
};
|
|
909
|
-
} finally {
|
|
910
|
-
if (!index) own.close();
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
function resolveLibraryPublisherDetailed(lib, opts, storeIdentity) {
|
|
914
|
-
const bare = (p6) => p6.startsWith("@") ? p6.slice(1) : p6;
|
|
915
|
-
if (opts.publisher?.trim()) return { publisher: bare(opts.publisher.trim()), source: "flag" };
|
|
916
|
-
const declared = loadSkPublishManifest(lib.path)?.publisher?.trim();
|
|
917
|
-
if (declared) return { publisher: bare(declared), source: "manifest" };
|
|
918
|
-
const identity = (storeIdentity?.githubLogin ?? storeIdentity?.username)?.trim();
|
|
919
|
-
if (identity) return { publisher: identity, source: "identity" };
|
|
920
|
-
try {
|
|
921
|
-
return { publisher: slugifyAssetName(lib.name), source: "library-name" };
|
|
922
|
-
} catch {
|
|
923
|
-
return { publisher: "library", source: "library-name" };
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
function warnLibraryNameFallback(libName, resolved) {
|
|
927
|
-
if (resolved.source !== "library-name") return;
|
|
928
|
-
logWarn(
|
|
929
|
-
`No publisher given and not signed in \u2014 using the library name "${resolved.publisher}" as the publisher. Pass --publisher <name> or run \`skaile store login\`; change it later with \`skaile library set ${libName} publisher=<name>\`.`
|
|
930
|
-
);
|
|
931
|
-
}
|
|
932
|
-
function normalizeAssetFrontmatter(assetDir) {
|
|
933
|
-
let markerFile = ["SKILL.md", "AGENT.md", "CONTRACT.md"].map((m) => path23.join(assetDir, m)).find((f) => fs9.existsSync(f));
|
|
934
|
-
if (!markerFile) {
|
|
935
|
-
const promptMd = fs9.readdirSync(assetDir).find((f) => f.endsWith(".prompt.md"));
|
|
936
|
-
if (promptMd) markerFile = path23.join(assetDir, promptMd);
|
|
937
|
-
}
|
|
938
|
-
if (!markerFile) return;
|
|
939
|
-
try {
|
|
940
|
-
const { data, body } = parseFrontmatter(fs9.readFileSync(markerFile, "utf8"));
|
|
941
|
-
const fm = stringify(data).trimEnd();
|
|
942
|
-
fs9.writeFileSync(markerFile, `---
|
|
943
|
-
${fm}
|
|
944
|
-
---
|
|
945
|
-
|
|
946
|
-
${body}
|
|
947
|
-
`, "utf8");
|
|
948
|
-
} catch {
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
async function registerLibraryAsset(lib, index, input) {
|
|
952
|
-
const { publisher, source } = resolveLibraryPublisherDetailed(
|
|
953
|
-
lib,
|
|
954
|
-
{ publisher: input.publisher },
|
|
955
|
-
getStoreIdentity()
|
|
956
|
-
);
|
|
957
|
-
warnLibraryNameFallback(lib.name, { publisher, source });
|
|
958
|
-
normalizeAssetFrontmatter(input.assetDir);
|
|
959
|
-
stampManifestPublisher(lib.path, publisher);
|
|
960
|
-
upsertManifestAsset(lib.path, {
|
|
961
|
-
kind: input.kind,
|
|
962
|
-
name: input.name,
|
|
963
|
-
root: path23.relative(lib.path, input.assetDir) || input.name,
|
|
964
|
-
version: input.version,
|
|
965
|
-
publisher
|
|
966
|
-
});
|
|
967
|
-
const idx = await indexLibrary(lib, index);
|
|
968
|
-
for (const e of idx.errors) logWarn(e);
|
|
969
|
-
return { publisher, ref: refFor(input.kind, publisher, input.name, input.version) };
|
|
970
|
-
}
|
|
971
|
-
var LIBRARY_UPGRADE_DOCS = "https://github.com/skaile-ai/workspaces/blob/main/docs/sections/cli/commands/library.md#upgrading-a-4x-library";
|
|
972
|
-
var DOMAIN_REMOVED_HINT = `Domains were removed in 5.0 \u2014 delete DOMAIN.md files; group assets with .claude-plugin/marketplace.json. See ${LIBRARY_UPGRADE_DOCS}`;
|
|
973
|
-
function removedDomainOption() {
|
|
974
|
-
return new Option("--domain <domain>", "Removed in 5.0").hideHelp();
|
|
975
|
-
}
|
|
976
|
-
function rejectRemovedDomainOption(opts) {
|
|
977
|
-
if (opts.domain === void 0) return;
|
|
978
|
-
logErr(DOMAIN_REMOVED_HINT);
|
|
979
|
-
process.exit(1);
|
|
980
|
-
}
|
|
981
|
-
function findFiles(root, match) {
|
|
982
|
-
const found = [];
|
|
983
|
-
const walk = (dir) => {
|
|
984
|
-
let entries;
|
|
985
|
-
try {
|
|
986
|
-
entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
987
|
-
} catch {
|
|
988
|
-
return;
|
|
989
|
-
}
|
|
990
|
-
for (const entry of entries) {
|
|
991
|
-
if (entry.isDirectory()) {
|
|
992
|
-
if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
993
|
-
walk(path23.join(dir, entry.name));
|
|
994
|
-
}
|
|
995
|
-
} else if (match(entry.name)) {
|
|
996
|
-
found.push(path23.join(dir, entry.name));
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
};
|
|
1000
|
-
walk(root);
|
|
1001
|
-
return found;
|
|
1002
|
-
}
|
|
1003
|
-
function countDomainFiles(root) {
|
|
1004
|
-
return findFiles(root, (name) => name === "DOMAIN.md").length;
|
|
1005
|
-
}
|
|
1006
|
-
function warnIgnoredDomainFiles(root) {
|
|
1007
|
-
const count = countDomainFiles(root);
|
|
1008
|
-
if (count > 0) {
|
|
1009
|
-
logWarn(
|
|
1010
|
-
`${count} DOMAIN.md file(s) are ignored since 5.0 (domains were removed) \u2014 delete them; group assets with .claude-plugin/marketplace.json. See ${LIBRARY_UPGRADE_DOCS}`
|
|
1011
|
-
);
|
|
1012
|
-
}
|
|
1013
|
-
return count;
|
|
1014
|
-
}
|
|
1015
|
-
function warnLegacyBundleFiles(root) {
|
|
1016
|
-
const files = findFiles(root, (name) => name.endsWith(".bundle.yaml"));
|
|
1017
|
-
if (files.length > 0) {
|
|
1018
|
-
const shown = files.slice(0, 5).map((f) => path23.relative(root, f) || f);
|
|
1019
|
-
const more = files.length > shown.length ? `, +${files.length - shown.length} more` : "";
|
|
1020
|
-
logWarn(
|
|
1021
|
-
`${files.length} *.bundle.yaml file(s) are not scanned (the bundle kind became preset): ${shown.join(", ")}${more}. Run \`skaile migrate assets ${root} --write\` to rename them to *.preset.yaml. See ${LIBRARY_UPGRADE_DOCS}`
|
|
1022
|
-
);
|
|
1023
|
-
}
|
|
1024
|
-
return files.length;
|
|
1025
|
-
}
|
|
1026
980
|
var DEFAULT_IMPORT_VERSION = "0.1.0";
|
|
1027
981
|
var DEFAULT_IMPORT_STAGE = "alpha";
|
|
1028
982
|
function claudeSkillRoots() {
|
|
1029
983
|
const roots = [];
|
|
1030
984
|
const override = process.env.SKAILE_CLAUDE_SKILLS_DIR;
|
|
1031
985
|
if (override) roots.push(override);
|
|
1032
|
-
roots.push(
|
|
986
|
+
roots.push(path18.join(os.homedir(), ".claude", "skills"));
|
|
1033
987
|
return roots;
|
|
1034
988
|
}
|
|
1035
989
|
function resolveImportSource(nameOrPath) {
|
|
1036
|
-
const asPath =
|
|
1037
|
-
if (
|
|
1038
|
-
const dir =
|
|
1039
|
-
const skillFile =
|
|
1040
|
-
if (
|
|
990
|
+
const asPath = path18.resolve(nameOrPath);
|
|
991
|
+
if (fs8.existsSync(asPath)) {
|
|
992
|
+
const dir = fs8.statSync(asPath).isDirectory() ? asPath : path18.dirname(asPath);
|
|
993
|
+
const skillFile = path18.join(dir, "SKILL.md");
|
|
994
|
+
if (fs8.existsSync(skillFile)) return { dir, skillFile, via: "path" };
|
|
1041
995
|
}
|
|
1042
|
-
if (!nameOrPath.includes(
|
|
996
|
+
if (!nameOrPath.includes(path18.sep) && !nameOrPath.startsWith(".")) {
|
|
1043
997
|
for (const root of claudeSkillRoots()) {
|
|
1044
|
-
const dir =
|
|
1045
|
-
const skillFile =
|
|
1046
|
-
if (
|
|
998
|
+
const dir = path18.join(root, nameOrPath);
|
|
999
|
+
const skillFile = path18.join(dir, "SKILL.md");
|
|
1000
|
+
if (fs8.existsSync(skillFile)) return { dir, skillFile, via: "claude-skills" };
|
|
1047
1001
|
}
|
|
1048
1002
|
}
|
|
1049
1003
|
return null;
|
|
@@ -1139,13 +1093,7 @@ function makeAssetCommand() {
|
|
|
1139
1093
|
).option("--commit", "Auto-commit in git-backed libraries", false).action(
|
|
1140
1094
|
async (nameOrPath, opts) => {
|
|
1141
1095
|
rejectRemovedDomainOption(opts);
|
|
1142
|
-
if (opts.publisher !== void 0)
|
|
1143
|
-
const bare = opts.publisher.trim().replace(/^@/, "");
|
|
1144
|
-
if (!isValidPublisher(bare)) {
|
|
1145
|
-
logErr(`Invalid publisher "${opts.publisher}": ${PUBLISHER_HINT}.`);
|
|
1146
|
-
process.exit(1);
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1096
|
+
if (opts.publisher !== void 0) requireValidPublisherOrExit(opts.publisher);
|
|
1149
1097
|
const src = resolveImportSource(nameOrPath);
|
|
1150
1098
|
if (!src) {
|
|
1151
1099
|
logErr(
|
|
@@ -1175,19 +1123,20 @@ function makeAssetCommand() {
|
|
|
1175
1123
|
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
1176
1124
|
process.exit(1);
|
|
1177
1125
|
}
|
|
1178
|
-
|
|
1126
|
+
exitOnManifestPublisherProblems(target.path, target.name);
|
|
1127
|
+
const rawSkill = fs8.readFileSync(src.skillFile, "utf8");
|
|
1179
1128
|
const norm = opts.normalize ? normalizeSkillContent(rawSkill, {
|
|
1180
|
-
fallbackName:
|
|
1129
|
+
fallbackName: path18.basename(src.dir),
|
|
1181
1130
|
version: opts.version,
|
|
1182
1131
|
stage: opts.stage
|
|
1183
|
-
}) : { content: rawSkill, name:
|
|
1132
|
+
}) : { content: rawSkill, name: path18.basename(src.dir), changed: false, notes: [] };
|
|
1184
1133
|
if (!opts.normalize && !isValidAssetName(norm.name)) {
|
|
1185
1134
|
logWarn(
|
|
1186
1135
|
`Name "${norm.name}" is not canonical (kebab-case); \`skaile validate\` will reject this manifest entry. Drop --no-normalize to slugify it.`
|
|
1187
1136
|
);
|
|
1188
1137
|
}
|
|
1189
|
-
const destDir =
|
|
1190
|
-
if (
|
|
1138
|
+
const destDir = path18.join(target.path, norm.name);
|
|
1139
|
+
if (fs8.existsSync(destDir)) {
|
|
1191
1140
|
logErr(`Destination already exists: ${destDir}`);
|
|
1192
1141
|
process.exit(1);
|
|
1193
1142
|
}
|
|
@@ -1198,8 +1147,8 @@ function makeAssetCommand() {
|
|
|
1198
1147
|
);
|
|
1199
1148
|
process.exit(1);
|
|
1200
1149
|
}
|
|
1201
|
-
|
|
1202
|
-
|
|
1150
|
+
fs8.cpSync(src.dir, destDir, { recursive: true });
|
|
1151
|
+
fs8.writeFileSync(path18.join(destDir, "SKILL.md"), norm.content, "utf8");
|
|
1203
1152
|
for (const note of norm.notes) logInfo(` \u2022 ${note}`);
|
|
1204
1153
|
const fm = parseFrontmatter(norm.content).data;
|
|
1205
1154
|
for (const f of checkAgentSkillConformance(fm, { dirName: norm.name })) {
|
|
@@ -1239,7 +1188,7 @@ function makeAssetCommand() {
|
|
|
1239
1188
|
logErr(`Invalid --mode "${opts.mode}". Expected: copy | move | link.`);
|
|
1240
1189
|
process.exit(1);
|
|
1241
1190
|
}
|
|
1242
|
-
if (!
|
|
1191
|
+
if (!fs8.existsSync(srcPath)) {
|
|
1243
1192
|
logErr(`Source path does not exist: ${srcPath}`);
|
|
1244
1193
|
process.exit(1);
|
|
1245
1194
|
}
|
|
@@ -1265,23 +1214,23 @@ function makeAssetCommand() {
|
|
|
1265
1214
|
);
|
|
1266
1215
|
process.exit(1);
|
|
1267
1216
|
}
|
|
1268
|
-
const basename3 =
|
|
1217
|
+
const basename3 = path18.basename(srcPath);
|
|
1269
1218
|
const destDir = target.path;
|
|
1270
|
-
|
|
1271
|
-
const destPath =
|
|
1272
|
-
if (
|
|
1219
|
+
fs8.mkdirSync(destDir, { recursive: true });
|
|
1220
|
+
const destPath = path18.join(destDir, basename3);
|
|
1221
|
+
if (fs8.existsSync(destPath)) {
|
|
1273
1222
|
logErr(`Destination already exists: ${destPath}`);
|
|
1274
1223
|
process.exit(1);
|
|
1275
1224
|
}
|
|
1276
1225
|
switch (opts.mode) {
|
|
1277
1226
|
case "copy":
|
|
1278
|
-
|
|
1227
|
+
fs8.cpSync(srcPath, destPath, { recursive: true });
|
|
1279
1228
|
break;
|
|
1280
1229
|
case "move":
|
|
1281
|
-
|
|
1230
|
+
fs8.renameSync(srcPath, destPath);
|
|
1282
1231
|
break;
|
|
1283
1232
|
case "link":
|
|
1284
|
-
|
|
1233
|
+
fs8.symlinkSync(path18.resolve(srcPath), destPath);
|
|
1285
1234
|
break;
|
|
1286
1235
|
}
|
|
1287
1236
|
if (target.backend === "git" && opts.commit) {
|
|
@@ -1411,14 +1360,14 @@ function makeAuthCommand() {
|
|
|
1411
1360
|
}
|
|
1412
1361
|
function collectCacheTargets(scope) {
|
|
1413
1362
|
const out = [];
|
|
1414
|
-
out.push(
|
|
1415
|
-
out.push(
|
|
1416
|
-
out.push(
|
|
1363
|
+
out.push(path18__default.join(scope.projectDir, ".skaile", "cache"));
|
|
1364
|
+
out.push(path18__default.join(scope.projectDir, ".skaile", "store-cache"));
|
|
1365
|
+
out.push(path18__default.join(scope.projectDir, ".skaile", "repos"));
|
|
1417
1366
|
if (scope.global) {
|
|
1418
1367
|
out.push(globalCacheRoot());
|
|
1419
1368
|
const home = globalSkaileDir();
|
|
1420
|
-
out.push(
|
|
1421
|
-
out.push(
|
|
1369
|
+
out.push(path18__default.join(home, "repos"));
|
|
1370
|
+
out.push(path18__default.join(home, "catalog-cache"));
|
|
1422
1371
|
}
|
|
1423
1372
|
return out;
|
|
1424
1373
|
}
|
|
@@ -1432,7 +1381,7 @@ function dirSize(target) {
|
|
|
1432
1381
|
function dirSizeOfDir(dir) {
|
|
1433
1382
|
let total = 0;
|
|
1434
1383
|
for (const ent of readdirSync(dir, { withFileTypes: true })) {
|
|
1435
|
-
const child =
|
|
1384
|
+
const child = path18__default.join(dir, ent.name);
|
|
1436
1385
|
if (ent.isSymbolicLink()) continue;
|
|
1437
1386
|
if (ent.isDirectory()) total += dirSizeOfDir(child);
|
|
1438
1387
|
else if (ent.isFile()) total += statSync(child).size;
|
|
@@ -1458,7 +1407,7 @@ function makeCacheCommand() {
|
|
|
1458
1407
|
const cmd = new Command("cache").description("Inspect and reclaim the re-derivable cache");
|
|
1459
1408
|
cmd.command("clean").description("Remove the project cache (.skaile/cache); --global also clears ~/.skaile/cache").option("--global", "Also clear the global cache (sources + catalog) and legacy dirs").option("--dry-run", "Show what would be removed without doing it").option("-y, --yes", "Skip confirmation prompt").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
1460
1409
|
const targets = collectCacheTargets({
|
|
1461
|
-
projectDir:
|
|
1410
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
1462
1411
|
global: opts.global
|
|
1463
1412
|
}).filter((t) => existsSync(t));
|
|
1464
1413
|
if (targets.length === 0) {
|
|
@@ -1488,12 +1437,12 @@ function makeCacheCommand() {
|
|
|
1488
1437
|
for (const r of removed) logOk(`Removed ${r}`);
|
|
1489
1438
|
});
|
|
1490
1439
|
cmd.command("dir").description("Print the resolved cache roots").option("--global", "Include the global cache root").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
1491
|
-
console.log(
|
|
1440
|
+
console.log(path18__default.join(path18__default.resolve(opts.projectDir), ".skaile", "cache"));
|
|
1492
1441
|
if (opts.global) console.log(globalCacheRoot());
|
|
1493
1442
|
});
|
|
1494
1443
|
cmd.command("size").description("Show cache disk usage per directory").option("--global", "Include the global cache").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
1495
1444
|
const targets = collectCacheTargets({
|
|
1496
|
-
projectDir:
|
|
1445
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
1497
1446
|
global: opts.global
|
|
1498
1447
|
});
|
|
1499
1448
|
console.log();
|
|
@@ -1509,7 +1458,7 @@ function makeCatalogCommand() {
|
|
|
1509
1458
|
const catalog = new Command("catalog").description("Catalog source health and configuration");
|
|
1510
1459
|
catalog.command("test").description("Probe the configured catalog source and report status").option("--project-dir <path>", "Project directory (for project-level config overlay)").option("--url <url>", "Override the catalog URL for this probe").option("--force", "Probe the network even in air-gapped mode (cache_ttl: 0)").action(async (opts) => {
|
|
1511
1460
|
const { resolveConfig, isLocalCatalogUrl, trpcGetUrl } = await import('../library/index.js');
|
|
1512
|
-
const projectDir = opts.projectDir ?
|
|
1461
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : void 0;
|
|
1513
1462
|
const cfg = resolveConfig({ projectDir });
|
|
1514
1463
|
const baseUrl = opts.url ?? cfg.catalog.url;
|
|
1515
1464
|
if (isLocalCatalogUrl(baseUrl)) {
|
|
@@ -1527,7 +1476,7 @@ function makeCatalogCommand() {
|
|
|
1527
1476
|
});
|
|
1528
1477
|
catalog.command("info").description("Print the resolved catalog configuration (url, framing, cacheTtlMs)").option("--project-dir <path>", "Project directory (for project-level config overlay)").action(async (opts) => {
|
|
1529
1478
|
const { resolveConfig } = await import('../library/index.js');
|
|
1530
|
-
const projectDir = opts.projectDir ?
|
|
1479
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : void 0;
|
|
1531
1480
|
const cfg = resolveConfig({ projectDir });
|
|
1532
1481
|
console.log(`url: ${cfg.catalog.url}`);
|
|
1533
1482
|
console.log(`framing: ${cfg.catalog.framing}`);
|
|
@@ -1536,7 +1485,7 @@ function makeCatalogCommand() {
|
|
|
1536
1485
|
return catalog;
|
|
1537
1486
|
}
|
|
1538
1487
|
async function runLocalCatalogTest(projectDir) {
|
|
1539
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
1488
|
+
const { resolveCatalogSource } = await import('../open-library-BOSPJVID.js');
|
|
1540
1489
|
let resolved;
|
|
1541
1490
|
try {
|
|
1542
1491
|
resolved = await resolveCatalogSource({ projectDir });
|
|
@@ -1679,7 +1628,7 @@ async function scanLibraryFlowEntries() {
|
|
|
1679
1628
|
const { LocalIndex, resolveIndexPath, scanAuthoringLibraries } = await import('../library/index.js');
|
|
1680
1629
|
const indexPath = resolveIndexPath();
|
|
1681
1630
|
if (!existsSync(indexPath)) return entries;
|
|
1682
|
-
const { getKindRegistry: getKindRegistry2 } = await import('../open-registry-
|
|
1631
|
+
const { getKindRegistry: getKindRegistry2 } = await import('../open-registry-4FI7HKET.js');
|
|
1683
1632
|
const index = new LocalIndex({ indexPath });
|
|
1684
1633
|
try {
|
|
1685
1634
|
for (const { assets } of await scanAuthoringLibraries(index, getKindRegistry2())) {
|
|
@@ -1729,11 +1678,11 @@ function findSkills() {
|
|
|
1729
1678
|
return deduped;
|
|
1730
1679
|
}
|
|
1731
1680
|
function walkSkills(dir, out) {
|
|
1732
|
-
for (const entry of
|
|
1733
|
-
const full =
|
|
1681
|
+
for (const entry of fs8__default.readdirSync(dir, { withFileTypes: true })) {
|
|
1682
|
+
const full = path18__default.join(dir, entry.name);
|
|
1734
1683
|
if (entry.isDirectory()) {
|
|
1735
|
-
const skillMd =
|
|
1736
|
-
if (
|
|
1684
|
+
const skillMd = path18__default.join(full, "SKILL.md");
|
|
1685
|
+
if (fs8__default.existsSync(skillMd)) {
|
|
1737
1686
|
out.push({ name: entry.name, path: full, skillPath: skillMd });
|
|
1738
1687
|
} else {
|
|
1739
1688
|
walkSkills(full, out);
|
|
@@ -1754,10 +1703,10 @@ function resolveFlowIds() {
|
|
|
1754
1703
|
}
|
|
1755
1704
|
}
|
|
1756
1705
|
function resolveSessionIds(projectDir) {
|
|
1757
|
-
const sessionsDir =
|
|
1758
|
-
if (!
|
|
1706
|
+
const sessionsDir = path18__default.join(projectDir, ".skaile", "sessions");
|
|
1707
|
+
if (!fs8__default.existsSync(sessionsDir)) return [];
|
|
1759
1708
|
try {
|
|
1760
|
-
return
|
|
1709
|
+
return fs8__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
1761
1710
|
} catch {
|
|
1762
1711
|
return [];
|
|
1763
1712
|
}
|
|
@@ -1896,7 +1845,7 @@ function printResolvedPathsSection(config) {
|
|
|
1896
1845
|
console.log(` ${S.label("prompts:".padEnd(16))} ${config.promptsDir ?? paths.promptsDir}`);
|
|
1897
1846
|
}
|
|
1898
1847
|
async function showConfig(opts) {
|
|
1899
|
-
const projectDir = opts.projectDir ?
|
|
1848
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
|
|
1900
1849
|
let config;
|
|
1901
1850
|
let wsDefaults;
|
|
1902
1851
|
try {
|
|
@@ -1941,13 +1890,13 @@ function makeConfigCommand() {
|
|
|
1941
1890
|
const cmd = new Command("config").description("Manage personal config (.skaile/settings.json)");
|
|
1942
1891
|
cmd.command("show").description("Show effective config with sources").option("--project-dir <path>", "Project directory").action((opts) => showConfig(opts));
|
|
1943
1892
|
cmd.command("get <key>").description("Get an effective config value").option("--project-dir <path>", "Project directory").action(async (key, opts) => {
|
|
1944
|
-
const projectDir = opts.projectDir ?
|
|
1893
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
|
|
1945
1894
|
const config = await resolveSettings(projectDir);
|
|
1946
1895
|
const value = config[key];
|
|
1947
1896
|
console.log(value ?? S.dim("(not set)"));
|
|
1948
1897
|
});
|
|
1949
1898
|
cmd.command("set <key> <value>").description("Set a personal config value (driver, model, apiKey.<provider>)").option("--project-dir <path>", "Project directory").option("--global", "Write to ~/.skaile/settings.json instead of project-local").action(async (key, value, opts) => {
|
|
1950
|
-
const projectDir = opts.projectDir ?
|
|
1899
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
|
|
1951
1900
|
if (key === "provider" || key === "cloud" || key === "cloudConfig") {
|
|
1952
1901
|
logErr(
|
|
1953
1902
|
`'${key}' is no longer a setting \u2014 an endpoint is an AI provider registry entry and a session selects one with a model reference.
|
|
@@ -2287,8 +2236,8 @@ function makeConnectorCommand() {
|
|
|
2287
2236
|
async (driver, opts) => {
|
|
2288
2237
|
const { installNpmPackages } = await import('../connectors/index.js');
|
|
2289
2238
|
const { scanDirectory: scanDirectory2, factoryAssetRoots: factoryAssetRoots2, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
2290
|
-
const projectDir =
|
|
2291
|
-
const yamlPath =
|
|
2239
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2240
|
+
const yamlPath = path18__default.join(projectDir, "skaile.yaml");
|
|
2292
2241
|
if (!existsSync(yamlPath)) {
|
|
2293
2242
|
logErr("No skaile.yaml found in current directory. Run 'skaile init' first.");
|
|
2294
2243
|
process.exit(1);
|
|
@@ -2348,8 +2297,8 @@ ${installResult.output}`);
|
|
|
2348
2297
|
);
|
|
2349
2298
|
cmd.command("remove <id>").option("--project-dir <path>", "Workspace directory", process.cwd()).description("Remove a connector from skaile.yaml by its instance ID").action(async (id, opts) => {
|
|
2350
2299
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
2351
|
-
const projectDir =
|
|
2352
|
-
const yamlPath =
|
|
2300
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2301
|
+
const yamlPath = path18__default.join(projectDir, "skaile.yaml");
|
|
2353
2302
|
if (!existsSync(yamlPath)) {
|
|
2354
2303
|
logErr("No skaile.yaml found in current directory.");
|
|
2355
2304
|
process.exit(1);
|
|
@@ -2366,7 +2315,7 @@ ${installResult.output}`);
|
|
|
2366
2315
|
cmd.command("status [id]").option("--project-dir <path>", "Workspace directory", process.cwd()).description("Connect and report health status for one or all connectors").action(async (id, opts) => {
|
|
2367
2316
|
const res = await import('../connectors/index.js');
|
|
2368
2317
|
res.registerBuiltinConnectors();
|
|
2369
|
-
const projectDir =
|
|
2318
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2370
2319
|
const declarations = res.loadConnectorDeclarations(projectDir);
|
|
2371
2320
|
if (declarations.length === 0) {
|
|
2372
2321
|
console.log("No connectors configured in skaile.yaml.");
|
|
@@ -2390,7 +2339,7 @@ ${installResult.output}`);
|
|
|
2390
2339
|
await manager.disconnectAll();
|
|
2391
2340
|
});
|
|
2392
2341
|
cmd.command("list").description("List all configured connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
2393
|
-
const projectDir =
|
|
2342
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2394
2343
|
const manager = await connectConnectors(projectDir);
|
|
2395
2344
|
try {
|
|
2396
2345
|
console.log(JSON.stringify(manager.listConnectors(), null, 2));
|
|
@@ -2399,7 +2348,7 @@ ${installResult.output}`);
|
|
|
2399
2348
|
}
|
|
2400
2349
|
});
|
|
2401
2350
|
cmd.command("sync [id]").description("Re-sync a filesystem-face connector or all of them (git pull, S3 refresh, etc.)").option("--all", "Sync all connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
|
|
2402
|
-
const projectDir =
|
|
2351
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2403
2352
|
const manager = await connectConnectors(projectDir);
|
|
2404
2353
|
try {
|
|
2405
2354
|
if (opts.all) {
|
|
@@ -2423,7 +2372,7 @@ ${installResult.output}`);
|
|
|
2423
2372
|
}
|
|
2424
2373
|
});
|
|
2425
2374
|
cmd.command("ops <id>").description("List available operations for a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
|
|
2426
|
-
const projectDir =
|
|
2375
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2427
2376
|
const manager = await connectConnectors(projectDir);
|
|
2428
2377
|
try {
|
|
2429
2378
|
if (!manager.has(id)) {
|
|
@@ -2438,7 +2387,7 @@ ${installResult.output}`);
|
|
|
2438
2387
|
}
|
|
2439
2388
|
});
|
|
2440
2389
|
cmd.command("read <id> <resource-path>").description("Read content from a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, opts) => {
|
|
2441
|
-
const projectDir =
|
|
2390
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2442
2391
|
const manager = await connectConnectors(projectDir);
|
|
2443
2392
|
try {
|
|
2444
2393
|
const content = await manager.read(id, resourcePath);
|
|
@@ -2448,7 +2397,7 @@ ${installResult.output}`);
|
|
|
2448
2397
|
}
|
|
2449
2398
|
});
|
|
2450
2399
|
cmd.command("write <id> <resource-path> <content>").description("Write content to a connector at a path").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, content, opts) => {
|
|
2451
|
-
const projectDir =
|
|
2400
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2452
2401
|
const manager = await connectConnectors(projectDir);
|
|
2453
2402
|
try {
|
|
2454
2403
|
await manager.write(id, resourcePath, { data: content });
|
|
@@ -2458,7 +2407,7 @@ ${installResult.output}`);
|
|
|
2458
2407
|
}
|
|
2459
2408
|
});
|
|
2460
2409
|
cmd.command("entries <id> [resource-path]").description("List entries in a connector (files, keys, rows, etc)").option("--project-dir <path>", "Workspace directory", process.cwd()).option("--recursive", "Include nested entries").option("--limit <n>", "Maximum entries to return", parsePositiveIntOption).action(async (id, resourcePath, opts) => {
|
|
2461
|
-
const projectDir =
|
|
2410
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2462
2411
|
const manager = await connectConnectors(projectDir);
|
|
2463
2412
|
try {
|
|
2464
2413
|
const entries = await manager.list(id, resourcePath, {
|
|
@@ -2471,7 +2420,7 @@ ${installResult.output}`);
|
|
|
2471
2420
|
}
|
|
2472
2421
|
});
|
|
2473
2422
|
cmd.command("search <id> <query>").description("Search within a connector for matching content").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, query, opts) => {
|
|
2474
|
-
const projectDir =
|
|
2423
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2475
2424
|
const manager = await connectConnectors(projectDir);
|
|
2476
2425
|
try {
|
|
2477
2426
|
const results = await manager.search(id, query);
|
|
@@ -2481,7 +2430,7 @@ ${installResult.output}`);
|
|
|
2481
2430
|
}
|
|
2482
2431
|
});
|
|
2483
2432
|
cmd.command("delete <id> <resource-path>").description("Delete an entry from a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, opts) => {
|
|
2484
|
-
const projectDir =
|
|
2433
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2485
2434
|
const manager = await connectConnectors(projectDir);
|
|
2486
2435
|
try {
|
|
2487
2436
|
const ok = await manager.delete(id, resourcePath);
|
|
@@ -2491,7 +2440,7 @@ ${installResult.output}`);
|
|
|
2491
2440
|
}
|
|
2492
2441
|
});
|
|
2493
2442
|
cmd.command("run <id> <op> [args...]").description("Run a custom adapter operation (e.g. git log, sqlite query)").option("--project-dir <path>", "Workspace directory", process.cwd()).allowUnknownOption().action(async (id, op, args, opts) => {
|
|
2494
|
-
const projectDir =
|
|
2443
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2495
2444
|
const manager = await connectConnectors(projectDir);
|
|
2496
2445
|
try {
|
|
2497
2446
|
if (!manager.has(id)) {
|
|
@@ -2600,7 +2549,7 @@ function envRecord() {
|
|
|
2600
2549
|
async function buildDeployContext(projectDir) {
|
|
2601
2550
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2602
2551
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
2603
|
-
const workspaceId = config.name ??
|
|
2552
|
+
const workspaceId = config.name ?? path18__default.basename(projectDir);
|
|
2604
2553
|
let log;
|
|
2605
2554
|
try {
|
|
2606
2555
|
const { createLogger } = await import('../core/logging.js');
|
|
@@ -2632,13 +2581,13 @@ async function ensureTargetsRegistered(projectDir) {
|
|
|
2632
2581
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2633
2582
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
2634
2583
|
if (config.plugins && config.plugins.length > 0) {
|
|
2635
|
-
const { ensurePluginsLoaded } = await import('../plugin-store-
|
|
2584
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-AGQDMING.js');
|
|
2636
2585
|
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
2637
2586
|
for (const f of result.failed) logWarn(f.error);
|
|
2638
2587
|
}
|
|
2639
2588
|
}
|
|
2640
2589
|
async function runUp(opts) {
|
|
2641
|
-
const projectDir =
|
|
2590
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2642
2591
|
await ensureTargetsRegistered(projectDir);
|
|
2643
2592
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2644
2593
|
const { resolveDeployTarget, pluginRegistry } = await import('../plugin-registry/index.js');
|
|
@@ -2706,7 +2655,7 @@ async function restoreFromHandle(projectDir) {
|
|
|
2706
2655
|
return { target, handle, ctx };
|
|
2707
2656
|
}
|
|
2708
2657
|
async function runDown(opts) {
|
|
2709
|
-
const projectDir =
|
|
2658
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2710
2659
|
const restored = await restoreFromHandle(projectDir);
|
|
2711
2660
|
if (!restored) return;
|
|
2712
2661
|
await restored.handle.stop();
|
|
@@ -2715,7 +2664,7 @@ async function runDown(opts) {
|
|
|
2715
2664
|
logOk(`Stopped ${S.cmd(restored.target.id)} and cleared the handle.`);
|
|
2716
2665
|
}
|
|
2717
2666
|
async function runStatus(opts) {
|
|
2718
|
-
const projectDir =
|
|
2667
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2719
2668
|
const restored = await restoreFromHandle(projectDir);
|
|
2720
2669
|
if (!restored) return;
|
|
2721
2670
|
const health = await restored.handle.health();
|
|
@@ -2729,7 +2678,7 @@ async function runStatus(opts) {
|
|
|
2729
2678
|
console.log();
|
|
2730
2679
|
}
|
|
2731
2680
|
async function runLogs(opts) {
|
|
2732
|
-
const projectDir =
|
|
2681
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2733
2682
|
const restored = await restoreFromHandle(projectDir);
|
|
2734
2683
|
if (!restored) return;
|
|
2735
2684
|
if (!restored.handle.logs) {
|
|
@@ -2751,34 +2700,51 @@ function makeDeployCommand() {
|
|
|
2751
2700
|
cmd.action(() => cmd.help());
|
|
2752
2701
|
return cmd;
|
|
2753
2702
|
}
|
|
2703
|
+
var DIFF_SHOWS = { content: true, modified: true, incomplete: true };
|
|
2754
2704
|
function makeDiffCommand() {
|
|
2755
2705
|
return new Command("diff").description("Show changes between deployed and source versions").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
2706
|
+
requireProjectConfig(opts.projectDir);
|
|
2756
2707
|
const am2 = new AssetManager({
|
|
2757
2708
|
registry: getKindRegistry(),
|
|
2758
|
-
projectDir:
|
|
2709
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
2759
2710
|
});
|
|
2711
|
+
const gaps = await am2.gapsOf(ref);
|
|
2712
|
+
const blocking = gaps.filter((g) => !DIFF_SHOWS[g.type]);
|
|
2713
|
+
if (blocking.length > 0) {
|
|
2714
|
+
for (const g of blocking) logErr(g.message);
|
|
2715
|
+
process.exitCode = 1;
|
|
2716
|
+
return;
|
|
2717
|
+
}
|
|
2760
2718
|
const result = await am2.diff(ref);
|
|
2719
|
+
const problems = gaps.filter(
|
|
2720
|
+
(g) => !(result.status === "differs" && (g.type === "content" || g.type === "modified"))
|
|
2721
|
+
);
|
|
2761
2722
|
switch (result.status) {
|
|
2762
2723
|
case "not-found":
|
|
2763
|
-
logErr(`Asset not found: ${ref}`);
|
|
2764
|
-
|
|
2765
|
-
return;
|
|
2724
|
+
if (problems.length === 0) logErr(`Asset not found: ${ref}`);
|
|
2725
|
+
break;
|
|
2766
2726
|
case "not-deployed":
|
|
2767
|
-
logWarn(`${ref} is not deployed \u2014 run skaile install`);
|
|
2768
|
-
|
|
2727
|
+
if (problems.length === 0) logWarn(`${ref} is not deployed \u2014 run skaile install`);
|
|
2728
|
+
break;
|
|
2729
|
+
case "no-files":
|
|
2730
|
+
if (problems.length === 0)
|
|
2731
|
+
logInfo(`${ref}: preset has no files of its own; run skaile diff on its items`);
|
|
2732
|
+
break;
|
|
2769
2733
|
case "identical":
|
|
2770
|
-
logInfo("No differences.");
|
|
2771
|
-
|
|
2734
|
+
if (problems.length === 0) logInfo("No differences.");
|
|
2735
|
+
break;
|
|
2772
2736
|
case "differs":
|
|
2773
2737
|
console.log(result.diff);
|
|
2774
|
-
|
|
2738
|
+
break;
|
|
2775
2739
|
}
|
|
2740
|
+
for (const g of problems) logErr(g.message);
|
|
2741
|
+
if (result.status === "not-found" || problems.length > 0) process.exitCode = 1;
|
|
2776
2742
|
});
|
|
2777
2743
|
}
|
|
2778
2744
|
function makeFlowCommand() {
|
|
2779
2745
|
const cmd = new Command("flow").description("Manage flows");
|
|
2780
2746
|
cmd.command("list").description("List available flows").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
2781
|
-
const flows = await discoverFlowsWithLibraries(
|
|
2747
|
+
const flows = await discoverFlowsWithLibraries(path18__default.resolve(opts.projectDir));
|
|
2782
2748
|
if (flows.length === 0) {
|
|
2783
2749
|
logInfo("No flows found.");
|
|
2784
2750
|
return;
|
|
@@ -2793,7 +2759,7 @@ function makeFlowCommand() {
|
|
|
2793
2759
|
console.log();
|
|
2794
2760
|
});
|
|
2795
2761
|
cmd.command("show <id>").description("Show flow details and node graph").option("--project-dir <path>", "Project directory", process.cwd()).action(async (id, opts) => {
|
|
2796
|
-
const flows = await discoverFlowsWithLibraries(
|
|
2762
|
+
const flows = await discoverFlowsWithLibraries(path18__default.resolve(opts.projectDir));
|
|
2797
2763
|
const flow = flows.find((f) => f.id === id);
|
|
2798
2764
|
if (!flow) {
|
|
2799
2765
|
logErr(`Flow not found: ${id}`);
|
|
@@ -2827,7 +2793,7 @@ function makeHistoryCommand() {
|
|
|
2827
2793
|
cmd.argument("[limit]", "Number of entries to show", "20").option("--project-dir <path>", "Project directory", process.cwd()).action((limitStr, opts) => {
|
|
2828
2794
|
const am2 = new AssetManager({
|
|
2829
2795
|
registry: getKindRegistry(),
|
|
2830
|
-
projectDir:
|
|
2796
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
2831
2797
|
});
|
|
2832
2798
|
const limit = parseInt(limitStr, 10) || 20;
|
|
2833
2799
|
const entries = am2.history(limit);
|
|
@@ -2850,7 +2816,7 @@ function makeHistoryCommand() {
|
|
|
2850
2816
|
cmd.command("clear").description("Clear action history").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
2851
2817
|
const am2 = new AssetManager({
|
|
2852
2818
|
registry: getKindRegistry(),
|
|
2853
|
-
projectDir:
|
|
2819
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
2854
2820
|
});
|
|
2855
2821
|
am2.clearHistory();
|
|
2856
2822
|
logOk("History cleared.");
|
|
@@ -2864,12 +2830,12 @@ var MCP_SERVER_ENTRY = {
|
|
|
2864
2830
|
env: {}
|
|
2865
2831
|
};
|
|
2866
2832
|
function pluginDir(projectDir) {
|
|
2867
|
-
return
|
|
2833
|
+
return path18__default.join(projectDir, ".claude", "plugins", "skaile");
|
|
2868
2834
|
}
|
|
2869
2835
|
async function readJsonStrict(p6) {
|
|
2870
2836
|
let raw;
|
|
2871
2837
|
try {
|
|
2872
|
-
raw = await
|
|
2838
|
+
raw = await fs5.readFile(p6, "utf-8");
|
|
2873
2839
|
} catch {
|
|
2874
2840
|
return null;
|
|
2875
2841
|
}
|
|
@@ -2882,32 +2848,32 @@ async function readJsonStrict(p6) {
|
|
|
2882
2848
|
}
|
|
2883
2849
|
}
|
|
2884
2850
|
async function writeJson(p6, value) {
|
|
2885
|
-
await
|
|
2886
|
-
await
|
|
2851
|
+
await fs5.mkdir(path18__default.dirname(p6), { recursive: true });
|
|
2852
|
+
await fs5.writeFile(p6, `${JSON.stringify(value, null, 2)}
|
|
2887
2853
|
`);
|
|
2888
2854
|
}
|
|
2889
2855
|
async function copyDir(src, dest) {
|
|
2890
|
-
await
|
|
2891
|
-
const entries = await
|
|
2856
|
+
await fs5.mkdir(dest, { recursive: true });
|
|
2857
|
+
const entries = await fs5.readdir(src, { withFileTypes: true });
|
|
2892
2858
|
for (const entry of entries) {
|
|
2893
|
-
const srcPath =
|
|
2894
|
-
const destPath =
|
|
2859
|
+
const srcPath = path18__default.join(src, entry.name);
|
|
2860
|
+
const destPath = path18__default.join(dest, entry.name);
|
|
2895
2861
|
if (entry.isDirectory()) await copyDir(srcPath, destPath);
|
|
2896
|
-
else await
|
|
2862
|
+
else await fs5.copyFile(srcPath, destPath);
|
|
2897
2863
|
}
|
|
2898
2864
|
}
|
|
2899
2865
|
async function install(projectDir, opts) {
|
|
2900
2866
|
return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);
|
|
2901
2867
|
}
|
|
2902
2868
|
async function installMcp(projectDir) {
|
|
2903
|
-
const mcpPath =
|
|
2869
|
+
const mcpPath = path18__default.join(projectDir, ".claude", "mcp.json");
|
|
2904
2870
|
const existing = await readJsonStrict(mcpPath) ?? {};
|
|
2905
2871
|
const mcpServers = { ...existing.mcpServers ?? {} };
|
|
2906
2872
|
const previous = mcpServers[SKAILE_MCP_NAME];
|
|
2907
2873
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);
|
|
2908
2874
|
let warning;
|
|
2909
2875
|
if (previous && !matches) {
|
|
2910
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${
|
|
2876
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path18__default.relative(projectDir, mcpPath)}`;
|
|
2911
2877
|
}
|
|
2912
2878
|
mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;
|
|
2913
2879
|
await writeJson(mcpPath, { ...existing, mcpServers });
|
|
@@ -2916,15 +2882,15 @@ async function installMcp(projectDir) {
|
|
|
2916
2882
|
async function installFullPlugin(projectDir) {
|
|
2917
2883
|
const dir = pluginDir(projectDir);
|
|
2918
2884
|
for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {
|
|
2919
|
-
const dest =
|
|
2920
|
-
await
|
|
2921
|
-
await
|
|
2885
|
+
const dest = path18__default.join(dir, rel);
|
|
2886
|
+
await fs5.mkdir(path18__default.dirname(dest), { recursive: true });
|
|
2887
|
+
await fs5.writeFile(dest, content);
|
|
2922
2888
|
}
|
|
2923
|
-
const projectSkillsDir =
|
|
2889
|
+
const projectSkillsDir = path18__default.join(projectDir, ".skaile", "skills");
|
|
2924
2890
|
if (existsSync(projectSkillsDir)) {
|
|
2925
|
-
await copyDir(projectSkillsDir,
|
|
2891
|
+
await copyDir(projectSkillsDir, path18__default.join(dir, "skills"));
|
|
2926
2892
|
}
|
|
2927
|
-
const settingsPath =
|
|
2893
|
+
const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
|
|
2928
2894
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2929
2895
|
const plugins = settings.plugins ?? [];
|
|
2930
2896
|
if (!plugins.includes(dir)) plugins.push(dir);
|
|
@@ -2932,8 +2898,8 @@ async function installFullPlugin(projectDir) {
|
|
|
2932
2898
|
return { changed: true, method: "plugin" };
|
|
2933
2899
|
}
|
|
2934
2900
|
async function uninstall(projectDir) {
|
|
2935
|
-
const settingsPath =
|
|
2936
|
-
const mcpPath =
|
|
2901
|
+
const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
|
|
2902
|
+
const mcpPath = path18__default.join(projectDir, ".claude", "mcp.json");
|
|
2937
2903
|
const dir = pluginDir(projectDir);
|
|
2938
2904
|
let changed = false;
|
|
2939
2905
|
const settings = await readJsonStrict(settingsPath);
|
|
@@ -2947,7 +2913,7 @@ async function uninstall(projectDir) {
|
|
|
2947
2913
|
}
|
|
2948
2914
|
}
|
|
2949
2915
|
if (existsSync(dir)) {
|
|
2950
|
-
await
|
|
2916
|
+
await fs5.rm(dir, { recursive: true, force: true });
|
|
2951
2917
|
changed = true;
|
|
2952
2918
|
}
|
|
2953
2919
|
const mcp = await readJsonStrict(mcpPath);
|
|
@@ -2957,7 +2923,7 @@ async function uninstall(projectDir) {
|
|
|
2957
2923
|
const updated = { ...mcp, mcpServers: rest };
|
|
2958
2924
|
if (Object.keys(rest).length === 0) delete updated.mcpServers;
|
|
2959
2925
|
if (Object.keys(updated).length === 0) {
|
|
2960
|
-
await
|
|
2926
|
+
await fs5.unlink(mcpPath);
|
|
2961
2927
|
} else {
|
|
2962
2928
|
await writeJson(mcpPath, updated);
|
|
2963
2929
|
}
|
|
@@ -2967,12 +2933,12 @@ async function uninstall(projectDir) {
|
|
|
2967
2933
|
async function detectInstall(projectDir) {
|
|
2968
2934
|
const dir = pluginDir(projectDir);
|
|
2969
2935
|
const settings = await readJsonStrict(
|
|
2970
|
-
|
|
2936
|
+
path18__default.join(projectDir, ".claude", "settings.json")
|
|
2971
2937
|
);
|
|
2972
|
-
if (existsSync(
|
|
2938
|
+
if (existsSync(path18__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
|
|
2973
2939
|
return { method: "plugin", pluginPath: dir };
|
|
2974
2940
|
}
|
|
2975
|
-
const mcp = await readJsonStrict(
|
|
2941
|
+
const mcp = await readJsonStrict(path18__default.join(projectDir, ".claude", "mcp.json"));
|
|
2976
2942
|
if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {
|
|
2977
2943
|
return { method: "mcp" };
|
|
2978
2944
|
}
|
|
@@ -2981,7 +2947,7 @@ async function detectInstall(projectDir) {
|
|
|
2981
2947
|
async function enable(projectDir) {
|
|
2982
2948
|
const detected = await detectInstall(projectDir);
|
|
2983
2949
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
2984
|
-
const settingsPath =
|
|
2950
|
+
const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
|
|
2985
2951
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2986
2952
|
if (detected.method === "plugin") {
|
|
2987
2953
|
const disabled2 = settings.disabledPlugins ?? [];
|
|
@@ -3003,7 +2969,7 @@ async function enable(projectDir) {
|
|
|
3003
2969
|
async function disable(projectDir) {
|
|
3004
2970
|
const detected = await detectInstall(projectDir);
|
|
3005
2971
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
3006
|
-
const settingsPath =
|
|
2972
|
+
const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
|
|
3007
2973
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
3008
2974
|
if (detected.method === "plugin") {
|
|
3009
2975
|
const list2 = settings.disabledPlugins ?? [];
|
|
@@ -3023,12 +2989,12 @@ async function disable(projectDir) {
|
|
|
3023
2989
|
return { changed: true };
|
|
3024
2990
|
}
|
|
3025
2991
|
async function status(projectDir) {
|
|
3026
|
-
const settingsPath =
|
|
3027
|
-
const mcpPath =
|
|
2992
|
+
const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
|
|
2993
|
+
const mcpPath = path18__default.join(projectDir, ".claude", "mcp.json");
|
|
3028
2994
|
const dir = pluginDir(projectDir);
|
|
3029
2995
|
const settings = await readJsonStrict(settingsPath);
|
|
3030
2996
|
const mcp = await readJsonStrict(mcpPath);
|
|
3031
|
-
const pluginInstalled = !!(existsSync(
|
|
2997
|
+
const pluginInstalled = !!(existsSync(path18__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
|
|
3032
2998
|
const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);
|
|
3033
2999
|
if (!pluginInstalled && !mcpInstalled) {
|
|
3034
3000
|
return {
|
|
@@ -3046,7 +3012,7 @@ async function status(projectDir) {
|
|
|
3046
3012
|
installed: "yes",
|
|
3047
3013
|
enabled: disabled2 ? "no" : "yes",
|
|
3048
3014
|
method: "plugin",
|
|
3049
|
-
location:
|
|
3015
|
+
location: path18__default.relative(projectDir, dir)
|
|
3050
3016
|
};
|
|
3051
3017
|
}
|
|
3052
3018
|
const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;
|
|
@@ -3055,7 +3021,7 @@ async function status(projectDir) {
|
|
|
3055
3021
|
installed: "yes",
|
|
3056
3022
|
enabled: disabled ? "no" : "yes",
|
|
3057
3023
|
method: "mcp",
|
|
3058
|
-
location:
|
|
3024
|
+
location: path18__default.relative(projectDir, mcpPath)
|
|
3059
3025
|
};
|
|
3060
3026
|
}
|
|
3061
3027
|
var SKAILE_MCP_NAME2 = "skaile-workspace";
|
|
@@ -3069,7 +3035,7 @@ function buildEntry(projectDir) {
|
|
|
3069
3035
|
async function readConfig(p6) {
|
|
3070
3036
|
let raw;
|
|
3071
3037
|
try {
|
|
3072
|
-
raw = await
|
|
3038
|
+
raw = await fs5.readFile(p6, "utf-8");
|
|
3073
3039
|
} catch {
|
|
3074
3040
|
return null;
|
|
3075
3041
|
}
|
|
@@ -3082,16 +3048,16 @@ async function readConfig(p6) {
|
|
|
3082
3048
|
}
|
|
3083
3049
|
}
|
|
3084
3050
|
async function writeConfig(p6, value) {
|
|
3085
|
-
await
|
|
3051
|
+
await fs5.mkdir(path18__default.dirname(p6), { recursive: true });
|
|
3086
3052
|
const cleaned = {};
|
|
3087
3053
|
for (const [k, v] of Object.entries(value)) {
|
|
3088
3054
|
if (v === void 0) continue;
|
|
3089
3055
|
cleaned[k] = v;
|
|
3090
3056
|
}
|
|
3091
|
-
await
|
|
3057
|
+
await fs5.writeFile(p6, stringify$1(cleaned));
|
|
3092
3058
|
}
|
|
3093
3059
|
function configPath(projectDir) {
|
|
3094
|
-
return
|
|
3060
|
+
return path18__default.join(projectDir, ".codex", "config.toml");
|
|
3095
3061
|
}
|
|
3096
3062
|
async function install2(projectDir) {
|
|
3097
3063
|
const p6 = configPath(projectDir);
|
|
@@ -3102,7 +3068,7 @@ async function install2(projectDir) {
|
|
|
3102
3068
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
|
|
3103
3069
|
let warning;
|
|
3104
3070
|
if (previous && !matches) {
|
|
3105
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${
|
|
3071
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path18__default.relative(projectDir, p6)}`;
|
|
3106
3072
|
}
|
|
3107
3073
|
if (matches) return { changed: false, method: "toml" };
|
|
3108
3074
|
servers[SKAILE_MCP_NAME2] = next;
|
|
@@ -3119,7 +3085,7 @@ async function uninstall2(projectDir) {
|
|
|
3119
3085
|
const updated = { ...cfg, mcp_servers: rest };
|
|
3120
3086
|
if (Object.keys(rest).length === 0) delete updated.mcp_servers;
|
|
3121
3087
|
if (Object.keys(updated).length === 0) {
|
|
3122
|
-
await
|
|
3088
|
+
await fs5.unlink(p6);
|
|
3123
3089
|
} else {
|
|
3124
3090
|
await writeConfig(p6, updated);
|
|
3125
3091
|
}
|
|
@@ -3143,43 +3109,43 @@ async function status2(projectDir) {
|
|
|
3143
3109
|
installed: "yes",
|
|
3144
3110
|
enabled: "n/a",
|
|
3145
3111
|
method: "mcp",
|
|
3146
|
-
location:
|
|
3112
|
+
location: path18__default.relative(projectDir, p6)
|
|
3147
3113
|
};
|
|
3148
3114
|
}
|
|
3149
3115
|
async function install3(projectDir) {
|
|
3150
|
-
const extDir =
|
|
3151
|
-
const extPath =
|
|
3152
|
-
await
|
|
3116
|
+
const extDir = path18__default.join(projectDir, ".omp", "extensions");
|
|
3117
|
+
const extPath = path18__default.join(extDir, "skaile.ts");
|
|
3118
|
+
await fs5.mkdir(extDir, { recursive: true });
|
|
3153
3119
|
const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
|
|
3154
3120
|
const plugin = new WorkspacePlugin({ projectDir });
|
|
3155
3121
|
const nextSrc = await plugin.buildOmpExtensionSource();
|
|
3156
3122
|
let prevSrc = null;
|
|
3157
3123
|
try {
|
|
3158
|
-
prevSrc = await
|
|
3124
|
+
prevSrc = await fs5.readFile(extPath, "utf-8");
|
|
3159
3125
|
} catch {
|
|
3160
3126
|
}
|
|
3161
3127
|
if (prevSrc === nextSrc) return { changed: false, method: "generated" };
|
|
3162
|
-
await
|
|
3128
|
+
await fs5.writeFile(extPath, nextSrc);
|
|
3163
3129
|
return { changed: true, method: "generated" };
|
|
3164
3130
|
}
|
|
3165
3131
|
async function uninstall3(projectDir) {
|
|
3166
|
-
const extPath =
|
|
3132
|
+
const extPath = path18__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3167
3133
|
try {
|
|
3168
|
-
await
|
|
3134
|
+
await fs5.unlink(extPath);
|
|
3169
3135
|
return { changed: true };
|
|
3170
3136
|
} catch {
|
|
3171
3137
|
return { changed: false };
|
|
3172
3138
|
}
|
|
3173
3139
|
}
|
|
3174
3140
|
async function status3(projectDir) {
|
|
3175
|
-
const extPath =
|
|
3141
|
+
const extPath = path18__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3176
3142
|
if (existsSync(extPath)) {
|
|
3177
3143
|
return {
|
|
3178
3144
|
harness: "omp",
|
|
3179
3145
|
installed: "yes",
|
|
3180
3146
|
enabled: "n/a",
|
|
3181
3147
|
method: "extension",
|
|
3182
|
-
location:
|
|
3148
|
+
location: path18__default.relative(projectDir, extPath)
|
|
3183
3149
|
};
|
|
3184
3150
|
}
|
|
3185
3151
|
return {
|
|
@@ -3242,7 +3208,7 @@ async function installCodex(projectDir) {
|
|
|
3242
3208
|
console.log(` ${S.dim("\u2192")} Restart Codex CLI to pick up the change.`);
|
|
3243
3209
|
}
|
|
3244
3210
|
async function runInstall(opts) {
|
|
3245
|
-
const projectDir =
|
|
3211
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
3246
3212
|
const targets = resolveDriver(opts.driver);
|
|
3247
3213
|
let exitCode = 0;
|
|
3248
3214
|
if (targets.includes("claude-code")) {
|
|
@@ -3276,7 +3242,7 @@ async function uninstallCodex(projectDir) {
|
|
|
3276
3242
|
else logInfo(`codex: not installed`);
|
|
3277
3243
|
}
|
|
3278
3244
|
async function runUninstall(opts) {
|
|
3279
|
-
const projectDir =
|
|
3245
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
3280
3246
|
const targets = resolveDriver(opts.driver);
|
|
3281
3247
|
let exitCode = 0;
|
|
3282
3248
|
if (targets.includes("claude-code")) {
|
|
@@ -3319,7 +3285,7 @@ async function toggleTarget(t, projectDir, action3) {
|
|
|
3319
3285
|
});
|
|
3320
3286
|
}
|
|
3321
3287
|
async function runToggle(opts, action3) {
|
|
3322
|
-
const projectDir =
|
|
3288
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
3323
3289
|
const requestedAll = opts.driver === "all";
|
|
3324
3290
|
const targets = resolveDriver(opts.driver);
|
|
3325
3291
|
const usageError = checkToggleSupported(targets, requestedAll, action3);
|
|
@@ -3331,7 +3297,7 @@ async function runToggle(opts, action3) {
|
|
|
3331
3297
|
return exitCode;
|
|
3332
3298
|
}
|
|
3333
3299
|
async function runStatus2(opts) {
|
|
3334
|
-
const projectDir =
|
|
3300
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
3335
3301
|
const targets = resolveDriver(opts.driver);
|
|
3336
3302
|
const rows = [];
|
|
3337
3303
|
let exitCode = 0;
|
|
@@ -3402,7 +3368,7 @@ async function runHook(event) {
|
|
|
3402
3368
|
await plugin.shutdown();
|
|
3403
3369
|
return;
|
|
3404
3370
|
}
|
|
3405
|
-
const store = new PluginStore(
|
|
3371
|
+
const store = new PluginStore(path18__default.join(projectDir, ".skaile", "plugin-state.json"));
|
|
3406
3372
|
await store.load();
|
|
3407
3373
|
const status4 = store.get("connector:status");
|
|
3408
3374
|
if (status4 && typeof status4 === "object" && Object.keys(status4).length > 0) {
|
|
@@ -3480,19 +3446,22 @@ function unfinishedGitState(dir) {
|
|
|
3480
3446
|
for (const [entry, state2] of Object.entries(UNFINISHED_GIT_ENTRIES)) {
|
|
3481
3447
|
const p6 = spawnSync("git", ["rev-parse", "--git-path", entry], { cwd: dir, encoding: "utf-8" });
|
|
3482
3448
|
if (p6.status !== 0) return "the git directory could not be read";
|
|
3483
|
-
if (
|
|
3449
|
+
if (fs8.existsSync(path18.resolve(dir, p6.stdout.trim()))) return state2;
|
|
3484
3450
|
}
|
|
3485
3451
|
return null;
|
|
3486
3452
|
}
|
|
3487
3453
|
async function reindexLibrary(lib, library, name) {
|
|
3488
3454
|
assertManifestEditableOrExit(lib.path);
|
|
3455
|
+
exitOnManifestPublisherProblems(lib.path, name);
|
|
3489
3456
|
const badRequires = manifestRequiresProblems(lib.path);
|
|
3490
3457
|
const resolved = resolveLibraryPublisherDetailed(lib, {}, getStoreIdentity());
|
|
3491
3458
|
warnLibraryNameFallback(name, resolved);
|
|
3492
|
-
const
|
|
3459
|
+
const registry = getKindRegistry();
|
|
3460
|
+
const { removed, unknownKind, skipped, failed } = await syncManifestWithDisk(
|
|
3493
3461
|
lib.path,
|
|
3494
3462
|
resolved.publisher,
|
|
3495
|
-
|
|
3463
|
+
registry,
|
|
3464
|
+
{ check: (e) => checkAssetFile(e.source, e.kind, registry) }
|
|
3496
3465
|
);
|
|
3497
3466
|
const manifest = loadSkPublishManifest(lib.path);
|
|
3498
3467
|
for (const a of unknownKind) {
|
|
@@ -3511,16 +3480,20 @@ async function reindexLibrary(lib, library, name) {
|
|
|
3511
3480
|
}
|
|
3512
3481
|
const duplicates = skipped.filter((x) => x.reason === "duplicate");
|
|
3513
3482
|
for (const s of duplicates) {
|
|
3514
|
-
logErr(
|
|
3515
|
-
`${s.kind}:${s.name} found in ${path23.dirname(s.file)} but ${s.detail}. Rename or delete one of the two directories, then re-run \`skaile library index ${name}\`.`
|
|
3516
|
-
);
|
|
3483
|
+
logErr(duplicateAssetMessage(s.kind, s.name, path18.dirname(s.file), s.detail, name));
|
|
3517
3484
|
}
|
|
3518
|
-
const
|
|
3485
|
+
for (const s of failed) {
|
|
3486
|
+
for (const f of s.findings) logErr(`${s.file} [${f.tag}] \u2014 ${f.text}`);
|
|
3487
|
+
}
|
|
3488
|
+
const duplicateFiles = new Set(duplicates.map((s) => path18.resolve(lib.path, s.file)));
|
|
3519
3489
|
const skippedKeys = new Set(
|
|
3520
|
-
|
|
3490
|
+
[
|
|
3491
|
+
...skipped.filter((s) => s.reason !== "duplicate"),
|
|
3492
|
+
...failed.filter((s) => !s.inManifest)
|
|
3493
|
+
].map((s) => `${s.kind}:${s.name}`)
|
|
3521
3494
|
);
|
|
3522
3495
|
const res = await indexLibrary(lib, library, {
|
|
3523
|
-
exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`) || duplicateFiles.has(
|
|
3496
|
+
exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`) || duplicateFiles.has(path18.resolve(a.manifestPath))
|
|
3524
3497
|
});
|
|
3525
3498
|
const unparsable = res.errors.filter((e) => e.includes("ManifestSchemaError:"));
|
|
3526
3499
|
for (const e of res.errors) (unparsable.includes(e) ? logErr : logWarn)(e);
|
|
@@ -3531,6 +3504,7 @@ async function reindexLibrary(lib, library, name) {
|
|
|
3531
3504
|
logErr(`${s.kind}:${s.name} skipped: manifest file ${s.file} could not be parsed.`);
|
|
3532
3505
|
}
|
|
3533
3506
|
for (const p6 of badRequires) logErr(`${p6.asset}: ${p6.message}`);
|
|
3507
|
+
for (const w of await unresolvedManifestDependencies(lib.path)) logWarn(w);
|
|
3534
3508
|
logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
|
|
3535
3509
|
warnIgnoredDomainFiles(lib.path);
|
|
3536
3510
|
warnLegacyBundleFiles(lib.path);
|
|
@@ -3545,6 +3519,12 @@ async function reindexLibrary(lib, library, name) {
|
|
|
3545
3519
|
);
|
|
3546
3520
|
process.exitCode = 1;
|
|
3547
3521
|
}
|
|
3522
|
+
if (failed.length > 0) {
|
|
3523
|
+
logErr(
|
|
3524
|
+
`${failed.length} asset(s) fail the checks of \`skaile validate\` (listed above); fix them and re-run \`skaile library index ${name}\`.`
|
|
3525
|
+
);
|
|
3526
|
+
process.exitCode = 1;
|
|
3527
|
+
}
|
|
3548
3528
|
if (duplicates.length > 0) {
|
|
3549
3529
|
logErr(
|
|
3550
3530
|
`${duplicates.length} asset(s) skipped: kind + name already registered in another directory.`
|
|
@@ -3567,26 +3547,26 @@ function assertManifestEditableOrExit(libraryPath) {
|
|
|
3567
3547
|
}
|
|
3568
3548
|
async function assertLibraryPathFree(manager, dir, exceptId) {
|
|
3569
3549
|
const clash = (await manager.listLibraries()).find(
|
|
3570
|
-
(l) => l.id !== exceptId &&
|
|
3550
|
+
(l) => l.id !== exceptId && path18.resolve(l.path) === dir
|
|
3571
3551
|
);
|
|
3572
3552
|
if (clash) throw new Error(`${dir} is already registered as library "${clash.name}".`);
|
|
3573
3553
|
}
|
|
3574
3554
|
function canonicalDir(dir) {
|
|
3575
|
-
const abs =
|
|
3555
|
+
const abs = path18.resolve(dir);
|
|
3576
3556
|
const missing = [];
|
|
3577
3557
|
let existing = abs;
|
|
3578
|
-
while (!
|
|
3579
|
-
const parent =
|
|
3558
|
+
while (!fs8.existsSync(existing)) {
|
|
3559
|
+
const parent = path18.dirname(existing);
|
|
3580
3560
|
if (parent === existing) return abs;
|
|
3581
|
-
missing.unshift(
|
|
3561
|
+
missing.unshift(path18.basename(existing));
|
|
3582
3562
|
existing = parent;
|
|
3583
3563
|
}
|
|
3584
|
-
return
|
|
3564
|
+
return path18.join(fs8.realpathSync(existing), ...missing);
|
|
3585
3565
|
}
|
|
3586
3566
|
function refuseGlobalInstallFolder(name, dir) {
|
|
3587
3567
|
const reserved = globalInstallDir();
|
|
3588
|
-
const rel =
|
|
3589
|
-
const inside = rel === "" || !rel.startsWith("..") && !
|
|
3568
|
+
const rel = path18.relative(canonicalDir(reserved).toLowerCase(), canonicalDir(dir).toLowerCase());
|
|
3569
|
+
const inside = rel === "" || !rel.startsWith("..") && !path18.isAbsolute(rel);
|
|
3590
3570
|
if (name?.toLowerCase() === GLOBAL_INSTALL_DIR_NAME || inside) {
|
|
3591
3571
|
logErr(
|
|
3592
3572
|
`"${GLOBAL_INSTALL_DIR_NAME}" is reserved: ${reserved} holds assets from \`skaile install\`, not a library you author.`
|
|
@@ -3594,6 +3574,85 @@ function refuseGlobalInstallFolder(name, dir) {
|
|
|
3594
3574
|
process.exit(1);
|
|
3595
3575
|
}
|
|
3596
3576
|
}
|
|
3577
|
+
async function refuseNestedLibraryPath(manager, dir, exceptId) {
|
|
3578
|
+
const within = (parent, child) => {
|
|
3579
|
+
const rel = path18.relative(parent, child);
|
|
3580
|
+
return rel === "" || !rel.startsWith("..") && !path18.isAbsolute(rel);
|
|
3581
|
+
};
|
|
3582
|
+
const target = canonicalDir(dir).toLowerCase();
|
|
3583
|
+
const librariesDir = resolveLibraryDir();
|
|
3584
|
+
if (within(target, canonicalDir(librariesDir).toLowerCase())) {
|
|
3585
|
+
logErr(
|
|
3586
|
+
`"libraries" is reserved: ${librariesDir} holds every library and the global installs, not a library you author.`
|
|
3587
|
+
);
|
|
3588
|
+
process.exit(1);
|
|
3589
|
+
}
|
|
3590
|
+
for (const other of await manager.listLibraries()) {
|
|
3591
|
+
if (other.id === exceptId) continue;
|
|
3592
|
+
const otherDir = canonicalDir(other.path).toLowerCase();
|
|
3593
|
+
if (within(otherDir, target)) {
|
|
3594
|
+
logErr(
|
|
3595
|
+
`${dir} is inside the library "${other.name}" (${other.path}): a library cannot live inside another library.`
|
|
3596
|
+
);
|
|
3597
|
+
process.exit(1);
|
|
3598
|
+
}
|
|
3599
|
+
if (within(target, otherDir)) {
|
|
3600
|
+
logErr(
|
|
3601
|
+
`${dir} contains the library "${other.name}" (${other.path}): a library cannot contain another library.`
|
|
3602
|
+
);
|
|
3603
|
+
process.exit(1);
|
|
3604
|
+
}
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
function assertCreateDirInsideLibrary(libRoot, destDir, given) {
|
|
3608
|
+
const exists = (p6) => {
|
|
3609
|
+
try {
|
|
3610
|
+
fs8.lstatSync(p6);
|
|
3611
|
+
return true;
|
|
3612
|
+
} catch {
|
|
3613
|
+
return false;
|
|
3614
|
+
}
|
|
3615
|
+
};
|
|
3616
|
+
let probe = destDir;
|
|
3617
|
+
while (!exists(probe)) probe = path18.dirname(probe);
|
|
3618
|
+
let realProbe;
|
|
3619
|
+
try {
|
|
3620
|
+
realProbe = fs8.realpathSync(probe);
|
|
3621
|
+
} catch {
|
|
3622
|
+
logErr(`--dir "${given}" passes through a broken symlink (${probe}).`);
|
|
3623
|
+
process.exit(1);
|
|
3624
|
+
}
|
|
3625
|
+
if (!fs8.statSync(realProbe).isDirectory()) {
|
|
3626
|
+
logErr(`--dir "${given}": ${probe} is not a directory.`);
|
|
3627
|
+
process.exit(1);
|
|
3628
|
+
}
|
|
3629
|
+
const realRoot = canonicalDir(libRoot);
|
|
3630
|
+
const realDest = path18.join(realProbe, path18.relative(probe, destDir));
|
|
3631
|
+
const rel = path18.relative(realRoot, realDest);
|
|
3632
|
+
if (rel === ".." || rel.startsWith(`..${path18.sep}`) || path18.isAbsolute(rel)) {
|
|
3633
|
+
logErr(
|
|
3634
|
+
`--dir "${given}" must stay inside the library (${realRoot}): it resolves to ${realDest}.`
|
|
3635
|
+
);
|
|
3636
|
+
process.exit(1);
|
|
3637
|
+
}
|
|
3638
|
+
}
|
|
3639
|
+
function adoptWritesManifest(libPath) {
|
|
3640
|
+
if (!fs8.existsSync(path18.join(libPath, SKAILE_MANIFEST_FILENAME))) return true;
|
|
3641
|
+
const manifest = loadSkPublishManifest(libPath);
|
|
3642
|
+
if (!manifest || manifest.source || (manifest.assets ?? []).length > 0) return false;
|
|
3643
|
+
return manifestPublisherProblems(libPath).length === 0;
|
|
3644
|
+
}
|
|
3645
|
+
async function countUnlistedAssets(libPath) {
|
|
3646
|
+
const manifest = loadSkPublishManifest(libPath);
|
|
3647
|
+
const listed = manifest?.assets ?? [];
|
|
3648
|
+
if (!manifest || manifest.source || listed.length === 0) return 0;
|
|
3649
|
+
const keys = new Set(listed.map((a) => `${a.kind}:${a.name}`));
|
|
3650
|
+
const onDisk = await scanDirectory(libPath, "unlisted", {
|
|
3651
|
+
knownKinds: new Set(getKindRegistry().getAllKinds()),
|
|
3652
|
+
keepDuplicates: true
|
|
3653
|
+
});
|
|
3654
|
+
return new Set(onDisk.map((e) => `${e.kind}:${e.name}`).filter((k) => !keys.has(k))).size;
|
|
3655
|
+
}
|
|
3597
3656
|
function readOriginTracking(dir) {
|
|
3598
3657
|
if (!isGitRepo(dir)) return null;
|
|
3599
3658
|
const origin = spawnSync("git", ["remote", "get-url", "origin"], { cwd: dir, encoding: "utf-8" });
|
|
@@ -3613,6 +3672,15 @@ function requireGitBackend(lib, verb) {
|
|
|
3613
3672
|
process.exit(1);
|
|
3614
3673
|
}
|
|
3615
3674
|
}
|
|
3675
|
+
async function findLibraryWithMissingDir(name) {
|
|
3676
|
+
const { manager, close } = await openLibraryManager();
|
|
3677
|
+
try {
|
|
3678
|
+
const lib = await manager.getLibrary(name);
|
|
3679
|
+
return lib && libraryDirMissing(lib) ? lib : null;
|
|
3680
|
+
} finally {
|
|
3681
|
+
close();
|
|
3682
|
+
}
|
|
3683
|
+
}
|
|
3616
3684
|
function requireValidLibraryName(name) {
|
|
3617
3685
|
try {
|
|
3618
3686
|
assertValidLibraryName(name);
|
|
@@ -3623,17 +3691,17 @@ function requireValidLibraryName(name) {
|
|
|
3623
3691
|
var LOCAL_OWNERSHIP_REASON = "ownership only governs sync with a git remote, and a local library is always owned by you.";
|
|
3624
3692
|
function pruneEmptyLibraryParents(libPath) {
|
|
3625
3693
|
const root = canonicalDir(resolveLibraryDir());
|
|
3626
|
-
let dir =
|
|
3694
|
+
let dir = path18.dirname(path18.resolve(libPath));
|
|
3627
3695
|
for (; ; ) {
|
|
3628
|
-
const rel =
|
|
3629
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
3630
|
-
if (!
|
|
3631
|
-
|
|
3632
|
-
dir =
|
|
3696
|
+
const rel = path18.relative(root, canonicalDir(dir));
|
|
3697
|
+
if (rel === "" || rel.startsWith("..") || path18.isAbsolute(rel)) return;
|
|
3698
|
+
if (!fs8.existsSync(dir) || fs8.readdirSync(dir).length > 0) return;
|
|
3699
|
+
fs8.rmdirSync(dir);
|
|
3700
|
+
dir = path18.dirname(dir);
|
|
3633
3701
|
}
|
|
3634
3702
|
}
|
|
3635
3703
|
async function warnIfNotGithubRemote(name, url) {
|
|
3636
|
-
const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-
|
|
3704
|
+
const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-53UTB3MB.js');
|
|
3637
3705
|
if (!isGithubRemote(url)) logWarn(notGithubRemoteMessage(name, url));
|
|
3638
3706
|
}
|
|
3639
3707
|
function scaffoldLibraryFiles(dir, name) {
|
|
@@ -3665,9 +3733,9 @@ by the same ref.
|
|
|
3665
3733
|
];
|
|
3666
3734
|
const written = [];
|
|
3667
3735
|
for (const [file, content] of files) {
|
|
3668
|
-
const target =
|
|
3669
|
-
if (
|
|
3670
|
-
|
|
3736
|
+
const target = path18.join(dir, file);
|
|
3737
|
+
if (fs8.existsSync(target)) continue;
|
|
3738
|
+
fs8.writeFileSync(target, content, "utf8");
|
|
3671
3739
|
written.push(file);
|
|
3672
3740
|
}
|
|
3673
3741
|
return written;
|
|
@@ -3678,7 +3746,15 @@ function makeLibraryCommand() {
|
|
|
3678
3746
|
const { manager, close } = await openLibraryManager();
|
|
3679
3747
|
try {
|
|
3680
3748
|
const ls = await manager.listLibraries();
|
|
3681
|
-
if (opts.json)
|
|
3749
|
+
if (opts.json) {
|
|
3750
|
+
return console.log(
|
|
3751
|
+
JSON.stringify(
|
|
3752
|
+
ls.map((l) => libraryDirMissing(l) ? { ...l, directoryMissing: true } : l),
|
|
3753
|
+
null,
|
|
3754
|
+
2
|
|
3755
|
+
)
|
|
3756
|
+
);
|
|
3757
|
+
}
|
|
3682
3758
|
if (ls.length === 0) {
|
|
3683
3759
|
logInfo("No libraries registered. Run `skaile library init personal` to start.");
|
|
3684
3760
|
return;
|
|
@@ -3698,6 +3774,7 @@ function makeLibraryCommand() {
|
|
|
3698
3774
|
console.log(`
|
|
3699
3775
|
${S.dim(`${ls.length} library(s)`)}
|
|
3700
3776
|
`);
|
|
3777
|
+
for (const l of ls) if (libraryDirMissing(l)) logWarn(missingLibraryDirMessage(l));
|
|
3701
3778
|
} finally {
|
|
3702
3779
|
close();
|
|
3703
3780
|
}
|
|
@@ -3724,6 +3801,10 @@ function makeLibraryCommand() {
|
|
|
3724
3801
|
console.log(` ${S.label("manifestGen")} ${l.manifestGenerated}`);
|
|
3725
3802
|
console.log(` ${S.label("backendConfig")} ${JSON.stringify(l.backendConfig)}`);
|
|
3726
3803
|
console.log();
|
|
3804
|
+
if (libraryDirMissing(l)) {
|
|
3805
|
+
logErr(missingLibraryDirMessage(l));
|
|
3806
|
+
process.exitCode = 1;
|
|
3807
|
+
}
|
|
3727
3808
|
} finally {
|
|
3728
3809
|
close();
|
|
3729
3810
|
}
|
|
@@ -3736,10 +3817,15 @@ function makeLibraryCommand() {
|
|
|
3736
3817
|
logErr("Pick one of --owner, --contributor, --reader.");
|
|
3737
3818
|
process.exit(1);
|
|
3738
3819
|
}
|
|
3739
|
-
const
|
|
3740
|
-
|
|
3820
|
+
const gone = await findLibraryWithMissingDir(name);
|
|
3821
|
+
if (gone) {
|
|
3822
|
+
if (gone.backend === "git") opts.git ??= gone.backendConfig.url;
|
|
3823
|
+
opts.path ??= gone.path;
|
|
3824
|
+
}
|
|
3825
|
+
const ownership = flagged[0] ?? gone?.ownership ?? "owner";
|
|
3826
|
+
const libPath = opts.path ? path18.resolve(opts.path) : path18.join(resolveLibraryDir(), name);
|
|
3741
3827
|
refuseGlobalInstallFolder(name, libPath);
|
|
3742
|
-
if (
|
|
3828
|
+
if (fs8.existsSync(libPath) && !fs8.statSync(libPath).isDirectory()) {
|
|
3743
3829
|
logErr(`${libPath} exists and is not a directory.`);
|
|
3744
3830
|
process.exit(1);
|
|
3745
3831
|
}
|
|
@@ -3752,11 +3838,14 @@ function makeLibraryCommand() {
|
|
|
3752
3838
|
}
|
|
3753
3839
|
const { manager, library, close } = await openLibraryManager();
|
|
3754
3840
|
try {
|
|
3755
|
-
|
|
3841
|
+
const existing = await manager.getLibrary(name);
|
|
3842
|
+
if (existing && !gone) {
|
|
3756
3843
|
logErr(`A library named "${name}" is already registered.`);
|
|
3757
3844
|
process.exit(1);
|
|
3758
3845
|
}
|
|
3846
|
+
if (existing) await manager.removeLibrary(name);
|
|
3759
3847
|
await assertLibraryPathFree(manager, libPath);
|
|
3848
|
+
await refuseNestedLibraryPath(manager, libPath);
|
|
3760
3849
|
const hasDefault = (await manager.listLibraries()).some((l) => l.isDefault);
|
|
3761
3850
|
let backend = "local";
|
|
3762
3851
|
let backendConfig;
|
|
@@ -3775,9 +3864,9 @@ function makeLibraryCommand() {
|
|
|
3775
3864
|
backend = "git";
|
|
3776
3865
|
backendConfig = { url: adopted.url, branch: adopted.branch, authHint: "ssh" };
|
|
3777
3866
|
} else {
|
|
3778
|
-
|
|
3867
|
+
fs8.mkdirSync(libPath, { recursive: true });
|
|
3779
3868
|
}
|
|
3780
|
-
const blank =
|
|
3869
|
+
const blank = fs8.readdirSync(libPath).every((entry) => entry === ".git");
|
|
3781
3870
|
const isDefault = !hasDefault && ownership !== "reader";
|
|
3782
3871
|
await manager.addLibrary({
|
|
3783
3872
|
name,
|
|
@@ -3804,6 +3893,11 @@ function makeLibraryCommand() {
|
|
|
3804
3893
|
}
|
|
3805
3894
|
if (!blank) {
|
|
3806
3895
|
const lib = await manager.requireLibrary(name);
|
|
3896
|
+
if (adoptWritesManifest(libPath)) {
|
|
3897
|
+
await reindexLibrary(lib, library, name);
|
|
3898
|
+
return;
|
|
3899
|
+
}
|
|
3900
|
+
const unlisted = await countUnlistedAssets(libPath);
|
|
3807
3901
|
const resolved = resolveLibraryPublisherDetailed(lib, {}, getStoreIdentity());
|
|
3808
3902
|
if (resolved.source === "manifest" && !isValidPublisher(resolved.publisher)) {
|
|
3809
3903
|
logWarn(
|
|
@@ -3817,6 +3911,11 @@ function makeLibraryCommand() {
|
|
|
3817
3911
|
const res = await indexLibrary(lib, library);
|
|
3818
3912
|
for (const e of res.errors) logWarn(e);
|
|
3819
3913
|
logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
|
|
3914
|
+
if (unlisted > 0) {
|
|
3915
|
+
logWarn(
|
|
3916
|
+
`${unlisted} asset(s) on disk are not in the manifest; run \`skaile library index ${name}\`.`
|
|
3917
|
+
);
|
|
3918
|
+
}
|
|
3820
3919
|
warnIgnoredDomainFiles(libPath);
|
|
3821
3920
|
}
|
|
3822
3921
|
} catch (err2) {
|
|
@@ -3829,7 +3928,7 @@ function makeLibraryCommand() {
|
|
|
3829
3928
|
cmd.command("link <name> <git-url>").description("Attach a github remote to a local library (makes it store-publishable)").option("--branch <name>", "Default branch", "main").action(async (name, url, opts) => {
|
|
3830
3929
|
const { manager, close } = await openLibraryManager();
|
|
3831
3930
|
try {
|
|
3832
|
-
const lib = await manager.
|
|
3931
|
+
const lib = await manager.requireLibraryDir(name);
|
|
3833
3932
|
if (lib.backend === "git") {
|
|
3834
3933
|
logErr(
|
|
3835
3934
|
`Library "${name}" is already git-backed. Use \`skaile library set ${name} backendConfig.url=${url}\` to change its remote.`
|
|
@@ -3866,13 +3965,7 @@ function makeLibraryCommand() {
|
|
|
3866
3965
|
logErr(`Invalid asset name "${name}": ${ASSET_NAME_HINT}.`);
|
|
3867
3966
|
process.exit(1);
|
|
3868
3967
|
}
|
|
3869
|
-
if (opts.publisher !== void 0)
|
|
3870
|
-
const bare = opts.publisher.trim().replace(/^@/, "");
|
|
3871
|
-
if (!isValidPublisher(bare)) {
|
|
3872
|
-
logErr(`Invalid publisher "${opts.publisher}": ${PUBLISHER_HINT}.`);
|
|
3873
|
-
process.exit(1);
|
|
3874
|
-
}
|
|
3875
|
-
}
|
|
3968
|
+
if (opts.publisher !== void 0) requireValidPublisherOrExit(opts.publisher);
|
|
3876
3969
|
if (opts.description !== void 0) {
|
|
3877
3970
|
const len = opts.description.trim().length;
|
|
3878
3971
|
if (len === 0 || len > 1024) {
|
|
@@ -3884,24 +3977,26 @@ function makeLibraryCommand() {
|
|
|
3884
3977
|
try {
|
|
3885
3978
|
const target = await resolveTargetLibrary(manager, opts.library);
|
|
3886
3979
|
assertManifestEditableOrExit(target.path);
|
|
3980
|
+
exitOnManifestPublisherProblems(target.path, target.name);
|
|
3887
3981
|
const effectiveKind = opts.kind ?? kind;
|
|
3888
3982
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
|
|
3889
|
-
const libRoot =
|
|
3890
|
-
const destDir = opts.dir ?
|
|
3891
|
-
const relDest =
|
|
3892
|
-
if (relDest === ".." || relDest.startsWith(`..${
|
|
3983
|
+
const libRoot = path18.resolve(target.path);
|
|
3984
|
+
const destDir = opts.dir ? path18.resolve(libRoot, opts.dir) : libRoot;
|
|
3985
|
+
const relDest = path18.relative(libRoot, destDir);
|
|
3986
|
+
if (relDest === ".." || relDest.startsWith(`..${path18.sep}`) || path18.isAbsolute(relDest)) {
|
|
3893
3987
|
logErr(`--dir "${opts.dir}" must stay inside the library (${libRoot}).`);
|
|
3894
3988
|
process.exit(1);
|
|
3895
3989
|
}
|
|
3990
|
+
if (opts.dir) assertCreateDirInsideLibrary(libRoot, destDir, opts.dir);
|
|
3896
3991
|
const taken = conflictingAssetRoot(
|
|
3897
3992
|
libRoot,
|
|
3898
3993
|
effectiveKind,
|
|
3899
3994
|
name,
|
|
3900
|
-
|
|
3995
|
+
path18.relative(libRoot, path18.join(destDir, name))
|
|
3901
3996
|
);
|
|
3902
3997
|
if (taken) {
|
|
3903
3998
|
logErr(
|
|
3904
|
-
`${effectiveKind}:${name} already exists at "${taken}" \u2014 creating it again under "${
|
|
3999
|
+
`${effectiveKind}:${name} already exists at "${taken}" \u2014 creating it again under "${path18.relative(libRoot, destDir) || "."}" would re-point the manifest entry. Pick another name.`
|
|
3905
4000
|
);
|
|
3906
4001
|
process.exit(1);
|
|
3907
4002
|
}
|
|
@@ -3911,9 +4006,9 @@ function makeLibraryCommand() {
|
|
|
3911
4006
|
process.exit(1);
|
|
3912
4007
|
}
|
|
3913
4008
|
logOk(`Created ${effectiveKind}: ${pc5.dim(res.path)}`);
|
|
3914
|
-
if (opts.description === void 0
|
|
4009
|
+
if (opts.description === void 0) {
|
|
3915
4010
|
logWarn(
|
|
3916
|
-
|
|
4011
|
+
`Description is a TODO placeholder \u2014 edit it (what the ${effectiveKind} does and when to use it) or \`skaile validate\` will fail.`
|
|
3917
4012
|
);
|
|
3918
4013
|
}
|
|
3919
4014
|
const { ref } = await registerLibraryAsset(target, library, {
|
|
@@ -3930,9 +4025,9 @@ function makeLibraryCommand() {
|
|
|
3930
4025
|
}
|
|
3931
4026
|
);
|
|
3932
4027
|
async function resolveTargetLibrary(manager, libraryName) {
|
|
3933
|
-
if (libraryName) return manager.
|
|
4028
|
+
if (libraryName) return manager.requireLibraryDir(libraryName);
|
|
3934
4029
|
const def = await manager.findDefaultLibrary();
|
|
3935
|
-
if (def) return def;
|
|
4030
|
+
if (def) return manager.requireLibraryDir(def.name);
|
|
3936
4031
|
if ((await manager.listLibraries()).length === 0) {
|
|
3937
4032
|
logErr("No libraries registered. Run `skaile library init <name>` first.");
|
|
3938
4033
|
process.exit(1);
|
|
@@ -3950,18 +4045,22 @@ function makeLibraryCommand() {
|
|
|
3950
4045
|
}
|
|
3951
4046
|
});
|
|
3952
4047
|
async function renameLibrary(manager, lib, newName) {
|
|
4048
|
+
if (libraryDirMissing(lib)) {
|
|
4049
|
+
logErr(missingLibraryDirMessage(lib));
|
|
4050
|
+
process.exit(1);
|
|
4051
|
+
}
|
|
3953
4052
|
requireValidLibraryName(newName);
|
|
3954
4053
|
if (await manager.getLibrary(newName)) {
|
|
3955
4054
|
logErr(`A library named "${newName}" is already registered.`);
|
|
3956
4055
|
process.exit(1);
|
|
3957
4056
|
}
|
|
3958
|
-
const newPath =
|
|
4057
|
+
const newPath = path18.join(path18.dirname(lib.path), newName);
|
|
3959
4058
|
refuseGlobalInstallFolder(newName, newPath);
|
|
3960
|
-
if (
|
|
4059
|
+
if (fs8.existsSync(newPath)) {
|
|
3961
4060
|
logErr(`Target directory already exists: ${newPath}`);
|
|
3962
4061
|
process.exit(1);
|
|
3963
4062
|
}
|
|
3964
|
-
|
|
4063
|
+
fs8.renameSync(lib.path, newPath);
|
|
3965
4064
|
await manager.updateLibrary(lib.id, { name: newName, path: newPath });
|
|
3966
4065
|
logOk(`Renamed ${lib.name} \u2192 ${newName}`);
|
|
3967
4066
|
}
|
|
@@ -3988,17 +4087,17 @@ function makeLibraryCommand() {
|
|
|
3988
4087
|
try {
|
|
3989
4088
|
const lib = await manager.requireLibrary(name);
|
|
3990
4089
|
if (field === "publisher") {
|
|
3991
|
-
const publisher = value
|
|
3992
|
-
if (!isValidPublisher(publisher)) {
|
|
3993
|
-
logErr(`Invalid publisher "${value}": ${PUBLISHER_HINT}.`);
|
|
3994
|
-
process.exit(1);
|
|
3995
|
-
}
|
|
4090
|
+
const publisher = requireValidPublisherOrExit(value);
|
|
3996
4091
|
if (lib.ownership === "reader") {
|
|
3997
4092
|
logErr(
|
|
3998
4093
|
`Library "${lib.name}" is read-only (ownership=reader); its publisher is not yours to set.`
|
|
3999
4094
|
);
|
|
4000
4095
|
process.exit(1);
|
|
4001
4096
|
}
|
|
4097
|
+
if (libraryDirMissing(lib)) {
|
|
4098
|
+
logErr(missingLibraryDirMessage(lib));
|
|
4099
|
+
process.exit(1);
|
|
4100
|
+
}
|
|
4002
4101
|
assertManifestEditableOrExit(lib.path);
|
|
4003
4102
|
setManifestPublisher(lib.path, publisher);
|
|
4004
4103
|
const res = await indexLibrary(lib, library);
|
|
@@ -4041,13 +4140,14 @@ function makeLibraryCommand() {
|
|
|
4041
4140
|
}
|
|
4042
4141
|
patch.isDefault = false;
|
|
4043
4142
|
} else if (field === "path") {
|
|
4044
|
-
const dir =
|
|
4045
|
-
if (!
|
|
4143
|
+
const dir = path18.resolve(value);
|
|
4144
|
+
if (!fs8.existsSync(dir) || !fs8.statSync(dir).isDirectory()) {
|
|
4046
4145
|
logErr(`Directory does not exist: ${dir}. \`library set path=\` does not move files.`);
|
|
4047
4146
|
process.exit(1);
|
|
4048
4147
|
}
|
|
4049
4148
|
refuseGlobalInstallFolder(null, dir);
|
|
4050
4149
|
await assertLibraryPathFree(manager, dir, lib.id);
|
|
4150
|
+
await refuseNestedLibraryPath(manager, dir, lib.id);
|
|
4051
4151
|
patch.path = dir;
|
|
4052
4152
|
} else if (field.startsWith("backendConfig.")) {
|
|
4053
4153
|
const key = field.split(".")[1];
|
|
@@ -4105,7 +4205,7 @@ function makeLibraryCommand() {
|
|
|
4105
4205
|
cmd.command("sync <name>").description("Pull then push (as backend permits)").action(async (name) => {
|
|
4106
4206
|
const { manager, library, close } = await openLibraryManager();
|
|
4107
4207
|
try {
|
|
4108
|
-
const lib = await manager.
|
|
4208
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4109
4209
|
requireGitBackend(lib, "sync");
|
|
4110
4210
|
const drv = manager.driverFor(lib.backend);
|
|
4111
4211
|
const pull = await drv.pull(lib);
|
|
@@ -4127,8 +4227,10 @@ function makeLibraryCommand() {
|
|
|
4127
4227
|
cmd.command("index <name>").description("(Re)index a library's assets into the local index").action(async (name) => {
|
|
4128
4228
|
const { manager, library, close } = await openLibraryManager();
|
|
4129
4229
|
try {
|
|
4130
|
-
const lib = await manager.
|
|
4230
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4131
4231
|
await reindexLibrary(lib, library, name);
|
|
4232
|
+
} catch (err2) {
|
|
4233
|
+
exitOnSyncError(err2);
|
|
4132
4234
|
} finally {
|
|
4133
4235
|
close();
|
|
4134
4236
|
}
|
|
@@ -4136,7 +4238,7 @@ function makeLibraryCommand() {
|
|
|
4136
4238
|
cmd.command("pull <name>").description("Pull from remote").action(async (name) => {
|
|
4137
4239
|
const { manager, library, close } = await openLibraryManager();
|
|
4138
4240
|
try {
|
|
4139
|
-
const lib = await manager.
|
|
4241
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4140
4242
|
requireGitBackend(lib, "pull");
|
|
4141
4243
|
const res = await manager.driverFor(lib.backend).pull(lib);
|
|
4142
4244
|
if (res.conflicts.length > 0) {
|
|
@@ -4154,7 +4256,7 @@ function makeLibraryCommand() {
|
|
|
4154
4256
|
cmd.command("push <name>").description("Push local commits (owner only)").option("--force", "Force-with-lease push", false).action(async (name, opts) => {
|
|
4155
4257
|
const { manager, close } = await openLibraryManager();
|
|
4156
4258
|
try {
|
|
4157
|
-
const lib = await manager.
|
|
4259
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4158
4260
|
requireGitBackend(lib, "push");
|
|
4159
4261
|
const res = await manager.driverFor(lib.backend).push(lib, { force: opts.force });
|
|
4160
4262
|
logOk(`Pushed (${res.pushed}).`);
|
|
@@ -4167,7 +4269,7 @@ function makeLibraryCommand() {
|
|
|
4167
4269
|
cmd.command("propose <name>").description("Open a pull request on the upstream repo (contributor only)").option("--title <title>", "PR title").option("--body <body>", "PR body").option("--branch <name>", "Branch name (default: skaile/<timestamp>)").action(async (name, opts) => {
|
|
4168
4270
|
const { manager, close } = await openLibraryManager();
|
|
4169
4271
|
try {
|
|
4170
|
-
const lib = await manager.
|
|
4272
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4171
4273
|
const res = await manager.driverFor(lib.backend).propose(lib, opts);
|
|
4172
4274
|
logOk(`PR opened: ${res.prUrl}`);
|
|
4173
4275
|
} catch (err2) {
|
|
@@ -4179,7 +4281,7 @@ function makeLibraryCommand() {
|
|
|
4179
4281
|
cmd.command("commit <name>").description("Git-commit local changes inside the library (git only)").option("-m, --message <msg>", "Commit message", "skaile: update assets").action(async (name, opts) => {
|
|
4180
4282
|
const { manager, close } = await openLibraryManager();
|
|
4181
4283
|
try {
|
|
4182
|
-
const lib = await manager.
|
|
4284
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4183
4285
|
requireGitBackend(lib, "commit");
|
|
4184
4286
|
if (!isGitRepo(lib.path)) {
|
|
4185
4287
|
logErr(
|
|
@@ -4232,13 +4334,15 @@ function makeLibraryCommand() {
|
|
|
4232
4334
|
const args = rawArgs[0] === "--" ? rawArgs.slice(1) : rawArgs;
|
|
4233
4335
|
const { manager, close } = await openLibraryManager();
|
|
4234
4336
|
try {
|
|
4235
|
-
const lib = await manager.
|
|
4337
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4236
4338
|
const r = spawnSync("git", args, { cwd: lib.path, stdio: "inherit" });
|
|
4237
4339
|
if (r.error) {
|
|
4238
4340
|
logErr(`Could not run git: ${r.error.message}`);
|
|
4239
4341
|
process.exit(1);
|
|
4240
4342
|
}
|
|
4241
4343
|
process.exit(r.status ?? 1);
|
|
4344
|
+
} catch (err2) {
|
|
4345
|
+
exitOnSyncError(err2);
|
|
4242
4346
|
} finally {
|
|
4243
4347
|
close();
|
|
4244
4348
|
}
|
|
@@ -4248,16 +4352,16 @@ function makeLibraryCommand() {
|
|
|
4248
4352
|
"With --create-repo: create the repo private (the store only accepts public repos)"
|
|
4249
4353
|
).option("--ref <gitref>", "Git ref to ingest (default: the library branch or main)").option("--dry-run", "Print the plan; push nothing and call no store endpoint").action(
|
|
4250
4354
|
async (lib, opts) => {
|
|
4251
|
-
const { runLibraryPublish } = await import('../library-publish-
|
|
4355
|
+
const { runLibraryPublish } = await import('../library-publish-53UTB3MB.js');
|
|
4252
4356
|
await withStoreErrorHandling(() => runLibraryPublish(lib, opts));
|
|
4253
4357
|
}
|
|
4254
4358
|
);
|
|
4255
4359
|
cmd.command("register <lib>").description("Register the library's manifest without pushing (bytes already on github)").option("--asset <ref>", "Publish only the single asset matching this ref/name").option("--ref <gitref>", "Git ref to ingest (default: the library branch or main)").option("--dry-run", "Print the plan; call no store endpoint").action(async (lib, opts) => {
|
|
4256
|
-
const { runLibraryRegister } = await import('../library-publish-
|
|
4360
|
+
const { runLibraryRegister } = await import('../library-publish-53UTB3MB.js');
|
|
4257
4361
|
await withStoreErrorHandling(() => runLibraryRegister(lib, opts));
|
|
4258
4362
|
});
|
|
4259
4363
|
cmd.command("yank <lib>").description("Retract the library's published assets from the store").option("--asset <ref>", "Yank only the single asset matching this ref/name").action(async (lib, opts) => {
|
|
4260
|
-
const { runLibraryYank } = await import('../library-publish-
|
|
4364
|
+
const { runLibraryYank } = await import('../library-publish-53UTB3MB.js');
|
|
4261
4365
|
await withStoreErrorHandling(() => runLibraryYank(lib, opts));
|
|
4262
4366
|
});
|
|
4263
4367
|
return cmd;
|
|
@@ -4273,7 +4377,7 @@ async function withStoreErrorHandling(fn) {
|
|
|
4273
4377
|
async function printPerLibraryStatus(name, asJson) {
|
|
4274
4378
|
const { manager, close } = await openLibraryManager();
|
|
4275
4379
|
try {
|
|
4276
|
-
const lib = await manager.
|
|
4380
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4277
4381
|
const status4 = await manager.driverFor(lib.backend).status(lib);
|
|
4278
4382
|
if (asJson) return console.log(JSON.stringify({ library: lib.name, status: status4 }, null, 2));
|
|
4279
4383
|
console.log(`
|
|
@@ -4308,9 +4412,9 @@ async function printOverallStatus(projectDir, asJson) {
|
|
|
4308
4412
|
} catch {
|
|
4309
4413
|
secretsStrategy = "unavailable";
|
|
4310
4414
|
}
|
|
4311
|
-
const resolvedProjectDir =
|
|
4312
|
-
const hasWorkspaceConfig = existsSync(
|
|
4313
|
-
const hasLockFile = existsSync(
|
|
4415
|
+
const resolvedProjectDir = path18.resolve(projectDir);
|
|
4416
|
+
const hasWorkspaceConfig = existsSync(path18.join(resolvedProjectDir, "skaile.yaml"));
|
|
4417
|
+
const hasLockFile = existsSync(path18.join(resolvedProjectDir, "skaile.lock.yaml"));
|
|
4314
4418
|
let assignments = [];
|
|
4315
4419
|
if (hasWorkspaceConfig) {
|
|
4316
4420
|
try {
|
|
@@ -4917,7 +5021,7 @@ function scheduleSoftDepPreview() {
|
|
|
4917
5021
|
}
|
|
4918
5022
|
async function loadAssets() {
|
|
4919
5023
|
softDepPreviewCache.clear();
|
|
4920
|
-
const { gatherAssetFeeds } = await import('../asset-feeds-
|
|
5024
|
+
const { gatherAssetFeeds } = await import('../asset-feeds-CXGQIDFR.js');
|
|
4921
5025
|
const { entries, notes } = await gatherAssetFeeds(am, am.projectDir);
|
|
4922
5026
|
if (notes.length > 0) {
|
|
4923
5027
|
state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
|
|
@@ -4925,10 +5029,15 @@ async function loadAssets() {
|
|
|
4925
5029
|
const installed = new Set(am.listDeployed().map((e) => `${e.kind}:${e.name}`));
|
|
4926
5030
|
let lock = null;
|
|
4927
5031
|
try {
|
|
4928
|
-
lock = readLock(
|
|
5032
|
+
lock = readLock(path18__default.join(am.projectDir, "skaile.lock.yaml"));
|
|
4929
5033
|
} catch {
|
|
4930
5034
|
}
|
|
4931
|
-
const rows = buildAssetRows(
|
|
5035
|
+
const rows = buildAssetRows(
|
|
5036
|
+
entries,
|
|
5037
|
+
installed,
|
|
5038
|
+
await am.lockedLibraryNames(),
|
|
5039
|
+
lockedPublishersByName(lock)
|
|
5040
|
+
);
|
|
4932
5041
|
state.assetRows = rows;
|
|
4933
5042
|
reconcileCollapsedSets(rows);
|
|
4934
5043
|
rebuildVisible();
|
|
@@ -4942,7 +5051,7 @@ function rebuildSourceTree() {
|
|
|
4942
5051
|
rebuildVisibleSources();
|
|
4943
5052
|
}
|
|
4944
5053
|
function sourceOrgRepo(s) {
|
|
4945
|
-
const parts = s.path.split(
|
|
5054
|
+
const parts = s.path.split(path18__default.sep).filter(Boolean);
|
|
4946
5055
|
if (parts.length < 2) return null;
|
|
4947
5056
|
return { org: parts[parts.length - 2], repo: parts[parts.length - 1] };
|
|
4948
5057
|
}
|
|
@@ -5015,22 +5124,27 @@ function rebuildVisibleLibraries() {
|
|
|
5015
5124
|
);
|
|
5016
5125
|
clampCursor();
|
|
5017
5126
|
}
|
|
5018
|
-
function
|
|
5127
|
+
function lockedPublishersByName(lock) {
|
|
5019
5128
|
const out = /* @__PURE__ */ new Map();
|
|
5020
|
-
for (const
|
|
5021
|
-
if (!locked.library) continue;
|
|
5129
|
+
for (const key of Object.keys(lock?.assets ?? {})) {
|
|
5022
5130
|
const ref = parseAssetRefLoose(key);
|
|
5023
|
-
if (ref?.publisher)
|
|
5131
|
+
if (!ref?.publisher) continue;
|
|
5132
|
+
const id = `${ref.kind}:${ref.name}`;
|
|
5133
|
+
const publishers = out.get(id) ?? /* @__PURE__ */ new Set();
|
|
5134
|
+
publishers.add(ref.publisher);
|
|
5135
|
+
out.set(id, publishers);
|
|
5024
5136
|
}
|
|
5025
5137
|
return out;
|
|
5026
5138
|
}
|
|
5027
|
-
function isRowInstalled(origin, group, entry, installed, lockedLibrary) {
|
|
5139
|
+
function isRowInstalled(origin, group, entry, installed, lockedLibrary, lockedPublishers) {
|
|
5028
5140
|
if (!installed.has(`${entry.kind}:${entry.name}`)) return false;
|
|
5029
5141
|
const publisher = entry.publisher?.replace(/^@/, "");
|
|
5142
|
+
const lockedFor = lockedPublishers.get(`${entry.kind}:${entry.name}`);
|
|
5143
|
+
if (publisher && lockedFor && !lockedFor.has(publisher)) return false;
|
|
5030
5144
|
const locked = publisher ? lockedLibrary.get(`${entry.kind}:${publisher}/${entry.name}`) : void 0;
|
|
5031
|
-
return locked === void 0 || origin === "library" && group === locked;
|
|
5145
|
+
return locked === void 0 || origin === "library" && locked !== null && group === locked;
|
|
5032
5146
|
}
|
|
5033
|
-
function buildAssetRows(entries, installed, lockedLibrary = /* @__PURE__ */ new Map()) {
|
|
5147
|
+
function buildAssetRows(entries, installed, lockedLibrary = /* @__PURE__ */ new Map(), lockedPublishers = /* @__PURE__ */ new Map()) {
|
|
5034
5148
|
const byOrigin = /* @__PURE__ */ new Map();
|
|
5035
5149
|
for (const { origin, entry, group } of entries) {
|
|
5036
5150
|
const publisher = group || entry.publisher || "other";
|
|
@@ -5058,7 +5172,14 @@ function buildAssetRows(entries, installed, lockedLibrary = /* @__PURE__ */ new
|
|
|
5058
5172
|
source: group,
|
|
5059
5173
|
org: entry.repo?.includes("/") ? entry.repo.slice(0, entry.repo.indexOf("/")) : void 0,
|
|
5060
5174
|
entry,
|
|
5061
|
-
installed: isRowInstalled(
|
|
5175
|
+
installed: isRowInstalled(
|
|
5176
|
+
origin,
|
|
5177
|
+
group,
|
|
5178
|
+
entry,
|
|
5179
|
+
installed,
|
|
5180
|
+
lockedLibrary,
|
|
5181
|
+
lockedPublishers
|
|
5182
|
+
),
|
|
5062
5183
|
plugin
|
|
5063
5184
|
});
|
|
5064
5185
|
}
|
|
@@ -5104,13 +5225,13 @@ function reconcileCollapsedSets(rows) {
|
|
|
5104
5225
|
async function loadSourcesAndLibraries() {
|
|
5105
5226
|
try {
|
|
5106
5227
|
const [{ openLibraryManager: openLibraryManager2 }, { getGlobalCacheDir: getGlobalCacheDir2, globalSkaileDir: globalSkaileDir2 }] = await Promise.all([
|
|
5107
|
-
import('../open-library-
|
|
5228
|
+
import('../open-library-BOSPJVID.js'),
|
|
5108
5229
|
import('../core/index.js')
|
|
5109
5230
|
]);
|
|
5110
5231
|
const { manager, library, close } = await openLibraryManager2();
|
|
5111
5232
|
try {
|
|
5112
5233
|
const newRoot = getGlobalCacheDir2();
|
|
5113
|
-
const legacyRoot =
|
|
5234
|
+
const legacyRoot = path18__default.join(globalSkaileDir2(), "sources");
|
|
5114
5235
|
const isSourceRow = (l) => l.path.startsWith(newRoot) || l.path.startsWith(legacyRoot);
|
|
5115
5236
|
const libs = await manager.listLibraries();
|
|
5116
5237
|
const defs = await library.listAssetDefs();
|
|
@@ -5236,12 +5357,25 @@ function pendingCountsFor(match) {
|
|
|
5236
5357
|
}
|
|
5237
5358
|
return [add, remove];
|
|
5238
5359
|
}
|
|
5239
|
-
function
|
|
5240
|
-
|
|
5241
|
-
if (
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5360
|
+
function groupSelectionState(rows, pendingAdds, pendingRemoves) {
|
|
5361
|
+
const own = rows.filter((r) => assetRefOf(r) !== null);
|
|
5362
|
+
if (own.length === 0) return "empty";
|
|
5363
|
+
const refs = refsOf(own);
|
|
5364
|
+
if (refs.some((r) => pendingAdds.has(r))) return "add";
|
|
5365
|
+
if (refs.some((r) => pendingRemoves.has(r))) return "remove";
|
|
5366
|
+
return own.every((r) => r.installed) ? "installed" : "none";
|
|
5367
|
+
}
|
|
5368
|
+
function groupStatus(rows) {
|
|
5369
|
+
switch (groupSelectionState(rows, state.pendingAdds, state.pendingRemoves)) {
|
|
5370
|
+
case "add":
|
|
5371
|
+
return pc5.blue("+ ");
|
|
5372
|
+
case "remove":
|
|
5373
|
+
return pc5.red("- ");
|
|
5374
|
+
case "installed":
|
|
5375
|
+
return pc5.green("\u2713 ");
|
|
5376
|
+
default:
|
|
5377
|
+
return pc5.dim("\xB7 ");
|
|
5378
|
+
}
|
|
5245
5379
|
}
|
|
5246
5380
|
function renderHeaderLine(opts) {
|
|
5247
5381
|
const indicator = opts.collapsed ? "\u25B6" : "\u25BC";
|
|
@@ -5253,7 +5387,7 @@ function renderHeaderLine(opts) {
|
|
|
5253
5387
|
if (add > 0) count += pc5.green(`+${add}`);
|
|
5254
5388
|
if (remove > 0) count += pc5.red(`-${remove}`);
|
|
5255
5389
|
count += `/${total}`;
|
|
5256
|
-
const status4 = groupStatus(opts.
|
|
5390
|
+
const status4 = groupStatus(countRows.filter(opts.match));
|
|
5257
5391
|
const line = `${opts.indent}${status4}${indicator} ${opts.label} (${count} assets)`;
|
|
5258
5392
|
return opts.selected ? pc5.bgWhite(pc5.black(`${line} `.padEnd(state.cols))) : line;
|
|
5259
5393
|
}
|
|
@@ -5265,7 +5399,6 @@ function renderAssetRow(row, selected) {
|
|
|
5265
5399
|
indent: " ",
|
|
5266
5400
|
collapsed: state.collapsedOrigins.has(origin),
|
|
5267
5401
|
match: (r) => isAsset(r) && rowOrigin(r) === origin,
|
|
5268
|
-
refs: originAssetRefs(state.assetRows, origin),
|
|
5269
5402
|
label: `${meta.icon} ${pc5.bold(pc5.cyan(meta.label))}`,
|
|
5270
5403
|
selected
|
|
5271
5404
|
});
|
|
@@ -5276,7 +5409,6 @@ function renderAssetRow(row, selected) {
|
|
|
5276
5409
|
indent: " ".repeat(3),
|
|
5277
5410
|
collapsed: state.collapsedSources.has(srcKey(origin, row.source)),
|
|
5278
5411
|
match: (r) => isAsset(r) && inSource(r, origin, row.source),
|
|
5279
|
-
refs: sourceAssetRefs(state.assetRows, origin, row.source),
|
|
5280
5412
|
label: pc5.bold(pc5.cyan(row.source)),
|
|
5281
5413
|
selected
|
|
5282
5414
|
});
|
|
@@ -5288,7 +5420,6 @@ function renderAssetRow(row, selected) {
|
|
|
5288
5420
|
indent: " ".repeat(5),
|
|
5289
5421
|
collapsed: state.collapsedPlugins.has(pluginKey(origin, row.source, plugin)),
|
|
5290
5422
|
match: (r) => isAsset(r) && inPlugin(r, origin, row.source, plugin),
|
|
5291
|
-
refs: pluginAssetRefs(state.assetRows, origin, row.source, plugin),
|
|
5292
5423
|
label: pluginHeaderLabel(plugin),
|
|
5293
5424
|
selected
|
|
5294
5425
|
});
|
|
@@ -5331,7 +5462,6 @@ function renderSourceTreeRow(row, selected) {
|
|
|
5331
5462
|
indent: " ".repeat(3),
|
|
5332
5463
|
collapsed: state.collapsedSourceOrgs.has(org),
|
|
5333
5464
|
match: (r) => isAsset(r) && rowOrigin(r) === "source" && rowOrg(r) === org,
|
|
5334
|
-
refs: sourceOrgRefs(state.sourceTreeRows, org),
|
|
5335
5465
|
label: pc5.bold(pc5.cyan(org)),
|
|
5336
5466
|
selected,
|
|
5337
5467
|
rows: state.sourceTreeRows
|
|
@@ -5344,7 +5474,6 @@ function renderSourceTreeRow(row, selected) {
|
|
|
5344
5474
|
indent: " ".repeat(5),
|
|
5345
5475
|
collapsed: state.collapsedSourceRepos.has(repoKey(org, repo)),
|
|
5346
5476
|
match: (r) => isAsset(r) && rowOrigin(r) === "source" && rowOrg(r) === org && rowGroup(r) === repo,
|
|
5347
|
-
refs: sourceRepoRefs(state.sourceTreeRows, org, repo),
|
|
5348
5477
|
label: pc5.bold(repo),
|
|
5349
5478
|
selected,
|
|
5350
5479
|
rows: state.sourceTreeRows
|
|
@@ -5358,7 +5487,6 @@ function renderSourceTreeRow(row, selected) {
|
|
|
5358
5487
|
indent: " ".repeat(7),
|
|
5359
5488
|
collapsed: state.collapsedSourcePlugins.has(srcPluginKey(org, repo, plugin)),
|
|
5360
5489
|
match: (r) => isAsset(r) && rowOrigin(r) === "source" && rowOrg(r) === org && rowGroup(r) === repo && r.plugin === plugin,
|
|
5361
|
-
refs: sourcePluginRefs(state.sourceTreeRows, org, repo, plugin),
|
|
5362
5490
|
label: pluginHeaderLabel(plugin),
|
|
5363
5491
|
selected,
|
|
5364
5492
|
rows: state.sourceTreeRows
|
|
@@ -5379,7 +5507,6 @@ function renderLibraryTreeRow(row, selected) {
|
|
|
5379
5507
|
indent: " ".repeat(3),
|
|
5380
5508
|
collapsed: state.collapsedLibraryGroups.has(group),
|
|
5381
5509
|
match: (r) => isAsset(r) && rowOrigin(r) === "library" && rowGroup(r) === group,
|
|
5382
|
-
refs: libraryGroupRefs(state.libraryTreeRows, group),
|
|
5383
5510
|
label: pc5.bold(pc5.cyan(group)),
|
|
5384
5511
|
selected,
|
|
5385
5512
|
rows: state.libraryTreeRows
|
|
@@ -5392,7 +5519,6 @@ function renderLibraryTreeRow(row, selected) {
|
|
|
5392
5519
|
indent: " ".repeat(5),
|
|
5393
5520
|
collapsed: state.collapsedLibraryPlugins.has(libPluginKey(group, plugin)),
|
|
5394
5521
|
match: (r) => isAsset(r) && inPlugin(r, "library", group, plugin),
|
|
5395
|
-
refs: pluginAssetRefs(state.libraryTreeRows, "library", group, plugin),
|
|
5396
5522
|
label: pluginHeaderLabel(plugin),
|
|
5397
5523
|
selected,
|
|
5398
5524
|
rows: state.libraryTreeRows
|
|
@@ -5480,10 +5606,15 @@ async function applyChanges() {
|
|
|
5480
5606
|
let pruned = 0;
|
|
5481
5607
|
const appliedAdds = [];
|
|
5482
5608
|
const appliedRemoves = [];
|
|
5609
|
+
const blockedRemovals = [];
|
|
5483
5610
|
for (const ref of state.pendingRemoves) {
|
|
5484
5611
|
try {
|
|
5485
5612
|
const result = await am.removeWithDependencies(ref);
|
|
5486
|
-
if (result.
|
|
5613
|
+
if (result.blocked) {
|
|
5614
|
+
blockedRemovals.push(
|
|
5615
|
+
`kept ${result.blocked.ref}: required by ${result.blocked.requiredBy.join(", ")} (skaile remove --force overrides)`
|
|
5616
|
+
);
|
|
5617
|
+
} else if (result.changed) {
|
|
5487
5618
|
removed++;
|
|
5488
5619
|
pruned += result.pruned.length;
|
|
5489
5620
|
appliedRemoves.push(ref);
|
|
@@ -5510,6 +5641,7 @@ async function applyChanges() {
|
|
|
5510
5641
|
if (added > 0) parts.push(pc5.green(`+${added} added`));
|
|
5511
5642
|
if (removed > 0) parts.push(pc5.red(`-${removed} removed`));
|
|
5512
5643
|
if (pruned > 0) parts.push(pc5.red(`-${pruned} no longer required`));
|
|
5644
|
+
for (const b of blockedRemovals) parts.push(pc5.yellow(b));
|
|
5513
5645
|
const softDeps = appliedAdds.length > 0 ? await am.reportSoftDeps(appliedAdds) : [];
|
|
5514
5646
|
if (softDeps.length > 0) {
|
|
5515
5647
|
parts.push(pc5.dim(`${softDeps.length} soft dep${softDeps.length === 1 ? "" : "s"} referenced`));
|
|
@@ -6059,13 +6191,13 @@ async function run(projectDir) {
|
|
|
6059
6191
|
}
|
|
6060
6192
|
function makeManageCommand() {
|
|
6061
6193
|
return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
6062
|
-
await run(
|
|
6194
|
+
await run(path18__default.resolve(opts.projectDir));
|
|
6063
6195
|
});
|
|
6064
6196
|
}
|
|
6065
6197
|
function makeMcpServerCommand() {
|
|
6066
6198
|
return new Command("mcp-server").description("Start skaile workspace MCP server (stdio transport)").option("--project-dir <path>", "Project directory (default: cwd)", process.cwd()).action(async (opts) => {
|
|
6067
|
-
const
|
|
6068
|
-
const projectDir =
|
|
6199
|
+
const path43 = await import('path');
|
|
6200
|
+
const projectDir = path43.default.resolve(opts.projectDir);
|
|
6069
6201
|
const { LogStore, StdoutSink, registerLogStore } = await import('../core/logging.js');
|
|
6070
6202
|
registerLogStore(
|
|
6071
6203
|
new LogStore({
|
|
@@ -6112,10 +6244,10 @@ function walkFiles(root, match) {
|
|
|
6112
6244
|
return;
|
|
6113
6245
|
}
|
|
6114
6246
|
for (const entry of entries) {
|
|
6115
|
-
const full =
|
|
6247
|
+
const full = path18__default.join(dir, entry.name);
|
|
6116
6248
|
if (entry.isDirectory()) {
|
|
6117
6249
|
if (SKIPPED_DIRS.has(entry.name)) continue;
|
|
6118
|
-
if (entry.name === "cache" &&
|
|
6250
|
+
if (entry.name === "cache" && path18__default.basename(dir) === ".skaile") continue;
|
|
6119
6251
|
visit(full);
|
|
6120
6252
|
} else if (entry.isFile() && match(entry.name)) {
|
|
6121
6253
|
out.push(full);
|
|
@@ -6133,14 +6265,14 @@ function applyChanges2(changes) {
|
|
|
6133
6265
|
switch (change.type) {
|
|
6134
6266
|
case "write":
|
|
6135
6267
|
case "create":
|
|
6136
|
-
mkdirSync(
|
|
6268
|
+
mkdirSync(path18__default.dirname(change.path), { recursive: true });
|
|
6137
6269
|
writeFileSync(change.path, change.after, "utf-8");
|
|
6138
6270
|
break;
|
|
6139
6271
|
case "delete":
|
|
6140
6272
|
rmSync(change.path, { force: true });
|
|
6141
6273
|
break;
|
|
6142
6274
|
case "move":
|
|
6143
|
-
mkdirSync(
|
|
6275
|
+
mkdirSync(path18__default.dirname(change.to), { recursive: true });
|
|
6144
6276
|
writeFileSync(change.to, change.after, "utf-8");
|
|
6145
6277
|
rmSync(change.from, { force: true });
|
|
6146
6278
|
break;
|
|
@@ -6233,7 +6365,7 @@ function unifiedDiff(before, after, oldLabel, newLabel, context = 3) {
|
|
|
6233
6365
|
return `${out.join("\n")}
|
|
6234
6366
|
`;
|
|
6235
6367
|
}
|
|
6236
|
-
var posix = (p6) => p6.split(
|
|
6368
|
+
var posix = (p6) => p6.split(path18__default.sep).join("/");
|
|
6237
6369
|
function colorizeDiff(diff) {
|
|
6238
6370
|
return diff.split("\n").map((line) => {
|
|
6239
6371
|
if (line.startsWith("+++") || line.startsWith("---")) return S.bold(line);
|
|
@@ -6244,7 +6376,7 @@ function colorizeDiff(diff) {
|
|
|
6244
6376
|
}).join("\n");
|
|
6245
6377
|
}
|
|
6246
6378
|
function renderChange(change, base) {
|
|
6247
|
-
const rel = (p6) => posix(
|
|
6379
|
+
const rel = (p6) => posix(path18__default.relative(base, p6) || path18__default.basename(p6));
|
|
6248
6380
|
switch (change.type) {
|
|
6249
6381
|
case "write":
|
|
6250
6382
|
return unifiedDiff(
|
|
@@ -6271,7 +6403,7 @@ ${diff}`;
|
|
|
6271
6403
|
}
|
|
6272
6404
|
}
|
|
6273
6405
|
function changeLabel(change, base) {
|
|
6274
|
-
const rel = (p6) => posix(
|
|
6406
|
+
const rel = (p6) => posix(path18__default.relative(base, p6) || path18__default.basename(p6));
|
|
6275
6407
|
switch (change.type) {
|
|
6276
6408
|
case "write":
|
|
6277
6409
|
return `modify ${rel(change.path)}`;
|
|
@@ -6331,10 +6463,10 @@ function loadAsset(projectDir, id, ref) {
|
|
|
6331
6463
|
)
|
|
6332
6464
|
};
|
|
6333
6465
|
}
|
|
6334
|
-
const manifestPath =
|
|
6466
|
+
const manifestPath = path18__default.join(dir, AGENT_MANIFEST_FILE);
|
|
6335
6467
|
let text;
|
|
6336
6468
|
try {
|
|
6337
|
-
text =
|
|
6469
|
+
text = fs8__default.readFileSync(manifestPath, "utf-8");
|
|
6338
6470
|
} catch {
|
|
6339
6471
|
return {
|
|
6340
6472
|
diagnostic: err(
|
|
@@ -6513,12 +6645,12 @@ function findManifestCandidates(rootPath) {
|
|
|
6513
6645
|
function walk(dir) {
|
|
6514
6646
|
let entries;
|
|
6515
6647
|
try {
|
|
6516
|
-
entries =
|
|
6648
|
+
entries = fs8__default.readdirSync(dir, { withFileTypes: true });
|
|
6517
6649
|
} catch {
|
|
6518
6650
|
return;
|
|
6519
6651
|
}
|
|
6520
6652
|
for (const entry of entries) {
|
|
6521
|
-
const fullPath =
|
|
6653
|
+
const fullPath = path18__default.join(dir, entry.name);
|
|
6522
6654
|
if (entry.isDirectory()) {
|
|
6523
6655
|
if (!SKIP_DIRS.has(entry.name)) walk(fullPath);
|
|
6524
6656
|
} else if (entry.isFile()) {
|
|
@@ -6534,30 +6666,11 @@ function findManifestCandidates(rootPath) {
|
|
|
6534
6666
|
walk(rootPath);
|
|
6535
6667
|
return candidates;
|
|
6536
6668
|
}
|
|
6537
|
-
function checkManifestIdentity(kind, parsed) {
|
|
6538
|
-
if (parsed === null || typeof parsed !== "object") return null;
|
|
6539
|
-
const obj = parsed;
|
|
6540
|
-
const identity = kind === "flow" ? obj.id : obj.name;
|
|
6541
|
-
if (typeof identity !== "string" || identity.length === 0) return null;
|
|
6542
|
-
const publisher = typeof obj.publisher === "string" ? obj.publisher : void 0;
|
|
6543
|
-
if (publisher !== void 0) {
|
|
6544
|
-
try {
|
|
6545
|
-
parseAssetRef(`${kind}:@${publisher}/${identity}`);
|
|
6546
|
-
return null;
|
|
6547
|
-
} catch (e) {
|
|
6548
|
-
return e instanceof Error ? e.message : String(e);
|
|
6549
|
-
}
|
|
6550
|
-
}
|
|
6551
|
-
if (!isValidAssetName(identity)) {
|
|
6552
|
-
return `invalid asset ${kind === "flow" ? "id" : "name"} "${identity}" \u2014 ${ASSET_NAME_HINT}`;
|
|
6553
|
-
}
|
|
6554
|
-
return null;
|
|
6555
|
-
}
|
|
6556
6669
|
function parseManifestCandidate(c, absRoot) {
|
|
6557
|
-
const content =
|
|
6670
|
+
const content = fs8__default.readFileSync(c.filePath, "utf-8");
|
|
6558
6671
|
const res = parseManifestFile(c.filePath, content);
|
|
6559
6672
|
if (!res.ok) {
|
|
6560
|
-
logErr(`${
|
|
6673
|
+
logErr(`${path18__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 parse error: ${res.reason}`);
|
|
6561
6674
|
return { kind: "error" };
|
|
6562
6675
|
}
|
|
6563
6676
|
return {
|
|
@@ -6587,34 +6700,32 @@ function checkComposeKinds(parsed, registry) {
|
|
|
6587
6700
|
return diagnostics;
|
|
6588
6701
|
}
|
|
6589
6702
|
function validateManifestCandidate(c, parsed, body, absRoot, registry, strictConformance) {
|
|
6590
|
-
const relPath =
|
|
6703
|
+
const relPath = path18__default.relative(absRoot, c.filePath);
|
|
6591
6704
|
let errors = 0;
|
|
6592
6705
|
let warnings = 0;
|
|
6593
|
-
const
|
|
6594
|
-
|
|
6595
|
-
|
|
6706
|
+
const dirName = path18__default.basename(path18__default.dirname(c.filePath));
|
|
6707
|
+
const checked = checkAsset(
|
|
6708
|
+
c.kind,
|
|
6709
|
+
parsed ?? {},
|
|
6710
|
+
body,
|
|
6711
|
+
dirName,
|
|
6712
|
+
registry
|
|
6713
|
+
);
|
|
6714
|
+
for (const f of checked.errors) {
|
|
6715
|
+
logErr(`${relPath} [${f.tag}] \u2014 ${f.text}`);
|
|
6596
6716
|
errors++;
|
|
6597
6717
|
}
|
|
6598
|
-
|
|
6599
|
-
const
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
logErr(`${relPath} [${c.kind}] \u2014 version "${version}" is not valid semver`);
|
|
6718
|
+
for (const f of checked.advisories) {
|
|
6719
|
+
const line = `${relPath} [${f.tag}] \u2014 ${f.text}`;
|
|
6720
|
+
if (f.conformance && strictConformance) {
|
|
6721
|
+
logErr(line);
|
|
6603
6722
|
errors++;
|
|
6604
|
-
}
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
const line = `${relPath} [${f.tag}] \u2014 ${f.text}`;
|
|
6608
|
-
if (f.conformance && strictConformance) {
|
|
6609
|
-
logErr(line);
|
|
6610
|
-
errors++;
|
|
6611
|
-
} else {
|
|
6612
|
-
logWarn(line);
|
|
6613
|
-
warnings++;
|
|
6614
|
-
}
|
|
6723
|
+
} else {
|
|
6724
|
+
logWarn(line);
|
|
6725
|
+
warnings++;
|
|
6615
6726
|
}
|
|
6616
6727
|
}
|
|
6617
|
-
if (c.kind === "agent" &&
|
|
6728
|
+
if (c.kind === "agent" && path18__default.basename(c.filePath) === "agent.yaml") {
|
|
6618
6729
|
for (const d of [
|
|
6619
6730
|
...checkComposeKinds(parsed, registry),
|
|
6620
6731
|
...composeSlotDiagnostics(parsed),
|
|
@@ -6630,23 +6741,11 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
|
|
|
6630
6741
|
}
|
|
6631
6742
|
}
|
|
6632
6743
|
}
|
|
6633
|
-
const provider = registry.getProvider(c.kind);
|
|
6634
|
-
if (!provider) {
|
|
6635
|
-
logErr(`${relPath} [${c.kind}] \u2014 unknown_asset_kind: kind "${c.kind}" is not registered`);
|
|
6636
|
-
return { errors: errors + 1, warnings };
|
|
6637
|
-
}
|
|
6638
|
-
const result = provider.validateManifest(parsed);
|
|
6639
|
-
if (!result.ok) {
|
|
6640
|
-
for (const err2 of result.errors) {
|
|
6641
|
-
logErr(`${relPath} [${c.kind}] \u2014 ${err2.path ? `${err2.path}: ` : ""}${err2.message}`);
|
|
6642
|
-
}
|
|
6643
|
-
errors += result.errors.length;
|
|
6644
|
-
}
|
|
6645
6744
|
return { errors, warnings };
|
|
6646
6745
|
}
|
|
6647
6746
|
function validateManifests(rootPath, strictConformance) {
|
|
6648
|
-
const absRoot =
|
|
6649
|
-
if (!
|
|
6747
|
+
const absRoot = path18__default.resolve(rootPath);
|
|
6748
|
+
if (!fs8__default.existsSync(absRoot)) {
|
|
6650
6749
|
logErr(`Path does not exist: ${absRoot}`);
|
|
6651
6750
|
return { total: 0, errors: 1, warnings: 0 };
|
|
6652
6751
|
}
|
|
@@ -6674,14 +6773,14 @@ function validateManifests(rootPath, strictConformance) {
|
|
|
6674
6773
|
const obj = parseResult.parsed;
|
|
6675
6774
|
const identity = obj && typeof obj === "object" ? obj[c.kind === "flow" ? "id" : "name"] : null;
|
|
6676
6775
|
if (typeof identity === "string" && identity.length > 0) {
|
|
6677
|
-
const dir =
|
|
6776
|
+
const dir = path18__default.dirname(c.filePath);
|
|
6678
6777
|
const key = `${c.kind}:${identity}`;
|
|
6679
6778
|
const first = seenIdentity.get(key);
|
|
6680
6779
|
if (first === void 0) {
|
|
6681
6780
|
seenIdentity.set(key, dir);
|
|
6682
6781
|
} else if (first !== dir) {
|
|
6683
6782
|
logErr(
|
|
6684
|
-
`${
|
|
6783
|
+
`${path18__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 ${key} is also defined in ${path18__default.relative(absRoot, first) || "."}; two directories cannot share a kind and name (\`skaile library index\` keeps only the first).`
|
|
6685
6784
|
);
|
|
6686
6785
|
errors++;
|
|
6687
6786
|
}
|
|
@@ -6694,12 +6793,12 @@ function findWorkspaceManifests(rootPath) {
|
|
|
6694
6793
|
function walk(dir) {
|
|
6695
6794
|
let entries;
|
|
6696
6795
|
try {
|
|
6697
|
-
entries =
|
|
6796
|
+
entries = fs8__default.readdirSync(dir, { withFileTypes: true });
|
|
6698
6797
|
} catch {
|
|
6699
6798
|
return;
|
|
6700
6799
|
}
|
|
6701
6800
|
for (const entry of entries) {
|
|
6702
|
-
const full =
|
|
6801
|
+
const full = path18__default.join(dir, entry.name);
|
|
6703
6802
|
if (entry.isDirectory()) {
|
|
6704
6803
|
if (!SKIP_DIRS.has(entry.name)) walk(full);
|
|
6705
6804
|
} else if (entry.isFile() && /(^|\.)skaile\.yaml$/.test(entry.name)) {
|
|
@@ -6762,14 +6861,14 @@ function validateWorkspaceAssets(parsed, relPath) {
|
|
|
6762
6861
|
return errors;
|
|
6763
6862
|
}
|
|
6764
6863
|
function validateWorkspaceManifests(rootPath) {
|
|
6765
|
-
const absRoot =
|
|
6864
|
+
const absRoot = path18__default.resolve(rootPath);
|
|
6766
6865
|
const files = findWorkspaceManifests(absRoot);
|
|
6767
6866
|
let errors = 0;
|
|
6768
6867
|
for (const file of files) {
|
|
6769
|
-
const relPath =
|
|
6868
|
+
const relPath = path18__default.relative(absRoot, file);
|
|
6770
6869
|
let parsed;
|
|
6771
6870
|
try {
|
|
6772
|
-
parsed = parse(
|
|
6871
|
+
parsed = parse(fs8__default.readFileSync(file, "utf-8")) ?? {};
|
|
6773
6872
|
} catch (e) {
|
|
6774
6873
|
logErr(`${relPath} \u2014 parse error: ${e instanceof Error ? e.message : String(e)}`);
|
|
6775
6874
|
errors++;
|
|
@@ -6777,7 +6876,7 @@ function validateWorkspaceManifests(rootPath) {
|
|
|
6777
6876
|
}
|
|
6778
6877
|
errors += validateWorkspaceRefs(collectWorkspaceRefFields(parsed), relPath);
|
|
6779
6878
|
errors += validateWorkspaceAssets(parsed, relPath);
|
|
6780
|
-
for (const d of checkAgentInstances(
|
|
6879
|
+
for (const d of checkAgentInstances(path18__default.dirname(file), parsed)) {
|
|
6781
6880
|
const line = `${relPath} [agents] \u2014 ${d.code}: ${d.path ? `${d.path}: ` : ""}${d.message}`;
|
|
6782
6881
|
if (d.severity === "error") {
|
|
6783
6882
|
logErr(line);
|
|
@@ -6790,7 +6889,7 @@ function validateWorkspaceManifests(rootPath) {
|
|
|
6790
6889
|
return { total: files.length, errors };
|
|
6791
6890
|
}
|
|
6792
6891
|
function validatePublishManifestRoots(rootPath) {
|
|
6793
|
-
const absRoot =
|
|
6892
|
+
const absRoot = path18__default.resolve(rootPath);
|
|
6794
6893
|
const manifest = loadSkPublishManifest(absRoot);
|
|
6795
6894
|
if (!manifest) return 0;
|
|
6796
6895
|
const missing = missingRootAssets(absRoot, manifest);
|
|
@@ -6802,7 +6901,7 @@ function validatePublishManifestRoots(rootPath) {
|
|
|
6802
6901
|
return missing.length;
|
|
6803
6902
|
}
|
|
6804
6903
|
function validatePublishManifestRequires(rootPath) {
|
|
6805
|
-
const problems = manifestRequiresProblems(
|
|
6904
|
+
const problems = manifestRequiresProblems(path18__default.resolve(rootPath));
|
|
6806
6905
|
for (const p6 of problems) {
|
|
6807
6906
|
logErr(
|
|
6808
6907
|
`${SKAILE_MANIFEST_FILENAME} [assets] \u2014 ${p6.asset}: ${p6.message}. Use the \`kind:@<publisher>/name[#version]\` form.`
|
|
@@ -6810,16 +6909,21 @@ function validatePublishManifestRequires(rootPath) {
|
|
|
6810
6909
|
}
|
|
6811
6910
|
return problems.length;
|
|
6812
6911
|
}
|
|
6912
|
+
function validatePublishManifestPublisherSlugs(rootPath) {
|
|
6913
|
+
const problems = manifestPublisherProblems(path18__default.resolve(rootPath));
|
|
6914
|
+
for (const message of problems) logErr(message);
|
|
6915
|
+
return problems.length;
|
|
6916
|
+
}
|
|
6813
6917
|
function validatePublishManifestVersions(rootPath) {
|
|
6814
|
-
const absRoot =
|
|
6918
|
+
const absRoot = path18__default.resolve(rootPath);
|
|
6815
6919
|
const manifest = loadSkPublishManifest(absRoot);
|
|
6816
6920
|
if (!manifest || manifest.source) return 0;
|
|
6817
6921
|
let warnings = 0;
|
|
6818
6922
|
for (const a of manifest.assets ?? []) {
|
|
6819
6923
|
if (!a.root || a.source || !a.version) continue;
|
|
6820
|
-
const file = findAssetManifestFile(
|
|
6924
|
+
const file = findAssetManifestFile(path18__default.join(absRoot, a.root), a.kind, a.name);
|
|
6821
6925
|
if (!file) continue;
|
|
6822
|
-
const res = parseManifestFile(file,
|
|
6926
|
+
const res = parseManifestFile(file, fs8__default.readFileSync(file, "utf-8"));
|
|
6823
6927
|
if (!res.ok) continue;
|
|
6824
6928
|
const fileVersion = declaredVersion(res.data);
|
|
6825
6929
|
if (fileVersion === void 0 || fileVersion === a.version) continue;
|
|
@@ -6827,7 +6931,7 @@ function validatePublishManifestVersions(rootPath) {
|
|
|
6827
6931
|
manifestVersionMismatchMessage(
|
|
6828
6932
|
assetEntryRef(a, manifest),
|
|
6829
6933
|
a.version,
|
|
6830
|
-
toPosix(
|
|
6934
|
+
toPosix(path18__default.relative(absRoot, file)),
|
|
6831
6935
|
fileVersion
|
|
6832
6936
|
)
|
|
6833
6937
|
);
|
|
@@ -6836,7 +6940,7 @@ function validatePublishManifestVersions(rootPath) {
|
|
|
6836
6940
|
return warnings;
|
|
6837
6941
|
}
|
|
6838
6942
|
function validatePublishManifestPublishers(rootPath) {
|
|
6839
|
-
const absRoot =
|
|
6943
|
+
const absRoot = path18__default.resolve(rootPath);
|
|
6840
6944
|
const manifest = loadSkPublishManifest(absRoot);
|
|
6841
6945
|
if (!manifest || manifest.source) return 0;
|
|
6842
6946
|
const bare = (p6) => p6.trim().replace(/^@/, "");
|
|
@@ -6844,15 +6948,15 @@ function validatePublishManifestPublishers(rootPath) {
|
|
|
6844
6948
|
for (const a of manifest.assets ?? []) {
|
|
6845
6949
|
const resolved = a.publisher ?? manifest.publisher;
|
|
6846
6950
|
if (!a.root || a.source || !resolved) continue;
|
|
6847
|
-
const file = findAssetManifestFile(
|
|
6951
|
+
const file = findAssetManifestFile(path18__default.join(absRoot, a.root), a.kind, a.name);
|
|
6848
6952
|
if (!file) continue;
|
|
6849
|
-
const res = parseManifestFile(file,
|
|
6953
|
+
const res = parseManifestFile(file, fs8__default.readFileSync(file, "utf-8"));
|
|
6850
6954
|
if (!res.ok) continue;
|
|
6851
6955
|
const meta = res.data.metadata;
|
|
6852
6956
|
const declared = meta !== null && typeof meta === "object" ? meta.publisher : null;
|
|
6853
6957
|
if (typeof declared !== "string" || bare(declared) === bare(resolved)) continue;
|
|
6854
6958
|
logWarn(
|
|
6855
|
-
`${toPosix(
|
|
6959
|
+
`${toPosix(path18__default.relative(absRoot, file))} [publisher] \u2014 metadata.publisher "${bare(declared)}" differs from the manifest publisher "${bare(resolved)}" for ${assetEntryRef(a, manifest)}. The manifest wins and the file value is ignored: delete \`metadata.publisher\` from the file, or set the publisher in ${SKAILE_MANIFEST_FILENAME}.`
|
|
6856
6960
|
);
|
|
6857
6961
|
warnings++;
|
|
6858
6962
|
}
|
|
@@ -6860,7 +6964,7 @@ function validatePublishManifestPublishers(rootPath) {
|
|
|
6860
6964
|
}
|
|
6861
6965
|
var EXCLUDED_PATHS = ["skaileup-shared/", "external/", "docs/"];
|
|
6862
6966
|
function toPosix(p6) {
|
|
6863
|
-
return p6.split(
|
|
6967
|
+
return p6.split(path18__default.sep).join("/");
|
|
6864
6968
|
}
|
|
6865
6969
|
function isExcludedPath(relPath) {
|
|
6866
6970
|
const rel = toPosix(relPath);
|
|
@@ -6870,20 +6974,23 @@ var VERSIONED_KINDS = {
|
|
|
6870
6974
|
skill: true,
|
|
6871
6975
|
agent: true,
|
|
6872
6976
|
flow: true,
|
|
6873
|
-
prompt: true
|
|
6977
|
+
prompt: true,
|
|
6978
|
+
preset: true,
|
|
6979
|
+
contract: true
|
|
6874
6980
|
};
|
|
6875
6981
|
function readAssetVersion(c) {
|
|
6876
6982
|
const kind = c.kind;
|
|
6877
|
-
const fileName =
|
|
6878
|
-
const dirName =
|
|
6879
|
-
const content =
|
|
6983
|
+
const fileName = path18__default.basename(c.filePath);
|
|
6984
|
+
const dirName = path18__default.basename(path18__default.dirname(c.filePath));
|
|
6985
|
+
const content = fs8__default.readFileSync(c.filePath, "utf-8");
|
|
6880
6986
|
if (c.filePath.endsWith(".md")) {
|
|
6881
|
-
const
|
|
6987
|
+
const res = parseManifestFile(c.filePath, content);
|
|
6988
|
+
const data = res.ok ? res.data : {};
|
|
6882
6989
|
const stem = fileName.replace(/\.prompt\.md$/, "");
|
|
6883
6990
|
return {
|
|
6884
6991
|
kind,
|
|
6885
|
-
name:
|
|
6886
|
-
version:
|
|
6992
|
+
name: typeof data.name === "string" ? data.name : kind === "prompt" ? stem : dirName,
|
|
6993
|
+
version: declaredVersion(data) ?? "",
|
|
6887
6994
|
filePath: c.filePath
|
|
6888
6995
|
};
|
|
6889
6996
|
}
|
|
@@ -6908,26 +7015,26 @@ function readAssetVersion(c) {
|
|
|
6908
7015
|
};
|
|
6909
7016
|
}
|
|
6910
7017
|
function collectAssetVersions(root) {
|
|
6911
|
-
if (!
|
|
7018
|
+
if (!fs8__default.existsSync(root)) return [];
|
|
6912
7019
|
const assets = [];
|
|
6913
7020
|
for (const c of findManifestCandidates(root)) {
|
|
6914
7021
|
if (!VERSIONED_KINDS[c.kind]) continue;
|
|
6915
7022
|
if (c.filePath.endsWith(".flow.json")) continue;
|
|
6916
|
-
if (isExcludedPath(
|
|
7023
|
+
if (isExcludedPath(path18__default.relative(root, c.filePath))) continue;
|
|
6917
7024
|
assets.push(readAssetVersion(c));
|
|
6918
7025
|
}
|
|
6919
7026
|
return assets;
|
|
6920
7027
|
}
|
|
6921
7028
|
function assetLocation(a, root) {
|
|
6922
|
-
return toPosix(
|
|
7029
|
+
return toPosix(path18__default.relative(root, a.filePath));
|
|
6923
7030
|
}
|
|
6924
7031
|
function findChangelogUnit(assetRelPath, root) {
|
|
6925
|
-
let dir =
|
|
7032
|
+
let dir = path18__default.posix.dirname(toPosix(assetRelPath));
|
|
6926
7033
|
for (; ; ) {
|
|
6927
7034
|
const candidate = dir === "." ? "CHANGELOG.md" : `${dir}/CHANGELOG.md`;
|
|
6928
|
-
if (
|
|
7035
|
+
if (fs8__default.existsSync(path18__default.join(root, candidate))) return candidate;
|
|
6929
7036
|
if (dir === ".") return null;
|
|
6930
|
-
dir =
|
|
7037
|
+
dir = path18__default.posix.dirname(dir);
|
|
6931
7038
|
}
|
|
6932
7039
|
}
|
|
6933
7040
|
function checkChangelogUnits(modifiedFiles, root) {
|
|
@@ -6945,9 +7052,6 @@ function checkChangelogUnits(modifiedFiles, root) {
|
|
|
6945
7052
|
const stale = [...units].filter((u) => !modified.has(u));
|
|
6946
7053
|
return { updated, stale, orphans };
|
|
6947
7054
|
}
|
|
6948
|
-
function isValidSemver(v) {
|
|
6949
|
-
return SEMVER_RE.test(v);
|
|
6950
|
-
}
|
|
6951
7055
|
function extractVersionFromContent(filePath, content) {
|
|
6952
7056
|
if (filePath.endsWith(".yaml")) {
|
|
6953
7057
|
const parsed2 = parse(content);
|
|
@@ -6962,13 +7066,15 @@ function checkAssetVersions(assets, root) {
|
|
|
6962
7066
|
let errors = 0;
|
|
6963
7067
|
const warnings = 0;
|
|
6964
7068
|
for (const a of assets) {
|
|
7069
|
+
const location = assetLocation(a, root);
|
|
6965
7070
|
if (!a.version) {
|
|
6966
|
-
logErr(`${a.kind}:${a.name} (${
|
|
7071
|
+
logErr(`${a.kind}:${a.name} (${location}) \u2014 missing version`);
|
|
6967
7072
|
errors++;
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
7073
|
+
continue;
|
|
7074
|
+
}
|
|
7075
|
+
const invalid = invalidSemverText(a.version);
|
|
7076
|
+
if (invalid) {
|
|
7077
|
+
logErr(`${a.kind}:${a.name} (${location}) \u2014 ${invalid}`);
|
|
6972
7078
|
errors++;
|
|
6973
7079
|
}
|
|
6974
7080
|
}
|
|
@@ -6978,7 +7084,7 @@ function checkVersionBumps(assets, root) {
|
|
|
6978
7084
|
let warnings = 0;
|
|
6979
7085
|
for (const a of assets) {
|
|
6980
7086
|
if (!a.version) continue;
|
|
6981
|
-
const relPath = toPosix(
|
|
7087
|
+
const relPath = toPosix(path18__default.relative(root, a.filePath));
|
|
6982
7088
|
try {
|
|
6983
7089
|
const headContent = execFileSync("git", ["show", `HEAD:./${relPath}`], {
|
|
6984
7090
|
cwd: root,
|
|
@@ -7011,7 +7117,7 @@ function checkFlowVersionPins(assets, root) {
|
|
|
7011
7117
|
pins = flowSkillVersionPins(loadFlow(f.filePath));
|
|
7012
7118
|
} catch (err2) {
|
|
7013
7119
|
logWarn(
|
|
7014
|
-
`flow:${f.name} (${
|
|
7120
|
+
`flow:${f.name} (${path18__default.relative(root, f.filePath)}) \u2014 could not be read: ${err2 instanceof Error ? err2.message : err2}`
|
|
7015
7121
|
);
|
|
7016
7122
|
warnings++;
|
|
7017
7123
|
continue;
|
|
@@ -7029,16 +7135,16 @@ function checkFlowVersionPins(assets, root) {
|
|
|
7029
7135
|
}
|
|
7030
7136
|
function resolveCheckRoot(pathArg) {
|
|
7031
7137
|
if (pathArg) {
|
|
7032
|
-
const abs =
|
|
7033
|
-
if (!
|
|
7138
|
+
const abs = path18__default.resolve(pathArg);
|
|
7139
|
+
if (!fs8__default.existsSync(abs)) {
|
|
7034
7140
|
logErr(`Path does not exist: ${abs}`);
|
|
7035
7141
|
return null;
|
|
7036
7142
|
}
|
|
7037
7143
|
return abs;
|
|
7038
7144
|
}
|
|
7039
|
-
for (let dir = process.cwd(); ; dir =
|
|
7040
|
-
if (
|
|
7041
|
-
if (
|
|
7145
|
+
for (let dir = process.cwd(); ; dir = path18__default.dirname(dir)) {
|
|
7146
|
+
if (fs8__default.existsSync(path18__default.join(dir, SKAILE_MANIFEST_FILENAME))) return dir;
|
|
7147
|
+
if (path18__default.dirname(dir) === dir) return AI_RESOURCES;
|
|
7042
7148
|
}
|
|
7043
7149
|
}
|
|
7044
7150
|
function changedFiles(root, ref) {
|
|
@@ -7073,7 +7179,7 @@ function runVersionsCheck(pathArg, opts) {
|
|
|
7073
7179
|
process.exit(1);
|
|
7074
7180
|
return;
|
|
7075
7181
|
}
|
|
7076
|
-
const changedAbs = new Set(changed.map((f) =>
|
|
7182
|
+
const changedAbs = new Set(changed.map((f) => path18__default.resolve(root, f)));
|
|
7077
7183
|
assets = assets.filter((a) => changedAbs.has(a.filePath));
|
|
7078
7184
|
}
|
|
7079
7185
|
logInfo(`Checking versions in ${root}`);
|
|
@@ -7105,8 +7211,8 @@ function makeValidateCommand() {
|
|
|
7105
7211
|
cmd.argument("[path]", "Path to asset repo or directory to validate", ".").option(
|
|
7106
7212
|
"--strict-conformance",
|
|
7107
7213
|
"Treat Agent Skills (agentskills.io) standard findings as errors"
|
|
7108
|
-
).action((targetPath, opts) => {
|
|
7109
|
-
const absPath =
|
|
7214
|
+
).action(async (targetPath, opts) => {
|
|
7215
|
+
const absPath = path18__default.resolve(targetPath);
|
|
7110
7216
|
logInfo(`Validating manifests in ${absPath}`);
|
|
7111
7217
|
const { total, errors, warnings } = validateManifests(
|
|
7112
7218
|
absPath,
|
|
@@ -7114,15 +7220,19 @@ function makeValidateCommand() {
|
|
|
7114
7220
|
);
|
|
7115
7221
|
const ws = validateWorkspaceManifests(absPath);
|
|
7116
7222
|
const rootErrors = validatePublishManifestRoots(absPath);
|
|
7223
|
+
const slugErrors = validatePublishManifestPublisherSlugs(absPath);
|
|
7117
7224
|
const requiresErrors = validatePublishManifestRequires(absPath);
|
|
7118
7225
|
const versionWarnings = validatePublishManifestVersions(absPath);
|
|
7119
7226
|
const publisherWarnings = validatePublishManifestPublishers(absPath);
|
|
7120
|
-
const
|
|
7227
|
+
const dependencyProblems = await unresolvedManifestDependencies(absPath);
|
|
7228
|
+
for (const w of dependencyProblems) logWarn(w);
|
|
7229
|
+
const dependencyWarnings = dependencyProblems.length;
|
|
7230
|
+
const totalErrors = errors + ws.errors + rootErrors + slugErrors + requiresErrors;
|
|
7121
7231
|
console.log();
|
|
7122
7232
|
warnIgnoredDomainFiles(absPath);
|
|
7123
7233
|
warnLegacyBundleFiles(absPath);
|
|
7124
7234
|
logInfo(`Scanned ${total} asset manifest(s) and ${ws.total} skaile.yaml file(s)`);
|
|
7125
|
-
const totalWarnings = warnings + versionWarnings + publisherWarnings;
|
|
7235
|
+
const totalWarnings = warnings + versionWarnings + publisherWarnings + dependencyWarnings;
|
|
7126
7236
|
if (totalWarnings > 0) logWarn(`${totalWarnings} warning(s)`);
|
|
7127
7237
|
if (totalErrors === 0) {
|
|
7128
7238
|
logOk("All manifests valid");
|
|
@@ -7192,7 +7302,7 @@ function itemFromRef(raw, defaultKind, ctx) {
|
|
|
7192
7302
|
return { kind: prefixed[1], ref: value };
|
|
7193
7303
|
}
|
|
7194
7304
|
if (PATH_LIKE.test(value)) return { kind: defaultKind, ref: value };
|
|
7195
|
-
if (defaultKind === "skill" && !value.includes("/") && existsSync(
|
|
7305
|
+
if (defaultKind === "skill" && !value.includes("/") && existsSync(path18__default.join(ctx.agentDir, "skills", value, "SKILL.md"))) {
|
|
7196
7306
|
return { kind: "skill", ref: `./skills/${value}` };
|
|
7197
7307
|
}
|
|
7198
7308
|
return { kind: defaultKind, ref: `${defaultKind}:${value}` };
|
|
@@ -7328,7 +7438,7 @@ function migrateAgentYaml(source, options) {
|
|
|
7328
7438
|
manual.push("metadata.soul: not a string; left unchanged");
|
|
7329
7439
|
continue;
|
|
7330
7440
|
}
|
|
7331
|
-
if (
|
|
7441
|
+
if (path18__default.posix.basename(soul.replace(/\\/g, "/")).toLowerCase() === "soul.md") {
|
|
7332
7442
|
notes.push("metadata.soul \u2192 dropped (SOUL.md is a convention file)");
|
|
7333
7443
|
} else {
|
|
7334
7444
|
derived.push({ kind: "persona", ref: soul });
|
|
@@ -7562,7 +7672,7 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7562
7672
|
if (!isMap(agentNode)) return void 0;
|
|
7563
7673
|
const subNode = agentNode.get("subagents", true);
|
|
7564
7674
|
if (!isMap(subNode)) return void 0;
|
|
7565
|
-
const dir =
|
|
7675
|
+
const dir = path18__default.dirname(skaileYamlPath);
|
|
7566
7676
|
const notes = [];
|
|
7567
7677
|
const manual = [];
|
|
7568
7678
|
const changes = [];
|
|
@@ -7580,10 +7690,10 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7580
7690
|
continue;
|
|
7581
7691
|
}
|
|
7582
7692
|
const id = instanceId(name);
|
|
7583
|
-
const assetDir =
|
|
7693
|
+
const assetDir = path18__default.join(dir, ".skaile", "agents", id);
|
|
7584
7694
|
if (takenIds.has(id) || existsSync(assetDir)) {
|
|
7585
7695
|
manual.push(
|
|
7586
|
-
`agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${
|
|
7696
|
+
`agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${path18__default.relative(dir, assetDir)} already exists`}; left in place`
|
|
7587
7697
|
);
|
|
7588
7698
|
continue;
|
|
7589
7699
|
}
|
|
@@ -7607,13 +7717,13 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7607
7717
|
manifest.tools = { ...allowed ? { allowed } : {}, ...denied ? { denied } : {} };
|
|
7608
7718
|
}
|
|
7609
7719
|
const text = stringify(manifest, { lineWidth: 0 });
|
|
7610
|
-
const manifestPath =
|
|
7720
|
+
const manifestPath = path18__default.join(assetDir, "agent.yaml");
|
|
7611
7721
|
changes.push({ type: "create", path: manifestPath, after: text });
|
|
7612
7722
|
assetManifests.push({ file: manifestPath, text });
|
|
7613
7723
|
if (typeof spec.prompt === "string" && spec.prompt.trim() !== "") {
|
|
7614
7724
|
changes.push({
|
|
7615
7725
|
type: "create",
|
|
7616
|
-
path:
|
|
7726
|
+
path: path18__default.join(assetDir, "SOUL.md"),
|
|
7617
7727
|
after: `${spec.prompt.replace(/\s+$/, "")}
|
|
7618
7728
|
`
|
|
7619
7729
|
});
|
|
@@ -7672,7 +7782,7 @@ function validateMigratedAgent(text, registry) {
|
|
|
7672
7782
|
function collectAgentFiles(paths) {
|
|
7673
7783
|
const files = /* @__PURE__ */ new Set();
|
|
7674
7784
|
for (const input of paths) {
|
|
7675
|
-
const abs =
|
|
7785
|
+
const abs = path18__default.resolve(input);
|
|
7676
7786
|
if (!existsSync(abs)) continue;
|
|
7677
7787
|
if (statSync(abs).isDirectory()) {
|
|
7678
7788
|
for (const f of walkFiles(abs, (b) => b === "agent.yaml" || b === "skaile.yaml"))
|
|
@@ -7689,7 +7799,7 @@ function planAgentMigration(options) {
|
|
|
7689
7799
|
const reports = [];
|
|
7690
7800
|
for (const file of collectAgentFiles(options.paths)) {
|
|
7691
7801
|
const source = readText(file);
|
|
7692
|
-
const base =
|
|
7802
|
+
const base = path18__default.basename(file);
|
|
7693
7803
|
if (base === "skaile.yaml") {
|
|
7694
7804
|
const result = migrateSubagents(file, source);
|
|
7695
7805
|
if (!result) continue;
|
|
@@ -7697,7 +7807,7 @@ function planAgentMigration(options) {
|
|
|
7697
7807
|
for (const asset of result.assetManifests) {
|
|
7698
7808
|
const v = validateMigratedAgent(asset.text, options.registry);
|
|
7699
7809
|
validation2.errors.push(
|
|
7700
|
-
...v.errors.map((e) => `${
|
|
7810
|
+
...v.errors.map((e) => `${path18__default.basename(path18__default.dirname(asset.file))}: ${e}`)
|
|
7701
7811
|
);
|
|
7702
7812
|
validation2.warnings.push(...v.warnings);
|
|
7703
7813
|
}
|
|
@@ -7725,7 +7835,7 @@ function planAgentMigration(options) {
|
|
|
7725
7835
|
});
|
|
7726
7836
|
continue;
|
|
7727
7837
|
}
|
|
7728
|
-
migration = migrateAgentYaml(source, { agentDir:
|
|
7838
|
+
migration = migrateAgentYaml(source, { agentDir: path18__default.dirname(file), knownKinds });
|
|
7729
7839
|
} catch (error) {
|
|
7730
7840
|
reports.push({
|
|
7731
7841
|
file,
|
|
@@ -7753,8 +7863,9 @@ function planAgentMigration(options) {
|
|
|
7753
7863
|
return { changes, reports };
|
|
7754
7864
|
}
|
|
7755
7865
|
var DEFAULT_PUBLISHER = "skaile-ai";
|
|
7866
|
+
var PRESET_DEFAULT_VERSION = "1.0.0";
|
|
7756
7867
|
var FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
7757
|
-
var posix2 = (p6) => p6.split(
|
|
7868
|
+
var posix2 = (p6) => p6.split(path18__default.sep).join("/");
|
|
7758
7869
|
var MOVED_KINDS = { persona: "PERSONA.md", ruleset: "RULESET.md" };
|
|
7759
7870
|
var KIND_MANIFEST_FILES = /* @__PURE__ */ new Set(["PERSONA.md", "RULESET.md", "SKILL.md"]);
|
|
7760
7871
|
function readFrontmatterType(text) {
|
|
@@ -7785,14 +7896,14 @@ function planMarkdownMoves(root, knownKinds, manual, unknownTypes) {
|
|
|
7785
7896
|
if (!text.startsWith("---")) continue;
|
|
7786
7897
|
const found = readFrontmatterType(text);
|
|
7787
7898
|
if (!found) continue;
|
|
7788
|
-
const base =
|
|
7789
|
-
const inAgentParts = file.split(
|
|
7899
|
+
const base = path18__default.basename(file);
|
|
7900
|
+
const inAgentParts = file.split(path18__default.sep).includes("_agent-parts");
|
|
7790
7901
|
const targetName = MOVED_KINDS[found.type];
|
|
7791
7902
|
if (targetName !== void 0 && !KIND_MANIFEST_FILES.has(base)) {
|
|
7792
|
-
const to =
|
|
7903
|
+
const to = path18__default.join(path18__default.dirname(file), base.replace(/\.md$/i, ""), targetName);
|
|
7793
7904
|
if (existsSync(to) || targets.has(to)) {
|
|
7794
7905
|
manual.push(
|
|
7795
|
-
`${posix2(
|
|
7906
|
+
`${posix2(path18__default.relative(root, file))}: ${posix2(path18__default.relative(root, to))} already exists; not moved`
|
|
7796
7907
|
);
|
|
7797
7908
|
continue;
|
|
7798
7909
|
}
|
|
@@ -7813,13 +7924,13 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
|
|
|
7813
7924
|
const changes = [];
|
|
7814
7925
|
for (const file of walkFiles(root, (b) => b === "agent.yaml")) {
|
|
7815
7926
|
const source = readText(file);
|
|
7816
|
-
const agentDir =
|
|
7927
|
+
const agentDir = path18__default.dirname(file);
|
|
7817
7928
|
let hits = 0;
|
|
7818
7929
|
const refRewrite = (_kind, ref) => {
|
|
7819
|
-
const moved = byOldPath.get(
|
|
7930
|
+
const moved = byOldPath.get(path18__default.resolve(agentDir, ref));
|
|
7820
7931
|
if (moved === void 0) return ref;
|
|
7821
7932
|
hits++;
|
|
7822
|
-
const rel = posix2(
|
|
7933
|
+
const rel = posix2(path18__default.relative(agentDir, moved));
|
|
7823
7934
|
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
7824
7935
|
};
|
|
7825
7936
|
let output;
|
|
@@ -7836,7 +7947,7 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
|
|
|
7836
7947
|
if (hits === 0 || output === source) continue;
|
|
7837
7948
|
changes.push({ type: "write", path: file, before: source, after: output });
|
|
7838
7949
|
notes.push(
|
|
7839
|
-
`${posix2(
|
|
7950
|
+
`${posix2(path18__default.relative(root, file))}: persona/ruleset refs \u2192 composes items at the new paths`
|
|
7840
7951
|
);
|
|
7841
7952
|
}
|
|
7842
7953
|
return changes;
|
|
@@ -7847,12 +7958,12 @@ function presetItemRef(dep, publisher) {
|
|
|
7847
7958
|
const [, kind, rest] = match;
|
|
7848
7959
|
return rest.startsWith("@") ? dep.trim() : `${kind}:@${publisher}/${rest}`;
|
|
7849
7960
|
}
|
|
7850
|
-
function presetText(name, description, refs, publisher) {
|
|
7961
|
+
function presetText(name, description, refs, publisher, version) {
|
|
7851
7962
|
return stringify(
|
|
7852
7963
|
{
|
|
7853
7964
|
publisher,
|
|
7854
7965
|
name,
|
|
7855
|
-
version
|
|
7966
|
+
version,
|
|
7856
7967
|
description: description && description.trim() !== "" ? description : `Preset ${name}`,
|
|
7857
7968
|
items: refs.map((ref) => ({ ref }))
|
|
7858
7969
|
},
|
|
@@ -7861,14 +7972,14 @@ function presetText(name, description, refs, publisher) {
|
|
|
7861
7972
|
}
|
|
7862
7973
|
function skillDirs(dir) {
|
|
7863
7974
|
try {
|
|
7864
|
-
return readdirSync(
|
|
7975
|
+
return readdirSync(path18__default.join(dir, "skills"), { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync(path18__default.join(dir, "skills", e.name, "SKILL.md"))).map((e) => e.name).sort();
|
|
7865
7976
|
} catch {
|
|
7866
7977
|
return [];
|
|
7867
7978
|
}
|
|
7868
7979
|
}
|
|
7869
7980
|
function repoPublisher(root) {
|
|
7870
7981
|
for (const name of ["skaile.manifest.yaml", "skaile.yaml"]) {
|
|
7871
|
-
const file =
|
|
7982
|
+
const file = path18__default.join(root, name);
|
|
7872
7983
|
if (!existsSync(file)) continue;
|
|
7873
7984
|
try {
|
|
7874
7985
|
const parsed = parse(readText(file));
|
|
@@ -7884,9 +7995,9 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7884
7995
|
const changes = [];
|
|
7885
7996
|
const presets = [];
|
|
7886
7997
|
const handled = /* @__PURE__ */ new Set();
|
|
7887
|
-
const rel = (p6) => posix2(
|
|
7998
|
+
const rel = (p6) => posix2(path18__default.relative(root, p6));
|
|
7888
7999
|
const convert = (name, bundleFile, dir) => {
|
|
7889
|
-
const target =
|
|
8000
|
+
const target = path18__default.join(dir, `${name}.preset.yaml`);
|
|
7890
8001
|
if (existsSync(target)) {
|
|
7891
8002
|
manual.push(`${rel(target)} already exists; bundle ${name} not converted`);
|
|
7892
8003
|
return;
|
|
@@ -7894,11 +8005,16 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7894
8005
|
let description;
|
|
7895
8006
|
let refs = [];
|
|
7896
8007
|
let before;
|
|
8008
|
+
let version = PRESET_DEFAULT_VERSION;
|
|
8009
|
+
let versionNote;
|
|
7897
8010
|
if (bundleFile && existsSync(bundleFile)) {
|
|
7898
8011
|
before = readText(bundleFile);
|
|
7899
8012
|
const parsed = parse(before);
|
|
7900
8013
|
if (isRecord(parsed)) {
|
|
7901
8014
|
if (typeof parsed.description === "string") description = parsed.description;
|
|
8015
|
+
const declared = typeof parsed.version === "string" || typeof parsed.version === "number" ? String(parsed.version) : void 0;
|
|
8016
|
+
if (declared !== void 0 && SEMVER_RE.test(declared)) version = declared;
|
|
8017
|
+
else if (declared !== void 0) versionNote = `version ${declared} \u2192 ${version}`;
|
|
7902
8018
|
const deps = Array.isArray(parsed.dependencies) ? parsed.dependencies : [];
|
|
7903
8019
|
refs = deps.filter((d) => typeof d === "string").map((d) => presetItemRef(d, publisher));
|
|
7904
8020
|
if (refs.length !== deps.length) {
|
|
@@ -7912,11 +8028,11 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7912
8028
|
}
|
|
7913
8029
|
if (refs.length === 0) {
|
|
7914
8030
|
manual.push(
|
|
7915
|
-
`bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(
|
|
8031
|
+
`bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(path18__default.join(dir, "skills"))}`}; no preset generated`
|
|
7916
8032
|
);
|
|
7917
8033
|
return;
|
|
7918
8034
|
}
|
|
7919
|
-
const after = presetText(name, description, refs, publisher);
|
|
8035
|
+
const after = presetText(name, description, refs, publisher, version);
|
|
7920
8036
|
if (before !== void 0 && bundleFile) {
|
|
7921
8037
|
changes.push({ type: "move", from: bundleFile, to: target, before, after });
|
|
7922
8038
|
handled.add(bundleFile);
|
|
@@ -7928,24 +8044,26 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7928
8044
|
file: target,
|
|
7929
8045
|
...bundleFile && before !== void 0 ? { bundleFile } : {}
|
|
7930
8046
|
});
|
|
7931
|
-
notes.push(
|
|
8047
|
+
notes.push(
|
|
8048
|
+
`bundle ${name} \u2192 ${rel(target)} (${refs.length} items${versionNote ? `, ${versionNote}` : ""})`
|
|
8049
|
+
);
|
|
7932
8050
|
};
|
|
7933
8051
|
for (const { file, raw } of skaileYamls) {
|
|
7934
8052
|
const assets = Array.isArray(raw.assets) ? raw.assets : [];
|
|
7935
8053
|
for (const entry of assets) {
|
|
7936
8054
|
if (!isRecord(entry) || entry.kind !== "bundle" || typeof entry.name !== "string") continue;
|
|
7937
|
-
const baseDir =
|
|
7938
|
-
const entryRoot = typeof entry.root === "string" ?
|
|
8055
|
+
const baseDir = path18__default.dirname(file);
|
|
8056
|
+
const entryRoot = typeof entry.root === "string" ? path18__default.join(baseDir, entry.root) : baseDir;
|
|
7939
8057
|
const files = Array.isArray(entry.files) ? entry.files : [];
|
|
7940
8058
|
const bundleName = files.find(
|
|
7941
8059
|
(f) => typeof f === "string" && f.endsWith(".bundle.yaml")
|
|
7942
8060
|
);
|
|
7943
|
-
convert(entry.name, bundleName ?
|
|
8061
|
+
convert(entry.name, bundleName ? path18__default.join(entryRoot, bundleName) : void 0, entryRoot);
|
|
7944
8062
|
}
|
|
7945
8063
|
}
|
|
7946
8064
|
for (const bundleFile of walkFiles(root, (b) => b.endsWith(".bundle.yaml"))) {
|
|
7947
8065
|
if (handled.has(bundleFile)) continue;
|
|
7948
|
-
const base =
|
|
8066
|
+
const base = path18__default.basename(bundleFile);
|
|
7949
8067
|
let name = base.replace(/\.bundle\.yaml$/, "");
|
|
7950
8068
|
try {
|
|
7951
8069
|
const parsed = parse(readText(bundleFile));
|
|
@@ -7954,7 +8072,7 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7954
8072
|
} catch {
|
|
7955
8073
|
}
|
|
7956
8074
|
if (presets.some((p6) => p6.bundleFile === bundleFile)) continue;
|
|
7957
|
-
convert(name, bundleFile,
|
|
8075
|
+
convert(name, bundleFile, path18__default.dirname(bundleFile));
|
|
7958
8076
|
}
|
|
7959
8077
|
return changes;
|
|
7960
8078
|
}
|
|
@@ -7964,8 +8082,8 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
7964
8082
|
if (doc.errors.length > 0 || !isMap(doc.contents)) return [];
|
|
7965
8083
|
const map = doc.contents;
|
|
7966
8084
|
const raw = doc.toJS();
|
|
7967
|
-
const dir =
|
|
7968
|
-
const rel = (p6) => posix2(
|
|
8085
|
+
const dir = path18__default.dirname(file);
|
|
8086
|
+
const rel = (p6) => posix2(path18__default.relative(root, p6));
|
|
7969
8087
|
const changes = [];
|
|
7970
8088
|
let changed = false;
|
|
7971
8089
|
const deps = map.get("dependencies", true);
|
|
@@ -7982,7 +8100,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
7982
8100
|
const hasPublication = PUBLICATION_KEYS.some((k) => raw[k] !== void 0);
|
|
7983
8101
|
let remove = false;
|
|
7984
8102
|
if (hasPublication) {
|
|
7985
|
-
const manifestPath =
|
|
8103
|
+
const manifestPath = path18__default.join(dir, "skaile.manifest.yaml");
|
|
7986
8104
|
if (existsSync(manifestPath)) {
|
|
7987
8105
|
manual.push(
|
|
7988
8106
|
`${rel(file)}: publisher/version/assets left in place \u2014 ${rel(manifestPath)} already exists; merge by hand`
|
|
@@ -8039,7 +8157,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
8039
8157
|
return changes;
|
|
8040
8158
|
}
|
|
8041
8159
|
function planAssetMigration(options) {
|
|
8042
|
-
const root =
|
|
8160
|
+
const root = path18__default.resolve(options.root);
|
|
8043
8161
|
const knownKinds = new Set(options.registry.getAllKinds());
|
|
8044
8162
|
const notes = [];
|
|
8045
8163
|
const manual = [];
|
|
@@ -8047,7 +8165,7 @@ function planAssetMigration(options) {
|
|
|
8047
8165
|
const { moves, changes: moveChanges } = planMarkdownMoves(root, knownKinds, manual, unknownTypes);
|
|
8048
8166
|
for (const move of moves) {
|
|
8049
8167
|
notes.push(
|
|
8050
|
-
`${posix2(
|
|
8168
|
+
`${posix2(path18__default.relative(root, move.from))} \u2192 ${posix2(path18__default.relative(root, move.to))} (${move.kind})`
|
|
8051
8169
|
);
|
|
8052
8170
|
}
|
|
8053
8171
|
const agentChanges = planAgentRefRewrites(root, moves, knownKinds, notes);
|
|
@@ -8059,7 +8177,7 @@ function planAssetMigration(options) {
|
|
|
8059
8177
|
const raw = parse(source);
|
|
8060
8178
|
if (isRecord(raw)) skaileYamls.push({ file, source, raw });
|
|
8061
8179
|
} catch {
|
|
8062
|
-
manual.push(`${posix2(
|
|
8180
|
+
manual.push(`${posix2(path18__default.relative(root, file))}: invalid YAML; skipped`);
|
|
8063
8181
|
}
|
|
8064
8182
|
}
|
|
8065
8183
|
const publisher = repoPublisher(root);
|
|
@@ -8213,7 +8331,7 @@ function workspaceConfigFiles(dir) {
|
|
|
8213
8331
|
} catch {
|
|
8214
8332
|
return [];
|
|
8215
8333
|
}
|
|
8216
|
-
return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) =>
|
|
8334
|
+
return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) => path18__default.join(dir, name));
|
|
8217
8335
|
}
|
|
8218
8336
|
function readAgentConfigBlock(raw) {
|
|
8219
8337
|
const key = AGENT_CONFIG_KEYS.find((candidate) => raw[candidate] !== void 0);
|
|
@@ -8225,7 +8343,7 @@ function readAgentConfigBlock(raw) {
|
|
|
8225
8343
|
return flat ? { key, profiles: { default: profiles }, flat } : { key, profiles, flat };
|
|
8226
8344
|
}
|
|
8227
8345
|
function planProviderMigration(options) {
|
|
8228
|
-
const projectDir =
|
|
8346
|
+
const projectDir = path18__default.resolve(options.projectDir);
|
|
8229
8347
|
const registryPath = options.workspace ? workspaceProviderRegistryPath(projectDir) : userProviderRegistryPath();
|
|
8230
8348
|
const plan = {
|
|
8231
8349
|
registryPath,
|
|
@@ -8241,7 +8359,7 @@ function planProviderMigration(options) {
|
|
|
8241
8359
|
raw = parseDocument(readFileSync(file, "utf-8")).toJS() ?? {};
|
|
8242
8360
|
} catch (error) {
|
|
8243
8361
|
plan.warnings.push(
|
|
8244
|
-
`${
|
|
8362
|
+
`${path18__default.basename(file)}: not valid YAML (${error instanceof Error ? error.message : String(error)}) \u2014 skipped`
|
|
8245
8363
|
);
|
|
8246
8364
|
continue;
|
|
8247
8365
|
}
|
|
@@ -8290,7 +8408,7 @@ function planProviderMigration(options) {
|
|
|
8290
8408
|
});
|
|
8291
8409
|
if (!model) {
|
|
8292
8410
|
plan.warnings.push(
|
|
8293
|
-
`${
|
|
8411
|
+
`${path18__default.basename(file)}: profile '${profile}' had no model: \u2014 it now resolves against registry order. Pin it with 'model: ${providerId}/<modelId>'.`
|
|
8294
8412
|
);
|
|
8295
8413
|
}
|
|
8296
8414
|
touched = true;
|
|
@@ -8357,7 +8475,7 @@ function printPlan(plan) {
|
|
|
8357
8475
|
for (const entry of plan.entries) {
|
|
8358
8476
|
const base = entry.entry.base_url ?? S.dim("(transport-derived)");
|
|
8359
8477
|
console.log(
|
|
8360
|
-
` ${S.label(`${
|
|
8478
|
+
` ${S.label(`${path18__default.basename(entry.file)} ${entry.profile}`)} provider: ${entry.legacy.provider}, cloud: ${entry.legacy.cloud}`
|
|
8361
8479
|
);
|
|
8362
8480
|
console.log(` \u2192 providers.yml ${S.bold(entry.providerId)} ${base}`);
|
|
8363
8481
|
console.log(
|
|
@@ -8373,7 +8491,7 @@ function printPlan(plan) {
|
|
|
8373
8491
|
console.log();
|
|
8374
8492
|
}
|
|
8375
8493
|
async function runMigrateProviders(opts) {
|
|
8376
|
-
const projectDir = opts.projectDir ?
|
|
8494
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
|
|
8377
8495
|
const plan = planProviderMigration({ projectDir, workspace: opts.workspace });
|
|
8378
8496
|
for (const warning of plan.warnings) logWarn(warning);
|
|
8379
8497
|
if (plan.entries.length === 0 && Object.keys(plan.providers).length === 0) {
|
|
@@ -8504,7 +8622,7 @@ async function runMigrateAgents(paths, opts) {
|
|
|
8504
8622
|
let failures = 0;
|
|
8505
8623
|
let manualCount = 0;
|
|
8506
8624
|
for (const report of plan.reports) {
|
|
8507
|
-
const rel =
|
|
8625
|
+
const rel = path18__default.relative(base, report.file) || report.file;
|
|
8508
8626
|
for (const note of report.notes) console.log(` ${S.label(rel)} ${note}`);
|
|
8509
8627
|
for (const note of report.manual) {
|
|
8510
8628
|
manualCount++;
|
|
@@ -8531,14 +8649,14 @@ async function runMigrateAssets(root, opts) {
|
|
|
8531
8649
|
const write = resolveMode(opts);
|
|
8532
8650
|
const base = process.cwd();
|
|
8533
8651
|
const plan = planAssetMigration({
|
|
8534
|
-
root:
|
|
8652
|
+
root: path18__default.resolve(root ?? base),
|
|
8535
8653
|
registry: getKindRegistry()
|
|
8536
8654
|
});
|
|
8537
8655
|
for (const note of plan.notes) console.log(` ${note}`);
|
|
8538
8656
|
for (const note of plan.manual) logWarn(note);
|
|
8539
8657
|
for (const { file, type } of plan.unknownTypes) {
|
|
8540
8658
|
logWarn(
|
|
8541
|
-
`${
|
|
8659
|
+
`${path18__default.relative(base, file) || file}: frontmatter type "${type}" is not a registered asset kind (reported, not rewritten)`
|
|
8542
8660
|
);
|
|
8543
8661
|
}
|
|
8544
8662
|
printChanges(plan.changes, base);
|
|
@@ -8561,8 +8679,8 @@ function makeNpxCommand() {
|
|
|
8561
8679
|
skills.command("add <url>").description(
|
|
8562
8680
|
"Clone a repo, register it in the project's skaile.yaml sources[], and install a skill from it"
|
|
8563
8681
|
).requiredOption("--skill <name>", "Skill name to install from the repo").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", `Agent framework (${TARGET_DEFAULT_HINT})`).option("--global", "Deploy globally").action(async (url, opts) => {
|
|
8564
|
-
const projectDir =
|
|
8565
|
-
const projYaml =
|
|
8682
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
8683
|
+
const projYaml = path18__default.join(projectDir, "skaile.yaml");
|
|
8566
8684
|
if (!existsSync(projYaml)) {
|
|
8567
8685
|
logErr(`No skaile.yaml in ${projectDir} \u2014 run \`skaile init\` first.`);
|
|
8568
8686
|
process.exit(1);
|
|
@@ -8575,11 +8693,11 @@ function makeNpxCommand() {
|
|
|
8575
8693
|
}
|
|
8576
8694
|
const spinner = createSpinner();
|
|
8577
8695
|
const key = sourceCacheKey(url);
|
|
8578
|
-
const clonePath =
|
|
8696
|
+
const clonePath = path18__default.join(getGlobalCacheDir(), key);
|
|
8579
8697
|
spinner.start(`Cloning ${url}`);
|
|
8580
8698
|
try {
|
|
8581
8699
|
if (!existsSync(clonePath)) {
|
|
8582
|
-
mkdirSync(
|
|
8700
|
+
mkdirSync(path18__default.dirname(clonePath), { recursive: true });
|
|
8583
8701
|
execSync(`git clone ${url} ${clonePath}`, { stdio: "ignore" });
|
|
8584
8702
|
}
|
|
8585
8703
|
spinner.stop(`Cloned to ${key}`);
|
|
@@ -8634,7 +8752,7 @@ function makeNpxCommand() {
|
|
|
8634
8752
|
return npx;
|
|
8635
8753
|
}
|
|
8636
8754
|
function resolvePublisher(clonePath, url) {
|
|
8637
|
-
const manifestPath =
|
|
8755
|
+
const manifestPath = path18__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
|
|
8638
8756
|
if (existsSync(manifestPath)) {
|
|
8639
8757
|
try {
|
|
8640
8758
|
const { manifest } = decodeSkaileManifest(readFileSync(manifestPath, "utf8"));
|
|
@@ -8647,12 +8765,12 @@ function resolvePublisher(clonePath, url) {
|
|
|
8647
8765
|
return url.match(/github\.com[/:]([^/]+)\/[^/]+/)?.[1];
|
|
8648
8766
|
}
|
|
8649
8767
|
function resolveSkillName(clonePath, requested) {
|
|
8650
|
-
const skillsDir =
|
|
8651
|
-
if (existsSync(
|
|
8768
|
+
const skillsDir = path18__default.join(clonePath, "skills");
|
|
8769
|
+
if (existsSync(path18__default.join(skillsDir, requested, "SKILL.md"))) return requested;
|
|
8652
8770
|
if (!existsSync(skillsDir)) return requested;
|
|
8653
8771
|
for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
|
|
8654
8772
|
if (!entry.isDirectory()) continue;
|
|
8655
|
-
const md =
|
|
8773
|
+
const md = path18__default.join(skillsDir, entry.name, "SKILL.md");
|
|
8656
8774
|
if (!existsSync(md)) continue;
|
|
8657
8775
|
try {
|
|
8658
8776
|
const { data } = parseFrontmatter(readFileSync(md, "utf8"));
|
|
@@ -8682,9 +8800,10 @@ function makeOutdatedCommand() {
|
|
|
8682
8800
|
SUPPORTED_DRIVER_TARGETS
|
|
8683
8801
|
)
|
|
8684
8802
|
).action(async (filter, opts) => {
|
|
8803
|
+
requireProjectConfig(opts.projectDir);
|
|
8685
8804
|
const am2 = new AssetManager({
|
|
8686
8805
|
registry: getKindRegistry(),
|
|
8687
|
-
projectDir:
|
|
8806
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
8688
8807
|
driverTarget: opts.target
|
|
8689
8808
|
});
|
|
8690
8809
|
const entries = await am2.outdated();
|
|
@@ -8714,6 +8833,12 @@ function makeOutdatedCommand() {
|
|
|
8714
8833
|
if (filtered.some((e) => e.problem !== void 0 && !e.manualFix)) {
|
|
8715
8834
|
logWarn(`Run ${S.cmd("skaile install")} to restore or re-lock the broken assets.`);
|
|
8716
8835
|
}
|
|
8836
|
+
for (const e of filtered) {
|
|
8837
|
+
if (e.problem !== void 0 || (await am2.gapsOf(outdatedRef(e))).length > 0) {
|
|
8838
|
+
process.exitCode = 1;
|
|
8839
|
+
break;
|
|
8840
|
+
}
|
|
8841
|
+
}
|
|
8717
8842
|
});
|
|
8718
8843
|
}
|
|
8719
8844
|
function makePatchCommand() {
|
|
@@ -8721,7 +8846,7 @@ function makePatchCommand() {
|
|
|
8721
8846
|
cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
8722
8847
|
const am2 = new AssetManager({
|
|
8723
8848
|
registry: getKindRegistry(),
|
|
8724
|
-
projectDir:
|
|
8849
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
8725
8850
|
});
|
|
8726
8851
|
try {
|
|
8727
8852
|
const dest = await am2.patch(ref);
|
|
@@ -8735,7 +8860,7 @@ function makePatchCommand() {
|
|
|
8735
8860
|
cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
8736
8861
|
const am2 = new AssetManager({
|
|
8737
8862
|
registry: getKindRegistry(),
|
|
8738
|
-
projectDir:
|
|
8863
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
8739
8864
|
});
|
|
8740
8865
|
try {
|
|
8741
8866
|
const patchFile = await am2.patchCommit(ref);
|
|
@@ -8749,7 +8874,7 @@ function makePatchCommand() {
|
|
|
8749
8874
|
cmd.command("submit <ref>").description("Apply patch to repo clone and prepare for PR").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
8750
8875
|
const am2 = new AssetManager({
|
|
8751
8876
|
registry: getKindRegistry(),
|
|
8752
|
-
projectDir:
|
|
8877
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
8753
8878
|
});
|
|
8754
8879
|
try {
|
|
8755
8880
|
await am2.patchSubmit(ref);
|
|
@@ -8765,7 +8890,7 @@ function makePatchCommand() {
|
|
|
8765
8890
|
cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
8766
8891
|
const am2 = new AssetManager({
|
|
8767
8892
|
registry: getKindRegistry(),
|
|
8768
|
-
projectDir:
|
|
8893
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
8769
8894
|
});
|
|
8770
8895
|
am2.patchRemove(ref);
|
|
8771
8896
|
logOk(`Patch removed for ${ref}`);
|
|
@@ -8784,7 +8909,7 @@ function action2(fn) {
|
|
|
8784
8909
|
};
|
|
8785
8910
|
}
|
|
8786
8911
|
async function reconcileAndReport(projectDir, plugins) {
|
|
8787
|
-
const { reconcilePlugins } = await import('../plugin-store-
|
|
8912
|
+
const { reconcilePlugins } = await import('../plugin-store-AGQDMING.js');
|
|
8788
8913
|
if (plugins.length === 0) {
|
|
8789
8914
|
logInfo("No plugins declared \u2014 nothing to reconcile.");
|
|
8790
8915
|
return;
|
|
@@ -8798,10 +8923,10 @@ async function reconcileAndReport(projectDir, plugins) {
|
|
|
8798
8923
|
}
|
|
8799
8924
|
}
|
|
8800
8925
|
async function runInstall2(spec, opts) {
|
|
8801
|
-
const projectDir =
|
|
8926
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
8802
8927
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
8803
|
-
const { specName } = await import('../plugin-store-
|
|
8804
|
-
const yamlPath =
|
|
8928
|
+
const { specName } = await import('../plugin-store-AGQDMING.js');
|
|
8929
|
+
const yamlPath = path18__default.join(projectDir, "skaile.yaml");
|
|
8805
8930
|
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
8806
8931
|
const replaced = editor.addPlugin(spec, specName);
|
|
8807
8932
|
editor.save();
|
|
@@ -8810,10 +8935,10 @@ async function runInstall2(spec, opts) {
|
|
|
8810
8935
|
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
8811
8936
|
}
|
|
8812
8937
|
async function runRemove(name, opts) {
|
|
8813
|
-
const projectDir =
|
|
8938
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
8814
8939
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
8815
|
-
const { specName } = await import('../plugin-store-
|
|
8816
|
-
const yamlPath =
|
|
8940
|
+
const { specName } = await import('../plugin-store-AGQDMING.js');
|
|
8941
|
+
const yamlPath = path18__default.join(projectDir, "skaile.yaml");
|
|
8817
8942
|
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
8818
8943
|
const removed = editor.removePlugin(name, specName);
|
|
8819
8944
|
if (!removed) {
|
|
@@ -8825,7 +8950,7 @@ async function runRemove(name, opts) {
|
|
|
8825
8950
|
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
8826
8951
|
}
|
|
8827
8952
|
async function runList(opts) {
|
|
8828
|
-
const projectDir =
|
|
8953
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
8829
8954
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
8830
8955
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
8831
8956
|
const declared = config.plugins ?? [];
|
|
@@ -8840,7 +8965,7 @@ async function runList(opts) {
|
|
|
8840
8965
|
const registry = createPluginRegistry();
|
|
8841
8966
|
if (declared.length > 0) {
|
|
8842
8967
|
try {
|
|
8843
|
-
const { loadPlugins } = await import('../plugin-store-
|
|
8968
|
+
const { loadPlugins } = await import('../plugin-store-AGQDMING.js');
|
|
8844
8969
|
const result = await loadPlugins(projectDir, declared, registry);
|
|
8845
8970
|
for (const f of result.failed) logWarn(f.error);
|
|
8846
8971
|
} catch (err2) {
|
|
@@ -9015,7 +9140,7 @@ function neededSources(config, lock) {
|
|
|
9015
9140
|
}
|
|
9016
9141
|
function sourcesWithSidecar(sources) {
|
|
9017
9142
|
const dir = getStoreManifestsDir();
|
|
9018
|
-
return sources.filter((s) => existsSync(
|
|
9143
|
+
return sources.filter((s) => existsSync(path18.join(dir, `${storeManifestSlug(s.url)}.yaml`))).map((s) => s.url);
|
|
9019
9144
|
}
|
|
9020
9145
|
function compact(obj) {
|
|
9021
9146
|
const out = {};
|
|
@@ -9107,8 +9232,8 @@ function redactSecrets(preset, findings) {
|
|
|
9107
9232
|
}
|
|
9108
9233
|
return { preset: next, keys };
|
|
9109
9234
|
}
|
|
9110
|
-
function placeholderKey(itemId,
|
|
9111
|
-
return `${itemId}_${
|
|
9235
|
+
function placeholderKey(itemId, path43) {
|
|
9236
|
+
return `${itemId}_${path43}`.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
|
|
9112
9237
|
}
|
|
9113
9238
|
function setAtPath(root, segments, value) {
|
|
9114
9239
|
let node = root;
|
|
@@ -9131,7 +9256,7 @@ function makePresetCommand() {
|
|
|
9131
9256
|
cmd.command("init [name]").description("Scaffold a new .preset.yaml file").option("--dir <path>", "Output directory", process.cwd()).action(async (name, opts) => {
|
|
9132
9257
|
const presetName = name ?? "my-preset";
|
|
9133
9258
|
const filename = `${presetName}.preset.yaml`;
|
|
9134
|
-
const outPath =
|
|
9259
|
+
const outPath = path18__default.join(path18__default.resolve(opts.dir), filename);
|
|
9135
9260
|
if (existsSync(outPath)) {
|
|
9136
9261
|
logErr(`File already exists: ${outPath}`);
|
|
9137
9262
|
logInfo("Choose a different name or remove the existing file.");
|
|
@@ -9164,7 +9289,7 @@ function makePresetCommand() {
|
|
|
9164
9289
|
return cmd;
|
|
9165
9290
|
}
|
|
9166
9291
|
async function runPresetExport(name, opts) {
|
|
9167
|
-
const projectDir =
|
|
9292
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9168
9293
|
const file = loadSkWorkspaceConfig(projectDir);
|
|
9169
9294
|
if (!file) {
|
|
9170
9295
|
logErr(`No skaile.yaml found in ${projectDir}`);
|
|
@@ -9174,7 +9299,7 @@ async function runPresetExport(name, opts) {
|
|
|
9174
9299
|
const presetName = name ?? file.config.name ?? "my-preset";
|
|
9175
9300
|
let lock = null;
|
|
9176
9301
|
try {
|
|
9177
|
-
lock = readLock(
|
|
9302
|
+
lock = readLock(path18__default.join(projectDir, "skaile.lock.yaml"));
|
|
9178
9303
|
} catch {
|
|
9179
9304
|
lock = null;
|
|
9180
9305
|
}
|
|
@@ -9215,7 +9340,7 @@ async function runPresetExport(name, opts) {
|
|
|
9215
9340
|
const contents = header ? `${header}
|
|
9216
9341
|
${body}` : body;
|
|
9217
9342
|
if (opts.out && opts.dir !== process.cwd()) logWarn("--dir is ignored when --out is set.");
|
|
9218
|
-
const outPath = opts.out ?
|
|
9343
|
+
const outPath = opts.out ? path18__default.resolve(opts.out) : path18__default.join(path18__default.resolve(opts.dir), `${presetName}.preset.yaml`);
|
|
9219
9344
|
if (existsSync(outPath) && !opts.force) {
|
|
9220
9345
|
logErr(`File already exists: ${outPath}`);
|
|
9221
9346
|
logInfo("Pass --force to overwrite, or choose a different --out/--dir.");
|
|
@@ -9227,7 +9352,7 @@ ${body}` : body;
|
|
|
9227
9352
|
logErr(`Failed to write ${outPath}: ${e.message}`);
|
|
9228
9353
|
process.exit(1);
|
|
9229
9354
|
}
|
|
9230
|
-
logOk(`Exported ${S.brand(
|
|
9355
|
+
logOk(`Exported ${S.brand(path18__default.basename(outPath))}`);
|
|
9231
9356
|
logInfo(`Path: ${outPath}`);
|
|
9232
9357
|
if (unresolved.length > 0) {
|
|
9233
9358
|
console.error(S.err("This file is NOT safe to share."));
|
|
@@ -9268,13 +9393,13 @@ function collectInput(value, acc) {
|
|
|
9268
9393
|
return acc;
|
|
9269
9394
|
}
|
|
9270
9395
|
async function runPresetApply(filePath, opts) {
|
|
9271
|
-
const projectDir =
|
|
9396
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9272
9397
|
const file = loadSkWorkspaceConfig(projectDir);
|
|
9273
9398
|
if (!file) {
|
|
9274
9399
|
logErr("No skaile.yaml \u2014 run `skaile init` first");
|
|
9275
9400
|
process.exit(1);
|
|
9276
9401
|
}
|
|
9277
|
-
const resolved =
|
|
9402
|
+
const resolved = path18__default.resolve(filePath);
|
|
9278
9403
|
if (!existsSync(resolved)) {
|
|
9279
9404
|
logErr(`File not found: ${resolved}`);
|
|
9280
9405
|
process.exit(1);
|
|
@@ -9490,7 +9615,7 @@ async function reportNestedPresetRefs(preset) {
|
|
|
9490
9615
|
}
|
|
9491
9616
|
async function checkPresetCycles(preset, resolved) {
|
|
9492
9617
|
const { detectCycles } = await import('../discovery/index.js');
|
|
9493
|
-
const presetRef =
|
|
9618
|
+
const presetRef = path18__default.basename(resolved, ".preset.yaml");
|
|
9494
9619
|
const edges = [];
|
|
9495
9620
|
for (const item of preset.items) {
|
|
9496
9621
|
if (item.ref) {
|
|
@@ -9542,7 +9667,7 @@ function printPresetSummary(preset, placeholderCount, hasWarnings) {
|
|
|
9542
9667
|
}
|
|
9543
9668
|
}
|
|
9544
9669
|
async function runPresetValidate(filePath) {
|
|
9545
|
-
const resolved =
|
|
9670
|
+
const resolved = path18__default.resolve(filePath);
|
|
9546
9671
|
const preset = await loadPresetForValidation(resolved);
|
|
9547
9672
|
await reportNestedPresetRefs(preset);
|
|
9548
9673
|
await checkPresetCycles(preset, resolved);
|
|
@@ -9592,11 +9717,11 @@ items:
|
|
|
9592
9717
|
}
|
|
9593
9718
|
function makeRebuildCommand() {
|
|
9594
9719
|
return new Command("rebuild").description("Re-snapshot inline-snapshot composition items and bump prompt version").argument("[agent]", "Agent name or path (defaults to current project agent)").option("--project-dir <dir>", "Project directory", process.cwd()).action(async (agentArg, opts) => {
|
|
9595
|
-
const projectDir =
|
|
9720
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9596
9721
|
let agentDir;
|
|
9597
9722
|
if (agentArg) {
|
|
9598
9723
|
if (agentArg.includes("/") || agentArg.includes("\\")) {
|
|
9599
|
-
agentDir =
|
|
9724
|
+
agentDir = path18__default.resolve(projectDir, agentArg);
|
|
9600
9725
|
} else {
|
|
9601
9726
|
let resolved;
|
|
9602
9727
|
try {
|
|
@@ -9605,7 +9730,7 @@ function makeRebuildCommand() {
|
|
|
9605
9730
|
if (!(err2 instanceof AgentRefResolutionError)) throw err2;
|
|
9606
9731
|
logWarn(`${err2.message} \u2014 using "${agentArg}"`);
|
|
9607
9732
|
}
|
|
9608
|
-
agentDir = resolved ??
|
|
9733
|
+
agentDir = resolved ?? path18__default.resolve(projectDir, agentArg);
|
|
9609
9734
|
}
|
|
9610
9735
|
} else {
|
|
9611
9736
|
let resolved;
|
|
@@ -9675,9 +9800,9 @@ Try a different harness with \`--driver claude-sdk\`.`;
|
|
|
9675
9800
|
// cli/src/commands/run.ts
|
|
9676
9801
|
function resolveSingleShotAgentDir(projectDir, agentDefinition) {
|
|
9677
9802
|
if (!agentDefinition) return resolveAgentDir(projectDir);
|
|
9678
|
-
const asPath = agentDefinition.endsWith("agent.yaml") ?
|
|
9803
|
+
const asPath = agentDefinition.endsWith("agent.yaml") ? path18__default.dirname(path18__default.resolve(projectDir, agentDefinition)) : agentDefinition;
|
|
9679
9804
|
const dir = resolveAgentDefinitionDir(projectDir, asPath);
|
|
9680
|
-
if (!dir || !
|
|
9805
|
+
if (!dir || !fs8__default.existsSync(path18__default.join(dir, "agent.yaml"))) {
|
|
9681
9806
|
throw new Error(
|
|
9682
9807
|
`--agent-definition "${agentDefinition}" does not resolve to an agent directory with agent.yaml${dir ? ` (looked in ${dir})` : ""}`
|
|
9683
9808
|
);
|
|
@@ -9776,7 +9901,7 @@ function makeRunCommand() {
|
|
|
9776
9901
|
"--agent-definition <ref|path>",
|
|
9777
9902
|
"Agent asset for this one invocation (agent:@pub/name, ai-assets://\u2026, or a directory with agent.yaml); single-shot prompts only"
|
|
9778
9903
|
).option("--skill <name>", "Skill name (for single-shot mode)").action(async (positional, opts) => {
|
|
9779
|
-
const projectDir =
|
|
9904
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9780
9905
|
const cliDriver = opts.driver;
|
|
9781
9906
|
const dryRun = opts.dryRun ?? false;
|
|
9782
9907
|
const agentDefinition = opts.agentDefinition?.trim() || void 0;
|
|
@@ -9895,7 +10020,7 @@ function makeRunCommand() {
|
|
|
9895
10020
|
}
|
|
9896
10021
|
function makeResumeCommand() {
|
|
9897
10022
|
const cmd = new Command("resume").description("Resume current session").option("--project-dir <path>", "Project directory", process.cwd()).option("--session <run-id>", "Target session by runId").option("--dry-run", "Print plan without executing").action(async (opts) => {
|
|
9898
|
-
const projectDir =
|
|
10023
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9899
10024
|
const sessionId = opts.session;
|
|
9900
10025
|
const dryRun = opts.dryRun ?? false;
|
|
9901
10026
|
const session = sessionId ? await loadSessionById(projectDir, sessionId) : await loadSession(projectDir);
|
|
@@ -9922,7 +10047,7 @@ function makeResumeCommand() {
|
|
|
9922
10047
|
}
|
|
9923
10048
|
function makeStatusCommand() {
|
|
9924
10049
|
return new Command("status").description("Show current session state").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
9925
|
-
const projectDir =
|
|
10050
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9926
10051
|
const session = await loadSession(projectDir);
|
|
9927
10052
|
if (!session) {
|
|
9928
10053
|
logInfo("No active session.");
|
|
@@ -9947,7 +10072,7 @@ function makeStatusCommand() {
|
|
|
9947
10072
|
}
|
|
9948
10073
|
function makeClearCommand() {
|
|
9949
10074
|
return new Command("clear").description("Unset current session pointer").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
9950
|
-
const projectDir =
|
|
10075
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9951
10076
|
await clearSession(projectDir);
|
|
9952
10077
|
logOk("Session cleared.");
|
|
9953
10078
|
});
|
|
@@ -9957,7 +10082,7 @@ function makeReplCommand() {
|
|
|
9957
10082
|
const { findWorkspaceRoot } = await import('../core/index.js');
|
|
9958
10083
|
const { startRepl } = await import('../tui/index.js');
|
|
9959
10084
|
const os2 = await import('os');
|
|
9960
|
-
const userCwd =
|
|
10085
|
+
const userCwd = path18__default.resolve(opts.projectDir ?? process.cwd());
|
|
9961
10086
|
const workspaceRoot = findWorkspaceRoot(userCwd);
|
|
9962
10087
|
let projectDir;
|
|
9963
10088
|
let agentCwd;
|
|
@@ -9979,13 +10104,13 @@ function makeReplCommand() {
|
|
|
9979
10104
|
p4.cancel("Cancelled.");
|
|
9980
10105
|
process.exit(0);
|
|
9981
10106
|
}
|
|
9982
|
-
const tmpDir =
|
|
10107
|
+
const tmpDir = fs8__default.mkdtempSync(path18__default.join(os2.tmpdir(), "skaile-repl-"));
|
|
9983
10108
|
projectDir = tmpDir;
|
|
9984
10109
|
agentCwd = userCwd;
|
|
9985
10110
|
logOk(`Temporary workspace: ${S.cmd(tmpDir)}`);
|
|
9986
10111
|
if (!driverOverride) {
|
|
9987
|
-
const claudeDir =
|
|
9988
|
-
if (
|
|
10112
|
+
const claudeDir = path18__default.join(os2.homedir(), ".claude");
|
|
10113
|
+
if (fs8__default.existsSync(claudeDir)) {
|
|
9989
10114
|
driverOverride = "claude-sdk";
|
|
9990
10115
|
logInfo(`Detected ${S.cmd("~/.claude")} \u2192 using ${S.cmd("claude-sdk")} harness`);
|
|
9991
10116
|
} else {
|
|
@@ -9995,14 +10120,19 @@ function makeReplCommand() {
|
|
|
9995
10120
|
}
|
|
9996
10121
|
console.log();
|
|
9997
10122
|
}
|
|
9998
|
-
|
|
9999
|
-
|
|
10000
|
-
|
|
10001
|
-
|
|
10002
|
-
|
|
10003
|
-
|
|
10004
|
-
|
|
10005
|
-
|
|
10123
|
+
try {
|
|
10124
|
+
await startRepl({
|
|
10125
|
+
projectDir,
|
|
10126
|
+
cwd: agentCwd !== projectDir ? agentCwd : void 0,
|
|
10127
|
+
driver: driverOverride,
|
|
10128
|
+
model: opts.model,
|
|
10129
|
+
resume: opts.resume,
|
|
10130
|
+
resumeSessionId: opts.resumeSession
|
|
10131
|
+
});
|
|
10132
|
+
} catch (err2) {
|
|
10133
|
+
logErr(friendlyDriverError(err2) ?? (err2 instanceof Error ? err2.message : String(err2)));
|
|
10134
|
+
process.exit(1);
|
|
10135
|
+
}
|
|
10006
10136
|
});
|
|
10007
10137
|
}
|
|
10008
10138
|
function parseProviderIds(raw) {
|
|
@@ -10057,12 +10187,12 @@ function makeServeCommand() {
|
|
|
10057
10187
|
);
|
|
10058
10188
|
}
|
|
10059
10189
|
async function ensurePluginsLoadedForServe(projectDir) {
|
|
10060
|
-
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-
|
|
10190
|
+
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-CFK6YP6R.js');
|
|
10061
10191
|
try {
|
|
10062
10192
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
10063
10193
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
10064
10194
|
if (!config.plugins || config.plugins.length === 0) return;
|
|
10065
|
-
const { ensurePluginsLoaded } = await import('../plugin-store-
|
|
10195
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-AGQDMING.js');
|
|
10066
10196
|
const { pluginRegistry } = await import('../plugin-registry/index.js');
|
|
10067
10197
|
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
10068
10198
|
if (result.loaded.length > 0) {
|
|
@@ -10076,21 +10206,21 @@ async function ensurePluginsLoadedForServe(projectDir) {
|
|
|
10076
10206
|
}
|
|
10077
10207
|
}
|
|
10078
10208
|
async function runCompileTest(opts) {
|
|
10079
|
-
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-
|
|
10209
|
+
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-CFK6YP6R.js');
|
|
10080
10210
|
const { tmpdir } = await import('os');
|
|
10081
|
-
const { dirname: dirname3, join:
|
|
10211
|
+
const { dirname: dirname3, join: join6, resolve: resolve5 } = await import('path');
|
|
10082
10212
|
const { fileURLToPath: fileURLToPath2 } = await import('url');
|
|
10083
|
-
const { unlinkSync, existsSync:
|
|
10213
|
+
const { unlinkSync, existsSync: existsSync17 } = await import('fs');
|
|
10084
10214
|
const { spawn } = await import('child_process');
|
|
10085
10215
|
const { portableSpawnSync: portableSpawnSync2 } = await import('../core/index.js');
|
|
10086
|
-
const { MONOREPO_ROOT } = await import('../paths-
|
|
10216
|
+
const { MONOREPO_ROOT } = await import('../paths-SUS4S4YT.js');
|
|
10087
10217
|
if (MONOREPO_ROOT === null) {
|
|
10088
10218
|
logErr2("--compile-test is only available inside the skaile-dev workspace.");
|
|
10089
10219
|
logInfo2("Run it from a checkout of skaile-ai/skaile-dev (the monorepo shell).");
|
|
10090
10220
|
process.exitCode = 2;
|
|
10091
10221
|
return;
|
|
10092
10222
|
}
|
|
10093
|
-
const outfile =
|
|
10223
|
+
const outfile = join6(tmpdir(), `skaile-compile-test-${Date.now()}`);
|
|
10094
10224
|
const __thisFile = fileURLToPath2(import.meta.url);
|
|
10095
10225
|
const entryPoint = resolve5(dirname3(__thisFile), "..", "index.ts");
|
|
10096
10226
|
logInfo2(`Building compiled binary...`);
|
|
@@ -10145,7 +10275,7 @@ async function runCompileTest(opts) {
|
|
|
10145
10275
|
} catch {
|
|
10146
10276
|
}
|
|
10147
10277
|
try {
|
|
10148
|
-
if (
|
|
10278
|
+
if (existsSync17(outfile)) unlinkSync(outfile);
|
|
10149
10279
|
} catch {
|
|
10150
10280
|
}
|
|
10151
10281
|
}
|
|
@@ -10566,7 +10696,7 @@ function resolveMode2(opts) {
|
|
|
10566
10696
|
if (opts.forceLocal && opts.forceRemote) {
|
|
10567
10697
|
throw new Error("Cannot use both --local and --remote");
|
|
10568
10698
|
}
|
|
10569
|
-
const startDir =
|
|
10699
|
+
const startDir = path18__default.resolve(opts.projectDir ?? process.cwd());
|
|
10570
10700
|
const localDb = findLogsDb(startDir);
|
|
10571
10701
|
if (opts.forceLocal) {
|
|
10572
10702
|
if (!localDb) {
|
|
@@ -10599,14 +10729,14 @@ function resolveMode2(opts) {
|
|
|
10599
10729
|
function findLogsDb(startDir) {
|
|
10600
10730
|
let dir = startDir;
|
|
10601
10731
|
for (let i = 0; i < MAX_WALK_LEVELS; i++) {
|
|
10602
|
-
const candidate =
|
|
10732
|
+
const candidate = path18__default.join(dir, ".skaile", "logs.db");
|
|
10603
10733
|
if (existsSync(candidate)) {
|
|
10604
10734
|
try {
|
|
10605
10735
|
if (statSync(candidate).isFile()) return candidate;
|
|
10606
10736
|
} catch {
|
|
10607
10737
|
}
|
|
10608
10738
|
}
|
|
10609
|
-
const parent =
|
|
10739
|
+
const parent = path18__default.dirname(dir);
|
|
10610
10740
|
if (parent === dir) return void 0;
|
|
10611
10741
|
dir = parent;
|
|
10612
10742
|
}
|
|
@@ -10781,7 +10911,7 @@ function parsePositiveInt(value, flag) {
|
|
|
10781
10911
|
function makeSessionCommand() {
|
|
10782
10912
|
const cmd = new Command("session").description("Manage sessions");
|
|
10783
10913
|
cmd.command("list").description("List all sessions for a project").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
10784
|
-
const projectDir =
|
|
10914
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
10785
10915
|
const sessions = await listSessions(projectDir);
|
|
10786
10916
|
const current = await loadSession(projectDir);
|
|
10787
10917
|
if (sessions.length === 0) {
|
|
@@ -10809,7 +10939,7 @@ function makeSessionCommand() {
|
|
|
10809
10939
|
console.log();
|
|
10810
10940
|
});
|
|
10811
10941
|
cmd.command("show <run-id>").description("Show a specific session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10812
|
-
const projectDir =
|
|
10942
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
10813
10943
|
const session = await loadSessionById(projectDir, runId);
|
|
10814
10944
|
if (!session) {
|
|
10815
10945
|
logErr(`Session not found: ${runId}`);
|
|
@@ -10818,7 +10948,7 @@ function makeSessionCommand() {
|
|
|
10818
10948
|
console.log(JSON.stringify(session, null, 2));
|
|
10819
10949
|
});
|
|
10820
10950
|
cmd.command("switch <run-id>").description("Switch the current session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10821
|
-
const projectDir =
|
|
10951
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
10822
10952
|
if (!await loadSessionById(projectDir, runId)) {
|
|
10823
10953
|
logErr(`Session not found: ${runId}`);
|
|
10824
10954
|
process.exit(1);
|
|
@@ -10827,7 +10957,7 @@ function makeSessionCommand() {
|
|
|
10827
10957
|
logOk(`Switched to session: ${S.dim(runId.slice(0, 8))}`);
|
|
10828
10958
|
});
|
|
10829
10959
|
cmd.command("delete <run-id>").description("Delete a session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10830
|
-
const projectDir =
|
|
10960
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
10831
10961
|
if (!await loadSessionById(projectDir, runId)) {
|
|
10832
10962
|
logErr(`Session not found: ${runId}`);
|
|
10833
10963
|
process.exit(1);
|
|
@@ -10885,12 +11015,12 @@ function showOverview(am2) {
|
|
|
10885
11015
|
}
|
|
10886
11016
|
async function showAsset(am2, kind, name) {
|
|
10887
11017
|
const entry = await am2.info(`${kind}:${name}`);
|
|
10888
|
-
if (entry?.source &&
|
|
11018
|
+
if (entry?.source && fs8__default.existsSync(entry.source)) {
|
|
10889
11019
|
console.log();
|
|
10890
11020
|
console.log(` ${kindColor(entry.kind)} ${S.heading(entry.name)}`);
|
|
10891
11021
|
console.log(` ${S.rule(40)}`);
|
|
10892
11022
|
console.log();
|
|
10893
|
-
console.log(
|
|
11023
|
+
console.log(fs8__default.readFileSync(entry.source, "utf-8"));
|
|
10894
11024
|
return;
|
|
10895
11025
|
}
|
|
10896
11026
|
logErr(`Asset not found: ${kind}:${name}`);
|
|
@@ -10900,7 +11030,7 @@ function makeShowCommand() {
|
|
|
10900
11030
|
return new Command("show").description("Show deployed assets overview, or print asset content").argument("[kind]", "Asset kind (skill, agent, prompt, flow, preset, contract)").argument("[name]", "Asset name").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", `Agent framework (${TARGET_DEFAULT_HINT})`).action(async (kind, name, opts) => {
|
|
10901
11031
|
const am2 = new AssetManager({
|
|
10902
11032
|
registry: getKindRegistry(),
|
|
10903
|
-
projectDir:
|
|
11033
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
10904
11034
|
driverTarget: opts.target
|
|
10905
11035
|
});
|
|
10906
11036
|
if (!kind) {
|
|
@@ -10963,14 +11093,14 @@ function makeStoreCommand() {
|
|
|
10963
11093
|
});
|
|
10964
11094
|
store.command("mode <auto|local|remote>").description("Set the catalog resolution mode (not yet wired)").action((_mode) => {
|
|
10965
11095
|
logErr(
|
|
10966
|
-
`\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${
|
|
11096
|
+
`\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${path18__default.join(globalSkaileDir(), "store", "config.yaml")}.`
|
|
10967
11097
|
);
|
|
10968
11098
|
process.exit(2);
|
|
10969
11099
|
});
|
|
10970
11100
|
store.command("search <query>").description("Search the AI Asset Store catalog by name, description, or publisher").option("--kind <kind>", "Filter by asset kind (skill, agent, prompt, flow, \u2026)").option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (query, opts) => {
|
|
10971
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-
|
|
11101
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-BOSPJVID.js');
|
|
10972
11102
|
try {
|
|
10973
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
11103
|
+
const remote = await openCatalogSource2({ projectDir: path18__default.resolve(opts.projectDir) });
|
|
10974
11104
|
const assets = await remote.listAssets(opts.kind ? { kind: opts.kind } : {});
|
|
10975
11105
|
const results = filterCatalogAssets(assets, query);
|
|
10976
11106
|
if (results.length === 0) {
|
|
@@ -10996,10 +11126,10 @@ function makeStoreCommand() {
|
|
|
10996
11126
|
}
|
|
10997
11127
|
});
|
|
10998
11128
|
store.command("show <ref>").description("Show a store asset's details + provenance (source, files, integrity)").option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (ref, opts) => {
|
|
10999
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-
|
|
11000
|
-
const { supportsInstallManifest } = await import('../project-
|
|
11129
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-BOSPJVID.js');
|
|
11130
|
+
const { supportsInstallManifest } = await import('../project-I55A4O2T.js');
|
|
11001
11131
|
try {
|
|
11002
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
11132
|
+
const remote = await openCatalogSource2({ projectDir: path18__default.resolve(opts.projectDir) });
|
|
11003
11133
|
const asset = await remote.resolve(ref);
|
|
11004
11134
|
if (!asset) {
|
|
11005
11135
|
logErr(`Not found in store: ${ref} (try a full ref, e.g. skill:@publisher/name#version)`);
|
|
@@ -11124,7 +11254,7 @@ function makeTreeCommand() {
|
|
|
11124
11254
|
return new Command("tree").description("Show full dependency tree").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
11125
11255
|
const am2 = new AssetManager({
|
|
11126
11256
|
registry: getKindRegistry(),
|
|
11127
|
-
projectDir:
|
|
11257
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
11128
11258
|
});
|
|
11129
11259
|
const root = await am2.tree();
|
|
11130
11260
|
if (root.children.length === 0) {
|
|
@@ -11146,13 +11276,20 @@ function makeTreeCommand() {
|
|
|
11146
11276
|
});
|
|
11147
11277
|
}
|
|
11148
11278
|
function makeUpdateCommand() {
|
|
11149
|
-
return new Command("update").description("Refresh the Catalog cache and re-deploy outdated assets in the current project").argument(
|
|
11150
|
-
|
|
11279
|
+
return new Command("update").description("Refresh the Catalog cache and re-deploy outdated assets in the current project").argument(
|
|
11280
|
+
"[name]",
|
|
11281
|
+
"Update only this declared asset (kind:@publisher/name, kind:name or name); exits 1 when none matches"
|
|
11282
|
+
).option("--project-dir <path>", "Project directory", process.cwd()).option("--no-catalog", "Skip refreshing the catalog cache").option("--catalog-only", "Refresh the catalog cache only; do not re-deploy assets").option("--no-sync", "Skip syncing sources from upstream before re-deploying").option("-y, --yes", "Sync sources without the confirmation prompt").action(
|
|
11283
|
+
async (name, opts) => {
|
|
11284
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
11285
|
+
if (!opts.catalogOnly) requireProjectConfig(projectDir);
|
|
11286
|
+
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
|
|
11287
|
+
const target = name !== void 0 && !opts.catalogOnly ? await resolveUpdateTarget(am2, name) : void 0;
|
|
11151
11288
|
if (opts.catalog !== false) {
|
|
11152
11289
|
const catalogSpinner = createSpinner();
|
|
11153
11290
|
catalogSpinner.start("Refreshing catalog cache");
|
|
11154
11291
|
try {
|
|
11155
|
-
const remote = await openCatalogSource({ projectDir:
|
|
11292
|
+
const remote = await openCatalogSource({ projectDir: path18__default.resolve(opts.projectDir) });
|
|
11156
11293
|
const result2 = await remote.refresh();
|
|
11157
11294
|
catalogSpinner.stop(
|
|
11158
11295
|
`Catalog refreshed: ${S.heading(String(result2.assetsCached))} assets cached`
|
|
@@ -11169,53 +11306,133 @@ function makeUpdateCommand() {
|
|
|
11169
11306
|
}
|
|
11170
11307
|
}
|
|
11171
11308
|
if (opts.catalogOnly) return;
|
|
11172
|
-
const projectDir = path23__default.resolve(opts.projectDir);
|
|
11173
11309
|
if (await shouldSyncSources(opts)) {
|
|
11174
11310
|
const syncSpinner = createSpinner();
|
|
11175
11311
|
syncSpinner.start("Syncing sources");
|
|
11176
|
-
const { total, synced, failed } = await syncProjectSources(projectDir);
|
|
11312
|
+
const { total, synced, failed: failed2 } = await syncProjectSources(projectDir);
|
|
11177
11313
|
syncSpinner.stop(
|
|
11178
|
-
total === 0 ? "No sources to sync." : `Synced ${S.heading(`${synced}/${total}`)} source(s)` + (
|
|
11314
|
+
total === 0 ? "No sources to sync." : `Synced ${S.heading(`${synced}/${total}`)} source(s)` + (failed2 ? ` (${failed2} failed)` : "")
|
|
11179
11315
|
);
|
|
11180
|
-
if (
|
|
11316
|
+
if (failed2 > 0) process.exitCode = 1;
|
|
11317
|
+
} else {
|
|
11318
|
+
for (const slug of divergedSourceClones(projectDir)) {
|
|
11319
|
+
logErr(`${slug}: git pull failed: Not possible to fast-forward, aborting.`);
|
|
11320
|
+
process.exitCode = 1;
|
|
11321
|
+
}
|
|
11322
|
+
}
|
|
11323
|
+
if (target) {
|
|
11324
|
+
await updateOne(am2, projectDir, target);
|
|
11325
|
+
return;
|
|
11181
11326
|
}
|
|
11182
|
-
const warnings = deferredWarnings();
|
|
11183
|
-
const am2 = new AssetManager({
|
|
11184
|
-
registry: getKindRegistry(),
|
|
11185
|
-
projectDir,
|
|
11186
|
-
onLibraryCollision: warnings.push
|
|
11187
|
-
});
|
|
11188
11327
|
const spinner = createSpinner();
|
|
11189
11328
|
spinner.start("Re-deploying assets");
|
|
11190
11329
|
let result;
|
|
11191
11330
|
try {
|
|
11192
|
-
result = await am2.install();
|
|
11331
|
+
result = await am2.install({ moveLibraries: true });
|
|
11193
11332
|
} catch (err2) {
|
|
11194
11333
|
spinner.stop("Failed");
|
|
11195
|
-
warnings.flush();
|
|
11196
11334
|
logErr(String(err2));
|
|
11197
11335
|
process.exit(1);
|
|
11198
11336
|
}
|
|
11199
|
-
|
|
11200
|
-
|
|
11337
|
+
const failed = result.missing.length > 0 || !!result.agentInstanceErrors?.length || process.exitCode === 1;
|
|
11338
|
+
spinner.stop(failed ? "Failed" : "Done");
|
|
11201
11339
|
if (result.deployed.length > 0) {
|
|
11202
11340
|
for (const d of result.deployed) logOk(`Updated ${d}`);
|
|
11203
11341
|
}
|
|
11342
|
+
for (const r of result.restored ?? []) {
|
|
11343
|
+
for (const f of r.restored) logInfo(`Restored ${f}`);
|
|
11344
|
+
for (const f of r.removed) logInfo(`Removed ${f} (not part of ${r.ref})`);
|
|
11345
|
+
}
|
|
11204
11346
|
for (const r of result.removed) logWarn(`Removed: ${r}`);
|
|
11347
|
+
reportReplaced(result.replaced);
|
|
11205
11348
|
reportRelocked(result.relocked);
|
|
11206
|
-
|
|
11349
|
+
reportMoved(result.moved);
|
|
11350
|
+
const changed = result.deployed.length > 0 || result.removed.length > 0 || !!result.replaced?.length || !!result.moved?.length || !!result.relocked?.length;
|
|
11207
11351
|
if (result.lockWritten && changed) {
|
|
11208
11352
|
logInfo(`Lock file written: ${S.dim("skaile.lock.yaml")}`);
|
|
11209
11353
|
}
|
|
11354
|
+
if (result.agentInstanceErrors?.length) {
|
|
11355
|
+
logErr(
|
|
11356
|
+
`${result.agentInstanceErrors.length} agent instance(s) could not be rendered (see above)`
|
|
11357
|
+
);
|
|
11358
|
+
process.exitCode = 1;
|
|
11359
|
+
}
|
|
11210
11360
|
if (result.missing.length > 0) {
|
|
11211
11361
|
for (const m of result.missing) logErr(`Missing: ${m}${result.missingHints?.[m] ?? ""}`);
|
|
11212
11362
|
process.exitCode = 1;
|
|
11213
|
-
} else if (!changed) {
|
|
11363
|
+
} else if (!changed && !failed) {
|
|
11214
11364
|
logInfo("Nothing to update.");
|
|
11215
11365
|
}
|
|
11216
11366
|
}
|
|
11217
11367
|
);
|
|
11218
11368
|
}
|
|
11369
|
+
function declaredMatches(d, arg) {
|
|
11370
|
+
const declared = parseAssetRefLoose(d.ref);
|
|
11371
|
+
if (!declared) return false;
|
|
11372
|
+
const spec = arg.trim().replace(/#.*$/, "");
|
|
11373
|
+
const colon = spec.indexOf(":");
|
|
11374
|
+
const kindRaw = colon >= 0 ? spec.slice(0, colon) : void 0;
|
|
11375
|
+
const rest = colon >= 0 ? spec.slice(colon + 1) : spec;
|
|
11376
|
+
const kind = kindRaw === "mcp" ? "mcp-server" : kindRaw;
|
|
11377
|
+
let publisher;
|
|
11378
|
+
let name = rest;
|
|
11379
|
+
if (rest.startsWith("@")) {
|
|
11380
|
+
const slash = rest.indexOf("/");
|
|
11381
|
+
publisher = rest.slice(1, slash < 0 ? void 0 : slash);
|
|
11382
|
+
name = slash < 0 ? "" : rest.slice(slash + 1);
|
|
11383
|
+
}
|
|
11384
|
+
return (kind === void 0 || kind === declared.kind) && (publisher === void 0 || publisher === declared.publisher?.replace(/^@/, "")) && name === declared.name;
|
|
11385
|
+
}
|
|
11386
|
+
async function resolveUpdateTarget(am2, name) {
|
|
11387
|
+
let declared;
|
|
11388
|
+
try {
|
|
11389
|
+
declared = (await am2.listDeclared()).filter((d) => d.state !== "invalid");
|
|
11390
|
+
} catch (err2) {
|
|
11391
|
+
if (err2 instanceof MissingManifestError) {
|
|
11392
|
+
logErr("No skaile.yaml found in this directory. Run `skaile init` first.");
|
|
11393
|
+
} else {
|
|
11394
|
+
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
11395
|
+
}
|
|
11396
|
+
process.exit(1);
|
|
11397
|
+
}
|
|
11398
|
+
const hits = declared.filter((d) => declaredMatches(d, name));
|
|
11399
|
+
if (hits.length === 1) return hits[0];
|
|
11400
|
+
if (hits.length > 1) {
|
|
11401
|
+
logErr(`"${name}" matches ${hits.length} declared assets; name the one you mean:`);
|
|
11402
|
+
for (const h of hits) console.error(` ${h.ref}`);
|
|
11403
|
+
process.exit(1);
|
|
11404
|
+
}
|
|
11405
|
+
logErr(`No declared asset matches "${name}".`);
|
|
11406
|
+
if (declared.length > 0) logInfo(`Declared: ${declared.map((d) => d.ref).join(", ")}`);
|
|
11407
|
+
process.exit(1);
|
|
11408
|
+
}
|
|
11409
|
+
function readText2(file) {
|
|
11410
|
+
try {
|
|
11411
|
+
return readFileSync(file, "utf8");
|
|
11412
|
+
} catch {
|
|
11413
|
+
return "";
|
|
11414
|
+
}
|
|
11415
|
+
}
|
|
11416
|
+
async function updateOne(am2, projectDir, target) {
|
|
11417
|
+
const lockPath = path18__default.join(projectDir, "skaile.lock.yaml");
|
|
11418
|
+
const before = readText2(lockPath);
|
|
11419
|
+
const spinner = createSpinner();
|
|
11420
|
+
spinner.start(`Updating ${target.ref}`);
|
|
11421
|
+
let deployed;
|
|
11422
|
+
try {
|
|
11423
|
+
deployed = await am2.add(target.ref, { onLibraryMoved: (m) => reportMoved([m]) });
|
|
11424
|
+
} catch (err2) {
|
|
11425
|
+
spinner.stop("Failed");
|
|
11426
|
+
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
11427
|
+
process.exitCode = 1;
|
|
11428
|
+
return;
|
|
11429
|
+
}
|
|
11430
|
+
spinner.stop(process.exitCode === 1 ? "Failed" : "Done");
|
|
11431
|
+
for (const d of deployed) logOk(`Updated ${d}`);
|
|
11432
|
+
if (deployed.length > 0) return;
|
|
11433
|
+
if (readText2(lockPath) !== before) logInfo(`Re-locked ${target.ref}`);
|
|
11434
|
+
else logInfo(`${target.ref} is up to date.`);
|
|
11435
|
+
}
|
|
11219
11436
|
async function shouldSyncSources(opts) {
|
|
11220
11437
|
if (opts.sync === false) return false;
|
|
11221
11438
|
if (opts.yes || !process.stdin.isTTY) return true;
|
|
@@ -11304,17 +11521,23 @@ function refKindName(ref) {
|
|
|
11304
11521
|
let rest = colon === -1 ? trimmed : trimmed.slice(colon + 1);
|
|
11305
11522
|
const hash = rest.indexOf("#");
|
|
11306
11523
|
if (hash !== -1) rest = rest.slice(0, hash);
|
|
11524
|
+
let publisher;
|
|
11307
11525
|
if (rest.startsWith("@")) {
|
|
11308
11526
|
const slash = rest.indexOf("/");
|
|
11309
|
-
if (slash !== -1)
|
|
11527
|
+
if (slash !== -1) {
|
|
11528
|
+
publisher = rest.slice(1, slash);
|
|
11529
|
+
rest = rest.slice(slash + 1);
|
|
11530
|
+
}
|
|
11310
11531
|
}
|
|
11311
|
-
return { kind, name: rest };
|
|
11532
|
+
return { kind, name: rest, publisher };
|
|
11312
11533
|
}
|
|
11313
11534
|
function whyEmptyMessage(ref, declared) {
|
|
11314
|
-
const { kind, name } = refKindName(ref);
|
|
11315
|
-
const isDeclared = declared.some(
|
|
11316
|
-
(d
|
|
11317
|
-
|
|
11535
|
+
const { kind, name, publisher } = refKindName(ref);
|
|
11536
|
+
const isDeclared = declared.some((d) => {
|
|
11537
|
+
if (d.name !== name || kind !== void 0 && d.kind !== kind) return false;
|
|
11538
|
+
const declaredPublisher = d.ref ? refKindName(d.ref).publisher : void 0;
|
|
11539
|
+
return !publisher || !declaredPublisher || publisher === declaredPublisher;
|
|
11540
|
+
});
|
|
11318
11541
|
if (isDeclared) {
|
|
11319
11542
|
return `${ref} not found in lock file. Run \`skaile install\` first.`;
|
|
11320
11543
|
}
|
|
@@ -11324,18 +11547,28 @@ function makeWhyCommand() {
|
|
|
11324
11547
|
return new Command("why").description("Show why an asset is installed (dependency chain)").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
11325
11548
|
const am2 = new AssetManager({
|
|
11326
11549
|
registry: getKindRegistry(),
|
|
11327
|
-
projectDir:
|
|
11550
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
11328
11551
|
});
|
|
11329
11552
|
const chain = await am2.why(ref);
|
|
11330
11553
|
if (chain.length === 0) {
|
|
11554
|
+
const declaredGap = (await am2.gapsOf(ref)).find((g) => g.type === "declared");
|
|
11555
|
+
if (declaredGap) {
|
|
11556
|
+
logErr(declaredGap.message);
|
|
11557
|
+
process.exitCode = 1;
|
|
11558
|
+
return;
|
|
11559
|
+
}
|
|
11331
11560
|
let declared;
|
|
11332
11561
|
try {
|
|
11333
11562
|
declared = await am2.listDeclared();
|
|
11334
|
-
} catch {
|
|
11335
|
-
logErr(
|
|
11563
|
+
} catch (err2) {
|
|
11564
|
+
logErr(
|
|
11565
|
+
`${ref} is not in the lock file, and skaile.yaml cannot be read: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
11566
|
+
);
|
|
11567
|
+
process.exitCode = 1;
|
|
11336
11568
|
return;
|
|
11337
11569
|
}
|
|
11338
11570
|
logErr(whyEmptyMessage(ref, declared));
|
|
11571
|
+
process.exitCode = 1;
|
|
11339
11572
|
return;
|
|
11340
11573
|
}
|
|
11341
11574
|
console.log();
|
|
@@ -11359,7 +11592,7 @@ function makeWhyCommand() {
|
|
|
11359
11592
|
var _defaultFormatHelp = Help.prototype.formatHelp;
|
|
11360
11593
|
var pkg = JSON.parse(
|
|
11361
11594
|
readFileSync(
|
|
11362
|
-
|
|
11595
|
+
path18__default.resolve(path18__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
|
|
11363
11596
|
"utf-8"
|
|
11364
11597
|
)
|
|
11365
11598
|
);
|
|
@@ -11370,7 +11603,7 @@ for (const key of [
|
|
|
11370
11603
|
"SKAILE_CACHE_DIR"
|
|
11371
11604
|
]) {
|
|
11372
11605
|
const value = process.env[key];
|
|
11373
|
-
if (value) process.env[key] =
|
|
11606
|
+
if (value) process.env[key] = path18__default.resolve(value);
|
|
11374
11607
|
}
|
|
11375
11608
|
var program = new Command("skaile").description("AI asset manager").version(pkg.version, "-v, --version", "Show the skaile CLI version").enablePositionalOptions().configureHelp({
|
|
11376
11609
|
formatHelp(cmd, helper) {
|
|
@@ -11490,7 +11723,7 @@ program.command("init [project-dir]").description("Initialize a project director
|
|
|
11490
11723
|
(projectDir, opts) => runInit(projectDir, opts)
|
|
11491
11724
|
);
|
|
11492
11725
|
async function runInit(projectDir, opts) {
|
|
11493
|
-
const { mkdirSync: mkdirSync5, writeFileSync:
|
|
11726
|
+
const { mkdirSync: mkdirSync5, writeFileSync: writeFileSync6 } = await import('fs');
|
|
11494
11727
|
const { stringify: stringify2 } = await import('yaml');
|
|
11495
11728
|
const { DRIVER_TARGETS, SUPPORTED_DRIVER_TARGETS: SUPPORTED_DRIVER_TARGETS2 } = await import('../core/index.js');
|
|
11496
11729
|
const harness = opts.harness;
|
|
@@ -11499,32 +11732,32 @@ async function runInit(projectDir, opts) {
|
|
|
11499
11732
|
process.exitCode = 1;
|
|
11500
11733
|
return;
|
|
11501
11734
|
}
|
|
11502
|
-
const resolved =
|
|
11503
|
-
const projectName =
|
|
11735
|
+
const resolved = path18__default.resolve(projectDir ?? ".");
|
|
11736
|
+
const projectName = path18__default.basename(resolved);
|
|
11504
11737
|
const created = [];
|
|
11505
|
-
const { existsSync:
|
|
11506
|
-
if (!
|
|
11738
|
+
const { existsSync: existsSync17 } = await import('fs');
|
|
11739
|
+
if (!existsSync17(resolved)) {
|
|
11507
11740
|
mkdirSync5(resolved, { recursive: true });
|
|
11508
11741
|
created.push(".");
|
|
11509
11742
|
}
|
|
11510
|
-
const skaileDir =
|
|
11511
|
-
if (!
|
|
11512
|
-
mkdirSync5(
|
|
11743
|
+
const skaileDir = path18__default.join(resolved, ".skaile");
|
|
11744
|
+
if (!existsSync17(skaileDir)) {
|
|
11745
|
+
mkdirSync5(path18__default.join(skaileDir, "sessions"), { recursive: true });
|
|
11513
11746
|
created.push(".skaile/");
|
|
11514
11747
|
}
|
|
11515
|
-
const settingsPath =
|
|
11516
|
-
if (!
|
|
11517
|
-
|
|
11748
|
+
const settingsPath = path18__default.join(skaileDir, "settings.json");
|
|
11749
|
+
if (!existsSync17(settingsPath)) {
|
|
11750
|
+
writeFileSync6(settingsPath, "{}\n");
|
|
11518
11751
|
created.push(".skaile/settings.json");
|
|
11519
11752
|
}
|
|
11520
|
-
const wsConfigPath =
|
|
11521
|
-
if (!
|
|
11522
|
-
|
|
11753
|
+
const wsConfigPath = path18__default.join(resolved, "skaile.yaml");
|
|
11754
|
+
if (!existsSync17(wsConfigPath)) {
|
|
11755
|
+
writeFileSync6(wsConfigPath, stringify2(buildInitWorkspaceConfig(projectName, harness)));
|
|
11523
11756
|
created.push("skaile.yaml");
|
|
11524
11757
|
}
|
|
11525
11758
|
for (const dir of new Set(Object.values(DRIVER_TARGETS[harness].local))) {
|
|
11526
|
-
const full =
|
|
11527
|
-
if (!
|
|
11759
|
+
const full = path18__default.join(resolved, dir);
|
|
11760
|
+
if (!existsSync17(full)) {
|
|
11528
11761
|
mkdirSync5(full, { recursive: true });
|
|
11529
11762
|
created.push(`${dir}/`);
|
|
11530
11763
|
}
|
|
@@ -11554,8 +11787,8 @@ function buildInitWorkspaceConfig(projectName, harness) {
|
|
|
11554
11787
|
}
|
|
11555
11788
|
async function initGitScaffold(resolved, created) {
|
|
11556
11789
|
const { execSync: execSync2 } = await import('child_process');
|
|
11557
|
-
const { existsSync:
|
|
11558
|
-
const gitignorePath =
|
|
11790
|
+
const { existsSync: existsSync17, readFileSync: readFileSync10, writeFileSync: writeFileSync6 } = await import('fs');
|
|
11791
|
+
const gitignorePath = path18__default.join(resolved, ".gitignore");
|
|
11559
11792
|
const entries = [
|
|
11560
11793
|
"node_modules/",
|
|
11561
11794
|
".skaile/sessions/",
|
|
@@ -11572,16 +11805,16 @@ async function initGitScaffold(resolved, created) {
|
|
|
11572
11805
|
".env",
|
|
11573
11806
|
".env.local"
|
|
11574
11807
|
];
|
|
11575
|
-
const existing =
|
|
11808
|
+
const existing = existsSync17(gitignorePath) ? readFileSync10(gitignorePath, "utf-8") : "";
|
|
11576
11809
|
const have = new Set(existing.split("\n").map((l) => l.trim()));
|
|
11577
11810
|
const append = entries.filter((e) => !have.has(e));
|
|
11578
11811
|
if (append.length > 0) {
|
|
11579
11812
|
const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
11580
|
-
|
|
11813
|
+
writeFileSync6(gitignorePath, `${existing + prefix}${append.join("\n")}
|
|
11581
11814
|
`);
|
|
11582
11815
|
if (!existing) created.push(".gitignore");
|
|
11583
11816
|
}
|
|
11584
|
-
if (!
|
|
11817
|
+
if (!existsSync17(path18__default.join(resolved, ".git"))) {
|
|
11585
11818
|
try {
|
|
11586
11819
|
execSync2("git init", { cwd: resolved, stdio: "pipe" });
|
|
11587
11820
|
created.push(".git/");
|
|
@@ -11593,10 +11826,10 @@ async function initGitScaffold(resolved, created) {
|
|
|
11593
11826
|
}
|
|
11594
11827
|
async function bootstrapUserConfig() {
|
|
11595
11828
|
try {
|
|
11596
|
-
const
|
|
11829
|
+
const fs13 = await import('fs');
|
|
11597
11830
|
const { userConfigPath: userConfigPath2, saveConfig, getConfigDefaults } = await import('../library/index.js');
|
|
11598
11831
|
const userCfgPath = userConfigPath2();
|
|
11599
|
-
if (!
|
|
11832
|
+
if (!fs13.existsSync(userCfgPath)) {
|
|
11600
11833
|
const defaults = getConfigDefaults();
|
|
11601
11834
|
saveConfig(userCfgPath, {
|
|
11602
11835
|
catalog: { url: defaults.catalog.url, cache_ttl: defaults.catalog.cache_ttl }
|
|
@@ -11611,7 +11844,7 @@ async function bootstrapUserConfig() {
|
|
|
11611
11844
|
}
|
|
11612
11845
|
async function hydrateInitSources(resolved, created) {
|
|
11613
11846
|
try {
|
|
11614
|
-
const { ensureSourcesCloned } = await import('../ensure-sources-
|
|
11847
|
+
const { ensureSourcesCloned } = await import('../ensure-sources-2RONZKCU.js');
|
|
11615
11848
|
const hydrate = ensureSourcesCloned(resolved, { quiet: true });
|
|
11616
11849
|
for (const n of hydrate.cloned) created.push(`~/.skaile/cache/sources/${n}/`);
|
|
11617
11850
|
if (hydrate.failed.length > 0) {
|
|
@@ -11627,7 +11860,7 @@ function printInitSummary(resolved, projectDir, created) {
|
|
|
11627
11860
|
logOk(`Initialized project at ${S.heading(resolved)}`);
|
|
11628
11861
|
console.log();
|
|
11629
11862
|
console.log(S.heading(" Next steps:"));
|
|
11630
|
-
const isCurrentDir = resolved ===
|
|
11863
|
+
const isCurrentDir = resolved === path18__default.resolve(".");
|
|
11631
11864
|
let step = 1;
|
|
11632
11865
|
if (!isCurrentDir) {
|
|
11633
11866
|
console.log(` ${S.dim(`${step}.`)} ${S.cmd(`cd ${projectDir}`)}`);
|
|
@@ -11651,7 +11884,7 @@ function printInitSummary(resolved, projectDir, created) {
|
|
|
11651
11884
|
console.log();
|
|
11652
11885
|
}
|
|
11653
11886
|
program.command("setup").description("Interactive provider setup wizard").action(async () => {
|
|
11654
|
-
const { cmdSetup } = await import('../setup-
|
|
11887
|
+
const { cmdSetup } = await import('../setup-7DQJKHUI.js');
|
|
11655
11888
|
await cmdSetup([], { projectDir: process.cwd() });
|
|
11656
11889
|
});
|
|
11657
11890
|
program.addCommand(makeInstallCommand());
|
|
@@ -11729,11 +11962,18 @@ process.stdout.on("error", (err2) => {
|
|
|
11729
11962
|
if (err2.code === "EPIPE") process.exit(0);
|
|
11730
11963
|
throw err2;
|
|
11731
11964
|
});
|
|
11965
|
+
var commandSettled = false;
|
|
11966
|
+
process.once("beforeExit", () => {
|
|
11967
|
+
if (commandSettled) return;
|
|
11968
|
+
logErr("The command ended before it finished (nothing left to wait for).");
|
|
11969
|
+
process.exit(1);
|
|
11970
|
+
});
|
|
11732
11971
|
try {
|
|
11733
11972
|
await program.parseAsync();
|
|
11973
|
+
commandSettled = true;
|
|
11734
11974
|
} catch (err2) {
|
|
11735
11975
|
const { LibrarySyncError } = await import('../library/index.js');
|
|
11736
|
-
if (!(err2 instanceof LibrarySyncError)) throw err2;
|
|
11976
|
+
if (!(err2 instanceof LibrarySyncError || err2 instanceof SourceEntryError)) throw err2;
|
|
11737
11977
|
logErr(err2.message);
|
|
11738
11978
|
process.exit(1);
|
|
11739
11979
|
}
|