@skaile/workspaces 5.11.0 → 5.12.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 +97 -0
- package/README.md +2 -2
- package/dist/{asset-feeds-CXGQIDFR.js → asset-feeds-AM6PSSGM.js} +24 -21
- package/dist/asset-feeds-AM6PSSGM.js.map +1 -0
- package/dist/asset-manager/catalog-deployer.js +8 -8
- package/dist/asset-manager/fragments.js +1 -1
- package/dist/asset-manager/index.js +16 -16
- package/dist/asset-manager/installer.js +11 -11
- package/dist/asset-manager/renderers.js +9 -9
- package/dist/asset-manager/src/fragments.d.ts +5 -0
- package/dist/asset-manager/src/fragments.d.ts.map +1 -1
- package/dist/asset-manager/src/index.d.ts +95 -10
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/install-agent.d.ts +9 -1
- package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts +10 -0
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/asset-manager/src/renderers.d.ts +5 -0
- package/dist/asset-manager/src/renderers.d.ts.map +1 -1
- package/dist/bridge/drivers/claude-sdk.js +16 -13
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +43 -16
- package/dist/bridge/drivers/codex.js.map +1 -1
- 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 +37 -10
- 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/codex/config-toml.d.ts +8 -3
- package/dist/bridge/src/codex/config-toml.d.ts.map +1 -1
- package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
- package/dist/bridge/src/drivers/claude-sdk.d.ts +1 -1
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
- package/dist/bridge/src/drivers/omp-models-yml.d.ts.map +1 -1
- package/dist/bridge/src/drivers/omp.d.ts +9 -0
- package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
- package/dist/bridge/src/provider-materialize/credential-env.d.ts +15 -0
- package/dist/bridge/src/provider-materialize/credential-env.d.ts.map +1 -1
- package/dist/{chunk-4A4OD24G.js → chunk-27L6BBAT.js} +9 -9
- package/dist/{chunk-4A4OD24G.js.map → chunk-27L6BBAT.js.map} +1 -1
- package/dist/{chunk-HCEVNYSH.js → chunk-2JFIFDDO.js} +3 -3
- package/dist/{chunk-HCEVNYSH.js.map → chunk-2JFIFDDO.js.map} +1 -1
- package/dist/{chunk-3SM2DL2T.js → chunk-2X3JBVGD.js} +11 -10
- package/dist/chunk-2X3JBVGD.js.map +1 -0
- package/dist/{chunk-G4FFOV3N.js → chunk-3HUV2LJF.js} +4 -4
- package/dist/{chunk-G4FFOV3N.js.map → chunk-3HUV2LJF.js.map} +1 -1
- package/dist/{chunk-QZNJOHN6.js → chunk-3LVB3HGH.js} +3 -3
- package/dist/{chunk-QZNJOHN6.js.map → chunk-3LVB3HGH.js.map} +1 -1
- package/dist/{chunk-ZCAJZ4B2.js → chunk-6VLHITAM.js} +145 -3
- package/dist/chunk-6VLHITAM.js.map +1 -0
- package/dist/{chunk-J4RBUFGM.js → chunk-7CR2OZPA.js} +6 -6
- package/dist/{chunk-J4RBUFGM.js.map → chunk-7CR2OZPA.js.map} +1 -1
- package/dist/{chunk-HZXUXHIV.js → chunk-7QWQTA5S.js} +89 -12
- package/dist/chunk-7QWQTA5S.js.map +1 -0
- package/dist/{chunk-TCHRMVTO.js → chunk-7XWUJC3A.js} +4 -4
- package/dist/{chunk-TCHRMVTO.js.map → chunk-7XWUJC3A.js.map} +1 -1
- package/dist/{chunk-2F5AWQX5.js → chunk-C3BMXXTN.js} +137 -31
- package/dist/chunk-C3BMXXTN.js.map +1 -0
- package/dist/{chunk-ZPWTOUTK.js → chunk-CTP3XBMF.js} +7 -4
- package/dist/chunk-CTP3XBMF.js.map +1 -0
- package/dist/{chunk-GCHPUTA3.js → chunk-DCHQ6BAZ.js} +3 -3
- package/dist/{chunk-GCHPUTA3.js.map → chunk-DCHQ6BAZ.js.map} +1 -1
- package/dist/{chunk-DALV4HHP.js → chunk-DKXNKFKP.js} +3 -2
- package/dist/{chunk-DALV4HHP.js.map → chunk-DKXNKFKP.js.map} +1 -1
- package/dist/{chunk-X77SUM4P.js → chunk-G3X4MLDB.js} +3 -3
- package/dist/{chunk-X77SUM4P.js.map → chunk-G3X4MLDB.js.map} +1 -1
- package/dist/{chunk-CAHB6MHA.js → chunk-GWD3QNVS.js} +5 -5
- package/dist/{chunk-CAHB6MHA.js.map → chunk-GWD3QNVS.js.map} +1 -1
- package/dist/chunk-H5U7LNTJ.js +122 -0
- package/dist/chunk-H5U7LNTJ.js.map +1 -0
- package/dist/{chunk-QVFAS5IO.js → chunk-HYMERG57.js} +3 -3
- package/dist/{chunk-QVFAS5IO.js.map → chunk-HYMERG57.js.map} +1 -1
- package/dist/{chunk-R7NHYEJF.js → chunk-ICIYSJBQ.js} +4 -4
- package/dist/{chunk-R7NHYEJF.js.map → chunk-ICIYSJBQ.js.map} +1 -1
- package/dist/{chunk-YOH2L76X.js → chunk-ID745F3R.js} +353 -233
- package/dist/chunk-ID745F3R.js.map +1 -0
- package/dist/{chunk-PQFHMQHQ.js → chunk-JQ3DXNQV.js} +4 -4
- package/dist/{chunk-PQFHMQHQ.js.map → chunk-JQ3DXNQV.js.map} +1 -1
- package/dist/chunk-K4VOEYOR.js +21 -0
- package/dist/chunk-K4VOEYOR.js.map +1 -0
- package/dist/{chunk-XDKH7XSA.js → chunk-KVSDRB35.js} +5 -5
- package/dist/{chunk-XDKH7XSA.js.map → chunk-KVSDRB35.js.map} +1 -1
- package/dist/{chunk-47U4GZ4M.js → chunk-MF54ZHWT.js} +20 -3
- package/dist/chunk-MF54ZHWT.js.map +1 -0
- package/dist/{chunk-VLTQGE2E.js → chunk-N5M2EISA.js} +197 -52
- package/dist/chunk-N5M2EISA.js.map +1 -0
- package/dist/{chunk-T7CTHHG7.js → chunk-NDF24LYP.js} +3 -3
- package/dist/{chunk-T7CTHHG7.js.map → chunk-NDF24LYP.js.map} +1 -1
- package/dist/{chunk-CPWLNZGJ.js → chunk-NGJIVDDD.js} +3 -3
- package/dist/{chunk-CPWLNZGJ.js.map → chunk-NGJIVDDD.js.map} +1 -1
- package/dist/{chunk-FH7W6TJ4.js → chunk-NJV5SLEK.js} +104 -23
- package/dist/chunk-NJV5SLEK.js.map +1 -0
- package/dist/{chunk-M3B6EIJD.js → chunk-NJXR5OAM.js} +4 -4
- package/dist/{chunk-M3B6EIJD.js.map → chunk-NJXR5OAM.js.map} +1 -1
- package/dist/{chunk-CGYEHQOX.js → chunk-NOA6EJXE.js} +11 -2
- package/dist/chunk-NOA6EJXE.js.map +1 -0
- package/dist/{chunk-RYYLMBA2.js → chunk-NR7H7ZJP.js} +14 -6
- package/dist/chunk-NR7H7ZJP.js.map +1 -0
- package/dist/{chunk-OBYKJB4U.js → chunk-O2SYFJWP.js} +79 -5
- package/dist/chunk-O2SYFJWP.js.map +1 -0
- package/dist/{chunk-5LKOAX7I.js → chunk-OQ5MKDS3.js} +21 -5
- package/dist/chunk-OQ5MKDS3.js.map +1 -0
- package/dist/{chunk-CJERAGFY.js → chunk-P23WJCH2.js} +37 -11
- package/dist/chunk-P23WJCH2.js.map +1 -0
- package/dist/{chunk-NWDSLXOX.js → chunk-PHRNUTSG.js} +118 -118
- package/dist/chunk-PHRNUTSG.js.map +1 -0
- package/dist/{chunk-ALEYHUC5.js → chunk-PNOGX36L.js} +104 -24
- package/dist/chunk-PNOGX36L.js.map +1 -0
- package/dist/{chunk-BNMZVPYA.js → chunk-PNTXHTBC.js} +2 -2
- package/dist/{chunk-BNMZVPYA.js.map → chunk-PNTXHTBC.js.map} +1 -1
- package/dist/{chunk-GV4DZ6MT.js → chunk-POQ6PGNE.js} +4 -4
- package/dist/{chunk-GV4DZ6MT.js.map → chunk-POQ6PGNE.js.map} +1 -1
- package/dist/{chunk-T42WRQ4O.js → chunk-QCEKGYHF.js} +3 -3
- package/dist/{chunk-T42WRQ4O.js.map → chunk-QCEKGYHF.js.map} +1 -1
- package/dist/{chunk-EDYHEMJA.js → chunk-SHQMPGOL.js} +4 -4
- package/dist/{chunk-EDYHEMJA.js.map → chunk-SHQMPGOL.js.map} +1 -1
- package/dist/{chunk-S3O3GKB7.js → chunk-SMT3LNAG.js} +4 -4
- package/dist/{chunk-S3O3GKB7.js.map → chunk-SMT3LNAG.js.map} +1 -1
- package/dist/{chunk-PBBPZYVG.js → chunk-T5TSLSRO.js} +110 -44
- package/dist/chunk-T5TSLSRO.js.map +1 -0
- package/dist/{chunk-DZMNFCWB.js → chunk-TVAR4JHA.js} +530 -126
- package/dist/chunk-TVAR4JHA.js.map +1 -0
- package/dist/{chunk-COH6FQAG.js → chunk-UTKENBB6.js} +5 -5
- package/dist/{chunk-COH6FQAG.js.map → chunk-UTKENBB6.js.map} +1 -1
- package/dist/{chunk-XUSALIEI.js → chunk-VRLKHL74.js} +6 -6
- package/dist/{chunk-XUSALIEI.js.map → chunk-VRLKHL74.js.map} +1 -1
- package/dist/{chunk-WSBKB4CJ.js → chunk-WI4T3KIS.js} +51 -16
- package/dist/chunk-WI4T3KIS.js.map +1 -0
- package/dist/{chunk-D3B36CYC.js → chunk-X3RMRJNR.js} +4 -3
- package/dist/chunk-X3RMRJNR.js.map +1 -0
- package/dist/{chunk-IER3KIPH.js → chunk-X6LKA3TJ.js} +5 -5
- package/dist/{chunk-IER3KIPH.js.map → chunk-X6LKA3TJ.js.map} +1 -1
- package/dist/{chunk-Y3HTGHJC.js → chunk-XMAJJPA4.js} +3 -3
- package/dist/{chunk-Y3HTGHJC.js.map → chunk-XMAJJPA4.js.map} +1 -1
- package/dist/{chunk-SBSA3IQA.js → chunk-XTVSNWLL.js} +19 -7
- package/dist/chunk-XTVSNWLL.js.map +1 -0
- package/dist/{chunk-MZG34MBZ.js → chunk-XZY6SBGU.js} +3 -3
- package/dist/{chunk-MZG34MBZ.js.map → chunk-XZY6SBGU.js.map} +1 -1
- package/dist/{chunk-6O2X3GPW.js → chunk-YQU2BPQD.js} +7 -5
- package/dist/chunk-YQU2BPQD.js.map +1 -0
- package/dist/cli/index.js +1077 -497
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/agent-checks.d.ts +40 -0
- package/dist/cli/src/agent-checks.d.ts.map +1 -0
- package/dist/cli/src/asset-feeds.d.ts.map +1 -1
- package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +24 -0
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/config.d.ts.map +1 -1
- package/dist/cli/src/commands/diff.d.ts.map +1 -1
- package/dist/cli/src/commands/integration.d.ts.map +1 -1
- package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
- package/dist/cli/src/commands/mcp-server.d.ts +1 -1
- package/dist/cli/src/commands/migrate-assets.d.ts +2 -1
- package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate.d.ts.map +1 -1
- package/dist/cli/src/commands/plugin/claude-code.d.ts +1 -1
- package/dist/cli/src/commands/plugin/claude-code.d.ts.map +1 -1
- package/dist/cli/src/commands/plugin/types.d.ts +1 -1
- package/dist/cli/src/commands/plugin-registry-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/publish-core.d.ts +5 -0
- package/dist/cli/src/commands/publish-core.d.ts.map +1 -1
- package/dist/cli/src/commands/run.d.ts +2 -1
- package/dist/cli/src/commands/run.d.ts.map +1 -1
- package/dist/cli/src/commands/serve-preflight.d.ts +22 -0
- package/dist/cli/src/commands/serve-preflight.d.ts.map +1 -0
- package/dist/cli/src/commands/serve.d.ts.map +1 -1
- package/dist/cli/src/commands/source-manifest-publish.d.ts.map +1 -1
- package/dist/cli/src/commands/source-manifest.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/store.d.ts.map +1 -1
- package/dist/cli/src/commands/tree.d.ts.map +1 -1
- package/dist/cli/src/commands/update.d.ts.map +1 -1
- package/dist/cli/src/commands/validate.d.ts.map +1 -1
- package/dist/cli/src/commands/why.d.ts.map +1 -1
- package/dist/cli/src/curated-manifests.d.ts +21 -0
- package/dist/cli/src/curated-manifests.d.ts.map +1 -0
- package/dist/cli/src/index-busy.d.ts +8 -0
- package/dist/cli/src/index-busy.d.ts.map +1 -0
- package/dist/cli/src/plugin-store/paths.d.ts +7 -3
- package/dist/cli/src/plugin-store/paths.d.ts.map +1 -1
- package/dist/cli/src/skill-checks.d.ts +15 -2
- package/dist/cli/src/skill-checks.d.ts.map +1 -1
- package/dist/cli/src/store-addable.d.ts +18 -0
- package/dist/cli/src/store-addable.d.ts.map +1 -0
- package/dist/connectors/config.js +5 -5
- package/dist/connectors/index.js +16 -16
- package/dist/{connectors-4QWAKPHB.js → connectors-UNKUKEPG.js} +19 -19
- package/dist/{connectors-4QWAKPHB.js.map → connectors-UNKUKEPG.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 +5 -4
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/lock.d.ts +15 -5
- package/dist/core/src/lock.d.ts.map +1 -1
- package/dist/core/src/logging/sinks/sqlite-sink.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +5 -0
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +3 -3
- package/dist/core/src/package-manager.d.ts +19 -0
- package/dist/core/src/package-manager.d.ts.map +1 -0
- package/dist/core/src/publish-manifest.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts +11 -0
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/settings.d.ts +26 -6
- package/dist/core/src/settings.d.ts.map +1 -1
- package/dist/core/src/walker.d.ts +6 -1
- package/dist/core/src/walker.d.ts.map +1 -1
- package/dist/core/src/workspace-config.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/{ensure-sources-2RONZKCU.js → ensure-sources-POMEQSTM.js} +19 -19
- package/dist/{ensure-sources-2RONZKCU.js.map → ensure-sources-POMEQSTM.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.d.ts.map +1 -1
- 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-assets/SKILL.md +10 -8
- package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +15 -11
- package/dist/factory-assets/skills/authoring-skaile-manifests/references/dependency-standard.md +12 -9
- package/dist/factory-assets/skills/skaile-author-asset/SKILL.md +2 -2
- package/dist/{flows-EQF2CH4U.js → flows-DVKMZKM4.js} +12 -12
- package/dist/{flows-EQF2CH4U.js.map → flows-DVKMZKM4.js.map} +1 -1
- package/dist/{helpers-CFK6YP6R.js → helpers-Y4OT7VIS.js} +19 -19
- package/dist/{helpers-CFK6YP6R.js.map → helpers-Y4OT7VIS.js.map} +1 -1
- package/dist/library/index.js +12 -12
- package/dist/library/install.js +4 -4
- package/dist/library/src/index.d.ts +2 -2
- package/dist/library/src/index.d.ts.map +1 -1
- package/dist/library/src/install/source-fetch-github.d.ts.map +1 -1
- package/dist/library/src/local/db.d.ts +2 -0
- package/dist/library/src/local/db.d.ts.map +1 -1
- package/dist/library/src/local/library-manager.d.ts +5 -0
- package/dist/library/src/local/library-manager.d.ts.map +1 -1
- package/dist/library/src/local/library.d.ts +5 -3
- package/dist/library/src/local/library.d.ts.map +1 -1
- package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
- package/dist/library/src/local/store-paths.d.ts +9 -0
- package/dist/library/src/local/store-paths.d.ts.map +1 -1
- package/dist/library/src/manifest-writer.d.ts.map +1 -1
- package/dist/library/src/remote/index.d.ts +1 -1
- package/dist/library/src/remote/index.d.ts.map +1 -1
- package/dist/library/src/remote/remote-catalog-source.d.ts +17 -0
- package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
- package/dist/library/src/sync/git-driver.d.ts.map +1 -1
- package/dist/{library-publish-53UTB3MB.js → library-publish-DI4Q5UOG.js} +45 -37
- package/dist/library-publish-DI4Q5UOG.js.map +1 -0
- package/dist/open-library-N6ESO6IK.js +40 -0
- package/dist/{open-library-BOSPJVID.js.map → open-library-N6ESO6IK.js.map} +1 -1
- package/dist/open-registry-CBZ5MWTT.js +32 -0
- package/dist/{open-registry-4FI7HKET.js.map → open-registry-CBZ5MWTT.js.map} +1 -1
- package/dist/paths-U6W6MQNQ.js +22 -0
- package/dist/{paths-SUS4S4YT.js.map → paths-U6W6MQNQ.js.map} +1 -1
- package/dist/{plugin-store-AGQDMING.js → plugin-store-XMZSPVBF.js} +48 -12
- package/dist/plugin-store-XMZSPVBF.js.map +1 -0
- package/dist/project-UP52HEHC.js +79 -0
- package/dist/{project-I55A4O2T.js.map → project-UP52HEHC.js.map} +1 -1
- package/dist/resolver/index.js +8 -8
- package/dist/runner/index.js +33 -33
- package/dist/runner/src/agent.d.ts.map +1 -1
- package/dist/runner/src/agents/in-process-host.d.ts.map +1 -1
- package/dist/runner/src/composition/index.d.ts +1 -0
- package/dist/runner/src/composition/index.d.ts.map +1 -1
- package/dist/runner/src/composition/prompt-sections.d.ts +7 -4
- package/dist/runner/src/composition/prompt-sections.d.ts.map +1 -1
- package/dist/runner/src/composition/resolve.d.ts +10 -1
- package/dist/runner/src/composition/resolve.d.ts.map +1 -1
- package/dist/runner/src/composition/verify.d.ts +29 -0
- package/dist/runner/src/composition/verify.d.ts.map +1 -0
- package/dist/runner/src/credential-notice.d.ts +14 -0
- package/dist/runner/src/credential-notice.d.ts.map +1 -0
- package/dist/runner/src/environment.d.ts.map +1 -1
- package/dist/runner/src/final-text.d.ts +17 -0
- package/dist/runner/src/final-text.d.ts.map +1 -0
- package/dist/runner/src/index.d.ts +2 -0
- package/dist/runner/src/index.d.ts.map +1 -1
- package/dist/runner/src/resource-handler.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts +13 -0
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +16 -16
- 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 +36 -34
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.js +8 -8
- package/dist/sdk/runner.js +33 -33
- package/dist/sdk/src/local-runtime.d.ts.map +1 -1
- package/dist/sdk/transport/ws/client.js +1 -1
- package/dist/sdk/transport/ws/server.js +1 -1
- package/dist/sdk/transport/ws.js +2 -2
- package/dist/sdk/transport.js +2 -2
- package/dist/serve-preflight-6P2JJEJ3.js +47 -0
- package/dist/serve-preflight-6P2JJEJ3.js.map +1 -0
- package/dist/{setup-7DQJKHUI.js → setup-5IRUH5OS.js} +24 -24
- package/dist/{setup-7DQJKHUI.js.map → setup-5IRUH5OS.js.map} +1 -1
- package/dist/{skills-NUEN5NDX.js → skills-HA36RFNM.js} +13 -13
- package/dist/{skills-NUEN5NDX.js.map → skills-HA36RFNM.js.map} +1 -1
- package/dist/source-DX5SGWEI.js +41 -0
- package/dist/{source-G2LV5LVD.js.map → source-DX5SGWEI.js.map} +1 -1
- package/dist/source-fetch-github-PIO6EMMF.js +4 -0
- package/dist/{source-fetch-github-QN4LLTL5.js.map → source-fetch-github-PIO6EMMF.js.map} +1 -1
- package/dist/{source-manifest-publish-6RM7SWLZ.js → source-manifest-publish-NMRLXWVW.js} +27 -26
- package/dist/source-manifest-publish-NMRLXWVW.js.map +1 -0
- package/dist/transport/index.js +2 -2
- package/dist/transport/src/ws/client.d.ts +6 -0
- package/dist/transport/src/ws/client.d.ts.map +1 -1
- package/dist/transport/src/ws/server.d.ts +4 -0
- package/dist/transport/src/ws/server.d.ts.map +1 -1
- package/dist/transport/ws/client.js +1 -1
- package/dist/transport/ws/server.js +1 -1
- package/dist/transport/ws.js +2 -2
- package/dist/tui/index.js +58 -41
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/src/repl-session.d.ts +1 -1
- package/dist/tui/src/repl-session.d.ts.map +1 -1
- package/dist/tui/src/repl.d.ts +3 -0
- package/dist/tui/src/repl.d.ts.map +1 -1
- package/dist/types/manifests.js +1 -1
- package/dist/types/src/manifests/agent-composition.d.ts +20 -0
- package/dist/types/src/manifests/agent-composition.d.ts.map +1 -1
- package/dist/types/src/manifests/agent.d.ts.map +1 -1
- package/dist/types/src/manifests/cron.d.ts +15 -0
- package/dist/types/src/manifests/cron.d.ts.map +1 -0
- package/dist/types/src/manifests/index.d.ts +3 -2
- package/dist/types/src/manifests/index.d.ts.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +23 -23
- package/dist/workspace-plugin/adapters/omp.js +106 -51
- package/dist/workspace-plugin/adapters/omp.js.map +1 -1
- package/dist/workspace-plugin/index.js +2 -2
- package/dist/workspace-plugin/src/adapters/claude-code.d.ts.map +1 -1
- package/dist/workspace-plugin/src/adapters/omp.d.ts +11 -2
- package/dist/workspace-plugin/src/adapters/omp.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/asset-feeds-CXGQIDFR.js.map +0 -1
- package/dist/chunk-2F5AWQX5.js.map +0 -1
- package/dist/chunk-3SM2DL2T.js.map +0 -1
- package/dist/chunk-47U4GZ4M.js.map +0 -1
- package/dist/chunk-5LKOAX7I.js.map +0 -1
- package/dist/chunk-6O2X3GPW.js.map +0 -1
- package/dist/chunk-ALEYHUC5.js.map +0 -1
- package/dist/chunk-CGYEHQOX.js.map +0 -1
- package/dist/chunk-CJERAGFY.js.map +0 -1
- package/dist/chunk-D3B36CYC.js.map +0 -1
- package/dist/chunk-DZMNFCWB.js.map +0 -1
- package/dist/chunk-FH7W6TJ4.js.map +0 -1
- package/dist/chunk-HZXUXHIV.js.map +0 -1
- package/dist/chunk-NWDSLXOX.js.map +0 -1
- package/dist/chunk-OBYKJB4U.js.map +0 -1
- package/dist/chunk-PBBPZYVG.js.map +0 -1
- package/dist/chunk-R7FOF242.js +0 -59
- package/dist/chunk-R7FOF242.js.map +0 -1
- package/dist/chunk-RYYLMBA2.js.map +0 -1
- package/dist/chunk-SBSA3IQA.js.map +0 -1
- package/dist/chunk-VLTQGE2E.js.map +0 -1
- package/dist/chunk-WSBKB4CJ.js.map +0 -1
- package/dist/chunk-YOH2L76X.js.map +0 -1
- package/dist/chunk-ZCAJZ4B2.js.map +0 -1
- package/dist/chunk-ZPWTOUTK.js.map +0 -1
- package/dist/library-publish-53UTB3MB.js.map +0 -1
- package/dist/open-library-BOSPJVID.js +0 -40
- package/dist/open-registry-4FI7HKET.js +0 -32
- package/dist/paths-SUS4S4YT.js +0 -22
- package/dist/plugin-store-AGQDMING.js.map +0 -1
- package/dist/project-I55A4O2T.js +0 -41
- package/dist/source-G2LV5LVD.js +0 -41
- package/dist/source-fetch-github-QN4LLTL5.js +0 -4
- package/dist/source-manifest-publish-6RM7SWLZ.js.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,98 +1,100 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-
|
|
3
|
-
import { makeSourceCommand, syncProjectSources, divergedSourceClones } from '../chunk-
|
|
4
|
-
import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportReplaced, reportRelocked, reportMoved, REF_HINT, reportInstalledSoftDeps } from '../chunk-
|
|
2
|
+
import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-KVSDRB35.js';
|
|
3
|
+
import { makeSourceCommand, syncProjectSources, divergedSourceClones } from '../chunk-WI4T3KIS.js';
|
|
4
|
+
import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportReplaced, reportRelocked, reportMoved, REF_HINT, reportInstalledSoftDeps } from '../chunk-P23WJCH2.js';
|
|
5
5
|
import { createSpinner } from '../chunk-NESV47MF.js';
|
|
6
|
-
import { AI_RESOURCES } from '../chunk-
|
|
7
|
-
import { unresolvedManifestDependencies, warnIgnoredDomainFiles, warnLegacyBundleFiles, removedDomainOption, rejectRemovedDomainOption, resolveLibraryPublisherDetailed, warnLibraryNameFallback, indexLibrary, requireValidPublisherOrExit, exitOnManifestPublisherProblems, registerLibraryAsset, DOMAIN_REMOVED_HINT, manifestPublisherProblems, manifestRequiresProblems, findAssetManifestFile, declaredVersion, checkAssetFile, duplicateAssetMessage, readAssetBody,
|
|
8
|
-
import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, assetEntryRef, manifestVersionMismatchMessage } from '../chunk-
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
6
|
+
import { AI_RESOURCES } from '../chunk-SMT3LNAG.js';
|
|
7
|
+
import { unresolvedManifestDependencies, warnIgnoredDomainFiles, warnLegacyBundleFiles, removedDomainOption, rejectRemovedDomainOption, resolveLibraryPublisherDetailed, warnLibraryNameFallback, indexLibrary, requireValidPublisherOrExit, exitOnManifestPublisherProblems, registerLibraryAsset, DOMAIN_REMOVED_HINT, checkAsset, agentComposeRefAdvisories, manifestPublisherProblems, manifestRequiresProblems, findAssetManifestFile, declaredVersion, checkAssetFile, duplicateAssetMessage, readAssetBody, checkAgentFiles, invalidSemverText } from '../chunk-ID745F3R.js';
|
|
8
|
+
import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, assetEntryRef, manifestVersionMismatchMessage } from '../chunk-NR7H7ZJP.js';
|
|
9
|
+
import { storeNotInstallableReason, STORE_UNADDABLE_KINDS } from '../chunk-K4VOEYOR.js';
|
|
10
|
+
import { openCatalogSource, LocalCatalogDisabledError, openLibraryManager, openLibrary } from '../chunk-JQ3DXNQV.js';
|
|
11
|
+
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-POQ6PGNE.js';
|
|
12
|
+
import { getKindRegistry, getKnownKinds } from '../chunk-GWD3QNVS.js';
|
|
12
13
|
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-
|
|
14
|
+
import { runAgentChat, isCompositionError, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, hashAgentFiles, createCompositionContentSource, compileComposition, instanceForSession, resolveAgentInstance, describeComposition, MarkdownStreamer, createFinalTextFallback } from '../chunk-N5M2EISA.js';
|
|
15
|
+
import { buildClaudePluginFiles } from '../chunk-YQU2BPQD.js';
|
|
16
|
+
import '../chunk-X6LKA3TJ.js';
|
|
17
|
+
import '../chunk-HYMERG57.js';
|
|
17
18
|
import '../chunk-R6O6YWU7.js';
|
|
18
|
-
import '../chunk-
|
|
19
|
-
import '../chunk-
|
|
19
|
+
import '../chunk-3HUV2LJF.js';
|
|
20
|
+
import '../chunk-QCEKGYHF.js';
|
|
20
21
|
import '../chunk-4ZTPYIBE.js';
|
|
21
|
-
import '../chunk-
|
|
22
|
+
import '../chunk-XZY6SBGU.js';
|
|
22
23
|
import '../chunk-X5YPJV4N.js';
|
|
23
24
|
import '../chunk-O7SG5PC2.js';
|
|
24
25
|
import '../chunk-7QBNJTTQ.js';
|
|
25
|
-
import '../chunk-
|
|
26
|
-
import '../chunk-
|
|
26
|
+
import '../chunk-O2SYFJWP.js';
|
|
27
|
+
import '../chunk-OQ5MKDS3.js';
|
|
27
28
|
import '../chunk-32NA4TVC.js';
|
|
28
29
|
import '../chunk-W3UDISS2.js';
|
|
29
|
-
import '../chunk-
|
|
30
|
-
import { runFlow, resumeFlow } from '../chunk-
|
|
30
|
+
import '../chunk-PHRNUTSG.js';
|
|
31
|
+
import { runFlow, resumeFlow } from '../chunk-2X3JBVGD.js';
|
|
31
32
|
import '../chunk-4R6DROGN.js';
|
|
32
|
-
import { validateFlowVersions } from '../chunk-
|
|
33
|
-
import '../chunk-
|
|
33
|
+
import { parseSkillRequirements, validateRequirements, validateFlowVersions } from '../chunk-G3X4MLDB.js';
|
|
34
|
+
import '../chunk-DCHQ6BAZ.js';
|
|
34
35
|
import '../chunk-ISHJITXJ.js';
|
|
35
|
-
import '../chunk-
|
|
36
|
+
import '../chunk-27L6BBAT.js';
|
|
36
37
|
import '../chunk-X4BAYGMT.js';
|
|
37
|
-
import '../chunk-
|
|
38
|
-
import '../chunk-
|
|
39
|
-
import '../chunk-
|
|
38
|
+
import '../chunk-ICIYSJBQ.js';
|
|
39
|
+
import '../chunk-NDF24LYP.js';
|
|
40
|
+
import '../chunk-2JFIFDDO.js';
|
|
40
41
|
import '../chunk-LOO5CB5M.js';
|
|
41
42
|
import '../chunk-2H73V6XR.js';
|
|
42
|
-
import '../chunk-
|
|
43
|
+
import '../chunk-NJXR5OAM.js';
|
|
43
44
|
import '../chunk-B4X2N7JQ.js';
|
|
44
45
|
import '../chunk-YROR332M.js';
|
|
45
|
-
import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-
|
|
46
|
+
import { listDrivers, getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-MF54ZHWT.js';
|
|
46
47
|
import '../chunk-6E6PKKAD.js';
|
|
47
48
|
import '../chunk-IFGTRL2I.js';
|
|
48
|
-
import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-
|
|
49
|
+
import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-7XWUJC3A.js';
|
|
49
50
|
import '../chunk-LNFKL23K.js';
|
|
50
|
-
import '../chunk-
|
|
51
|
+
import '../chunk-X3RMRJNR.js';
|
|
51
52
|
import '../chunk-M3WPBTGJ.js';
|
|
52
53
|
import { nodeLabel, nodeSkillAsset, nodeIsInert, nodeIsOptional, nodeRunKind, flowSkillVersionPins } from '../chunk-7RGTAEG6.js';
|
|
53
54
|
import '../chunk-NUELZWCF.js';
|
|
54
55
|
import '../chunk-F4NJDSR7.js';
|
|
55
|
-
import { AssetManager, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-
|
|
56
|
-
import { libraryDirMissing, missingLibraryDirMessage, cloneOrInitGitRepo, trackOriginBranch, stampManifestPublisher, ensureGitRepo, conflictingAssetRoot, setManifestPublisher, LIBRARY_OWNERSHIPS,
|
|
57
|
-
import { parseManifestFile, SEMVER_RE } from '../chunk-
|
|
58
|
-
import '../chunk-
|
|
59
|
-
import '../chunk-
|
|
56
|
+
import { AssetManager, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-TVAR4JHA.js';
|
|
57
|
+
import { libraryDirMissing, missingLibraryDirMessage, cloneOrInitGitRepo, trackOriginBranch, stampManifestPublisher, isGitRepo, ensureGitRepo, conflictingAssetRoot, setManifestPublisher, LIBRARY_OWNERSHIPS, assertManifestEditable, installLibraryAsset, missingRootAssets, getStoreManifestsDir, assertValidLibraryName, syncManifestWithDisk, getDefaultValue, isSecretPlaceholder } from '../chunk-C3BMXXTN.js';
|
|
58
|
+
import { parseManifestFile, SEMVER_RE } from '../chunk-7CR2OZPA.js';
|
|
59
|
+
import '../chunk-UTKENBB6.js';
|
|
60
|
+
import '../chunk-H5U7LNTJ.js';
|
|
60
61
|
import '../chunk-3TXEJN4W.js';
|
|
61
|
-
import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-
|
|
62
|
-
import '../chunk-
|
|
62
|
+
import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-NJV5SLEK.js';
|
|
63
|
+
import '../chunk-NOA6EJXE.js';
|
|
63
64
|
import '../chunk-KTBKW2FI.js';
|
|
64
65
|
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-
|
|
66
|
+
import '../chunk-7QWQTA5S.js';
|
|
67
|
+
import { effectiveComposes, validatePreset, composeSlotDiagnostics, agentDeprecationDiagnostics, validateAgent, SLOT_ID_PATTERN } from '../chunk-6VLHITAM.js';
|
|
68
|
+
import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, resolveSettingsWithSources, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, readLock, aiResourceRoots, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-T5TSLSRO.js';
|
|
68
69
|
import '../chunk-4GY63JU6.js';
|
|
69
|
-
import { factoryAssetRoots } from '../chunk-
|
|
70
|
-
import '../chunk-PMECEZK3.js';
|
|
70
|
+
import { factoryAssetRoots } from '../chunk-SHQMPGOL.js';
|
|
71
|
+
import { deployedDir } from '../chunk-PMECEZK3.js';
|
|
71
72
|
import { DEFAULT_DRIVER_ID, DRIVER_DEFAULTS } from '../chunk-5BEFNLOR.js';
|
|
72
73
|
import { findKindDirs } from '../chunk-A2ULN3KX.js';
|
|
73
|
-
import { SourceEntryError, sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir,
|
|
74
|
+
import { SourceEntryError, resolveSkWorkspaceConfig, sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, decodeSkaileYaml, matchPin, coerceVersion, loadSkWorkspaceConfig, normalizeAgentInstances, agentInstanceDiagnostics, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-PNOGX36L.js';
|
|
74
75
|
import { globalCacheRoot, globalSkaileDir, userConfigPath } from '../chunk-L5VSIPQD.js';
|
|
75
76
|
import { SUPPORTED_DRIVER_TARGETS, driverTargetForDriver } from '../chunk-CPSIPIX7.js';
|
|
76
|
-
import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest,
|
|
77
|
+
import { SKAILE_MANIFEST_FILENAME, loadSkPublishManifest, decodeSkaileManifest, isNonAssetPath, isNonAssetDir, encodeSkaileManifest } from '../chunk-CTP3XBMF.js';
|
|
77
78
|
import { pluginTitle } from '../chunk-RVRB27AN.js';
|
|
78
|
-
import { dedupeRequirements, parseFrontmatter, scanDirectory } from '../chunk-
|
|
79
|
-
import { parseAssetRef, isValidPublisher, PUBLISHER_HINT, isValidAssetName, ASSET_NAME_HINT, slugifyAssetName, parseAssetRefLoose, assetRefToStr } from '../chunk-
|
|
79
|
+
import { dedupeRequirements, parseFrontmatter, scanDirectory, parseRequires } from '../chunk-XTVSNWLL.js';
|
|
80
|
+
import { parseAssetRef, isValidPublisher, PUBLISHER_HINT, isValidAssetName, ASSET_NAME_HINT, depToStr, slugifyAssetName, parseAssetRefLoose, assetRefToStr } from '../chunk-PNTXHTBC.js';
|
|
80
81
|
import { portableSpawn, portableSpawnSync } from '../chunk-ICSCSM5D.js';
|
|
81
|
-
import { openSqlite } from '../chunk-
|
|
82
|
+
import { openSqlite } from '../chunk-DKXNKFKP.js';
|
|
82
83
|
import { parseModelRef, resolveEntryBaseUrl } from '../chunk-MJHSLODD.js';
|
|
83
84
|
import '../chunk-C3CAXQMA.js';
|
|
84
|
-
import '../chunk-BOFL7GIF.js';
|
|
85
|
+
import { registerLogStore, LogStore, StdoutSink } from '../chunk-BOFL7GIF.js';
|
|
85
86
|
import '../chunk-NSBPE2FW.js';
|
|
86
87
|
import * as fs8 from 'fs';
|
|
87
88
|
import fs8__default, { readFileSync, existsSync, mkdirSync, writeFileSync, lstatSync, rmSync, readdirSync, statSync } from 'fs';
|
|
88
|
-
import * as
|
|
89
|
-
import
|
|
89
|
+
import * as path22 from 'path';
|
|
90
|
+
import path22__default, { resolve, join } from 'path';
|
|
90
91
|
import { fileURLToPath } from 'url';
|
|
91
92
|
import { Help, Command, Option } from 'commander';
|
|
92
93
|
import { rcompare } from 'semver';
|
|
94
|
+
import * as os from 'os';
|
|
95
|
+
import { homedir } from 'os';
|
|
93
96
|
import * as p4 from '@clack/prompts';
|
|
94
97
|
import pc5 from 'picocolors';
|
|
95
|
-
import * as os from 'os';
|
|
96
98
|
import { parse, stringify, parseDocument, isMap, isScalar, isSeq } from 'yaml';
|
|
97
99
|
import * as readline from 'readline';
|
|
98
100
|
import { createInterface } from 'readline';
|
|
@@ -128,6 +130,45 @@ function filterCatalogAssets(assets, query) {
|
|
|
128
130
|
(a) => a.name.toLowerCase().includes(q) || (a.description?.toLowerCase().includes(q) ?? false) || a.publisher.toLowerCase().includes(q)
|
|
129
131
|
);
|
|
130
132
|
}
|
|
133
|
+
var STORE_TEST_NAME_RE = /^(test|demo)(-|$)/;
|
|
134
|
+
var STORE_ROW_LIMIT = 20;
|
|
135
|
+
function selectStoreRows(matches, query, all) {
|
|
136
|
+
const q = query?.toLowerCase();
|
|
137
|
+
const rank = (a) => {
|
|
138
|
+
if (!q) return 3;
|
|
139
|
+
const n = a.name.toLowerCase();
|
|
140
|
+
if (n === q) return 0;
|
|
141
|
+
if (n.startsWith(q)) return 1;
|
|
142
|
+
if (n.includes(q)) return 2;
|
|
143
|
+
return 3;
|
|
144
|
+
};
|
|
145
|
+
const ranked = [...matches].sort(
|
|
146
|
+
(a, b) => rank(a) - rank(b) || a.name.localeCompare(b.name) || a.version.localeCompare(b.version)
|
|
147
|
+
);
|
|
148
|
+
if (all) return { shown: ranked, hidden: 0, cut: 0 };
|
|
149
|
+
const keep = ranked.filter(
|
|
150
|
+
(a) => storeNotInstallableReason(a) === void 0 && !STORE_TEST_NAME_RE.test(a.name)
|
|
151
|
+
);
|
|
152
|
+
return {
|
|
153
|
+
shown: keep.slice(0, STORE_ROW_LIMIT),
|
|
154
|
+
hidden: ranked.length - keep.length,
|
|
155
|
+
cut: Math.max(0, keep.length - STORE_ROW_LIMIT)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function storeSelectionNotes(sel, indent) {
|
|
159
|
+
const notes = [];
|
|
160
|
+
if (sel.cut > 0) {
|
|
161
|
+
notes.push(
|
|
162
|
+
`${indent}${S.dim(`\u2026 ${sel.cut} more store match(es); narrow the query, or pass --all to list every one`)}`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
if (sel.hidden > 0) {
|
|
166
|
+
notes.push(
|
|
167
|
+
`${indent}${S.dim(`${sel.hidden} store entr${sel.hidden === 1 ? "y" : "ies"} hidden: kinds \`add\` cannot install yet (${[...STORE_UNADDABLE_KINDS].join(", ")}), names that are not valid refs, test/demo entries; --all lists them`)}`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
return notes;
|
|
171
|
+
}
|
|
131
172
|
function nearAssetKind(word) {
|
|
132
173
|
const w = word.toLowerCase();
|
|
133
174
|
let best;
|
|
@@ -175,7 +216,7 @@ async function runSearch(kind, query, opts) {
|
|
|
175
216
|
const showLocal = !opts.store;
|
|
176
217
|
const showStore = !opts.local;
|
|
177
218
|
const { resolveConfig } = await import('../library/index.js');
|
|
178
|
-
const airGapped = resolveConfig({ projectDir:
|
|
219
|
+
const airGapped = resolveConfig({ projectDir: path22__default.resolve(opts.projectDir) }).catalog.cache_ttl === 0;
|
|
179
220
|
if (showLocal) {
|
|
180
221
|
await searchLocal(query, kind, opts, showStore, airGapped);
|
|
181
222
|
}
|
|
@@ -184,7 +225,7 @@ async function runSearch(kind, query, opts) {
|
|
|
184
225
|
}
|
|
185
226
|
}
|
|
186
227
|
async function searchIndex(query, kind) {
|
|
187
|
-
const { openLibrary: openLibrary2 } = await import('../open-library-
|
|
228
|
+
const { openLibrary: openLibrary2 } = await import('../open-library-N6ESO6IK.js');
|
|
188
229
|
const library = await openLibrary2();
|
|
189
230
|
try {
|
|
190
231
|
const { libraryDirMissing: libraryDirMissing2 } = await import('../library/index.js');
|
|
@@ -221,7 +262,7 @@ async function searchIndex(query, kind) {
|
|
|
221
262
|
}
|
|
222
263
|
}
|
|
223
264
|
async function searchFactory(projectDir, query, kind) {
|
|
224
|
-
const prefixes = factoryAssetRoots().map((r) => r.endsWith(
|
|
265
|
+
const prefixes = factoryAssetRoots().map((r) => r.endsWith(path22__default.sep) ? r : r + path22__default.sep);
|
|
225
266
|
const isFactoryPath = (p6) => prefixes.some((fp) => p6 === fp.slice(0, -1) || p6.startsWith(fp));
|
|
226
267
|
try {
|
|
227
268
|
const entries = await new AssetManager({ registry: getKindRegistry(), projectDir }).search(
|
|
@@ -331,11 +372,11 @@ async function expandCompetingOrigins(entries, projectDir) {
|
|
|
331
372
|
return out;
|
|
332
373
|
}
|
|
333
374
|
async function searchLocal(query, kind, opts, showStore, airGapped) {
|
|
334
|
-
const projectDir =
|
|
375
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
335
376
|
const factory = await searchFactory(projectDir, query, kind);
|
|
336
377
|
let entries = unionEntries(await searchIndex(query, kind), factory);
|
|
337
378
|
if (entries.length === 0 && !query && !kind && !airGapped) {
|
|
338
|
-
const { autoSyncForSearch } = await import('../source-
|
|
379
|
+
const { autoSyncForSearch } = await import('../source-DX5SGWEI.js');
|
|
339
380
|
if (await autoSyncForSearch(projectDir)) {
|
|
340
381
|
entries = unionEntries(await searchIndex(query, kind), factory);
|
|
341
382
|
}
|
|
@@ -455,24 +496,26 @@ async function searchStore(query, kind, opts, airGapped) {
|
|
|
455
496
|
logInfo("air-gapped (cache_ttl: 0) \u2014 local sources only");
|
|
456
497
|
return;
|
|
457
498
|
}
|
|
458
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-
|
|
499
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-N6ESO6IK.js');
|
|
459
500
|
try {
|
|
460
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
501
|
+
const remote = await openCatalogSource2({ projectDir: path22__default.resolve(opts.projectDir) });
|
|
461
502
|
const assets = await remote.listAssets(kind ? { kind } : {});
|
|
462
|
-
const
|
|
463
|
-
if (
|
|
503
|
+
const sel = selectStoreRows(filterCatalogAssets(assets, query), query, Boolean(opts.all));
|
|
504
|
+
if (sel.shown.length > 0) {
|
|
464
505
|
console.log(`
|
|
465
506
|
${S.heading("Store:")}`);
|
|
466
|
-
for (const row of formatStoreRows(
|
|
507
|
+
for (const row of formatStoreRows(sel.shown, " ")) console.log(row);
|
|
467
508
|
} else if (opts.store) {
|
|
468
509
|
logInfo("No results in store");
|
|
469
510
|
}
|
|
511
|
+
for (const note of storeSelectionNotes(sel, " ")) console.log(note);
|
|
470
512
|
} catch (e) {
|
|
471
513
|
const local = e instanceof LocalCatalogDisabledError2;
|
|
472
514
|
if (opts.store) {
|
|
473
515
|
logErr(
|
|
474
|
-
local ? "remote catalog disabled (catalog.url: local) \u2014 set catalog.url: https://skaile.store to search the store" : `Store search failed: ${e.
|
|
516
|
+
local ? "remote catalog disabled (catalog.url: local) \u2014 set catalog.url: https://skaile.store to search the store" : `Store search failed: ${await describeStoreFailure(e, path22__default.resolve(opts.projectDir))}`
|
|
475
517
|
);
|
|
518
|
+
process.exit(1);
|
|
476
519
|
} else {
|
|
477
520
|
logInfo(
|
|
478
521
|
local ? "remote catalog disabled (catalog.url: local) \u2014 showing local results only" : "store unavailable \u2014 showing local results only (run with --store to see the error)"
|
|
@@ -480,8 +523,16 @@ async function searchStore(query, kind, opts, airGapped) {
|
|
|
480
523
|
}
|
|
481
524
|
}
|
|
482
525
|
}
|
|
526
|
+
async function describeStoreFailure(err2, projectDir) {
|
|
527
|
+
const { resolveConfig, describeCatalogError } = await import('../library/index.js');
|
|
528
|
+
const url = resolveConfig({ projectDir }).catalog.url;
|
|
529
|
+
return `${describeCatalogError(err2, url)}. Check the catalog with \`skaile catalog test\`.`;
|
|
530
|
+
}
|
|
483
531
|
function makeSearchCommand() {
|
|
484
|
-
return new Command("search").description("Search across all repos").argument("[kind]", "Filter by asset kind (a single non-kind argument is the query)").argument("[query]", "Search query").option("--project-dir <path>", "Project directory", process.cwd()).option("--store", "Search only the store").option("--local", "Search only local repos").
|
|
532
|
+
return new Command("search").description("Search across all repos").argument("[kind]", "Filter by asset kind (a single non-kind argument is the query)").argument("[query]", "Search query").option("--project-dir <path>", "Project directory", process.cwd()).option("--store", "Search only the store").option("--local", "Search only local repos").option(
|
|
533
|
+
"--all",
|
|
534
|
+
`Store leg: list every match (default: ${STORE_ROW_LIMIT} rows, only what add can install)`
|
|
535
|
+
).action(async (kind, query, opts) => {
|
|
485
536
|
await runSearch(kind, query, opts);
|
|
486
537
|
});
|
|
487
538
|
}
|
|
@@ -582,7 +633,7 @@ function makeAddCommand() {
|
|
|
582
633
|
const warnings = deferredWarnings();
|
|
583
634
|
const am2 = new AssetManager({
|
|
584
635
|
registry: getKindRegistry(),
|
|
585
|
-
projectDir:
|
|
636
|
+
projectDir: path22__default.resolve(opts.projectDir),
|
|
586
637
|
global: opts.global || harnesses !== void 0,
|
|
587
638
|
harnesses,
|
|
588
639
|
driverTarget: opts.target,
|
|
@@ -644,6 +695,20 @@ function makeAddCommand() {
|
|
|
644
695
|
const library = libraryOf.get(a);
|
|
645
696
|
logOk(library ? `${a} (library ${library})` : a);
|
|
646
697
|
}
|
|
698
|
+
if (am2.global) {
|
|
699
|
+
for (const a of added) {
|
|
700
|
+
const { kind, name } = parseAssetRef(a);
|
|
701
|
+
const component = installTargetOf(getKindRegistry(), kind);
|
|
702
|
+
if (!component) continue;
|
|
703
|
+
for (const harness of am2.deployTargets()) {
|
|
704
|
+
const dir = deployedDir(component, name, harness, true);
|
|
705
|
+
if (existsSync(dir)) logInfo(S.dim(`${harness}: ${dir.replace(homedir(), "~")}`));
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
if (added.length > 1) {
|
|
710
|
+
logInfo(S.dim(`${added.length} assets deployed (${ref} and ${added.length - 1} more)`));
|
|
711
|
+
}
|
|
647
712
|
}
|
|
648
713
|
const addOrigins = await competingOriginsOf(am2, ref);
|
|
649
714
|
if (addOrigins) {
|
|
@@ -673,7 +738,7 @@ function makeRemoveCommand() {
|
|
|
673
738
|
requireProjectConfig(opts.projectDir, { allowMissing: true });
|
|
674
739
|
const am2 = new AssetManager({
|
|
675
740
|
registry: getKindRegistry(),
|
|
676
|
-
projectDir:
|
|
741
|
+
projectDir: path22__default.resolve(opts.projectDir),
|
|
677
742
|
global: opts.global || harnesses !== void 0,
|
|
678
743
|
harnesses,
|
|
679
744
|
driverTarget: opts.target
|
|
@@ -735,7 +800,7 @@ function makeListCommand() {
|
|
|
735
800
|
}
|
|
736
801
|
const am2 = new AssetManager({
|
|
737
802
|
registry: getKindRegistry(),
|
|
738
|
-
projectDir:
|
|
803
|
+
projectDir: path22__default.resolve(opts.projectDir),
|
|
739
804
|
driverTarget: opts.target
|
|
740
805
|
});
|
|
741
806
|
let declared;
|
|
@@ -783,7 +848,7 @@ function makeListCommand() {
|
|
|
783
848
|
function runGlobalList(kind, opts, harnesses) {
|
|
784
849
|
const am2 = new AssetManager({
|
|
785
850
|
registry: getKindRegistry(),
|
|
786
|
-
projectDir:
|
|
851
|
+
projectDir: path22__default.resolve(opts.projectDir),
|
|
787
852
|
global: true,
|
|
788
853
|
harnesses
|
|
789
854
|
});
|
|
@@ -856,7 +921,7 @@ async function resolveInfoEntry(am2, ref, opts) {
|
|
|
856
921
|
return { entry: match ?? deployed };
|
|
857
922
|
}
|
|
858
923
|
const lookup = opts.storeLookup ?? (async (filter) => {
|
|
859
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
924
|
+
const { resolveCatalogSource } = await import('../open-library-N6ESO6IK.js');
|
|
860
925
|
const { source, close } = await resolveCatalogSource({ projectDir: opts.projectDir });
|
|
861
926
|
try {
|
|
862
927
|
return await source.listAssets(filter);
|
|
@@ -872,7 +937,7 @@ async function resolveInfoEntry(am2, ref, opts) {
|
|
|
872
937
|
);
|
|
873
938
|
return { entry: hit ? catalogAssetToEntry(hit) : null };
|
|
874
939
|
} catch (err2) {
|
|
875
|
-
const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-
|
|
940
|
+
const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-N6ESO6IK.js');
|
|
876
941
|
const storeNote = err2 instanceof Error ? err2.message : String(err2);
|
|
877
942
|
const disabled = err2 instanceof LocalCatalogDisabledError2 || /catalog\.url/i.test(storeNote);
|
|
878
943
|
return { entry: null, storeNote, ...disabled ? { storeDisabled: true } : {} };
|
|
@@ -888,7 +953,8 @@ function infoNotFoundHint(ref, lookup) {
|
|
|
888
953
|
}
|
|
889
954
|
function makeInfoCommand() {
|
|
890
955
|
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) => {
|
|
891
|
-
const projectDir =
|
|
956
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
957
|
+
requireProjectConfig(projectDir, { allowMissing: true });
|
|
892
958
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
|
|
893
959
|
const lookup = await resolveInfoEntry(am2, ref, { projectDir });
|
|
894
960
|
const entry = lookup.entry;
|
|
@@ -937,7 +1003,7 @@ function makeCreateCommand() {
|
|
|
937
1003
|
new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...SCAFFOLD_KINDS])
|
|
938
1004
|
).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
|
|
939
1005
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
|
|
940
|
-
const destDir = opts.dir ?
|
|
1006
|
+
const destDir = opts.dir ? path22__default.resolve(opts.dir) : process.cwd();
|
|
941
1007
|
const result = am2.create(name, opts.kind, destDir);
|
|
942
1008
|
if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
|
|
943
1009
|
else {
|
|
@@ -951,7 +1017,7 @@ function makeDoctorCommand() {
|
|
|
951
1017
|
requireProjectConfig(opts.projectDir);
|
|
952
1018
|
const am2 = new AssetManager({
|
|
953
1019
|
registry: getKindRegistry(),
|
|
954
|
-
projectDir:
|
|
1020
|
+
projectDir: path22__default.resolve(opts.projectDir)
|
|
955
1021
|
});
|
|
956
1022
|
const { gaps } = await am2.projectState();
|
|
957
1023
|
if (gaps.length === 0) {
|
|
@@ -983,20 +1049,20 @@ function claudeSkillRoots() {
|
|
|
983
1049
|
const roots = [];
|
|
984
1050
|
const override = process.env.SKAILE_CLAUDE_SKILLS_DIR;
|
|
985
1051
|
if (override) roots.push(override);
|
|
986
|
-
roots.push(
|
|
1052
|
+
roots.push(path22.join(os.homedir(), ".claude", "skills"));
|
|
987
1053
|
return roots;
|
|
988
1054
|
}
|
|
989
1055
|
function resolveImportSource(nameOrPath) {
|
|
990
|
-
const asPath =
|
|
1056
|
+
const asPath = path22.resolve(nameOrPath);
|
|
991
1057
|
if (fs8.existsSync(asPath)) {
|
|
992
|
-
const dir = fs8.statSync(asPath).isDirectory() ? asPath :
|
|
993
|
-
const skillFile =
|
|
1058
|
+
const dir = fs8.statSync(asPath).isDirectory() ? asPath : path22.dirname(asPath);
|
|
1059
|
+
const skillFile = path22.join(dir, "SKILL.md");
|
|
994
1060
|
if (fs8.existsSync(skillFile)) return { dir, skillFile, via: "path" };
|
|
995
1061
|
}
|
|
996
|
-
if (!nameOrPath.includes(
|
|
1062
|
+
if (!nameOrPath.includes(path22.sep) && !nameOrPath.startsWith(".")) {
|
|
997
1063
|
for (const root of claudeSkillRoots()) {
|
|
998
|
-
const dir =
|
|
999
|
-
const skillFile =
|
|
1064
|
+
const dir = path22.join(root, nameOrPath);
|
|
1065
|
+
const skillFile = path22.join(dir, "SKILL.md");
|
|
1000
1066
|
if (fs8.existsSync(skillFile)) return { dir, skillFile, via: "claude-skills" };
|
|
1001
1067
|
}
|
|
1002
1068
|
}
|
|
@@ -1052,6 +1118,12 @@ ${body}
|
|
|
1052
1118
|
}
|
|
1053
1119
|
|
|
1054
1120
|
// cli/src/commands/asset-cmd.ts
|
|
1121
|
+
function copyFilter(root) {
|
|
1122
|
+
return (src) => {
|
|
1123
|
+
const rel = path22.relative(root, src).split(path22.sep).join("/");
|
|
1124
|
+
return rel === "" || !(isNonAssetPath(rel) || isNonAssetDir(path22.basename(src)));
|
|
1125
|
+
};
|
|
1126
|
+
}
|
|
1055
1127
|
async function resolveDefByRef(library, ref, opts) {
|
|
1056
1128
|
let parsed;
|
|
1057
1129
|
try {
|
|
@@ -1126,16 +1198,16 @@ function makeAssetCommand() {
|
|
|
1126
1198
|
exitOnManifestPublisherProblems(target.path, target.name);
|
|
1127
1199
|
const rawSkill = fs8.readFileSync(src.skillFile, "utf8");
|
|
1128
1200
|
const norm = opts.normalize ? normalizeSkillContent(rawSkill, {
|
|
1129
|
-
fallbackName:
|
|
1201
|
+
fallbackName: path22.basename(src.dir),
|
|
1130
1202
|
version: opts.version,
|
|
1131
1203
|
stage: opts.stage
|
|
1132
|
-
}) : { content: rawSkill, name:
|
|
1204
|
+
}) : { content: rawSkill, name: path22.basename(src.dir), changed: false, notes: [] };
|
|
1133
1205
|
if (!opts.normalize && !isValidAssetName(norm.name)) {
|
|
1134
1206
|
logWarn(
|
|
1135
1207
|
`Name "${norm.name}" is not canonical (kebab-case); \`skaile validate\` will reject this manifest entry. Drop --no-normalize to slugify it.`
|
|
1136
1208
|
);
|
|
1137
1209
|
}
|
|
1138
|
-
const destDir =
|
|
1210
|
+
const destDir = path22.join(target.path, norm.name);
|
|
1139
1211
|
if (fs8.existsSync(destDir)) {
|
|
1140
1212
|
logErr(`Destination already exists: ${destDir}`);
|
|
1141
1213
|
process.exit(1);
|
|
@@ -1147,8 +1219,27 @@ function makeAssetCommand() {
|
|
|
1147
1219
|
);
|
|
1148
1220
|
process.exit(1);
|
|
1149
1221
|
}
|
|
1150
|
-
|
|
1151
|
-
|
|
1222
|
+
const importedFm = parseFrontmatter(norm.content);
|
|
1223
|
+
const checked = checkAsset(
|
|
1224
|
+
"skill",
|
|
1225
|
+
importedFm.data,
|
|
1226
|
+
importedFm.body,
|
|
1227
|
+
norm.name,
|
|
1228
|
+
getKindRegistry(),
|
|
1229
|
+
norm.content
|
|
1230
|
+
);
|
|
1231
|
+
if (checked.errors.length > 0) {
|
|
1232
|
+
for (const f of checked.errors) logErr(`${norm.name}/SKILL.md [${f.tag}] \u2014 ${f.text}`);
|
|
1233
|
+
logErr(
|
|
1234
|
+
`Not imported: ${checked.errors.length} problem(s) in SKILL.md. Fix them in ${src.skillFile} (or drop --no-normalize) and run the import again.`
|
|
1235
|
+
);
|
|
1236
|
+
process.exit(1);
|
|
1237
|
+
}
|
|
1238
|
+
for (const f of checked.advisories) {
|
|
1239
|
+
logWarn(`${norm.name}/SKILL.md [${f.tag}] \u2014 ${f.text}`);
|
|
1240
|
+
}
|
|
1241
|
+
fs8.cpSync(src.dir, destDir, { recursive: true, filter: copyFilter(src.dir) });
|
|
1242
|
+
fs8.writeFileSync(path22.join(destDir, "SKILL.md"), norm.content, "utf8");
|
|
1152
1243
|
for (const note of norm.notes) logInfo(` \u2022 ${note}`);
|
|
1153
1244
|
const fm = parseFrontmatter(norm.content).data;
|
|
1154
1245
|
for (const f of checkAgentSkillConformance(fm, { dirName: norm.name })) {
|
|
@@ -1214,23 +1305,23 @@ function makeAssetCommand() {
|
|
|
1214
1305
|
);
|
|
1215
1306
|
process.exit(1);
|
|
1216
1307
|
}
|
|
1217
|
-
const basename3 =
|
|
1308
|
+
const basename3 = path22.basename(srcPath);
|
|
1218
1309
|
const destDir = target.path;
|
|
1219
1310
|
fs8.mkdirSync(destDir, { recursive: true });
|
|
1220
|
-
const destPath =
|
|
1311
|
+
const destPath = path22.join(destDir, basename3);
|
|
1221
1312
|
if (fs8.existsSync(destPath)) {
|
|
1222
1313
|
logErr(`Destination already exists: ${destPath}`);
|
|
1223
1314
|
process.exit(1);
|
|
1224
1315
|
}
|
|
1225
1316
|
switch (opts.mode) {
|
|
1226
1317
|
case "copy":
|
|
1227
|
-
fs8.cpSync(srcPath, destPath, { recursive: true });
|
|
1318
|
+
fs8.cpSync(srcPath, destPath, { recursive: true, filter: copyFilter(srcPath) });
|
|
1228
1319
|
break;
|
|
1229
1320
|
case "move":
|
|
1230
1321
|
fs8.renameSync(srcPath, destPath);
|
|
1231
1322
|
break;
|
|
1232
1323
|
case "link":
|
|
1233
|
-
fs8.symlinkSync(
|
|
1324
|
+
fs8.symlinkSync(path22.resolve(srcPath), destPath);
|
|
1234
1325
|
break;
|
|
1235
1326
|
}
|
|
1236
1327
|
if (target.backend === "git" && opts.commit) {
|
|
@@ -1245,6 +1336,11 @@ function makeAssetCommand() {
|
|
|
1245
1336
|
}
|
|
1246
1337
|
}
|
|
1247
1338
|
logOk(`Migrated ${basename3} \u2192 ${target.name} (${opts.mode})`);
|
|
1339
|
+
const publisher = loadSkPublishManifest(target.path)?.publisher ?? "<publisher>";
|
|
1340
|
+
const migratedKind = fs8.existsSync(path22.join(destPath, "SKILL.md")) ? "skill" : "<kind>";
|
|
1341
|
+
logInfo(
|
|
1342
|
+
`Not addable yet: run ${S.cmd(`skaile library index ${target.name}`)}, then ${S.cmd(`skaile add ${migratedKind}:@${publisher.replace(/^@/, "")}/${basename3}`)}`
|
|
1343
|
+
);
|
|
1248
1344
|
if (opts.mode === "move") {
|
|
1249
1345
|
logInfo("Source moved into the library \u2014 future edits modify the library copy.");
|
|
1250
1346
|
} else if (opts.mode === "copy") {
|
|
@@ -1360,14 +1456,14 @@ function makeAuthCommand() {
|
|
|
1360
1456
|
}
|
|
1361
1457
|
function collectCacheTargets(scope) {
|
|
1362
1458
|
const out = [];
|
|
1363
|
-
out.push(
|
|
1364
|
-
out.push(
|
|
1365
|
-
out.push(
|
|
1459
|
+
out.push(path22__default.join(scope.projectDir, ".skaile", "cache"));
|
|
1460
|
+
out.push(path22__default.join(scope.projectDir, ".skaile", "store-cache"));
|
|
1461
|
+
out.push(path22__default.join(scope.projectDir, ".skaile", "repos"));
|
|
1366
1462
|
if (scope.global) {
|
|
1367
1463
|
out.push(globalCacheRoot());
|
|
1368
1464
|
const home = globalSkaileDir();
|
|
1369
|
-
out.push(
|
|
1370
|
-
out.push(
|
|
1465
|
+
out.push(path22__default.join(home, "repos"));
|
|
1466
|
+
out.push(path22__default.join(home, "catalog-cache"));
|
|
1371
1467
|
}
|
|
1372
1468
|
return out;
|
|
1373
1469
|
}
|
|
@@ -1381,7 +1477,7 @@ function dirSize(target) {
|
|
|
1381
1477
|
function dirSizeOfDir(dir) {
|
|
1382
1478
|
let total = 0;
|
|
1383
1479
|
for (const ent of readdirSync(dir, { withFileTypes: true })) {
|
|
1384
|
-
const child =
|
|
1480
|
+
const child = path22__default.join(dir, ent.name);
|
|
1385
1481
|
if (ent.isSymbolicLink()) continue;
|
|
1386
1482
|
if (ent.isDirectory()) total += dirSizeOfDir(child);
|
|
1387
1483
|
else if (ent.isFile()) total += statSync(child).size;
|
|
@@ -1407,7 +1503,7 @@ function makeCacheCommand() {
|
|
|
1407
1503
|
const cmd = new Command("cache").description("Inspect and reclaim the re-derivable cache");
|
|
1408
1504
|
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) => {
|
|
1409
1505
|
const targets = collectCacheTargets({
|
|
1410
|
-
projectDir:
|
|
1506
|
+
projectDir: path22__default.resolve(opts.projectDir),
|
|
1411
1507
|
global: opts.global
|
|
1412
1508
|
}).filter((t) => existsSync(t));
|
|
1413
1509
|
if (targets.length === 0) {
|
|
@@ -1437,12 +1533,12 @@ function makeCacheCommand() {
|
|
|
1437
1533
|
for (const r of removed) logOk(`Removed ${r}`);
|
|
1438
1534
|
});
|
|
1439
1535
|
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) => {
|
|
1440
|
-
console.log(
|
|
1536
|
+
console.log(path22__default.join(path22__default.resolve(opts.projectDir), ".skaile", "cache"));
|
|
1441
1537
|
if (opts.global) console.log(globalCacheRoot());
|
|
1442
1538
|
});
|
|
1443
1539
|
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) => {
|
|
1444
1540
|
const targets = collectCacheTargets({
|
|
1445
|
-
projectDir:
|
|
1541
|
+
projectDir: path22__default.resolve(opts.projectDir),
|
|
1446
1542
|
global: opts.global
|
|
1447
1543
|
});
|
|
1448
1544
|
console.log();
|
|
@@ -1458,7 +1554,7 @@ function makeCatalogCommand() {
|
|
|
1458
1554
|
const catalog = new Command("catalog").description("Catalog source health and configuration");
|
|
1459
1555
|
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) => {
|
|
1460
1556
|
const { resolveConfig, isLocalCatalogUrl, trpcGetUrl } = await import('../library/index.js');
|
|
1461
|
-
const projectDir = opts.projectDir ?
|
|
1557
|
+
const projectDir = opts.projectDir ? path22__default.resolve(opts.projectDir) : void 0;
|
|
1462
1558
|
const cfg = resolveConfig({ projectDir });
|
|
1463
1559
|
const baseUrl = opts.url ?? cfg.catalog.url;
|
|
1464
1560
|
if (isLocalCatalogUrl(baseUrl)) {
|
|
@@ -1476,7 +1572,7 @@ function makeCatalogCommand() {
|
|
|
1476
1572
|
});
|
|
1477
1573
|
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) => {
|
|
1478
1574
|
const { resolveConfig } = await import('../library/index.js');
|
|
1479
|
-
const projectDir = opts.projectDir ?
|
|
1575
|
+
const projectDir = opts.projectDir ? path22__default.resolve(opts.projectDir) : void 0;
|
|
1480
1576
|
const cfg = resolveConfig({ projectDir });
|
|
1481
1577
|
console.log(`url: ${cfg.catalog.url}`);
|
|
1482
1578
|
console.log(`framing: ${cfg.catalog.framing}`);
|
|
@@ -1485,7 +1581,7 @@ function makeCatalogCommand() {
|
|
|
1485
1581
|
return catalog;
|
|
1486
1582
|
}
|
|
1487
1583
|
async function runLocalCatalogTest(projectDir) {
|
|
1488
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
1584
|
+
const { resolveCatalogSource } = await import('../open-library-N6ESO6IK.js');
|
|
1489
1585
|
let resolved;
|
|
1490
1586
|
try {
|
|
1491
1587
|
resolved = await resolveCatalogSource({ projectDir });
|
|
@@ -1628,7 +1724,7 @@ async function scanLibraryFlowEntries() {
|
|
|
1628
1724
|
const { LocalIndex, resolveIndexPath, scanAuthoringLibraries } = await import('../library/index.js');
|
|
1629
1725
|
const indexPath = resolveIndexPath();
|
|
1630
1726
|
if (!existsSync(indexPath)) return entries;
|
|
1631
|
-
const { getKindRegistry: getKindRegistry2 } = await import('../open-registry-
|
|
1727
|
+
const { getKindRegistry: getKindRegistry2 } = await import('../open-registry-CBZ5MWTT.js');
|
|
1632
1728
|
const index = new LocalIndex({ indexPath });
|
|
1633
1729
|
try {
|
|
1634
1730
|
for (const { assets } of await scanAuthoringLibraries(index, getKindRegistry2())) {
|
|
@@ -1679,9 +1775,9 @@ function findSkills() {
|
|
|
1679
1775
|
}
|
|
1680
1776
|
function walkSkills(dir, out) {
|
|
1681
1777
|
for (const entry of fs8__default.readdirSync(dir, { withFileTypes: true })) {
|
|
1682
|
-
const full =
|
|
1778
|
+
const full = path22__default.join(dir, entry.name);
|
|
1683
1779
|
if (entry.isDirectory()) {
|
|
1684
|
-
const skillMd =
|
|
1780
|
+
const skillMd = path22__default.join(full, "SKILL.md");
|
|
1685
1781
|
if (fs8__default.existsSync(skillMd)) {
|
|
1686
1782
|
out.push({ name: entry.name, path: full, skillPath: skillMd });
|
|
1687
1783
|
} else {
|
|
@@ -1703,7 +1799,7 @@ function resolveFlowIds() {
|
|
|
1703
1799
|
}
|
|
1704
1800
|
}
|
|
1705
1801
|
function resolveSessionIds(projectDir) {
|
|
1706
|
-
const sessionsDir =
|
|
1802
|
+
const sessionsDir = path22__default.join(projectDir, ".skaile", "sessions");
|
|
1707
1803
|
if (!fs8__default.existsSync(sessionsDir)) return [];
|
|
1708
1804
|
try {
|
|
1709
1805
|
return fs8__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
@@ -1759,6 +1855,33 @@ function resolveDynamic(words, cword) {
|
|
|
1759
1855
|
return null;
|
|
1760
1856
|
}
|
|
1761
1857
|
var PERSONAL_KEYS = /* @__PURE__ */ new Set(["driver", "model"]);
|
|
1858
|
+
var CATALOG_KEYS = /* @__PURE__ */ new Set(["catalog.url", "catalog.cache_ttl", "catalog.framing"]);
|
|
1859
|
+
async function setCatalogKey(key, raw) {
|
|
1860
|
+
const { CatalogConfigSchema, saveConfig } = await import('../library/index.js');
|
|
1861
|
+
const { parse: parseYaml5 } = await import('yaml');
|
|
1862
|
+
const field = key.slice("catalog.".length);
|
|
1863
|
+
const value = field === "cache_ttl" ? /^\d+$/.test(raw.trim()) ? Number(raw) : raw : raw;
|
|
1864
|
+
const checked = CatalogConfigSchema.safeParse({ [field]: value });
|
|
1865
|
+
if (!checked.success) {
|
|
1866
|
+
const hint = field === "url" ? 'a http(s) URL, or "local" to turn the remote catalog off' : field === "cache_ttl" ? "a whole number of seconds (0 = air-gapped)" : '"trpc" or "rest"';
|
|
1867
|
+
logErr(`'${key}' must be ${hint}; got "${raw}".`);
|
|
1868
|
+
process.exit(1);
|
|
1869
|
+
}
|
|
1870
|
+
const filePath = userConfigPath();
|
|
1871
|
+
const fs13 = await import('fs');
|
|
1872
|
+
let existing = {};
|
|
1873
|
+
if (fs13.existsSync(filePath)) {
|
|
1874
|
+
const parsed = parseYaml5(fs13.readFileSync(filePath, "utf-8"));
|
|
1875
|
+
if (parsed && typeof parsed === "object") existing = parsed;
|
|
1876
|
+
}
|
|
1877
|
+
const catalog = {
|
|
1878
|
+
...existing.catalog ?? {},
|
|
1879
|
+
[field]: checked.data[field]
|
|
1880
|
+
};
|
|
1881
|
+
saveConfig(filePath, { ...existing, catalog });
|
|
1882
|
+
logOk(`Set ${pc5.bold(key)} = ${String(checked.data[field])}`);
|
|
1883
|
+
console.log(S.dim(` \u2192 ${filePath}`));
|
|
1884
|
+
}
|
|
1762
1885
|
var API_KEY_PREFIX = "apiKey.";
|
|
1763
1886
|
function collectWorkspaceDefaults(projectDir) {
|
|
1764
1887
|
const wsDefaults = {};
|
|
@@ -1774,14 +1897,17 @@ function collectWorkspaceDefaults(projectDir) {
|
|
|
1774
1897
|
}
|
|
1775
1898
|
return wsDefaults;
|
|
1776
1899
|
}
|
|
1777
|
-
function printEffectiveSection(config) {
|
|
1900
|
+
function printEffectiveSection(config, sources) {
|
|
1778
1901
|
console.log();
|
|
1779
1902
|
console.log(S.heading(" Effective Config"));
|
|
1780
1903
|
console.log(` ${S.rule(40)}`);
|
|
1781
1904
|
for (const key of ["driver", "model"]) {
|
|
1782
1905
|
const value = config[key];
|
|
1783
1906
|
if (value !== void 0) {
|
|
1784
|
-
|
|
1907
|
+
const origin = sources[key];
|
|
1908
|
+
console.log(
|
|
1909
|
+
` ${S.label(`${key}:`.padEnd(16))} ${value}${origin ? ` ${S.dim(`(${origin})`)}` : ""}`
|
|
1910
|
+
);
|
|
1785
1911
|
}
|
|
1786
1912
|
}
|
|
1787
1913
|
}
|
|
@@ -1845,17 +1971,18 @@ function printResolvedPathsSection(config) {
|
|
|
1845
1971
|
console.log(` ${S.label("prompts:".padEnd(16))} ${config.promptsDir ?? paths.promptsDir}`);
|
|
1846
1972
|
}
|
|
1847
1973
|
async function showConfig(opts) {
|
|
1848
|
-
const projectDir = opts.projectDir ?
|
|
1974
|
+
const projectDir = opts.projectDir ? path22__default.resolve(opts.projectDir) : process.cwd();
|
|
1849
1975
|
let config;
|
|
1976
|
+
let sources;
|
|
1850
1977
|
let wsDefaults;
|
|
1851
1978
|
try {
|
|
1852
|
-
config = await
|
|
1979
|
+
({ settings: config, sources } = await resolveSettingsWithSources(projectDir));
|
|
1853
1980
|
wsDefaults = collectWorkspaceDefaults(projectDir);
|
|
1854
1981
|
} catch (error) {
|
|
1855
1982
|
logErr(error instanceof Error ? error.message : String(error));
|
|
1856
1983
|
process.exit(1);
|
|
1857
1984
|
}
|
|
1858
|
-
printEffectiveSection(config);
|
|
1985
|
+
printEffectiveSection(config, sources);
|
|
1859
1986
|
printWorkspaceDefaultsSection(wsDefaults);
|
|
1860
1987
|
printModelSelectionSection(config, projectDir);
|
|
1861
1988
|
printResolvedPathsSection(config);
|
|
@@ -1890,13 +2017,25 @@ function makeConfigCommand() {
|
|
|
1890
2017
|
const cmd = new Command("config").description("Manage personal config (.skaile/settings.json)");
|
|
1891
2018
|
cmd.command("show").description("Show effective config with sources").option("--project-dir <path>", "Project directory").action((opts) => showConfig(opts));
|
|
1892
2019
|
cmd.command("get <key>").description("Get an effective config value").option("--project-dir <path>", "Project directory").action(async (key, opts) => {
|
|
1893
|
-
const projectDir = opts.projectDir ?
|
|
2020
|
+
const projectDir = opts.projectDir ? path22__default.resolve(opts.projectDir) : process.cwd();
|
|
2021
|
+
if (CATALOG_KEYS.has(key)) {
|
|
2022
|
+
const { resolveConfig } = await import('../library/index.js');
|
|
2023
|
+
const field = key.slice("catalog.".length);
|
|
2024
|
+
console.log(resolveConfig({ projectDir }).catalog[field]);
|
|
2025
|
+
return;
|
|
2026
|
+
}
|
|
1894
2027
|
const config = await resolveSettings(projectDir);
|
|
1895
2028
|
const value = config[key];
|
|
1896
2029
|
console.log(value ?? S.dim("(not set)"));
|
|
1897
2030
|
});
|
|
1898
|
-
cmd.command("set <key> <value>").description(
|
|
1899
|
-
|
|
2031
|
+
cmd.command("set <key> <value>").description(
|
|
2032
|
+
"Set a personal config value (driver, model, apiKey.<provider>) or a catalog setting (catalog.url, catalog.cache_ttl, catalog.framing)"
|
|
2033
|
+
).option("--project-dir <path>", "Project directory").option("--global", "Write to ~/.skaile/settings.json instead of project-local").action(async (key, value, opts) => {
|
|
2034
|
+
const projectDir = opts.projectDir ? path22__default.resolve(opts.projectDir) : process.cwd();
|
|
2035
|
+
if (CATALOG_KEYS.has(key)) {
|
|
2036
|
+
await setCatalogKey(key, value);
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
1900
2039
|
if (key === "provider" || key === "cloud" || key === "cloudConfig") {
|
|
1901
2040
|
logErr(
|
|
1902
2041
|
`'${key}' is no longer a setting \u2014 an endpoint is an AI provider registry entry and a session selects one with a model reference.
|
|
@@ -1923,6 +2062,14 @@ function makeConfigCommand() {
|
|
|
1923
2062
|
await saveSettings({ ...existing, [key]: value }, filePath);
|
|
1924
2063
|
logOk(`Set ${pc5.bold(key)} = ${value}`);
|
|
1925
2064
|
console.log(S.dim(` \u2192 ${filePath}`));
|
|
2065
|
+
if (key === "driver") {
|
|
2066
|
+
const projectDriver = resolveSkWorkspaceConfig(projectDir).agent_config?.default?.driver;
|
|
2067
|
+
if (projectDriver && projectDriver !== value) {
|
|
2068
|
+
logWarn(
|
|
2069
|
+
`skaile.yaml sets driver ${projectDriver}; a personal driver does not override the project harness. Change agent-config.default.driver in skaile.yaml to move the project.`
|
|
2070
|
+
);
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
1926
2073
|
if (key === "model") {
|
|
1927
2074
|
const view = loadRegistryView({ projectDir });
|
|
1928
2075
|
const resolved = parseModelRef(value, view.merged);
|
|
@@ -2236,8 +2383,8 @@ function makeConnectorCommand() {
|
|
|
2236
2383
|
async (driver, opts) => {
|
|
2237
2384
|
const { installNpmPackages } = await import('../connectors/index.js');
|
|
2238
2385
|
const { scanDirectory: scanDirectory2, factoryAssetRoots: factoryAssetRoots2, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
2239
|
-
const projectDir =
|
|
2240
|
-
const yamlPath =
|
|
2386
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2387
|
+
const yamlPath = path22__default.join(projectDir, "skaile.yaml");
|
|
2241
2388
|
if (!existsSync(yamlPath)) {
|
|
2242
2389
|
logErr("No skaile.yaml found in current directory. Run 'skaile init' first.");
|
|
2243
2390
|
process.exit(1);
|
|
@@ -2297,8 +2444,8 @@ ${installResult.output}`);
|
|
|
2297
2444
|
);
|
|
2298
2445
|
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) => {
|
|
2299
2446
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
2300
|
-
const projectDir =
|
|
2301
|
-
const yamlPath =
|
|
2447
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2448
|
+
const yamlPath = path22__default.join(projectDir, "skaile.yaml");
|
|
2302
2449
|
if (!existsSync(yamlPath)) {
|
|
2303
2450
|
logErr("No skaile.yaml found in current directory.");
|
|
2304
2451
|
process.exit(1);
|
|
@@ -2315,7 +2462,7 @@ ${installResult.output}`);
|
|
|
2315
2462
|
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) => {
|
|
2316
2463
|
const res = await import('../connectors/index.js');
|
|
2317
2464
|
res.registerBuiltinConnectors();
|
|
2318
|
-
const projectDir =
|
|
2465
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2319
2466
|
const declarations = res.loadConnectorDeclarations(projectDir);
|
|
2320
2467
|
if (declarations.length === 0) {
|
|
2321
2468
|
console.log("No connectors configured in skaile.yaml.");
|
|
@@ -2339,7 +2486,7 @@ ${installResult.output}`);
|
|
|
2339
2486
|
await manager.disconnectAll();
|
|
2340
2487
|
});
|
|
2341
2488
|
cmd.command("list").description("List all configured connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
2342
|
-
const projectDir =
|
|
2489
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2343
2490
|
const manager = await connectConnectors(projectDir);
|
|
2344
2491
|
try {
|
|
2345
2492
|
console.log(JSON.stringify(manager.listConnectors(), null, 2));
|
|
@@ -2348,7 +2495,7 @@ ${installResult.output}`);
|
|
|
2348
2495
|
}
|
|
2349
2496
|
});
|
|
2350
2497
|
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) => {
|
|
2351
|
-
const projectDir =
|
|
2498
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2352
2499
|
const manager = await connectConnectors(projectDir);
|
|
2353
2500
|
try {
|
|
2354
2501
|
if (opts.all) {
|
|
@@ -2372,7 +2519,7 @@ ${installResult.output}`);
|
|
|
2372
2519
|
}
|
|
2373
2520
|
});
|
|
2374
2521
|
cmd.command("ops <id>").description("List available operations for a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
|
|
2375
|
-
const projectDir =
|
|
2522
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2376
2523
|
const manager = await connectConnectors(projectDir);
|
|
2377
2524
|
try {
|
|
2378
2525
|
if (!manager.has(id)) {
|
|
@@ -2387,7 +2534,7 @@ ${installResult.output}`);
|
|
|
2387
2534
|
}
|
|
2388
2535
|
});
|
|
2389
2536
|
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) => {
|
|
2390
|
-
const projectDir =
|
|
2537
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2391
2538
|
const manager = await connectConnectors(projectDir);
|
|
2392
2539
|
try {
|
|
2393
2540
|
const content = await manager.read(id, resourcePath);
|
|
@@ -2397,7 +2544,7 @@ ${installResult.output}`);
|
|
|
2397
2544
|
}
|
|
2398
2545
|
});
|
|
2399
2546
|
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) => {
|
|
2400
|
-
const projectDir =
|
|
2547
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2401
2548
|
const manager = await connectConnectors(projectDir);
|
|
2402
2549
|
try {
|
|
2403
2550
|
await manager.write(id, resourcePath, { data: content });
|
|
@@ -2407,7 +2554,7 @@ ${installResult.output}`);
|
|
|
2407
2554
|
}
|
|
2408
2555
|
});
|
|
2409
2556
|
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) => {
|
|
2410
|
-
const projectDir =
|
|
2557
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2411
2558
|
const manager = await connectConnectors(projectDir);
|
|
2412
2559
|
try {
|
|
2413
2560
|
const entries = await manager.list(id, resourcePath, {
|
|
@@ -2420,7 +2567,7 @@ ${installResult.output}`);
|
|
|
2420
2567
|
}
|
|
2421
2568
|
});
|
|
2422
2569
|
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) => {
|
|
2423
|
-
const projectDir =
|
|
2570
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2424
2571
|
const manager = await connectConnectors(projectDir);
|
|
2425
2572
|
try {
|
|
2426
2573
|
const results = await manager.search(id, query);
|
|
@@ -2430,7 +2577,7 @@ ${installResult.output}`);
|
|
|
2430
2577
|
}
|
|
2431
2578
|
});
|
|
2432
2579
|
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) => {
|
|
2433
|
-
const projectDir =
|
|
2580
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2434
2581
|
const manager = await connectConnectors(projectDir);
|
|
2435
2582
|
try {
|
|
2436
2583
|
const ok = await manager.delete(id, resourcePath);
|
|
@@ -2440,7 +2587,7 @@ ${installResult.output}`);
|
|
|
2440
2587
|
}
|
|
2441
2588
|
});
|
|
2442
2589
|
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) => {
|
|
2443
|
-
const projectDir =
|
|
2590
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2444
2591
|
const manager = await connectConnectors(projectDir);
|
|
2445
2592
|
try {
|
|
2446
2593
|
if (!manager.has(id)) {
|
|
@@ -2549,7 +2696,7 @@ function envRecord() {
|
|
|
2549
2696
|
async function buildDeployContext(projectDir) {
|
|
2550
2697
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2551
2698
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
2552
|
-
const workspaceId = config.name ??
|
|
2699
|
+
const workspaceId = config.name ?? path22__default.basename(projectDir);
|
|
2553
2700
|
let log;
|
|
2554
2701
|
try {
|
|
2555
2702
|
const { createLogger } = await import('../core/logging.js');
|
|
@@ -2581,13 +2728,13 @@ async function ensureTargetsRegistered(projectDir) {
|
|
|
2581
2728
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2582
2729
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
2583
2730
|
if (config.plugins && config.plugins.length > 0) {
|
|
2584
|
-
const { ensurePluginsLoaded } = await import('../plugin-store-
|
|
2731
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-XMZSPVBF.js');
|
|
2585
2732
|
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
2586
2733
|
for (const f of result.failed) logWarn(f.error);
|
|
2587
2734
|
}
|
|
2588
2735
|
}
|
|
2589
2736
|
async function runUp(opts) {
|
|
2590
|
-
const projectDir =
|
|
2737
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2591
2738
|
await ensureTargetsRegistered(projectDir);
|
|
2592
2739
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2593
2740
|
const { resolveDeployTarget, pluginRegistry } = await import('../plugin-registry/index.js');
|
|
@@ -2655,7 +2802,7 @@ async function restoreFromHandle(projectDir) {
|
|
|
2655
2802
|
return { target, handle, ctx };
|
|
2656
2803
|
}
|
|
2657
2804
|
async function runDown(opts) {
|
|
2658
|
-
const projectDir =
|
|
2805
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2659
2806
|
const restored = await restoreFromHandle(projectDir);
|
|
2660
2807
|
if (!restored) return;
|
|
2661
2808
|
await restored.handle.stop();
|
|
@@ -2664,7 +2811,7 @@ async function runDown(opts) {
|
|
|
2664
2811
|
logOk(`Stopped ${S.cmd(restored.target.id)} and cleared the handle.`);
|
|
2665
2812
|
}
|
|
2666
2813
|
async function runStatus(opts) {
|
|
2667
|
-
const projectDir =
|
|
2814
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2668
2815
|
const restored = await restoreFromHandle(projectDir);
|
|
2669
2816
|
if (!restored) return;
|
|
2670
2817
|
const health = await restored.handle.health();
|
|
@@ -2678,7 +2825,7 @@ async function runStatus(opts) {
|
|
|
2678
2825
|
console.log();
|
|
2679
2826
|
}
|
|
2680
2827
|
async function runLogs(opts) {
|
|
2681
|
-
const projectDir =
|
|
2828
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
2682
2829
|
const restored = await restoreFromHandle(projectDir);
|
|
2683
2830
|
if (!restored) return;
|
|
2684
2831
|
if (!restored.handle.logs) {
|
|
@@ -2706,10 +2853,26 @@ function makeDiffCommand() {
|
|
|
2706
2853
|
requireProjectConfig(opts.projectDir);
|
|
2707
2854
|
const am2 = new AssetManager({
|
|
2708
2855
|
registry: getKindRegistry(),
|
|
2709
|
-
projectDir:
|
|
2856
|
+
projectDir: path22__default.resolve(opts.projectDir)
|
|
2710
2857
|
});
|
|
2858
|
+
try {
|
|
2859
|
+
parseAssetRef(ref);
|
|
2860
|
+
} catch (err2) {
|
|
2861
|
+
const plain = (err2 instanceof Error ? err2.message : String(err2)).replace(
|
|
2862
|
+
/ Run the `migrate-skaile-manifest`.*$/,
|
|
2863
|
+
""
|
|
2864
|
+
);
|
|
2865
|
+
const bare = /^([^:@/]+):([^@/#]+)$/.exec(ref.trim());
|
|
2866
|
+
const held = plain.startsWith("publisher required") && bare ? am2.lockedRefsNamed(bare[1], bare[2]) : [];
|
|
2867
|
+
if (held.length !== 1) {
|
|
2868
|
+
logErr(held.length > 1 ? `${plain} (locked: ${held.join(", ")})` : plain);
|
|
2869
|
+
process.exitCode = 1;
|
|
2870
|
+
return;
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2711
2873
|
const gaps = await am2.gapsOf(ref);
|
|
2712
|
-
const
|
|
2874
|
+
const requirementGaps = await am2.requirementGapsOf(ref);
|
|
2875
|
+
const blocking = [...gaps.filter((g) => !DIFF_SHOWS[g.type]), ...requirementGaps];
|
|
2713
2876
|
if (blocking.length > 0) {
|
|
2714
2877
|
for (const g of blocking) logErr(g.message);
|
|
2715
2878
|
process.exitCode = 1;
|
|
@@ -2724,7 +2887,12 @@ function makeDiffCommand() {
|
|
|
2724
2887
|
if (problems.length === 0) logErr(`Asset not found: ${ref}`);
|
|
2725
2888
|
break;
|
|
2726
2889
|
case "not-deployed":
|
|
2727
|
-
if (problems.length === 0)
|
|
2890
|
+
if (problems.length === 0) {
|
|
2891
|
+
logErr(
|
|
2892
|
+
`${ref} is not deployed \u2014 nothing in this project locks it; run skaile add ${ref}`
|
|
2893
|
+
);
|
|
2894
|
+
process.exitCode = 1;
|
|
2895
|
+
}
|
|
2728
2896
|
break;
|
|
2729
2897
|
case "no-files":
|
|
2730
2898
|
if (problems.length === 0)
|
|
@@ -2744,7 +2912,7 @@ function makeDiffCommand() {
|
|
|
2744
2912
|
function makeFlowCommand() {
|
|
2745
2913
|
const cmd = new Command("flow").description("Manage flows");
|
|
2746
2914
|
cmd.command("list").description("List available flows").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
2747
|
-
const flows = await discoverFlowsWithLibraries(
|
|
2915
|
+
const flows = await discoverFlowsWithLibraries(path22__default.resolve(opts.projectDir));
|
|
2748
2916
|
if (flows.length === 0) {
|
|
2749
2917
|
logInfo("No flows found.");
|
|
2750
2918
|
return;
|
|
@@ -2759,7 +2927,7 @@ function makeFlowCommand() {
|
|
|
2759
2927
|
console.log();
|
|
2760
2928
|
});
|
|
2761
2929
|
cmd.command("show <id>").description("Show flow details and node graph").option("--project-dir <path>", "Project directory", process.cwd()).action(async (id, opts) => {
|
|
2762
|
-
const flows = await discoverFlowsWithLibraries(
|
|
2930
|
+
const flows = await discoverFlowsWithLibraries(path22__default.resolve(opts.projectDir));
|
|
2763
2931
|
const flow = flows.find((f) => f.id === id);
|
|
2764
2932
|
if (!flow) {
|
|
2765
2933
|
logErr(`Flow not found: ${id}`);
|
|
@@ -2793,7 +2961,7 @@ function makeHistoryCommand() {
|
|
|
2793
2961
|
cmd.argument("[limit]", "Number of entries to show", "20").option("--project-dir <path>", "Project directory", process.cwd()).action((limitStr, opts) => {
|
|
2794
2962
|
const am2 = new AssetManager({
|
|
2795
2963
|
registry: getKindRegistry(),
|
|
2796
|
-
projectDir:
|
|
2964
|
+
projectDir: path22__default.resolve(opts.projectDir)
|
|
2797
2965
|
});
|
|
2798
2966
|
const limit = parseInt(limitStr, 10) || 20;
|
|
2799
2967
|
const entries = am2.history(limit);
|
|
@@ -2816,7 +2984,7 @@ function makeHistoryCommand() {
|
|
|
2816
2984
|
cmd.command("clear").description("Clear action history").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
2817
2985
|
const am2 = new AssetManager({
|
|
2818
2986
|
registry: getKindRegistry(),
|
|
2819
|
-
projectDir:
|
|
2987
|
+
projectDir: path22__default.resolve(opts.projectDir)
|
|
2820
2988
|
});
|
|
2821
2989
|
am2.clearHistory();
|
|
2822
2990
|
logOk("History cleared.");
|
|
@@ -2829,8 +2997,24 @@ var MCP_SERVER_ENTRY = {
|
|
|
2829
2997
|
args: ["mcp-server"],
|
|
2830
2998
|
env: {}
|
|
2831
2999
|
};
|
|
3000
|
+
function mcpFilePath(projectDir) {
|
|
3001
|
+
return path22__default.join(projectDir, ".mcp.json");
|
|
3002
|
+
}
|
|
3003
|
+
function legacyMcpFilePath(projectDir) {
|
|
3004
|
+
return path22__default.join(projectDir, ".claude", "mcp.json");
|
|
3005
|
+
}
|
|
3006
|
+
async function removeSkaileMcpEntry(mcpPath) {
|
|
3007
|
+
const mcp = await readJsonStrict(mcpPath);
|
|
3008
|
+
if (!mcp?.mcpServers || !(SKAILE_MCP_NAME in mcp.mcpServers)) return false;
|
|
3009
|
+
const { [SKAILE_MCP_NAME]: _removed, ...rest } = mcp.mcpServers;
|
|
3010
|
+
const updated = { ...mcp, mcpServers: rest };
|
|
3011
|
+
if (Object.keys(rest).length === 0) delete updated.mcpServers;
|
|
3012
|
+
if (Object.keys(updated).length === 0) await fs5.unlink(mcpPath);
|
|
3013
|
+
else await writeJson(mcpPath, updated);
|
|
3014
|
+
return true;
|
|
3015
|
+
}
|
|
2832
3016
|
function pluginDir(projectDir) {
|
|
2833
|
-
return
|
|
3017
|
+
return path22__default.join(projectDir, ".claude", "plugins", "skaile");
|
|
2834
3018
|
}
|
|
2835
3019
|
async function readJsonStrict(p6) {
|
|
2836
3020
|
let raw;
|
|
@@ -2848,7 +3032,7 @@ async function readJsonStrict(p6) {
|
|
|
2848
3032
|
}
|
|
2849
3033
|
}
|
|
2850
3034
|
async function writeJson(p6, value) {
|
|
2851
|
-
await fs5.mkdir(
|
|
3035
|
+
await fs5.mkdir(path22__default.dirname(p6), { recursive: true });
|
|
2852
3036
|
await fs5.writeFile(p6, `${JSON.stringify(value, null, 2)}
|
|
2853
3037
|
`);
|
|
2854
3038
|
}
|
|
@@ -2856,8 +3040,8 @@ async function copyDir(src, dest) {
|
|
|
2856
3040
|
await fs5.mkdir(dest, { recursive: true });
|
|
2857
3041
|
const entries = await fs5.readdir(src, { withFileTypes: true });
|
|
2858
3042
|
for (const entry of entries) {
|
|
2859
|
-
const srcPath =
|
|
2860
|
-
const destPath =
|
|
3043
|
+
const srcPath = path22__default.join(src, entry.name);
|
|
3044
|
+
const destPath = path22__default.join(dest, entry.name);
|
|
2861
3045
|
if (entry.isDirectory()) await copyDir(srcPath, destPath);
|
|
2862
3046
|
else await fs5.copyFile(srcPath, destPath);
|
|
2863
3047
|
}
|
|
@@ -2866,31 +3050,32 @@ async function install(projectDir, opts) {
|
|
|
2866
3050
|
return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);
|
|
2867
3051
|
}
|
|
2868
3052
|
async function installMcp(projectDir) {
|
|
2869
|
-
const mcpPath =
|
|
3053
|
+
const mcpPath = mcpFilePath(projectDir);
|
|
2870
3054
|
const existing = await readJsonStrict(mcpPath) ?? {};
|
|
2871
3055
|
const mcpServers = { ...existing.mcpServers ?? {} };
|
|
2872
3056
|
const previous = mcpServers[SKAILE_MCP_NAME];
|
|
2873
3057
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);
|
|
2874
3058
|
let warning;
|
|
2875
3059
|
if (previous && !matches) {
|
|
2876
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${
|
|
3060
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path22__default.relative(projectDir, mcpPath)}`;
|
|
2877
3061
|
}
|
|
2878
3062
|
mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;
|
|
2879
3063
|
await writeJson(mcpPath, { ...existing, mcpServers });
|
|
2880
|
-
|
|
3064
|
+
const migrated = await removeSkaileMcpEntry(legacyMcpFilePath(projectDir));
|
|
3065
|
+
return { changed: !matches || migrated, method: "mcp", warning };
|
|
2881
3066
|
}
|
|
2882
3067
|
async function installFullPlugin(projectDir) {
|
|
2883
3068
|
const dir = pluginDir(projectDir);
|
|
2884
3069
|
for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {
|
|
2885
|
-
const dest =
|
|
2886
|
-
await fs5.mkdir(
|
|
3070
|
+
const dest = path22__default.join(dir, rel);
|
|
3071
|
+
await fs5.mkdir(path22__default.dirname(dest), { recursive: true });
|
|
2887
3072
|
await fs5.writeFile(dest, content);
|
|
2888
3073
|
}
|
|
2889
|
-
const projectSkillsDir =
|
|
3074
|
+
const projectSkillsDir = path22__default.join(projectDir, ".skaile", "skills");
|
|
2890
3075
|
if (existsSync(projectSkillsDir)) {
|
|
2891
|
-
await copyDir(projectSkillsDir,
|
|
3076
|
+
await copyDir(projectSkillsDir, path22__default.join(dir, "skills"));
|
|
2892
3077
|
}
|
|
2893
|
-
const settingsPath =
|
|
3078
|
+
const settingsPath = path22__default.join(projectDir, ".claude", "settings.json");
|
|
2894
3079
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2895
3080
|
const plugins = settings.plugins ?? [];
|
|
2896
3081
|
if (!plugins.includes(dir)) plugins.push(dir);
|
|
@@ -2898,8 +3083,8 @@ async function installFullPlugin(projectDir) {
|
|
|
2898
3083
|
return { changed: true, method: "plugin" };
|
|
2899
3084
|
}
|
|
2900
3085
|
async function uninstall(projectDir) {
|
|
2901
|
-
const settingsPath =
|
|
2902
|
-
const mcpPath =
|
|
3086
|
+
const settingsPath = path22__default.join(projectDir, ".claude", "settings.json");
|
|
3087
|
+
const mcpPath = mcpFilePath(projectDir);
|
|
2903
3088
|
const dir = pluginDir(projectDir);
|
|
2904
3089
|
let changed = false;
|
|
2905
3090
|
const settings = await readJsonStrict(settingsPath);
|
|
@@ -2916,29 +3101,19 @@ async function uninstall(projectDir) {
|
|
|
2916
3101
|
await fs5.rm(dir, { recursive: true, force: true });
|
|
2917
3102
|
changed = true;
|
|
2918
3103
|
}
|
|
2919
|
-
|
|
2920
|
-
if (
|
|
2921
|
-
changed = true;
|
|
2922
|
-
const { [SKAILE_MCP_NAME]: _removed, ...rest } = mcp.mcpServers;
|
|
2923
|
-
const updated = { ...mcp, mcpServers: rest };
|
|
2924
|
-
if (Object.keys(rest).length === 0) delete updated.mcpServers;
|
|
2925
|
-
if (Object.keys(updated).length === 0) {
|
|
2926
|
-
await fs5.unlink(mcpPath);
|
|
2927
|
-
} else {
|
|
2928
|
-
await writeJson(mcpPath, updated);
|
|
2929
|
-
}
|
|
2930
|
-
}
|
|
3104
|
+
if (await removeSkaileMcpEntry(mcpPath)) changed = true;
|
|
3105
|
+
if (await removeSkaileMcpEntry(legacyMcpFilePath(projectDir))) changed = true;
|
|
2931
3106
|
return { changed };
|
|
2932
3107
|
}
|
|
2933
3108
|
async function detectInstall(projectDir) {
|
|
2934
3109
|
const dir = pluginDir(projectDir);
|
|
2935
3110
|
const settings = await readJsonStrict(
|
|
2936
|
-
|
|
3111
|
+
path22__default.join(projectDir, ".claude", "settings.json")
|
|
2937
3112
|
);
|
|
2938
|
-
if (existsSync(
|
|
3113
|
+
if (existsSync(path22__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
|
|
2939
3114
|
return { method: "plugin", pluginPath: dir };
|
|
2940
3115
|
}
|
|
2941
|
-
const mcp = await readJsonStrict(
|
|
3116
|
+
const mcp = await readJsonStrict(mcpFilePath(projectDir));
|
|
2942
3117
|
if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {
|
|
2943
3118
|
return { method: "mcp" };
|
|
2944
3119
|
}
|
|
@@ -2947,7 +3122,7 @@ async function detectInstall(projectDir) {
|
|
|
2947
3122
|
async function enable(projectDir) {
|
|
2948
3123
|
const detected = await detectInstall(projectDir);
|
|
2949
3124
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
2950
|
-
const settingsPath =
|
|
3125
|
+
const settingsPath = path22__default.join(projectDir, ".claude", "settings.json");
|
|
2951
3126
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2952
3127
|
if (detected.method === "plugin") {
|
|
2953
3128
|
const disabled2 = settings.disabledPlugins ?? [];
|
|
@@ -2969,7 +3144,7 @@ async function enable(projectDir) {
|
|
|
2969
3144
|
async function disable(projectDir) {
|
|
2970
3145
|
const detected = await detectInstall(projectDir);
|
|
2971
3146
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
2972
|
-
const settingsPath =
|
|
3147
|
+
const settingsPath = path22__default.join(projectDir, ".claude", "settings.json");
|
|
2973
3148
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2974
3149
|
if (detected.method === "plugin") {
|
|
2975
3150
|
const list2 = settings.disabledPlugins ?? [];
|
|
@@ -2989,12 +3164,12 @@ async function disable(projectDir) {
|
|
|
2989
3164
|
return { changed: true };
|
|
2990
3165
|
}
|
|
2991
3166
|
async function status(projectDir) {
|
|
2992
|
-
const settingsPath =
|
|
2993
|
-
const mcpPath =
|
|
3167
|
+
const settingsPath = path22__default.join(projectDir, ".claude", "settings.json");
|
|
3168
|
+
const mcpPath = mcpFilePath(projectDir);
|
|
2994
3169
|
const dir = pluginDir(projectDir);
|
|
2995
3170
|
const settings = await readJsonStrict(settingsPath);
|
|
2996
3171
|
const mcp = await readJsonStrict(mcpPath);
|
|
2997
|
-
const pluginInstalled = !!(existsSync(
|
|
3172
|
+
const pluginInstalled = !!(existsSync(path22__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
|
|
2998
3173
|
const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);
|
|
2999
3174
|
if (!pluginInstalled && !mcpInstalled) {
|
|
3000
3175
|
return {
|
|
@@ -3012,7 +3187,7 @@ async function status(projectDir) {
|
|
|
3012
3187
|
installed: "yes",
|
|
3013
3188
|
enabled: disabled2 ? "no" : "yes",
|
|
3014
3189
|
method: "plugin",
|
|
3015
|
-
location:
|
|
3190
|
+
location: path22__default.relative(projectDir, dir)
|
|
3016
3191
|
};
|
|
3017
3192
|
}
|
|
3018
3193
|
const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;
|
|
@@ -3021,7 +3196,7 @@ async function status(projectDir) {
|
|
|
3021
3196
|
installed: "yes",
|
|
3022
3197
|
enabled: disabled ? "no" : "yes",
|
|
3023
3198
|
method: "mcp",
|
|
3024
|
-
location:
|
|
3199
|
+
location: path22__default.relative(projectDir, mcpPath)
|
|
3025
3200
|
};
|
|
3026
3201
|
}
|
|
3027
3202
|
var SKAILE_MCP_NAME2 = "skaile-workspace";
|
|
@@ -3048,7 +3223,7 @@ async function readConfig(p6) {
|
|
|
3048
3223
|
}
|
|
3049
3224
|
}
|
|
3050
3225
|
async function writeConfig(p6, value) {
|
|
3051
|
-
await fs5.mkdir(
|
|
3226
|
+
await fs5.mkdir(path22__default.dirname(p6), { recursive: true });
|
|
3052
3227
|
const cleaned = {};
|
|
3053
3228
|
for (const [k, v] of Object.entries(value)) {
|
|
3054
3229
|
if (v === void 0) continue;
|
|
@@ -3057,7 +3232,7 @@ async function writeConfig(p6, value) {
|
|
|
3057
3232
|
await fs5.writeFile(p6, stringify$1(cleaned));
|
|
3058
3233
|
}
|
|
3059
3234
|
function configPath(projectDir) {
|
|
3060
|
-
return
|
|
3235
|
+
return path22__default.join(projectDir, ".codex", "config.toml");
|
|
3061
3236
|
}
|
|
3062
3237
|
async function install2(projectDir) {
|
|
3063
3238
|
const p6 = configPath(projectDir);
|
|
@@ -3068,7 +3243,7 @@ async function install2(projectDir) {
|
|
|
3068
3243
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
|
|
3069
3244
|
let warning;
|
|
3070
3245
|
if (previous && !matches) {
|
|
3071
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${
|
|
3246
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path22__default.relative(projectDir, p6)}`;
|
|
3072
3247
|
}
|
|
3073
3248
|
if (matches) return { changed: false, method: "toml" };
|
|
3074
3249
|
servers[SKAILE_MCP_NAME2] = next;
|
|
@@ -3109,12 +3284,12 @@ async function status2(projectDir) {
|
|
|
3109
3284
|
installed: "yes",
|
|
3110
3285
|
enabled: "n/a",
|
|
3111
3286
|
method: "mcp",
|
|
3112
|
-
location:
|
|
3287
|
+
location: path22__default.relative(projectDir, p6)
|
|
3113
3288
|
};
|
|
3114
3289
|
}
|
|
3115
3290
|
async function install3(projectDir) {
|
|
3116
|
-
const extDir =
|
|
3117
|
-
const extPath =
|
|
3291
|
+
const extDir = path22__default.join(projectDir, ".omp", "extensions");
|
|
3292
|
+
const extPath = path22__default.join(extDir, "skaile.ts");
|
|
3118
3293
|
await fs5.mkdir(extDir, { recursive: true });
|
|
3119
3294
|
const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
|
|
3120
3295
|
const plugin = new WorkspacePlugin({ projectDir });
|
|
@@ -3129,7 +3304,7 @@ async function install3(projectDir) {
|
|
|
3129
3304
|
return { changed: true, method: "generated" };
|
|
3130
3305
|
}
|
|
3131
3306
|
async function uninstall3(projectDir) {
|
|
3132
|
-
const extPath =
|
|
3307
|
+
const extPath = path22__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3133
3308
|
try {
|
|
3134
3309
|
await fs5.unlink(extPath);
|
|
3135
3310
|
return { changed: true };
|
|
@@ -3138,14 +3313,14 @@ async function uninstall3(projectDir) {
|
|
|
3138
3313
|
}
|
|
3139
3314
|
}
|
|
3140
3315
|
async function status3(projectDir) {
|
|
3141
|
-
const extPath =
|
|
3316
|
+
const extPath = path22__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3142
3317
|
if (existsSync(extPath)) {
|
|
3143
3318
|
return {
|
|
3144
3319
|
harness: "omp",
|
|
3145
3320
|
installed: "yes",
|
|
3146
3321
|
enabled: "n/a",
|
|
3147
3322
|
method: "extension",
|
|
3148
|
-
location:
|
|
3323
|
+
location: path22__default.relative(projectDir, extPath)
|
|
3149
3324
|
};
|
|
3150
3325
|
}
|
|
3151
3326
|
return {
|
|
@@ -3182,7 +3357,7 @@ async function installClaudeCode(projectDir, opts) {
|
|
|
3182
3357
|
`Generated ${S.cmd(".claude/plugins/skaile/")} and registered it in ${S.cmd(".claude/settings.json")}`
|
|
3183
3358
|
);
|
|
3184
3359
|
} else if (r.changed) {
|
|
3185
|
-
logOk(`Wrote ${S.cmd(".
|
|
3360
|
+
logOk(`Wrote ${S.cmd(".mcp.json")} (${SKAILE_MCP_LABEL})`);
|
|
3186
3361
|
} else {
|
|
3187
3362
|
logInfo(`claude-code: already installed (mcp)`);
|
|
3188
3363
|
}
|
|
@@ -3208,7 +3383,7 @@ async function installCodex(projectDir) {
|
|
|
3208
3383
|
console.log(` ${S.dim("\u2192")} Restart Codex CLI to pick up the change.`);
|
|
3209
3384
|
}
|
|
3210
3385
|
async function runInstall(opts) {
|
|
3211
|
-
const projectDir =
|
|
3386
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
3212
3387
|
const targets = resolveDriver(opts.driver);
|
|
3213
3388
|
let exitCode = 0;
|
|
3214
3389
|
if (targets.includes("claude-code")) {
|
|
@@ -3242,7 +3417,7 @@ async function uninstallCodex(projectDir) {
|
|
|
3242
3417
|
else logInfo(`codex: not installed`);
|
|
3243
3418
|
}
|
|
3244
3419
|
async function runUninstall(opts) {
|
|
3245
|
-
const projectDir =
|
|
3420
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
3246
3421
|
const targets = resolveDriver(opts.driver);
|
|
3247
3422
|
let exitCode = 0;
|
|
3248
3423
|
if (targets.includes("claude-code")) {
|
|
@@ -3285,7 +3460,7 @@ async function toggleTarget(t, projectDir, action3) {
|
|
|
3285
3460
|
});
|
|
3286
3461
|
}
|
|
3287
3462
|
async function runToggle(opts, action3) {
|
|
3288
|
-
const projectDir =
|
|
3463
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
3289
3464
|
const requestedAll = opts.driver === "all";
|
|
3290
3465
|
const targets = resolveDriver(opts.driver);
|
|
3291
3466
|
const usageError = checkToggleSupported(targets, requestedAll, action3);
|
|
@@ -3297,7 +3472,7 @@ async function runToggle(opts, action3) {
|
|
|
3297
3472
|
return exitCode;
|
|
3298
3473
|
}
|
|
3299
3474
|
async function runStatus2(opts) {
|
|
3300
|
-
const projectDir =
|
|
3475
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
3301
3476
|
const targets = resolveDriver(opts.driver);
|
|
3302
3477
|
const rows = [];
|
|
3303
3478
|
let exitCode = 0;
|
|
@@ -3338,12 +3513,12 @@ function printStatusTable(rows) {
|
|
|
3338
3513
|
var SKAILE_MCP_LABEL = "skaile-workspace entry";
|
|
3339
3514
|
var HOOK_EVENTS = ["session-start", "session-end", "user-prompt-submit"];
|
|
3340
3515
|
async function runHook(event) {
|
|
3341
|
-
const { LogStore, StdoutSink, registerLogStore } = await import('../core/logging.js');
|
|
3342
|
-
|
|
3343
|
-
new
|
|
3516
|
+
const { LogStore: LogStore2, StdoutSink: StdoutSink2, registerLogStore: registerLogStore2 } = await import('../core/logging.js');
|
|
3517
|
+
registerLogStore2(
|
|
3518
|
+
new LogStore2({
|
|
3344
3519
|
sessionId: `hook-${event}`,
|
|
3345
3520
|
level: "info",
|
|
3346
|
-
sinks: [new
|
|
3521
|
+
sinks: [new StdoutSink2({ stream: "stderr" })]
|
|
3347
3522
|
})
|
|
3348
3523
|
);
|
|
3349
3524
|
const { WorkspacePlugin, PluginStore, resolveProjectDir } = await import('../workspace-plugin/index.js');
|
|
@@ -3368,7 +3543,7 @@ async function runHook(event) {
|
|
|
3368
3543
|
await plugin.shutdown();
|
|
3369
3544
|
return;
|
|
3370
3545
|
}
|
|
3371
|
-
const store = new PluginStore(
|
|
3546
|
+
const store = new PluginStore(path22__default.join(projectDir, ".skaile", "plugin-state.json"));
|
|
3372
3547
|
await store.load();
|
|
3373
3548
|
const status4 = store.get("connector:status");
|
|
3374
3549
|
if (status4 && typeof status4 === "object" && Object.keys(status4).length > 0) {
|
|
@@ -3383,6 +3558,45 @@ async function runHook(event) {
|
|
|
3383
3558
|
);
|
|
3384
3559
|
}
|
|
3385
3560
|
}
|
|
3561
|
+
async function readStdin() {
|
|
3562
|
+
if (process.stdin.isTTY) return "";
|
|
3563
|
+
const chunks = [];
|
|
3564
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
3565
|
+
return Buffer.concat(chunks).toString("utf-8");
|
|
3566
|
+
}
|
|
3567
|
+
async function runOmpExec(kind, name, projectDir) {
|
|
3568
|
+
if (kind !== "tool" && kind !== "slash") {
|
|
3569
|
+
logErr(`omp-exec: unknown kind '${kind}' (expected: tool | slash)`);
|
|
3570
|
+
return 2;
|
|
3571
|
+
}
|
|
3572
|
+
const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
|
|
3573
|
+
const plugin = new WorkspacePlugin({ projectDir, bootOwned: true });
|
|
3574
|
+
try {
|
|
3575
|
+
const raw = (await readStdin()).trim();
|
|
3576
|
+
const payload = raw ? JSON.parse(raw) : kind === "tool" ? {} : [];
|
|
3577
|
+
await plugin.boot();
|
|
3578
|
+
if (kind === "slash") {
|
|
3579
|
+
const parts = Array.isArray(payload) ? payload.map(String) : [];
|
|
3580
|
+
process.stdout.write(`${await plugin.handleSlashCommand(name, parts)}
|
|
3581
|
+
`);
|
|
3582
|
+
return 0;
|
|
3583
|
+
}
|
|
3584
|
+
const tools = await plugin.buildOmpToolSet();
|
|
3585
|
+
const tool = tools.find((t) => t.name === name);
|
|
3586
|
+
if (!tool) {
|
|
3587
|
+
logErr(`omp-exec: unknown tool '${name}'`);
|
|
3588
|
+
return 2;
|
|
3589
|
+
}
|
|
3590
|
+
process.stdout.write(`${await tool.handler(payload)}
|
|
3591
|
+
`);
|
|
3592
|
+
return 0;
|
|
3593
|
+
} catch (e) {
|
|
3594
|
+
logErr(`omp-exec ${kind} ${name}: ${e instanceof Error ? e.message : String(e)}`);
|
|
3595
|
+
return 1;
|
|
3596
|
+
} finally {
|
|
3597
|
+
await plugin.shutdown();
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3386
3600
|
function makeIntegrationCommand() {
|
|
3387
3601
|
const cmd = new Command("integration").description(
|
|
3388
3602
|
"Manage skaile agent integration / workspace-plugin adapter (Claude Code / OMP / Codex)"
|
|
@@ -3405,13 +3619,18 @@ function makeIntegrationCommand() {
|
|
|
3405
3619
|
cmd.command("status").description("Show install / enable status across harnesses").option("--driver <name>", "Target: claude-code | omp | codex | all", "all").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
3406
3620
|
process.exitCode = await runStatus2(opts);
|
|
3407
3621
|
});
|
|
3622
|
+
cmd.command("omp-exec <kind> <name>").description(
|
|
3623
|
+
"Run one tool or slash command of the omp extension (used by .omp/extensions/skaile.ts)"
|
|
3624
|
+
).option("--project-dir <path>", "Project directory", process.cwd()).action(async (kind, name, opts) => {
|
|
3625
|
+
process.exitCode = await runOmpExec(kind, name, path22__default.resolve(opts.projectDir));
|
|
3626
|
+
});
|
|
3408
3627
|
cmd.command("hook <event>").description(
|
|
3409
3628
|
"Run a Claude Code lifecycle hook (session-start | session-end | user-prompt-submit)"
|
|
3410
3629
|
).action(async (event) => {
|
|
3411
3630
|
try {
|
|
3412
3631
|
if (!HOOK_EVENTS.includes(event)) {
|
|
3413
3632
|
process.stderr.write(
|
|
3414
|
-
`
|
|
3633
|
+
`integration hook: unknown event '${event}' (expected: ${HOOK_EVENTS.join(" | ")})
|
|
3415
3634
|
`
|
|
3416
3635
|
);
|
|
3417
3636
|
} else {
|
|
@@ -3419,7 +3638,7 @@ function makeIntegrationCommand() {
|
|
|
3419
3638
|
}
|
|
3420
3639
|
} catch (err2) {
|
|
3421
3640
|
process.stderr.write(
|
|
3422
|
-
`
|
|
3641
|
+
`integration hook ${event} warning: ${err2 instanceof Error ? err2.message : String(err2)}
|
|
3423
3642
|
`
|
|
3424
3643
|
);
|
|
3425
3644
|
}
|
|
@@ -3446,7 +3665,7 @@ function unfinishedGitState(dir) {
|
|
|
3446
3665
|
for (const [entry, state2] of Object.entries(UNFINISHED_GIT_ENTRIES)) {
|
|
3447
3666
|
const p6 = spawnSync("git", ["rev-parse", "--git-path", entry], { cwd: dir, encoding: "utf-8" });
|
|
3448
3667
|
if (p6.status !== 0) return "the git directory could not be read";
|
|
3449
|
-
if (fs8.existsSync(
|
|
3668
|
+
if (fs8.existsSync(path22.resolve(dir, p6.stdout.trim()))) return state2;
|
|
3450
3669
|
}
|
|
3451
3670
|
return null;
|
|
3452
3671
|
}
|
|
@@ -3461,7 +3680,7 @@ async function reindexLibrary(lib, library, name) {
|
|
|
3461
3680
|
lib.path,
|
|
3462
3681
|
resolved.publisher,
|
|
3463
3682
|
registry,
|
|
3464
|
-
{ check: (e) => checkAssetFile(e.source, e.kind, registry) }
|
|
3683
|
+
{ check: (e) => checkAssetFile(e.source, e.kind, registry, lib.path) }
|
|
3465
3684
|
);
|
|
3466
3685
|
const manifest = loadSkPublishManifest(lib.path);
|
|
3467
3686
|
for (const a of unknownKind) {
|
|
@@ -3473,19 +3692,25 @@ async function reindexLibrary(lib, library, name) {
|
|
|
3473
3692
|
const ref = manifest ? assetEntryRef(a, manifest) : `${a.kind}:${a.name}`;
|
|
3474
3693
|
logInfo(`Removed manifest entry ${ref} (root ${a.root} is gone)`);
|
|
3475
3694
|
}
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3695
|
+
const invalidVersion = skipped.filter((x) => x.reason === "invalid-version");
|
|
3696
|
+
for (const s of invalidVersion) {
|
|
3697
|
+
const found = checkAssetFile(path22.join(lib.path, s.file), s.kind, registry).find(
|
|
3698
|
+
(f) => f.text.startsWith("version ")
|
|
3699
|
+
);
|
|
3700
|
+
const detail = found?.text ?? s.detail;
|
|
3701
|
+
const hint = detail.includes("Write it quoted") ? "" : " Set a valid `metadata.version` (e.g. 0.1.0).";
|
|
3702
|
+
logErr(
|
|
3703
|
+
`${s.kind}:${s.name} skipped: ${detail}.${hint} Re-run \`skaile library index ${name}\` after the fix.`
|
|
3479
3704
|
);
|
|
3480
3705
|
}
|
|
3481
3706
|
const duplicates = skipped.filter((x) => x.reason === "duplicate");
|
|
3482
3707
|
for (const s of duplicates) {
|
|
3483
|
-
logErr(duplicateAssetMessage(s.kind, s.name,
|
|
3708
|
+
logErr(duplicateAssetMessage(s.kind, s.name, path22.dirname(s.file), s.detail, name));
|
|
3484
3709
|
}
|
|
3485
3710
|
for (const s of failed) {
|
|
3486
3711
|
for (const f of s.findings) logErr(`${s.file} [${f.tag}] \u2014 ${f.text}`);
|
|
3487
3712
|
}
|
|
3488
|
-
const duplicateFiles = new Set(duplicates.map((s) =>
|
|
3713
|
+
const duplicateFiles = new Set(duplicates.map((s) => path22.resolve(lib.path, s.file)));
|
|
3489
3714
|
const skippedKeys = new Set(
|
|
3490
3715
|
[
|
|
3491
3716
|
...skipped.filter((s) => s.reason !== "duplicate"),
|
|
@@ -3493,7 +3718,7 @@ async function reindexLibrary(lib, library, name) {
|
|
|
3493
3718
|
].map((s) => `${s.kind}:${s.name}`)
|
|
3494
3719
|
);
|
|
3495
3720
|
const res = await indexLibrary(lib, library, {
|
|
3496
|
-
exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`) || duplicateFiles.has(
|
|
3721
|
+
exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`) || duplicateFiles.has(path22.resolve(a.manifestPath))
|
|
3497
3722
|
});
|
|
3498
3723
|
const unparsable = res.errors.filter((e) => e.includes("ManifestSchemaError:"));
|
|
3499
3724
|
for (const e of res.errors) (unparsable.includes(e) ? logErr : logWarn)(e);
|
|
@@ -3505,14 +3730,21 @@ async function reindexLibrary(lib, library, name) {
|
|
|
3505
3730
|
}
|
|
3506
3731
|
for (const p6 of badRequires) logErr(`${p6.asset}: ${p6.message}`);
|
|
3507
3732
|
for (const w of await unresolvedManifestDependencies(lib.path)) logWarn(w);
|
|
3508
|
-
|
|
3733
|
+
const skippedUnparsable = unparsable.length + syncUnparsable.length;
|
|
3734
|
+
const failing = skippedUnparsable + invalidVersion.length + badRequires.length + failed.length + duplicates.length;
|
|
3735
|
+
(failing > 0 ? logWarn : logOk)(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
|
|
3509
3736
|
warnIgnoredDomainFiles(lib.path);
|
|
3510
3737
|
warnLegacyBundleFiles(lib.path);
|
|
3511
|
-
const skippedUnparsable = unparsable.length + syncUnparsable.length;
|
|
3512
3738
|
if (skippedUnparsable > 0) {
|
|
3513
3739
|
logErr(`${skippedUnparsable} asset(s) skipped: manifest could not be parsed.`);
|
|
3514
3740
|
process.exitCode = 1;
|
|
3515
3741
|
}
|
|
3742
|
+
if (invalidVersion.length > 0) {
|
|
3743
|
+
logErr(
|
|
3744
|
+
`${invalidVersion.length} asset(s) skipped: the version is not valid semver (listed above).`
|
|
3745
|
+
);
|
|
3746
|
+
process.exitCode = 1;
|
|
3747
|
+
}
|
|
3516
3748
|
if (badRequires.length > 0) {
|
|
3517
3749
|
logErr(
|
|
3518
3750
|
`${badRequires.length} invalid requires entr${badRequires.length === 1 ? "y" : "ies"} ignored: use the \`kind:@<publisher>/name[#version]\` form.`
|
|
@@ -3547,26 +3779,26 @@ function assertManifestEditableOrExit(libraryPath) {
|
|
|
3547
3779
|
}
|
|
3548
3780
|
async function assertLibraryPathFree(manager, dir, exceptId) {
|
|
3549
3781
|
const clash = (await manager.listLibraries()).find(
|
|
3550
|
-
(l) => l.id !== exceptId &&
|
|
3782
|
+
(l) => l.id !== exceptId && path22.resolve(l.path) === dir
|
|
3551
3783
|
);
|
|
3552
3784
|
if (clash) throw new Error(`${dir} is already registered as library "${clash.name}".`);
|
|
3553
3785
|
}
|
|
3554
3786
|
function canonicalDir(dir) {
|
|
3555
|
-
const abs =
|
|
3787
|
+
const abs = path22.resolve(dir);
|
|
3556
3788
|
const missing = [];
|
|
3557
3789
|
let existing = abs;
|
|
3558
3790
|
while (!fs8.existsSync(existing)) {
|
|
3559
|
-
const parent =
|
|
3791
|
+
const parent = path22.dirname(existing);
|
|
3560
3792
|
if (parent === existing) return abs;
|
|
3561
|
-
missing.unshift(
|
|
3793
|
+
missing.unshift(path22.basename(existing));
|
|
3562
3794
|
existing = parent;
|
|
3563
3795
|
}
|
|
3564
|
-
return
|
|
3796
|
+
return path22.join(fs8.realpathSync(existing), ...missing);
|
|
3565
3797
|
}
|
|
3566
3798
|
function refuseGlobalInstallFolder(name, dir) {
|
|
3567
3799
|
const reserved = globalInstallDir();
|
|
3568
|
-
const rel =
|
|
3569
|
-
const inside = rel === "" || !rel.startsWith("..") && !
|
|
3800
|
+
const rel = path22.relative(canonicalDir(reserved).toLowerCase(), canonicalDir(dir).toLowerCase());
|
|
3801
|
+
const inside = rel === "" || !rel.startsWith("..") && !path22.isAbsolute(rel);
|
|
3570
3802
|
if (name?.toLowerCase() === GLOBAL_INSTALL_DIR_NAME || inside) {
|
|
3571
3803
|
logErr(
|
|
3572
3804
|
`"${GLOBAL_INSTALL_DIR_NAME}" is reserved: ${reserved} holds assets from \`skaile install\`, not a library you author.`
|
|
@@ -3576,8 +3808,8 @@ function refuseGlobalInstallFolder(name, dir) {
|
|
|
3576
3808
|
}
|
|
3577
3809
|
async function refuseNestedLibraryPath(manager, dir, exceptId) {
|
|
3578
3810
|
const within = (parent, child) => {
|
|
3579
|
-
const rel =
|
|
3580
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
3811
|
+
const rel = path22.relative(parent, child);
|
|
3812
|
+
return rel === "" || !rel.startsWith("..") && !path22.isAbsolute(rel);
|
|
3581
3813
|
};
|
|
3582
3814
|
const target = canonicalDir(dir).toLowerCase();
|
|
3583
3815
|
const librariesDir = resolveLibraryDir();
|
|
@@ -3614,7 +3846,7 @@ function assertCreateDirInsideLibrary(libRoot, destDir, given) {
|
|
|
3614
3846
|
}
|
|
3615
3847
|
};
|
|
3616
3848
|
let probe = destDir;
|
|
3617
|
-
while (!exists(probe)) probe =
|
|
3849
|
+
while (!exists(probe)) probe = path22.dirname(probe);
|
|
3618
3850
|
let realProbe;
|
|
3619
3851
|
try {
|
|
3620
3852
|
realProbe = fs8.realpathSync(probe);
|
|
@@ -3627,9 +3859,9 @@ function assertCreateDirInsideLibrary(libRoot, destDir, given) {
|
|
|
3627
3859
|
process.exit(1);
|
|
3628
3860
|
}
|
|
3629
3861
|
const realRoot = canonicalDir(libRoot);
|
|
3630
|
-
const realDest =
|
|
3631
|
-
const rel =
|
|
3632
|
-
if (rel === ".." || rel.startsWith(`..${
|
|
3862
|
+
const realDest = path22.join(realProbe, path22.relative(probe, destDir));
|
|
3863
|
+
const rel = path22.relative(realRoot, realDest);
|
|
3864
|
+
if (rel === ".." || rel.startsWith(`..${path22.sep}`) || path22.isAbsolute(rel)) {
|
|
3633
3865
|
logErr(
|
|
3634
3866
|
`--dir "${given}" must stay inside the library (${realRoot}): it resolves to ${realDest}.`
|
|
3635
3867
|
);
|
|
@@ -3637,7 +3869,7 @@ function assertCreateDirInsideLibrary(libRoot, destDir, given) {
|
|
|
3637
3869
|
}
|
|
3638
3870
|
}
|
|
3639
3871
|
function adoptWritesManifest(libPath) {
|
|
3640
|
-
if (!fs8.existsSync(
|
|
3872
|
+
if (!fs8.existsSync(path22.join(libPath, SKAILE_MANIFEST_FILENAME))) return true;
|
|
3641
3873
|
const manifest = loadSkPublishManifest(libPath);
|
|
3642
3874
|
if (!manifest || manifest.source || (manifest.assets ?? []).length > 0) return false;
|
|
3643
3875
|
return manifestPublisherProblems(libPath).length === 0;
|
|
@@ -3691,17 +3923,17 @@ function requireValidLibraryName(name) {
|
|
|
3691
3923
|
var LOCAL_OWNERSHIP_REASON = "ownership only governs sync with a git remote, and a local library is always owned by you.";
|
|
3692
3924
|
function pruneEmptyLibraryParents(libPath) {
|
|
3693
3925
|
const root = canonicalDir(resolveLibraryDir());
|
|
3694
|
-
let dir =
|
|
3926
|
+
let dir = path22.dirname(path22.resolve(libPath));
|
|
3695
3927
|
for (; ; ) {
|
|
3696
|
-
const rel =
|
|
3697
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
3928
|
+
const rel = path22.relative(root, canonicalDir(dir));
|
|
3929
|
+
if (rel === "" || rel.startsWith("..") || path22.isAbsolute(rel)) return;
|
|
3698
3930
|
if (!fs8.existsSync(dir) || fs8.readdirSync(dir).length > 0) return;
|
|
3699
3931
|
fs8.rmdirSync(dir);
|
|
3700
|
-
dir =
|
|
3932
|
+
dir = path22.dirname(dir);
|
|
3701
3933
|
}
|
|
3702
3934
|
}
|
|
3703
3935
|
async function warnIfNotGithubRemote(name, url) {
|
|
3704
|
-
const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-
|
|
3936
|
+
const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-DI4Q5UOG.js');
|
|
3705
3937
|
if (!isGithubRemote(url)) logWarn(notGithubRemoteMessage(name, url));
|
|
3706
3938
|
}
|
|
3707
3939
|
function scaffoldLibraryFiles(dir, name) {
|
|
@@ -3733,7 +3965,7 @@ by the same ref.
|
|
|
3733
3965
|
];
|
|
3734
3966
|
const written = [];
|
|
3735
3967
|
for (const [file, content] of files) {
|
|
3736
|
-
const target =
|
|
3968
|
+
const target = path22.join(dir, file);
|
|
3737
3969
|
if (fs8.existsSync(target)) continue;
|
|
3738
3970
|
fs8.writeFileSync(target, content, "utf8");
|
|
3739
3971
|
written.push(file);
|
|
@@ -3823,7 +4055,7 @@ function makeLibraryCommand() {
|
|
|
3823
4055
|
opts.path ??= gone.path;
|
|
3824
4056
|
}
|
|
3825
4057
|
const ownership = flagged[0] ?? gone?.ownership ?? "owner";
|
|
3826
|
-
const libPath = opts.path ?
|
|
4058
|
+
const libPath = opts.path ? path22.resolve(opts.path) : path22.join(resolveLibraryDir(), name);
|
|
3827
4059
|
refuseGlobalInstallFolder(name, libPath);
|
|
3828
4060
|
if (fs8.existsSync(libPath) && !fs8.statSync(libPath).isDirectory()) {
|
|
3829
4061
|
logErr(`${libPath} exists and is not a directory.`);
|
|
@@ -3925,7 +4157,10 @@ function makeLibraryCommand() {
|
|
|
3925
4157
|
}
|
|
3926
4158
|
}
|
|
3927
4159
|
);
|
|
3928
|
-
cmd.command("link <name> <git-url>").description("Attach a github remote to a local library (makes it store-publishable)").option(
|
|
4160
|
+
cmd.command("link <name> <git-url>").description("Attach a github remote to a local library (makes it store-publishable)").option(
|
|
4161
|
+
"--branch <name>",
|
|
4162
|
+
"Branch to track (default: the checked-out branch of an existing repo, else main)"
|
|
4163
|
+
).action(async (name, url, opts) => {
|
|
3929
4164
|
const { manager, close } = await openLibraryManager();
|
|
3930
4165
|
try {
|
|
3931
4166
|
const lib = await manager.requireLibraryDir(name);
|
|
@@ -3935,11 +4170,16 @@ function makeLibraryCommand() {
|
|
|
3935
4170
|
);
|
|
3936
4171
|
process.exit(1);
|
|
3937
4172
|
}
|
|
3938
|
-
|
|
3939
|
-
|
|
4173
|
+
const head = isGitRepo(lib.path) ? spawnSync("git", ["symbolic-ref", "--short", "-q", "HEAD"], {
|
|
4174
|
+
cwd: lib.path,
|
|
4175
|
+
encoding: "utf-8"
|
|
4176
|
+
}) : void 0;
|
|
4177
|
+
const branch = opts.branch ?? (head?.status === 0 && head.stdout.trim() || "main");
|
|
4178
|
+
ensureGitRepo(lib.path, url, branch);
|
|
4179
|
+
trackOriginBranch(lib.path, branch, { fetch: true });
|
|
3940
4180
|
await manager.updateLibrary(name, {
|
|
3941
4181
|
backend: "git",
|
|
3942
|
-
backendConfig: { url, branch
|
|
4182
|
+
backendConfig: { url, branch, authHint: "ssh" }
|
|
3943
4183
|
});
|
|
3944
4184
|
logOk(`Library "${name}" linked to ${url}.`);
|
|
3945
4185
|
await warnIfNotGithubRemote(name, url);
|
|
@@ -3980,10 +4220,10 @@ function makeLibraryCommand() {
|
|
|
3980
4220
|
exitOnManifestPublisherProblems(target.path, target.name);
|
|
3981
4221
|
const effectiveKind = opts.kind ?? kind;
|
|
3982
4222
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
|
|
3983
|
-
const libRoot =
|
|
3984
|
-
const destDir = opts.dir ?
|
|
3985
|
-
const relDest =
|
|
3986
|
-
if (relDest === ".." || relDest.startsWith(`..${
|
|
4223
|
+
const libRoot = path22.resolve(target.path);
|
|
4224
|
+
const destDir = opts.dir ? path22.resolve(libRoot, opts.dir) : libRoot;
|
|
4225
|
+
const relDest = path22.relative(libRoot, destDir);
|
|
4226
|
+
if (relDest === ".." || relDest.startsWith(`..${path22.sep}`) || path22.isAbsolute(relDest)) {
|
|
3987
4227
|
logErr(`--dir "${opts.dir}" must stay inside the library (${libRoot}).`);
|
|
3988
4228
|
process.exit(1);
|
|
3989
4229
|
}
|
|
@@ -3992,11 +4232,11 @@ function makeLibraryCommand() {
|
|
|
3992
4232
|
libRoot,
|
|
3993
4233
|
effectiveKind,
|
|
3994
4234
|
name,
|
|
3995
|
-
|
|
4235
|
+
path22.relative(libRoot, path22.join(destDir, name))
|
|
3996
4236
|
);
|
|
3997
4237
|
if (taken) {
|
|
3998
4238
|
logErr(
|
|
3999
|
-
`${effectiveKind}:${name} already exists at "${taken}" \u2014 creating it again under "${
|
|
4239
|
+
`${effectiveKind}:${name} already exists at "${taken}" \u2014 creating it again under "${path22.relative(libRoot, destDir) || "."}" would re-point the manifest entry. Pick another name.`
|
|
4000
4240
|
);
|
|
4001
4241
|
process.exit(1);
|
|
4002
4242
|
}
|
|
@@ -4054,7 +4294,7 @@ function makeLibraryCommand() {
|
|
|
4054
4294
|
logErr(`A library named "${newName}" is already registered.`);
|
|
4055
4295
|
process.exit(1);
|
|
4056
4296
|
}
|
|
4057
|
-
const newPath =
|
|
4297
|
+
const newPath = path22.join(path22.dirname(lib.path), newName);
|
|
4058
4298
|
refuseGlobalInstallFolder(newName, newPath);
|
|
4059
4299
|
if (fs8.existsSync(newPath)) {
|
|
4060
4300
|
logErr(`Target directory already exists: ${newPath}`);
|
|
@@ -4140,7 +4380,7 @@ function makeLibraryCommand() {
|
|
|
4140
4380
|
}
|
|
4141
4381
|
patch.isDefault = false;
|
|
4142
4382
|
} else if (field === "path") {
|
|
4143
|
-
const dir =
|
|
4383
|
+
const dir = path22.resolve(value);
|
|
4144
4384
|
if (!fs8.existsSync(dir) || !fs8.statSync(dir).isDirectory()) {
|
|
4145
4385
|
logErr(`Directory does not exist: ${dir}. \`library set path=\` does not move files.`);
|
|
4146
4386
|
process.exit(1);
|
|
@@ -4352,16 +4592,16 @@ function makeLibraryCommand() {
|
|
|
4352
4592
|
"With --create-repo: create the repo private (the store only accepts public repos)"
|
|
4353
4593
|
).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(
|
|
4354
4594
|
async (lib, opts) => {
|
|
4355
|
-
const { runLibraryPublish } = await import('../library-publish-
|
|
4595
|
+
const { runLibraryPublish } = await import('../library-publish-DI4Q5UOG.js');
|
|
4356
4596
|
await withStoreErrorHandling(() => runLibraryPublish(lib, opts));
|
|
4357
4597
|
}
|
|
4358
4598
|
);
|
|
4359
4599
|
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) => {
|
|
4360
|
-
const { runLibraryRegister } = await import('../library-publish-
|
|
4600
|
+
const { runLibraryRegister } = await import('../library-publish-DI4Q5UOG.js');
|
|
4361
4601
|
await withStoreErrorHandling(() => runLibraryRegister(lib, opts));
|
|
4362
4602
|
});
|
|
4363
4603
|
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) => {
|
|
4364
|
-
const { runLibraryYank } = await import('../library-publish-
|
|
4604
|
+
const { runLibraryYank } = await import('../library-publish-DI4Q5UOG.js');
|
|
4365
4605
|
await withStoreErrorHandling(() => runLibraryYank(lib, opts));
|
|
4366
4606
|
});
|
|
4367
4607
|
return cmd;
|
|
@@ -4412,9 +4652,9 @@ async function printOverallStatus(projectDir, asJson) {
|
|
|
4412
4652
|
} catch {
|
|
4413
4653
|
secretsStrategy = "unavailable";
|
|
4414
4654
|
}
|
|
4415
|
-
const resolvedProjectDir =
|
|
4416
|
-
const hasWorkspaceConfig = existsSync(
|
|
4417
|
-
const hasLockFile = existsSync(
|
|
4655
|
+
const resolvedProjectDir = path22.resolve(projectDir);
|
|
4656
|
+
const hasWorkspaceConfig = existsSync(path22.join(resolvedProjectDir, "skaile.yaml"));
|
|
4657
|
+
const hasLockFile = existsSync(path22.join(resolvedProjectDir, "skaile.lock.yaml"));
|
|
4418
4658
|
let assignments = [];
|
|
4419
4659
|
if (hasWorkspaceConfig) {
|
|
4420
4660
|
try {
|
|
@@ -5021,7 +5261,7 @@ function scheduleSoftDepPreview() {
|
|
|
5021
5261
|
}
|
|
5022
5262
|
async function loadAssets() {
|
|
5023
5263
|
softDepPreviewCache.clear();
|
|
5024
|
-
const { gatherAssetFeeds } = await import('../asset-feeds-
|
|
5264
|
+
const { gatherAssetFeeds } = await import('../asset-feeds-AM6PSSGM.js');
|
|
5025
5265
|
const { entries, notes } = await gatherAssetFeeds(am, am.projectDir);
|
|
5026
5266
|
if (notes.length > 0) {
|
|
5027
5267
|
state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
|
|
@@ -5029,7 +5269,7 @@ async function loadAssets() {
|
|
|
5029
5269
|
const installed = new Set(am.listDeployed().map((e) => `${e.kind}:${e.name}`));
|
|
5030
5270
|
let lock = null;
|
|
5031
5271
|
try {
|
|
5032
|
-
lock = readLock(
|
|
5272
|
+
lock = readLock(path22__default.join(am.projectDir, "skaile.lock.yaml"));
|
|
5033
5273
|
} catch {
|
|
5034
5274
|
}
|
|
5035
5275
|
const rows = buildAssetRows(
|
|
@@ -5051,7 +5291,7 @@ function rebuildSourceTree() {
|
|
|
5051
5291
|
rebuildVisibleSources();
|
|
5052
5292
|
}
|
|
5053
5293
|
function sourceOrgRepo(s) {
|
|
5054
|
-
const parts = s.path.split(
|
|
5294
|
+
const parts = s.path.split(path22__default.sep).filter(Boolean);
|
|
5055
5295
|
if (parts.length < 2) return null;
|
|
5056
5296
|
return { org: parts[parts.length - 2], repo: parts[parts.length - 1] };
|
|
5057
5297
|
}
|
|
@@ -5225,13 +5465,13 @@ function reconcileCollapsedSets(rows) {
|
|
|
5225
5465
|
async function loadSourcesAndLibraries() {
|
|
5226
5466
|
try {
|
|
5227
5467
|
const [{ openLibraryManager: openLibraryManager2 }, { getGlobalCacheDir: getGlobalCacheDir2, globalSkaileDir: globalSkaileDir2 }] = await Promise.all([
|
|
5228
|
-
import('../open-library-
|
|
5468
|
+
import('../open-library-N6ESO6IK.js'),
|
|
5229
5469
|
import('../core/index.js')
|
|
5230
5470
|
]);
|
|
5231
5471
|
const { manager, library, close } = await openLibraryManager2();
|
|
5232
5472
|
try {
|
|
5233
5473
|
const newRoot = getGlobalCacheDir2();
|
|
5234
|
-
const legacyRoot =
|
|
5474
|
+
const legacyRoot = path22__default.join(globalSkaileDir2(), "sources");
|
|
5235
5475
|
const isSourceRow = (l) => l.path.startsWith(newRoot) || l.path.startsWith(legacyRoot);
|
|
5236
5476
|
const libs = await manager.listLibraries();
|
|
5237
5477
|
const defs = await library.listAssetDefs();
|
|
@@ -6191,19 +6431,19 @@ async function run(projectDir) {
|
|
|
6191
6431
|
}
|
|
6192
6432
|
function makeManageCommand() {
|
|
6193
6433
|
return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
6194
|
-
await run(
|
|
6434
|
+
await run(path22__default.resolve(opts.projectDir));
|
|
6195
6435
|
});
|
|
6196
6436
|
}
|
|
6197
6437
|
function makeMcpServerCommand() {
|
|
6198
6438
|
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) => {
|
|
6199
|
-
const
|
|
6200
|
-
const projectDir =
|
|
6201
|
-
const { LogStore, StdoutSink, registerLogStore } = await import('../core/logging.js');
|
|
6202
|
-
|
|
6203
|
-
new
|
|
6439
|
+
const path44 = await import('path');
|
|
6440
|
+
const projectDir = path44.default.resolve(opts.projectDir);
|
|
6441
|
+
const { LogStore: LogStore2, StdoutSink: StdoutSink2, registerLogStore: registerLogStore2 } = await import('../core/logging.js');
|
|
6442
|
+
registerLogStore2(
|
|
6443
|
+
new LogStore2({
|
|
6204
6444
|
sessionId: "mcp-server",
|
|
6205
6445
|
level: "info",
|
|
6206
|
-
sinks: [new
|
|
6446
|
+
sinks: [new StdoutSink2({ stream: "stderr" })]
|
|
6207
6447
|
})
|
|
6208
6448
|
);
|
|
6209
6449
|
const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
|
|
@@ -6244,10 +6484,10 @@ function walkFiles(root, match) {
|
|
|
6244
6484
|
return;
|
|
6245
6485
|
}
|
|
6246
6486
|
for (const entry of entries) {
|
|
6247
|
-
const full =
|
|
6487
|
+
const full = path22__default.join(dir, entry.name);
|
|
6248
6488
|
if (entry.isDirectory()) {
|
|
6249
6489
|
if (SKIPPED_DIRS.has(entry.name)) continue;
|
|
6250
|
-
if (entry.name === "cache" &&
|
|
6490
|
+
if (entry.name === "cache" && path22__default.basename(dir) === ".skaile") continue;
|
|
6251
6491
|
visit(full);
|
|
6252
6492
|
} else if (entry.isFile() && match(entry.name)) {
|
|
6253
6493
|
out.push(full);
|
|
@@ -6265,14 +6505,14 @@ function applyChanges2(changes) {
|
|
|
6265
6505
|
switch (change.type) {
|
|
6266
6506
|
case "write":
|
|
6267
6507
|
case "create":
|
|
6268
|
-
mkdirSync(
|
|
6508
|
+
mkdirSync(path22__default.dirname(change.path), { recursive: true });
|
|
6269
6509
|
writeFileSync(change.path, change.after, "utf-8");
|
|
6270
6510
|
break;
|
|
6271
6511
|
case "delete":
|
|
6272
6512
|
rmSync(change.path, { force: true });
|
|
6273
6513
|
break;
|
|
6274
6514
|
case "move":
|
|
6275
|
-
mkdirSync(
|
|
6515
|
+
mkdirSync(path22__default.dirname(change.to), { recursive: true });
|
|
6276
6516
|
writeFileSync(change.to, change.after, "utf-8");
|
|
6277
6517
|
rmSync(change.from, { force: true });
|
|
6278
6518
|
break;
|
|
@@ -6365,7 +6605,7 @@ function unifiedDiff(before, after, oldLabel, newLabel, context = 3) {
|
|
|
6365
6605
|
return `${out.join("\n")}
|
|
6366
6606
|
`;
|
|
6367
6607
|
}
|
|
6368
|
-
var posix = (p6) => p6.split(
|
|
6608
|
+
var posix = (p6) => p6.split(path22__default.sep).join("/");
|
|
6369
6609
|
function colorizeDiff(diff) {
|
|
6370
6610
|
return diff.split("\n").map((line) => {
|
|
6371
6611
|
if (line.startsWith("+++") || line.startsWith("---")) return S.bold(line);
|
|
@@ -6376,7 +6616,7 @@ function colorizeDiff(diff) {
|
|
|
6376
6616
|
}).join("\n");
|
|
6377
6617
|
}
|
|
6378
6618
|
function renderChange(change, base) {
|
|
6379
|
-
const rel = (p6) => posix(
|
|
6619
|
+
const rel = (p6) => posix(path22__default.relative(base, p6) || path22__default.basename(p6));
|
|
6380
6620
|
switch (change.type) {
|
|
6381
6621
|
case "write":
|
|
6382
6622
|
return unifiedDiff(
|
|
@@ -6403,7 +6643,7 @@ ${diff}`;
|
|
|
6403
6643
|
}
|
|
6404
6644
|
}
|
|
6405
6645
|
function changeLabel(change, base) {
|
|
6406
|
-
const rel = (p6) => posix(
|
|
6646
|
+
const rel = (p6) => posix(path22__default.relative(base, p6) || path22__default.basename(p6));
|
|
6407
6647
|
switch (change.type) {
|
|
6408
6648
|
case "write":
|
|
6409
6649
|
return `modify ${rel(change.path)}`;
|
|
@@ -6463,7 +6703,7 @@ function loadAsset(projectDir, id, ref) {
|
|
|
6463
6703
|
)
|
|
6464
6704
|
};
|
|
6465
6705
|
}
|
|
6466
|
-
const manifestPath =
|
|
6706
|
+
const manifestPath = path22__default.join(dir, AGENT_MANIFEST_FILE);
|
|
6467
6707
|
let text;
|
|
6468
6708
|
try {
|
|
6469
6709
|
text = fs8__default.readFileSync(manifestPath, "utf-8");
|
|
@@ -6650,7 +6890,7 @@ function findManifestCandidates(rootPath) {
|
|
|
6650
6890
|
return;
|
|
6651
6891
|
}
|
|
6652
6892
|
for (const entry of entries) {
|
|
6653
|
-
const fullPath =
|
|
6893
|
+
const fullPath = path22__default.join(dir, entry.name);
|
|
6654
6894
|
if (entry.isDirectory()) {
|
|
6655
6895
|
if (!SKIP_DIRS.has(entry.name)) walk(fullPath);
|
|
6656
6896
|
} else if (entry.isFile()) {
|
|
@@ -6670,7 +6910,7 @@ function parseManifestCandidate(c, absRoot) {
|
|
|
6670
6910
|
const content = fs8__default.readFileSync(c.filePath, "utf-8");
|
|
6671
6911
|
const res = parseManifestFile(c.filePath, content);
|
|
6672
6912
|
if (!res.ok) {
|
|
6673
|
-
logErr(`${
|
|
6913
|
+
logErr(`${path22__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 parse error: ${res.reason}`);
|
|
6674
6914
|
return { kind: "error" };
|
|
6675
6915
|
}
|
|
6676
6916
|
return {
|
|
@@ -6699,17 +6939,24 @@ function checkComposeKinds(parsed, registry) {
|
|
|
6699
6939
|
});
|
|
6700
6940
|
return diagnostics;
|
|
6701
6941
|
}
|
|
6942
|
+
function libraryRootOf(absRoot) {
|
|
6943
|
+
for (let dir = absRoot; ; dir = path22__default.dirname(dir)) {
|
|
6944
|
+
if (fs8__default.existsSync(path22__default.join(dir, SKAILE_MANIFEST_FILENAME))) return dir;
|
|
6945
|
+
if (path22__default.dirname(dir) === dir) return absRoot;
|
|
6946
|
+
}
|
|
6947
|
+
}
|
|
6702
6948
|
function validateManifestCandidate(c, parsed, body, absRoot, registry, strictConformance) {
|
|
6703
|
-
const relPath =
|
|
6949
|
+
const relPath = path22__default.relative(absRoot, c.filePath);
|
|
6704
6950
|
let errors = 0;
|
|
6705
6951
|
let warnings = 0;
|
|
6706
|
-
const dirName =
|
|
6952
|
+
const dirName = path22__default.basename(path22__default.dirname(c.filePath));
|
|
6707
6953
|
const checked = checkAsset(
|
|
6708
6954
|
c.kind,
|
|
6709
6955
|
parsed ?? {},
|
|
6710
6956
|
body,
|
|
6711
6957
|
dirName,
|
|
6712
|
-
registry
|
|
6958
|
+
registry,
|
|
6959
|
+
fs8__default.readFileSync(c.filePath, "utf-8")
|
|
6713
6960
|
);
|
|
6714
6961
|
for (const f of checked.errors) {
|
|
6715
6962
|
logErr(`${relPath} [${f.tag}] \u2014 ${f.text}`);
|
|
@@ -6725,7 +6972,17 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
|
|
|
6725
6972
|
warnings++;
|
|
6726
6973
|
}
|
|
6727
6974
|
}
|
|
6728
|
-
if (c.kind === "agent" &&
|
|
6975
|
+
if (c.kind === "agent" && parsed !== null && typeof parsed === "object") {
|
|
6976
|
+
for (const f of checkAgentFiles(
|
|
6977
|
+
parsed,
|
|
6978
|
+
path22__default.dirname(c.filePath),
|
|
6979
|
+
libraryRootOf(absRoot)
|
|
6980
|
+
)) {
|
|
6981
|
+
logErr(`${relPath} [${f.tag}] \u2014 ${f.text}`);
|
|
6982
|
+
errors++;
|
|
6983
|
+
}
|
|
6984
|
+
}
|
|
6985
|
+
if (c.kind === "agent" && path22__default.basename(c.filePath) === "agent.yaml") {
|
|
6729
6986
|
for (const d of [
|
|
6730
6987
|
...checkComposeKinds(parsed, registry),
|
|
6731
6988
|
...composeSlotDiagnostics(parsed),
|
|
@@ -6744,7 +7001,7 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
|
|
|
6744
7001
|
return { errors, warnings };
|
|
6745
7002
|
}
|
|
6746
7003
|
function validateManifests(rootPath, strictConformance) {
|
|
6747
|
-
const absRoot =
|
|
7004
|
+
const absRoot = path22__default.resolve(rootPath);
|
|
6748
7005
|
if (!fs8__default.existsSync(absRoot)) {
|
|
6749
7006
|
logErr(`Path does not exist: ${absRoot}`);
|
|
6750
7007
|
return { total: 0, errors: 1, warnings: 0 };
|
|
@@ -6754,6 +7011,7 @@ function validateManifests(rootPath, strictConformance) {
|
|
|
6754
7011
|
let errors = 0;
|
|
6755
7012
|
let warnings = 0;
|
|
6756
7013
|
const seenIdentity = /* @__PURE__ */ new Map();
|
|
7014
|
+
const agentsToResolve = [];
|
|
6757
7015
|
for (const c of candidates) {
|
|
6758
7016
|
const parseResult = parseManifestCandidate(c, absRoot);
|
|
6759
7017
|
if (parseResult.kind === "error") {
|
|
@@ -6770,22 +7028,36 @@ function validateManifests(rootPath, strictConformance) {
|
|
|
6770
7028
|
);
|
|
6771
7029
|
errors += delta.errors;
|
|
6772
7030
|
warnings += delta.warnings;
|
|
7031
|
+
if (c.kind === "agent" && parseResult.parsed !== null && typeof parseResult.parsed === "object") {
|
|
7032
|
+
agentsToResolve.push({
|
|
7033
|
+
relPath: path22__default.relative(absRoot, c.filePath),
|
|
7034
|
+
parsed: parseResult.parsed
|
|
7035
|
+
});
|
|
7036
|
+
}
|
|
6773
7037
|
const obj = parseResult.parsed;
|
|
6774
7038
|
const identity = obj && typeof obj === "object" ? obj[c.kind === "flow" ? "id" : "name"] : null;
|
|
6775
7039
|
if (typeof identity === "string" && identity.length > 0) {
|
|
6776
|
-
const dir =
|
|
7040
|
+
const dir = path22__default.dirname(c.filePath);
|
|
6777
7041
|
const key = `${c.kind}:${identity}`;
|
|
6778
7042
|
const first = seenIdentity.get(key);
|
|
6779
7043
|
if (first === void 0) {
|
|
6780
7044
|
seenIdentity.set(key, dir);
|
|
6781
7045
|
} else if (first !== dir) {
|
|
6782
7046
|
logErr(
|
|
6783
|
-
`${
|
|
7047
|
+
`${path22__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 ${key} is also defined in ${path22__default.relative(absRoot, first) || "."}; two directories cannot share a kind and name (\`skaile library index\` keeps only the first).`
|
|
6784
7048
|
);
|
|
6785
7049
|
errors++;
|
|
6786
7050
|
}
|
|
6787
7051
|
}
|
|
6788
7052
|
}
|
|
7053
|
+
const libraryPublisher = loadSkPublishManifest(libraryRootOf(absRoot))?.publisher;
|
|
7054
|
+
const hasAsset = (kind, name) => seenIdentity.has(`${kind}:${name}`);
|
|
7055
|
+
for (const agent of agentsToResolve) {
|
|
7056
|
+
for (const f of agentComposeRefAdvisories(agent.parsed, hasAsset, libraryPublisher)) {
|
|
7057
|
+
logWarn(`${agent.relPath} [${f.tag}] \u2014 ${f.text}`);
|
|
7058
|
+
warnings++;
|
|
7059
|
+
}
|
|
7060
|
+
}
|
|
6789
7061
|
return { total: candidates.length, errors, warnings };
|
|
6790
7062
|
}
|
|
6791
7063
|
function findWorkspaceManifests(rootPath) {
|
|
@@ -6798,7 +7070,7 @@ function findWorkspaceManifests(rootPath) {
|
|
|
6798
7070
|
return;
|
|
6799
7071
|
}
|
|
6800
7072
|
for (const entry of entries) {
|
|
6801
|
-
const full =
|
|
7073
|
+
const full = path22__default.join(dir, entry.name);
|
|
6802
7074
|
if (entry.isDirectory()) {
|
|
6803
7075
|
if (!SKIP_DIRS.has(entry.name)) walk(full);
|
|
6804
7076
|
} else if (entry.isFile() && /(^|\.)skaile\.yaml$/.test(entry.name)) {
|
|
@@ -6861,11 +7133,11 @@ function validateWorkspaceAssets(parsed, relPath) {
|
|
|
6861
7133
|
return errors;
|
|
6862
7134
|
}
|
|
6863
7135
|
function validateWorkspaceManifests(rootPath) {
|
|
6864
|
-
const absRoot =
|
|
7136
|
+
const absRoot = path22__default.resolve(rootPath);
|
|
6865
7137
|
const files = findWorkspaceManifests(absRoot);
|
|
6866
7138
|
let errors = 0;
|
|
6867
7139
|
for (const file of files) {
|
|
6868
|
-
const relPath =
|
|
7140
|
+
const relPath = path22__default.relative(absRoot, file);
|
|
6869
7141
|
let parsed;
|
|
6870
7142
|
try {
|
|
6871
7143
|
parsed = parse(fs8__default.readFileSync(file, "utf-8")) ?? {};
|
|
@@ -6876,7 +7148,7 @@ function validateWorkspaceManifests(rootPath) {
|
|
|
6876
7148
|
}
|
|
6877
7149
|
errors += validateWorkspaceRefs(collectWorkspaceRefFields(parsed), relPath);
|
|
6878
7150
|
errors += validateWorkspaceAssets(parsed, relPath);
|
|
6879
|
-
for (const d of checkAgentInstances(
|
|
7151
|
+
for (const d of checkAgentInstances(path22__default.dirname(file), parsed)) {
|
|
6880
7152
|
const line = `${relPath} [agents] \u2014 ${d.code}: ${d.path ? `${d.path}: ` : ""}${d.message}`;
|
|
6881
7153
|
if (d.severity === "error") {
|
|
6882
7154
|
logErr(line);
|
|
@@ -6885,11 +7157,16 @@ function validateWorkspaceManifests(rootPath) {
|
|
|
6885
7157
|
logWarn(line);
|
|
6886
7158
|
}
|
|
6887
7159
|
}
|
|
7160
|
+
for (const d of decodeSkaileYaml(fs8__default.readFileSync(file, "utf-8")).diagnostics) {
|
|
7161
|
+
if (d.code !== "connector_missing_driver") continue;
|
|
7162
|
+
logErr(`${relPath} [connectors] \u2014 ${d.code}: ${d.path ? `${d.path}: ` : ""}${d.message}`);
|
|
7163
|
+
errors++;
|
|
7164
|
+
}
|
|
6888
7165
|
}
|
|
6889
7166
|
return { total: files.length, errors };
|
|
6890
7167
|
}
|
|
6891
7168
|
function validatePublishManifestRoots(rootPath) {
|
|
6892
|
-
const absRoot =
|
|
7169
|
+
const absRoot = path22__default.resolve(rootPath);
|
|
6893
7170
|
const manifest = loadSkPublishManifest(absRoot);
|
|
6894
7171
|
if (!manifest) return 0;
|
|
6895
7172
|
const missing = missingRootAssets(absRoot, manifest);
|
|
@@ -6901,7 +7178,7 @@ function validatePublishManifestRoots(rootPath) {
|
|
|
6901
7178
|
return missing.length;
|
|
6902
7179
|
}
|
|
6903
7180
|
function validatePublishManifestRequires(rootPath) {
|
|
6904
|
-
const problems = manifestRequiresProblems(
|
|
7181
|
+
const problems = manifestRequiresProblems(path22__default.resolve(rootPath));
|
|
6905
7182
|
for (const p6 of problems) {
|
|
6906
7183
|
logErr(
|
|
6907
7184
|
`${SKAILE_MANIFEST_FILENAME} [assets] \u2014 ${p6.asset}: ${p6.message}. Use the \`kind:@<publisher>/name[#version]\` form.`
|
|
@@ -6910,18 +7187,27 @@ function validatePublishManifestRequires(rootPath) {
|
|
|
6910
7187
|
return problems.length;
|
|
6911
7188
|
}
|
|
6912
7189
|
function validatePublishManifestPublisherSlugs(rootPath) {
|
|
6913
|
-
const problems = manifestPublisherProblems(
|
|
7190
|
+
const problems = manifestPublisherProblems(path22__default.resolve(rootPath));
|
|
6914
7191
|
for (const message of problems) logErr(message);
|
|
6915
7192
|
return problems.length;
|
|
6916
7193
|
}
|
|
7194
|
+
function validatePublishManifestParses(rootPath) {
|
|
7195
|
+
try {
|
|
7196
|
+
assertManifestEditable(path22__default.resolve(rootPath));
|
|
7197
|
+
return 0;
|
|
7198
|
+
} catch (err2) {
|
|
7199
|
+
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
7200
|
+
return 1;
|
|
7201
|
+
}
|
|
7202
|
+
}
|
|
6917
7203
|
function validatePublishManifestVersions(rootPath) {
|
|
6918
|
-
const absRoot =
|
|
7204
|
+
const absRoot = path22__default.resolve(rootPath);
|
|
6919
7205
|
const manifest = loadSkPublishManifest(absRoot);
|
|
6920
7206
|
if (!manifest || manifest.source) return 0;
|
|
6921
7207
|
let warnings = 0;
|
|
6922
7208
|
for (const a of manifest.assets ?? []) {
|
|
6923
7209
|
if (!a.root || a.source || !a.version) continue;
|
|
6924
|
-
const file = findAssetManifestFile(
|
|
7210
|
+
const file = findAssetManifestFile(path22__default.join(absRoot, a.root), a.kind, a.name);
|
|
6925
7211
|
if (!file) continue;
|
|
6926
7212
|
const res = parseManifestFile(file, fs8__default.readFileSync(file, "utf-8"));
|
|
6927
7213
|
if (!res.ok) continue;
|
|
@@ -6931,7 +7217,7 @@ function validatePublishManifestVersions(rootPath) {
|
|
|
6931
7217
|
manifestVersionMismatchMessage(
|
|
6932
7218
|
assetEntryRef(a, manifest),
|
|
6933
7219
|
a.version,
|
|
6934
|
-
toPosix(
|
|
7220
|
+
toPosix(path22__default.relative(absRoot, file)),
|
|
6935
7221
|
fileVersion
|
|
6936
7222
|
)
|
|
6937
7223
|
);
|
|
@@ -6940,7 +7226,7 @@ function validatePublishManifestVersions(rootPath) {
|
|
|
6940
7226
|
return warnings;
|
|
6941
7227
|
}
|
|
6942
7228
|
function validatePublishManifestPublishers(rootPath) {
|
|
6943
|
-
const absRoot =
|
|
7229
|
+
const absRoot = path22__default.resolve(rootPath);
|
|
6944
7230
|
const manifest = loadSkPublishManifest(absRoot);
|
|
6945
7231
|
if (!manifest || manifest.source) return 0;
|
|
6946
7232
|
const bare = (p6) => p6.trim().replace(/^@/, "");
|
|
@@ -6948,7 +7234,7 @@ function validatePublishManifestPublishers(rootPath) {
|
|
|
6948
7234
|
for (const a of manifest.assets ?? []) {
|
|
6949
7235
|
const resolved = a.publisher ?? manifest.publisher;
|
|
6950
7236
|
if (!a.root || a.source || !resolved) continue;
|
|
6951
|
-
const file = findAssetManifestFile(
|
|
7237
|
+
const file = findAssetManifestFile(path22__default.join(absRoot, a.root), a.kind, a.name);
|
|
6952
7238
|
if (!file) continue;
|
|
6953
7239
|
const res = parseManifestFile(file, fs8__default.readFileSync(file, "utf-8"));
|
|
6954
7240
|
if (!res.ok) continue;
|
|
@@ -6956,7 +7242,7 @@ function validatePublishManifestPublishers(rootPath) {
|
|
|
6956
7242
|
const declared = meta !== null && typeof meta === "object" ? meta.publisher : null;
|
|
6957
7243
|
if (typeof declared !== "string" || bare(declared) === bare(resolved)) continue;
|
|
6958
7244
|
logWarn(
|
|
6959
|
-
`${toPosix(
|
|
7245
|
+
`${toPosix(path22__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}.`
|
|
6960
7246
|
);
|
|
6961
7247
|
warnings++;
|
|
6962
7248
|
}
|
|
@@ -6964,7 +7250,7 @@ function validatePublishManifestPublishers(rootPath) {
|
|
|
6964
7250
|
}
|
|
6965
7251
|
var EXCLUDED_PATHS = ["skaileup-shared/", "external/", "docs/"];
|
|
6966
7252
|
function toPosix(p6) {
|
|
6967
|
-
return p6.split(
|
|
7253
|
+
return p6.split(path22__default.sep).join("/");
|
|
6968
7254
|
}
|
|
6969
7255
|
function isExcludedPath(relPath) {
|
|
6970
7256
|
const rel = toPosix(relPath);
|
|
@@ -6980,8 +7266,8 @@ var VERSIONED_KINDS = {
|
|
|
6980
7266
|
};
|
|
6981
7267
|
function readAssetVersion(c) {
|
|
6982
7268
|
const kind = c.kind;
|
|
6983
|
-
const fileName =
|
|
6984
|
-
const dirName =
|
|
7269
|
+
const fileName = path22__default.basename(c.filePath);
|
|
7270
|
+
const dirName = path22__default.basename(path22__default.dirname(c.filePath));
|
|
6985
7271
|
const content = fs8__default.readFileSync(c.filePath, "utf-8");
|
|
6986
7272
|
if (c.filePath.endsWith(".md")) {
|
|
6987
7273
|
const res = parseManifestFile(c.filePath, content);
|
|
@@ -7020,21 +7306,21 @@ function collectAssetVersions(root) {
|
|
|
7020
7306
|
for (const c of findManifestCandidates(root)) {
|
|
7021
7307
|
if (!VERSIONED_KINDS[c.kind]) continue;
|
|
7022
7308
|
if (c.filePath.endsWith(".flow.json")) continue;
|
|
7023
|
-
if (isExcludedPath(
|
|
7309
|
+
if (isExcludedPath(path22__default.relative(root, c.filePath))) continue;
|
|
7024
7310
|
assets.push(readAssetVersion(c));
|
|
7025
7311
|
}
|
|
7026
7312
|
return assets;
|
|
7027
7313
|
}
|
|
7028
7314
|
function assetLocation(a, root) {
|
|
7029
|
-
return toPosix(
|
|
7315
|
+
return toPosix(path22__default.relative(root, a.filePath));
|
|
7030
7316
|
}
|
|
7031
7317
|
function findChangelogUnit(assetRelPath, root) {
|
|
7032
|
-
let dir =
|
|
7318
|
+
let dir = path22__default.posix.dirname(toPosix(assetRelPath));
|
|
7033
7319
|
for (; ; ) {
|
|
7034
7320
|
const candidate = dir === "." ? "CHANGELOG.md" : `${dir}/CHANGELOG.md`;
|
|
7035
|
-
if (fs8__default.existsSync(
|
|
7321
|
+
if (fs8__default.existsSync(path22__default.join(root, candidate))) return candidate;
|
|
7036
7322
|
if (dir === ".") return null;
|
|
7037
|
-
dir =
|
|
7323
|
+
dir = path22__default.posix.dirname(dir);
|
|
7038
7324
|
}
|
|
7039
7325
|
}
|
|
7040
7326
|
function checkChangelogUnits(modifiedFiles, root) {
|
|
@@ -7084,7 +7370,7 @@ function checkVersionBumps(assets, root) {
|
|
|
7084
7370
|
let warnings = 0;
|
|
7085
7371
|
for (const a of assets) {
|
|
7086
7372
|
if (!a.version) continue;
|
|
7087
|
-
const relPath = toPosix(
|
|
7373
|
+
const relPath = toPosix(path22__default.relative(root, a.filePath));
|
|
7088
7374
|
try {
|
|
7089
7375
|
const headContent = execFileSync("git", ["show", `HEAD:./${relPath}`], {
|
|
7090
7376
|
cwd: root,
|
|
@@ -7117,7 +7403,7 @@ function checkFlowVersionPins(assets, root) {
|
|
|
7117
7403
|
pins = flowSkillVersionPins(loadFlow(f.filePath));
|
|
7118
7404
|
} catch (err2) {
|
|
7119
7405
|
logWarn(
|
|
7120
|
-
`flow:${f.name} (${
|
|
7406
|
+
`flow:${f.name} (${path22__default.relative(root, f.filePath)}) \u2014 could not be read: ${err2 instanceof Error ? err2.message : err2}`
|
|
7121
7407
|
);
|
|
7122
7408
|
warnings++;
|
|
7123
7409
|
continue;
|
|
@@ -7135,19 +7421,34 @@ function checkFlowVersionPins(assets, root) {
|
|
|
7135
7421
|
}
|
|
7136
7422
|
function resolveCheckRoot(pathArg) {
|
|
7137
7423
|
if (pathArg) {
|
|
7138
|
-
const abs =
|
|
7424
|
+
const abs = path22__default.resolve(pathArg);
|
|
7139
7425
|
if (!fs8__default.existsSync(abs)) {
|
|
7140
7426
|
logErr(`Path does not exist: ${abs}`);
|
|
7141
7427
|
return null;
|
|
7142
7428
|
}
|
|
7143
7429
|
return abs;
|
|
7144
7430
|
}
|
|
7145
|
-
for (let dir = process.cwd(); ; dir =
|
|
7146
|
-
if (fs8__default.existsSync(
|
|
7147
|
-
if (
|
|
7431
|
+
for (let dir = process.cwd(); ; dir = path22__default.dirname(dir)) {
|
|
7432
|
+
if (fs8__default.existsSync(path22__default.join(dir, SKAILE_MANIFEST_FILENAME))) return dir;
|
|
7433
|
+
if (path22__default.dirname(dir) === dir) return AI_RESOURCES;
|
|
7434
|
+
}
|
|
7435
|
+
}
|
|
7436
|
+
function isInGitWorkTree(root) {
|
|
7437
|
+
try {
|
|
7438
|
+
return execFileSync("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
7439
|
+
cwd: root,
|
|
7440
|
+
encoding: "utf-8",
|
|
7441
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
7442
|
+
}).trim() === "true";
|
|
7443
|
+
} catch {
|
|
7444
|
+
return false;
|
|
7148
7445
|
}
|
|
7149
7446
|
}
|
|
7150
|
-
function changedFiles(root, ref) {
|
|
7447
|
+
function changedFiles(root, ref, what, opts = {}) {
|
|
7448
|
+
if (!isInGitWorkTree(root)) {
|
|
7449
|
+
logErr(`${what} needs a git repository: ${root} is not inside a git work tree.`);
|
|
7450
|
+
return null;
|
|
7451
|
+
}
|
|
7151
7452
|
try {
|
|
7152
7453
|
const out = execFileSync(
|
|
7153
7454
|
"git",
|
|
@@ -7158,7 +7459,16 @@ function changedFiles(root, ref) {
|
|
|
7158
7459
|
stdio: ["ignore", "pipe", "pipe"]
|
|
7159
7460
|
}
|
|
7160
7461
|
);
|
|
7161
|
-
|
|
7462
|
+
const changed = out.trim().split("\n").filter(Boolean);
|
|
7463
|
+
if (opts.untracked) {
|
|
7464
|
+
const fresh = execFileSync("git", ["ls-files", "--others", "--exclude-standard"], {
|
|
7465
|
+
cwd: root,
|
|
7466
|
+
encoding: "utf-8",
|
|
7467
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
7468
|
+
});
|
|
7469
|
+
changed.push(...fresh.trim().split("\n").filter(Boolean));
|
|
7470
|
+
}
|
|
7471
|
+
return changed;
|
|
7162
7472
|
} catch (err2) {
|
|
7163
7473
|
const stderr = err2 instanceof Error && "stderr" in err2 ? String(err2.stderr).trim() : "";
|
|
7164
7474
|
const reason = (stderr || (err2 instanceof Error ? err2.message : String(err2))).split("\n")[0];
|
|
@@ -7166,6 +7476,22 @@ function changedFiles(root, ref) {
|
|
|
7166
7476
|
return null;
|
|
7167
7477
|
}
|
|
7168
7478
|
}
|
|
7479
|
+
function assetOwnDir(a) {
|
|
7480
|
+
const dir = path22__default.dirname(a.filePath);
|
|
7481
|
+
if (["skill", "agent", "contract"].includes(a.kind) || path22__default.basename(dir) === a.name) return dir;
|
|
7482
|
+
return null;
|
|
7483
|
+
}
|
|
7484
|
+
function assetChanged(a, changedAbs) {
|
|
7485
|
+
if (changedAbs.has(a.filePath)) return true;
|
|
7486
|
+
const dir = assetOwnDir(a);
|
|
7487
|
+
if (dir === null) return false;
|
|
7488
|
+
for (const f of changedAbs) {
|
|
7489
|
+
const rel = path22__default.relative(dir, f);
|
|
7490
|
+
if (rel.startsWith("..") || path22__default.isAbsolute(rel)) continue;
|
|
7491
|
+
if (!isNonAssetPath(toPosix(rel))) return true;
|
|
7492
|
+
}
|
|
7493
|
+
return false;
|
|
7494
|
+
}
|
|
7169
7495
|
function runVersionsCheck(pathArg, opts) {
|
|
7170
7496
|
const root = resolveCheckRoot(pathArg);
|
|
7171
7497
|
if (root === null) {
|
|
@@ -7174,13 +7500,13 @@ function runVersionsCheck(pathArg, opts) {
|
|
|
7174
7500
|
}
|
|
7175
7501
|
let assets = collectAssetVersions(root);
|
|
7176
7502
|
if (opts.changedOnly) {
|
|
7177
|
-
const changed = changedFiles(root, "HEAD");
|
|
7503
|
+
const changed = changedFiles(root, "HEAD", "--changed-only", { untracked: true });
|
|
7178
7504
|
if (changed === null) {
|
|
7179
7505
|
process.exit(1);
|
|
7180
7506
|
return;
|
|
7181
7507
|
}
|
|
7182
|
-
const changedAbs = new Set(changed.map((f) =>
|
|
7183
|
-
assets = assets.filter((a) =>
|
|
7508
|
+
const changedAbs = new Set(changed.map((f) => path22__default.resolve(root, f)));
|
|
7509
|
+
assets = assets.filter((a) => assetChanged(a, changedAbs));
|
|
7184
7510
|
}
|
|
7185
7511
|
logInfo(`Checking versions in ${root}`);
|
|
7186
7512
|
const versionCheck = checkAssetVersions(assets, root);
|
|
@@ -7212,7 +7538,7 @@ function makeValidateCommand() {
|
|
|
7212
7538
|
"--strict-conformance",
|
|
7213
7539
|
"Treat Agent Skills (agentskills.io) standard findings as errors"
|
|
7214
7540
|
).action(async (targetPath, opts) => {
|
|
7215
|
-
const absPath =
|
|
7541
|
+
const absPath = path22__default.resolve(targetPath);
|
|
7216
7542
|
logInfo(`Validating manifests in ${absPath}`);
|
|
7217
7543
|
const { total, errors, warnings } = validateManifests(
|
|
7218
7544
|
absPath,
|
|
@@ -7221,13 +7547,14 @@ function makeValidateCommand() {
|
|
|
7221
7547
|
const ws = validateWorkspaceManifests(absPath);
|
|
7222
7548
|
const rootErrors = validatePublishManifestRoots(absPath);
|
|
7223
7549
|
const slugErrors = validatePublishManifestPublisherSlugs(absPath);
|
|
7550
|
+
const parseErrors = validatePublishManifestParses(absPath);
|
|
7224
7551
|
const requiresErrors = validatePublishManifestRequires(absPath);
|
|
7225
7552
|
const versionWarnings = validatePublishManifestVersions(absPath);
|
|
7226
7553
|
const publisherWarnings = validatePublishManifestPublishers(absPath);
|
|
7227
7554
|
const dependencyProblems = await unresolvedManifestDependencies(absPath);
|
|
7228
7555
|
for (const w of dependencyProblems) logWarn(w);
|
|
7229
7556
|
const dependencyWarnings = dependencyProblems.length;
|
|
7230
|
-
const totalErrors = errors + ws.errors + rootErrors + slugErrors + requiresErrors;
|
|
7557
|
+
const totalErrors = errors + ws.errors + rootErrors + slugErrors + parseErrors + requiresErrors;
|
|
7231
7558
|
console.log();
|
|
7232
7559
|
warnIgnoredDomainFiles(absPath);
|
|
7233
7560
|
warnLegacyBundleFiles(absPath);
|
|
@@ -7253,7 +7580,7 @@ function makeValidateCommand() {
|
|
|
7253
7580
|
process.exit(1);
|
|
7254
7581
|
return;
|
|
7255
7582
|
}
|
|
7256
|
-
const modifiedFiles = changedFiles(root, opts.base);
|
|
7583
|
+
const modifiedFiles = changedFiles(root, opts.base, "changelog");
|
|
7257
7584
|
if (modifiedFiles === null) {
|
|
7258
7585
|
process.exit(1);
|
|
7259
7586
|
return;
|
|
@@ -7302,7 +7629,7 @@ function itemFromRef(raw, defaultKind, ctx) {
|
|
|
7302
7629
|
return { kind: prefixed[1], ref: value };
|
|
7303
7630
|
}
|
|
7304
7631
|
if (PATH_LIKE.test(value)) return { kind: defaultKind, ref: value };
|
|
7305
|
-
if (defaultKind === "skill" && !value.includes("/") && existsSync(
|
|
7632
|
+
if (defaultKind === "skill" && !value.includes("/") && existsSync(path22__default.join(ctx.agentDir, "skills", value, "SKILL.md"))) {
|
|
7306
7633
|
return { kind: "skill", ref: `./skills/${value}` };
|
|
7307
7634
|
}
|
|
7308
7635
|
return { kind: defaultKind, ref: `${defaultKind}:${value}` };
|
|
@@ -7438,7 +7765,7 @@ function migrateAgentYaml(source, options) {
|
|
|
7438
7765
|
manual.push("metadata.soul: not a string; left unchanged");
|
|
7439
7766
|
continue;
|
|
7440
7767
|
}
|
|
7441
|
-
if (
|
|
7768
|
+
if (path22__default.posix.basename(soul.replace(/\\/g, "/")).toLowerCase() === "soul.md") {
|
|
7442
7769
|
notes.push("metadata.soul \u2192 dropped (SOUL.md is a convention file)");
|
|
7443
7770
|
} else {
|
|
7444
7771
|
derived.push({ kind: "persona", ref: soul });
|
|
@@ -7672,7 +7999,7 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7672
7999
|
if (!isMap(agentNode)) return void 0;
|
|
7673
8000
|
const subNode = agentNode.get("subagents", true);
|
|
7674
8001
|
if (!isMap(subNode)) return void 0;
|
|
7675
|
-
const dir =
|
|
8002
|
+
const dir = path22__default.dirname(skaileYamlPath);
|
|
7676
8003
|
const notes = [];
|
|
7677
8004
|
const manual = [];
|
|
7678
8005
|
const changes = [];
|
|
@@ -7690,10 +8017,10 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7690
8017
|
continue;
|
|
7691
8018
|
}
|
|
7692
8019
|
const id = instanceId(name);
|
|
7693
|
-
const assetDir =
|
|
8020
|
+
const assetDir = path22__default.join(dir, ".skaile", "agents", id);
|
|
7694
8021
|
if (takenIds.has(id) || existsSync(assetDir)) {
|
|
7695
8022
|
manual.push(
|
|
7696
|
-
`agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${
|
|
8023
|
+
`agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${path22__default.relative(dir, assetDir)} already exists`}; left in place`
|
|
7697
8024
|
);
|
|
7698
8025
|
continue;
|
|
7699
8026
|
}
|
|
@@ -7717,13 +8044,13 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7717
8044
|
manifest.tools = { ...allowed ? { allowed } : {}, ...denied ? { denied } : {} };
|
|
7718
8045
|
}
|
|
7719
8046
|
const text = stringify(manifest, { lineWidth: 0 });
|
|
7720
|
-
const manifestPath =
|
|
8047
|
+
const manifestPath = path22__default.join(assetDir, "agent.yaml");
|
|
7721
8048
|
changes.push({ type: "create", path: manifestPath, after: text });
|
|
7722
8049
|
assetManifests.push({ file: manifestPath, text });
|
|
7723
8050
|
if (typeof spec.prompt === "string" && spec.prompt.trim() !== "") {
|
|
7724
8051
|
changes.push({
|
|
7725
8052
|
type: "create",
|
|
7726
|
-
path:
|
|
8053
|
+
path: path22__default.join(assetDir, "SOUL.md"),
|
|
7727
8054
|
after: `${spec.prompt.replace(/\s+$/, "")}
|
|
7728
8055
|
`
|
|
7729
8056
|
});
|
|
@@ -7782,7 +8109,7 @@ function validateMigratedAgent(text, registry) {
|
|
|
7782
8109
|
function collectAgentFiles(paths) {
|
|
7783
8110
|
const files = /* @__PURE__ */ new Set();
|
|
7784
8111
|
for (const input of paths) {
|
|
7785
|
-
const abs =
|
|
8112
|
+
const abs = path22__default.resolve(input);
|
|
7786
8113
|
if (!existsSync(abs)) continue;
|
|
7787
8114
|
if (statSync(abs).isDirectory()) {
|
|
7788
8115
|
for (const f of walkFiles(abs, (b) => b === "agent.yaml" || b === "skaile.yaml"))
|
|
@@ -7799,7 +8126,7 @@ function planAgentMigration(options) {
|
|
|
7799
8126
|
const reports = [];
|
|
7800
8127
|
for (const file of collectAgentFiles(options.paths)) {
|
|
7801
8128
|
const source = readText(file);
|
|
7802
|
-
const base =
|
|
8129
|
+
const base = path22__default.basename(file);
|
|
7803
8130
|
if (base === "skaile.yaml") {
|
|
7804
8131
|
const result = migrateSubagents(file, source);
|
|
7805
8132
|
if (!result) continue;
|
|
@@ -7807,7 +8134,7 @@ function planAgentMigration(options) {
|
|
|
7807
8134
|
for (const asset of result.assetManifests) {
|
|
7808
8135
|
const v = validateMigratedAgent(asset.text, options.registry);
|
|
7809
8136
|
validation2.errors.push(
|
|
7810
|
-
...v.errors.map((e) => `${
|
|
8137
|
+
...v.errors.map((e) => `${path22__default.basename(path22__default.dirname(asset.file))}: ${e}`)
|
|
7811
8138
|
);
|
|
7812
8139
|
validation2.warnings.push(...v.warnings);
|
|
7813
8140
|
}
|
|
@@ -7835,7 +8162,7 @@ function planAgentMigration(options) {
|
|
|
7835
8162
|
});
|
|
7836
8163
|
continue;
|
|
7837
8164
|
}
|
|
7838
|
-
migration = migrateAgentYaml(source, { agentDir:
|
|
8165
|
+
migration = migrateAgentYaml(source, { agentDir: path22__default.dirname(file), knownKinds });
|
|
7839
8166
|
} catch (error) {
|
|
7840
8167
|
reports.push({
|
|
7841
8168
|
file,
|
|
@@ -7865,7 +8192,7 @@ function planAgentMigration(options) {
|
|
|
7865
8192
|
var DEFAULT_PUBLISHER = "skaile-ai";
|
|
7866
8193
|
var PRESET_DEFAULT_VERSION = "1.0.0";
|
|
7867
8194
|
var FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
7868
|
-
var posix2 = (p6) => p6.split(
|
|
8195
|
+
var posix2 = (p6) => p6.split(path22__default.sep).join("/");
|
|
7869
8196
|
var MOVED_KINDS = { persona: "PERSONA.md", ruleset: "RULESET.md" };
|
|
7870
8197
|
var KIND_MANIFEST_FILES = /* @__PURE__ */ new Set(["PERSONA.md", "RULESET.md", "SKILL.md"]);
|
|
7871
8198
|
function readFrontmatterType(text) {
|
|
@@ -7896,14 +8223,14 @@ function planMarkdownMoves(root, knownKinds, manual, unknownTypes) {
|
|
|
7896
8223
|
if (!text.startsWith("---")) continue;
|
|
7897
8224
|
const found = readFrontmatterType(text);
|
|
7898
8225
|
if (!found) continue;
|
|
7899
|
-
const base =
|
|
7900
|
-
const inAgentParts = file.split(
|
|
8226
|
+
const base = path22__default.basename(file);
|
|
8227
|
+
const inAgentParts = file.split(path22__default.sep).includes("_agent-parts");
|
|
7901
8228
|
const targetName = MOVED_KINDS[found.type];
|
|
7902
8229
|
if (targetName !== void 0 && !KIND_MANIFEST_FILES.has(base)) {
|
|
7903
|
-
const to =
|
|
8230
|
+
const to = path22__default.join(path22__default.dirname(file), base.replace(/\.md$/i, ""), targetName);
|
|
7904
8231
|
if (existsSync(to) || targets.has(to)) {
|
|
7905
8232
|
manual.push(
|
|
7906
|
-
`${posix2(
|
|
8233
|
+
`${posix2(path22__default.relative(root, file))}: ${posix2(path22__default.relative(root, to))} already exists; not moved`
|
|
7907
8234
|
);
|
|
7908
8235
|
continue;
|
|
7909
8236
|
}
|
|
@@ -7924,13 +8251,13 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
|
|
|
7924
8251
|
const changes = [];
|
|
7925
8252
|
for (const file of walkFiles(root, (b) => b === "agent.yaml")) {
|
|
7926
8253
|
const source = readText(file);
|
|
7927
|
-
const agentDir =
|
|
8254
|
+
const agentDir = path22__default.dirname(file);
|
|
7928
8255
|
let hits = 0;
|
|
7929
8256
|
const refRewrite = (_kind, ref) => {
|
|
7930
|
-
const moved = byOldPath.get(
|
|
8257
|
+
const moved = byOldPath.get(path22__default.resolve(agentDir, ref));
|
|
7931
8258
|
if (moved === void 0) return ref;
|
|
7932
8259
|
hits++;
|
|
7933
|
-
const rel = posix2(
|
|
8260
|
+
const rel = posix2(path22__default.relative(agentDir, moved));
|
|
7934
8261
|
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
7935
8262
|
};
|
|
7936
8263
|
let output;
|
|
@@ -7947,7 +8274,7 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
|
|
|
7947
8274
|
if (hits === 0 || output === source) continue;
|
|
7948
8275
|
changes.push({ type: "write", path: file, before: source, after: output });
|
|
7949
8276
|
notes.push(
|
|
7950
|
-
`${posix2(
|
|
8277
|
+
`${posix2(path22__default.relative(root, file))}: persona/ruleset refs \u2192 composes items at the new paths`
|
|
7951
8278
|
);
|
|
7952
8279
|
}
|
|
7953
8280
|
return changes;
|
|
@@ -7958,10 +8285,9 @@ function presetItemRef(dep, publisher) {
|
|
|
7958
8285
|
const [, kind, rest] = match;
|
|
7959
8286
|
return rest.startsWith("@") ? dep.trim() : `${kind}:@${publisher}/${rest}`;
|
|
7960
8287
|
}
|
|
7961
|
-
function presetText(name, description, refs,
|
|
8288
|
+
function presetText(name, description, refs, version) {
|
|
7962
8289
|
return stringify(
|
|
7963
8290
|
{
|
|
7964
|
-
publisher,
|
|
7965
8291
|
name,
|
|
7966
8292
|
version,
|
|
7967
8293
|
description: description && description.trim() !== "" ? description : `Preset ${name}`,
|
|
@@ -7972,14 +8298,14 @@ function presetText(name, description, refs, publisher, version) {
|
|
|
7972
8298
|
}
|
|
7973
8299
|
function skillDirs(dir) {
|
|
7974
8300
|
try {
|
|
7975
|
-
return readdirSync(
|
|
8301
|
+
return readdirSync(path22__default.join(dir, "skills"), { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync(path22__default.join(dir, "skills", e.name, "SKILL.md"))).map((e) => e.name).sort();
|
|
7976
8302
|
} catch {
|
|
7977
8303
|
return [];
|
|
7978
8304
|
}
|
|
7979
8305
|
}
|
|
7980
8306
|
function repoPublisher(root) {
|
|
7981
8307
|
for (const name of ["skaile.manifest.yaml", "skaile.yaml"]) {
|
|
7982
|
-
const file =
|
|
8308
|
+
const file = path22__default.join(root, name);
|
|
7983
8309
|
if (!existsSync(file)) continue;
|
|
7984
8310
|
try {
|
|
7985
8311
|
const parsed = parse(readText(file));
|
|
@@ -7995,9 +8321,9 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7995
8321
|
const changes = [];
|
|
7996
8322
|
const presets = [];
|
|
7997
8323
|
const handled = /* @__PURE__ */ new Set();
|
|
7998
|
-
const rel = (p6) => posix2(
|
|
8324
|
+
const rel = (p6) => posix2(path22__default.relative(root, p6));
|
|
7999
8325
|
const convert = (name, bundleFile, dir) => {
|
|
8000
|
-
const target =
|
|
8326
|
+
const target = path22__default.join(dir === root ? path22__default.join(dir, name) : dir, `${name}.preset.yaml`);
|
|
8001
8327
|
if (existsSync(target)) {
|
|
8002
8328
|
manual.push(`${rel(target)} already exists; bundle ${name} not converted`);
|
|
8003
8329
|
return;
|
|
@@ -8015,6 +8341,7 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
8015
8341
|
const declared = typeof parsed.version === "string" || typeof parsed.version === "number" ? String(parsed.version) : void 0;
|
|
8016
8342
|
if (declared !== void 0 && SEMVER_RE.test(declared)) version = declared;
|
|
8017
8343
|
else if (declared !== void 0) versionNote = `version ${declared} \u2192 ${version}`;
|
|
8344
|
+
else versionNote = `version (none) \u2192 ${version}`;
|
|
8018
8345
|
const deps = Array.isArray(parsed.dependencies) ? parsed.dependencies : [];
|
|
8019
8346
|
refs = deps.filter((d) => typeof d === "string").map((d) => presetItemRef(d, publisher));
|
|
8020
8347
|
if (refs.length !== deps.length) {
|
|
@@ -8028,11 +8355,11 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
8028
8355
|
}
|
|
8029
8356
|
if (refs.length === 0) {
|
|
8030
8357
|
manual.push(
|
|
8031
|
-
`bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(
|
|
8358
|
+
`bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(path22__default.join(dir, "skills"))}`}; no preset generated`
|
|
8032
8359
|
);
|
|
8033
8360
|
return;
|
|
8034
8361
|
}
|
|
8035
|
-
const after = presetText(name, description, refs,
|
|
8362
|
+
const after = presetText(name, description, refs, version);
|
|
8036
8363
|
if (before !== void 0 && bundleFile) {
|
|
8037
8364
|
changes.push({ type: "move", from: bundleFile, to: target, before, after });
|
|
8038
8365
|
handled.add(bundleFile);
|
|
@@ -8052,18 +8379,18 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
8052
8379
|
const assets = Array.isArray(raw.assets) ? raw.assets : [];
|
|
8053
8380
|
for (const entry of assets) {
|
|
8054
8381
|
if (!isRecord(entry) || entry.kind !== "bundle" || typeof entry.name !== "string") continue;
|
|
8055
|
-
const baseDir =
|
|
8056
|
-
const entryRoot = typeof entry.root === "string" ?
|
|
8382
|
+
const baseDir = path22__default.dirname(file);
|
|
8383
|
+
const entryRoot = typeof entry.root === "string" ? path22__default.join(baseDir, entry.root) : baseDir;
|
|
8057
8384
|
const files = Array.isArray(entry.files) ? entry.files : [];
|
|
8058
8385
|
const bundleName = files.find(
|
|
8059
8386
|
(f) => typeof f === "string" && f.endsWith(".bundle.yaml")
|
|
8060
8387
|
);
|
|
8061
|
-
convert(entry.name, bundleName ?
|
|
8388
|
+
convert(entry.name, bundleName ? path22__default.join(entryRoot, bundleName) : void 0, entryRoot);
|
|
8062
8389
|
}
|
|
8063
8390
|
}
|
|
8064
8391
|
for (const bundleFile of walkFiles(root, (b) => b.endsWith(".bundle.yaml"))) {
|
|
8065
8392
|
if (handled.has(bundleFile)) continue;
|
|
8066
|
-
const base =
|
|
8393
|
+
const base = path22__default.basename(bundleFile);
|
|
8067
8394
|
let name = base.replace(/\.bundle\.yaml$/, "");
|
|
8068
8395
|
try {
|
|
8069
8396
|
const parsed = parse(readText(bundleFile));
|
|
@@ -8072,7 +8399,7 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
8072
8399
|
} catch {
|
|
8073
8400
|
}
|
|
8074
8401
|
if (presets.some((p6) => p6.bundleFile === bundleFile)) continue;
|
|
8075
|
-
convert(name, bundleFile,
|
|
8402
|
+
convert(name, bundleFile, path22__default.dirname(bundleFile));
|
|
8076
8403
|
}
|
|
8077
8404
|
return changes;
|
|
8078
8405
|
}
|
|
@@ -8082,8 +8409,8 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
8082
8409
|
if (doc.errors.length > 0 || !isMap(doc.contents)) return [];
|
|
8083
8410
|
const map = doc.contents;
|
|
8084
8411
|
const raw = doc.toJS();
|
|
8085
|
-
const dir =
|
|
8086
|
-
const rel = (p6) => posix2(
|
|
8412
|
+
const dir = path22__default.dirname(file);
|
|
8413
|
+
const rel = (p6) => posix2(path22__default.relative(root, p6));
|
|
8087
8414
|
const changes = [];
|
|
8088
8415
|
let changed = false;
|
|
8089
8416
|
const deps = map.get("dependencies", true);
|
|
@@ -8100,7 +8427,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
8100
8427
|
const hasPublication = PUBLICATION_KEYS.some((k) => raw[k] !== void 0);
|
|
8101
8428
|
let remove = false;
|
|
8102
8429
|
if (hasPublication) {
|
|
8103
|
-
const manifestPath =
|
|
8430
|
+
const manifestPath = path22__default.join(dir, "skaile.manifest.yaml");
|
|
8104
8431
|
if (existsSync(manifestPath)) {
|
|
8105
8432
|
manual.push(
|
|
8106
8433
|
`${rel(file)}: publisher/version/assets left in place \u2014 ${rel(manifestPath)} already exists; merge by hand`
|
|
@@ -8157,7 +8484,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
8157
8484
|
return changes;
|
|
8158
8485
|
}
|
|
8159
8486
|
function planAssetMigration(options) {
|
|
8160
|
-
const root =
|
|
8487
|
+
const root = path22__default.resolve(options.root);
|
|
8161
8488
|
const knownKinds = new Set(options.registry.getAllKinds());
|
|
8162
8489
|
const notes = [];
|
|
8163
8490
|
const manual = [];
|
|
@@ -8165,7 +8492,7 @@ function planAssetMigration(options) {
|
|
|
8165
8492
|
const { moves, changes: moveChanges } = planMarkdownMoves(root, knownKinds, manual, unknownTypes);
|
|
8166
8493
|
for (const move of moves) {
|
|
8167
8494
|
notes.push(
|
|
8168
|
-
`${posix2(
|
|
8495
|
+
`${posix2(path22__default.relative(root, move.from))} \u2192 ${posix2(path22__default.relative(root, move.to))} (${move.kind})`
|
|
8169
8496
|
);
|
|
8170
8497
|
}
|
|
8171
8498
|
const agentChanges = planAgentRefRewrites(root, moves, knownKinds, notes);
|
|
@@ -8177,7 +8504,7 @@ function planAssetMigration(options) {
|
|
|
8177
8504
|
const raw = parse(source);
|
|
8178
8505
|
if (isRecord(raw)) skaileYamls.push({ file, source, raw });
|
|
8179
8506
|
} catch {
|
|
8180
|
-
manual.push(`${posix2(
|
|
8507
|
+
manual.push(`${posix2(path22__default.relative(root, file))}: invalid YAML; skipped`);
|
|
8181
8508
|
}
|
|
8182
8509
|
}
|
|
8183
8510
|
const publisher = repoPublisher(root);
|
|
@@ -8331,7 +8658,7 @@ function workspaceConfigFiles(dir) {
|
|
|
8331
8658
|
} catch {
|
|
8332
8659
|
return [];
|
|
8333
8660
|
}
|
|
8334
|
-
return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) =>
|
|
8661
|
+
return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) => path22__default.join(dir, name));
|
|
8335
8662
|
}
|
|
8336
8663
|
function readAgentConfigBlock(raw) {
|
|
8337
8664
|
const key = AGENT_CONFIG_KEYS.find((candidate) => raw[candidate] !== void 0);
|
|
@@ -8343,7 +8670,7 @@ function readAgentConfigBlock(raw) {
|
|
|
8343
8670
|
return flat ? { key, profiles: { default: profiles }, flat } : { key, profiles, flat };
|
|
8344
8671
|
}
|
|
8345
8672
|
function planProviderMigration(options) {
|
|
8346
|
-
const projectDir =
|
|
8673
|
+
const projectDir = path22__default.resolve(options.projectDir);
|
|
8347
8674
|
const registryPath = options.workspace ? workspaceProviderRegistryPath(projectDir) : userProviderRegistryPath();
|
|
8348
8675
|
const plan = {
|
|
8349
8676
|
registryPath,
|
|
@@ -8359,7 +8686,7 @@ function planProviderMigration(options) {
|
|
|
8359
8686
|
raw = parseDocument(readFileSync(file, "utf-8")).toJS() ?? {};
|
|
8360
8687
|
} catch (error) {
|
|
8361
8688
|
plan.warnings.push(
|
|
8362
|
-
`${
|
|
8689
|
+
`${path22__default.basename(file)}: not valid YAML (${error instanceof Error ? error.message : String(error)}) \u2014 skipped`
|
|
8363
8690
|
);
|
|
8364
8691
|
continue;
|
|
8365
8692
|
}
|
|
@@ -8408,7 +8735,7 @@ function planProviderMigration(options) {
|
|
|
8408
8735
|
});
|
|
8409
8736
|
if (!model) {
|
|
8410
8737
|
plan.warnings.push(
|
|
8411
|
-
`${
|
|
8738
|
+
`${path22__default.basename(file)}: profile '${profile}' had no model: \u2014 it now resolves against registry order. Pin it with 'model: ${providerId}/<modelId>'.`
|
|
8412
8739
|
);
|
|
8413
8740
|
}
|
|
8414
8741
|
touched = true;
|
|
@@ -8475,7 +8802,7 @@ function printPlan(plan) {
|
|
|
8475
8802
|
for (const entry of plan.entries) {
|
|
8476
8803
|
const base = entry.entry.base_url ?? S.dim("(transport-derived)");
|
|
8477
8804
|
console.log(
|
|
8478
|
-
` ${S.label(`${
|
|
8805
|
+
` ${S.label(`${path22__default.basename(entry.file)} ${entry.profile}`)} provider: ${entry.legacy.provider}, cloud: ${entry.legacy.cloud}`
|
|
8479
8806
|
);
|
|
8480
8807
|
console.log(` \u2192 providers.yml ${S.bold(entry.providerId)} ${base}`);
|
|
8481
8808
|
console.log(
|
|
@@ -8491,7 +8818,7 @@ function printPlan(plan) {
|
|
|
8491
8818
|
console.log();
|
|
8492
8819
|
}
|
|
8493
8820
|
async function runMigrateProviders(opts) {
|
|
8494
|
-
const projectDir = opts.projectDir ?
|
|
8821
|
+
const projectDir = opts.projectDir ? path22__default.resolve(opts.projectDir) : process.cwd();
|
|
8495
8822
|
const plan = planProviderMigration({ projectDir, workspace: opts.workspace });
|
|
8496
8823
|
for (const warning of plan.warnings) logWarn(warning);
|
|
8497
8824
|
if (plan.entries.length === 0 && Object.keys(plan.providers).length === 0) {
|
|
@@ -8573,7 +8900,8 @@ var ASSETS_HELP = `
|
|
|
8573
8900
|
Rewrites (run on a repo root):
|
|
8574
8901
|
type: persona|ruleset markdown <n>.md -> <n>/PERSONA.md | <n>/RULESET.md (type: dropped);
|
|
8575
8902
|
agent persona:/rules: refs to the old path become composes items
|
|
8576
|
-
*.bundle.yaml <name>.preset.yaml beside it
|
|
8903
|
+
*.bundle.yaml <name>.preset.yaml beside it, or <name>/<name>.preset.yaml
|
|
8904
|
+
for a bundle at the repo root (items: kind:@publisher/name);
|
|
8577
8905
|
kind: bundle entries of skaile.yaml#assets become kind: preset
|
|
8578
8906
|
skaile.yaml dependencies bundle:@... -> preset:@...
|
|
8579
8907
|
skaile.yaml publisher/version/assets
|
|
@@ -8622,7 +8950,7 @@ async function runMigrateAgents(paths, opts) {
|
|
|
8622
8950
|
let failures = 0;
|
|
8623
8951
|
let manualCount = 0;
|
|
8624
8952
|
for (const report of plan.reports) {
|
|
8625
|
-
const rel =
|
|
8953
|
+
const rel = path22__default.relative(base, report.file) || report.file;
|
|
8626
8954
|
for (const note of report.notes) console.log(` ${S.label(rel)} ${note}`);
|
|
8627
8955
|
for (const note of report.manual) {
|
|
8628
8956
|
manualCount++;
|
|
@@ -8649,14 +8977,14 @@ async function runMigrateAssets(root, opts) {
|
|
|
8649
8977
|
const write = resolveMode(opts);
|
|
8650
8978
|
const base = process.cwd();
|
|
8651
8979
|
const plan = planAssetMigration({
|
|
8652
|
-
root:
|
|
8980
|
+
root: path22__default.resolve(root ?? base),
|
|
8653
8981
|
registry: getKindRegistry()
|
|
8654
8982
|
});
|
|
8655
8983
|
for (const note of plan.notes) console.log(` ${note}`);
|
|
8656
8984
|
for (const note of plan.manual) logWarn(note);
|
|
8657
8985
|
for (const { file, type } of plan.unknownTypes) {
|
|
8658
8986
|
logWarn(
|
|
8659
|
-
`${
|
|
8987
|
+
`${path22__default.relative(base, file) || file}: frontmatter type "${type}" is not a registered asset kind (reported, not rewritten)`
|
|
8660
8988
|
);
|
|
8661
8989
|
}
|
|
8662
8990
|
printChanges(plan.changes, base);
|
|
@@ -8679,8 +9007,8 @@ function makeNpxCommand() {
|
|
|
8679
9007
|
skills.command("add <url>").description(
|
|
8680
9008
|
"Clone a repo, register it in the project's skaile.yaml sources[], and install a skill from it"
|
|
8681
9009
|
).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) => {
|
|
8682
|
-
const projectDir =
|
|
8683
|
-
const projYaml =
|
|
9010
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
9011
|
+
const projYaml = path22__default.join(projectDir, "skaile.yaml");
|
|
8684
9012
|
if (!existsSync(projYaml)) {
|
|
8685
9013
|
logErr(`No skaile.yaml in ${projectDir} \u2014 run \`skaile init\` first.`);
|
|
8686
9014
|
process.exit(1);
|
|
@@ -8693,11 +9021,11 @@ function makeNpxCommand() {
|
|
|
8693
9021
|
}
|
|
8694
9022
|
const spinner = createSpinner();
|
|
8695
9023
|
const key = sourceCacheKey(url);
|
|
8696
|
-
const clonePath =
|
|
9024
|
+
const clonePath = path22__default.join(getGlobalCacheDir(), key);
|
|
8697
9025
|
spinner.start(`Cloning ${url}`);
|
|
8698
9026
|
try {
|
|
8699
9027
|
if (!existsSync(clonePath)) {
|
|
8700
|
-
mkdirSync(
|
|
9028
|
+
mkdirSync(path22__default.dirname(clonePath), { recursive: true });
|
|
8701
9029
|
execSync(`git clone ${url} ${clonePath}`, { stdio: "ignore" });
|
|
8702
9030
|
}
|
|
8703
9031
|
spinner.stop(`Cloned to ${key}`);
|
|
@@ -8752,7 +9080,7 @@ function makeNpxCommand() {
|
|
|
8752
9080
|
return npx;
|
|
8753
9081
|
}
|
|
8754
9082
|
function resolvePublisher(clonePath, url) {
|
|
8755
|
-
const manifestPath =
|
|
9083
|
+
const manifestPath = path22__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
|
|
8756
9084
|
if (existsSync(manifestPath)) {
|
|
8757
9085
|
try {
|
|
8758
9086
|
const { manifest } = decodeSkaileManifest(readFileSync(manifestPath, "utf8"));
|
|
@@ -8765,12 +9093,12 @@ function resolvePublisher(clonePath, url) {
|
|
|
8765
9093
|
return url.match(/github\.com[/:]([^/]+)\/[^/]+/)?.[1];
|
|
8766
9094
|
}
|
|
8767
9095
|
function resolveSkillName(clonePath, requested) {
|
|
8768
|
-
const skillsDir =
|
|
8769
|
-
if (existsSync(
|
|
9096
|
+
const skillsDir = path22__default.join(clonePath, "skills");
|
|
9097
|
+
if (existsSync(path22__default.join(skillsDir, requested, "SKILL.md"))) return requested;
|
|
8770
9098
|
if (!existsSync(skillsDir)) return requested;
|
|
8771
9099
|
for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
|
|
8772
9100
|
if (!entry.isDirectory()) continue;
|
|
8773
|
-
const md =
|
|
9101
|
+
const md = path22__default.join(skillsDir, entry.name, "SKILL.md");
|
|
8774
9102
|
if (!existsSync(md)) continue;
|
|
8775
9103
|
try {
|
|
8776
9104
|
const { data } = parseFrontmatter(readFileSync(md, "utf8"));
|
|
@@ -8803,7 +9131,7 @@ function makeOutdatedCommand() {
|
|
|
8803
9131
|
requireProjectConfig(opts.projectDir);
|
|
8804
9132
|
const am2 = new AssetManager({
|
|
8805
9133
|
registry: getKindRegistry(),
|
|
8806
|
-
projectDir:
|
|
9134
|
+
projectDir: path22__default.resolve(opts.projectDir),
|
|
8807
9135
|
driverTarget: opts.target
|
|
8808
9136
|
});
|
|
8809
9137
|
const entries = await am2.outdated();
|
|
@@ -8846,7 +9174,7 @@ function makePatchCommand() {
|
|
|
8846
9174
|
cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
8847
9175
|
const am2 = new AssetManager({
|
|
8848
9176
|
registry: getKindRegistry(),
|
|
8849
|
-
projectDir:
|
|
9177
|
+
projectDir: path22__default.resolve(opts.projectDir)
|
|
8850
9178
|
});
|
|
8851
9179
|
try {
|
|
8852
9180
|
const dest = await am2.patch(ref);
|
|
@@ -8860,7 +9188,7 @@ function makePatchCommand() {
|
|
|
8860
9188
|
cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
8861
9189
|
const am2 = new AssetManager({
|
|
8862
9190
|
registry: getKindRegistry(),
|
|
8863
|
-
projectDir:
|
|
9191
|
+
projectDir: path22__default.resolve(opts.projectDir)
|
|
8864
9192
|
});
|
|
8865
9193
|
try {
|
|
8866
9194
|
const patchFile = await am2.patchCommit(ref);
|
|
@@ -8874,7 +9202,7 @@ function makePatchCommand() {
|
|
|
8874
9202
|
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) => {
|
|
8875
9203
|
const am2 = new AssetManager({
|
|
8876
9204
|
registry: getKindRegistry(),
|
|
8877
|
-
projectDir:
|
|
9205
|
+
projectDir: path22__default.resolve(opts.projectDir)
|
|
8878
9206
|
});
|
|
8879
9207
|
try {
|
|
8880
9208
|
await am2.patchSubmit(ref);
|
|
@@ -8890,7 +9218,7 @@ function makePatchCommand() {
|
|
|
8890
9218
|
cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
8891
9219
|
const am2 = new AssetManager({
|
|
8892
9220
|
registry: getKindRegistry(),
|
|
8893
|
-
projectDir:
|
|
9221
|
+
projectDir: path22__default.resolve(opts.projectDir)
|
|
8894
9222
|
});
|
|
8895
9223
|
am2.patchRemove(ref);
|
|
8896
9224
|
logOk(`Patch removed for ${ref}`);
|
|
@@ -8908,8 +9236,8 @@ function action2(fn) {
|
|
|
8908
9236
|
}
|
|
8909
9237
|
};
|
|
8910
9238
|
}
|
|
8911
|
-
async function reconcileAndReport(projectDir, plugins) {
|
|
8912
|
-
const { reconcilePlugins } = await import('../plugin-store-
|
|
9239
|
+
async function reconcileAndReport(projectDir, plugins, opts = {}) {
|
|
9240
|
+
const { reconcilePlugins } = await import('../plugin-store-XMZSPVBF.js');
|
|
8913
9241
|
if (plugins.length === 0) {
|
|
8914
9242
|
logInfo("No plugins declared \u2014 nothing to reconcile.");
|
|
8915
9243
|
return;
|
|
@@ -8919,26 +9247,52 @@ async function reconcileAndReport(projectDir, plugins) {
|
|
|
8919
9247
|
if (result.changed) logOk(`Reconciled plugin store (${result.reason}).`);
|
|
8920
9248
|
else logInfo(`Plugin store ${result.reason}.`);
|
|
8921
9249
|
} catch (err2) {
|
|
9250
|
+
if (opts.strict) throw err2;
|
|
8922
9251
|
logWarn(`reconcile skipped: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
8923
9252
|
}
|
|
8924
9253
|
}
|
|
9254
|
+
async function verifyPluginLoads(projectDir, spec) {
|
|
9255
|
+
const { loadPlugins } = await import('../plugin-store-XMZSPVBF.js');
|
|
9256
|
+
const { createPluginRegistry } = await import('../plugin-registry/index.js');
|
|
9257
|
+
const registry = createPluginRegistry();
|
|
9258
|
+
const result = await loadPlugins(projectDir, [spec], registry);
|
|
9259
|
+
const failure = result.failed[0];
|
|
9260
|
+
if (failure) throw new Error(failure.error);
|
|
9261
|
+
const contributed = ["driver", "connector", "deployTarget"].flatMap(
|
|
9262
|
+
(kind) => registry.list(kind).map((m) => `${kind} ${m.id}`)
|
|
9263
|
+
);
|
|
9264
|
+
logOk(`Loaded ${S.cmd(spec)}${contributed.length > 0 ? ` (${contributed.join(", ")})` : ""}`);
|
|
9265
|
+
}
|
|
8925
9266
|
async function runInstall2(spec, opts) {
|
|
8926
|
-
const projectDir =
|
|
9267
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
8927
9268
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
8928
|
-
const { specName } = await import('../plugin-store-
|
|
8929
|
-
const yamlPath =
|
|
9269
|
+
const { specName } = await import('../plugin-store-XMZSPVBF.js');
|
|
9270
|
+
const yamlPath = path22__default.join(projectDir, "skaile.yaml");
|
|
9271
|
+
const original = existsSync(yamlPath) ? readFileSync(yamlPath, "utf8") : void 0;
|
|
8930
9272
|
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
8931
9273
|
const replaced = editor.addPlugin(spec, specName);
|
|
8932
9274
|
editor.save();
|
|
8933
9275
|
if (replaced) logOk(`Updated ${S.cmd(specName(spec))} \u2192 ${S.cmd(spec)} in skaile.yaml`);
|
|
8934
9276
|
else logOk(`Added ${S.cmd(spec)} to skaile.yaml plugins`);
|
|
8935
|
-
|
|
9277
|
+
try {
|
|
9278
|
+
await reconcileAndReport(projectDir, editor.getPlugins(), { strict: true });
|
|
9279
|
+
await verifyPluginLoads(projectDir, spec);
|
|
9280
|
+
} catch (err2) {
|
|
9281
|
+
if (original !== void 0) {
|
|
9282
|
+
writeFileSync(yamlPath, original);
|
|
9283
|
+
logInfo("skaile.yaml restored; the plugin was not recorded.");
|
|
9284
|
+
} else {
|
|
9285
|
+
rmSync(yamlPath, { force: true });
|
|
9286
|
+
logInfo("skaile.yaml removed; the plugin was not recorded.");
|
|
9287
|
+
}
|
|
9288
|
+
throw err2;
|
|
9289
|
+
}
|
|
8936
9290
|
}
|
|
8937
9291
|
async function runRemove(name, opts) {
|
|
8938
|
-
const projectDir =
|
|
9292
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
8939
9293
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
8940
|
-
const { specName } = await import('../plugin-store-
|
|
8941
|
-
const yamlPath =
|
|
9294
|
+
const { specName } = await import('../plugin-store-XMZSPVBF.js');
|
|
9295
|
+
const yamlPath = path22__default.join(projectDir, "skaile.yaml");
|
|
8942
9296
|
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
8943
9297
|
const removed = editor.removePlugin(name, specName);
|
|
8944
9298
|
if (!removed) {
|
|
@@ -8950,7 +9304,7 @@ async function runRemove(name, opts) {
|
|
|
8950
9304
|
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
8951
9305
|
}
|
|
8952
9306
|
async function runList(opts) {
|
|
8953
|
-
const projectDir =
|
|
9307
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
8954
9308
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
8955
9309
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
8956
9310
|
const declared = config.plugins ?? [];
|
|
@@ -8965,7 +9319,7 @@ async function runList(opts) {
|
|
|
8965
9319
|
const registry = createPluginRegistry();
|
|
8966
9320
|
if (declared.length > 0) {
|
|
8967
9321
|
try {
|
|
8968
|
-
const { loadPlugins } = await import('../plugin-store-
|
|
9322
|
+
const { loadPlugins } = await import('../plugin-store-XMZSPVBF.js');
|
|
8969
9323
|
const result = await loadPlugins(projectDir, declared, registry);
|
|
8970
9324
|
for (const f of result.failed) logWarn(f.error);
|
|
8971
9325
|
} catch (err2) {
|
|
@@ -9140,7 +9494,7 @@ function neededSources(config, lock) {
|
|
|
9140
9494
|
}
|
|
9141
9495
|
function sourcesWithSidecar(sources) {
|
|
9142
9496
|
const dir = getStoreManifestsDir();
|
|
9143
|
-
return sources.filter((s) => existsSync(
|
|
9497
|
+
return sources.filter((s) => existsSync(path22.join(dir, `${storeManifestSlug(s.url)}.yaml`))).map((s) => s.url);
|
|
9144
9498
|
}
|
|
9145
9499
|
function compact(obj) {
|
|
9146
9500
|
const out = {};
|
|
@@ -9232,8 +9586,8 @@ function redactSecrets(preset, findings) {
|
|
|
9232
9586
|
}
|
|
9233
9587
|
return { preset: next, keys };
|
|
9234
9588
|
}
|
|
9235
|
-
function placeholderKey(itemId,
|
|
9236
|
-
return `${itemId}_${
|
|
9589
|
+
function placeholderKey(itemId, path44) {
|
|
9590
|
+
return `${itemId}_${path44}`.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
|
|
9237
9591
|
}
|
|
9238
9592
|
function setAtPath(root, segments, value) {
|
|
9239
9593
|
let node = root;
|
|
@@ -9256,7 +9610,7 @@ function makePresetCommand() {
|
|
|
9256
9610
|
cmd.command("init [name]").description("Scaffold a new .preset.yaml file").option("--dir <path>", "Output directory", process.cwd()).action(async (name, opts) => {
|
|
9257
9611
|
const presetName = name ?? "my-preset";
|
|
9258
9612
|
const filename = `${presetName}.preset.yaml`;
|
|
9259
|
-
const outPath =
|
|
9613
|
+
const outPath = path22__default.join(path22__default.resolve(opts.dir), filename);
|
|
9260
9614
|
if (existsSync(outPath)) {
|
|
9261
9615
|
logErr(`File already exists: ${outPath}`);
|
|
9262
9616
|
logInfo("Choose a different name or remove the existing file.");
|
|
@@ -9289,7 +9643,7 @@ function makePresetCommand() {
|
|
|
9289
9643
|
return cmd;
|
|
9290
9644
|
}
|
|
9291
9645
|
async function runPresetExport(name, opts) {
|
|
9292
|
-
const projectDir =
|
|
9646
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
9293
9647
|
const file = loadSkWorkspaceConfig(projectDir);
|
|
9294
9648
|
if (!file) {
|
|
9295
9649
|
logErr(`No skaile.yaml found in ${projectDir}`);
|
|
@@ -9299,7 +9653,7 @@ async function runPresetExport(name, opts) {
|
|
|
9299
9653
|
const presetName = name ?? file.config.name ?? "my-preset";
|
|
9300
9654
|
let lock = null;
|
|
9301
9655
|
try {
|
|
9302
|
-
lock = readLock(
|
|
9656
|
+
lock = readLock(path22__default.join(projectDir, "skaile.lock.yaml"));
|
|
9303
9657
|
} catch {
|
|
9304
9658
|
lock = null;
|
|
9305
9659
|
}
|
|
@@ -9340,7 +9694,7 @@ async function runPresetExport(name, opts) {
|
|
|
9340
9694
|
const contents = header ? `${header}
|
|
9341
9695
|
${body}` : body;
|
|
9342
9696
|
if (opts.out && opts.dir !== process.cwd()) logWarn("--dir is ignored when --out is set.");
|
|
9343
|
-
const outPath = opts.out ?
|
|
9697
|
+
const outPath = opts.out ? path22__default.resolve(opts.out) : path22__default.join(path22__default.resolve(opts.dir), `${presetName}.preset.yaml`);
|
|
9344
9698
|
if (existsSync(outPath) && !opts.force) {
|
|
9345
9699
|
logErr(`File already exists: ${outPath}`);
|
|
9346
9700
|
logInfo("Pass --force to overwrite, or choose a different --out/--dir.");
|
|
@@ -9352,7 +9706,7 @@ ${body}` : body;
|
|
|
9352
9706
|
logErr(`Failed to write ${outPath}: ${e.message}`);
|
|
9353
9707
|
process.exit(1);
|
|
9354
9708
|
}
|
|
9355
|
-
logOk(`Exported ${S.brand(
|
|
9709
|
+
logOk(`Exported ${S.brand(path22__default.basename(outPath))}`);
|
|
9356
9710
|
logInfo(`Path: ${outPath}`);
|
|
9357
9711
|
if (unresolved.length > 0) {
|
|
9358
9712
|
console.error(S.err("This file is NOT safe to share."));
|
|
@@ -9393,13 +9747,13 @@ function collectInput(value, acc) {
|
|
|
9393
9747
|
return acc;
|
|
9394
9748
|
}
|
|
9395
9749
|
async function runPresetApply(filePath, opts) {
|
|
9396
|
-
const projectDir =
|
|
9750
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
9397
9751
|
const file = loadSkWorkspaceConfig(projectDir);
|
|
9398
9752
|
if (!file) {
|
|
9399
9753
|
logErr("No skaile.yaml \u2014 run `skaile init` first");
|
|
9400
9754
|
process.exit(1);
|
|
9401
9755
|
}
|
|
9402
|
-
const resolved =
|
|
9756
|
+
const resolved = path22__default.resolve(filePath);
|
|
9403
9757
|
if (!existsSync(resolved)) {
|
|
9404
9758
|
logErr(`File not found: ${resolved}`);
|
|
9405
9759
|
process.exit(1);
|
|
@@ -9615,7 +9969,7 @@ async function reportNestedPresetRefs(preset) {
|
|
|
9615
9969
|
}
|
|
9616
9970
|
async function checkPresetCycles(preset, resolved) {
|
|
9617
9971
|
const { detectCycles } = await import('../discovery/index.js');
|
|
9618
|
-
const presetRef =
|
|
9972
|
+
const presetRef = path22__default.basename(resolved, ".preset.yaml");
|
|
9619
9973
|
const edges = [];
|
|
9620
9974
|
for (const item of preset.items) {
|
|
9621
9975
|
if (item.ref) {
|
|
@@ -9667,7 +10021,7 @@ function printPresetSummary(preset, placeholderCount, hasWarnings) {
|
|
|
9667
10021
|
}
|
|
9668
10022
|
}
|
|
9669
10023
|
async function runPresetValidate(filePath) {
|
|
9670
|
-
const resolved =
|
|
10024
|
+
const resolved = path22__default.resolve(filePath);
|
|
9671
10025
|
const preset = await loadPresetForValidation(resolved);
|
|
9672
10026
|
await reportNestedPresetRefs(preset);
|
|
9673
10027
|
await checkPresetCycles(preset, resolved);
|
|
@@ -9717,11 +10071,11 @@ items:
|
|
|
9717
10071
|
}
|
|
9718
10072
|
function makeRebuildCommand() {
|
|
9719
10073
|
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) => {
|
|
9720
|
-
const projectDir =
|
|
10074
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
9721
10075
|
let agentDir;
|
|
9722
10076
|
if (agentArg) {
|
|
9723
10077
|
if (agentArg.includes("/") || agentArg.includes("\\")) {
|
|
9724
|
-
agentDir =
|
|
10078
|
+
agentDir = path22__default.resolve(projectDir, agentArg);
|
|
9725
10079
|
} else {
|
|
9726
10080
|
let resolved;
|
|
9727
10081
|
try {
|
|
@@ -9730,7 +10084,7 @@ function makeRebuildCommand() {
|
|
|
9730
10084
|
if (!(err2 instanceof AgentRefResolutionError)) throw err2;
|
|
9731
10085
|
logWarn(`${err2.message} \u2014 using "${agentArg}"`);
|
|
9732
10086
|
}
|
|
9733
|
-
agentDir = resolved ??
|
|
10087
|
+
agentDir = resolved ?? path22__default.resolve(projectDir, agentArg);
|
|
9734
10088
|
}
|
|
9735
10089
|
} else {
|
|
9736
10090
|
let resolved;
|
|
@@ -9800,9 +10154,9 @@ Try a different harness with \`--driver claude-sdk\`.`;
|
|
|
9800
10154
|
// cli/src/commands/run.ts
|
|
9801
10155
|
function resolveSingleShotAgentDir(projectDir, agentDefinition) {
|
|
9802
10156
|
if (!agentDefinition) return resolveAgentDir(projectDir);
|
|
9803
|
-
const asPath = agentDefinition.endsWith("agent.yaml") ?
|
|
10157
|
+
const asPath = agentDefinition.endsWith("agent.yaml") ? path22__default.dirname(path22__default.resolve(projectDir, agentDefinition)) : agentDefinition;
|
|
9804
10158
|
const dir = resolveAgentDefinitionDir(projectDir, asPath);
|
|
9805
|
-
if (!dir || !fs8__default.existsSync(
|
|
10159
|
+
if (!dir || !fs8__default.existsSync(path22__default.join(dir, "agent.yaml"))) {
|
|
9806
10160
|
throw new Error(
|
|
9807
10161
|
`--agent-definition "${agentDefinition}" does not resolve to an agent directory with agent.yaml${dir ? ` (looked in ${dir})` : ""}`
|
|
9808
10162
|
);
|
|
@@ -9853,10 +10207,58 @@ async function printCompositionDryRun(projectDir, agentDir, driver, model) {
|
|
|
9853
10207
|
}
|
|
9854
10208
|
for (const warning of resolved.warnings) logWarn(warning);
|
|
9855
10209
|
}
|
|
10210
|
+
async function findSkillFile(projectDir, skill) {
|
|
10211
|
+
const name = skill.trim().replace(/^skill:/, "").replace(/^@[^/]+\//, "").replace(/#.*$/, "");
|
|
10212
|
+
for (const target of SUPPORTED_DRIVER_TARGETS) {
|
|
10213
|
+
const file = path22__default.join(deployedDir("skill", name, target, false, projectDir), "SKILL.md");
|
|
10214
|
+
if (fs8__default.existsSync(file)) return file;
|
|
10215
|
+
}
|
|
10216
|
+
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
|
|
10217
|
+
const entry = await am2.info(`skill:${name}`);
|
|
10218
|
+
return entry?.source && fs8__default.existsSync(entry.source) ? entry.source : void 0;
|
|
10219
|
+
}
|
|
10220
|
+
async function printSkillDryRun(projectDir, skill) {
|
|
10221
|
+
const file = await findSkillFile(projectDir, skill);
|
|
10222
|
+
if (!file) {
|
|
10223
|
+
logErr(
|
|
10224
|
+
`Skill not found: ${skill} - not deployed in the project and not held by a registered library or source`
|
|
10225
|
+
);
|
|
10226
|
+
return false;
|
|
10227
|
+
}
|
|
10228
|
+
const content = fs8__default.readFileSync(file, "utf-8");
|
|
10229
|
+
const { data } = parseFrontmatter(content);
|
|
10230
|
+
const meta = data.metadata ?? {};
|
|
10231
|
+
console.log(` ${S.label("Skill:")} ${S.heading(String(data.name ?? skill))}`);
|
|
10232
|
+
console.log(` ${S.label("Source:")} ${file}`);
|
|
10233
|
+
if (meta.version) console.log(` ${S.label("Version:")} ${String(meta.version)}`);
|
|
10234
|
+
if (data.description) console.log(` ${S.label("About:")} ${String(data.description)}`);
|
|
10235
|
+
const requires = parseRequires(data);
|
|
10236
|
+
if (requires.length > 0) {
|
|
10237
|
+
console.log(` ${S.label("Requires:")} ${requires.map((d) => depToStr(d)).join(", ")}`);
|
|
10238
|
+
}
|
|
10239
|
+
const requirements = parseSkillRequirements(content);
|
|
10240
|
+
const report = await validateRequirements(String(data.name ?? skill), requirements, projectDir);
|
|
10241
|
+
const unmet = report.files.filter((f) => !f.exists);
|
|
10242
|
+
for (const f of report.files) {
|
|
10243
|
+
const mark = f.exists ? S.ok("present") : f.gate === "hard" ? S.err("missing") : S.warn("missing");
|
|
10244
|
+
const gate = f.gate === "soft" ? " (soft)" : "";
|
|
10245
|
+
console.log(` ${S.label("File:")} ${f.path}${gate} ${mark}`);
|
|
10246
|
+
}
|
|
10247
|
+
for (const input of report.inputs.filter((i) => i.required && !i.present)) {
|
|
10248
|
+
console.log(` ${S.label("Input:")} ${input.id} ${S.err("required, not collected")}`);
|
|
10249
|
+
}
|
|
10250
|
+
if (unmet.some((f) => f.gate === "hard")) {
|
|
10251
|
+
logWarn("Unmet hard prerequisites: the skill cannot run until those files exist.");
|
|
10252
|
+
}
|
|
10253
|
+
console.log();
|
|
10254
|
+
return true;
|
|
10255
|
+
}
|
|
9856
10256
|
function makeFlowEventHandler() {
|
|
9857
10257
|
const md = new MarkdownStreamer();
|
|
9858
10258
|
const displayed = /* @__PURE__ */ new Set();
|
|
10259
|
+
const printUnstreamed = createFinalTextFallback((text) => md.write(text));
|
|
9859
10260
|
return (event) => {
|
|
10261
|
+
printUnstreamed(event);
|
|
9860
10262
|
const e = event;
|
|
9861
10263
|
if (e.type === "state_changed" && typeof e.store === "string" && e.store.startsWith("flow:")) {
|
|
9862
10264
|
const nodes = e.state?.nodes ?? {};
|
|
@@ -9896,12 +10298,35 @@ function logAgentRunEvent(event) {
|
|
|
9896
10298
|
const verdict = e.error ? `${e.runStatus ?? "failed"}: ${e.error.code} ${e.error.message}` : e.runStatus ?? "finished";
|
|
9897
10299
|
console.error(` ${S.dim("subagent")} ${who} ${verdict} output=${JSON.stringify(e.output)}`);
|
|
9898
10300
|
}
|
|
10301
|
+
function editDistance2(a, b) {
|
|
10302
|
+
let prev = Array.from({ length: b.length + 1 }, (_, j) => j);
|
|
10303
|
+
for (let i = 1; i <= a.length; i++) {
|
|
10304
|
+
const row = [i];
|
|
10305
|
+
for (let j = 1; j <= b.length; j++) {
|
|
10306
|
+
row[j] = Math.min(
|
|
10307
|
+
prev[j] + 1,
|
|
10308
|
+
row[j - 1] + 1,
|
|
10309
|
+
prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)
|
|
10310
|
+
);
|
|
10311
|
+
}
|
|
10312
|
+
prev = row;
|
|
10313
|
+
}
|
|
10314
|
+
return prev[b.length];
|
|
10315
|
+
}
|
|
10316
|
+
function isNearFlowId(typed, id) {
|
|
10317
|
+
const a = typed.toLowerCase();
|
|
10318
|
+
const b = id.toLowerCase();
|
|
10319
|
+
return a.length >= 3 && (b.includes(a) || a.includes(b) || editDistance2(a, b) <= 2);
|
|
10320
|
+
}
|
|
10321
|
+
function driverOptionDescription() {
|
|
10322
|
+
return `Harness to run (${listDrivers().map((d) => d.id).join(", ")})`;
|
|
10323
|
+
}
|
|
9899
10324
|
function makeRunCommand() {
|
|
9900
|
-
const cmd = new Command("run").description("Start a flow or run a single-shot text prompt").argument("[flow-id-or-text...]", "Flow ID or text prompt").option("--project-dir <path>", "Project directory", process.cwd()).option("--driver <name>",
|
|
10325
|
+
const cmd = new Command("run").description("Start a flow or run a single-shot text prompt").argument("[flow-id-or-text...]", "Flow ID or text prompt").option("--project-dir <path>", "Project directory", process.cwd()).option("--driver <name>", driverOptionDescription()).option("--model <name>", "Model override").option("--label <label>", "Human-readable session label").option("--dry-run", "Print plan without executing (single-shot: resolved composition items)").option(
|
|
9901
10326
|
"--agent-definition <ref|path>",
|
|
9902
10327
|
"Agent asset for this one invocation (agent:@pub/name, ai-assets://\u2026, or a directory with agent.yaml); single-shot prompts only"
|
|
9903
10328
|
).option("--skill <name>", "Skill name (for single-shot mode)").action(async (positional, opts) => {
|
|
9904
|
-
const projectDir =
|
|
10329
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
9905
10330
|
const cliDriver = opts.driver;
|
|
9906
10331
|
const dryRun = opts.dryRun ?? false;
|
|
9907
10332
|
const agentDefinition = opts.agentDefinition?.trim() || void 0;
|
|
@@ -9945,18 +10370,29 @@ function makeRunCommand() {
|
|
|
9945
10370
|
}
|
|
9946
10371
|
if (!flowPath) {
|
|
9947
10372
|
const textPrompt = positional.join(" ");
|
|
9948
|
-
|
|
10373
|
+
const promptOnlyOption = agentDefinition !== void 0 || opts.skill !== void 0;
|
|
10374
|
+
if (!textPrompt.trim() || positional.length === 1 && !/\s/.test(flowId) && !promptOnlyOption) {
|
|
9949
10375
|
logErr(`Flow not found: ${flowId}`);
|
|
9950
10376
|
const available = (await discoverFlowsWithLibraries(projectDir)).map((f) => f.id);
|
|
9951
|
-
|
|
9952
|
-
|
|
10377
|
+
const near = available.filter((id) => isNearFlowId(flowId, id));
|
|
10378
|
+
const listed = near.length > 0 ? near : available;
|
|
10379
|
+
if (listed.length > 0) {
|
|
10380
|
+
console.log(
|
|
10381
|
+
` ${S.dim(near.length > 0 ? "Did you mean:" : "Available:")} ${listed.map((id) => S.cmd(id)).join(", ")}`
|
|
10382
|
+
);
|
|
9953
10383
|
}
|
|
10384
|
+
console.log(
|
|
10385
|
+
` ${S.dim('To send it as a prompt, quote more than one word: skaile run "\u2026".')}`
|
|
10386
|
+
);
|
|
9954
10387
|
process.exit(1);
|
|
9955
10388
|
}
|
|
9956
10389
|
try {
|
|
9957
10390
|
const agentDir = resolveSingleShotAgentDir(projectDir, agentDefinition);
|
|
9958
10391
|
if (dryRun) {
|
|
9959
10392
|
await printCompositionDryRun(projectDir, agentDir, driver, model);
|
|
10393
|
+
if (opts.skill && !await printSkillDryRun(projectDir, opts.skill)) {
|
|
10394
|
+
process.exit(1);
|
|
10395
|
+
}
|
|
9960
10396
|
return;
|
|
9961
10397
|
}
|
|
9962
10398
|
await runAgentChat({
|
|
@@ -10020,7 +10456,7 @@ function makeRunCommand() {
|
|
|
10020
10456
|
}
|
|
10021
10457
|
function makeResumeCommand() {
|
|
10022
10458
|
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) => {
|
|
10023
|
-
const projectDir =
|
|
10459
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
10024
10460
|
const sessionId = opts.session;
|
|
10025
10461
|
const dryRun = opts.dryRun ?? false;
|
|
10026
10462
|
const session = sessionId ? await loadSessionById(projectDir, sessionId) : await loadSession(projectDir);
|
|
@@ -10047,7 +10483,7 @@ function makeResumeCommand() {
|
|
|
10047
10483
|
}
|
|
10048
10484
|
function makeStatusCommand() {
|
|
10049
10485
|
return new Command("status").description("Show current session state").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
10050
|
-
const projectDir =
|
|
10486
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
10051
10487
|
const session = await loadSession(projectDir);
|
|
10052
10488
|
if (!session) {
|
|
10053
10489
|
logInfo("No active session.");
|
|
@@ -10072,17 +10508,17 @@ function makeStatusCommand() {
|
|
|
10072
10508
|
}
|
|
10073
10509
|
function makeClearCommand() {
|
|
10074
10510
|
return new Command("clear").description("Unset current session pointer").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
10075
|
-
const projectDir =
|
|
10511
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
10076
10512
|
await clearSession(projectDir);
|
|
10077
10513
|
logOk("Session cleared.");
|
|
10078
10514
|
});
|
|
10079
10515
|
}
|
|
10080
10516
|
function makeReplCommand() {
|
|
10081
|
-
return new Command("repl").description("Start an interactive agent session").option("--project-dir <path>", "Project directory").option("--driver <name>",
|
|
10517
|
+
return new Command("repl").description("Start an interactive agent session").option("--project-dir <path>", "Project directory").option("--driver <name>", driverOptionDescription()).option("--model <name>", "Model override").option("--resume", "Resume last session").option("--resume-session <id>", "Resume specific session").action(async (opts) => {
|
|
10082
10518
|
const { findWorkspaceRoot } = await import('../core/index.js');
|
|
10083
10519
|
const { startRepl } = await import('../tui/index.js');
|
|
10084
10520
|
const os2 = await import('os');
|
|
10085
|
-
const userCwd =
|
|
10521
|
+
const userCwd = path22__default.resolve(opts.projectDir ?? process.cwd());
|
|
10086
10522
|
const workspaceRoot = findWorkspaceRoot(userCwd);
|
|
10087
10523
|
let projectDir;
|
|
10088
10524
|
let agentCwd;
|
|
@@ -10097,6 +10533,12 @@ function makeReplCommand() {
|
|
|
10097
10533
|
console.log();
|
|
10098
10534
|
logWarn(`No skaile.yaml found in ${S.cmd(userCwd)} or any parent directory.`);
|
|
10099
10535
|
console.log();
|
|
10536
|
+
if (!process.stdin.isTTY) {
|
|
10537
|
+
logErr(
|
|
10538
|
+
`repl needs a skaile.yaml here when stdin is not a terminal: run ${S.cmd("skaile init")} first.`
|
|
10539
|
+
);
|
|
10540
|
+
process.exit(1);
|
|
10541
|
+
}
|
|
10100
10542
|
const shouldCreate = await p4.confirm({
|
|
10101
10543
|
message: "Create a temporary workspace? (session state in /tmp/)"
|
|
10102
10544
|
});
|
|
@@ -10104,12 +10546,12 @@ function makeReplCommand() {
|
|
|
10104
10546
|
p4.cancel("Cancelled.");
|
|
10105
10547
|
process.exit(0);
|
|
10106
10548
|
}
|
|
10107
|
-
const tmpDir = fs8__default.mkdtempSync(
|
|
10549
|
+
const tmpDir = fs8__default.mkdtempSync(path22__default.join(os2.tmpdir(), "skaile-repl-"));
|
|
10108
10550
|
projectDir = tmpDir;
|
|
10109
10551
|
agentCwd = userCwd;
|
|
10110
10552
|
logOk(`Temporary workspace: ${S.cmd(tmpDir)}`);
|
|
10111
10553
|
if (!driverOverride) {
|
|
10112
|
-
const claudeDir =
|
|
10554
|
+
const claudeDir = path22__default.join(os2.homedir(), ".claude");
|
|
10113
10555
|
if (fs8__default.existsSync(claudeDir)) {
|
|
10114
10556
|
driverOverride = "claude-sdk";
|
|
10115
10557
|
logInfo(`Detected ${S.cmd("~/.claude")} \u2192 using ${S.cmd("claude-sdk")} harness`);
|
|
@@ -10139,7 +10581,10 @@ function parseProviderIds(raw) {
|
|
|
10139
10581
|
return (raw ?? "").split(",").map((id) => id.trim()).filter((id) => id.length > 0);
|
|
10140
10582
|
}
|
|
10141
10583
|
function makeServeCommand() {
|
|
10142
|
-
return new Command("serve").description("Start a WebSocket agent server (for platform integration)").option("--port <port>", "WebSocket server port", "8080").option(
|
|
10584
|
+
return new Command("serve").description("Start a WebSocket agent server (for platform integration)").option("--port <port>", "WebSocket server port", "8080").option(
|
|
10585
|
+
"--host <address>",
|
|
10586
|
+
"Address to bind (default: all interfaces; use 127.0.0.1 for local clients only)"
|
|
10587
|
+
).option("--project-dir <path>", "Project directory", process.cwd()).option(
|
|
10143
10588
|
"--managed-codex-config <path>",
|
|
10144
10589
|
"Explicit private host configuration for managed Codex"
|
|
10145
10590
|
).option("--driver <name>", "Override driver").option("--model <name>", "Override model").option("--provider <name>", "Override provider").option("--session-id <id>", "Session ID for conversation continuity").option("--resume-session-id <id>", "OMP session ID to resume (restores native OMP context)").option(
|
|
@@ -10167,32 +10612,48 @@ function makeServeCommand() {
|
|
|
10167
10612
|
await ensurePluginsLoadedForServe(opts.projectDir);
|
|
10168
10613
|
}
|
|
10169
10614
|
const providers = parseProviderIds(opts.providers);
|
|
10170
|
-
await
|
|
10171
|
-
|
|
10172
|
-
|
|
10173
|
-
|
|
10174
|
-
|
|
10175
|
-
|
|
10176
|
-
|
|
10177
|
-
|
|
10178
|
-
|
|
10179
|
-
|
|
10180
|
-
|
|
10181
|
-
|
|
10182
|
-
|
|
10183
|
-
|
|
10184
|
-
|
|
10185
|
-
|
|
10615
|
+
const { checkDriverSdk } = await import('../serve-preflight-6P2JJEJ3.js');
|
|
10616
|
+
const driverProblem = managedCodex ? null : await checkDriverSdk(opts.projectDir, opts.driver);
|
|
10617
|
+
if (driverProblem) {
|
|
10618
|
+
const { logErr: logErr2 } = await import('../helpers-Y4OT7VIS.js');
|
|
10619
|
+
logErr2(driverProblem);
|
|
10620
|
+
process.exitCode = 1;
|
|
10621
|
+
return;
|
|
10622
|
+
}
|
|
10623
|
+
try {
|
|
10624
|
+
await startAgentServer({
|
|
10625
|
+
port: parseInt(opts.port, 10),
|
|
10626
|
+
...opts.host ? { host: opts.host } : {},
|
|
10627
|
+
authTokenIntake: wsAuth,
|
|
10628
|
+
...managedCodex ? { managedCodex } : {},
|
|
10629
|
+
// The CLI owns its process, so a dead stdout pipe is fatal here.
|
|
10630
|
+
// `SKAILE_SERVE_EXIT_ON_BROKEN_STDOUT=0` opts out — the `local` /
|
|
10631
|
+
// `nix` deploy targets set it for children meant to outlive them.
|
|
10632
|
+
exitOnBrokenPipe: process.env.SKAILE_SERVE_EXIT_ON_BROKEN_STDOUT !== "0",
|
|
10633
|
+
projectDir: opts.projectDir,
|
|
10634
|
+
driver: opts.driver,
|
|
10635
|
+
model: opts.model,
|
|
10636
|
+
provider: opts.provider,
|
|
10637
|
+
sessionId: opts.sessionId,
|
|
10638
|
+
resumeSessionId: opts.resumeSessionId,
|
|
10639
|
+
...providers.length > 0 ? { providers } : {}
|
|
10640
|
+
});
|
|
10641
|
+
} catch (err2) {
|
|
10642
|
+
if (err2?.code !== "EADDRINUSE") throw err2;
|
|
10643
|
+
const { logErr: logErr2 } = await import('../helpers-Y4OT7VIS.js');
|
|
10644
|
+
logErr2(err2.message);
|
|
10645
|
+
process.exitCode = 1;
|
|
10646
|
+
}
|
|
10186
10647
|
}
|
|
10187
10648
|
);
|
|
10188
10649
|
}
|
|
10189
10650
|
async function ensurePluginsLoadedForServe(projectDir) {
|
|
10190
|
-
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-
|
|
10651
|
+
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-Y4OT7VIS.js');
|
|
10191
10652
|
try {
|
|
10192
10653
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
10193
10654
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
10194
10655
|
if (!config.plugins || config.plugins.length === 0) return;
|
|
10195
|
-
const { ensurePluginsLoaded } = await import('../plugin-store-
|
|
10656
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-XMZSPVBF.js');
|
|
10196
10657
|
const { pluginRegistry } = await import('../plugin-registry/index.js');
|
|
10197
10658
|
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
10198
10659
|
if (result.loaded.length > 0) {
|
|
@@ -10206,21 +10667,21 @@ async function ensurePluginsLoadedForServe(projectDir) {
|
|
|
10206
10667
|
}
|
|
10207
10668
|
}
|
|
10208
10669
|
async function runCompileTest(opts) {
|
|
10209
|
-
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-
|
|
10670
|
+
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-Y4OT7VIS.js');
|
|
10210
10671
|
const { tmpdir } = await import('os');
|
|
10211
|
-
const { dirname: dirname3, join:
|
|
10672
|
+
const { dirname: dirname3, join: join7, resolve: resolve5 } = await import('path');
|
|
10212
10673
|
const { fileURLToPath: fileURLToPath2 } = await import('url');
|
|
10213
|
-
const { unlinkSync, existsSync:
|
|
10674
|
+
const { unlinkSync, existsSync: existsSync20 } = await import('fs');
|
|
10214
10675
|
const { spawn } = await import('child_process');
|
|
10215
10676
|
const { portableSpawnSync: portableSpawnSync2 } = await import('../core/index.js');
|
|
10216
|
-
const { MONOREPO_ROOT } = await import('../paths-
|
|
10677
|
+
const { MONOREPO_ROOT } = await import('../paths-U6W6MQNQ.js');
|
|
10217
10678
|
if (MONOREPO_ROOT === null) {
|
|
10218
10679
|
logErr2("--compile-test is only available inside the skaile-dev workspace.");
|
|
10219
10680
|
logInfo2("Run it from a checkout of skaile-ai/skaile-dev (the monorepo shell).");
|
|
10220
10681
|
process.exitCode = 2;
|
|
10221
10682
|
return;
|
|
10222
10683
|
}
|
|
10223
|
-
const outfile =
|
|
10684
|
+
const outfile = join7(tmpdir(), `skaile-compile-test-${Date.now()}`);
|
|
10224
10685
|
const __thisFile = fileURLToPath2(import.meta.url);
|
|
10225
10686
|
const entryPoint = resolve5(dirname3(__thisFile), "..", "index.ts");
|
|
10226
10687
|
logInfo2(`Building compiled binary...`);
|
|
@@ -10275,7 +10736,7 @@ async function runCompileTest(opts) {
|
|
|
10275
10736
|
} catch {
|
|
10276
10737
|
}
|
|
10277
10738
|
try {
|
|
10278
|
-
if (
|
|
10739
|
+
if (existsSync20(outfile)) unlinkSync(outfile);
|
|
10279
10740
|
} catch {
|
|
10280
10741
|
}
|
|
10281
10742
|
}
|
|
@@ -10696,7 +11157,7 @@ function resolveMode2(opts) {
|
|
|
10696
11157
|
if (opts.forceLocal && opts.forceRemote) {
|
|
10697
11158
|
throw new Error("Cannot use both --local and --remote");
|
|
10698
11159
|
}
|
|
10699
|
-
const startDir =
|
|
11160
|
+
const startDir = path22__default.resolve(opts.projectDir ?? process.cwd());
|
|
10700
11161
|
const localDb = findLogsDb(startDir);
|
|
10701
11162
|
if (opts.forceLocal) {
|
|
10702
11163
|
if (!localDb) {
|
|
@@ -10729,14 +11190,14 @@ function resolveMode2(opts) {
|
|
|
10729
11190
|
function findLogsDb(startDir) {
|
|
10730
11191
|
let dir = startDir;
|
|
10731
11192
|
for (let i = 0; i < MAX_WALK_LEVELS; i++) {
|
|
10732
|
-
const candidate =
|
|
11193
|
+
const candidate = path22__default.join(dir, ".skaile", "logs.db");
|
|
10733
11194
|
if (existsSync(candidate)) {
|
|
10734
11195
|
try {
|
|
10735
11196
|
if (statSync(candidate).isFile()) return candidate;
|
|
10736
11197
|
} catch {
|
|
10737
11198
|
}
|
|
10738
11199
|
}
|
|
10739
|
-
const parent =
|
|
11200
|
+
const parent = path22__default.dirname(dir);
|
|
10740
11201
|
if (parent === dir) return void 0;
|
|
10741
11202
|
dir = parent;
|
|
10742
11203
|
}
|
|
@@ -10911,7 +11372,7 @@ function parsePositiveInt(value, flag) {
|
|
|
10911
11372
|
function makeSessionCommand() {
|
|
10912
11373
|
const cmd = new Command("session").description("Manage sessions");
|
|
10913
11374
|
cmd.command("list").description("List all sessions for a project").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
10914
|
-
const projectDir =
|
|
11375
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
10915
11376
|
const sessions = await listSessions(projectDir);
|
|
10916
11377
|
const current = await loadSession(projectDir);
|
|
10917
11378
|
if (sessions.length === 0) {
|
|
@@ -10939,7 +11400,7 @@ function makeSessionCommand() {
|
|
|
10939
11400
|
console.log();
|
|
10940
11401
|
});
|
|
10941
11402
|
cmd.command("show <run-id>").description("Show a specific session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10942
|
-
const projectDir =
|
|
11403
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
10943
11404
|
const session = await loadSessionById(projectDir, runId);
|
|
10944
11405
|
if (!session) {
|
|
10945
11406
|
logErr(`Session not found: ${runId}`);
|
|
@@ -10948,7 +11409,7 @@ function makeSessionCommand() {
|
|
|
10948
11409
|
console.log(JSON.stringify(session, null, 2));
|
|
10949
11410
|
});
|
|
10950
11411
|
cmd.command("switch <run-id>").description("Switch the current session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10951
|
-
const projectDir =
|
|
11412
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
10952
11413
|
if (!await loadSessionById(projectDir, runId)) {
|
|
10953
11414
|
logErr(`Session not found: ${runId}`);
|
|
10954
11415
|
process.exit(1);
|
|
@@ -10957,7 +11418,7 @@ function makeSessionCommand() {
|
|
|
10957
11418
|
logOk(`Switched to session: ${S.dim(runId.slice(0, 8))}`);
|
|
10958
11419
|
});
|
|
10959
11420
|
cmd.command("delete <run-id>").description("Delete a session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10960
|
-
const projectDir =
|
|
11421
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
10961
11422
|
if (!await loadSessionById(projectDir, runId)) {
|
|
10962
11423
|
logErr(`Session not found: ${runId}`);
|
|
10963
11424
|
process.exit(1);
|
|
@@ -11030,7 +11491,7 @@ function makeShowCommand() {
|
|
|
11030
11491
|
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) => {
|
|
11031
11492
|
const am2 = new AssetManager({
|
|
11032
11493
|
registry: getKindRegistry(),
|
|
11033
|
-
projectDir:
|
|
11494
|
+
projectDir: path22__default.resolve(opts.projectDir),
|
|
11034
11495
|
driverTarget: opts.target
|
|
11035
11496
|
});
|
|
11036
11497
|
if (!kind) {
|
|
@@ -11048,6 +11509,32 @@ function makeShowCommand() {
|
|
|
11048
11509
|
}
|
|
11049
11510
|
});
|
|
11050
11511
|
}
|
|
11512
|
+
function searchCuratedManifests(query) {
|
|
11513
|
+
const dir = getStoreManifestsDir();
|
|
11514
|
+
if (!existsSync(dir)) return [];
|
|
11515
|
+
const q = query.toLowerCase();
|
|
11516
|
+
const hits = [];
|
|
11517
|
+
for (const file of readdirSync(dir).sort()) {
|
|
11518
|
+
if (!file.endsWith(".yaml")) continue;
|
|
11519
|
+
const slug = file.slice(0, -".yaml".length);
|
|
11520
|
+
let manifest;
|
|
11521
|
+
try {
|
|
11522
|
+
manifest = decodeSkaileManifest(readFileSync(path22.join(dir, file), "utf-8")).manifest;
|
|
11523
|
+
} catch {
|
|
11524
|
+
continue;
|
|
11525
|
+
}
|
|
11526
|
+
const repoPublisher2 = manifest.publisher?.replace(/^@/, "");
|
|
11527
|
+
for (const a of manifest.assets ?? []) {
|
|
11528
|
+
const publisher = (a.publisher ?? repoPublisher2 ?? "").replace(/^@/, "");
|
|
11529
|
+
const haystack = [a.name, a.description ?? "", publisher, a.kind].join(" ").toLowerCase();
|
|
11530
|
+
if (!haystack.includes(q)) continue;
|
|
11531
|
+
hits.push({ slug, kind: a.kind, publisher, name: a.name, description: a.description });
|
|
11532
|
+
}
|
|
11533
|
+
}
|
|
11534
|
+
return hits;
|
|
11535
|
+
}
|
|
11536
|
+
|
|
11537
|
+
// cli/src/commands/store.ts
|
|
11051
11538
|
async function fetchIdentity() {
|
|
11052
11539
|
const jwt = await getStoreToken();
|
|
11053
11540
|
return storeFetch({ ...getStoreConfig(), jwt }, "/api/v1/me");
|
|
@@ -11093,43 +11580,70 @@ function makeStoreCommand() {
|
|
|
11093
11580
|
});
|
|
11094
11581
|
store.command("mode <auto|local|remote>").description("Set the catalog resolution mode (not yet wired)").action((_mode) => {
|
|
11095
11582
|
logErr(
|
|
11096
|
-
`\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${
|
|
11583
|
+
`\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${path22__default.join(globalSkaileDir(), "store", "config.yaml")}.`
|
|
11097
11584
|
);
|
|
11098
11585
|
process.exit(2);
|
|
11099
11586
|
});
|
|
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,
|
|
11101
|
-
|
|
11102
|
-
|
|
11103
|
-
|
|
11104
|
-
|
|
11105
|
-
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
|
|
11587
|
+
store.command("search <query>").description("Search the AI Asset Store catalog by name, description, or publisher").option("--kind <kind>", "Filter by asset kind (skill, prompt, flow, \u2026)").option(
|
|
11588
|
+
"--all",
|
|
11589
|
+
`List every match (default: ${STORE_ROW_LIMIT} rows, only what \`skaile add\` can install)`
|
|
11590
|
+
).option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (query, opts) => {
|
|
11591
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-N6ESO6IK.js');
|
|
11592
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
11593
|
+
const curated = searchCuratedManifests(query).filter(
|
|
11594
|
+
(h) => !opts.kind || h.kind === opts.kind
|
|
11595
|
+
);
|
|
11596
|
+
const printCurated = () => {
|
|
11597
|
+
if (curated.length === 0) return;
|
|
11598
|
+
console.log(`
|
|
11599
|
+
${S.heading("Local curated manifests")}`);
|
|
11600
|
+
for (const h of curated) {
|
|
11601
|
+
console.log(
|
|
11602
|
+
` ${kindColorPad(h.kind)} ${h.kind}:@${h.publisher}/${h.name} ${S.dim(`(manifest ${h.slug})`)}`
|
|
11603
|
+
);
|
|
11109
11604
|
}
|
|
11110
|
-
console.log();
|
|
11111
|
-
for (const row of formatStoreRows(results, " ")) console.log(row);
|
|
11112
11605
|
console.log(
|
|
11113
11606
|
`
|
|
11114
|
-
${S.dim(
|
|
11607
|
+
${S.dim("Not published: `skaile source add <repo URL>` indexes them for `skaile add`.")}
|
|
11115
11608
|
`
|
|
11116
11609
|
);
|
|
11610
|
+
};
|
|
11611
|
+
try {
|
|
11612
|
+
const remote = await openCatalogSource2({ projectDir });
|
|
11613
|
+
const assets = await remote.listAssets(opts.kind ? { kind: opts.kind } : {});
|
|
11614
|
+
const sel = selectStoreRows(filterCatalogAssets(assets, query), query, Boolean(opts.all));
|
|
11615
|
+
if (sel.shown.length === 0) {
|
|
11616
|
+
logInfo(`No store results for "${query}".`);
|
|
11617
|
+
for (const note of storeSelectionNotes(sel, "")) console.log(note);
|
|
11618
|
+
} else {
|
|
11619
|
+
console.log();
|
|
11620
|
+
for (const row of formatStoreRows(sel.shown, " ")) console.log(row);
|
|
11621
|
+
console.log(
|
|
11622
|
+
`
|
|
11623
|
+
${S.dim(`${sel.shown.length} result(s) \xB7 \`skaile store show <ref>\` for details`)}`
|
|
11624
|
+
);
|
|
11625
|
+
for (const note of storeSelectionNotes(sel, " ")) console.log(note);
|
|
11626
|
+
if (curated.length === 0) console.log();
|
|
11627
|
+
}
|
|
11628
|
+
printCurated();
|
|
11117
11629
|
} catch (e) {
|
|
11630
|
+
printCurated();
|
|
11631
|
+
if (e instanceof LocalCatalogDisabledError2 && curated.length > 0) return;
|
|
11118
11632
|
if (e instanceof LocalCatalogDisabledError2) {
|
|
11119
11633
|
logErr(
|
|
11120
11634
|
`Remote catalog disabled (catalog.url: local). Set \`catalog.url: https://skaile.store\` in ${userConfigPath()}.`
|
|
11121
11635
|
);
|
|
11122
11636
|
} else {
|
|
11123
|
-
logErr(`Store search failed: ${e
|
|
11637
|
+
logErr(`Store search failed: ${await describeStoreFailure(e, projectDir)}`);
|
|
11124
11638
|
}
|
|
11125
11639
|
process.exit(1);
|
|
11126
11640
|
}
|
|
11127
11641
|
});
|
|
11128
11642
|
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) => {
|
|
11129
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-
|
|
11130
|
-
const { supportsInstallManifest } = await import('../project-
|
|
11643
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-N6ESO6IK.js');
|
|
11644
|
+
const { supportsInstallManifest } = await import('../project-UP52HEHC.js');
|
|
11131
11645
|
try {
|
|
11132
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
11646
|
+
const remote = await openCatalogSource2({ projectDir: path22__default.resolve(opts.projectDir) });
|
|
11133
11647
|
const asset = await remote.resolve(ref);
|
|
11134
11648
|
if (!asset) {
|
|
11135
11649
|
logErr(`Not found in store: ${ref} (try a full ref, e.g. skill:@publisher/name#version)`);
|
|
@@ -11137,8 +11651,12 @@ function makeStoreCommand() {
|
|
|
11137
11651
|
}
|
|
11138
11652
|
const canonical = catalogAssetRef(asset);
|
|
11139
11653
|
let manifest = null;
|
|
11654
|
+
const manifestFailure = {};
|
|
11140
11655
|
if (supportsInstallManifest(remote)) {
|
|
11141
|
-
manifest = await remote.getInstallManifest(canonical).catch(() =>
|
|
11656
|
+
manifest = await remote.getInstallManifest(canonical).catch(async (err2) => {
|
|
11657
|
+
manifestFailure.text = await describeStoreFailure(err2, path22__default.resolve(opts.projectDir));
|
|
11658
|
+
return null;
|
|
11659
|
+
});
|
|
11142
11660
|
}
|
|
11143
11661
|
const field = (label, value) => ` ${S.label(label.padEnd(11))}${value}`;
|
|
11144
11662
|
console.log();
|
|
@@ -11168,13 +11686,25 @@ function makeStoreCommand() {
|
|
|
11168
11686
|
console.log(field("Repo", asset.repo));
|
|
11169
11687
|
if (asset.sha256) console.log(field("Integrity", asset.sha256));
|
|
11170
11688
|
}
|
|
11689
|
+
if (!manifest && manifestFailure.text) {
|
|
11690
|
+
console.log();
|
|
11691
|
+
console.log(field("Files", S.dim(`unavailable (${manifestFailure.text})`)));
|
|
11692
|
+
}
|
|
11693
|
+
if (asset.requires?.length) {
|
|
11694
|
+
console.log();
|
|
11695
|
+
console.log(` ${S.heading("Requires")}`);
|
|
11696
|
+
for (const dep of asset.requires) console.log(` ${S.dim("\u2192")} ${dep}`);
|
|
11697
|
+
}
|
|
11171
11698
|
if (asset.softDeps?.length) {
|
|
11172
11699
|
console.log();
|
|
11173
11700
|
console.log(` ${S.heading("Soft dependencies")}`);
|
|
11174
11701
|
for (const dep of asset.softDeps) console.log(` ${S.dim("\u2192")} ${dep}`);
|
|
11175
11702
|
}
|
|
11176
11703
|
console.log();
|
|
11177
|
-
|
|
11704
|
+
const notInstallable = storeNotInstallableReason(asset);
|
|
11705
|
+
console.log(
|
|
11706
|
+
notInstallable ? ` ${S.dim(`Not installable: ${notInstallable}`)}` : ` ${S.dim(`Install: skaile add ${canonical}`)}`
|
|
11707
|
+
);
|
|
11178
11708
|
console.log();
|
|
11179
11709
|
} catch (e) {
|
|
11180
11710
|
if (e instanceof LocalCatalogDisabledError2) {
|
|
@@ -11182,7 +11712,9 @@ function makeStoreCommand() {
|
|
|
11182
11712
|
`Remote catalog disabled (catalog.url: local). Set \`catalog.url: https://skaile.store\` in ${userConfigPath()}.`
|
|
11183
11713
|
);
|
|
11184
11714
|
} else {
|
|
11185
|
-
logErr(
|
|
11715
|
+
logErr(
|
|
11716
|
+
`Store show failed: ${await describeStoreFailure(e, path22__default.resolve(opts.projectDir))}`
|
|
11717
|
+
);
|
|
11186
11718
|
}
|
|
11187
11719
|
process.exit(1);
|
|
11188
11720
|
}
|
|
@@ -11252,9 +11784,10 @@ function treeRefs(nodes) {
|
|
|
11252
11784
|
}
|
|
11253
11785
|
function makeTreeCommand() {
|
|
11254
11786
|
return new Command("tree").description("Show full dependency tree").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
11787
|
+
requireProjectConfig(opts.projectDir);
|
|
11255
11788
|
const am2 = new AssetManager({
|
|
11256
11789
|
registry: getKindRegistry(),
|
|
11257
|
-
projectDir:
|
|
11790
|
+
projectDir: path22__default.resolve(opts.projectDir)
|
|
11258
11791
|
});
|
|
11259
11792
|
const root = await am2.tree();
|
|
11260
11793
|
if (root.children.length === 0) {
|
|
@@ -11281,7 +11814,7 @@ function makeUpdateCommand() {
|
|
|
11281
11814
|
"Update only this declared asset (kind:@publisher/name, kind:name or name); exits 1 when none matches"
|
|
11282
11815
|
).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
11816
|
async (name, opts) => {
|
|
11284
|
-
const projectDir =
|
|
11817
|
+
const projectDir = path22__default.resolve(opts.projectDir);
|
|
11285
11818
|
if (!opts.catalogOnly) requireProjectConfig(projectDir);
|
|
11286
11819
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
|
|
11287
11820
|
const target = name !== void 0 && !opts.catalogOnly ? await resolveUpdateTarget(am2, name) : void 0;
|
|
@@ -11289,7 +11822,7 @@ function makeUpdateCommand() {
|
|
|
11289
11822
|
const catalogSpinner = createSpinner();
|
|
11290
11823
|
catalogSpinner.start("Refreshing catalog cache");
|
|
11291
11824
|
try {
|
|
11292
|
-
const remote = await openCatalogSource({ projectDir:
|
|
11825
|
+
const remote = await openCatalogSource({ projectDir: path22__default.resolve(opts.projectDir) });
|
|
11293
11826
|
const result2 = await remote.refresh();
|
|
11294
11827
|
catalogSpinner.stop(
|
|
11295
11828
|
`Catalog refreshed: ${S.heading(String(result2.assetsCached))} assets cached`
|
|
@@ -11301,6 +11834,10 @@ function makeUpdateCommand() {
|
|
|
11301
11834
|
} else {
|
|
11302
11835
|
catalogSpinner.stop("Catalog refresh failed");
|
|
11303
11836
|
logErr(`Catalog refresh failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
11837
|
+
if (opts.catalogOnly) {
|
|
11838
|
+
logInfo("Run `skaile catalog test` to debug.");
|
|
11839
|
+
process.exit(1);
|
|
11840
|
+
}
|
|
11304
11841
|
logInfo("Continuing with asset re-deploy. Run `skaile catalog test` to debug.");
|
|
11305
11842
|
}
|
|
11306
11843
|
}
|
|
@@ -11414,13 +11951,16 @@ function readText2(file) {
|
|
|
11414
11951
|
}
|
|
11415
11952
|
}
|
|
11416
11953
|
async function updateOne(am2, projectDir, target) {
|
|
11417
|
-
const lockPath =
|
|
11954
|
+
const lockPath = path22__default.join(projectDir, "skaile.lock.yaml");
|
|
11418
11955
|
const before = readText2(lockPath);
|
|
11419
11956
|
const spinner = createSpinner();
|
|
11420
11957
|
spinner.start(`Updating ${target.ref}`);
|
|
11421
11958
|
let deployed;
|
|
11422
11959
|
try {
|
|
11423
|
-
deployed = await am2.add(target.ref, {
|
|
11960
|
+
deployed = await am2.add(target.ref, {
|
|
11961
|
+
preferLockedLibrary: true,
|
|
11962
|
+
onLibraryMoved: (m) => reportMoved([m])
|
|
11963
|
+
});
|
|
11424
11964
|
} catch (err2) {
|
|
11425
11965
|
spinner.stop("Failed");
|
|
11426
11966
|
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
@@ -11545,9 +12085,10 @@ function whyEmptyMessage(ref, declared) {
|
|
|
11545
12085
|
}
|
|
11546
12086
|
function makeWhyCommand() {
|
|
11547
12087
|
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) => {
|
|
12088
|
+
requireProjectConfig(opts.projectDir);
|
|
11548
12089
|
const am2 = new AssetManager({
|
|
11549
12090
|
registry: getKindRegistry(),
|
|
11550
|
-
projectDir:
|
|
12091
|
+
projectDir: path22__default.resolve(opts.projectDir)
|
|
11551
12092
|
});
|
|
11552
12093
|
const chain = await am2.why(ref);
|
|
11553
12094
|
if (chain.length === 0) {
|
|
@@ -11588,11 +12129,38 @@ function makeWhyCommand() {
|
|
|
11588
12129
|
});
|
|
11589
12130
|
}
|
|
11590
12131
|
|
|
12132
|
+
// cli/src/index-busy.ts
|
|
12133
|
+
var INDEX_BUSY_MESSAGE = "The skaile index is busy (another skaile process holds it); retry in a moment.";
|
|
12134
|
+
function isIndexBusyError(err2) {
|
|
12135
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12136
|
+
let cur = err2;
|
|
12137
|
+
while (cur && typeof cur === "object" && !seen.has(cur)) {
|
|
12138
|
+
seen.add(cur);
|
|
12139
|
+
const { code, message, cause } = cur;
|
|
12140
|
+
if (typeof code === "string" && code.startsWith("SQLITE_BUSY")) return true;
|
|
12141
|
+
if (typeof message === "string" && /SQLITE_BUSY|database is locked/i.test(message)) return true;
|
|
12142
|
+
cur = cause;
|
|
12143
|
+
}
|
|
12144
|
+
return false;
|
|
12145
|
+
}
|
|
12146
|
+
|
|
11591
12147
|
// cli/src/index.ts
|
|
12148
|
+
{
|
|
12149
|
+
const envLevel = process.env.SKAILE_LOG_LEVEL;
|
|
12150
|
+
const level = envLevel === "debug" || envLevel === "info" || envLevel === "warn" || envLevel === "error" ? envLevel : "warn";
|
|
12151
|
+
registerLogStore(
|
|
12152
|
+
new LogStore({
|
|
12153
|
+
sessionId: "cli",
|
|
12154
|
+
level,
|
|
12155
|
+
flushIntervalMs: 0,
|
|
12156
|
+
sinks: [new StdoutSink({ stream: "stderr", format: "pretty" })]
|
|
12157
|
+
})
|
|
12158
|
+
);
|
|
12159
|
+
}
|
|
11592
12160
|
var _defaultFormatHelp = Help.prototype.formatHelp;
|
|
11593
12161
|
var pkg = JSON.parse(
|
|
11594
12162
|
readFileSync(
|
|
11595
|
-
|
|
12163
|
+
path22__default.resolve(path22__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
|
|
11596
12164
|
"utf-8"
|
|
11597
12165
|
)
|
|
11598
12166
|
);
|
|
@@ -11603,7 +12171,7 @@ for (const key of [
|
|
|
11603
12171
|
"SKAILE_CACHE_DIR"
|
|
11604
12172
|
]) {
|
|
11605
12173
|
const value = process.env[key];
|
|
11606
|
-
if (value) process.env[key] =
|
|
12174
|
+
if (value) process.env[key] = path22__default.resolve(value);
|
|
11607
12175
|
}
|
|
11608
12176
|
var program = new Command("skaile").description("AI asset manager").version(pkg.version, "-v, --version", "Show the skaile CLI version").enablePositionalOptions().configureHelp({
|
|
11609
12177
|
formatHelp(cmd, helper) {
|
|
@@ -11648,7 +12216,7 @@ Execution:
|
|
|
11648
12216
|
repl Interactive agent REPL
|
|
11649
12217
|
resume Resume last session
|
|
11650
12218
|
serve [--compile-test] Start WebSocket agent server
|
|
11651
|
-
mcp-server Start workspace MCP server (for .
|
|
12219
|
+
mcp-server Start workspace MCP server (for .mcp.json)
|
|
11652
12220
|
integration install [--driver all] Install agent integration (claude-code | omp | codex)
|
|
11653
12221
|
integration uninstall [--driver all] Uninstall agent integration
|
|
11654
12222
|
integration enable Enable integration (claude-code only)
|
|
@@ -11723,7 +12291,7 @@ program.command("init [project-dir]").description("Initialize a project director
|
|
|
11723
12291
|
(projectDir, opts) => runInit(projectDir, opts)
|
|
11724
12292
|
);
|
|
11725
12293
|
async function runInit(projectDir, opts) {
|
|
11726
|
-
const { mkdirSync: mkdirSync5, writeFileSync:
|
|
12294
|
+
const { mkdirSync: mkdirSync5, writeFileSync: writeFileSync7 } = await import('fs');
|
|
11727
12295
|
const { stringify: stringify2 } = await import('yaml');
|
|
11728
12296
|
const { DRIVER_TARGETS, SUPPORTED_DRIVER_TARGETS: SUPPORTED_DRIVER_TARGETS2 } = await import('../core/index.js');
|
|
11729
12297
|
const harness = opts.harness;
|
|
@@ -11732,32 +12300,32 @@ async function runInit(projectDir, opts) {
|
|
|
11732
12300
|
process.exitCode = 1;
|
|
11733
12301
|
return;
|
|
11734
12302
|
}
|
|
11735
|
-
const resolved =
|
|
11736
|
-
const projectName =
|
|
12303
|
+
const resolved = path22__default.resolve(projectDir ?? ".");
|
|
12304
|
+
const projectName = path22__default.basename(resolved);
|
|
11737
12305
|
const created = [];
|
|
11738
|
-
const { existsSync:
|
|
11739
|
-
if (!
|
|
12306
|
+
const { existsSync: existsSync20 } = await import('fs');
|
|
12307
|
+
if (!existsSync20(resolved)) {
|
|
11740
12308
|
mkdirSync5(resolved, { recursive: true });
|
|
11741
12309
|
created.push(".");
|
|
11742
12310
|
}
|
|
11743
|
-
const skaileDir =
|
|
11744
|
-
if (!
|
|
11745
|
-
mkdirSync5(
|
|
12311
|
+
const skaileDir = path22__default.join(resolved, ".skaile");
|
|
12312
|
+
if (!existsSync20(skaileDir)) {
|
|
12313
|
+
mkdirSync5(path22__default.join(skaileDir, "sessions"), { recursive: true });
|
|
11746
12314
|
created.push(".skaile/");
|
|
11747
12315
|
}
|
|
11748
|
-
const settingsPath =
|
|
11749
|
-
if (!
|
|
11750
|
-
|
|
12316
|
+
const settingsPath = path22__default.join(skaileDir, "settings.json");
|
|
12317
|
+
if (!existsSync20(settingsPath)) {
|
|
12318
|
+
writeFileSync7(settingsPath, "{}\n");
|
|
11751
12319
|
created.push(".skaile/settings.json");
|
|
11752
12320
|
}
|
|
11753
|
-
const wsConfigPath =
|
|
11754
|
-
if (!
|
|
11755
|
-
|
|
12321
|
+
const wsConfigPath = path22__default.join(resolved, "skaile.yaml");
|
|
12322
|
+
if (!existsSync20(wsConfigPath)) {
|
|
12323
|
+
writeFileSync7(wsConfigPath, stringify2(buildInitWorkspaceConfig(projectName, harness)));
|
|
11756
12324
|
created.push("skaile.yaml");
|
|
11757
12325
|
}
|
|
11758
12326
|
for (const dir of new Set(Object.values(DRIVER_TARGETS[harness].local))) {
|
|
11759
|
-
const full =
|
|
11760
|
-
if (!
|
|
12327
|
+
const full = path22__default.join(resolved, dir);
|
|
12328
|
+
if (!existsSync20(full)) {
|
|
11761
12329
|
mkdirSync5(full, { recursive: true });
|
|
11762
12330
|
created.push(`${dir}/`);
|
|
11763
12331
|
}
|
|
@@ -11787,10 +12355,13 @@ function buildInitWorkspaceConfig(projectName, harness) {
|
|
|
11787
12355
|
}
|
|
11788
12356
|
async function initGitScaffold(resolved, created) {
|
|
11789
12357
|
const { execSync: execSync2 } = await import('child_process');
|
|
11790
|
-
const { existsSync:
|
|
11791
|
-
const gitignorePath =
|
|
12358
|
+
const { existsSync: existsSync20, readFileSync: readFileSync12, writeFileSync: writeFileSync7 } = await import('fs');
|
|
12359
|
+
const gitignorePath = path22__default.join(resolved, ".gitignore");
|
|
11792
12360
|
const entries = [
|
|
11793
12361
|
"node_modules/",
|
|
12362
|
+
// Python bytecode a deployed skill script leaves inside `.claude/skills` and friends.
|
|
12363
|
+
"__pycache__/",
|
|
12364
|
+
"*.pyc",
|
|
11794
12365
|
".skaile/sessions/",
|
|
11795
12366
|
".skaile/cache/",
|
|
11796
12367
|
// skaile-created artifacts that must never be committed: the per-session log
|
|
@@ -11801,20 +12372,25 @@ async function initGitScaffold(resolved, created) {
|
|
|
11801
12372
|
".skaile/settings.json",
|
|
11802
12373
|
".skaile/providers.yml",
|
|
11803
12374
|
".skaile/history.yaml",
|
|
12375
|
+
// Per-machine files a run writes into the project: the system prompt handed to the harness
|
|
12376
|
+
// (it carries the host path) and omp's session logs.
|
|
12377
|
+
".codex/skaile-session-instructions.md",
|
|
12378
|
+
".omp/system.md",
|
|
12379
|
+
".omp/sessions/",
|
|
11804
12380
|
"*.log",
|
|
11805
12381
|
".env",
|
|
11806
12382
|
".env.local"
|
|
11807
12383
|
];
|
|
11808
|
-
const existing =
|
|
12384
|
+
const existing = existsSync20(gitignorePath) ? readFileSync12(gitignorePath, "utf-8") : "";
|
|
11809
12385
|
const have = new Set(existing.split("\n").map((l) => l.trim()));
|
|
11810
12386
|
const append = entries.filter((e) => !have.has(e));
|
|
11811
12387
|
if (append.length > 0) {
|
|
11812
12388
|
const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
11813
|
-
|
|
12389
|
+
writeFileSync7(gitignorePath, `${existing + prefix}${append.join("\n")}
|
|
11814
12390
|
`);
|
|
11815
12391
|
if (!existing) created.push(".gitignore");
|
|
11816
12392
|
}
|
|
11817
|
-
if (!
|
|
12393
|
+
if (!existsSync20(path22__default.join(resolved, ".git"))) {
|
|
11818
12394
|
try {
|
|
11819
12395
|
execSync2("git init", { cwd: resolved, stdio: "pipe" });
|
|
11820
12396
|
created.push(".git/");
|
|
@@ -11844,7 +12420,7 @@ async function bootstrapUserConfig() {
|
|
|
11844
12420
|
}
|
|
11845
12421
|
async function hydrateInitSources(resolved, created) {
|
|
11846
12422
|
try {
|
|
11847
|
-
const { ensureSourcesCloned } = await import('../ensure-sources-
|
|
12423
|
+
const { ensureSourcesCloned } = await import('../ensure-sources-POMEQSTM.js');
|
|
11848
12424
|
const hydrate = ensureSourcesCloned(resolved, { quiet: true });
|
|
11849
12425
|
for (const n of hydrate.cloned) created.push(`~/.skaile/cache/sources/${n}/`);
|
|
11850
12426
|
if (hydrate.failed.length > 0) {
|
|
@@ -11860,7 +12436,7 @@ function printInitSummary(resolved, projectDir, created) {
|
|
|
11860
12436
|
logOk(`Initialized project at ${S.heading(resolved)}`);
|
|
11861
12437
|
console.log();
|
|
11862
12438
|
console.log(S.heading(" Next steps:"));
|
|
11863
|
-
const isCurrentDir = resolved ===
|
|
12439
|
+
const isCurrentDir = resolved === path22__default.resolve(".");
|
|
11864
12440
|
let step = 1;
|
|
11865
12441
|
if (!isCurrentDir) {
|
|
11866
12442
|
console.log(` ${S.dim(`${step}.`)} ${S.cmd(`cd ${projectDir}`)}`);
|
|
@@ -11884,7 +12460,7 @@ function printInitSummary(resolved, projectDir, created) {
|
|
|
11884
12460
|
console.log();
|
|
11885
12461
|
}
|
|
11886
12462
|
program.command("setup").description("Interactive provider setup wizard").action(async () => {
|
|
11887
|
-
const { cmdSetup } = await import('../setup-
|
|
12463
|
+
const { cmdSetup } = await import('../setup-5IRUH5OS.js');
|
|
11888
12464
|
await cmdSetup([], { projectDir: process.cwd() });
|
|
11889
12465
|
});
|
|
11890
12466
|
program.addCommand(makeInstallCommand());
|
|
@@ -11972,6 +12548,10 @@ try {
|
|
|
11972
12548
|
await program.parseAsync();
|
|
11973
12549
|
commandSettled = true;
|
|
11974
12550
|
} catch (err2) {
|
|
12551
|
+
if (isIndexBusyError(err2)) {
|
|
12552
|
+
logErr(INDEX_BUSY_MESSAGE);
|
|
12553
|
+
process.exit(1);
|
|
12554
|
+
}
|
|
11975
12555
|
const { LibrarySyncError } = await import('../library/index.js');
|
|
11976
12556
|
if (!(err2 instanceof LibrarySyncError || err2 instanceof SourceEntryError)) throw err2;
|
|
11977
12557
|
logErr(err2.message);
|