@skaile/workspaces 5.8.0 → 5.10.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 +102 -0
- package/dist/app-sdk/index.js +1 -1
- package/dist/{asset-feeds-EYRZR4K5.js → asset-feeds-ELEBTNUS.js} +18 -18
- package/dist/{asset-feeds-EYRZR4K5.js.map → asset-feeds-ELEBTNUS.js.map} +1 -1
- package/dist/asset-manager/catalog-deployer.js +8 -8
- package/dist/asset-manager/index.js +14 -14
- package/dist/asset-manager/installer.js +10 -10
- package/dist/asset-manager/renderers.js +9 -9
- package/dist/asset-manager/src/index.d.ts +300 -36
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/install-agent.d.ts +3 -1
- package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
- package/dist/asset-manager/src/install-instances.d.ts +31 -1
- package/dist/asset-manager/src/install-instances.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts +20 -0
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/asset-manager/src/renderers.d.ts +4 -5
- package/dist/asset-manager/src/renderers.d.ts.map +1 -1
- package/dist/bridge/drivers/claude-sdk.js +170 -17
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +13 -11
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/continue.js +10 -10
- package/dist/bridge/drivers/echo.js +4 -4
- package/dist/bridge/drivers/gemini.js +7 -7
- package/dist/bridge/drivers/goose.js +10 -10
- package/dist/bridge/drivers/omp.js +7 -5
- 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 +14 -14
- package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
- package/dist/bridge/src/drivers/claude-sdk.d.ts +31 -1
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/claude-tool-allowlist.d.ts +43 -0
- package/dist/bridge/src/drivers/claude-tool-allowlist.d.ts.map +1 -0
- package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
- package/dist/bridge/src/types.d.ts +20 -1
- package/dist/bridge/src/types.d.ts.map +1 -1
- package/dist/{chunk-36AFURKZ.js → chunk-2FMEGSBN.js} +38 -11
- package/dist/chunk-2FMEGSBN.js.map +1 -0
- package/dist/{chunk-GCICGXDD.js → chunk-2H73V6XR.js} +3 -3
- package/dist/{chunk-GCICGXDD.js.map → chunk-2H73V6XR.js.map} +1 -1
- package/dist/{chunk-H7QUDDKH.js → chunk-2JMLDZLP.js} +1069 -182
- package/dist/chunk-2JMLDZLP.js.map +1 -0
- package/dist/{chunk-B6GIW55K.js → chunk-32XKCNCL.js} +6 -3
- package/dist/chunk-32XKCNCL.js.map +1 -0
- package/dist/{chunk-4MQS7CAF.js → chunk-3BEY4WK3.js} +371 -175
- package/dist/chunk-3BEY4WK3.js.map +1 -0
- package/dist/{chunk-SH5D7U7N.js → chunk-3KHYGOEY.js} +3 -3
- package/dist/{chunk-SH5D7U7N.js.map → chunk-3KHYGOEY.js.map} +1 -1
- package/dist/{chunk-CGT45WN7.js → chunk-3MKPZZRE.js} +3 -3
- package/dist/{chunk-CGT45WN7.js.map → chunk-3MKPZZRE.js.map} +1 -1
- package/dist/{chunk-QVNRCDTV.js → chunk-4OV5DSBB.js} +4 -4
- package/dist/chunk-4OV5DSBB.js.map +1 -0
- package/dist/{chunk-GXXFLBUQ.js → chunk-4P3KTUZH.js} +33 -33
- package/dist/chunk-4P3KTUZH.js.map +1 -0
- package/dist/{chunk-I6NLLJHZ.js → chunk-5QI2JYJC.js} +2 -2
- package/dist/{chunk-I6NLLJHZ.js.map → chunk-5QI2JYJC.js.map} +1 -1
- package/dist/{chunk-EF7NPDDU.js → chunk-6HHE63CO.js} +31 -17
- package/dist/chunk-6HHE63CO.js.map +1 -0
- package/dist/{chunk-FTJJO3EM.js → chunk-7CR6HT2X.js} +10 -10
- package/dist/{chunk-FTJJO3EM.js.map → chunk-7CR6HT2X.js.map} +1 -1
- package/dist/{chunk-FZNG4V4J.js → chunk-7I5VRVDP.js} +3 -3
- package/dist/{chunk-FZNG4V4J.js.map → chunk-7I5VRVDP.js.map} +1 -1
- package/dist/{chunk-HG34RNTK.js → chunk-CLTHEKHR.js} +10 -9
- package/dist/chunk-CLTHEKHR.js.map +1 -0
- package/dist/{chunk-UMVKJM4Q.js → chunk-DALV4HHP.js} +18 -3
- package/dist/chunk-DALV4HHP.js.map +1 -0
- package/dist/{chunk-F3RDEH5U.js → chunk-F4NJDSR7.js} +6 -5
- package/dist/chunk-F4NJDSR7.js.map +1 -0
- package/dist/{chunk-LSXHED6I.js → chunk-FRPBSUFH.js} +6 -6
- package/dist/{chunk-LSXHED6I.js.map → chunk-FRPBSUFH.js.map} +1 -1
- package/dist/{chunk-W5DWWE4Y.js → chunk-G54USEUP.js} +4 -4
- package/dist/{chunk-W5DWWE4Y.js.map → chunk-G54USEUP.js.map} +1 -1
- package/dist/{chunk-Y7QA2OLD.js → chunk-GEWAIQZ5.js} +24 -20
- package/dist/chunk-GEWAIQZ5.js.map +1 -0
- package/dist/{chunk-GB7WDMH2.js → chunk-GFCXNFTW.js} +4 -4
- package/dist/{chunk-GB7WDMH2.js.map → chunk-GFCXNFTW.js.map} +1 -1
- package/dist/{chunk-AWQYXZVG.js → chunk-HJ5MCB3L.js} +28 -4
- package/dist/chunk-HJ5MCB3L.js.map +1 -0
- package/dist/{chunk-2LWYNQK7.js → chunk-HOHUEKES.js} +3 -3
- package/dist/{chunk-2LWYNQK7.js.map → chunk-HOHUEKES.js.map} +1 -1
- package/dist/{chunk-ZKSJMZKD.js → chunk-IJHH4DSW.js} +8 -8
- package/dist/{chunk-ZKSJMZKD.js.map → chunk-IJHH4DSW.js.map} +1 -1
- package/dist/{chunk-BTE2V4IW.js → chunk-IXWODEED.js} +40 -7
- package/dist/chunk-IXWODEED.js.map +1 -0
- package/dist/{chunk-OFBIWVCR.js → chunk-JFXQEVLF.js} +3 -3
- package/dist/{chunk-OFBIWVCR.js.map → chunk-JFXQEVLF.js.map} +1 -1
- package/dist/{chunk-JAKOMFC6.js → chunk-JZCSNEHK.js} +77 -31
- package/dist/chunk-JZCSNEHK.js.map +1 -0
- package/dist/{chunk-CKQEIY43.js → chunk-MVQ3Q2HM.js} +4 -4
- package/dist/{chunk-CKQEIY43.js.map → chunk-MVQ3Q2HM.js.map} +1 -1
- package/dist/{chunk-LEMHVDET.js → chunk-NRDSGLCQ.js} +188 -33
- package/dist/chunk-NRDSGLCQ.js.map +1 -0
- package/dist/{chunk-V2DXZYBB.js → chunk-NWDSLXOX.js} +3 -3
- package/dist/{chunk-V2DXZYBB.js.map → chunk-NWDSLXOX.js.map} +1 -1
- package/dist/{chunk-6GRX5L6A.js → chunk-OBVJ7RPW.js} +4 -4
- package/dist/{chunk-6GRX5L6A.js.map → chunk-OBVJ7RPW.js.map} +1 -1
- package/dist/{chunk-PTSGWKHR.js → chunk-OOWHXOK6.js} +4 -4
- package/dist/{chunk-PTSGWKHR.js.map → chunk-OOWHXOK6.js.map} +1 -1
- package/dist/{chunk-YSHVQGUS.js → chunk-PE36IF2D.js} +119 -30
- package/dist/chunk-PE36IF2D.js.map +1 -0
- package/dist/{chunk-S53LOR7B.js → chunk-QG3HOJEK.js} +3 -3
- package/dist/{chunk-S53LOR7B.js.map → chunk-QG3HOJEK.js.map} +1 -1
- package/dist/{chunk-2FRUUDZY.js → chunk-SBFW3CJH.js} +5 -5
- package/dist/{chunk-2FRUUDZY.js.map → chunk-SBFW3CJH.js.map} +1 -1
- package/dist/{chunk-UAROCOXF.js → chunk-SX5U422E.js} +3 -3
- package/dist/{chunk-UAROCOXF.js.map → chunk-SX5U422E.js.map} +1 -1
- package/dist/{chunk-QOP6KDFR.js → chunk-TH4CTXHX.js} +6 -6
- package/dist/{chunk-QOP6KDFR.js.map → chunk-TH4CTXHX.js.map} +1 -1
- package/dist/{chunk-F2EKONM7.js → chunk-TRSQP3JD.js} +3 -3
- package/dist/{chunk-F2EKONM7.js.map → chunk-TRSQP3JD.js.map} +1 -1
- package/dist/{chunk-FVJK4QWM.js → chunk-V5TZH4GF.js} +4 -4
- package/dist/{chunk-FVJK4QWM.js.map → chunk-V5TZH4GF.js.map} +1 -1
- package/dist/{chunk-HYDRDNKN.js → chunk-V7PQZOBR.js} +5 -5
- package/dist/{chunk-HYDRDNKN.js.map → chunk-V7PQZOBR.js.map} +1 -1
- package/dist/{chunk-IONAUNWB.js → chunk-VLXDXRRX.js} +3 -3
- package/dist/{chunk-IONAUNWB.js.map → chunk-VLXDXRRX.js.map} +1 -1
- package/dist/{chunk-CIFS5K6T.js → chunk-VMKMFS2Q.js} +28 -7
- package/dist/chunk-VMKMFS2Q.js.map +1 -0
- package/dist/{chunk-Y4N2NUZD.js → chunk-WBYDAL6X.js} +4 -4
- package/dist/{chunk-Y4N2NUZD.js.map → chunk-WBYDAL6X.js.map} +1 -1
- package/dist/{chunk-WTQ3TATB.js → chunk-X4BAYGMT.js} +3 -3
- package/dist/{chunk-WTQ3TATB.js.map → chunk-X4BAYGMT.js.map} +1 -1
- package/dist/{chunk-NPLPCRW5.js → chunk-XCNK4UE5.js} +5 -5
- package/dist/{chunk-NPLPCRW5.js.map → chunk-XCNK4UE5.js.map} +1 -1
- package/dist/{chunk-OJ4N4T4H.js → chunk-XDVR7QIT.js} +20 -6
- package/dist/chunk-XDVR7QIT.js.map +1 -0
- package/dist/{chunk-GTILM2CI.js → chunk-Y34MSWEZ.js} +43 -12
- package/dist/chunk-Y34MSWEZ.js.map +1 -0
- package/dist/{chunk-4PTSR4UU.js → chunk-Y63UQZ7P.js} +3 -3
- package/dist/{chunk-4PTSR4UU.js.map → chunk-Y63UQZ7P.js.map} +1 -1
- package/dist/chunk-YBQONMH2.js +465 -0
- package/dist/chunk-YBQONMH2.js.map +1 -0
- package/dist/{chunk-P23M65LB.js → chunk-Z2K6BGUR.js} +71 -24
- package/dist/chunk-Z2K6BGUR.js.map +1 -0
- package/dist/{chunk-BJNUNQAW.js → chunk-ZGQTS3Y4.js} +3 -3
- package/dist/{chunk-BJNUNQAW.js.map → chunk-ZGQTS3Y4.js.map} +1 -1
- package/dist/cli/index.js +913 -720
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +8 -5
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/diff.d.ts +3 -1
- package/dist/cli/src/commands/diff.d.ts.map +1 -1
- package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/library-index.d.ts +34 -2
- package/dist/cli/src/commands/library-index.d.ts.map +1 -1
- package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
- package/dist/cli/src/commands/manage.d.ts +6 -5
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
- package/dist/cli/src/commands/outdated.d.ts +7 -5
- package/dist/cli/src/commands/outdated.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts +11 -8
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts +30 -1
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/update.d.ts.map +1 -1
- package/dist/cli/src/commands/validate.d.ts.map +1 -1
- package/dist/cli/src/commands/why.d.ts.map +1 -1
- package/dist/cli/src/skill-checks.d.ts +47 -2
- package/dist/cli/src/skill-checks.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/src/client.d.ts +10 -3
- package/dist/client/src/client.d.ts.map +1 -1
- package/dist/connectors/config.js +5 -5
- package/dist/connectors/index.js +18 -18
- package/dist/{connectors-O6Y6VESP.js → connectors-OXP2JBGI.js} +21 -21
- package/dist/{connectors-O6Y6VESP.js.map → connectors-OXP2JBGI.js.map} +1 -1
- package/dist/connectors-shared/index.js +2 -2
- package/dist/core/index.js +7 -7
- package/dist/core/logging.js +1 -1
- package/dist/core/manifest.js +2 -2
- package/dist/core/models.js +1 -1
- package/dist/core/publish-manifest.js +2 -2
- package/dist/core/ref.js +1 -1
- package/dist/core/runtime-assets.js +5 -5
- package/dist/core/src/index.d.ts +2 -1
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/lock.d.ts +5 -2
- package/dist/core/src/lock.d.ts.map +1 -1
- package/dist/core/src/logging/sinks/sqlite-runtime.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +21 -5
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/publish-manifest.d.ts +19 -3
- package/dist/core/src/publish-manifest.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/requirements.d.ts +26 -0
- package/dist/core/src/requirements.d.ts.map +1 -0
- package/dist/core/src/walker.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +18 -0
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/src/workspace-yaml-editor.d.ts +4 -1
- package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
- package/dist/core/workspace-config.js +4 -4
- package/dist/deploy/index.js +7 -7
- package/dist/discovery/index.js +5 -5
- package/dist/discovery/src/builtin-providers.d.ts.map +1 -1
- package/dist/discovery/src/discover-manifest.d.ts.map +1 -1
- package/dist/discovery/src/discover.d.ts.map +1 -1
- package/dist/discovery/src/source-config.d.ts.map +1 -1
- package/dist/discovery/src/tree-entries.d.ts.map +1 -1
- package/dist/{ensure-sources-SKLNM4UZ.js → ensure-sources-5ISVIA4T.js} +17 -17
- package/dist/{ensure-sources-SKLNM4UZ.js.map → ensure-sources-5ISVIA4T.js.map} +1 -1
- package/dist/factory-assets/connectors/box.js +18 -18
- package/dist/factory-assets/connectors/deploy.js +18 -18
- package/dist/factory-assets/connectors/devserver.js +18 -18
- package/dist/factory-assets/connectors/flow/adapter.js +18 -18
- package/dist/factory-assets/connectors/flow/engine.js +8 -8
- package/dist/factory-assets/connectors/flow/run-flow.js +20 -20
- package/dist/factory-assets/connectors/flow.js +18 -18
- package/dist/factory-assets/connectors/git.js +18 -18
- package/dist/factory-assets/connectors/gmail.js +18 -18
- package/dist/factory-assets/connectors/googledrive.js +18 -18
- package/dist/factory-assets/connectors/local.js +18 -18
- package/dist/factory-assets/connectors/mattermost.js +18 -18
- package/dist/factory-assets/connectors/memory.js +18 -18
- package/dist/factory-assets/connectors/minio.js +18 -18
- package/dist/factory-assets/connectors/postgres.js +18 -18
- package/dist/factory-assets/connectors/s3.js +18 -18
- package/dist/factory-assets/connectors/sharepoint.js +18 -18
- package/dist/factory-assets/connectors/sqlite.js +18 -18
- package/dist/factory-assets/connectors/static-server.js +18 -18
- package/dist/factory-assets/connectors/tunnel.js +18 -18
- package/dist/factory-assets/connectors/webdav.js +18 -18
- package/dist/factory-assets/connectors/xstate-store.js +18 -18
- package/dist/factory-assets/connectors/xstate.js +18 -18
- package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +9 -3
- package/dist/{flows-CBYRSAGS.js → flows-HMSE76PO.js} +12 -12
- package/dist/{flows-CBYRSAGS.js.map → flows-HMSE76PO.js.map} +1 -1
- package/dist/{helpers-MWZDRBLD.js → helpers-X6URBGSF.js} +17 -17
- package/dist/{helpers-MWZDRBLD.js.map → helpers-X6URBGSF.js.map} +1 -1
- package/dist/library/index.js +11 -11
- package/dist/library/install.js +3 -3
- package/dist/library/src/index.d.ts +2 -1
- package/dist/library/src/index.d.ts.map +1 -1
- package/dist/library/src/local/library-dir.d.ts +42 -0
- package/dist/library/src/local/library-dir.d.ts.map +1 -0
- package/dist/library/src/local/library-manager.d.ts +10 -1
- package/dist/library/src/local/library-manager.d.ts.map +1 -1
- package/dist/library/src/local/library.d.ts +2 -2
- package/dist/library/src/local/library.d.ts.map +1 -1
- package/dist/library/src/local/local-catalog-source.d.ts +9 -0
- package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
- package/dist/library/src/manifest-writer.d.ts +55 -4
- package/dist/library/src/manifest-writer.d.ts.map +1 -1
- package/dist/library/src/remote/cache.d.ts +18 -1
- package/dist/library/src/remote/cache.d.ts.map +1 -1
- package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
- package/dist/library/src/remote/rest-catalog-source.d.ts.map +1 -1
- package/dist/library/src/sync/git-driver.d.ts +5 -6
- package/dist/library/src/sync/git-driver.d.ts.map +1 -1
- package/dist/{library-publish-PICMDSB2.js → library-publish-OS3JDW4S.js} +123 -41
- package/dist/library-publish-OS3JDW4S.js.map +1 -0
- package/dist/open-library-4QSUORI6.js +40 -0
- package/dist/{open-library-OG457THY.js.map → open-library-4QSUORI6.js.map} +1 -1
- package/dist/open-registry-VCKS3MP5.js +32 -0
- package/dist/{open-registry-ZUZJ7MS7.js.map → open-registry-VCKS3MP5.js.map} +1 -1
- package/dist/paths-BVO56A25.js +22 -0
- package/dist/{paths-FQ64OLJG.js.map → paths-BVO56A25.js.map} +1 -1
- package/dist/{plugin-store-MPAMD5OT.js → plugin-store-X7GPWGBG.js} +9 -9
- package/dist/{plugin-store-MPAMD5OT.js.map → plugin-store-X7GPWGBG.js.map} +1 -1
- package/dist/{project-2GFT5LEZ.js → project-PAXP46RD.js} +20 -20
- package/dist/{project-2GFT5LEZ.js.map → project-PAXP46RD.js.map} +1 -1
- package/dist/resolver/index.js +8 -8
- package/dist/runner/index.js +32 -32
- package/dist/runner/src/agent.d.ts.map +1 -1
- package/dist/runner/src/context-usage/compose.d.ts.map +1 -1
- package/dist/runner/src/platform-blocks.d.ts +55 -0
- package/dist/runner/src/platform-blocks.d.ts.map +1 -0
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +14 -14
- package/dist/sdk/bridge.js +14 -14
- package/dist/sdk/client.js +1 -1
- package/dist/sdk/core.js +7 -7
- package/dist/sdk/flow.js +8 -8
- package/dist/sdk/index.js +33 -33
- package/dist/sdk/resolver.js +8 -8
- package/dist/sdk/runner.js +32 -32
- package/dist/sdk/session.js +2 -2
- package/dist/sdk/types.js +1 -1
- package/dist/session/index.js +2 -2
- package/dist/session/src/dispatcher.d.ts +25 -4
- package/dist/session/src/dispatcher.d.ts.map +1 -1
- package/dist/session/src/index.d.ts +1 -1
- package/dist/session/src/index.d.ts.map +1 -1
- package/dist/{setup-WHMCSIF2.js → setup-BV55VHWC.js} +24 -24
- package/dist/{setup-WHMCSIF2.js.map → setup-BV55VHWC.js.map} +1 -1
- package/dist/{skills-TVO26Y4V.js → skills-EDFUCJPX.js} +13 -13
- package/dist/{skills-TVO26Y4V.js.map → skills-EDFUCJPX.js.map} +1 -1
- package/dist/source-E4VAT5RZ.js +41 -0
- package/dist/{source-LKOFTOEK.js.map → source-E4VAT5RZ.js.map} +1 -1
- package/dist/{source-manifest-publish-L5J3QXER.js → source-manifest-publish-CLEE6TNH.js} +23 -23
- package/dist/{source-manifest-publish-L5J3QXER.js.map → source-manifest-publish-CLEE6TNH.js.map} +1 -1
- package/dist/tui/index.js +32 -32
- package/dist/types/index.js +1 -1
- package/dist/types/manifests.js +1 -1
- package/dist/types/src/events.d.ts +1 -1
- package/dist/types/src/events.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/manifests/agent.d.ts +2 -0
- package/dist/types/src/manifests/agent.d.ts.map +1 -1
- package/dist/types/src/manifests/contract.d.ts +2 -0
- package/dist/types/src/manifests/contract.d.ts.map +1 -1
- package/dist/types/src/manifests/index.d.ts +3 -3
- package/dist/types/src/manifests/index.d.ts.map +1 -1
- package/dist/types/src/manifests/prompt.d.ts +2 -0
- package/dist/types/src/manifests/prompt.d.ts.map +1 -1
- package/dist/types/src/protocol.d.ts +43 -1
- package/dist/types/src/protocol.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +17 -1
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +25 -25
- package/dist/workspace-plugin/adapters/omp.js +14 -14
- package/dist/workspace-plugin/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-36AFURKZ.js.map +0 -1
- package/dist/chunk-4MQS7CAF.js.map +0 -1
- package/dist/chunk-AWQYXZVG.js.map +0 -1
- package/dist/chunk-B6GIW55K.js.map +0 -1
- package/dist/chunk-BTE2V4IW.js.map +0 -1
- package/dist/chunk-CIFS5K6T.js.map +0 -1
- package/dist/chunk-EF7NPDDU.js.map +0 -1
- package/dist/chunk-F3RDEH5U.js.map +0 -1
- package/dist/chunk-GTILM2CI.js.map +0 -1
- package/dist/chunk-GXXFLBUQ.js.map +0 -1
- package/dist/chunk-H7QUDDKH.js.map +0 -1
- package/dist/chunk-HG34RNTK.js.map +0 -1
- package/dist/chunk-JAKOMFC6.js.map +0 -1
- package/dist/chunk-LEMHVDET.js.map +0 -1
- package/dist/chunk-OJ4N4T4H.js.map +0 -1
- package/dist/chunk-P23M65LB.js.map +0 -1
- package/dist/chunk-QVNRCDTV.js.map +0 -1
- package/dist/chunk-UMVKJM4Q.js.map +0 -1
- package/dist/chunk-Y7QA2OLD.js.map +0 -1
- package/dist/chunk-YSHVQGUS.js.map +0 -1
- package/dist/chunk-ZAOGFXDO.js +0 -112
- package/dist/chunk-ZAOGFXDO.js.map +0 -1
- package/dist/library-publish-PICMDSB2.js.map +0 -1
- package/dist/open-library-OG457THY.js +0 -40
- package/dist/open-registry-ZUZJ7MS7.js +0 -32
- package/dist/paths-FQ64OLJG.js +0 -22
- package/dist/source-LKOFTOEK.js +0 -41
package/dist/cli/index.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-
|
|
3
|
-
import { makeSourceCommand, syncProjectSources } from '../chunk-
|
|
4
|
-
import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportRelocked, REF_HINT, reportInstalledSoftDeps } from '../chunk-
|
|
2
|
+
import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-XCNK4UE5.js';
|
|
3
|
+
import { makeSourceCommand, syncProjectSources, divergedSourceClones } from '../chunk-Z2K6BGUR.js';
|
|
4
|
+
import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportReplaced, reportRelocked, REF_HINT, reportInstalledSoftDeps } from '../chunk-4P3KTUZH.js';
|
|
5
5
|
import { createSpinner } from '../chunk-NESV47MF.js';
|
|
6
|
-
import { AI_RESOURCES } from '../chunk-
|
|
7
|
-
import { findAssetManifestFile, declaredVersion, readAssetBody,
|
|
8
|
-
import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, assetEntryRef, manifestVersionMismatchMessage
|
|
9
|
-
import { openCatalogSource, LocalCatalogDisabledError, openLibraryManager, openLibrary } from '../chunk-
|
|
10
|
-
import { logErr, S, logOk, logInfo, logWarn, TARGET_DEFAULT_HINT, deferredWarnings, warnLegacyClaudeCopies, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth, KIND_COL_WIDTH } from '../chunk-
|
|
11
|
-
import { getKindRegistry, getKnownKinds } from '../chunk-
|
|
6
|
+
import { AI_RESOURCES } from '../chunk-WBYDAL6X.js';
|
|
7
|
+
import { unresolvedManifestDependencies, warnIgnoredDomainFiles, warnLegacyBundleFiles, removedDomainOption, rejectRemovedDomainOption, resolveLibraryPublisherDetailed, warnLibraryNameFallback, indexLibrary, requireValidPublisherOrExit, exitOnManifestPublisherProblems, registerLibraryAsset, DOMAIN_REMOVED_HINT, manifestPublisherProblems, manifestRequiresProblems, findAssetManifestFile, declaredVersion, checkAssetFile, duplicateAssetMessage, readAssetBody, checkAsset, invalidSemverText } from '../chunk-YBQONMH2.js';
|
|
8
|
+
import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, assetEntryRef, manifestVersionMismatchMessage } from '../chunk-V7PQZOBR.js';
|
|
9
|
+
import { openCatalogSource, LocalCatalogDisabledError, openLibraryManager, openLibrary } from '../chunk-CLTHEKHR.js';
|
|
10
|
+
import { logErr, S, logOk, logInfo, logWarn, TARGET_DEFAULT_HINT, deferredWarnings, warnLegacyClaudeCopies, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth, KIND_COL_WIDTH } from '../chunk-TRSQP3JD.js';
|
|
11
|
+
import { getKindRegistry, getKnownKinds } from '../chunk-SBFW3CJH.js';
|
|
12
12
|
import { LocalSecretsProvider } from '../chunk-ILFGVSTJ.js';
|
|
13
|
-
import { runAgentChat, isCompositionError, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, hashAgentFiles, createCompositionContentSource, compileComposition, instanceForSession, resolveAgentInstance, describeComposition, MarkdownStreamer } from '../chunk-
|
|
14
|
-
import { buildClaudePluginFiles } from '../chunk-
|
|
15
|
-
import '../chunk-
|
|
16
|
-
import '../chunk-
|
|
13
|
+
import { runAgentChat, isCompositionError, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, hashAgentFiles, createCompositionContentSource, compileComposition, instanceForSession, resolveAgentInstance, describeComposition, MarkdownStreamer } from '../chunk-NRDSGLCQ.js';
|
|
14
|
+
import { buildClaudePluginFiles } from '../chunk-5QI2JYJC.js';
|
|
15
|
+
import '../chunk-FRPBSUFH.js';
|
|
16
|
+
import '../chunk-SX5U422E.js';
|
|
17
17
|
import '../chunk-R6O6YWU7.js';
|
|
18
|
-
import '../chunk-
|
|
19
|
-
import '../chunk-
|
|
18
|
+
import '../chunk-G54USEUP.js';
|
|
19
|
+
import '../chunk-Y63UQZ7P.js';
|
|
20
20
|
import '../chunk-4ZTPYIBE.js';
|
|
21
|
-
import '../chunk-
|
|
21
|
+
import '../chunk-VLXDXRRX.js';
|
|
22
22
|
import '../chunk-X5YPJV4N.js';
|
|
23
23
|
import '../chunk-O7SG5PC2.js';
|
|
24
24
|
import '../chunk-7QBNJTTQ.js';
|
|
@@ -26,77 +26,77 @@ import '../chunk-OBYKJB4U.js';
|
|
|
26
26
|
import '../chunk-5LKOAX7I.js';
|
|
27
27
|
import '../chunk-32NA4TVC.js';
|
|
28
28
|
import '../chunk-W3UDISS2.js';
|
|
29
|
-
import '../chunk-
|
|
30
|
-
import { runFlow, resumeFlow } from '../chunk-
|
|
29
|
+
import '../chunk-NWDSLXOX.js';
|
|
30
|
+
import { runFlow, resumeFlow } from '../chunk-IJHH4DSW.js';
|
|
31
31
|
import '../chunk-4R6DROGN.js';
|
|
32
|
-
import { validateFlowVersions
|
|
33
|
-
import '../chunk-
|
|
32
|
+
import { validateFlowVersions } from '../chunk-3MKPZZRE.js';
|
|
33
|
+
import '../chunk-HOHUEKES.js';
|
|
34
34
|
import '../chunk-ISHJITXJ.js';
|
|
35
|
-
import '../chunk-
|
|
36
|
-
import '../chunk-
|
|
37
|
-
import '../chunk-
|
|
38
|
-
import '../chunk-
|
|
39
|
-
import '../chunk-
|
|
35
|
+
import '../chunk-7CR6HT2X.js';
|
|
36
|
+
import '../chunk-X4BAYGMT.js';
|
|
37
|
+
import '../chunk-V5TZH4GF.js';
|
|
38
|
+
import '../chunk-OBVJ7RPW.js';
|
|
39
|
+
import '../chunk-QG3HOJEK.js';
|
|
40
40
|
import '../chunk-LOO5CB5M.js';
|
|
41
|
-
import '../chunk-
|
|
42
|
-
import '../chunk-
|
|
41
|
+
import '../chunk-2H73V6XR.js';
|
|
42
|
+
import '../chunk-OOWHXOK6.js';
|
|
43
43
|
import '../chunk-B4X2N7JQ.js';
|
|
44
44
|
import '../chunk-YROR332M.js';
|
|
45
|
-
import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-
|
|
45
|
+
import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-HJ5MCB3L.js';
|
|
46
46
|
import '../chunk-6E6PKKAD.js';
|
|
47
47
|
import '../chunk-IFGTRL2I.js';
|
|
48
|
-
import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-
|
|
48
|
+
import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-7I5VRVDP.js';
|
|
49
49
|
import '../chunk-LNFKL23K.js';
|
|
50
50
|
import '../chunk-MGGFBZWA.js';
|
|
51
51
|
import '../chunk-M3WPBTGJ.js';
|
|
52
52
|
import { nodeLabel, nodeSkillAsset, nodeIsInert, nodeIsOptional, nodeRunKind, flowSkillVersionPins } from '../chunk-7RGTAEG6.js';
|
|
53
53
|
import '../chunk-NUELZWCF.js';
|
|
54
|
-
import '../chunk-
|
|
55
|
-
import { AssetManager, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-
|
|
56
|
-
import { cloneOrInitGitRepo, trackOriginBranch, stampManifestPublisher, ensureGitRepo, conflictingAssetRoot, setManifestPublisher, LIBRARY_OWNERSHIPS, isGitRepo, assertManifestEditable, installLibraryAsset, missingRootAssets, assertValidLibraryName,
|
|
57
|
-
import { parseManifestFile,
|
|
58
|
-
import '../chunk-
|
|
54
|
+
import '../chunk-F4NJDSR7.js';
|
|
55
|
+
import { AssetManager, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-2JMLDZLP.js';
|
|
56
|
+
import { libraryDirMissing, missingLibraryDirMessage, cloneOrInitGitRepo, trackOriginBranch, stampManifestPublisher, ensureGitRepo, conflictingAssetRoot, setManifestPublisher, LIBRARY_OWNERSHIPS, isGitRepo, assertManifestEditable, installLibraryAsset, missingRootAssets, assertValidLibraryName, syncManifestWithDisk, getStoreManifestsDir, getDefaultValue, isSecretPlaceholder } from '../chunk-3BEY4WK3.js';
|
|
57
|
+
import { parseManifestFile, SEMVER_RE } from '../chunk-GEWAIQZ5.js';
|
|
58
|
+
import '../chunk-MVQ3Q2HM.js';
|
|
59
59
|
import '../chunk-R7FOF242.js';
|
|
60
60
|
import '../chunk-3TXEJN4W.js';
|
|
61
|
-
import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-
|
|
61
|
+
import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-PE36IF2D.js';
|
|
62
62
|
import '../chunk-CGYEHQOX.js';
|
|
63
63
|
import '../chunk-KTBKW2FI.js';
|
|
64
64
|
import '../chunk-UQ6LFBPZ.js';
|
|
65
|
-
import '../chunk-
|
|
66
|
-
import { effectiveComposes, validatePreset, composeSlotDiagnostics, agentDeprecationDiagnostics, validateAgent, SLOT_ID_PATTERN } from '../chunk-
|
|
67
|
-
import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, readLock, aiResourceRoots, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-
|
|
65
|
+
import '../chunk-6HHE63CO.js';
|
|
66
|
+
import { effectiveComposes, validatePreset, composeSlotDiagnostics, agentDeprecationDiagnostics, validateAgent, SLOT_ID_PATTERN } from '../chunk-32XKCNCL.js';
|
|
67
|
+
import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, readLock, aiResourceRoots, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-2FMEGSBN.js';
|
|
68
68
|
import '../chunk-4GY63JU6.js';
|
|
69
|
-
import { factoryAssetRoots } from '../chunk-
|
|
69
|
+
import { factoryAssetRoots } from '../chunk-GFCXNFTW.js';
|
|
70
70
|
import '../chunk-PMECEZK3.js';
|
|
71
71
|
import { DEFAULT_DRIVER_ID, DRIVER_DEFAULTS } from '../chunk-5BEFNLOR.js';
|
|
72
72
|
import { findKindDirs } from '../chunk-A2ULN3KX.js';
|
|
73
|
-
import { sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, resolveSkWorkspaceConfig, matchPin, coerceVersion, loadSkWorkspaceConfig, normalizeAgentInstances, agentInstanceDiagnostics, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-
|
|
73
|
+
import { SourceEntryError, SKAILE_YAML_DEFAULT, sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, resolveSkWorkspaceConfig, matchPin, coerceVersion, loadSkWorkspaceConfig, normalizeAgentInstances, agentInstanceDiagnostics, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-JZCSNEHK.js';
|
|
74
74
|
import { globalCacheRoot, globalSkaileDir, userConfigPath } from '../chunk-L5VSIPQD.js';
|
|
75
75
|
import { SUPPORTED_DRIVER_TARGETS, driverTargetForDriver } from '../chunk-CPSIPIX7.js';
|
|
76
|
-
import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest, loadSkPublishManifest, encodeSkaileManifest } from '../chunk-
|
|
76
|
+
import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest, loadSkPublishManifest, encodeSkaileManifest } from '../chunk-IXWODEED.js';
|
|
77
77
|
import { pluginTitle } from '../chunk-RVRB27AN.js';
|
|
78
|
-
import { parseFrontmatter, scanDirectory } from '../chunk-
|
|
79
|
-
import { parseAssetRef, isValidPublisher, PUBLISHER_HINT, isValidAssetName, ASSET_NAME_HINT, slugifyAssetName, parseAssetRefLoose, assetRefToStr } from '../chunk-
|
|
78
|
+
import { dedupeRequirements, parseFrontmatter, scanDirectory } from '../chunk-Y34MSWEZ.js';
|
|
79
|
+
import { parseAssetRef, isValidPublisher, PUBLISHER_HINT, isValidAssetName, ASSET_NAME_HINT, slugifyAssetName, parseAssetRefLoose, assetRefToStr } from '../chunk-4OV5DSBB.js';
|
|
80
80
|
import { portableSpawn, portableSpawnSync } from '../chunk-ICSCSM5D.js';
|
|
81
|
-
import { openSqlite } from '../chunk-
|
|
81
|
+
import { openSqlite } from '../chunk-DALV4HHP.js';
|
|
82
82
|
import { parseModelRef, resolveEntryBaseUrl } from '../chunk-MJHSLODD.js';
|
|
83
83
|
import '../chunk-C3CAXQMA.js';
|
|
84
84
|
import '../chunk-BOFL7GIF.js';
|
|
85
85
|
import '../chunk-NSBPE2FW.js';
|
|
86
|
-
import * as
|
|
87
|
-
import
|
|
88
|
-
import * as
|
|
89
|
-
import
|
|
86
|
+
import * as fs8 from 'fs';
|
|
87
|
+
import fs8__default, { readFileSync, existsSync, mkdirSync, writeFileSync, lstatSync, rmSync, readdirSync, statSync } from 'fs';
|
|
88
|
+
import * as path18 from 'path';
|
|
89
|
+
import path18__default, { resolve, join } from 'path';
|
|
90
90
|
import { fileURLToPath } from 'url';
|
|
91
91
|
import { Help, Command, Option } from 'commander';
|
|
92
92
|
import { rcompare } from 'semver';
|
|
93
93
|
import * as p4 from '@clack/prompts';
|
|
94
94
|
import pc5 from 'picocolors';
|
|
95
|
-
import { parse, stringify, parseDocument, isMap, isScalar, isSeq } from 'yaml';
|
|
96
95
|
import * as os from 'os';
|
|
96
|
+
import { parse, stringify, parseDocument, isMap, isScalar, isSeq } from 'yaml';
|
|
97
97
|
import * as readline from 'readline';
|
|
98
98
|
import { createInterface } from 'readline';
|
|
99
|
-
import
|
|
99
|
+
import fs5 from 'fs/promises';
|
|
100
100
|
import { parse as parse$1, stringify as stringify$1 } from 'smol-toml';
|
|
101
101
|
import { execSync, spawnSync, execFileSync } from 'child_process';
|
|
102
102
|
import * as readline2 from 'readline/promises';
|
|
@@ -175,7 +175,7 @@ async function runSearch(kind, query, opts) {
|
|
|
175
175
|
const showLocal = !opts.store;
|
|
176
176
|
const showStore = !opts.local;
|
|
177
177
|
const { resolveConfig } = await import('../library/index.js');
|
|
178
|
-
const airGapped = resolveConfig({ projectDir:
|
|
178
|
+
const airGapped = resolveConfig({ projectDir: path18__default.resolve(opts.projectDir) }).catalog.cache_ttl === 0;
|
|
179
179
|
if (showLocal) {
|
|
180
180
|
await searchLocal(query, kind, opts, showStore, airGapped);
|
|
181
181
|
}
|
|
@@ -184,11 +184,14 @@ async function runSearch(kind, query, opts) {
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
async function searchIndex(query, kind) {
|
|
187
|
-
const { openLibrary: openLibrary2 } = await import('../open-library-
|
|
187
|
+
const { openLibrary: openLibrary2 } = await import('../open-library-4QSUORI6.js');
|
|
188
188
|
const library = await openLibrary2();
|
|
189
189
|
try {
|
|
190
|
-
const
|
|
191
|
-
const
|
|
190
|
+
const { libraryDirMissing: libraryDirMissing2 } = await import('../library/index.js');
|
|
191
|
+
const sources = await library.listSources();
|
|
192
|
+
const gone = new Set(sources.filter(libraryDirMissing2).map((l) => l.id));
|
|
193
|
+
const defs = (await library.listAssetDefs(kind ? { kind } : {})).filter((d) => !d.libraryId || !gone.has(d.libraryId));
|
|
194
|
+
const libraryNames = new Map(sources.map((l) => [l.id, l.name]));
|
|
192
195
|
let entries = defs.map(
|
|
193
196
|
(d) => ({
|
|
194
197
|
name: d.name,
|
|
@@ -218,7 +221,7 @@ async function searchIndex(query, kind) {
|
|
|
218
221
|
}
|
|
219
222
|
}
|
|
220
223
|
async function searchFactory(projectDir, query, kind) {
|
|
221
|
-
const prefixes = factoryAssetRoots().map((r) => r.endsWith(
|
|
224
|
+
const prefixes = factoryAssetRoots().map((r) => r.endsWith(path18__default.sep) ? r : r + path18__default.sep);
|
|
222
225
|
const isFactoryPath = (p6) => prefixes.some((fp) => p6 === fp.slice(0, -1) || p6.startsWith(fp));
|
|
223
226
|
try {
|
|
224
227
|
const entries = await new AssetManager({ registry: getKindRegistry(), projectDir }).search(
|
|
@@ -269,12 +272,70 @@ async function expandLibraryCopies(entries, projectDir) {
|
|
|
269
272
|
}
|
|
270
273
|
return out;
|
|
271
274
|
}
|
|
275
|
+
function originAtVersion(o) {
|
|
276
|
+
return `${describeOrigin(o)}${o.version ? ` v${o.version}` : ""}`;
|
|
277
|
+
}
|
|
278
|
+
async function competingOriginsOf(am2, target) {
|
|
279
|
+
let ref;
|
|
280
|
+
if (typeof target === "string") {
|
|
281
|
+
if (target.includes("#")) return void 0;
|
|
282
|
+
ref = target;
|
|
283
|
+
} else {
|
|
284
|
+
const publisher = (target.canonicalRef ? parseRefTolerant(target.canonicalRef)?.publisher : void 0) ?? target.publisher;
|
|
285
|
+
if (!publisher) return void 0;
|
|
286
|
+
ref = `${target.kind}:@${publisher}/${target.name}`;
|
|
287
|
+
}
|
|
288
|
+
try {
|
|
289
|
+
const origins = await am2.refOrigins(ref);
|
|
290
|
+
return new Set(origins.map((o) => o.version)).size > 1 ? origins : void 0;
|
|
291
|
+
} catch {
|
|
292
|
+
return void 0;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function describeOrigin(o) {
|
|
296
|
+
return o.kind === "factory" ? "factory" : `${o.kind} ${o.label}`;
|
|
297
|
+
}
|
|
298
|
+
async function expandCompetingOrigins(entries, projectDir) {
|
|
299
|
+
if (entries.length === 0) return entries;
|
|
300
|
+
let competing;
|
|
301
|
+
try {
|
|
302
|
+
competing = await new AssetManager({
|
|
303
|
+
registry: getKindRegistry(),
|
|
304
|
+
projectDir
|
|
305
|
+
}).competingOrigins();
|
|
306
|
+
} catch {
|
|
307
|
+
return entries;
|
|
308
|
+
}
|
|
309
|
+
if (competing.size === 0) return entries;
|
|
310
|
+
const out = [];
|
|
311
|
+
const expanded = /* @__PURE__ */ new Set();
|
|
312
|
+
for (const e of entries) {
|
|
313
|
+
const key = entryDedupKey(e);
|
|
314
|
+
const origins = competing.get(key);
|
|
315
|
+
if (!origins) {
|
|
316
|
+
out.push(e);
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
if (expanded.has(key)) continue;
|
|
320
|
+
expanded.add(key);
|
|
321
|
+
origins.forEach((o, i) => {
|
|
322
|
+
out.push({
|
|
323
|
+
...e,
|
|
324
|
+
version: o.version,
|
|
325
|
+
description: o.description || e.description,
|
|
326
|
+
library: describeOrigin(o),
|
|
327
|
+
usedByAdd: i === 0
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
return out;
|
|
332
|
+
}
|
|
272
333
|
async function searchLocal(query, kind, opts, showStore, airGapped) {
|
|
273
|
-
const projectDir =
|
|
334
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
274
335
|
const factory = await searchFactory(projectDir, query, kind);
|
|
275
336
|
let entries = unionEntries(await searchIndex(query, kind), factory);
|
|
276
337
|
if (entries.length === 0 && !query && !kind && !airGapped) {
|
|
277
|
-
const { autoSyncForSearch } = await import('../source-
|
|
338
|
+
const { autoSyncForSearch } = await import('../source-E4VAT5RZ.js');
|
|
278
339
|
if (await autoSyncForSearch(projectDir)) {
|
|
279
340
|
entries = unionEntries(await searchIndex(query, kind), factory);
|
|
280
341
|
}
|
|
@@ -291,7 +352,9 @@ async function searchLocal(query, kind, opts, showStore, airGapped) {
|
|
|
291
352
|
console.log(`
|
|
292
353
|
${S.heading("Local:")}`);
|
|
293
354
|
}
|
|
294
|
-
printLocalEntries(
|
|
355
|
+
printLocalEntries(
|
|
356
|
+
await expandCompetingOrigins(await expandLibraryCopies(entries, projectDir), projectDir)
|
|
357
|
+
);
|
|
295
358
|
}
|
|
296
359
|
var MIN_LOCAL_DESCRIPTION_WIDTH = 10;
|
|
297
360
|
function layoutLocalTable(rows, width, style = {}) {
|
|
@@ -392,9 +455,9 @@ async function searchStore(query, kind, opts, airGapped) {
|
|
|
392
455
|
logInfo("air-gapped (cache_ttl: 0) \u2014 local sources only");
|
|
393
456
|
return;
|
|
394
457
|
}
|
|
395
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-
|
|
458
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-4QSUORI6.js');
|
|
396
459
|
try {
|
|
397
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
460
|
+
const remote = await openCatalogSource2({ projectDir: path18__default.resolve(opts.projectDir) });
|
|
398
461
|
const assets = await remote.listAssets(kind ? { kind } : {});
|
|
399
462
|
const results = filterCatalogAssets(assets, query);
|
|
400
463
|
if (results.length > 0) {
|
|
@@ -515,10 +578,17 @@ function makeAddCommand() {
|
|
|
515
578
|
process.exit(1);
|
|
516
579
|
}
|
|
517
580
|
const harnesses = parseHarnessFilter(opts.harness);
|
|
581
|
+
if (!opts.global && harnesses === void 0) {
|
|
582
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
583
|
+
if (!existsSync(path18__default.join(projectDir, SKAILE_YAML_DEFAULT))) {
|
|
584
|
+
logErr(`No ${S.cmd("skaile.yaml")} found. Run ${S.cmd("skaile init")} to create one.`);
|
|
585
|
+
process.exit(1);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
518
588
|
const warnings = deferredWarnings();
|
|
519
589
|
const am2 = new AssetManager({
|
|
520
590
|
registry: getKindRegistry(),
|
|
521
|
-
projectDir:
|
|
591
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
522
592
|
global: opts.global || harnesses !== void 0,
|
|
523
593
|
harnesses,
|
|
524
594
|
driverTarget: opts.target,
|
|
@@ -529,11 +599,18 @@ function makeAddCommand() {
|
|
|
529
599
|
try {
|
|
530
600
|
const libraryOf = /* @__PURE__ */ new Map();
|
|
531
601
|
let presets = [];
|
|
602
|
+
const skippedLinks = /* @__PURE__ */ new Set();
|
|
532
603
|
const added = await am2.add(ref, {
|
|
533
604
|
link: opts.link,
|
|
534
605
|
onLibraryOrigin: (deployedRef, library) => libraryOf.set(deployedRef, library),
|
|
535
606
|
onPresets: (expanded) => {
|
|
536
607
|
presets = expanded;
|
|
608
|
+
},
|
|
609
|
+
// One line per dropped link, however many harnesses the asset is deployed into.
|
|
610
|
+
onSkippedSymlink: (_assetRef, linkPath) => {
|
|
611
|
+
if (skippedLinks.has(linkPath)) return;
|
|
612
|
+
skippedLinks.add(linkPath);
|
|
613
|
+
warnings.push(`skipped symlink ${linkPath}`);
|
|
537
614
|
}
|
|
538
615
|
});
|
|
539
616
|
spinner.stop("Done");
|
|
@@ -564,6 +641,15 @@ function makeAddCommand() {
|
|
|
564
641
|
logOk(library ? `${a} (library ${library})` : a);
|
|
565
642
|
}
|
|
566
643
|
}
|
|
644
|
+
const addOrigins = await competingOriginsOf(am2, ref);
|
|
645
|
+
if (addOrigins) {
|
|
646
|
+
const [first, ...rest] = addOrigins;
|
|
647
|
+
logInfo(
|
|
648
|
+
S.dim(
|
|
649
|
+
`${ref} is held at different versions; used ${originAtVersion(first)} (also ${rest.map(originAtVersion).join(", ")})`
|
|
650
|
+
)
|
|
651
|
+
);
|
|
652
|
+
}
|
|
567
653
|
await reportPresetMembership(am2, ref, (line) => logInfo(S.dim(line)));
|
|
568
654
|
} catch (err2) {
|
|
569
655
|
spinner.stop("Failed");
|
|
@@ -577,23 +663,31 @@ function makeRemoveCommand() {
|
|
|
577
663
|
return new Command("remove").description("Remove from skaile.yaml + undeploy").argument("<ref>", "Asset reference (kind:@publisher/name, or kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Remove from ~/.skaile/skaile.yaml + undeploy from every global harness").option(
|
|
578
664
|
"--harness <ids>",
|
|
579
665
|
"Comma-separated global harnesses to undeploy from (default: all resolved); implies --global"
|
|
580
|
-
).option("--target <agent>", `Driver target (${TARGET_DEFAULT_HINT})`).option("--no-soft-deps", "skip the orphaned-soft-dep prompt (don't remove, don't report)").action(async (ref, opts) => {
|
|
666
|
+
).option("--target <agent>", `Driver target (${TARGET_DEFAULT_HINT})`).option("--force", "Remove even when another installed asset requires it").option("--no-soft-deps", "skip the orphaned-soft-dep prompt (don't remove, don't report)").action(async (ref, opts) => {
|
|
581
667
|
const harnesses = parseHarnessFilter(opts.harness);
|
|
582
668
|
const am2 = new AssetManager({
|
|
583
669
|
registry: getKindRegistry(),
|
|
584
|
-
projectDir:
|
|
670
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
585
671
|
global: opts.global || harnesses !== void 0,
|
|
586
672
|
harnesses,
|
|
587
673
|
driverTarget: opts.target
|
|
588
674
|
});
|
|
589
675
|
let result;
|
|
590
676
|
try {
|
|
591
|
-
result = await am2.removeWithDependencies(ref);
|
|
677
|
+
result = await am2.removeWithDependencies(ref, { force: opts.force === true });
|
|
592
678
|
} catch (err2) {
|
|
593
679
|
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
594
680
|
process.exitCode = 1;
|
|
595
681
|
return;
|
|
596
682
|
}
|
|
683
|
+
if (result.blocked) {
|
|
684
|
+
logWarn(`${result.blocked.ref} is required by ${result.blocked.requiredBy.join(", ")}`);
|
|
685
|
+
logInfo(
|
|
686
|
+
`Nothing removed. Remove ${result.blocked.requiredBy.length === 1 ? "that asset" : "those assets"} first, or run \`skaile remove ${ref} --force\`.`
|
|
687
|
+
);
|
|
688
|
+
process.exitCode = 1;
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
597
691
|
if (!result.changed) {
|
|
598
692
|
logErr(`Not deployed or declared: ${ref}`);
|
|
599
693
|
process.exitCode = 1;
|
|
@@ -635,7 +729,7 @@ function makeListCommand() {
|
|
|
635
729
|
}
|
|
636
730
|
const am2 = new AssetManager({
|
|
637
731
|
registry: getKindRegistry(),
|
|
638
|
-
projectDir:
|
|
732
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
639
733
|
driverTarget: opts.target
|
|
640
734
|
});
|
|
641
735
|
let declared;
|
|
@@ -683,7 +777,7 @@ function makeListCommand() {
|
|
|
683
777
|
function runGlobalList(kind, opts, harnesses) {
|
|
684
778
|
const am2 = new AssetManager({
|
|
685
779
|
registry: getKindRegistry(),
|
|
686
|
-
projectDir:
|
|
780
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
687
781
|
global: true,
|
|
688
782
|
harnesses
|
|
689
783
|
});
|
|
@@ -756,7 +850,7 @@ async function resolveInfoEntry(am2, ref, opts) {
|
|
|
756
850
|
return { entry: match ?? deployed };
|
|
757
851
|
}
|
|
758
852
|
const lookup = opts.storeLookup ?? (async (filter) => {
|
|
759
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
853
|
+
const { resolveCatalogSource } = await import('../open-library-4QSUORI6.js');
|
|
760
854
|
const { source, close } = await resolveCatalogSource({ projectDir: opts.projectDir });
|
|
761
855
|
try {
|
|
762
856
|
return await source.listAssets(filter);
|
|
@@ -772,7 +866,7 @@ async function resolveInfoEntry(am2, ref, opts) {
|
|
|
772
866
|
);
|
|
773
867
|
return { entry: hit ? catalogAssetToEntry(hit) : null };
|
|
774
868
|
} catch (err2) {
|
|
775
|
-
const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-
|
|
869
|
+
const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-4QSUORI6.js');
|
|
776
870
|
const storeNote = err2 instanceof Error ? err2.message : String(err2);
|
|
777
871
|
const disabled = err2 instanceof LocalCatalogDisabledError2 || /catalog\.url/i.test(storeNote);
|
|
778
872
|
return { entry: null, storeNote, ...disabled ? { storeDisabled: true } : {} };
|
|
@@ -788,7 +882,7 @@ function infoNotFoundHint(ref, lookup) {
|
|
|
788
882
|
}
|
|
789
883
|
function makeInfoCommand() {
|
|
790
884
|
return new Command("info").description("Show asset metadata, deps, deploy status").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
791
|
-
const projectDir =
|
|
885
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
792
886
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
|
|
793
887
|
const lookup = await resolveInfoEntry(am2, ref, { projectDir });
|
|
794
888
|
const entry = lookup.entry;
|
|
@@ -805,9 +899,20 @@ function makeInfoCommand() {
|
|
|
805
899
|
if (entry.description) console.log(` description: ${entry.description}`);
|
|
806
900
|
if (entry.publisher) console.log(` repository: ${S.dim(entry.publisher)}`);
|
|
807
901
|
console.log(` source: ${S.dim(entry.source)}`);
|
|
808
|
-
|
|
902
|
+
const infoOrigins = await competingOriginsOf(am2, entry);
|
|
903
|
+
if (infoOrigins) {
|
|
904
|
+
const [first, ...rest] = infoOrigins;
|
|
905
|
+
console.log(
|
|
906
|
+
` origin: ${describeOrigin(first)} (used by add; also ${rest.map(originAtVersion).join(", ")})`
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
const ownPublisher = (entry.canonicalRef ? parseRefTolerant(entry.canonicalRef)?.publisher : void 0) ?? entry.publisher;
|
|
910
|
+
const requirements = dedupeRequirements(entry.requires, ownPublisher).map(
|
|
911
|
+
(d) => d.publisher || !ownPublisher ? d : { ...d, publisher: ownPublisher }
|
|
912
|
+
);
|
|
913
|
+
if (requirements.length) {
|
|
809
914
|
console.log(` requires:`);
|
|
810
|
-
for (const d of
|
|
915
|
+
for (const d of requirements) {
|
|
811
916
|
const scope = d.publisher ? `@${d.publisher}/` : "";
|
|
812
917
|
console.log(` ${S.dim("\xB7")} ${kindColor(d.kind)}:${scope}${d.name}`);
|
|
813
918
|
}
|
|
@@ -826,7 +931,7 @@ function makeCreateCommand() {
|
|
|
826
931
|
new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...SCAFFOLD_KINDS])
|
|
827
932
|
).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
|
|
828
933
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
|
|
829
|
-
const destDir = opts.dir ?
|
|
934
|
+
const destDir = opts.dir ? path18__default.resolve(opts.dir) : process.cwd();
|
|
830
935
|
const result = am2.create(name, opts.kind, destDir);
|
|
831
936
|
if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
|
|
832
937
|
else {
|
|
@@ -839,20 +944,16 @@ function makeDoctorCommand() {
|
|
|
839
944
|
return new Command("doctor").description("Scan for missing dependency chains").argument("[name]", "Check a specific asset (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (name, opts) => {
|
|
840
945
|
const am2 = new AssetManager({
|
|
841
946
|
registry: getKindRegistry(),
|
|
842
|
-
projectDir:
|
|
947
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
843
948
|
});
|
|
844
|
-
const
|
|
845
|
-
if (
|
|
949
|
+
const { gaps, requirements } = await am2.projectState();
|
|
950
|
+
if (gaps.length === 0) {
|
|
846
951
|
logOk("No missing dependencies.");
|
|
847
952
|
return;
|
|
848
953
|
}
|
|
849
|
-
|
|
850
|
-
const
|
|
851
|
-
|
|
852
|
-
logErr(
|
|
853
|
-
`${i.assetKind}:${i.assetName}: locked, but no source or library provides it \u2014 ${i.fix ?? "run skaile install"}`
|
|
854
|
-
);
|
|
855
|
-
}
|
|
954
|
+
process.exitCode = 1;
|
|
955
|
+
for (const g of gaps) if (g.type !== "requires") logErr(g.message);
|
|
956
|
+
const missing = requirements.filter((i) => !i.unresolved);
|
|
856
957
|
if (missing.length === 0) return;
|
|
857
958
|
const assetW = Math.max(5, ...missing.map((i) => `${i.assetKind}:${i.assetName}`.length));
|
|
858
959
|
const depW = Math.max(11, ...missing.map((i) => `${i.depKind}:${i.depName}`.length));
|
|
@@ -870,180 +971,27 @@ function makeDoctorCommand() {
|
|
|
870
971
|
console.log();
|
|
871
972
|
});
|
|
872
973
|
}
|
|
873
|
-
function manifestRequiresProblems(dir) {
|
|
874
|
-
const file = path23.join(dir, "skaile.manifest.yaml");
|
|
875
|
-
let doc;
|
|
876
|
-
try {
|
|
877
|
-
doc = parse(fs9.readFileSync(file, "utf-8"));
|
|
878
|
-
} catch {
|
|
879
|
-
return [];
|
|
880
|
-
}
|
|
881
|
-
const assets = doc?.assets;
|
|
882
|
-
if (!Array.isArray(assets)) return [];
|
|
883
|
-
const problems = [];
|
|
884
|
-
for (const a of assets) {
|
|
885
|
-
if (!a || typeof a !== "object") continue;
|
|
886
|
-
const { kind, name, dependencies } = a;
|
|
887
|
-
if (!Array.isArray(dependencies)) continue;
|
|
888
|
-
const entries = dependencies.map((d) => typeof d === "string" ? d : String(d));
|
|
889
|
-
for (const message of requiresSyntaxErrors(entries)) {
|
|
890
|
-
problems.push({
|
|
891
|
-
asset: `${String(kind)}:${String(name)}`,
|
|
892
|
-
message: `ManifestRequiresError: ${message}`
|
|
893
|
-
});
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
return problems;
|
|
897
|
-
}
|
|
898
|
-
async function indexLibrary(lib, index, opts = {}) {
|
|
899
|
-
const { LocalCatalogSource } = await import('../library/index.js');
|
|
900
|
-
const own = index ?? await openLibrary();
|
|
901
|
-
try {
|
|
902
|
-
const source = new LocalCatalogSource(own, lib.id, lib.path, getKindRegistry());
|
|
903
|
-
const res = await source.sync({ exclude: opts.exclude });
|
|
904
|
-
return {
|
|
905
|
-
assetsFound: res.assetsFound,
|
|
906
|
-
assetsUpdated: res.assetsUpdated,
|
|
907
|
-
errors: res.errors
|
|
908
|
-
};
|
|
909
|
-
} finally {
|
|
910
|
-
if (!index) own.close();
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
function resolveLibraryPublisherDetailed(lib, opts, storeIdentity) {
|
|
914
|
-
const bare = (p6) => p6.startsWith("@") ? p6.slice(1) : p6;
|
|
915
|
-
if (opts.publisher?.trim()) return { publisher: bare(opts.publisher.trim()), source: "flag" };
|
|
916
|
-
const declared = loadSkPublishManifest(lib.path)?.publisher?.trim();
|
|
917
|
-
if (declared) return { publisher: bare(declared), source: "manifest" };
|
|
918
|
-
const identity = (storeIdentity?.githubLogin ?? storeIdentity?.username)?.trim();
|
|
919
|
-
if (identity) return { publisher: identity, source: "identity" };
|
|
920
|
-
try {
|
|
921
|
-
return { publisher: slugifyAssetName(lib.name), source: "library-name" };
|
|
922
|
-
} catch {
|
|
923
|
-
return { publisher: "library", source: "library-name" };
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
function warnLibraryNameFallback(libName, resolved) {
|
|
927
|
-
if (resolved.source !== "library-name") return;
|
|
928
|
-
logWarn(
|
|
929
|
-
`No publisher given and not signed in \u2014 using the library name "${resolved.publisher}" as the publisher. Pass --publisher <name> or run \`skaile store login\`; change it later with \`skaile library set ${libName} publisher=<name>\`.`
|
|
930
|
-
);
|
|
931
|
-
}
|
|
932
|
-
function normalizeAssetFrontmatter(assetDir) {
|
|
933
|
-
let markerFile = ["SKILL.md", "AGENT.md", "CONTRACT.md"].map((m) => path23.join(assetDir, m)).find((f) => fs9.existsSync(f));
|
|
934
|
-
if (!markerFile) {
|
|
935
|
-
const promptMd = fs9.readdirSync(assetDir).find((f) => f.endsWith(".prompt.md"));
|
|
936
|
-
if (promptMd) markerFile = path23.join(assetDir, promptMd);
|
|
937
|
-
}
|
|
938
|
-
if (!markerFile) return;
|
|
939
|
-
try {
|
|
940
|
-
const { data, body } = parseFrontmatter(fs9.readFileSync(markerFile, "utf8"));
|
|
941
|
-
const fm = stringify(data).trimEnd();
|
|
942
|
-
fs9.writeFileSync(markerFile, `---
|
|
943
|
-
${fm}
|
|
944
|
-
---
|
|
945
|
-
|
|
946
|
-
${body}
|
|
947
|
-
`, "utf8");
|
|
948
|
-
} catch {
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
async function registerLibraryAsset(lib, index, input) {
|
|
952
|
-
const { publisher, source } = resolveLibraryPublisherDetailed(
|
|
953
|
-
lib,
|
|
954
|
-
{ publisher: input.publisher },
|
|
955
|
-
getStoreIdentity()
|
|
956
|
-
);
|
|
957
|
-
warnLibraryNameFallback(lib.name, { publisher, source });
|
|
958
|
-
normalizeAssetFrontmatter(input.assetDir);
|
|
959
|
-
stampManifestPublisher(lib.path, publisher);
|
|
960
|
-
upsertManifestAsset(lib.path, {
|
|
961
|
-
kind: input.kind,
|
|
962
|
-
name: input.name,
|
|
963
|
-
root: path23.relative(lib.path, input.assetDir) || input.name,
|
|
964
|
-
version: input.version,
|
|
965
|
-
publisher
|
|
966
|
-
});
|
|
967
|
-
const idx = await indexLibrary(lib, index);
|
|
968
|
-
for (const e of idx.errors) logWarn(e);
|
|
969
|
-
return { publisher, ref: refFor(input.kind, publisher, input.name, input.version) };
|
|
970
|
-
}
|
|
971
|
-
var LIBRARY_UPGRADE_DOCS = "https://github.com/skaile-ai/workspaces/blob/main/docs/sections/cli/commands/library.md#upgrading-a-4x-library";
|
|
972
|
-
var DOMAIN_REMOVED_HINT = `Domains were removed in 5.0 \u2014 delete DOMAIN.md files; group assets with .claude-plugin/marketplace.json. See ${LIBRARY_UPGRADE_DOCS}`;
|
|
973
|
-
function removedDomainOption() {
|
|
974
|
-
return new Option("--domain <domain>", "Removed in 5.0").hideHelp();
|
|
975
|
-
}
|
|
976
|
-
function rejectRemovedDomainOption(opts) {
|
|
977
|
-
if (opts.domain === void 0) return;
|
|
978
|
-
logErr(DOMAIN_REMOVED_HINT);
|
|
979
|
-
process.exit(1);
|
|
980
|
-
}
|
|
981
|
-
function findFiles(root, match) {
|
|
982
|
-
const found = [];
|
|
983
|
-
const walk = (dir) => {
|
|
984
|
-
let entries;
|
|
985
|
-
try {
|
|
986
|
-
entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
987
|
-
} catch {
|
|
988
|
-
return;
|
|
989
|
-
}
|
|
990
|
-
for (const entry of entries) {
|
|
991
|
-
if (entry.isDirectory()) {
|
|
992
|
-
if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
993
|
-
walk(path23.join(dir, entry.name));
|
|
994
|
-
}
|
|
995
|
-
} else if (match(entry.name)) {
|
|
996
|
-
found.push(path23.join(dir, entry.name));
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
};
|
|
1000
|
-
walk(root);
|
|
1001
|
-
return found;
|
|
1002
|
-
}
|
|
1003
|
-
function countDomainFiles(root) {
|
|
1004
|
-
return findFiles(root, (name) => name === "DOMAIN.md").length;
|
|
1005
|
-
}
|
|
1006
|
-
function warnIgnoredDomainFiles(root) {
|
|
1007
|
-
const count = countDomainFiles(root);
|
|
1008
|
-
if (count > 0) {
|
|
1009
|
-
logWarn(
|
|
1010
|
-
`${count} DOMAIN.md file(s) are ignored since 5.0 (domains were removed) \u2014 delete them; group assets with .claude-plugin/marketplace.json. See ${LIBRARY_UPGRADE_DOCS}`
|
|
1011
|
-
);
|
|
1012
|
-
}
|
|
1013
|
-
return count;
|
|
1014
|
-
}
|
|
1015
|
-
function warnLegacyBundleFiles(root) {
|
|
1016
|
-
const files = findFiles(root, (name) => name.endsWith(".bundle.yaml"));
|
|
1017
|
-
if (files.length > 0) {
|
|
1018
|
-
const shown = files.slice(0, 5).map((f) => path23.relative(root, f) || f);
|
|
1019
|
-
const more = files.length > shown.length ? `, +${files.length - shown.length} more` : "";
|
|
1020
|
-
logWarn(
|
|
1021
|
-
`${files.length} *.bundle.yaml file(s) are not scanned (the bundle kind became preset): ${shown.join(", ")}${more}. Run \`skaile migrate assets ${root} --write\` to rename them to *.preset.yaml. See ${LIBRARY_UPGRADE_DOCS}`
|
|
1022
|
-
);
|
|
1023
|
-
}
|
|
1024
|
-
return files.length;
|
|
1025
|
-
}
|
|
1026
974
|
var DEFAULT_IMPORT_VERSION = "0.1.0";
|
|
1027
975
|
var DEFAULT_IMPORT_STAGE = "alpha";
|
|
1028
976
|
function claudeSkillRoots() {
|
|
1029
977
|
const roots = [];
|
|
1030
978
|
const override = process.env.SKAILE_CLAUDE_SKILLS_DIR;
|
|
1031
979
|
if (override) roots.push(override);
|
|
1032
|
-
roots.push(
|
|
980
|
+
roots.push(path18.join(os.homedir(), ".claude", "skills"));
|
|
1033
981
|
return roots;
|
|
1034
982
|
}
|
|
1035
983
|
function resolveImportSource(nameOrPath) {
|
|
1036
|
-
const asPath =
|
|
1037
|
-
if (
|
|
1038
|
-
const dir =
|
|
1039
|
-
const skillFile =
|
|
1040
|
-
if (
|
|
984
|
+
const asPath = path18.resolve(nameOrPath);
|
|
985
|
+
if (fs8.existsSync(asPath)) {
|
|
986
|
+
const dir = fs8.statSync(asPath).isDirectory() ? asPath : path18.dirname(asPath);
|
|
987
|
+
const skillFile = path18.join(dir, "SKILL.md");
|
|
988
|
+
if (fs8.existsSync(skillFile)) return { dir, skillFile, via: "path" };
|
|
1041
989
|
}
|
|
1042
|
-
if (!nameOrPath.includes(
|
|
990
|
+
if (!nameOrPath.includes(path18.sep) && !nameOrPath.startsWith(".")) {
|
|
1043
991
|
for (const root of claudeSkillRoots()) {
|
|
1044
|
-
const dir =
|
|
1045
|
-
const skillFile =
|
|
1046
|
-
if (
|
|
992
|
+
const dir = path18.join(root, nameOrPath);
|
|
993
|
+
const skillFile = path18.join(dir, "SKILL.md");
|
|
994
|
+
if (fs8.existsSync(skillFile)) return { dir, skillFile, via: "claude-skills" };
|
|
1047
995
|
}
|
|
1048
996
|
}
|
|
1049
997
|
return null;
|
|
@@ -1139,13 +1087,7 @@ function makeAssetCommand() {
|
|
|
1139
1087
|
).option("--commit", "Auto-commit in git-backed libraries", false).action(
|
|
1140
1088
|
async (nameOrPath, opts) => {
|
|
1141
1089
|
rejectRemovedDomainOption(opts);
|
|
1142
|
-
if (opts.publisher !== void 0)
|
|
1143
|
-
const bare = opts.publisher.trim().replace(/^@/, "");
|
|
1144
|
-
if (!isValidPublisher(bare)) {
|
|
1145
|
-
logErr(`Invalid publisher "${opts.publisher}": ${PUBLISHER_HINT}.`);
|
|
1146
|
-
process.exit(1);
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1090
|
+
if (opts.publisher !== void 0) requireValidPublisherOrExit(opts.publisher);
|
|
1149
1091
|
const src = resolveImportSource(nameOrPath);
|
|
1150
1092
|
if (!src) {
|
|
1151
1093
|
logErr(
|
|
@@ -1175,19 +1117,20 @@ function makeAssetCommand() {
|
|
|
1175
1117
|
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
1176
1118
|
process.exit(1);
|
|
1177
1119
|
}
|
|
1178
|
-
|
|
1120
|
+
exitOnManifestPublisherProblems(target.path, target.name);
|
|
1121
|
+
const rawSkill = fs8.readFileSync(src.skillFile, "utf8");
|
|
1179
1122
|
const norm = opts.normalize ? normalizeSkillContent(rawSkill, {
|
|
1180
|
-
fallbackName:
|
|
1123
|
+
fallbackName: path18.basename(src.dir),
|
|
1181
1124
|
version: opts.version,
|
|
1182
1125
|
stage: opts.stage
|
|
1183
|
-
}) : { content: rawSkill, name:
|
|
1126
|
+
}) : { content: rawSkill, name: path18.basename(src.dir), changed: false, notes: [] };
|
|
1184
1127
|
if (!opts.normalize && !isValidAssetName(norm.name)) {
|
|
1185
1128
|
logWarn(
|
|
1186
1129
|
`Name "${norm.name}" is not canonical (kebab-case); \`skaile validate\` will reject this manifest entry. Drop --no-normalize to slugify it.`
|
|
1187
1130
|
);
|
|
1188
1131
|
}
|
|
1189
|
-
const destDir =
|
|
1190
|
-
if (
|
|
1132
|
+
const destDir = path18.join(target.path, norm.name);
|
|
1133
|
+
if (fs8.existsSync(destDir)) {
|
|
1191
1134
|
logErr(`Destination already exists: ${destDir}`);
|
|
1192
1135
|
process.exit(1);
|
|
1193
1136
|
}
|
|
@@ -1198,8 +1141,8 @@ function makeAssetCommand() {
|
|
|
1198
1141
|
);
|
|
1199
1142
|
process.exit(1);
|
|
1200
1143
|
}
|
|
1201
|
-
|
|
1202
|
-
|
|
1144
|
+
fs8.cpSync(src.dir, destDir, { recursive: true });
|
|
1145
|
+
fs8.writeFileSync(path18.join(destDir, "SKILL.md"), norm.content, "utf8");
|
|
1203
1146
|
for (const note of norm.notes) logInfo(` \u2022 ${note}`);
|
|
1204
1147
|
const fm = parseFrontmatter(norm.content).data;
|
|
1205
1148
|
for (const f of checkAgentSkillConformance(fm, { dirName: norm.name })) {
|
|
@@ -1239,7 +1182,7 @@ function makeAssetCommand() {
|
|
|
1239
1182
|
logErr(`Invalid --mode "${opts.mode}". Expected: copy | move | link.`);
|
|
1240
1183
|
process.exit(1);
|
|
1241
1184
|
}
|
|
1242
|
-
if (!
|
|
1185
|
+
if (!fs8.existsSync(srcPath)) {
|
|
1243
1186
|
logErr(`Source path does not exist: ${srcPath}`);
|
|
1244
1187
|
process.exit(1);
|
|
1245
1188
|
}
|
|
@@ -1265,23 +1208,23 @@ function makeAssetCommand() {
|
|
|
1265
1208
|
);
|
|
1266
1209
|
process.exit(1);
|
|
1267
1210
|
}
|
|
1268
|
-
const basename3 =
|
|
1211
|
+
const basename3 = path18.basename(srcPath);
|
|
1269
1212
|
const destDir = target.path;
|
|
1270
|
-
|
|
1271
|
-
const destPath =
|
|
1272
|
-
if (
|
|
1213
|
+
fs8.mkdirSync(destDir, { recursive: true });
|
|
1214
|
+
const destPath = path18.join(destDir, basename3);
|
|
1215
|
+
if (fs8.existsSync(destPath)) {
|
|
1273
1216
|
logErr(`Destination already exists: ${destPath}`);
|
|
1274
1217
|
process.exit(1);
|
|
1275
1218
|
}
|
|
1276
1219
|
switch (opts.mode) {
|
|
1277
1220
|
case "copy":
|
|
1278
|
-
|
|
1221
|
+
fs8.cpSync(srcPath, destPath, { recursive: true });
|
|
1279
1222
|
break;
|
|
1280
1223
|
case "move":
|
|
1281
|
-
|
|
1224
|
+
fs8.renameSync(srcPath, destPath);
|
|
1282
1225
|
break;
|
|
1283
1226
|
case "link":
|
|
1284
|
-
|
|
1227
|
+
fs8.symlinkSync(path18.resolve(srcPath), destPath);
|
|
1285
1228
|
break;
|
|
1286
1229
|
}
|
|
1287
1230
|
if (target.backend === "git" && opts.commit) {
|
|
@@ -1411,14 +1354,14 @@ function makeAuthCommand() {
|
|
|
1411
1354
|
}
|
|
1412
1355
|
function collectCacheTargets(scope) {
|
|
1413
1356
|
const out = [];
|
|
1414
|
-
out.push(
|
|
1415
|
-
out.push(
|
|
1416
|
-
out.push(
|
|
1357
|
+
out.push(path18__default.join(scope.projectDir, ".skaile", "cache"));
|
|
1358
|
+
out.push(path18__default.join(scope.projectDir, ".skaile", "store-cache"));
|
|
1359
|
+
out.push(path18__default.join(scope.projectDir, ".skaile", "repos"));
|
|
1417
1360
|
if (scope.global) {
|
|
1418
1361
|
out.push(globalCacheRoot());
|
|
1419
1362
|
const home = globalSkaileDir();
|
|
1420
|
-
out.push(
|
|
1421
|
-
out.push(
|
|
1363
|
+
out.push(path18__default.join(home, "repos"));
|
|
1364
|
+
out.push(path18__default.join(home, "catalog-cache"));
|
|
1422
1365
|
}
|
|
1423
1366
|
return out;
|
|
1424
1367
|
}
|
|
@@ -1432,7 +1375,7 @@ function dirSize(target) {
|
|
|
1432
1375
|
function dirSizeOfDir(dir) {
|
|
1433
1376
|
let total = 0;
|
|
1434
1377
|
for (const ent of readdirSync(dir, { withFileTypes: true })) {
|
|
1435
|
-
const child =
|
|
1378
|
+
const child = path18__default.join(dir, ent.name);
|
|
1436
1379
|
if (ent.isSymbolicLink()) continue;
|
|
1437
1380
|
if (ent.isDirectory()) total += dirSizeOfDir(child);
|
|
1438
1381
|
else if (ent.isFile()) total += statSync(child).size;
|
|
@@ -1458,7 +1401,7 @@ function makeCacheCommand() {
|
|
|
1458
1401
|
const cmd = new Command("cache").description("Inspect and reclaim the re-derivable cache");
|
|
1459
1402
|
cmd.command("clean").description("Remove the project cache (.skaile/cache); --global also clears ~/.skaile/cache").option("--global", "Also clear the global cache (sources + catalog) and legacy dirs").option("--dry-run", "Show what would be removed without doing it").option("-y, --yes", "Skip confirmation prompt").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
1460
1403
|
const targets = collectCacheTargets({
|
|
1461
|
-
projectDir:
|
|
1404
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
1462
1405
|
global: opts.global
|
|
1463
1406
|
}).filter((t) => existsSync(t));
|
|
1464
1407
|
if (targets.length === 0) {
|
|
@@ -1488,12 +1431,12 @@ function makeCacheCommand() {
|
|
|
1488
1431
|
for (const r of removed) logOk(`Removed ${r}`);
|
|
1489
1432
|
});
|
|
1490
1433
|
cmd.command("dir").description("Print the resolved cache roots").option("--global", "Include the global cache root").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
1491
|
-
console.log(
|
|
1434
|
+
console.log(path18__default.join(path18__default.resolve(opts.projectDir), ".skaile", "cache"));
|
|
1492
1435
|
if (opts.global) console.log(globalCacheRoot());
|
|
1493
1436
|
});
|
|
1494
1437
|
cmd.command("size").description("Show cache disk usage per directory").option("--global", "Include the global cache").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
1495
1438
|
const targets = collectCacheTargets({
|
|
1496
|
-
projectDir:
|
|
1439
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
1497
1440
|
global: opts.global
|
|
1498
1441
|
});
|
|
1499
1442
|
console.log();
|
|
@@ -1509,7 +1452,7 @@ function makeCatalogCommand() {
|
|
|
1509
1452
|
const catalog = new Command("catalog").description("Catalog source health and configuration");
|
|
1510
1453
|
catalog.command("test").description("Probe the configured catalog source and report status").option("--project-dir <path>", "Project directory (for project-level config overlay)").option("--url <url>", "Override the catalog URL for this probe").option("--force", "Probe the network even in air-gapped mode (cache_ttl: 0)").action(async (opts) => {
|
|
1511
1454
|
const { resolveConfig, isLocalCatalogUrl, trpcGetUrl } = await import('../library/index.js');
|
|
1512
|
-
const projectDir = opts.projectDir ?
|
|
1455
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : void 0;
|
|
1513
1456
|
const cfg = resolveConfig({ projectDir });
|
|
1514
1457
|
const baseUrl = opts.url ?? cfg.catalog.url;
|
|
1515
1458
|
if (isLocalCatalogUrl(baseUrl)) {
|
|
@@ -1527,7 +1470,7 @@ function makeCatalogCommand() {
|
|
|
1527
1470
|
});
|
|
1528
1471
|
catalog.command("info").description("Print the resolved catalog configuration (url, framing, cacheTtlMs)").option("--project-dir <path>", "Project directory (for project-level config overlay)").action(async (opts) => {
|
|
1529
1472
|
const { resolveConfig } = await import('../library/index.js');
|
|
1530
|
-
const projectDir = opts.projectDir ?
|
|
1473
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : void 0;
|
|
1531
1474
|
const cfg = resolveConfig({ projectDir });
|
|
1532
1475
|
console.log(`url: ${cfg.catalog.url}`);
|
|
1533
1476
|
console.log(`framing: ${cfg.catalog.framing}`);
|
|
@@ -1536,7 +1479,7 @@ function makeCatalogCommand() {
|
|
|
1536
1479
|
return catalog;
|
|
1537
1480
|
}
|
|
1538
1481
|
async function runLocalCatalogTest(projectDir) {
|
|
1539
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
1482
|
+
const { resolveCatalogSource } = await import('../open-library-4QSUORI6.js');
|
|
1540
1483
|
let resolved;
|
|
1541
1484
|
try {
|
|
1542
1485
|
resolved = await resolveCatalogSource({ projectDir });
|
|
@@ -1679,7 +1622,7 @@ async function scanLibraryFlowEntries() {
|
|
|
1679
1622
|
const { LocalIndex, resolveIndexPath, scanAuthoringLibraries } = await import('../library/index.js');
|
|
1680
1623
|
const indexPath = resolveIndexPath();
|
|
1681
1624
|
if (!existsSync(indexPath)) return entries;
|
|
1682
|
-
const { getKindRegistry: getKindRegistry2 } = await import('../open-registry-
|
|
1625
|
+
const { getKindRegistry: getKindRegistry2 } = await import('../open-registry-VCKS3MP5.js');
|
|
1683
1626
|
const index = new LocalIndex({ indexPath });
|
|
1684
1627
|
try {
|
|
1685
1628
|
for (const { assets } of await scanAuthoringLibraries(index, getKindRegistry2())) {
|
|
@@ -1729,11 +1672,11 @@ function findSkills() {
|
|
|
1729
1672
|
return deduped;
|
|
1730
1673
|
}
|
|
1731
1674
|
function walkSkills(dir, out) {
|
|
1732
|
-
for (const entry of
|
|
1733
|
-
const full =
|
|
1675
|
+
for (const entry of fs8__default.readdirSync(dir, { withFileTypes: true })) {
|
|
1676
|
+
const full = path18__default.join(dir, entry.name);
|
|
1734
1677
|
if (entry.isDirectory()) {
|
|
1735
|
-
const skillMd =
|
|
1736
|
-
if (
|
|
1678
|
+
const skillMd = path18__default.join(full, "SKILL.md");
|
|
1679
|
+
if (fs8__default.existsSync(skillMd)) {
|
|
1737
1680
|
out.push({ name: entry.name, path: full, skillPath: skillMd });
|
|
1738
1681
|
} else {
|
|
1739
1682
|
walkSkills(full, out);
|
|
@@ -1754,10 +1697,10 @@ function resolveFlowIds() {
|
|
|
1754
1697
|
}
|
|
1755
1698
|
}
|
|
1756
1699
|
function resolveSessionIds(projectDir) {
|
|
1757
|
-
const sessionsDir =
|
|
1758
|
-
if (!
|
|
1700
|
+
const sessionsDir = path18__default.join(projectDir, ".skaile", "sessions");
|
|
1701
|
+
if (!fs8__default.existsSync(sessionsDir)) return [];
|
|
1759
1702
|
try {
|
|
1760
|
-
return
|
|
1703
|
+
return fs8__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
1761
1704
|
} catch {
|
|
1762
1705
|
return [];
|
|
1763
1706
|
}
|
|
@@ -1896,7 +1839,7 @@ function printResolvedPathsSection(config) {
|
|
|
1896
1839
|
console.log(` ${S.label("prompts:".padEnd(16))} ${config.promptsDir ?? paths.promptsDir}`);
|
|
1897
1840
|
}
|
|
1898
1841
|
async function showConfig(opts) {
|
|
1899
|
-
const projectDir = opts.projectDir ?
|
|
1842
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
|
|
1900
1843
|
let config;
|
|
1901
1844
|
let wsDefaults;
|
|
1902
1845
|
try {
|
|
@@ -1941,13 +1884,13 @@ function makeConfigCommand() {
|
|
|
1941
1884
|
const cmd = new Command("config").description("Manage personal config (.skaile/settings.json)");
|
|
1942
1885
|
cmd.command("show").description("Show effective config with sources").option("--project-dir <path>", "Project directory").action((opts) => showConfig(opts));
|
|
1943
1886
|
cmd.command("get <key>").description("Get an effective config value").option("--project-dir <path>", "Project directory").action(async (key, opts) => {
|
|
1944
|
-
const projectDir = opts.projectDir ?
|
|
1887
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
|
|
1945
1888
|
const config = await resolveSettings(projectDir);
|
|
1946
1889
|
const value = config[key];
|
|
1947
1890
|
console.log(value ?? S.dim("(not set)"));
|
|
1948
1891
|
});
|
|
1949
1892
|
cmd.command("set <key> <value>").description("Set a personal config value (driver, model, apiKey.<provider>)").option("--project-dir <path>", "Project directory").option("--global", "Write to ~/.skaile/settings.json instead of project-local").action(async (key, value, opts) => {
|
|
1950
|
-
const projectDir = opts.projectDir ?
|
|
1893
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
|
|
1951
1894
|
if (key === "provider" || key === "cloud" || key === "cloudConfig") {
|
|
1952
1895
|
logErr(
|
|
1953
1896
|
`'${key}' is no longer a setting \u2014 an endpoint is an AI provider registry entry and a session selects one with a model reference.
|
|
@@ -2287,8 +2230,8 @@ function makeConnectorCommand() {
|
|
|
2287
2230
|
async (driver, opts) => {
|
|
2288
2231
|
const { installNpmPackages } = await import('../connectors/index.js');
|
|
2289
2232
|
const { scanDirectory: scanDirectory2, factoryAssetRoots: factoryAssetRoots2, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
2290
|
-
const projectDir =
|
|
2291
|
-
const yamlPath =
|
|
2233
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2234
|
+
const yamlPath = path18__default.join(projectDir, "skaile.yaml");
|
|
2292
2235
|
if (!existsSync(yamlPath)) {
|
|
2293
2236
|
logErr("No skaile.yaml found in current directory. Run 'skaile init' first.");
|
|
2294
2237
|
process.exit(1);
|
|
@@ -2348,8 +2291,8 @@ ${installResult.output}`);
|
|
|
2348
2291
|
);
|
|
2349
2292
|
cmd.command("remove <id>").option("--project-dir <path>", "Workspace directory", process.cwd()).description("Remove a connector from skaile.yaml by its instance ID").action(async (id, opts) => {
|
|
2350
2293
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
2351
|
-
const projectDir =
|
|
2352
|
-
const yamlPath =
|
|
2294
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2295
|
+
const yamlPath = path18__default.join(projectDir, "skaile.yaml");
|
|
2353
2296
|
if (!existsSync(yamlPath)) {
|
|
2354
2297
|
logErr("No skaile.yaml found in current directory.");
|
|
2355
2298
|
process.exit(1);
|
|
@@ -2366,7 +2309,7 @@ ${installResult.output}`);
|
|
|
2366
2309
|
cmd.command("status [id]").option("--project-dir <path>", "Workspace directory", process.cwd()).description("Connect and report health status for one or all connectors").action(async (id, opts) => {
|
|
2367
2310
|
const res = await import('../connectors/index.js');
|
|
2368
2311
|
res.registerBuiltinConnectors();
|
|
2369
|
-
const projectDir =
|
|
2312
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2370
2313
|
const declarations = res.loadConnectorDeclarations(projectDir);
|
|
2371
2314
|
if (declarations.length === 0) {
|
|
2372
2315
|
console.log("No connectors configured in skaile.yaml.");
|
|
@@ -2390,7 +2333,7 @@ ${installResult.output}`);
|
|
|
2390
2333
|
await manager.disconnectAll();
|
|
2391
2334
|
});
|
|
2392
2335
|
cmd.command("list").description("List all configured connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
2393
|
-
const projectDir =
|
|
2336
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2394
2337
|
const manager = await connectConnectors(projectDir);
|
|
2395
2338
|
try {
|
|
2396
2339
|
console.log(JSON.stringify(manager.listConnectors(), null, 2));
|
|
@@ -2399,7 +2342,7 @@ ${installResult.output}`);
|
|
|
2399
2342
|
}
|
|
2400
2343
|
});
|
|
2401
2344
|
cmd.command("sync [id]").description("Re-sync a filesystem-face connector or all of them (git pull, S3 refresh, etc.)").option("--all", "Sync all connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
|
|
2402
|
-
const projectDir =
|
|
2345
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2403
2346
|
const manager = await connectConnectors(projectDir);
|
|
2404
2347
|
try {
|
|
2405
2348
|
if (opts.all) {
|
|
@@ -2423,7 +2366,7 @@ ${installResult.output}`);
|
|
|
2423
2366
|
}
|
|
2424
2367
|
});
|
|
2425
2368
|
cmd.command("ops <id>").description("List available operations for a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
|
|
2426
|
-
const projectDir =
|
|
2369
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2427
2370
|
const manager = await connectConnectors(projectDir);
|
|
2428
2371
|
try {
|
|
2429
2372
|
if (!manager.has(id)) {
|
|
@@ -2438,7 +2381,7 @@ ${installResult.output}`);
|
|
|
2438
2381
|
}
|
|
2439
2382
|
});
|
|
2440
2383
|
cmd.command("read <id> <resource-path>").description("Read content from a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, opts) => {
|
|
2441
|
-
const projectDir =
|
|
2384
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2442
2385
|
const manager = await connectConnectors(projectDir);
|
|
2443
2386
|
try {
|
|
2444
2387
|
const content = await manager.read(id, resourcePath);
|
|
@@ -2448,7 +2391,7 @@ ${installResult.output}`);
|
|
|
2448
2391
|
}
|
|
2449
2392
|
});
|
|
2450
2393
|
cmd.command("write <id> <resource-path> <content>").description("Write content to a connector at a path").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, content, opts) => {
|
|
2451
|
-
const projectDir =
|
|
2394
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2452
2395
|
const manager = await connectConnectors(projectDir);
|
|
2453
2396
|
try {
|
|
2454
2397
|
await manager.write(id, resourcePath, { data: content });
|
|
@@ -2458,7 +2401,7 @@ ${installResult.output}`);
|
|
|
2458
2401
|
}
|
|
2459
2402
|
});
|
|
2460
2403
|
cmd.command("entries <id> [resource-path]").description("List entries in a connector (files, keys, rows, etc)").option("--project-dir <path>", "Workspace directory", process.cwd()).option("--recursive", "Include nested entries").option("--limit <n>", "Maximum entries to return", parsePositiveIntOption).action(async (id, resourcePath, opts) => {
|
|
2461
|
-
const projectDir =
|
|
2404
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2462
2405
|
const manager = await connectConnectors(projectDir);
|
|
2463
2406
|
try {
|
|
2464
2407
|
const entries = await manager.list(id, resourcePath, {
|
|
@@ -2471,7 +2414,7 @@ ${installResult.output}`);
|
|
|
2471
2414
|
}
|
|
2472
2415
|
});
|
|
2473
2416
|
cmd.command("search <id> <query>").description("Search within a connector for matching content").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, query, opts) => {
|
|
2474
|
-
const projectDir =
|
|
2417
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2475
2418
|
const manager = await connectConnectors(projectDir);
|
|
2476
2419
|
try {
|
|
2477
2420
|
const results = await manager.search(id, query);
|
|
@@ -2481,7 +2424,7 @@ ${installResult.output}`);
|
|
|
2481
2424
|
}
|
|
2482
2425
|
});
|
|
2483
2426
|
cmd.command("delete <id> <resource-path>").description("Delete an entry from a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, opts) => {
|
|
2484
|
-
const projectDir =
|
|
2427
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2485
2428
|
const manager = await connectConnectors(projectDir);
|
|
2486
2429
|
try {
|
|
2487
2430
|
const ok = await manager.delete(id, resourcePath);
|
|
@@ -2491,7 +2434,7 @@ ${installResult.output}`);
|
|
|
2491
2434
|
}
|
|
2492
2435
|
});
|
|
2493
2436
|
cmd.command("run <id> <op> [args...]").description("Run a custom adapter operation (e.g. git log, sqlite query)").option("--project-dir <path>", "Workspace directory", process.cwd()).allowUnknownOption().action(async (id, op, args, opts) => {
|
|
2494
|
-
const projectDir =
|
|
2437
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2495
2438
|
const manager = await connectConnectors(projectDir);
|
|
2496
2439
|
try {
|
|
2497
2440
|
if (!manager.has(id)) {
|
|
@@ -2600,7 +2543,7 @@ function envRecord() {
|
|
|
2600
2543
|
async function buildDeployContext(projectDir) {
|
|
2601
2544
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2602
2545
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
2603
|
-
const workspaceId = config.name ??
|
|
2546
|
+
const workspaceId = config.name ?? path18__default.basename(projectDir);
|
|
2604
2547
|
let log;
|
|
2605
2548
|
try {
|
|
2606
2549
|
const { createLogger } = await import('../core/logging.js');
|
|
@@ -2632,13 +2575,13 @@ async function ensureTargetsRegistered(projectDir) {
|
|
|
2632
2575
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2633
2576
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
2634
2577
|
if (config.plugins && config.plugins.length > 0) {
|
|
2635
|
-
const { ensurePluginsLoaded } = await import('../plugin-store-
|
|
2578
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-X7GPWGBG.js');
|
|
2636
2579
|
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
2637
2580
|
for (const f of result.failed) logWarn(f.error);
|
|
2638
2581
|
}
|
|
2639
2582
|
}
|
|
2640
2583
|
async function runUp(opts) {
|
|
2641
|
-
const projectDir =
|
|
2584
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2642
2585
|
await ensureTargetsRegistered(projectDir);
|
|
2643
2586
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2644
2587
|
const { resolveDeployTarget, pluginRegistry } = await import('../plugin-registry/index.js');
|
|
@@ -2706,7 +2649,7 @@ async function restoreFromHandle(projectDir) {
|
|
|
2706
2649
|
return { target, handle, ctx };
|
|
2707
2650
|
}
|
|
2708
2651
|
async function runDown(opts) {
|
|
2709
|
-
const projectDir =
|
|
2652
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2710
2653
|
const restored = await restoreFromHandle(projectDir);
|
|
2711
2654
|
if (!restored) return;
|
|
2712
2655
|
await restored.handle.stop();
|
|
@@ -2715,7 +2658,7 @@ async function runDown(opts) {
|
|
|
2715
2658
|
logOk(`Stopped ${S.cmd(restored.target.id)} and cleared the handle.`);
|
|
2716
2659
|
}
|
|
2717
2660
|
async function runStatus(opts) {
|
|
2718
|
-
const projectDir =
|
|
2661
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2719
2662
|
const restored = await restoreFromHandle(projectDir);
|
|
2720
2663
|
if (!restored) return;
|
|
2721
2664
|
const health = await restored.handle.health();
|
|
@@ -2729,7 +2672,7 @@ async function runStatus(opts) {
|
|
|
2729
2672
|
console.log();
|
|
2730
2673
|
}
|
|
2731
2674
|
async function runLogs(opts) {
|
|
2732
|
-
const projectDir =
|
|
2675
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
2733
2676
|
const restored = await restoreFromHandle(projectDir);
|
|
2734
2677
|
if (!restored) return;
|
|
2735
2678
|
if (!restored.handle.logs) {
|
|
@@ -2755,30 +2698,34 @@ function makeDiffCommand() {
|
|
|
2755
2698
|
return new Command("diff").description("Show changes between deployed and source versions").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
2756
2699
|
const am2 = new AssetManager({
|
|
2757
2700
|
registry: getKindRegistry(),
|
|
2758
|
-
projectDir:
|
|
2701
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
2759
2702
|
});
|
|
2760
2703
|
const result = await am2.diff(ref);
|
|
2704
|
+
const problems = (await am2.gapsOf(ref)).filter(
|
|
2705
|
+
(g) => !(g.type === "content" && result.status === "differs")
|
|
2706
|
+
);
|
|
2761
2707
|
switch (result.status) {
|
|
2762
2708
|
case "not-found":
|
|
2763
|
-
logErr(`Asset not found: ${ref}`);
|
|
2764
|
-
|
|
2765
|
-
return;
|
|
2709
|
+
if (problems.length === 0) logErr(`Asset not found: ${ref}`);
|
|
2710
|
+
break;
|
|
2766
2711
|
case "not-deployed":
|
|
2767
|
-
logWarn(`${ref} is not deployed \u2014 run skaile install`);
|
|
2768
|
-
|
|
2712
|
+
if (problems.length === 0) logWarn(`${ref} is not deployed \u2014 run skaile install`);
|
|
2713
|
+
break;
|
|
2769
2714
|
case "identical":
|
|
2770
2715
|
logInfo("No differences.");
|
|
2771
|
-
|
|
2716
|
+
break;
|
|
2772
2717
|
case "differs":
|
|
2773
2718
|
console.log(result.diff);
|
|
2774
|
-
|
|
2719
|
+
break;
|
|
2775
2720
|
}
|
|
2721
|
+
for (const g of problems) logErr(g.message);
|
|
2722
|
+
if (result.status === "not-found" || problems.length > 0) process.exitCode = 1;
|
|
2776
2723
|
});
|
|
2777
2724
|
}
|
|
2778
2725
|
function makeFlowCommand() {
|
|
2779
2726
|
const cmd = new Command("flow").description("Manage flows");
|
|
2780
2727
|
cmd.command("list").description("List available flows").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
2781
|
-
const flows = await discoverFlowsWithLibraries(
|
|
2728
|
+
const flows = await discoverFlowsWithLibraries(path18__default.resolve(opts.projectDir));
|
|
2782
2729
|
if (flows.length === 0) {
|
|
2783
2730
|
logInfo("No flows found.");
|
|
2784
2731
|
return;
|
|
@@ -2793,7 +2740,7 @@ function makeFlowCommand() {
|
|
|
2793
2740
|
console.log();
|
|
2794
2741
|
});
|
|
2795
2742
|
cmd.command("show <id>").description("Show flow details and node graph").option("--project-dir <path>", "Project directory", process.cwd()).action(async (id, opts) => {
|
|
2796
|
-
const flows = await discoverFlowsWithLibraries(
|
|
2743
|
+
const flows = await discoverFlowsWithLibraries(path18__default.resolve(opts.projectDir));
|
|
2797
2744
|
const flow = flows.find((f) => f.id === id);
|
|
2798
2745
|
if (!flow) {
|
|
2799
2746
|
logErr(`Flow not found: ${id}`);
|
|
@@ -2827,7 +2774,7 @@ function makeHistoryCommand() {
|
|
|
2827
2774
|
cmd.argument("[limit]", "Number of entries to show", "20").option("--project-dir <path>", "Project directory", process.cwd()).action((limitStr, opts) => {
|
|
2828
2775
|
const am2 = new AssetManager({
|
|
2829
2776
|
registry: getKindRegistry(),
|
|
2830
|
-
projectDir:
|
|
2777
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
2831
2778
|
});
|
|
2832
2779
|
const limit = parseInt(limitStr, 10) || 20;
|
|
2833
2780
|
const entries = am2.history(limit);
|
|
@@ -2850,7 +2797,7 @@ function makeHistoryCommand() {
|
|
|
2850
2797
|
cmd.command("clear").description("Clear action history").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
2851
2798
|
const am2 = new AssetManager({
|
|
2852
2799
|
registry: getKindRegistry(),
|
|
2853
|
-
projectDir:
|
|
2800
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
2854
2801
|
});
|
|
2855
2802
|
am2.clearHistory();
|
|
2856
2803
|
logOk("History cleared.");
|
|
@@ -2864,12 +2811,12 @@ var MCP_SERVER_ENTRY = {
|
|
|
2864
2811
|
env: {}
|
|
2865
2812
|
};
|
|
2866
2813
|
function pluginDir(projectDir) {
|
|
2867
|
-
return
|
|
2814
|
+
return path18__default.join(projectDir, ".claude", "plugins", "skaile");
|
|
2868
2815
|
}
|
|
2869
2816
|
async function readJsonStrict(p6) {
|
|
2870
2817
|
let raw;
|
|
2871
2818
|
try {
|
|
2872
|
-
raw = await
|
|
2819
|
+
raw = await fs5.readFile(p6, "utf-8");
|
|
2873
2820
|
} catch {
|
|
2874
2821
|
return null;
|
|
2875
2822
|
}
|
|
@@ -2882,32 +2829,32 @@ async function readJsonStrict(p6) {
|
|
|
2882
2829
|
}
|
|
2883
2830
|
}
|
|
2884
2831
|
async function writeJson(p6, value) {
|
|
2885
|
-
await
|
|
2886
|
-
await
|
|
2832
|
+
await fs5.mkdir(path18__default.dirname(p6), { recursive: true });
|
|
2833
|
+
await fs5.writeFile(p6, `${JSON.stringify(value, null, 2)}
|
|
2887
2834
|
`);
|
|
2888
2835
|
}
|
|
2889
2836
|
async function copyDir(src, dest) {
|
|
2890
|
-
await
|
|
2891
|
-
const entries = await
|
|
2837
|
+
await fs5.mkdir(dest, { recursive: true });
|
|
2838
|
+
const entries = await fs5.readdir(src, { withFileTypes: true });
|
|
2892
2839
|
for (const entry of entries) {
|
|
2893
|
-
const srcPath =
|
|
2894
|
-
const destPath =
|
|
2840
|
+
const srcPath = path18__default.join(src, entry.name);
|
|
2841
|
+
const destPath = path18__default.join(dest, entry.name);
|
|
2895
2842
|
if (entry.isDirectory()) await copyDir(srcPath, destPath);
|
|
2896
|
-
else await
|
|
2843
|
+
else await fs5.copyFile(srcPath, destPath);
|
|
2897
2844
|
}
|
|
2898
2845
|
}
|
|
2899
2846
|
async function install(projectDir, opts) {
|
|
2900
2847
|
return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);
|
|
2901
2848
|
}
|
|
2902
2849
|
async function installMcp(projectDir) {
|
|
2903
|
-
const mcpPath =
|
|
2850
|
+
const mcpPath = path18__default.join(projectDir, ".claude", "mcp.json");
|
|
2904
2851
|
const existing = await readJsonStrict(mcpPath) ?? {};
|
|
2905
2852
|
const mcpServers = { ...existing.mcpServers ?? {} };
|
|
2906
2853
|
const previous = mcpServers[SKAILE_MCP_NAME];
|
|
2907
2854
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);
|
|
2908
2855
|
let warning;
|
|
2909
2856
|
if (previous && !matches) {
|
|
2910
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${
|
|
2857
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path18__default.relative(projectDir, mcpPath)}`;
|
|
2911
2858
|
}
|
|
2912
2859
|
mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;
|
|
2913
2860
|
await writeJson(mcpPath, { ...existing, mcpServers });
|
|
@@ -2916,15 +2863,15 @@ async function installMcp(projectDir) {
|
|
|
2916
2863
|
async function installFullPlugin(projectDir) {
|
|
2917
2864
|
const dir = pluginDir(projectDir);
|
|
2918
2865
|
for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {
|
|
2919
|
-
const dest =
|
|
2920
|
-
await
|
|
2921
|
-
await
|
|
2866
|
+
const dest = path18__default.join(dir, rel);
|
|
2867
|
+
await fs5.mkdir(path18__default.dirname(dest), { recursive: true });
|
|
2868
|
+
await fs5.writeFile(dest, content);
|
|
2922
2869
|
}
|
|
2923
|
-
const projectSkillsDir =
|
|
2870
|
+
const projectSkillsDir = path18__default.join(projectDir, ".skaile", "skills");
|
|
2924
2871
|
if (existsSync(projectSkillsDir)) {
|
|
2925
|
-
await copyDir(projectSkillsDir,
|
|
2872
|
+
await copyDir(projectSkillsDir, path18__default.join(dir, "skills"));
|
|
2926
2873
|
}
|
|
2927
|
-
const settingsPath =
|
|
2874
|
+
const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
|
|
2928
2875
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2929
2876
|
const plugins = settings.plugins ?? [];
|
|
2930
2877
|
if (!plugins.includes(dir)) plugins.push(dir);
|
|
@@ -2932,8 +2879,8 @@ async function installFullPlugin(projectDir) {
|
|
|
2932
2879
|
return { changed: true, method: "plugin" };
|
|
2933
2880
|
}
|
|
2934
2881
|
async function uninstall(projectDir) {
|
|
2935
|
-
const settingsPath =
|
|
2936
|
-
const mcpPath =
|
|
2882
|
+
const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
|
|
2883
|
+
const mcpPath = path18__default.join(projectDir, ".claude", "mcp.json");
|
|
2937
2884
|
const dir = pluginDir(projectDir);
|
|
2938
2885
|
let changed = false;
|
|
2939
2886
|
const settings = await readJsonStrict(settingsPath);
|
|
@@ -2947,7 +2894,7 @@ async function uninstall(projectDir) {
|
|
|
2947
2894
|
}
|
|
2948
2895
|
}
|
|
2949
2896
|
if (existsSync(dir)) {
|
|
2950
|
-
await
|
|
2897
|
+
await fs5.rm(dir, { recursive: true, force: true });
|
|
2951
2898
|
changed = true;
|
|
2952
2899
|
}
|
|
2953
2900
|
const mcp = await readJsonStrict(mcpPath);
|
|
@@ -2957,7 +2904,7 @@ async function uninstall(projectDir) {
|
|
|
2957
2904
|
const updated = { ...mcp, mcpServers: rest };
|
|
2958
2905
|
if (Object.keys(rest).length === 0) delete updated.mcpServers;
|
|
2959
2906
|
if (Object.keys(updated).length === 0) {
|
|
2960
|
-
await
|
|
2907
|
+
await fs5.unlink(mcpPath);
|
|
2961
2908
|
} else {
|
|
2962
2909
|
await writeJson(mcpPath, updated);
|
|
2963
2910
|
}
|
|
@@ -2967,12 +2914,12 @@ async function uninstall(projectDir) {
|
|
|
2967
2914
|
async function detectInstall(projectDir) {
|
|
2968
2915
|
const dir = pluginDir(projectDir);
|
|
2969
2916
|
const settings = await readJsonStrict(
|
|
2970
|
-
|
|
2917
|
+
path18__default.join(projectDir, ".claude", "settings.json")
|
|
2971
2918
|
);
|
|
2972
|
-
if (existsSync(
|
|
2919
|
+
if (existsSync(path18__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
|
|
2973
2920
|
return { method: "plugin", pluginPath: dir };
|
|
2974
2921
|
}
|
|
2975
|
-
const mcp = await readJsonStrict(
|
|
2922
|
+
const mcp = await readJsonStrict(path18__default.join(projectDir, ".claude", "mcp.json"));
|
|
2976
2923
|
if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {
|
|
2977
2924
|
return { method: "mcp" };
|
|
2978
2925
|
}
|
|
@@ -2981,7 +2928,7 @@ async function detectInstall(projectDir) {
|
|
|
2981
2928
|
async function enable(projectDir) {
|
|
2982
2929
|
const detected = await detectInstall(projectDir);
|
|
2983
2930
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
2984
|
-
const settingsPath =
|
|
2931
|
+
const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
|
|
2985
2932
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2986
2933
|
if (detected.method === "plugin") {
|
|
2987
2934
|
const disabled2 = settings.disabledPlugins ?? [];
|
|
@@ -3003,7 +2950,7 @@ async function enable(projectDir) {
|
|
|
3003
2950
|
async function disable(projectDir) {
|
|
3004
2951
|
const detected = await detectInstall(projectDir);
|
|
3005
2952
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
3006
|
-
const settingsPath =
|
|
2953
|
+
const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
|
|
3007
2954
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
3008
2955
|
if (detected.method === "plugin") {
|
|
3009
2956
|
const list2 = settings.disabledPlugins ?? [];
|
|
@@ -3023,12 +2970,12 @@ async function disable(projectDir) {
|
|
|
3023
2970
|
return { changed: true };
|
|
3024
2971
|
}
|
|
3025
2972
|
async function status(projectDir) {
|
|
3026
|
-
const settingsPath =
|
|
3027
|
-
const mcpPath =
|
|
2973
|
+
const settingsPath = path18__default.join(projectDir, ".claude", "settings.json");
|
|
2974
|
+
const mcpPath = path18__default.join(projectDir, ".claude", "mcp.json");
|
|
3028
2975
|
const dir = pluginDir(projectDir);
|
|
3029
2976
|
const settings = await readJsonStrict(settingsPath);
|
|
3030
2977
|
const mcp = await readJsonStrict(mcpPath);
|
|
3031
|
-
const pluginInstalled = !!(existsSync(
|
|
2978
|
+
const pluginInstalled = !!(existsSync(path18__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
|
|
3032
2979
|
const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);
|
|
3033
2980
|
if (!pluginInstalled && !mcpInstalled) {
|
|
3034
2981
|
return {
|
|
@@ -3046,7 +2993,7 @@ async function status(projectDir) {
|
|
|
3046
2993
|
installed: "yes",
|
|
3047
2994
|
enabled: disabled2 ? "no" : "yes",
|
|
3048
2995
|
method: "plugin",
|
|
3049
|
-
location:
|
|
2996
|
+
location: path18__default.relative(projectDir, dir)
|
|
3050
2997
|
};
|
|
3051
2998
|
}
|
|
3052
2999
|
const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;
|
|
@@ -3055,7 +3002,7 @@ async function status(projectDir) {
|
|
|
3055
3002
|
installed: "yes",
|
|
3056
3003
|
enabled: disabled ? "no" : "yes",
|
|
3057
3004
|
method: "mcp",
|
|
3058
|
-
location:
|
|
3005
|
+
location: path18__default.relative(projectDir, mcpPath)
|
|
3059
3006
|
};
|
|
3060
3007
|
}
|
|
3061
3008
|
var SKAILE_MCP_NAME2 = "skaile-workspace";
|
|
@@ -3069,7 +3016,7 @@ function buildEntry(projectDir) {
|
|
|
3069
3016
|
async function readConfig(p6) {
|
|
3070
3017
|
let raw;
|
|
3071
3018
|
try {
|
|
3072
|
-
raw = await
|
|
3019
|
+
raw = await fs5.readFile(p6, "utf-8");
|
|
3073
3020
|
} catch {
|
|
3074
3021
|
return null;
|
|
3075
3022
|
}
|
|
@@ -3082,16 +3029,16 @@ async function readConfig(p6) {
|
|
|
3082
3029
|
}
|
|
3083
3030
|
}
|
|
3084
3031
|
async function writeConfig(p6, value) {
|
|
3085
|
-
await
|
|
3032
|
+
await fs5.mkdir(path18__default.dirname(p6), { recursive: true });
|
|
3086
3033
|
const cleaned = {};
|
|
3087
3034
|
for (const [k, v] of Object.entries(value)) {
|
|
3088
3035
|
if (v === void 0) continue;
|
|
3089
3036
|
cleaned[k] = v;
|
|
3090
3037
|
}
|
|
3091
|
-
await
|
|
3038
|
+
await fs5.writeFile(p6, stringify$1(cleaned));
|
|
3092
3039
|
}
|
|
3093
3040
|
function configPath(projectDir) {
|
|
3094
|
-
return
|
|
3041
|
+
return path18__default.join(projectDir, ".codex", "config.toml");
|
|
3095
3042
|
}
|
|
3096
3043
|
async function install2(projectDir) {
|
|
3097
3044
|
const p6 = configPath(projectDir);
|
|
@@ -3102,7 +3049,7 @@ async function install2(projectDir) {
|
|
|
3102
3049
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
|
|
3103
3050
|
let warning;
|
|
3104
3051
|
if (previous && !matches) {
|
|
3105
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${
|
|
3052
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path18__default.relative(projectDir, p6)}`;
|
|
3106
3053
|
}
|
|
3107
3054
|
if (matches) return { changed: false, method: "toml" };
|
|
3108
3055
|
servers[SKAILE_MCP_NAME2] = next;
|
|
@@ -3119,7 +3066,7 @@ async function uninstall2(projectDir) {
|
|
|
3119
3066
|
const updated = { ...cfg, mcp_servers: rest };
|
|
3120
3067
|
if (Object.keys(rest).length === 0) delete updated.mcp_servers;
|
|
3121
3068
|
if (Object.keys(updated).length === 0) {
|
|
3122
|
-
await
|
|
3069
|
+
await fs5.unlink(p6);
|
|
3123
3070
|
} else {
|
|
3124
3071
|
await writeConfig(p6, updated);
|
|
3125
3072
|
}
|
|
@@ -3143,43 +3090,43 @@ async function status2(projectDir) {
|
|
|
3143
3090
|
installed: "yes",
|
|
3144
3091
|
enabled: "n/a",
|
|
3145
3092
|
method: "mcp",
|
|
3146
|
-
location:
|
|
3093
|
+
location: path18__default.relative(projectDir, p6)
|
|
3147
3094
|
};
|
|
3148
3095
|
}
|
|
3149
3096
|
async function install3(projectDir) {
|
|
3150
|
-
const extDir =
|
|
3151
|
-
const extPath =
|
|
3152
|
-
await
|
|
3097
|
+
const extDir = path18__default.join(projectDir, ".omp", "extensions");
|
|
3098
|
+
const extPath = path18__default.join(extDir, "skaile.ts");
|
|
3099
|
+
await fs5.mkdir(extDir, { recursive: true });
|
|
3153
3100
|
const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
|
|
3154
3101
|
const plugin = new WorkspacePlugin({ projectDir });
|
|
3155
3102
|
const nextSrc = await plugin.buildOmpExtensionSource();
|
|
3156
3103
|
let prevSrc = null;
|
|
3157
3104
|
try {
|
|
3158
|
-
prevSrc = await
|
|
3105
|
+
prevSrc = await fs5.readFile(extPath, "utf-8");
|
|
3159
3106
|
} catch {
|
|
3160
3107
|
}
|
|
3161
3108
|
if (prevSrc === nextSrc) return { changed: false, method: "generated" };
|
|
3162
|
-
await
|
|
3109
|
+
await fs5.writeFile(extPath, nextSrc);
|
|
3163
3110
|
return { changed: true, method: "generated" };
|
|
3164
3111
|
}
|
|
3165
3112
|
async function uninstall3(projectDir) {
|
|
3166
|
-
const extPath =
|
|
3113
|
+
const extPath = path18__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3167
3114
|
try {
|
|
3168
|
-
await
|
|
3115
|
+
await fs5.unlink(extPath);
|
|
3169
3116
|
return { changed: true };
|
|
3170
3117
|
} catch {
|
|
3171
3118
|
return { changed: false };
|
|
3172
3119
|
}
|
|
3173
3120
|
}
|
|
3174
3121
|
async function status3(projectDir) {
|
|
3175
|
-
const extPath =
|
|
3122
|
+
const extPath = path18__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3176
3123
|
if (existsSync(extPath)) {
|
|
3177
3124
|
return {
|
|
3178
3125
|
harness: "omp",
|
|
3179
3126
|
installed: "yes",
|
|
3180
3127
|
enabled: "n/a",
|
|
3181
3128
|
method: "extension",
|
|
3182
|
-
location:
|
|
3129
|
+
location: path18__default.relative(projectDir, extPath)
|
|
3183
3130
|
};
|
|
3184
3131
|
}
|
|
3185
3132
|
return {
|
|
@@ -3242,7 +3189,7 @@ async function installCodex(projectDir) {
|
|
|
3242
3189
|
console.log(` ${S.dim("\u2192")} Restart Codex CLI to pick up the change.`);
|
|
3243
3190
|
}
|
|
3244
3191
|
async function runInstall(opts) {
|
|
3245
|
-
const projectDir =
|
|
3192
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
3246
3193
|
const targets = resolveDriver(opts.driver);
|
|
3247
3194
|
let exitCode = 0;
|
|
3248
3195
|
if (targets.includes("claude-code")) {
|
|
@@ -3276,7 +3223,7 @@ async function uninstallCodex(projectDir) {
|
|
|
3276
3223
|
else logInfo(`codex: not installed`);
|
|
3277
3224
|
}
|
|
3278
3225
|
async function runUninstall(opts) {
|
|
3279
|
-
const projectDir =
|
|
3226
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
3280
3227
|
const targets = resolveDriver(opts.driver);
|
|
3281
3228
|
let exitCode = 0;
|
|
3282
3229
|
if (targets.includes("claude-code")) {
|
|
@@ -3319,7 +3266,7 @@ async function toggleTarget(t, projectDir, action3) {
|
|
|
3319
3266
|
});
|
|
3320
3267
|
}
|
|
3321
3268
|
async function runToggle(opts, action3) {
|
|
3322
|
-
const projectDir =
|
|
3269
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
3323
3270
|
const requestedAll = opts.driver === "all";
|
|
3324
3271
|
const targets = resolveDriver(opts.driver);
|
|
3325
3272
|
const usageError = checkToggleSupported(targets, requestedAll, action3);
|
|
@@ -3331,7 +3278,7 @@ async function runToggle(opts, action3) {
|
|
|
3331
3278
|
return exitCode;
|
|
3332
3279
|
}
|
|
3333
3280
|
async function runStatus2(opts) {
|
|
3334
|
-
const projectDir =
|
|
3281
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
3335
3282
|
const targets = resolveDriver(opts.driver);
|
|
3336
3283
|
const rows = [];
|
|
3337
3284
|
let exitCode = 0;
|
|
@@ -3402,7 +3349,7 @@ async function runHook(event) {
|
|
|
3402
3349
|
await plugin.shutdown();
|
|
3403
3350
|
return;
|
|
3404
3351
|
}
|
|
3405
|
-
const store = new PluginStore(
|
|
3352
|
+
const store = new PluginStore(path18__default.join(projectDir, ".skaile", "plugin-state.json"));
|
|
3406
3353
|
await store.load();
|
|
3407
3354
|
const status4 = store.get("connector:status");
|
|
3408
3355
|
if (status4 && typeof status4 === "object" && Object.keys(status4).length > 0) {
|
|
@@ -3480,19 +3427,22 @@ function unfinishedGitState(dir) {
|
|
|
3480
3427
|
for (const [entry, state2] of Object.entries(UNFINISHED_GIT_ENTRIES)) {
|
|
3481
3428
|
const p6 = spawnSync("git", ["rev-parse", "--git-path", entry], { cwd: dir, encoding: "utf-8" });
|
|
3482
3429
|
if (p6.status !== 0) return "the git directory could not be read";
|
|
3483
|
-
if (
|
|
3430
|
+
if (fs8.existsSync(path18.resolve(dir, p6.stdout.trim()))) return state2;
|
|
3484
3431
|
}
|
|
3485
3432
|
return null;
|
|
3486
3433
|
}
|
|
3487
3434
|
async function reindexLibrary(lib, library, name) {
|
|
3488
3435
|
assertManifestEditableOrExit(lib.path);
|
|
3436
|
+
exitOnManifestPublisherProblems(lib.path, name);
|
|
3489
3437
|
const badRequires = manifestRequiresProblems(lib.path);
|
|
3490
3438
|
const resolved = resolveLibraryPublisherDetailed(lib, {}, getStoreIdentity());
|
|
3491
3439
|
warnLibraryNameFallback(name, resolved);
|
|
3492
|
-
const
|
|
3440
|
+
const registry = getKindRegistry();
|
|
3441
|
+
const { removed, unknownKind, skipped, failed } = await syncManifestWithDisk(
|
|
3493
3442
|
lib.path,
|
|
3494
3443
|
resolved.publisher,
|
|
3495
|
-
|
|
3444
|
+
registry,
|
|
3445
|
+
{ check: (e) => checkAssetFile(e.source, e.kind, registry) }
|
|
3496
3446
|
);
|
|
3497
3447
|
const manifest = loadSkPublishManifest(lib.path);
|
|
3498
3448
|
for (const a of unknownKind) {
|
|
@@ -3511,16 +3461,20 @@ async function reindexLibrary(lib, library, name) {
|
|
|
3511
3461
|
}
|
|
3512
3462
|
const duplicates = skipped.filter((x) => x.reason === "duplicate");
|
|
3513
3463
|
for (const s of duplicates) {
|
|
3514
|
-
logErr(
|
|
3515
|
-
|
|
3516
|
-
|
|
3464
|
+
logErr(duplicateAssetMessage(s.kind, s.name, path18.dirname(s.file), s.detail, name));
|
|
3465
|
+
}
|
|
3466
|
+
for (const s of failed) {
|
|
3467
|
+
for (const f of s.findings) logErr(`${s.file} [${f.tag}] \u2014 ${f.text}`);
|
|
3517
3468
|
}
|
|
3518
|
-
const duplicateFiles = new Set(duplicates.map((s) =>
|
|
3469
|
+
const duplicateFiles = new Set(duplicates.map((s) => path18.resolve(lib.path, s.file)));
|
|
3519
3470
|
const skippedKeys = new Set(
|
|
3520
|
-
|
|
3471
|
+
[
|
|
3472
|
+
...skipped.filter((s) => s.reason !== "duplicate"),
|
|
3473
|
+
...failed.filter((s) => !s.inManifest)
|
|
3474
|
+
].map((s) => `${s.kind}:${s.name}`)
|
|
3521
3475
|
);
|
|
3522
3476
|
const res = await indexLibrary(lib, library, {
|
|
3523
|
-
exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`) || duplicateFiles.has(
|
|
3477
|
+
exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`) || duplicateFiles.has(path18.resolve(a.manifestPath))
|
|
3524
3478
|
});
|
|
3525
3479
|
const unparsable = res.errors.filter((e) => e.includes("ManifestSchemaError:"));
|
|
3526
3480
|
for (const e of res.errors) (unparsable.includes(e) ? logErr : logWarn)(e);
|
|
@@ -3531,6 +3485,7 @@ async function reindexLibrary(lib, library, name) {
|
|
|
3531
3485
|
logErr(`${s.kind}:${s.name} skipped: manifest file ${s.file} could not be parsed.`);
|
|
3532
3486
|
}
|
|
3533
3487
|
for (const p6 of badRequires) logErr(`${p6.asset}: ${p6.message}`);
|
|
3488
|
+
for (const w of await unresolvedManifestDependencies(lib.path)) logWarn(w);
|
|
3534
3489
|
logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
|
|
3535
3490
|
warnIgnoredDomainFiles(lib.path);
|
|
3536
3491
|
warnLegacyBundleFiles(lib.path);
|
|
@@ -3545,6 +3500,12 @@ async function reindexLibrary(lib, library, name) {
|
|
|
3545
3500
|
);
|
|
3546
3501
|
process.exitCode = 1;
|
|
3547
3502
|
}
|
|
3503
|
+
if (failed.length > 0) {
|
|
3504
|
+
logErr(
|
|
3505
|
+
`${failed.length} asset(s) fail the checks of \`skaile validate\` (listed above); fix them and re-run \`skaile library index ${name}\`.`
|
|
3506
|
+
);
|
|
3507
|
+
process.exitCode = 1;
|
|
3508
|
+
}
|
|
3548
3509
|
if (duplicates.length > 0) {
|
|
3549
3510
|
logErr(
|
|
3550
3511
|
`${duplicates.length} asset(s) skipped: kind + name already registered in another directory.`
|
|
@@ -3567,26 +3528,26 @@ function assertManifestEditableOrExit(libraryPath) {
|
|
|
3567
3528
|
}
|
|
3568
3529
|
async function assertLibraryPathFree(manager, dir, exceptId) {
|
|
3569
3530
|
const clash = (await manager.listLibraries()).find(
|
|
3570
|
-
(l) => l.id !== exceptId &&
|
|
3531
|
+
(l) => l.id !== exceptId && path18.resolve(l.path) === dir
|
|
3571
3532
|
);
|
|
3572
3533
|
if (clash) throw new Error(`${dir} is already registered as library "${clash.name}".`);
|
|
3573
3534
|
}
|
|
3574
3535
|
function canonicalDir(dir) {
|
|
3575
|
-
const abs =
|
|
3536
|
+
const abs = path18.resolve(dir);
|
|
3576
3537
|
const missing = [];
|
|
3577
3538
|
let existing = abs;
|
|
3578
|
-
while (!
|
|
3579
|
-
const parent =
|
|
3539
|
+
while (!fs8.existsSync(existing)) {
|
|
3540
|
+
const parent = path18.dirname(existing);
|
|
3580
3541
|
if (parent === existing) return abs;
|
|
3581
|
-
missing.unshift(
|
|
3542
|
+
missing.unshift(path18.basename(existing));
|
|
3582
3543
|
existing = parent;
|
|
3583
3544
|
}
|
|
3584
|
-
return
|
|
3545
|
+
return path18.join(fs8.realpathSync(existing), ...missing);
|
|
3585
3546
|
}
|
|
3586
3547
|
function refuseGlobalInstallFolder(name, dir) {
|
|
3587
3548
|
const reserved = globalInstallDir();
|
|
3588
|
-
const rel =
|
|
3589
|
-
const inside = rel === "" || !rel.startsWith("..") && !
|
|
3549
|
+
const rel = path18.relative(canonicalDir(reserved).toLowerCase(), canonicalDir(dir).toLowerCase());
|
|
3550
|
+
const inside = rel === "" || !rel.startsWith("..") && !path18.isAbsolute(rel);
|
|
3590
3551
|
if (name?.toLowerCase() === GLOBAL_INSTALL_DIR_NAME || inside) {
|
|
3591
3552
|
logErr(
|
|
3592
3553
|
`"${GLOBAL_INSTALL_DIR_NAME}" is reserved: ${reserved} holds assets from \`skaile install\`, not a library you author.`
|
|
@@ -3594,6 +3555,85 @@ function refuseGlobalInstallFolder(name, dir) {
|
|
|
3594
3555
|
process.exit(1);
|
|
3595
3556
|
}
|
|
3596
3557
|
}
|
|
3558
|
+
async function refuseNestedLibraryPath(manager, dir, exceptId) {
|
|
3559
|
+
const within = (parent, child) => {
|
|
3560
|
+
const rel = path18.relative(parent, child);
|
|
3561
|
+
return rel === "" || !rel.startsWith("..") && !path18.isAbsolute(rel);
|
|
3562
|
+
};
|
|
3563
|
+
const target = canonicalDir(dir).toLowerCase();
|
|
3564
|
+
const librariesDir = resolveLibraryDir();
|
|
3565
|
+
if (within(target, canonicalDir(librariesDir).toLowerCase())) {
|
|
3566
|
+
logErr(
|
|
3567
|
+
`"libraries" is reserved: ${librariesDir} holds every library and the global installs, not a library you author.`
|
|
3568
|
+
);
|
|
3569
|
+
process.exit(1);
|
|
3570
|
+
}
|
|
3571
|
+
for (const other of await manager.listLibraries()) {
|
|
3572
|
+
if (other.id === exceptId) continue;
|
|
3573
|
+
const otherDir = canonicalDir(other.path).toLowerCase();
|
|
3574
|
+
if (within(otherDir, target)) {
|
|
3575
|
+
logErr(
|
|
3576
|
+
`${dir} is inside the library "${other.name}" (${other.path}): a library cannot live inside another library.`
|
|
3577
|
+
);
|
|
3578
|
+
process.exit(1);
|
|
3579
|
+
}
|
|
3580
|
+
if (within(target, otherDir)) {
|
|
3581
|
+
logErr(
|
|
3582
|
+
`${dir} contains the library "${other.name}" (${other.path}): a library cannot contain another library.`
|
|
3583
|
+
);
|
|
3584
|
+
process.exit(1);
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
}
|
|
3588
|
+
function assertCreateDirInsideLibrary(libRoot, destDir, given) {
|
|
3589
|
+
const exists = (p6) => {
|
|
3590
|
+
try {
|
|
3591
|
+
fs8.lstatSync(p6);
|
|
3592
|
+
return true;
|
|
3593
|
+
} catch {
|
|
3594
|
+
return false;
|
|
3595
|
+
}
|
|
3596
|
+
};
|
|
3597
|
+
let probe = destDir;
|
|
3598
|
+
while (!exists(probe)) probe = path18.dirname(probe);
|
|
3599
|
+
let realProbe;
|
|
3600
|
+
try {
|
|
3601
|
+
realProbe = fs8.realpathSync(probe);
|
|
3602
|
+
} catch {
|
|
3603
|
+
logErr(`--dir "${given}" passes through a broken symlink (${probe}).`);
|
|
3604
|
+
process.exit(1);
|
|
3605
|
+
}
|
|
3606
|
+
if (!fs8.statSync(realProbe).isDirectory()) {
|
|
3607
|
+
logErr(`--dir "${given}": ${probe} is not a directory.`);
|
|
3608
|
+
process.exit(1);
|
|
3609
|
+
}
|
|
3610
|
+
const realRoot = canonicalDir(libRoot);
|
|
3611
|
+
const realDest = path18.join(realProbe, path18.relative(probe, destDir));
|
|
3612
|
+
const rel = path18.relative(realRoot, realDest);
|
|
3613
|
+
if (rel === ".." || rel.startsWith(`..${path18.sep}`) || path18.isAbsolute(rel)) {
|
|
3614
|
+
logErr(
|
|
3615
|
+
`--dir "${given}" must stay inside the library (${realRoot}): it resolves to ${realDest}.`
|
|
3616
|
+
);
|
|
3617
|
+
process.exit(1);
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
function adoptWritesManifest(libPath) {
|
|
3621
|
+
if (!fs8.existsSync(path18.join(libPath, SKAILE_MANIFEST_FILENAME))) return true;
|
|
3622
|
+
const manifest = loadSkPublishManifest(libPath);
|
|
3623
|
+
if (!manifest || manifest.source || (manifest.assets ?? []).length > 0) return false;
|
|
3624
|
+
return manifestPublisherProblems(libPath).length === 0;
|
|
3625
|
+
}
|
|
3626
|
+
async function countUnlistedAssets(libPath) {
|
|
3627
|
+
const manifest = loadSkPublishManifest(libPath);
|
|
3628
|
+
const listed = manifest?.assets ?? [];
|
|
3629
|
+
if (!manifest || manifest.source || listed.length === 0) return 0;
|
|
3630
|
+
const keys = new Set(listed.map((a) => `${a.kind}:${a.name}`));
|
|
3631
|
+
const onDisk = await scanDirectory(libPath, "unlisted", {
|
|
3632
|
+
knownKinds: new Set(getKindRegistry().getAllKinds()),
|
|
3633
|
+
keepDuplicates: true
|
|
3634
|
+
});
|
|
3635
|
+
return new Set(onDisk.map((e) => `${e.kind}:${e.name}`).filter((k) => !keys.has(k))).size;
|
|
3636
|
+
}
|
|
3597
3637
|
function readOriginTracking(dir) {
|
|
3598
3638
|
if (!isGitRepo(dir)) return null;
|
|
3599
3639
|
const origin = spawnSync("git", ["remote", "get-url", "origin"], { cwd: dir, encoding: "utf-8" });
|
|
@@ -3613,6 +3653,15 @@ function requireGitBackend(lib, verb) {
|
|
|
3613
3653
|
process.exit(1);
|
|
3614
3654
|
}
|
|
3615
3655
|
}
|
|
3656
|
+
async function findLibraryWithMissingDir(name) {
|
|
3657
|
+
const { manager, close } = await openLibraryManager();
|
|
3658
|
+
try {
|
|
3659
|
+
const lib = await manager.getLibrary(name);
|
|
3660
|
+
return lib && libraryDirMissing(lib) ? lib : null;
|
|
3661
|
+
} finally {
|
|
3662
|
+
close();
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3616
3665
|
function requireValidLibraryName(name) {
|
|
3617
3666
|
try {
|
|
3618
3667
|
assertValidLibraryName(name);
|
|
@@ -3623,17 +3672,17 @@ function requireValidLibraryName(name) {
|
|
|
3623
3672
|
var LOCAL_OWNERSHIP_REASON = "ownership only governs sync with a git remote, and a local library is always owned by you.";
|
|
3624
3673
|
function pruneEmptyLibraryParents(libPath) {
|
|
3625
3674
|
const root = canonicalDir(resolveLibraryDir());
|
|
3626
|
-
let dir =
|
|
3675
|
+
let dir = path18.dirname(path18.resolve(libPath));
|
|
3627
3676
|
for (; ; ) {
|
|
3628
|
-
const rel =
|
|
3629
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
3630
|
-
if (!
|
|
3631
|
-
|
|
3632
|
-
dir =
|
|
3677
|
+
const rel = path18.relative(root, canonicalDir(dir));
|
|
3678
|
+
if (rel === "" || rel.startsWith("..") || path18.isAbsolute(rel)) return;
|
|
3679
|
+
if (!fs8.existsSync(dir) || fs8.readdirSync(dir).length > 0) return;
|
|
3680
|
+
fs8.rmdirSync(dir);
|
|
3681
|
+
dir = path18.dirname(dir);
|
|
3633
3682
|
}
|
|
3634
3683
|
}
|
|
3635
3684
|
async function warnIfNotGithubRemote(name, url) {
|
|
3636
|
-
const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-
|
|
3685
|
+
const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-OS3JDW4S.js');
|
|
3637
3686
|
if (!isGithubRemote(url)) logWarn(notGithubRemoteMessage(name, url));
|
|
3638
3687
|
}
|
|
3639
3688
|
function scaffoldLibraryFiles(dir, name) {
|
|
@@ -3665,9 +3714,9 @@ by the same ref.
|
|
|
3665
3714
|
];
|
|
3666
3715
|
const written = [];
|
|
3667
3716
|
for (const [file, content] of files) {
|
|
3668
|
-
const target =
|
|
3669
|
-
if (
|
|
3670
|
-
|
|
3717
|
+
const target = path18.join(dir, file);
|
|
3718
|
+
if (fs8.existsSync(target)) continue;
|
|
3719
|
+
fs8.writeFileSync(target, content, "utf8");
|
|
3671
3720
|
written.push(file);
|
|
3672
3721
|
}
|
|
3673
3722
|
return written;
|
|
@@ -3678,7 +3727,15 @@ function makeLibraryCommand() {
|
|
|
3678
3727
|
const { manager, close } = await openLibraryManager();
|
|
3679
3728
|
try {
|
|
3680
3729
|
const ls = await manager.listLibraries();
|
|
3681
|
-
if (opts.json)
|
|
3730
|
+
if (opts.json) {
|
|
3731
|
+
return console.log(
|
|
3732
|
+
JSON.stringify(
|
|
3733
|
+
ls.map((l) => libraryDirMissing(l) ? { ...l, directoryMissing: true } : l),
|
|
3734
|
+
null,
|
|
3735
|
+
2
|
|
3736
|
+
)
|
|
3737
|
+
);
|
|
3738
|
+
}
|
|
3682
3739
|
if (ls.length === 0) {
|
|
3683
3740
|
logInfo("No libraries registered. Run `skaile library init personal` to start.");
|
|
3684
3741
|
return;
|
|
@@ -3698,6 +3755,7 @@ function makeLibraryCommand() {
|
|
|
3698
3755
|
console.log(`
|
|
3699
3756
|
${S.dim(`${ls.length} library(s)`)}
|
|
3700
3757
|
`);
|
|
3758
|
+
for (const l of ls) if (libraryDirMissing(l)) logWarn(missingLibraryDirMessage(l));
|
|
3701
3759
|
} finally {
|
|
3702
3760
|
close();
|
|
3703
3761
|
}
|
|
@@ -3724,6 +3782,7 @@ function makeLibraryCommand() {
|
|
|
3724
3782
|
console.log(` ${S.label("manifestGen")} ${l.manifestGenerated}`);
|
|
3725
3783
|
console.log(` ${S.label("backendConfig")} ${JSON.stringify(l.backendConfig)}`);
|
|
3726
3784
|
console.log();
|
|
3785
|
+
if (libraryDirMissing(l)) logWarn(missingLibraryDirMessage(l));
|
|
3727
3786
|
} finally {
|
|
3728
3787
|
close();
|
|
3729
3788
|
}
|
|
@@ -3736,10 +3795,15 @@ function makeLibraryCommand() {
|
|
|
3736
3795
|
logErr("Pick one of --owner, --contributor, --reader.");
|
|
3737
3796
|
process.exit(1);
|
|
3738
3797
|
}
|
|
3739
|
-
const
|
|
3740
|
-
|
|
3798
|
+
const gone = await findLibraryWithMissingDir(name);
|
|
3799
|
+
if (gone) {
|
|
3800
|
+
if (gone.backend === "git") opts.git ??= gone.backendConfig.url;
|
|
3801
|
+
opts.path ??= gone.path;
|
|
3802
|
+
}
|
|
3803
|
+
const ownership = flagged[0] ?? gone?.ownership ?? "owner";
|
|
3804
|
+
const libPath = opts.path ? path18.resolve(opts.path) : path18.join(resolveLibraryDir(), name);
|
|
3741
3805
|
refuseGlobalInstallFolder(name, libPath);
|
|
3742
|
-
if (
|
|
3806
|
+
if (fs8.existsSync(libPath) && !fs8.statSync(libPath).isDirectory()) {
|
|
3743
3807
|
logErr(`${libPath} exists and is not a directory.`);
|
|
3744
3808
|
process.exit(1);
|
|
3745
3809
|
}
|
|
@@ -3752,11 +3816,14 @@ function makeLibraryCommand() {
|
|
|
3752
3816
|
}
|
|
3753
3817
|
const { manager, library, close } = await openLibraryManager();
|
|
3754
3818
|
try {
|
|
3755
|
-
|
|
3819
|
+
const existing = await manager.getLibrary(name);
|
|
3820
|
+
if (existing && !gone) {
|
|
3756
3821
|
logErr(`A library named "${name}" is already registered.`);
|
|
3757
3822
|
process.exit(1);
|
|
3758
3823
|
}
|
|
3824
|
+
if (existing) await manager.removeLibrary(name);
|
|
3759
3825
|
await assertLibraryPathFree(manager, libPath);
|
|
3826
|
+
await refuseNestedLibraryPath(manager, libPath);
|
|
3760
3827
|
const hasDefault = (await manager.listLibraries()).some((l) => l.isDefault);
|
|
3761
3828
|
let backend = "local";
|
|
3762
3829
|
let backendConfig;
|
|
@@ -3775,9 +3842,9 @@ function makeLibraryCommand() {
|
|
|
3775
3842
|
backend = "git";
|
|
3776
3843
|
backendConfig = { url: adopted.url, branch: adopted.branch, authHint: "ssh" };
|
|
3777
3844
|
} else {
|
|
3778
|
-
|
|
3845
|
+
fs8.mkdirSync(libPath, { recursive: true });
|
|
3779
3846
|
}
|
|
3780
|
-
const blank =
|
|
3847
|
+
const blank = fs8.readdirSync(libPath).every((entry) => entry === ".git");
|
|
3781
3848
|
const isDefault = !hasDefault && ownership !== "reader";
|
|
3782
3849
|
await manager.addLibrary({
|
|
3783
3850
|
name,
|
|
@@ -3804,6 +3871,11 @@ function makeLibraryCommand() {
|
|
|
3804
3871
|
}
|
|
3805
3872
|
if (!blank) {
|
|
3806
3873
|
const lib = await manager.requireLibrary(name);
|
|
3874
|
+
if (adoptWritesManifest(libPath)) {
|
|
3875
|
+
await reindexLibrary(lib, library, name);
|
|
3876
|
+
return;
|
|
3877
|
+
}
|
|
3878
|
+
const unlisted = await countUnlistedAssets(libPath);
|
|
3807
3879
|
const resolved = resolveLibraryPublisherDetailed(lib, {}, getStoreIdentity());
|
|
3808
3880
|
if (resolved.source === "manifest" && !isValidPublisher(resolved.publisher)) {
|
|
3809
3881
|
logWarn(
|
|
@@ -3817,6 +3889,11 @@ function makeLibraryCommand() {
|
|
|
3817
3889
|
const res = await indexLibrary(lib, library);
|
|
3818
3890
|
for (const e of res.errors) logWarn(e);
|
|
3819
3891
|
logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
|
|
3892
|
+
if (unlisted > 0) {
|
|
3893
|
+
logWarn(
|
|
3894
|
+
`${unlisted} asset(s) on disk are not in the manifest; run \`skaile library index ${name}\`.`
|
|
3895
|
+
);
|
|
3896
|
+
}
|
|
3820
3897
|
warnIgnoredDomainFiles(libPath);
|
|
3821
3898
|
}
|
|
3822
3899
|
} catch (err2) {
|
|
@@ -3829,7 +3906,7 @@ function makeLibraryCommand() {
|
|
|
3829
3906
|
cmd.command("link <name> <git-url>").description("Attach a github remote to a local library (makes it store-publishable)").option("--branch <name>", "Default branch", "main").action(async (name, url, opts) => {
|
|
3830
3907
|
const { manager, close } = await openLibraryManager();
|
|
3831
3908
|
try {
|
|
3832
|
-
const lib = await manager.
|
|
3909
|
+
const lib = await manager.requireLibraryDir(name);
|
|
3833
3910
|
if (lib.backend === "git") {
|
|
3834
3911
|
logErr(
|
|
3835
3912
|
`Library "${name}" is already git-backed. Use \`skaile library set ${name} backendConfig.url=${url}\` to change its remote.`
|
|
@@ -3866,13 +3943,7 @@ function makeLibraryCommand() {
|
|
|
3866
3943
|
logErr(`Invalid asset name "${name}": ${ASSET_NAME_HINT}.`);
|
|
3867
3944
|
process.exit(1);
|
|
3868
3945
|
}
|
|
3869
|
-
if (opts.publisher !== void 0)
|
|
3870
|
-
const bare = opts.publisher.trim().replace(/^@/, "");
|
|
3871
|
-
if (!isValidPublisher(bare)) {
|
|
3872
|
-
logErr(`Invalid publisher "${opts.publisher}": ${PUBLISHER_HINT}.`);
|
|
3873
|
-
process.exit(1);
|
|
3874
|
-
}
|
|
3875
|
-
}
|
|
3946
|
+
if (opts.publisher !== void 0) requireValidPublisherOrExit(opts.publisher);
|
|
3876
3947
|
if (opts.description !== void 0) {
|
|
3877
3948
|
const len = opts.description.trim().length;
|
|
3878
3949
|
if (len === 0 || len > 1024) {
|
|
@@ -3884,24 +3955,26 @@ function makeLibraryCommand() {
|
|
|
3884
3955
|
try {
|
|
3885
3956
|
const target = await resolveTargetLibrary(manager, opts.library);
|
|
3886
3957
|
assertManifestEditableOrExit(target.path);
|
|
3958
|
+
exitOnManifestPublisherProblems(target.path, target.name);
|
|
3887
3959
|
const effectiveKind = opts.kind ?? kind;
|
|
3888
3960
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
|
|
3889
|
-
const libRoot =
|
|
3890
|
-
const destDir = opts.dir ?
|
|
3891
|
-
const relDest =
|
|
3892
|
-
if (relDest === ".." || relDest.startsWith(`..${
|
|
3961
|
+
const libRoot = path18.resolve(target.path);
|
|
3962
|
+
const destDir = opts.dir ? path18.resolve(libRoot, opts.dir) : libRoot;
|
|
3963
|
+
const relDest = path18.relative(libRoot, destDir);
|
|
3964
|
+
if (relDest === ".." || relDest.startsWith(`..${path18.sep}`) || path18.isAbsolute(relDest)) {
|
|
3893
3965
|
logErr(`--dir "${opts.dir}" must stay inside the library (${libRoot}).`);
|
|
3894
3966
|
process.exit(1);
|
|
3895
3967
|
}
|
|
3968
|
+
if (opts.dir) assertCreateDirInsideLibrary(libRoot, destDir, opts.dir);
|
|
3896
3969
|
const taken = conflictingAssetRoot(
|
|
3897
3970
|
libRoot,
|
|
3898
3971
|
effectiveKind,
|
|
3899
3972
|
name,
|
|
3900
|
-
|
|
3973
|
+
path18.relative(libRoot, path18.join(destDir, name))
|
|
3901
3974
|
);
|
|
3902
3975
|
if (taken) {
|
|
3903
3976
|
logErr(
|
|
3904
|
-
`${effectiveKind}:${name} already exists at "${taken}" \u2014 creating it again under "${
|
|
3977
|
+
`${effectiveKind}:${name} already exists at "${taken}" \u2014 creating it again under "${path18.relative(libRoot, destDir) || "."}" would re-point the manifest entry. Pick another name.`
|
|
3905
3978
|
);
|
|
3906
3979
|
process.exit(1);
|
|
3907
3980
|
}
|
|
@@ -3911,9 +3984,9 @@ function makeLibraryCommand() {
|
|
|
3911
3984
|
process.exit(1);
|
|
3912
3985
|
}
|
|
3913
3986
|
logOk(`Created ${effectiveKind}: ${pc5.dim(res.path)}`);
|
|
3914
|
-
if (opts.description === void 0 &&
|
|
3987
|
+
if (opts.description === void 0 && ["skill", "agent", "prompt", "contract"].includes(effectiveKind)) {
|
|
3915
3988
|
logWarn(
|
|
3916
|
-
|
|
3989
|
+
`Description is a TODO placeholder \u2014 edit it (what the ${effectiveKind} does and when to use it) or \`skaile validate\` will fail.`
|
|
3917
3990
|
);
|
|
3918
3991
|
}
|
|
3919
3992
|
const { ref } = await registerLibraryAsset(target, library, {
|
|
@@ -3930,9 +4003,9 @@ function makeLibraryCommand() {
|
|
|
3930
4003
|
}
|
|
3931
4004
|
);
|
|
3932
4005
|
async function resolveTargetLibrary(manager, libraryName) {
|
|
3933
|
-
if (libraryName) return manager.
|
|
4006
|
+
if (libraryName) return manager.requireLibraryDir(libraryName);
|
|
3934
4007
|
const def = await manager.findDefaultLibrary();
|
|
3935
|
-
if (def) return def;
|
|
4008
|
+
if (def) return manager.requireLibraryDir(def.name);
|
|
3936
4009
|
if ((await manager.listLibraries()).length === 0) {
|
|
3937
4010
|
logErr("No libraries registered. Run `skaile library init <name>` first.");
|
|
3938
4011
|
process.exit(1);
|
|
@@ -3955,13 +4028,13 @@ function makeLibraryCommand() {
|
|
|
3955
4028
|
logErr(`A library named "${newName}" is already registered.`);
|
|
3956
4029
|
process.exit(1);
|
|
3957
4030
|
}
|
|
3958
|
-
const newPath =
|
|
4031
|
+
const newPath = path18.join(path18.dirname(lib.path), newName);
|
|
3959
4032
|
refuseGlobalInstallFolder(newName, newPath);
|
|
3960
|
-
if (
|
|
4033
|
+
if (fs8.existsSync(newPath)) {
|
|
3961
4034
|
logErr(`Target directory already exists: ${newPath}`);
|
|
3962
4035
|
process.exit(1);
|
|
3963
4036
|
}
|
|
3964
|
-
|
|
4037
|
+
fs8.renameSync(lib.path, newPath);
|
|
3965
4038
|
await manager.updateLibrary(lib.id, { name: newName, path: newPath });
|
|
3966
4039
|
logOk(`Renamed ${lib.name} \u2192 ${newName}`);
|
|
3967
4040
|
}
|
|
@@ -3988,17 +4061,17 @@ function makeLibraryCommand() {
|
|
|
3988
4061
|
try {
|
|
3989
4062
|
const lib = await manager.requireLibrary(name);
|
|
3990
4063
|
if (field === "publisher") {
|
|
3991
|
-
const publisher = value
|
|
3992
|
-
if (!isValidPublisher(publisher)) {
|
|
3993
|
-
logErr(`Invalid publisher "${value}": ${PUBLISHER_HINT}.`);
|
|
3994
|
-
process.exit(1);
|
|
3995
|
-
}
|
|
4064
|
+
const publisher = requireValidPublisherOrExit(value);
|
|
3996
4065
|
if (lib.ownership === "reader") {
|
|
3997
4066
|
logErr(
|
|
3998
4067
|
`Library "${lib.name}" is read-only (ownership=reader); its publisher is not yours to set.`
|
|
3999
4068
|
);
|
|
4000
4069
|
process.exit(1);
|
|
4001
4070
|
}
|
|
4071
|
+
if (libraryDirMissing(lib)) {
|
|
4072
|
+
logErr(missingLibraryDirMessage(lib));
|
|
4073
|
+
process.exit(1);
|
|
4074
|
+
}
|
|
4002
4075
|
assertManifestEditableOrExit(lib.path);
|
|
4003
4076
|
setManifestPublisher(lib.path, publisher);
|
|
4004
4077
|
const res = await indexLibrary(lib, library);
|
|
@@ -4041,13 +4114,14 @@ function makeLibraryCommand() {
|
|
|
4041
4114
|
}
|
|
4042
4115
|
patch.isDefault = false;
|
|
4043
4116
|
} else if (field === "path") {
|
|
4044
|
-
const dir =
|
|
4045
|
-
if (!
|
|
4117
|
+
const dir = path18.resolve(value);
|
|
4118
|
+
if (!fs8.existsSync(dir) || !fs8.statSync(dir).isDirectory()) {
|
|
4046
4119
|
logErr(`Directory does not exist: ${dir}. \`library set path=\` does not move files.`);
|
|
4047
4120
|
process.exit(1);
|
|
4048
4121
|
}
|
|
4049
4122
|
refuseGlobalInstallFolder(null, dir);
|
|
4050
4123
|
await assertLibraryPathFree(manager, dir, lib.id);
|
|
4124
|
+
await refuseNestedLibraryPath(manager, dir, lib.id);
|
|
4051
4125
|
patch.path = dir;
|
|
4052
4126
|
} else if (field.startsWith("backendConfig.")) {
|
|
4053
4127
|
const key = field.split(".")[1];
|
|
@@ -4105,7 +4179,7 @@ function makeLibraryCommand() {
|
|
|
4105
4179
|
cmd.command("sync <name>").description("Pull then push (as backend permits)").action(async (name) => {
|
|
4106
4180
|
const { manager, library, close } = await openLibraryManager();
|
|
4107
4181
|
try {
|
|
4108
|
-
const lib = await manager.
|
|
4182
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4109
4183
|
requireGitBackend(lib, "sync");
|
|
4110
4184
|
const drv = manager.driverFor(lib.backend);
|
|
4111
4185
|
const pull = await drv.pull(lib);
|
|
@@ -4127,8 +4201,10 @@ function makeLibraryCommand() {
|
|
|
4127
4201
|
cmd.command("index <name>").description("(Re)index a library's assets into the local index").action(async (name) => {
|
|
4128
4202
|
const { manager, library, close } = await openLibraryManager();
|
|
4129
4203
|
try {
|
|
4130
|
-
const lib = await manager.
|
|
4204
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4131
4205
|
await reindexLibrary(lib, library, name);
|
|
4206
|
+
} catch (err2) {
|
|
4207
|
+
exitOnSyncError(err2);
|
|
4132
4208
|
} finally {
|
|
4133
4209
|
close();
|
|
4134
4210
|
}
|
|
@@ -4136,7 +4212,7 @@ function makeLibraryCommand() {
|
|
|
4136
4212
|
cmd.command("pull <name>").description("Pull from remote").action(async (name) => {
|
|
4137
4213
|
const { manager, library, close } = await openLibraryManager();
|
|
4138
4214
|
try {
|
|
4139
|
-
const lib = await manager.
|
|
4215
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4140
4216
|
requireGitBackend(lib, "pull");
|
|
4141
4217
|
const res = await manager.driverFor(lib.backend).pull(lib);
|
|
4142
4218
|
if (res.conflicts.length > 0) {
|
|
@@ -4154,7 +4230,7 @@ function makeLibraryCommand() {
|
|
|
4154
4230
|
cmd.command("push <name>").description("Push local commits (owner only)").option("--force", "Force-with-lease push", false).action(async (name, opts) => {
|
|
4155
4231
|
const { manager, close } = await openLibraryManager();
|
|
4156
4232
|
try {
|
|
4157
|
-
const lib = await manager.
|
|
4233
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4158
4234
|
requireGitBackend(lib, "push");
|
|
4159
4235
|
const res = await manager.driverFor(lib.backend).push(lib, { force: opts.force });
|
|
4160
4236
|
logOk(`Pushed (${res.pushed}).`);
|
|
@@ -4167,7 +4243,7 @@ function makeLibraryCommand() {
|
|
|
4167
4243
|
cmd.command("propose <name>").description("Open a pull request on the upstream repo (contributor only)").option("--title <title>", "PR title").option("--body <body>", "PR body").option("--branch <name>", "Branch name (default: skaile/<timestamp>)").action(async (name, opts) => {
|
|
4168
4244
|
const { manager, close } = await openLibraryManager();
|
|
4169
4245
|
try {
|
|
4170
|
-
const lib = await manager.
|
|
4246
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4171
4247
|
const res = await manager.driverFor(lib.backend).propose(lib, opts);
|
|
4172
4248
|
logOk(`PR opened: ${res.prUrl}`);
|
|
4173
4249
|
} catch (err2) {
|
|
@@ -4179,7 +4255,7 @@ function makeLibraryCommand() {
|
|
|
4179
4255
|
cmd.command("commit <name>").description("Git-commit local changes inside the library (git only)").option("-m, --message <msg>", "Commit message", "skaile: update assets").action(async (name, opts) => {
|
|
4180
4256
|
const { manager, close } = await openLibraryManager();
|
|
4181
4257
|
try {
|
|
4182
|
-
const lib = await manager.
|
|
4258
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4183
4259
|
requireGitBackend(lib, "commit");
|
|
4184
4260
|
if (!isGitRepo(lib.path)) {
|
|
4185
4261
|
logErr(
|
|
@@ -4232,13 +4308,15 @@ function makeLibraryCommand() {
|
|
|
4232
4308
|
const args = rawArgs[0] === "--" ? rawArgs.slice(1) : rawArgs;
|
|
4233
4309
|
const { manager, close } = await openLibraryManager();
|
|
4234
4310
|
try {
|
|
4235
|
-
const lib = await manager.
|
|
4311
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4236
4312
|
const r = spawnSync("git", args, { cwd: lib.path, stdio: "inherit" });
|
|
4237
4313
|
if (r.error) {
|
|
4238
4314
|
logErr(`Could not run git: ${r.error.message}`);
|
|
4239
4315
|
process.exit(1);
|
|
4240
4316
|
}
|
|
4241
4317
|
process.exit(r.status ?? 1);
|
|
4318
|
+
} catch (err2) {
|
|
4319
|
+
exitOnSyncError(err2);
|
|
4242
4320
|
} finally {
|
|
4243
4321
|
close();
|
|
4244
4322
|
}
|
|
@@ -4248,16 +4326,16 @@ function makeLibraryCommand() {
|
|
|
4248
4326
|
"With --create-repo: create the repo private (the store only accepts public repos)"
|
|
4249
4327
|
).option("--ref <gitref>", "Git ref to ingest (default: the library branch or main)").option("--dry-run", "Print the plan; push nothing and call no store endpoint").action(
|
|
4250
4328
|
async (lib, opts) => {
|
|
4251
|
-
const { runLibraryPublish } = await import('../library-publish-
|
|
4329
|
+
const { runLibraryPublish } = await import('../library-publish-OS3JDW4S.js');
|
|
4252
4330
|
await withStoreErrorHandling(() => runLibraryPublish(lib, opts));
|
|
4253
4331
|
}
|
|
4254
4332
|
);
|
|
4255
4333
|
cmd.command("register <lib>").description("Register the library's manifest without pushing (bytes already on github)").option("--asset <ref>", "Publish only the single asset matching this ref/name").option("--ref <gitref>", "Git ref to ingest (default: the library branch or main)").option("--dry-run", "Print the plan; call no store endpoint").action(async (lib, opts) => {
|
|
4256
|
-
const { runLibraryRegister } = await import('../library-publish-
|
|
4334
|
+
const { runLibraryRegister } = await import('../library-publish-OS3JDW4S.js');
|
|
4257
4335
|
await withStoreErrorHandling(() => runLibraryRegister(lib, opts));
|
|
4258
4336
|
});
|
|
4259
4337
|
cmd.command("yank <lib>").description("Retract the library's published assets from the store").option("--asset <ref>", "Yank only the single asset matching this ref/name").action(async (lib, opts) => {
|
|
4260
|
-
const { runLibraryYank } = await import('../library-publish-
|
|
4338
|
+
const { runLibraryYank } = await import('../library-publish-OS3JDW4S.js');
|
|
4261
4339
|
await withStoreErrorHandling(() => runLibraryYank(lib, opts));
|
|
4262
4340
|
});
|
|
4263
4341
|
return cmd;
|
|
@@ -4273,7 +4351,7 @@ async function withStoreErrorHandling(fn) {
|
|
|
4273
4351
|
async function printPerLibraryStatus(name, asJson) {
|
|
4274
4352
|
const { manager, close } = await openLibraryManager();
|
|
4275
4353
|
try {
|
|
4276
|
-
const lib = await manager.
|
|
4354
|
+
const lib = await manager.requireLibraryDir(name);
|
|
4277
4355
|
const status4 = await manager.driverFor(lib.backend).status(lib);
|
|
4278
4356
|
if (asJson) return console.log(JSON.stringify({ library: lib.name, status: status4 }, null, 2));
|
|
4279
4357
|
console.log(`
|
|
@@ -4308,9 +4386,9 @@ async function printOverallStatus(projectDir, asJson) {
|
|
|
4308
4386
|
} catch {
|
|
4309
4387
|
secretsStrategy = "unavailable";
|
|
4310
4388
|
}
|
|
4311
|
-
const resolvedProjectDir =
|
|
4312
|
-
const hasWorkspaceConfig = existsSync(
|
|
4313
|
-
const hasLockFile = existsSync(
|
|
4389
|
+
const resolvedProjectDir = path18.resolve(projectDir);
|
|
4390
|
+
const hasWorkspaceConfig = existsSync(path18.join(resolvedProjectDir, "skaile.yaml"));
|
|
4391
|
+
const hasLockFile = existsSync(path18.join(resolvedProjectDir, "skaile.lock.yaml"));
|
|
4314
4392
|
let assignments = [];
|
|
4315
4393
|
if (hasWorkspaceConfig) {
|
|
4316
4394
|
try {
|
|
@@ -4917,7 +4995,7 @@ function scheduleSoftDepPreview() {
|
|
|
4917
4995
|
}
|
|
4918
4996
|
async function loadAssets() {
|
|
4919
4997
|
softDepPreviewCache.clear();
|
|
4920
|
-
const { gatherAssetFeeds } = await import('../asset-feeds-
|
|
4998
|
+
const { gatherAssetFeeds } = await import('../asset-feeds-ELEBTNUS.js');
|
|
4921
4999
|
const { entries, notes } = await gatherAssetFeeds(am, am.projectDir);
|
|
4922
5000
|
if (notes.length > 0) {
|
|
4923
5001
|
state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
|
|
@@ -4925,10 +5003,15 @@ async function loadAssets() {
|
|
|
4925
5003
|
const installed = new Set(am.listDeployed().map((e) => `${e.kind}:${e.name}`));
|
|
4926
5004
|
let lock = null;
|
|
4927
5005
|
try {
|
|
4928
|
-
lock = readLock(
|
|
5006
|
+
lock = readLock(path18__default.join(am.projectDir, "skaile.lock.yaml"));
|
|
4929
5007
|
} catch {
|
|
4930
5008
|
}
|
|
4931
|
-
const rows = buildAssetRows(
|
|
5009
|
+
const rows = buildAssetRows(
|
|
5010
|
+
entries,
|
|
5011
|
+
installed,
|
|
5012
|
+
await am.lockedLibraryNames(),
|
|
5013
|
+
lockedPublishersByName(lock)
|
|
5014
|
+
);
|
|
4932
5015
|
state.assetRows = rows;
|
|
4933
5016
|
reconcileCollapsedSets(rows);
|
|
4934
5017
|
rebuildVisible();
|
|
@@ -4942,7 +5025,7 @@ function rebuildSourceTree() {
|
|
|
4942
5025
|
rebuildVisibleSources();
|
|
4943
5026
|
}
|
|
4944
5027
|
function sourceOrgRepo(s) {
|
|
4945
|
-
const parts = s.path.split(
|
|
5028
|
+
const parts = s.path.split(path18__default.sep).filter(Boolean);
|
|
4946
5029
|
if (parts.length < 2) return null;
|
|
4947
5030
|
return { org: parts[parts.length - 2], repo: parts[parts.length - 1] };
|
|
4948
5031
|
}
|
|
@@ -5015,22 +5098,27 @@ function rebuildVisibleLibraries() {
|
|
|
5015
5098
|
);
|
|
5016
5099
|
clampCursor();
|
|
5017
5100
|
}
|
|
5018
|
-
function
|
|
5101
|
+
function lockedPublishersByName(lock) {
|
|
5019
5102
|
const out = /* @__PURE__ */ new Map();
|
|
5020
|
-
for (const
|
|
5021
|
-
if (!locked.library) continue;
|
|
5103
|
+
for (const key of Object.keys(lock?.assets ?? {})) {
|
|
5022
5104
|
const ref = parseAssetRefLoose(key);
|
|
5023
|
-
if (ref?.publisher)
|
|
5105
|
+
if (!ref?.publisher) continue;
|
|
5106
|
+
const id = `${ref.kind}:${ref.name}`;
|
|
5107
|
+
const publishers = out.get(id) ?? /* @__PURE__ */ new Set();
|
|
5108
|
+
publishers.add(ref.publisher);
|
|
5109
|
+
out.set(id, publishers);
|
|
5024
5110
|
}
|
|
5025
5111
|
return out;
|
|
5026
5112
|
}
|
|
5027
|
-
function isRowInstalled(origin, group, entry, installed, lockedLibrary) {
|
|
5113
|
+
function isRowInstalled(origin, group, entry, installed, lockedLibrary, lockedPublishers) {
|
|
5028
5114
|
if (!installed.has(`${entry.kind}:${entry.name}`)) return false;
|
|
5029
5115
|
const publisher = entry.publisher?.replace(/^@/, "");
|
|
5116
|
+
const lockedFor = lockedPublishers.get(`${entry.kind}:${entry.name}`);
|
|
5117
|
+
if (publisher && lockedFor && !lockedFor.has(publisher)) return false;
|
|
5030
5118
|
const locked = publisher ? lockedLibrary.get(`${entry.kind}:${publisher}/${entry.name}`) : void 0;
|
|
5031
|
-
return locked === void 0 || origin === "library" && group === locked;
|
|
5119
|
+
return locked === void 0 || origin === "library" && locked !== null && group === locked;
|
|
5032
5120
|
}
|
|
5033
|
-
function buildAssetRows(entries, installed, lockedLibrary = /* @__PURE__ */ new Map()) {
|
|
5121
|
+
function buildAssetRows(entries, installed, lockedLibrary = /* @__PURE__ */ new Map(), lockedPublishers = /* @__PURE__ */ new Map()) {
|
|
5034
5122
|
const byOrigin = /* @__PURE__ */ new Map();
|
|
5035
5123
|
for (const { origin, entry, group } of entries) {
|
|
5036
5124
|
const publisher = group || entry.publisher || "other";
|
|
@@ -5058,7 +5146,14 @@ function buildAssetRows(entries, installed, lockedLibrary = /* @__PURE__ */ new
|
|
|
5058
5146
|
source: group,
|
|
5059
5147
|
org: entry.repo?.includes("/") ? entry.repo.slice(0, entry.repo.indexOf("/")) : void 0,
|
|
5060
5148
|
entry,
|
|
5061
|
-
installed: isRowInstalled(
|
|
5149
|
+
installed: isRowInstalled(
|
|
5150
|
+
origin,
|
|
5151
|
+
group,
|
|
5152
|
+
entry,
|
|
5153
|
+
installed,
|
|
5154
|
+
lockedLibrary,
|
|
5155
|
+
lockedPublishers
|
|
5156
|
+
),
|
|
5062
5157
|
plugin
|
|
5063
5158
|
});
|
|
5064
5159
|
}
|
|
@@ -5104,13 +5199,13 @@ function reconcileCollapsedSets(rows) {
|
|
|
5104
5199
|
async function loadSourcesAndLibraries() {
|
|
5105
5200
|
try {
|
|
5106
5201
|
const [{ openLibraryManager: openLibraryManager2 }, { getGlobalCacheDir: getGlobalCacheDir2, globalSkaileDir: globalSkaileDir2 }] = await Promise.all([
|
|
5107
|
-
import('../open-library-
|
|
5202
|
+
import('../open-library-4QSUORI6.js'),
|
|
5108
5203
|
import('../core/index.js')
|
|
5109
5204
|
]);
|
|
5110
5205
|
const { manager, library, close } = await openLibraryManager2();
|
|
5111
5206
|
try {
|
|
5112
5207
|
const newRoot = getGlobalCacheDir2();
|
|
5113
|
-
const legacyRoot =
|
|
5208
|
+
const legacyRoot = path18__default.join(globalSkaileDir2(), "sources");
|
|
5114
5209
|
const isSourceRow = (l) => l.path.startsWith(newRoot) || l.path.startsWith(legacyRoot);
|
|
5115
5210
|
const libs = await manager.listLibraries();
|
|
5116
5211
|
const defs = await library.listAssetDefs();
|
|
@@ -5480,10 +5575,15 @@ async function applyChanges() {
|
|
|
5480
5575
|
let pruned = 0;
|
|
5481
5576
|
const appliedAdds = [];
|
|
5482
5577
|
const appliedRemoves = [];
|
|
5578
|
+
const blockedRemovals = [];
|
|
5483
5579
|
for (const ref of state.pendingRemoves) {
|
|
5484
5580
|
try {
|
|
5485
5581
|
const result = await am.removeWithDependencies(ref);
|
|
5486
|
-
if (result.
|
|
5582
|
+
if (result.blocked) {
|
|
5583
|
+
blockedRemovals.push(
|
|
5584
|
+
`kept ${result.blocked.ref}: required by ${result.blocked.requiredBy.join(", ")} (skaile remove --force overrides)`
|
|
5585
|
+
);
|
|
5586
|
+
} else if (result.changed) {
|
|
5487
5587
|
removed++;
|
|
5488
5588
|
pruned += result.pruned.length;
|
|
5489
5589
|
appliedRemoves.push(ref);
|
|
@@ -5510,6 +5610,7 @@ async function applyChanges() {
|
|
|
5510
5610
|
if (added > 0) parts.push(pc5.green(`+${added} added`));
|
|
5511
5611
|
if (removed > 0) parts.push(pc5.red(`-${removed} removed`));
|
|
5512
5612
|
if (pruned > 0) parts.push(pc5.red(`-${pruned} no longer required`));
|
|
5613
|
+
for (const b of blockedRemovals) parts.push(pc5.yellow(b));
|
|
5513
5614
|
const softDeps = appliedAdds.length > 0 ? await am.reportSoftDeps(appliedAdds) : [];
|
|
5514
5615
|
if (softDeps.length > 0) {
|
|
5515
5616
|
parts.push(pc5.dim(`${softDeps.length} soft dep${softDeps.length === 1 ? "" : "s"} referenced`));
|
|
@@ -6059,13 +6160,13 @@ async function run(projectDir) {
|
|
|
6059
6160
|
}
|
|
6060
6161
|
function makeManageCommand() {
|
|
6061
6162
|
return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
6062
|
-
await run(
|
|
6163
|
+
await run(path18__default.resolve(opts.projectDir));
|
|
6063
6164
|
});
|
|
6064
6165
|
}
|
|
6065
6166
|
function makeMcpServerCommand() {
|
|
6066
6167
|
return new Command("mcp-server").description("Start skaile workspace MCP server (stdio transport)").option("--project-dir <path>", "Project directory (default: cwd)", process.cwd()).action(async (opts) => {
|
|
6067
|
-
const
|
|
6068
|
-
const projectDir =
|
|
6168
|
+
const path43 = await import('path');
|
|
6169
|
+
const projectDir = path43.default.resolve(opts.projectDir);
|
|
6069
6170
|
const { LogStore, StdoutSink, registerLogStore } = await import('../core/logging.js');
|
|
6070
6171
|
registerLogStore(
|
|
6071
6172
|
new LogStore({
|
|
@@ -6112,10 +6213,10 @@ function walkFiles(root, match) {
|
|
|
6112
6213
|
return;
|
|
6113
6214
|
}
|
|
6114
6215
|
for (const entry of entries) {
|
|
6115
|
-
const full =
|
|
6216
|
+
const full = path18__default.join(dir, entry.name);
|
|
6116
6217
|
if (entry.isDirectory()) {
|
|
6117
6218
|
if (SKIPPED_DIRS.has(entry.name)) continue;
|
|
6118
|
-
if (entry.name === "cache" &&
|
|
6219
|
+
if (entry.name === "cache" && path18__default.basename(dir) === ".skaile") continue;
|
|
6119
6220
|
visit(full);
|
|
6120
6221
|
} else if (entry.isFile() && match(entry.name)) {
|
|
6121
6222
|
out.push(full);
|
|
@@ -6133,14 +6234,14 @@ function applyChanges2(changes) {
|
|
|
6133
6234
|
switch (change.type) {
|
|
6134
6235
|
case "write":
|
|
6135
6236
|
case "create":
|
|
6136
|
-
mkdirSync(
|
|
6237
|
+
mkdirSync(path18__default.dirname(change.path), { recursive: true });
|
|
6137
6238
|
writeFileSync(change.path, change.after, "utf-8");
|
|
6138
6239
|
break;
|
|
6139
6240
|
case "delete":
|
|
6140
6241
|
rmSync(change.path, { force: true });
|
|
6141
6242
|
break;
|
|
6142
6243
|
case "move":
|
|
6143
|
-
mkdirSync(
|
|
6244
|
+
mkdirSync(path18__default.dirname(change.to), { recursive: true });
|
|
6144
6245
|
writeFileSync(change.to, change.after, "utf-8");
|
|
6145
6246
|
rmSync(change.from, { force: true });
|
|
6146
6247
|
break;
|
|
@@ -6233,7 +6334,7 @@ function unifiedDiff(before, after, oldLabel, newLabel, context = 3) {
|
|
|
6233
6334
|
return `${out.join("\n")}
|
|
6234
6335
|
`;
|
|
6235
6336
|
}
|
|
6236
|
-
var posix = (p6) => p6.split(
|
|
6337
|
+
var posix = (p6) => p6.split(path18__default.sep).join("/");
|
|
6237
6338
|
function colorizeDiff(diff) {
|
|
6238
6339
|
return diff.split("\n").map((line) => {
|
|
6239
6340
|
if (line.startsWith("+++") || line.startsWith("---")) return S.bold(line);
|
|
@@ -6244,7 +6345,7 @@ function colorizeDiff(diff) {
|
|
|
6244
6345
|
}).join("\n");
|
|
6245
6346
|
}
|
|
6246
6347
|
function renderChange(change, base) {
|
|
6247
|
-
const rel = (p6) => posix(
|
|
6348
|
+
const rel = (p6) => posix(path18__default.relative(base, p6) || path18__default.basename(p6));
|
|
6248
6349
|
switch (change.type) {
|
|
6249
6350
|
case "write":
|
|
6250
6351
|
return unifiedDiff(
|
|
@@ -6271,7 +6372,7 @@ ${diff}`;
|
|
|
6271
6372
|
}
|
|
6272
6373
|
}
|
|
6273
6374
|
function changeLabel(change, base) {
|
|
6274
|
-
const rel = (p6) => posix(
|
|
6375
|
+
const rel = (p6) => posix(path18__default.relative(base, p6) || path18__default.basename(p6));
|
|
6275
6376
|
switch (change.type) {
|
|
6276
6377
|
case "write":
|
|
6277
6378
|
return `modify ${rel(change.path)}`;
|
|
@@ -6331,10 +6432,10 @@ function loadAsset(projectDir, id, ref) {
|
|
|
6331
6432
|
)
|
|
6332
6433
|
};
|
|
6333
6434
|
}
|
|
6334
|
-
const manifestPath =
|
|
6435
|
+
const manifestPath = path18__default.join(dir, AGENT_MANIFEST_FILE);
|
|
6335
6436
|
let text;
|
|
6336
6437
|
try {
|
|
6337
|
-
text =
|
|
6438
|
+
text = fs8__default.readFileSync(manifestPath, "utf-8");
|
|
6338
6439
|
} catch {
|
|
6339
6440
|
return {
|
|
6340
6441
|
diagnostic: err(
|
|
@@ -6513,12 +6614,12 @@ function findManifestCandidates(rootPath) {
|
|
|
6513
6614
|
function walk(dir) {
|
|
6514
6615
|
let entries;
|
|
6515
6616
|
try {
|
|
6516
|
-
entries =
|
|
6617
|
+
entries = fs8__default.readdirSync(dir, { withFileTypes: true });
|
|
6517
6618
|
} catch {
|
|
6518
6619
|
return;
|
|
6519
6620
|
}
|
|
6520
6621
|
for (const entry of entries) {
|
|
6521
|
-
const fullPath =
|
|
6622
|
+
const fullPath = path18__default.join(dir, entry.name);
|
|
6522
6623
|
if (entry.isDirectory()) {
|
|
6523
6624
|
if (!SKIP_DIRS.has(entry.name)) walk(fullPath);
|
|
6524
6625
|
} else if (entry.isFile()) {
|
|
@@ -6554,10 +6655,10 @@ function checkManifestIdentity(kind, parsed) {
|
|
|
6554
6655
|
return null;
|
|
6555
6656
|
}
|
|
6556
6657
|
function parseManifestCandidate(c, absRoot) {
|
|
6557
|
-
const content =
|
|
6658
|
+
const content = fs8__default.readFileSync(c.filePath, "utf-8");
|
|
6558
6659
|
const res = parseManifestFile(c.filePath, content);
|
|
6559
6660
|
if (!res.ok) {
|
|
6560
|
-
logErr(`${
|
|
6661
|
+
logErr(`${path18__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 parse error: ${res.reason}`);
|
|
6561
6662
|
return { kind: "error" };
|
|
6562
6663
|
}
|
|
6563
6664
|
return {
|
|
@@ -6587,7 +6688,7 @@ function checkComposeKinds(parsed, registry) {
|
|
|
6587
6688
|
return diagnostics;
|
|
6588
6689
|
}
|
|
6589
6690
|
function validateManifestCandidate(c, parsed, body, absRoot, registry, strictConformance) {
|
|
6590
|
-
const relPath =
|
|
6691
|
+
const relPath = path18__default.relative(absRoot, c.filePath);
|
|
6591
6692
|
let errors = 0;
|
|
6592
6693
|
let warnings = 0;
|
|
6593
6694
|
const identityError = checkManifestIdentity(c.kind, parsed);
|
|
@@ -6595,26 +6696,29 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
|
|
|
6595
6696
|
logErr(`${relPath} [${c.kind}] \u2014 ${identityError}`);
|
|
6596
6697
|
errors++;
|
|
6597
6698
|
}
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6699
|
+
const dirName = path18__default.basename(path18__default.dirname(c.filePath));
|
|
6700
|
+
const checked = checkAsset(
|
|
6701
|
+
c.kind,
|
|
6702
|
+
parsed ?? {},
|
|
6703
|
+
body,
|
|
6704
|
+
dirName,
|
|
6705
|
+
registry
|
|
6706
|
+
);
|
|
6707
|
+
for (const f of checked.errors) {
|
|
6708
|
+
logErr(`${relPath} [${f.tag}] \u2014 ${f.text}`);
|
|
6709
|
+
errors++;
|
|
6710
|
+
}
|
|
6711
|
+
for (const f of checked.advisories) {
|
|
6712
|
+
const line = `${relPath} [${f.tag}] \u2014 ${f.text}`;
|
|
6713
|
+
if (f.conformance && strictConformance) {
|
|
6714
|
+
logErr(line);
|
|
6603
6715
|
errors++;
|
|
6604
|
-
}
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
const line = `${relPath} [${f.tag}] \u2014 ${f.text}`;
|
|
6608
|
-
if (f.conformance && strictConformance) {
|
|
6609
|
-
logErr(line);
|
|
6610
|
-
errors++;
|
|
6611
|
-
} else {
|
|
6612
|
-
logWarn(line);
|
|
6613
|
-
warnings++;
|
|
6614
|
-
}
|
|
6716
|
+
} else {
|
|
6717
|
+
logWarn(line);
|
|
6718
|
+
warnings++;
|
|
6615
6719
|
}
|
|
6616
6720
|
}
|
|
6617
|
-
if (c.kind === "agent" &&
|
|
6721
|
+
if (c.kind === "agent" && path18__default.basename(c.filePath) === "agent.yaml") {
|
|
6618
6722
|
for (const d of [
|
|
6619
6723
|
...checkComposeKinds(parsed, registry),
|
|
6620
6724
|
...composeSlotDiagnostics(parsed),
|
|
@@ -6630,23 +6734,11 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
|
|
|
6630
6734
|
}
|
|
6631
6735
|
}
|
|
6632
6736
|
}
|
|
6633
|
-
const provider = registry.getProvider(c.kind);
|
|
6634
|
-
if (!provider) {
|
|
6635
|
-
logErr(`${relPath} [${c.kind}] \u2014 unknown_asset_kind: kind "${c.kind}" is not registered`);
|
|
6636
|
-
return { errors: errors + 1, warnings };
|
|
6637
|
-
}
|
|
6638
|
-
const result = provider.validateManifest(parsed);
|
|
6639
|
-
if (!result.ok) {
|
|
6640
|
-
for (const err2 of result.errors) {
|
|
6641
|
-
logErr(`${relPath} [${c.kind}] \u2014 ${err2.path ? `${err2.path}: ` : ""}${err2.message}`);
|
|
6642
|
-
}
|
|
6643
|
-
errors += result.errors.length;
|
|
6644
|
-
}
|
|
6645
6737
|
return { errors, warnings };
|
|
6646
6738
|
}
|
|
6647
6739
|
function validateManifests(rootPath, strictConformance) {
|
|
6648
|
-
const absRoot =
|
|
6649
|
-
if (!
|
|
6740
|
+
const absRoot = path18__default.resolve(rootPath);
|
|
6741
|
+
if (!fs8__default.existsSync(absRoot)) {
|
|
6650
6742
|
logErr(`Path does not exist: ${absRoot}`);
|
|
6651
6743
|
return { total: 0, errors: 1, warnings: 0 };
|
|
6652
6744
|
}
|
|
@@ -6674,14 +6766,14 @@ function validateManifests(rootPath, strictConformance) {
|
|
|
6674
6766
|
const obj = parseResult.parsed;
|
|
6675
6767
|
const identity = obj && typeof obj === "object" ? obj[c.kind === "flow" ? "id" : "name"] : null;
|
|
6676
6768
|
if (typeof identity === "string" && identity.length > 0) {
|
|
6677
|
-
const dir =
|
|
6769
|
+
const dir = path18__default.dirname(c.filePath);
|
|
6678
6770
|
const key = `${c.kind}:${identity}`;
|
|
6679
6771
|
const first = seenIdentity.get(key);
|
|
6680
6772
|
if (first === void 0) {
|
|
6681
6773
|
seenIdentity.set(key, dir);
|
|
6682
6774
|
} else if (first !== dir) {
|
|
6683
6775
|
logErr(
|
|
6684
|
-
`${
|
|
6776
|
+
`${path18__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 ${key} is also defined in ${path18__default.relative(absRoot, first) || "."}; two directories cannot share a kind and name (\`skaile library index\` keeps only the first).`
|
|
6685
6777
|
);
|
|
6686
6778
|
errors++;
|
|
6687
6779
|
}
|
|
@@ -6694,12 +6786,12 @@ function findWorkspaceManifests(rootPath) {
|
|
|
6694
6786
|
function walk(dir) {
|
|
6695
6787
|
let entries;
|
|
6696
6788
|
try {
|
|
6697
|
-
entries =
|
|
6789
|
+
entries = fs8__default.readdirSync(dir, { withFileTypes: true });
|
|
6698
6790
|
} catch {
|
|
6699
6791
|
return;
|
|
6700
6792
|
}
|
|
6701
6793
|
for (const entry of entries) {
|
|
6702
|
-
const full =
|
|
6794
|
+
const full = path18__default.join(dir, entry.name);
|
|
6703
6795
|
if (entry.isDirectory()) {
|
|
6704
6796
|
if (!SKIP_DIRS.has(entry.name)) walk(full);
|
|
6705
6797
|
} else if (entry.isFile() && /(^|\.)skaile\.yaml$/.test(entry.name)) {
|
|
@@ -6762,14 +6854,14 @@ function validateWorkspaceAssets(parsed, relPath) {
|
|
|
6762
6854
|
return errors;
|
|
6763
6855
|
}
|
|
6764
6856
|
function validateWorkspaceManifests(rootPath) {
|
|
6765
|
-
const absRoot =
|
|
6857
|
+
const absRoot = path18__default.resolve(rootPath);
|
|
6766
6858
|
const files = findWorkspaceManifests(absRoot);
|
|
6767
6859
|
let errors = 0;
|
|
6768
6860
|
for (const file of files) {
|
|
6769
|
-
const relPath =
|
|
6861
|
+
const relPath = path18__default.relative(absRoot, file);
|
|
6770
6862
|
let parsed;
|
|
6771
6863
|
try {
|
|
6772
|
-
parsed = parse(
|
|
6864
|
+
parsed = parse(fs8__default.readFileSync(file, "utf-8")) ?? {};
|
|
6773
6865
|
} catch (e) {
|
|
6774
6866
|
logErr(`${relPath} \u2014 parse error: ${e instanceof Error ? e.message : String(e)}`);
|
|
6775
6867
|
errors++;
|
|
@@ -6777,7 +6869,7 @@ function validateWorkspaceManifests(rootPath) {
|
|
|
6777
6869
|
}
|
|
6778
6870
|
errors += validateWorkspaceRefs(collectWorkspaceRefFields(parsed), relPath);
|
|
6779
6871
|
errors += validateWorkspaceAssets(parsed, relPath);
|
|
6780
|
-
for (const d of checkAgentInstances(
|
|
6872
|
+
for (const d of checkAgentInstances(path18__default.dirname(file), parsed)) {
|
|
6781
6873
|
const line = `${relPath} [agents] \u2014 ${d.code}: ${d.path ? `${d.path}: ` : ""}${d.message}`;
|
|
6782
6874
|
if (d.severity === "error") {
|
|
6783
6875
|
logErr(line);
|
|
@@ -6790,7 +6882,7 @@ function validateWorkspaceManifests(rootPath) {
|
|
|
6790
6882
|
return { total: files.length, errors };
|
|
6791
6883
|
}
|
|
6792
6884
|
function validatePublishManifestRoots(rootPath) {
|
|
6793
|
-
const absRoot =
|
|
6885
|
+
const absRoot = path18__default.resolve(rootPath);
|
|
6794
6886
|
const manifest = loadSkPublishManifest(absRoot);
|
|
6795
6887
|
if (!manifest) return 0;
|
|
6796
6888
|
const missing = missingRootAssets(absRoot, manifest);
|
|
@@ -6802,7 +6894,7 @@ function validatePublishManifestRoots(rootPath) {
|
|
|
6802
6894
|
return missing.length;
|
|
6803
6895
|
}
|
|
6804
6896
|
function validatePublishManifestRequires(rootPath) {
|
|
6805
|
-
const problems = manifestRequiresProblems(
|
|
6897
|
+
const problems = manifestRequiresProblems(path18__default.resolve(rootPath));
|
|
6806
6898
|
for (const p6 of problems) {
|
|
6807
6899
|
logErr(
|
|
6808
6900
|
`${SKAILE_MANIFEST_FILENAME} [assets] \u2014 ${p6.asset}: ${p6.message}. Use the \`kind:@<publisher>/name[#version]\` form.`
|
|
@@ -6810,16 +6902,21 @@ function validatePublishManifestRequires(rootPath) {
|
|
|
6810
6902
|
}
|
|
6811
6903
|
return problems.length;
|
|
6812
6904
|
}
|
|
6905
|
+
function validatePublishManifestPublisherSlugs(rootPath) {
|
|
6906
|
+
const problems = manifestPublisherProblems(path18__default.resolve(rootPath));
|
|
6907
|
+
for (const message of problems) logErr(message);
|
|
6908
|
+
return problems.length;
|
|
6909
|
+
}
|
|
6813
6910
|
function validatePublishManifestVersions(rootPath) {
|
|
6814
|
-
const absRoot =
|
|
6911
|
+
const absRoot = path18__default.resolve(rootPath);
|
|
6815
6912
|
const manifest = loadSkPublishManifest(absRoot);
|
|
6816
6913
|
if (!manifest || manifest.source) return 0;
|
|
6817
6914
|
let warnings = 0;
|
|
6818
6915
|
for (const a of manifest.assets ?? []) {
|
|
6819
6916
|
if (!a.root || a.source || !a.version) continue;
|
|
6820
|
-
const file = findAssetManifestFile(
|
|
6917
|
+
const file = findAssetManifestFile(path18__default.join(absRoot, a.root), a.kind, a.name);
|
|
6821
6918
|
if (!file) continue;
|
|
6822
|
-
const res = parseManifestFile(file,
|
|
6919
|
+
const res = parseManifestFile(file, fs8__default.readFileSync(file, "utf-8"));
|
|
6823
6920
|
if (!res.ok) continue;
|
|
6824
6921
|
const fileVersion = declaredVersion(res.data);
|
|
6825
6922
|
if (fileVersion === void 0 || fileVersion === a.version) continue;
|
|
@@ -6827,7 +6924,7 @@ function validatePublishManifestVersions(rootPath) {
|
|
|
6827
6924
|
manifestVersionMismatchMessage(
|
|
6828
6925
|
assetEntryRef(a, manifest),
|
|
6829
6926
|
a.version,
|
|
6830
|
-
toPosix(
|
|
6927
|
+
toPosix(path18__default.relative(absRoot, file)),
|
|
6831
6928
|
fileVersion
|
|
6832
6929
|
)
|
|
6833
6930
|
);
|
|
@@ -6836,7 +6933,7 @@ function validatePublishManifestVersions(rootPath) {
|
|
|
6836
6933
|
return warnings;
|
|
6837
6934
|
}
|
|
6838
6935
|
function validatePublishManifestPublishers(rootPath) {
|
|
6839
|
-
const absRoot =
|
|
6936
|
+
const absRoot = path18__default.resolve(rootPath);
|
|
6840
6937
|
const manifest = loadSkPublishManifest(absRoot);
|
|
6841
6938
|
if (!manifest || manifest.source) return 0;
|
|
6842
6939
|
const bare = (p6) => p6.trim().replace(/^@/, "");
|
|
@@ -6844,15 +6941,15 @@ function validatePublishManifestPublishers(rootPath) {
|
|
|
6844
6941
|
for (const a of manifest.assets ?? []) {
|
|
6845
6942
|
const resolved = a.publisher ?? manifest.publisher;
|
|
6846
6943
|
if (!a.root || a.source || !resolved) continue;
|
|
6847
|
-
const file = findAssetManifestFile(
|
|
6944
|
+
const file = findAssetManifestFile(path18__default.join(absRoot, a.root), a.kind, a.name);
|
|
6848
6945
|
if (!file) continue;
|
|
6849
|
-
const res = parseManifestFile(file,
|
|
6946
|
+
const res = parseManifestFile(file, fs8__default.readFileSync(file, "utf-8"));
|
|
6850
6947
|
if (!res.ok) continue;
|
|
6851
6948
|
const meta = res.data.metadata;
|
|
6852
6949
|
const declared = meta !== null && typeof meta === "object" ? meta.publisher : null;
|
|
6853
6950
|
if (typeof declared !== "string" || bare(declared) === bare(resolved)) continue;
|
|
6854
6951
|
logWarn(
|
|
6855
|
-
`${toPosix(
|
|
6952
|
+
`${toPosix(path18__default.relative(absRoot, file))} [publisher] \u2014 metadata.publisher "${bare(declared)}" differs from the manifest publisher "${bare(resolved)}" for ${assetEntryRef(a, manifest)}. The manifest wins and the file value is ignored: delete \`metadata.publisher\` from the file, or set the publisher in ${SKAILE_MANIFEST_FILENAME}.`
|
|
6856
6953
|
);
|
|
6857
6954
|
warnings++;
|
|
6858
6955
|
}
|
|
@@ -6860,7 +6957,7 @@ function validatePublishManifestPublishers(rootPath) {
|
|
|
6860
6957
|
}
|
|
6861
6958
|
var EXCLUDED_PATHS = ["skaileup-shared/", "external/", "docs/"];
|
|
6862
6959
|
function toPosix(p6) {
|
|
6863
|
-
return p6.split(
|
|
6960
|
+
return p6.split(path18__default.sep).join("/");
|
|
6864
6961
|
}
|
|
6865
6962
|
function isExcludedPath(relPath) {
|
|
6866
6963
|
const rel = toPosix(relPath);
|
|
@@ -6870,20 +6967,23 @@ var VERSIONED_KINDS = {
|
|
|
6870
6967
|
skill: true,
|
|
6871
6968
|
agent: true,
|
|
6872
6969
|
flow: true,
|
|
6873
|
-
prompt: true
|
|
6970
|
+
prompt: true,
|
|
6971
|
+
preset: true,
|
|
6972
|
+
contract: true
|
|
6874
6973
|
};
|
|
6875
6974
|
function readAssetVersion(c) {
|
|
6876
6975
|
const kind = c.kind;
|
|
6877
|
-
const fileName =
|
|
6878
|
-
const dirName =
|
|
6879
|
-
const content =
|
|
6976
|
+
const fileName = path18__default.basename(c.filePath);
|
|
6977
|
+
const dirName = path18__default.basename(path18__default.dirname(c.filePath));
|
|
6978
|
+
const content = fs8__default.readFileSync(c.filePath, "utf-8");
|
|
6880
6979
|
if (c.filePath.endsWith(".md")) {
|
|
6881
|
-
const
|
|
6980
|
+
const res = parseManifestFile(c.filePath, content);
|
|
6981
|
+
const data = res.ok ? res.data : {};
|
|
6882
6982
|
const stem = fileName.replace(/\.prompt\.md$/, "");
|
|
6883
6983
|
return {
|
|
6884
6984
|
kind,
|
|
6885
|
-
name:
|
|
6886
|
-
version:
|
|
6985
|
+
name: typeof data.name === "string" ? data.name : kind === "prompt" ? stem : dirName,
|
|
6986
|
+
version: declaredVersion(data) ?? "",
|
|
6887
6987
|
filePath: c.filePath
|
|
6888
6988
|
};
|
|
6889
6989
|
}
|
|
@@ -6908,26 +7008,26 @@ function readAssetVersion(c) {
|
|
|
6908
7008
|
};
|
|
6909
7009
|
}
|
|
6910
7010
|
function collectAssetVersions(root) {
|
|
6911
|
-
if (!
|
|
7011
|
+
if (!fs8__default.existsSync(root)) return [];
|
|
6912
7012
|
const assets = [];
|
|
6913
7013
|
for (const c of findManifestCandidates(root)) {
|
|
6914
7014
|
if (!VERSIONED_KINDS[c.kind]) continue;
|
|
6915
7015
|
if (c.filePath.endsWith(".flow.json")) continue;
|
|
6916
|
-
if (isExcludedPath(
|
|
7016
|
+
if (isExcludedPath(path18__default.relative(root, c.filePath))) continue;
|
|
6917
7017
|
assets.push(readAssetVersion(c));
|
|
6918
7018
|
}
|
|
6919
7019
|
return assets;
|
|
6920
7020
|
}
|
|
6921
7021
|
function assetLocation(a, root) {
|
|
6922
|
-
return toPosix(
|
|
7022
|
+
return toPosix(path18__default.relative(root, a.filePath));
|
|
6923
7023
|
}
|
|
6924
7024
|
function findChangelogUnit(assetRelPath, root) {
|
|
6925
|
-
let dir =
|
|
7025
|
+
let dir = path18__default.posix.dirname(toPosix(assetRelPath));
|
|
6926
7026
|
for (; ; ) {
|
|
6927
7027
|
const candidate = dir === "." ? "CHANGELOG.md" : `${dir}/CHANGELOG.md`;
|
|
6928
|
-
if (
|
|
7028
|
+
if (fs8__default.existsSync(path18__default.join(root, candidate))) return candidate;
|
|
6929
7029
|
if (dir === ".") return null;
|
|
6930
|
-
dir =
|
|
7030
|
+
dir = path18__default.posix.dirname(dir);
|
|
6931
7031
|
}
|
|
6932
7032
|
}
|
|
6933
7033
|
function checkChangelogUnits(modifiedFiles, root) {
|
|
@@ -6945,9 +7045,6 @@ function checkChangelogUnits(modifiedFiles, root) {
|
|
|
6945
7045
|
const stale = [...units].filter((u) => !modified.has(u));
|
|
6946
7046
|
return { updated, stale, orphans };
|
|
6947
7047
|
}
|
|
6948
|
-
function isValidSemver(v) {
|
|
6949
|
-
return SEMVER_RE.test(v);
|
|
6950
|
-
}
|
|
6951
7048
|
function extractVersionFromContent(filePath, content) {
|
|
6952
7049
|
if (filePath.endsWith(".yaml")) {
|
|
6953
7050
|
const parsed2 = parse(content);
|
|
@@ -6962,13 +7059,15 @@ function checkAssetVersions(assets, root) {
|
|
|
6962
7059
|
let errors = 0;
|
|
6963
7060
|
const warnings = 0;
|
|
6964
7061
|
for (const a of assets) {
|
|
7062
|
+
const location = assetLocation(a, root);
|
|
6965
7063
|
if (!a.version) {
|
|
6966
|
-
logErr(`${a.kind}:${a.name} (${
|
|
7064
|
+
logErr(`${a.kind}:${a.name} (${location}) \u2014 missing version`);
|
|
6967
7065
|
errors++;
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
7066
|
+
continue;
|
|
7067
|
+
}
|
|
7068
|
+
const invalid = invalidSemverText(a.version);
|
|
7069
|
+
if (invalid) {
|
|
7070
|
+
logErr(`${a.kind}:${a.name} (${location}) \u2014 ${invalid}`);
|
|
6972
7071
|
errors++;
|
|
6973
7072
|
}
|
|
6974
7073
|
}
|
|
@@ -6978,7 +7077,7 @@ function checkVersionBumps(assets, root) {
|
|
|
6978
7077
|
let warnings = 0;
|
|
6979
7078
|
for (const a of assets) {
|
|
6980
7079
|
if (!a.version) continue;
|
|
6981
|
-
const relPath = toPosix(
|
|
7080
|
+
const relPath = toPosix(path18__default.relative(root, a.filePath));
|
|
6982
7081
|
try {
|
|
6983
7082
|
const headContent = execFileSync("git", ["show", `HEAD:./${relPath}`], {
|
|
6984
7083
|
cwd: root,
|
|
@@ -7011,7 +7110,7 @@ function checkFlowVersionPins(assets, root) {
|
|
|
7011
7110
|
pins = flowSkillVersionPins(loadFlow(f.filePath));
|
|
7012
7111
|
} catch (err2) {
|
|
7013
7112
|
logWarn(
|
|
7014
|
-
`flow:${f.name} (${
|
|
7113
|
+
`flow:${f.name} (${path18__default.relative(root, f.filePath)}) \u2014 could not be read: ${err2 instanceof Error ? err2.message : err2}`
|
|
7015
7114
|
);
|
|
7016
7115
|
warnings++;
|
|
7017
7116
|
continue;
|
|
@@ -7029,16 +7128,16 @@ function checkFlowVersionPins(assets, root) {
|
|
|
7029
7128
|
}
|
|
7030
7129
|
function resolveCheckRoot(pathArg) {
|
|
7031
7130
|
if (pathArg) {
|
|
7032
|
-
const abs =
|
|
7033
|
-
if (!
|
|
7131
|
+
const abs = path18__default.resolve(pathArg);
|
|
7132
|
+
if (!fs8__default.existsSync(abs)) {
|
|
7034
7133
|
logErr(`Path does not exist: ${abs}`);
|
|
7035
7134
|
return null;
|
|
7036
7135
|
}
|
|
7037
7136
|
return abs;
|
|
7038
7137
|
}
|
|
7039
|
-
for (let dir = process.cwd(); ; dir =
|
|
7040
|
-
if (
|
|
7041
|
-
if (
|
|
7138
|
+
for (let dir = process.cwd(); ; dir = path18__default.dirname(dir)) {
|
|
7139
|
+
if (fs8__default.existsSync(path18__default.join(dir, SKAILE_MANIFEST_FILENAME))) return dir;
|
|
7140
|
+
if (path18__default.dirname(dir) === dir) return AI_RESOURCES;
|
|
7042
7141
|
}
|
|
7043
7142
|
}
|
|
7044
7143
|
function changedFiles(root, ref) {
|
|
@@ -7073,7 +7172,7 @@ function runVersionsCheck(pathArg, opts) {
|
|
|
7073
7172
|
process.exit(1);
|
|
7074
7173
|
return;
|
|
7075
7174
|
}
|
|
7076
|
-
const changedAbs = new Set(changed.map((f) =>
|
|
7175
|
+
const changedAbs = new Set(changed.map((f) => path18__default.resolve(root, f)));
|
|
7077
7176
|
assets = assets.filter((a) => changedAbs.has(a.filePath));
|
|
7078
7177
|
}
|
|
7079
7178
|
logInfo(`Checking versions in ${root}`);
|
|
@@ -7105,8 +7204,8 @@ function makeValidateCommand() {
|
|
|
7105
7204
|
cmd.argument("[path]", "Path to asset repo or directory to validate", ".").option(
|
|
7106
7205
|
"--strict-conformance",
|
|
7107
7206
|
"Treat Agent Skills (agentskills.io) standard findings as errors"
|
|
7108
|
-
).action((targetPath, opts) => {
|
|
7109
|
-
const absPath =
|
|
7207
|
+
).action(async (targetPath, opts) => {
|
|
7208
|
+
const absPath = path18__default.resolve(targetPath);
|
|
7110
7209
|
logInfo(`Validating manifests in ${absPath}`);
|
|
7111
7210
|
const { total, errors, warnings } = validateManifests(
|
|
7112
7211
|
absPath,
|
|
@@ -7114,15 +7213,19 @@ function makeValidateCommand() {
|
|
|
7114
7213
|
);
|
|
7115
7214
|
const ws = validateWorkspaceManifests(absPath);
|
|
7116
7215
|
const rootErrors = validatePublishManifestRoots(absPath);
|
|
7216
|
+
const slugErrors = validatePublishManifestPublisherSlugs(absPath);
|
|
7117
7217
|
const requiresErrors = validatePublishManifestRequires(absPath);
|
|
7118
7218
|
const versionWarnings = validatePublishManifestVersions(absPath);
|
|
7119
7219
|
const publisherWarnings = validatePublishManifestPublishers(absPath);
|
|
7120
|
-
const
|
|
7220
|
+
const dependencyProblems = await unresolvedManifestDependencies(absPath);
|
|
7221
|
+
for (const w of dependencyProblems) logWarn(w);
|
|
7222
|
+
const dependencyWarnings = dependencyProblems.length;
|
|
7223
|
+
const totalErrors = errors + ws.errors + rootErrors + slugErrors + requiresErrors;
|
|
7121
7224
|
console.log();
|
|
7122
7225
|
warnIgnoredDomainFiles(absPath);
|
|
7123
7226
|
warnLegacyBundleFiles(absPath);
|
|
7124
7227
|
logInfo(`Scanned ${total} asset manifest(s) and ${ws.total} skaile.yaml file(s)`);
|
|
7125
|
-
const totalWarnings = warnings + versionWarnings + publisherWarnings;
|
|
7228
|
+
const totalWarnings = warnings + versionWarnings + publisherWarnings + dependencyWarnings;
|
|
7126
7229
|
if (totalWarnings > 0) logWarn(`${totalWarnings} warning(s)`);
|
|
7127
7230
|
if (totalErrors === 0) {
|
|
7128
7231
|
logOk("All manifests valid");
|
|
@@ -7192,7 +7295,7 @@ function itemFromRef(raw, defaultKind, ctx) {
|
|
|
7192
7295
|
return { kind: prefixed[1], ref: value };
|
|
7193
7296
|
}
|
|
7194
7297
|
if (PATH_LIKE.test(value)) return { kind: defaultKind, ref: value };
|
|
7195
|
-
if (defaultKind === "skill" && !value.includes("/") && existsSync(
|
|
7298
|
+
if (defaultKind === "skill" && !value.includes("/") && existsSync(path18__default.join(ctx.agentDir, "skills", value, "SKILL.md"))) {
|
|
7196
7299
|
return { kind: "skill", ref: `./skills/${value}` };
|
|
7197
7300
|
}
|
|
7198
7301
|
return { kind: defaultKind, ref: `${defaultKind}:${value}` };
|
|
@@ -7328,7 +7431,7 @@ function migrateAgentYaml(source, options) {
|
|
|
7328
7431
|
manual.push("metadata.soul: not a string; left unchanged");
|
|
7329
7432
|
continue;
|
|
7330
7433
|
}
|
|
7331
|
-
if (
|
|
7434
|
+
if (path18__default.posix.basename(soul.replace(/\\/g, "/")).toLowerCase() === "soul.md") {
|
|
7332
7435
|
notes.push("metadata.soul \u2192 dropped (SOUL.md is a convention file)");
|
|
7333
7436
|
} else {
|
|
7334
7437
|
derived.push({ kind: "persona", ref: soul });
|
|
@@ -7562,7 +7665,7 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7562
7665
|
if (!isMap(agentNode)) return void 0;
|
|
7563
7666
|
const subNode = agentNode.get("subagents", true);
|
|
7564
7667
|
if (!isMap(subNode)) return void 0;
|
|
7565
|
-
const dir =
|
|
7668
|
+
const dir = path18__default.dirname(skaileYamlPath);
|
|
7566
7669
|
const notes = [];
|
|
7567
7670
|
const manual = [];
|
|
7568
7671
|
const changes = [];
|
|
@@ -7580,10 +7683,10 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7580
7683
|
continue;
|
|
7581
7684
|
}
|
|
7582
7685
|
const id = instanceId(name);
|
|
7583
|
-
const assetDir =
|
|
7686
|
+
const assetDir = path18__default.join(dir, ".skaile", "agents", id);
|
|
7584
7687
|
if (takenIds.has(id) || existsSync(assetDir)) {
|
|
7585
7688
|
manual.push(
|
|
7586
|
-
`agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${
|
|
7689
|
+
`agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${path18__default.relative(dir, assetDir)} already exists`}; left in place`
|
|
7587
7690
|
);
|
|
7588
7691
|
continue;
|
|
7589
7692
|
}
|
|
@@ -7607,13 +7710,13 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7607
7710
|
manifest.tools = { ...allowed ? { allowed } : {}, ...denied ? { denied } : {} };
|
|
7608
7711
|
}
|
|
7609
7712
|
const text = stringify(manifest, { lineWidth: 0 });
|
|
7610
|
-
const manifestPath =
|
|
7713
|
+
const manifestPath = path18__default.join(assetDir, "agent.yaml");
|
|
7611
7714
|
changes.push({ type: "create", path: manifestPath, after: text });
|
|
7612
7715
|
assetManifests.push({ file: manifestPath, text });
|
|
7613
7716
|
if (typeof spec.prompt === "string" && spec.prompt.trim() !== "") {
|
|
7614
7717
|
changes.push({
|
|
7615
7718
|
type: "create",
|
|
7616
|
-
path:
|
|
7719
|
+
path: path18__default.join(assetDir, "SOUL.md"),
|
|
7617
7720
|
after: `${spec.prompt.replace(/\s+$/, "")}
|
|
7618
7721
|
`
|
|
7619
7722
|
});
|
|
@@ -7672,7 +7775,7 @@ function validateMigratedAgent(text, registry) {
|
|
|
7672
7775
|
function collectAgentFiles(paths) {
|
|
7673
7776
|
const files = /* @__PURE__ */ new Set();
|
|
7674
7777
|
for (const input of paths) {
|
|
7675
|
-
const abs =
|
|
7778
|
+
const abs = path18__default.resolve(input);
|
|
7676
7779
|
if (!existsSync(abs)) continue;
|
|
7677
7780
|
if (statSync(abs).isDirectory()) {
|
|
7678
7781
|
for (const f of walkFiles(abs, (b) => b === "agent.yaml" || b === "skaile.yaml"))
|
|
@@ -7689,7 +7792,7 @@ function planAgentMigration(options) {
|
|
|
7689
7792
|
const reports = [];
|
|
7690
7793
|
for (const file of collectAgentFiles(options.paths)) {
|
|
7691
7794
|
const source = readText(file);
|
|
7692
|
-
const base =
|
|
7795
|
+
const base = path18__default.basename(file);
|
|
7693
7796
|
if (base === "skaile.yaml") {
|
|
7694
7797
|
const result = migrateSubagents(file, source);
|
|
7695
7798
|
if (!result) continue;
|
|
@@ -7697,7 +7800,7 @@ function planAgentMigration(options) {
|
|
|
7697
7800
|
for (const asset of result.assetManifests) {
|
|
7698
7801
|
const v = validateMigratedAgent(asset.text, options.registry);
|
|
7699
7802
|
validation2.errors.push(
|
|
7700
|
-
...v.errors.map((e) => `${
|
|
7803
|
+
...v.errors.map((e) => `${path18__default.basename(path18__default.dirname(asset.file))}: ${e}`)
|
|
7701
7804
|
);
|
|
7702
7805
|
validation2.warnings.push(...v.warnings);
|
|
7703
7806
|
}
|
|
@@ -7725,7 +7828,7 @@ function planAgentMigration(options) {
|
|
|
7725
7828
|
});
|
|
7726
7829
|
continue;
|
|
7727
7830
|
}
|
|
7728
|
-
migration = migrateAgentYaml(source, { agentDir:
|
|
7831
|
+
migration = migrateAgentYaml(source, { agentDir: path18__default.dirname(file), knownKinds });
|
|
7729
7832
|
} catch (error) {
|
|
7730
7833
|
reports.push({
|
|
7731
7834
|
file,
|
|
@@ -7753,8 +7856,9 @@ function planAgentMigration(options) {
|
|
|
7753
7856
|
return { changes, reports };
|
|
7754
7857
|
}
|
|
7755
7858
|
var DEFAULT_PUBLISHER = "skaile-ai";
|
|
7859
|
+
var PRESET_DEFAULT_VERSION = "1.0.0";
|
|
7756
7860
|
var FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
7757
|
-
var posix2 = (p6) => p6.split(
|
|
7861
|
+
var posix2 = (p6) => p6.split(path18__default.sep).join("/");
|
|
7758
7862
|
var MOVED_KINDS = { persona: "PERSONA.md", ruleset: "RULESET.md" };
|
|
7759
7863
|
var KIND_MANIFEST_FILES = /* @__PURE__ */ new Set(["PERSONA.md", "RULESET.md", "SKILL.md"]);
|
|
7760
7864
|
function readFrontmatterType(text) {
|
|
@@ -7785,14 +7889,14 @@ function planMarkdownMoves(root, knownKinds, manual, unknownTypes) {
|
|
|
7785
7889
|
if (!text.startsWith("---")) continue;
|
|
7786
7890
|
const found = readFrontmatterType(text);
|
|
7787
7891
|
if (!found) continue;
|
|
7788
|
-
const base =
|
|
7789
|
-
const inAgentParts = file.split(
|
|
7892
|
+
const base = path18__default.basename(file);
|
|
7893
|
+
const inAgentParts = file.split(path18__default.sep).includes("_agent-parts");
|
|
7790
7894
|
const targetName = MOVED_KINDS[found.type];
|
|
7791
7895
|
if (targetName !== void 0 && !KIND_MANIFEST_FILES.has(base)) {
|
|
7792
|
-
const to =
|
|
7896
|
+
const to = path18__default.join(path18__default.dirname(file), base.replace(/\.md$/i, ""), targetName);
|
|
7793
7897
|
if (existsSync(to) || targets.has(to)) {
|
|
7794
7898
|
manual.push(
|
|
7795
|
-
`${posix2(
|
|
7899
|
+
`${posix2(path18__default.relative(root, file))}: ${posix2(path18__default.relative(root, to))} already exists; not moved`
|
|
7796
7900
|
);
|
|
7797
7901
|
continue;
|
|
7798
7902
|
}
|
|
@@ -7813,13 +7917,13 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
|
|
|
7813
7917
|
const changes = [];
|
|
7814
7918
|
for (const file of walkFiles(root, (b) => b === "agent.yaml")) {
|
|
7815
7919
|
const source = readText(file);
|
|
7816
|
-
const agentDir =
|
|
7920
|
+
const agentDir = path18__default.dirname(file);
|
|
7817
7921
|
let hits = 0;
|
|
7818
7922
|
const refRewrite = (_kind, ref) => {
|
|
7819
|
-
const moved = byOldPath.get(
|
|
7923
|
+
const moved = byOldPath.get(path18__default.resolve(agentDir, ref));
|
|
7820
7924
|
if (moved === void 0) return ref;
|
|
7821
7925
|
hits++;
|
|
7822
|
-
const rel = posix2(
|
|
7926
|
+
const rel = posix2(path18__default.relative(agentDir, moved));
|
|
7823
7927
|
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
7824
7928
|
};
|
|
7825
7929
|
let output;
|
|
@@ -7836,7 +7940,7 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
|
|
|
7836
7940
|
if (hits === 0 || output === source) continue;
|
|
7837
7941
|
changes.push({ type: "write", path: file, before: source, after: output });
|
|
7838
7942
|
notes.push(
|
|
7839
|
-
`${posix2(
|
|
7943
|
+
`${posix2(path18__default.relative(root, file))}: persona/ruleset refs \u2192 composes items at the new paths`
|
|
7840
7944
|
);
|
|
7841
7945
|
}
|
|
7842
7946
|
return changes;
|
|
@@ -7847,12 +7951,12 @@ function presetItemRef(dep, publisher) {
|
|
|
7847
7951
|
const [, kind, rest] = match;
|
|
7848
7952
|
return rest.startsWith("@") ? dep.trim() : `${kind}:@${publisher}/${rest}`;
|
|
7849
7953
|
}
|
|
7850
|
-
function presetText(name, description, refs, publisher) {
|
|
7954
|
+
function presetText(name, description, refs, publisher, version) {
|
|
7851
7955
|
return stringify(
|
|
7852
7956
|
{
|
|
7853
7957
|
publisher,
|
|
7854
7958
|
name,
|
|
7855
|
-
version
|
|
7959
|
+
version,
|
|
7856
7960
|
description: description && description.trim() !== "" ? description : `Preset ${name}`,
|
|
7857
7961
|
items: refs.map((ref) => ({ ref }))
|
|
7858
7962
|
},
|
|
@@ -7861,14 +7965,14 @@ function presetText(name, description, refs, publisher) {
|
|
|
7861
7965
|
}
|
|
7862
7966
|
function skillDirs(dir) {
|
|
7863
7967
|
try {
|
|
7864
|
-
return readdirSync(
|
|
7968
|
+
return readdirSync(path18__default.join(dir, "skills"), { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync(path18__default.join(dir, "skills", e.name, "SKILL.md"))).map((e) => e.name).sort();
|
|
7865
7969
|
} catch {
|
|
7866
7970
|
return [];
|
|
7867
7971
|
}
|
|
7868
7972
|
}
|
|
7869
7973
|
function repoPublisher(root) {
|
|
7870
7974
|
for (const name of ["skaile.manifest.yaml", "skaile.yaml"]) {
|
|
7871
|
-
const file =
|
|
7975
|
+
const file = path18__default.join(root, name);
|
|
7872
7976
|
if (!existsSync(file)) continue;
|
|
7873
7977
|
try {
|
|
7874
7978
|
const parsed = parse(readText(file));
|
|
@@ -7884,9 +7988,9 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7884
7988
|
const changes = [];
|
|
7885
7989
|
const presets = [];
|
|
7886
7990
|
const handled = /* @__PURE__ */ new Set();
|
|
7887
|
-
const rel = (p6) => posix2(
|
|
7991
|
+
const rel = (p6) => posix2(path18__default.relative(root, p6));
|
|
7888
7992
|
const convert = (name, bundleFile, dir) => {
|
|
7889
|
-
const target =
|
|
7993
|
+
const target = path18__default.join(dir, `${name}.preset.yaml`);
|
|
7890
7994
|
if (existsSync(target)) {
|
|
7891
7995
|
manual.push(`${rel(target)} already exists; bundle ${name} not converted`);
|
|
7892
7996
|
return;
|
|
@@ -7894,11 +7998,16 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7894
7998
|
let description;
|
|
7895
7999
|
let refs = [];
|
|
7896
8000
|
let before;
|
|
8001
|
+
let version = PRESET_DEFAULT_VERSION;
|
|
8002
|
+
let versionNote;
|
|
7897
8003
|
if (bundleFile && existsSync(bundleFile)) {
|
|
7898
8004
|
before = readText(bundleFile);
|
|
7899
8005
|
const parsed = parse(before);
|
|
7900
8006
|
if (isRecord(parsed)) {
|
|
7901
8007
|
if (typeof parsed.description === "string") description = parsed.description;
|
|
8008
|
+
const declared = typeof parsed.version === "string" || typeof parsed.version === "number" ? String(parsed.version) : void 0;
|
|
8009
|
+
if (declared !== void 0 && SEMVER_RE.test(declared)) version = declared;
|
|
8010
|
+
else if (declared !== void 0) versionNote = `version ${declared} \u2192 ${version}`;
|
|
7902
8011
|
const deps = Array.isArray(parsed.dependencies) ? parsed.dependencies : [];
|
|
7903
8012
|
refs = deps.filter((d) => typeof d === "string").map((d) => presetItemRef(d, publisher));
|
|
7904
8013
|
if (refs.length !== deps.length) {
|
|
@@ -7912,11 +8021,11 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7912
8021
|
}
|
|
7913
8022
|
if (refs.length === 0) {
|
|
7914
8023
|
manual.push(
|
|
7915
|
-
`bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(
|
|
8024
|
+
`bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(path18__default.join(dir, "skills"))}`}; no preset generated`
|
|
7916
8025
|
);
|
|
7917
8026
|
return;
|
|
7918
8027
|
}
|
|
7919
|
-
const after = presetText(name, description, refs, publisher);
|
|
8028
|
+
const after = presetText(name, description, refs, publisher, version);
|
|
7920
8029
|
if (before !== void 0 && bundleFile) {
|
|
7921
8030
|
changes.push({ type: "move", from: bundleFile, to: target, before, after });
|
|
7922
8031
|
handled.add(bundleFile);
|
|
@@ -7928,24 +8037,26 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7928
8037
|
file: target,
|
|
7929
8038
|
...bundleFile && before !== void 0 ? { bundleFile } : {}
|
|
7930
8039
|
});
|
|
7931
|
-
notes.push(
|
|
8040
|
+
notes.push(
|
|
8041
|
+
`bundle ${name} \u2192 ${rel(target)} (${refs.length} items${versionNote ? `, ${versionNote}` : ""})`
|
|
8042
|
+
);
|
|
7932
8043
|
};
|
|
7933
8044
|
for (const { file, raw } of skaileYamls) {
|
|
7934
8045
|
const assets = Array.isArray(raw.assets) ? raw.assets : [];
|
|
7935
8046
|
for (const entry of assets) {
|
|
7936
8047
|
if (!isRecord(entry) || entry.kind !== "bundle" || typeof entry.name !== "string") continue;
|
|
7937
|
-
const baseDir =
|
|
7938
|
-
const entryRoot = typeof entry.root === "string" ?
|
|
8048
|
+
const baseDir = path18__default.dirname(file);
|
|
8049
|
+
const entryRoot = typeof entry.root === "string" ? path18__default.join(baseDir, entry.root) : baseDir;
|
|
7939
8050
|
const files = Array.isArray(entry.files) ? entry.files : [];
|
|
7940
8051
|
const bundleName = files.find(
|
|
7941
8052
|
(f) => typeof f === "string" && f.endsWith(".bundle.yaml")
|
|
7942
8053
|
);
|
|
7943
|
-
convert(entry.name, bundleName ?
|
|
8054
|
+
convert(entry.name, bundleName ? path18__default.join(entryRoot, bundleName) : void 0, entryRoot);
|
|
7944
8055
|
}
|
|
7945
8056
|
}
|
|
7946
8057
|
for (const bundleFile of walkFiles(root, (b) => b.endsWith(".bundle.yaml"))) {
|
|
7947
8058
|
if (handled.has(bundleFile)) continue;
|
|
7948
|
-
const base =
|
|
8059
|
+
const base = path18__default.basename(bundleFile);
|
|
7949
8060
|
let name = base.replace(/\.bundle\.yaml$/, "");
|
|
7950
8061
|
try {
|
|
7951
8062
|
const parsed = parse(readText(bundleFile));
|
|
@@ -7954,7 +8065,7 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7954
8065
|
} catch {
|
|
7955
8066
|
}
|
|
7956
8067
|
if (presets.some((p6) => p6.bundleFile === bundleFile)) continue;
|
|
7957
|
-
convert(name, bundleFile,
|
|
8068
|
+
convert(name, bundleFile, path18__default.dirname(bundleFile));
|
|
7958
8069
|
}
|
|
7959
8070
|
return changes;
|
|
7960
8071
|
}
|
|
@@ -7964,8 +8075,8 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
7964
8075
|
if (doc.errors.length > 0 || !isMap(doc.contents)) return [];
|
|
7965
8076
|
const map = doc.contents;
|
|
7966
8077
|
const raw = doc.toJS();
|
|
7967
|
-
const dir =
|
|
7968
|
-
const rel = (p6) => posix2(
|
|
8078
|
+
const dir = path18__default.dirname(file);
|
|
8079
|
+
const rel = (p6) => posix2(path18__default.relative(root, p6));
|
|
7969
8080
|
const changes = [];
|
|
7970
8081
|
let changed = false;
|
|
7971
8082
|
const deps = map.get("dependencies", true);
|
|
@@ -7982,7 +8093,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
7982
8093
|
const hasPublication = PUBLICATION_KEYS.some((k) => raw[k] !== void 0);
|
|
7983
8094
|
let remove = false;
|
|
7984
8095
|
if (hasPublication) {
|
|
7985
|
-
const manifestPath =
|
|
8096
|
+
const manifestPath = path18__default.join(dir, "skaile.manifest.yaml");
|
|
7986
8097
|
if (existsSync(manifestPath)) {
|
|
7987
8098
|
manual.push(
|
|
7988
8099
|
`${rel(file)}: publisher/version/assets left in place \u2014 ${rel(manifestPath)} already exists; merge by hand`
|
|
@@ -8039,7 +8150,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
8039
8150
|
return changes;
|
|
8040
8151
|
}
|
|
8041
8152
|
function planAssetMigration(options) {
|
|
8042
|
-
const root =
|
|
8153
|
+
const root = path18__default.resolve(options.root);
|
|
8043
8154
|
const knownKinds = new Set(options.registry.getAllKinds());
|
|
8044
8155
|
const notes = [];
|
|
8045
8156
|
const manual = [];
|
|
@@ -8047,7 +8158,7 @@ function planAssetMigration(options) {
|
|
|
8047
8158
|
const { moves, changes: moveChanges } = planMarkdownMoves(root, knownKinds, manual, unknownTypes);
|
|
8048
8159
|
for (const move of moves) {
|
|
8049
8160
|
notes.push(
|
|
8050
|
-
`${posix2(
|
|
8161
|
+
`${posix2(path18__default.relative(root, move.from))} \u2192 ${posix2(path18__default.relative(root, move.to))} (${move.kind})`
|
|
8051
8162
|
);
|
|
8052
8163
|
}
|
|
8053
8164
|
const agentChanges = planAgentRefRewrites(root, moves, knownKinds, notes);
|
|
@@ -8059,7 +8170,7 @@ function planAssetMigration(options) {
|
|
|
8059
8170
|
const raw = parse(source);
|
|
8060
8171
|
if (isRecord(raw)) skaileYamls.push({ file, source, raw });
|
|
8061
8172
|
} catch {
|
|
8062
|
-
manual.push(`${posix2(
|
|
8173
|
+
manual.push(`${posix2(path18__default.relative(root, file))}: invalid YAML; skipped`);
|
|
8063
8174
|
}
|
|
8064
8175
|
}
|
|
8065
8176
|
const publisher = repoPublisher(root);
|
|
@@ -8213,7 +8324,7 @@ function workspaceConfigFiles(dir) {
|
|
|
8213
8324
|
} catch {
|
|
8214
8325
|
return [];
|
|
8215
8326
|
}
|
|
8216
|
-
return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) =>
|
|
8327
|
+
return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) => path18__default.join(dir, name));
|
|
8217
8328
|
}
|
|
8218
8329
|
function readAgentConfigBlock(raw) {
|
|
8219
8330
|
const key = AGENT_CONFIG_KEYS.find((candidate) => raw[candidate] !== void 0);
|
|
@@ -8225,7 +8336,7 @@ function readAgentConfigBlock(raw) {
|
|
|
8225
8336
|
return flat ? { key, profiles: { default: profiles }, flat } : { key, profiles, flat };
|
|
8226
8337
|
}
|
|
8227
8338
|
function planProviderMigration(options) {
|
|
8228
|
-
const projectDir =
|
|
8339
|
+
const projectDir = path18__default.resolve(options.projectDir);
|
|
8229
8340
|
const registryPath = options.workspace ? workspaceProviderRegistryPath(projectDir) : userProviderRegistryPath();
|
|
8230
8341
|
const plan = {
|
|
8231
8342
|
registryPath,
|
|
@@ -8241,7 +8352,7 @@ function planProviderMigration(options) {
|
|
|
8241
8352
|
raw = parseDocument(readFileSync(file, "utf-8")).toJS() ?? {};
|
|
8242
8353
|
} catch (error) {
|
|
8243
8354
|
plan.warnings.push(
|
|
8244
|
-
`${
|
|
8355
|
+
`${path18__default.basename(file)}: not valid YAML (${error instanceof Error ? error.message : String(error)}) \u2014 skipped`
|
|
8245
8356
|
);
|
|
8246
8357
|
continue;
|
|
8247
8358
|
}
|
|
@@ -8290,7 +8401,7 @@ function planProviderMigration(options) {
|
|
|
8290
8401
|
});
|
|
8291
8402
|
if (!model) {
|
|
8292
8403
|
plan.warnings.push(
|
|
8293
|
-
`${
|
|
8404
|
+
`${path18__default.basename(file)}: profile '${profile}' had no model: \u2014 it now resolves against registry order. Pin it with 'model: ${providerId}/<modelId>'.`
|
|
8294
8405
|
);
|
|
8295
8406
|
}
|
|
8296
8407
|
touched = true;
|
|
@@ -8357,7 +8468,7 @@ function printPlan(plan) {
|
|
|
8357
8468
|
for (const entry of plan.entries) {
|
|
8358
8469
|
const base = entry.entry.base_url ?? S.dim("(transport-derived)");
|
|
8359
8470
|
console.log(
|
|
8360
|
-
` ${S.label(`${
|
|
8471
|
+
` ${S.label(`${path18__default.basename(entry.file)} ${entry.profile}`)} provider: ${entry.legacy.provider}, cloud: ${entry.legacy.cloud}`
|
|
8361
8472
|
);
|
|
8362
8473
|
console.log(` \u2192 providers.yml ${S.bold(entry.providerId)} ${base}`);
|
|
8363
8474
|
console.log(
|
|
@@ -8373,7 +8484,7 @@ function printPlan(plan) {
|
|
|
8373
8484
|
console.log();
|
|
8374
8485
|
}
|
|
8375
8486
|
async function runMigrateProviders(opts) {
|
|
8376
|
-
const projectDir = opts.projectDir ?
|
|
8487
|
+
const projectDir = opts.projectDir ? path18__default.resolve(opts.projectDir) : process.cwd();
|
|
8377
8488
|
const plan = planProviderMigration({ projectDir, workspace: opts.workspace });
|
|
8378
8489
|
for (const warning of plan.warnings) logWarn(warning);
|
|
8379
8490
|
if (plan.entries.length === 0 && Object.keys(plan.providers).length === 0) {
|
|
@@ -8504,7 +8615,7 @@ async function runMigrateAgents(paths, opts) {
|
|
|
8504
8615
|
let failures = 0;
|
|
8505
8616
|
let manualCount = 0;
|
|
8506
8617
|
for (const report of plan.reports) {
|
|
8507
|
-
const rel =
|
|
8618
|
+
const rel = path18__default.relative(base, report.file) || report.file;
|
|
8508
8619
|
for (const note of report.notes) console.log(` ${S.label(rel)} ${note}`);
|
|
8509
8620
|
for (const note of report.manual) {
|
|
8510
8621
|
manualCount++;
|
|
@@ -8531,14 +8642,14 @@ async function runMigrateAssets(root, opts) {
|
|
|
8531
8642
|
const write = resolveMode(opts);
|
|
8532
8643
|
const base = process.cwd();
|
|
8533
8644
|
const plan = planAssetMigration({
|
|
8534
|
-
root:
|
|
8645
|
+
root: path18__default.resolve(root ?? base),
|
|
8535
8646
|
registry: getKindRegistry()
|
|
8536
8647
|
});
|
|
8537
8648
|
for (const note of plan.notes) console.log(` ${note}`);
|
|
8538
8649
|
for (const note of plan.manual) logWarn(note);
|
|
8539
8650
|
for (const { file, type } of plan.unknownTypes) {
|
|
8540
8651
|
logWarn(
|
|
8541
|
-
`${
|
|
8652
|
+
`${path18__default.relative(base, file) || file}: frontmatter type "${type}" is not a registered asset kind (reported, not rewritten)`
|
|
8542
8653
|
);
|
|
8543
8654
|
}
|
|
8544
8655
|
printChanges(plan.changes, base);
|
|
@@ -8561,8 +8672,8 @@ function makeNpxCommand() {
|
|
|
8561
8672
|
skills.command("add <url>").description(
|
|
8562
8673
|
"Clone a repo, register it in the project's skaile.yaml sources[], and install a skill from it"
|
|
8563
8674
|
).requiredOption("--skill <name>", "Skill name to install from the repo").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", `Agent framework (${TARGET_DEFAULT_HINT})`).option("--global", "Deploy globally").action(async (url, opts) => {
|
|
8564
|
-
const projectDir =
|
|
8565
|
-
const projYaml =
|
|
8675
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
8676
|
+
const projYaml = path18__default.join(projectDir, "skaile.yaml");
|
|
8566
8677
|
if (!existsSync(projYaml)) {
|
|
8567
8678
|
logErr(`No skaile.yaml in ${projectDir} \u2014 run \`skaile init\` first.`);
|
|
8568
8679
|
process.exit(1);
|
|
@@ -8575,11 +8686,11 @@ function makeNpxCommand() {
|
|
|
8575
8686
|
}
|
|
8576
8687
|
const spinner = createSpinner();
|
|
8577
8688
|
const key = sourceCacheKey(url);
|
|
8578
|
-
const clonePath =
|
|
8689
|
+
const clonePath = path18__default.join(getGlobalCacheDir(), key);
|
|
8579
8690
|
spinner.start(`Cloning ${url}`);
|
|
8580
8691
|
try {
|
|
8581
8692
|
if (!existsSync(clonePath)) {
|
|
8582
|
-
mkdirSync(
|
|
8693
|
+
mkdirSync(path18__default.dirname(clonePath), { recursive: true });
|
|
8583
8694
|
execSync(`git clone ${url} ${clonePath}`, { stdio: "ignore" });
|
|
8584
8695
|
}
|
|
8585
8696
|
spinner.stop(`Cloned to ${key}`);
|
|
@@ -8634,7 +8745,7 @@ function makeNpxCommand() {
|
|
|
8634
8745
|
return npx;
|
|
8635
8746
|
}
|
|
8636
8747
|
function resolvePublisher(clonePath, url) {
|
|
8637
|
-
const manifestPath =
|
|
8748
|
+
const manifestPath = path18__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
|
|
8638
8749
|
if (existsSync(manifestPath)) {
|
|
8639
8750
|
try {
|
|
8640
8751
|
const { manifest } = decodeSkaileManifest(readFileSync(manifestPath, "utf8"));
|
|
@@ -8647,12 +8758,12 @@ function resolvePublisher(clonePath, url) {
|
|
|
8647
8758
|
return url.match(/github\.com[/:]([^/]+)\/[^/]+/)?.[1];
|
|
8648
8759
|
}
|
|
8649
8760
|
function resolveSkillName(clonePath, requested) {
|
|
8650
|
-
const skillsDir =
|
|
8651
|
-
if (existsSync(
|
|
8761
|
+
const skillsDir = path18__default.join(clonePath, "skills");
|
|
8762
|
+
if (existsSync(path18__default.join(skillsDir, requested, "SKILL.md"))) return requested;
|
|
8652
8763
|
if (!existsSync(skillsDir)) return requested;
|
|
8653
8764
|
for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
|
|
8654
8765
|
if (!entry.isDirectory()) continue;
|
|
8655
|
-
const md =
|
|
8766
|
+
const md = path18__default.join(skillsDir, entry.name, "SKILL.md");
|
|
8656
8767
|
if (!existsSync(md)) continue;
|
|
8657
8768
|
try {
|
|
8658
8769
|
const { data } = parseFrontmatter(readFileSync(md, "utf8"));
|
|
@@ -8684,7 +8795,7 @@ function makeOutdatedCommand() {
|
|
|
8684
8795
|
).action(async (filter, opts) => {
|
|
8685
8796
|
const am2 = new AssetManager({
|
|
8686
8797
|
registry: getKindRegistry(),
|
|
8687
|
-
projectDir:
|
|
8798
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
8688
8799
|
driverTarget: opts.target
|
|
8689
8800
|
});
|
|
8690
8801
|
const entries = await am2.outdated();
|
|
@@ -8714,6 +8825,12 @@ function makeOutdatedCommand() {
|
|
|
8714
8825
|
if (filtered.some((e) => e.problem !== void 0 && !e.manualFix)) {
|
|
8715
8826
|
logWarn(`Run ${S.cmd("skaile install")} to restore or re-lock the broken assets.`);
|
|
8716
8827
|
}
|
|
8828
|
+
for (const e of filtered) {
|
|
8829
|
+
if (e.problem !== void 0 || (await am2.gapsOf(outdatedRef(e))).length > 0) {
|
|
8830
|
+
process.exitCode = 1;
|
|
8831
|
+
break;
|
|
8832
|
+
}
|
|
8833
|
+
}
|
|
8717
8834
|
});
|
|
8718
8835
|
}
|
|
8719
8836
|
function makePatchCommand() {
|
|
@@ -8721,7 +8838,7 @@ function makePatchCommand() {
|
|
|
8721
8838
|
cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
8722
8839
|
const am2 = new AssetManager({
|
|
8723
8840
|
registry: getKindRegistry(),
|
|
8724
|
-
projectDir:
|
|
8841
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
8725
8842
|
});
|
|
8726
8843
|
try {
|
|
8727
8844
|
const dest = await am2.patch(ref);
|
|
@@ -8735,7 +8852,7 @@ function makePatchCommand() {
|
|
|
8735
8852
|
cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
8736
8853
|
const am2 = new AssetManager({
|
|
8737
8854
|
registry: getKindRegistry(),
|
|
8738
|
-
projectDir:
|
|
8855
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
8739
8856
|
});
|
|
8740
8857
|
try {
|
|
8741
8858
|
const patchFile = await am2.patchCommit(ref);
|
|
@@ -8749,7 +8866,7 @@ function makePatchCommand() {
|
|
|
8749
8866
|
cmd.command("submit <ref>").description("Apply patch to repo clone and prepare for PR").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
8750
8867
|
const am2 = new AssetManager({
|
|
8751
8868
|
registry: getKindRegistry(),
|
|
8752
|
-
projectDir:
|
|
8869
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
8753
8870
|
});
|
|
8754
8871
|
try {
|
|
8755
8872
|
await am2.patchSubmit(ref);
|
|
@@ -8765,7 +8882,7 @@ function makePatchCommand() {
|
|
|
8765
8882
|
cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
8766
8883
|
const am2 = new AssetManager({
|
|
8767
8884
|
registry: getKindRegistry(),
|
|
8768
|
-
projectDir:
|
|
8885
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
8769
8886
|
});
|
|
8770
8887
|
am2.patchRemove(ref);
|
|
8771
8888
|
logOk(`Patch removed for ${ref}`);
|
|
@@ -8784,7 +8901,7 @@ function action2(fn) {
|
|
|
8784
8901
|
};
|
|
8785
8902
|
}
|
|
8786
8903
|
async function reconcileAndReport(projectDir, plugins) {
|
|
8787
|
-
const { reconcilePlugins } = await import('../plugin-store-
|
|
8904
|
+
const { reconcilePlugins } = await import('../plugin-store-X7GPWGBG.js');
|
|
8788
8905
|
if (plugins.length === 0) {
|
|
8789
8906
|
logInfo("No plugins declared \u2014 nothing to reconcile.");
|
|
8790
8907
|
return;
|
|
@@ -8798,10 +8915,10 @@ async function reconcileAndReport(projectDir, plugins) {
|
|
|
8798
8915
|
}
|
|
8799
8916
|
}
|
|
8800
8917
|
async function runInstall2(spec, opts) {
|
|
8801
|
-
const projectDir =
|
|
8918
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
8802
8919
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
8803
|
-
const { specName } = await import('../plugin-store-
|
|
8804
|
-
const yamlPath =
|
|
8920
|
+
const { specName } = await import('../plugin-store-X7GPWGBG.js');
|
|
8921
|
+
const yamlPath = path18__default.join(projectDir, "skaile.yaml");
|
|
8805
8922
|
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
8806
8923
|
const replaced = editor.addPlugin(spec, specName);
|
|
8807
8924
|
editor.save();
|
|
@@ -8810,10 +8927,10 @@ async function runInstall2(spec, opts) {
|
|
|
8810
8927
|
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
8811
8928
|
}
|
|
8812
8929
|
async function runRemove(name, opts) {
|
|
8813
|
-
const projectDir =
|
|
8930
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
8814
8931
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
8815
|
-
const { specName } = await import('../plugin-store-
|
|
8816
|
-
const yamlPath =
|
|
8932
|
+
const { specName } = await import('../plugin-store-X7GPWGBG.js');
|
|
8933
|
+
const yamlPath = path18__default.join(projectDir, "skaile.yaml");
|
|
8817
8934
|
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
8818
8935
|
const removed = editor.removePlugin(name, specName);
|
|
8819
8936
|
if (!removed) {
|
|
@@ -8825,7 +8942,7 @@ async function runRemove(name, opts) {
|
|
|
8825
8942
|
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
8826
8943
|
}
|
|
8827
8944
|
async function runList(opts) {
|
|
8828
|
-
const projectDir =
|
|
8945
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
8829
8946
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
8830
8947
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
8831
8948
|
const declared = config.plugins ?? [];
|
|
@@ -8840,7 +8957,7 @@ async function runList(opts) {
|
|
|
8840
8957
|
const registry = createPluginRegistry();
|
|
8841
8958
|
if (declared.length > 0) {
|
|
8842
8959
|
try {
|
|
8843
|
-
const { loadPlugins } = await import('../plugin-store-
|
|
8960
|
+
const { loadPlugins } = await import('../plugin-store-X7GPWGBG.js');
|
|
8844
8961
|
const result = await loadPlugins(projectDir, declared, registry);
|
|
8845
8962
|
for (const f of result.failed) logWarn(f.error);
|
|
8846
8963
|
} catch (err2) {
|
|
@@ -9015,7 +9132,7 @@ function neededSources(config, lock) {
|
|
|
9015
9132
|
}
|
|
9016
9133
|
function sourcesWithSidecar(sources) {
|
|
9017
9134
|
const dir = getStoreManifestsDir();
|
|
9018
|
-
return sources.filter((s) => existsSync(
|
|
9135
|
+
return sources.filter((s) => existsSync(path18.join(dir, `${storeManifestSlug(s.url)}.yaml`))).map((s) => s.url);
|
|
9019
9136
|
}
|
|
9020
9137
|
function compact(obj) {
|
|
9021
9138
|
const out = {};
|
|
@@ -9107,8 +9224,8 @@ function redactSecrets(preset, findings) {
|
|
|
9107
9224
|
}
|
|
9108
9225
|
return { preset: next, keys };
|
|
9109
9226
|
}
|
|
9110
|
-
function placeholderKey(itemId,
|
|
9111
|
-
return `${itemId}_${
|
|
9227
|
+
function placeholderKey(itemId, path43) {
|
|
9228
|
+
return `${itemId}_${path43}`.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
|
|
9112
9229
|
}
|
|
9113
9230
|
function setAtPath(root, segments, value) {
|
|
9114
9231
|
let node = root;
|
|
@@ -9131,7 +9248,7 @@ function makePresetCommand() {
|
|
|
9131
9248
|
cmd.command("init [name]").description("Scaffold a new .preset.yaml file").option("--dir <path>", "Output directory", process.cwd()).action(async (name, opts) => {
|
|
9132
9249
|
const presetName = name ?? "my-preset";
|
|
9133
9250
|
const filename = `${presetName}.preset.yaml`;
|
|
9134
|
-
const outPath =
|
|
9251
|
+
const outPath = path18__default.join(path18__default.resolve(opts.dir), filename);
|
|
9135
9252
|
if (existsSync(outPath)) {
|
|
9136
9253
|
logErr(`File already exists: ${outPath}`);
|
|
9137
9254
|
logInfo("Choose a different name or remove the existing file.");
|
|
@@ -9164,7 +9281,7 @@ function makePresetCommand() {
|
|
|
9164
9281
|
return cmd;
|
|
9165
9282
|
}
|
|
9166
9283
|
async function runPresetExport(name, opts) {
|
|
9167
|
-
const projectDir =
|
|
9284
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9168
9285
|
const file = loadSkWorkspaceConfig(projectDir);
|
|
9169
9286
|
if (!file) {
|
|
9170
9287
|
logErr(`No skaile.yaml found in ${projectDir}`);
|
|
@@ -9174,7 +9291,7 @@ async function runPresetExport(name, opts) {
|
|
|
9174
9291
|
const presetName = name ?? file.config.name ?? "my-preset";
|
|
9175
9292
|
let lock = null;
|
|
9176
9293
|
try {
|
|
9177
|
-
lock = readLock(
|
|
9294
|
+
lock = readLock(path18__default.join(projectDir, "skaile.lock.yaml"));
|
|
9178
9295
|
} catch {
|
|
9179
9296
|
lock = null;
|
|
9180
9297
|
}
|
|
@@ -9215,7 +9332,7 @@ async function runPresetExport(name, opts) {
|
|
|
9215
9332
|
const contents = header ? `${header}
|
|
9216
9333
|
${body}` : body;
|
|
9217
9334
|
if (opts.out && opts.dir !== process.cwd()) logWarn("--dir is ignored when --out is set.");
|
|
9218
|
-
const outPath = opts.out ?
|
|
9335
|
+
const outPath = opts.out ? path18__default.resolve(opts.out) : path18__default.join(path18__default.resolve(opts.dir), `${presetName}.preset.yaml`);
|
|
9219
9336
|
if (existsSync(outPath) && !opts.force) {
|
|
9220
9337
|
logErr(`File already exists: ${outPath}`);
|
|
9221
9338
|
logInfo("Pass --force to overwrite, or choose a different --out/--dir.");
|
|
@@ -9227,7 +9344,7 @@ ${body}` : body;
|
|
|
9227
9344
|
logErr(`Failed to write ${outPath}: ${e.message}`);
|
|
9228
9345
|
process.exit(1);
|
|
9229
9346
|
}
|
|
9230
|
-
logOk(`Exported ${S.brand(
|
|
9347
|
+
logOk(`Exported ${S.brand(path18__default.basename(outPath))}`);
|
|
9231
9348
|
logInfo(`Path: ${outPath}`);
|
|
9232
9349
|
if (unresolved.length > 0) {
|
|
9233
9350
|
console.error(S.err("This file is NOT safe to share."));
|
|
@@ -9268,13 +9385,13 @@ function collectInput(value, acc) {
|
|
|
9268
9385
|
return acc;
|
|
9269
9386
|
}
|
|
9270
9387
|
async function runPresetApply(filePath, opts) {
|
|
9271
|
-
const projectDir =
|
|
9388
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9272
9389
|
const file = loadSkWorkspaceConfig(projectDir);
|
|
9273
9390
|
if (!file) {
|
|
9274
9391
|
logErr("No skaile.yaml \u2014 run `skaile init` first");
|
|
9275
9392
|
process.exit(1);
|
|
9276
9393
|
}
|
|
9277
|
-
const resolved =
|
|
9394
|
+
const resolved = path18__default.resolve(filePath);
|
|
9278
9395
|
if (!existsSync(resolved)) {
|
|
9279
9396
|
logErr(`File not found: ${resolved}`);
|
|
9280
9397
|
process.exit(1);
|
|
@@ -9490,7 +9607,7 @@ async function reportNestedPresetRefs(preset) {
|
|
|
9490
9607
|
}
|
|
9491
9608
|
async function checkPresetCycles(preset, resolved) {
|
|
9492
9609
|
const { detectCycles } = await import('../discovery/index.js');
|
|
9493
|
-
const presetRef =
|
|
9610
|
+
const presetRef = path18__default.basename(resolved, ".preset.yaml");
|
|
9494
9611
|
const edges = [];
|
|
9495
9612
|
for (const item of preset.items) {
|
|
9496
9613
|
if (item.ref) {
|
|
@@ -9542,7 +9659,7 @@ function printPresetSummary(preset, placeholderCount, hasWarnings) {
|
|
|
9542
9659
|
}
|
|
9543
9660
|
}
|
|
9544
9661
|
async function runPresetValidate(filePath) {
|
|
9545
|
-
const resolved =
|
|
9662
|
+
const resolved = path18__default.resolve(filePath);
|
|
9546
9663
|
const preset = await loadPresetForValidation(resolved);
|
|
9547
9664
|
await reportNestedPresetRefs(preset);
|
|
9548
9665
|
await checkPresetCycles(preset, resolved);
|
|
@@ -9592,11 +9709,11 @@ items:
|
|
|
9592
9709
|
}
|
|
9593
9710
|
function makeRebuildCommand() {
|
|
9594
9711
|
return new Command("rebuild").description("Re-snapshot inline-snapshot composition items and bump prompt version").argument("[agent]", "Agent name or path (defaults to current project agent)").option("--project-dir <dir>", "Project directory", process.cwd()).action(async (agentArg, opts) => {
|
|
9595
|
-
const projectDir =
|
|
9712
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9596
9713
|
let agentDir;
|
|
9597
9714
|
if (agentArg) {
|
|
9598
9715
|
if (agentArg.includes("/") || agentArg.includes("\\")) {
|
|
9599
|
-
agentDir =
|
|
9716
|
+
agentDir = path18__default.resolve(projectDir, agentArg);
|
|
9600
9717
|
} else {
|
|
9601
9718
|
let resolved;
|
|
9602
9719
|
try {
|
|
@@ -9605,7 +9722,7 @@ function makeRebuildCommand() {
|
|
|
9605
9722
|
if (!(err2 instanceof AgentRefResolutionError)) throw err2;
|
|
9606
9723
|
logWarn(`${err2.message} \u2014 using "${agentArg}"`);
|
|
9607
9724
|
}
|
|
9608
|
-
agentDir = resolved ??
|
|
9725
|
+
agentDir = resolved ?? path18__default.resolve(projectDir, agentArg);
|
|
9609
9726
|
}
|
|
9610
9727
|
} else {
|
|
9611
9728
|
let resolved;
|
|
@@ -9675,9 +9792,9 @@ Try a different harness with \`--driver claude-sdk\`.`;
|
|
|
9675
9792
|
// cli/src/commands/run.ts
|
|
9676
9793
|
function resolveSingleShotAgentDir(projectDir, agentDefinition) {
|
|
9677
9794
|
if (!agentDefinition) return resolveAgentDir(projectDir);
|
|
9678
|
-
const asPath = agentDefinition.endsWith("agent.yaml") ?
|
|
9795
|
+
const asPath = agentDefinition.endsWith("agent.yaml") ? path18__default.dirname(path18__default.resolve(projectDir, agentDefinition)) : agentDefinition;
|
|
9679
9796
|
const dir = resolveAgentDefinitionDir(projectDir, asPath);
|
|
9680
|
-
if (!dir || !
|
|
9797
|
+
if (!dir || !fs8__default.existsSync(path18__default.join(dir, "agent.yaml"))) {
|
|
9681
9798
|
throw new Error(
|
|
9682
9799
|
`--agent-definition "${agentDefinition}" does not resolve to an agent directory with agent.yaml${dir ? ` (looked in ${dir})` : ""}`
|
|
9683
9800
|
);
|
|
@@ -9776,7 +9893,7 @@ function makeRunCommand() {
|
|
|
9776
9893
|
"--agent-definition <ref|path>",
|
|
9777
9894
|
"Agent asset for this one invocation (agent:@pub/name, ai-assets://\u2026, or a directory with agent.yaml); single-shot prompts only"
|
|
9778
9895
|
).option("--skill <name>", "Skill name (for single-shot mode)").action(async (positional, opts) => {
|
|
9779
|
-
const projectDir =
|
|
9896
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9780
9897
|
const cliDriver = opts.driver;
|
|
9781
9898
|
const dryRun = opts.dryRun ?? false;
|
|
9782
9899
|
const agentDefinition = opts.agentDefinition?.trim() || void 0;
|
|
@@ -9895,7 +10012,7 @@ function makeRunCommand() {
|
|
|
9895
10012
|
}
|
|
9896
10013
|
function makeResumeCommand() {
|
|
9897
10014
|
const cmd = new Command("resume").description("Resume current session").option("--project-dir <path>", "Project directory", process.cwd()).option("--session <run-id>", "Target session by runId").option("--dry-run", "Print plan without executing").action(async (opts) => {
|
|
9898
|
-
const projectDir =
|
|
10015
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9899
10016
|
const sessionId = opts.session;
|
|
9900
10017
|
const dryRun = opts.dryRun ?? false;
|
|
9901
10018
|
const session = sessionId ? await loadSessionById(projectDir, sessionId) : await loadSession(projectDir);
|
|
@@ -9922,7 +10039,7 @@ function makeResumeCommand() {
|
|
|
9922
10039
|
}
|
|
9923
10040
|
function makeStatusCommand() {
|
|
9924
10041
|
return new Command("status").description("Show current session state").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
9925
|
-
const projectDir =
|
|
10042
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9926
10043
|
const session = await loadSession(projectDir);
|
|
9927
10044
|
if (!session) {
|
|
9928
10045
|
logInfo("No active session.");
|
|
@@ -9947,7 +10064,7 @@ function makeStatusCommand() {
|
|
|
9947
10064
|
}
|
|
9948
10065
|
function makeClearCommand() {
|
|
9949
10066
|
return new Command("clear").description("Unset current session pointer").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
9950
|
-
const projectDir =
|
|
10067
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
9951
10068
|
await clearSession(projectDir);
|
|
9952
10069
|
logOk("Session cleared.");
|
|
9953
10070
|
});
|
|
@@ -9957,7 +10074,7 @@ function makeReplCommand() {
|
|
|
9957
10074
|
const { findWorkspaceRoot } = await import('../core/index.js');
|
|
9958
10075
|
const { startRepl } = await import('../tui/index.js');
|
|
9959
10076
|
const os2 = await import('os');
|
|
9960
|
-
const userCwd =
|
|
10077
|
+
const userCwd = path18__default.resolve(opts.projectDir ?? process.cwd());
|
|
9961
10078
|
const workspaceRoot = findWorkspaceRoot(userCwd);
|
|
9962
10079
|
let projectDir;
|
|
9963
10080
|
let agentCwd;
|
|
@@ -9979,13 +10096,13 @@ function makeReplCommand() {
|
|
|
9979
10096
|
p4.cancel("Cancelled.");
|
|
9980
10097
|
process.exit(0);
|
|
9981
10098
|
}
|
|
9982
|
-
const tmpDir =
|
|
10099
|
+
const tmpDir = fs8__default.mkdtempSync(path18__default.join(os2.tmpdir(), "skaile-repl-"));
|
|
9983
10100
|
projectDir = tmpDir;
|
|
9984
10101
|
agentCwd = userCwd;
|
|
9985
10102
|
logOk(`Temporary workspace: ${S.cmd(tmpDir)}`);
|
|
9986
10103
|
if (!driverOverride) {
|
|
9987
|
-
const claudeDir =
|
|
9988
|
-
if (
|
|
10104
|
+
const claudeDir = path18__default.join(os2.homedir(), ".claude");
|
|
10105
|
+
if (fs8__default.existsSync(claudeDir)) {
|
|
9989
10106
|
driverOverride = "claude-sdk";
|
|
9990
10107
|
logInfo(`Detected ${S.cmd("~/.claude")} \u2192 using ${S.cmd("claude-sdk")} harness`);
|
|
9991
10108
|
} else {
|
|
@@ -10057,12 +10174,12 @@ function makeServeCommand() {
|
|
|
10057
10174
|
);
|
|
10058
10175
|
}
|
|
10059
10176
|
async function ensurePluginsLoadedForServe(projectDir) {
|
|
10060
|
-
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-
|
|
10177
|
+
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-X6URBGSF.js');
|
|
10061
10178
|
try {
|
|
10062
10179
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
10063
10180
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
10064
10181
|
if (!config.plugins || config.plugins.length === 0) return;
|
|
10065
|
-
const { ensurePluginsLoaded } = await import('../plugin-store-
|
|
10182
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-X7GPWGBG.js');
|
|
10066
10183
|
const { pluginRegistry } = await import('../plugin-registry/index.js');
|
|
10067
10184
|
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
10068
10185
|
if (result.loaded.length > 0) {
|
|
@@ -10076,21 +10193,21 @@ async function ensurePluginsLoadedForServe(projectDir) {
|
|
|
10076
10193
|
}
|
|
10077
10194
|
}
|
|
10078
10195
|
async function runCompileTest(opts) {
|
|
10079
|
-
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-
|
|
10196
|
+
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-X6URBGSF.js');
|
|
10080
10197
|
const { tmpdir } = await import('os');
|
|
10081
|
-
const { dirname: dirname3, join:
|
|
10198
|
+
const { dirname: dirname3, join: join6, resolve: resolve5 } = await import('path');
|
|
10082
10199
|
const { fileURLToPath: fileURLToPath2 } = await import('url');
|
|
10083
10200
|
const { unlinkSync, existsSync: existsSync18 } = await import('fs');
|
|
10084
10201
|
const { spawn } = await import('child_process');
|
|
10085
10202
|
const { portableSpawnSync: portableSpawnSync2 } = await import('../core/index.js');
|
|
10086
|
-
const { MONOREPO_ROOT } = await import('../paths-
|
|
10203
|
+
const { MONOREPO_ROOT } = await import('../paths-BVO56A25.js');
|
|
10087
10204
|
if (MONOREPO_ROOT === null) {
|
|
10088
10205
|
logErr2("--compile-test is only available inside the skaile-dev workspace.");
|
|
10089
10206
|
logInfo2("Run it from a checkout of skaile-ai/skaile-dev (the monorepo shell).");
|
|
10090
10207
|
process.exitCode = 2;
|
|
10091
10208
|
return;
|
|
10092
10209
|
}
|
|
10093
|
-
const outfile =
|
|
10210
|
+
const outfile = join6(tmpdir(), `skaile-compile-test-${Date.now()}`);
|
|
10094
10211
|
const __thisFile = fileURLToPath2(import.meta.url);
|
|
10095
10212
|
const entryPoint = resolve5(dirname3(__thisFile), "..", "index.ts");
|
|
10096
10213
|
logInfo2(`Building compiled binary...`);
|
|
@@ -10566,7 +10683,7 @@ function resolveMode2(opts) {
|
|
|
10566
10683
|
if (opts.forceLocal && opts.forceRemote) {
|
|
10567
10684
|
throw new Error("Cannot use both --local and --remote");
|
|
10568
10685
|
}
|
|
10569
|
-
const startDir =
|
|
10686
|
+
const startDir = path18__default.resolve(opts.projectDir ?? process.cwd());
|
|
10570
10687
|
const localDb = findLogsDb(startDir);
|
|
10571
10688
|
if (opts.forceLocal) {
|
|
10572
10689
|
if (!localDb) {
|
|
@@ -10599,14 +10716,14 @@ function resolveMode2(opts) {
|
|
|
10599
10716
|
function findLogsDb(startDir) {
|
|
10600
10717
|
let dir = startDir;
|
|
10601
10718
|
for (let i = 0; i < MAX_WALK_LEVELS; i++) {
|
|
10602
|
-
const candidate =
|
|
10719
|
+
const candidate = path18__default.join(dir, ".skaile", "logs.db");
|
|
10603
10720
|
if (existsSync(candidate)) {
|
|
10604
10721
|
try {
|
|
10605
10722
|
if (statSync(candidate).isFile()) return candidate;
|
|
10606
10723
|
} catch {
|
|
10607
10724
|
}
|
|
10608
10725
|
}
|
|
10609
|
-
const parent =
|
|
10726
|
+
const parent = path18__default.dirname(dir);
|
|
10610
10727
|
if (parent === dir) return void 0;
|
|
10611
10728
|
dir = parent;
|
|
10612
10729
|
}
|
|
@@ -10781,7 +10898,7 @@ function parsePositiveInt(value, flag) {
|
|
|
10781
10898
|
function makeSessionCommand() {
|
|
10782
10899
|
const cmd = new Command("session").description("Manage sessions");
|
|
10783
10900
|
cmd.command("list").description("List all sessions for a project").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
10784
|
-
const projectDir =
|
|
10901
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
10785
10902
|
const sessions = await listSessions(projectDir);
|
|
10786
10903
|
const current = await loadSession(projectDir);
|
|
10787
10904
|
if (sessions.length === 0) {
|
|
@@ -10809,7 +10926,7 @@ function makeSessionCommand() {
|
|
|
10809
10926
|
console.log();
|
|
10810
10927
|
});
|
|
10811
10928
|
cmd.command("show <run-id>").description("Show a specific session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10812
|
-
const projectDir =
|
|
10929
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
10813
10930
|
const session = await loadSessionById(projectDir, runId);
|
|
10814
10931
|
if (!session) {
|
|
10815
10932
|
logErr(`Session not found: ${runId}`);
|
|
@@ -10818,7 +10935,7 @@ function makeSessionCommand() {
|
|
|
10818
10935
|
console.log(JSON.stringify(session, null, 2));
|
|
10819
10936
|
});
|
|
10820
10937
|
cmd.command("switch <run-id>").description("Switch the current session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10821
|
-
const projectDir =
|
|
10938
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
10822
10939
|
if (!await loadSessionById(projectDir, runId)) {
|
|
10823
10940
|
logErr(`Session not found: ${runId}`);
|
|
10824
10941
|
process.exit(1);
|
|
@@ -10827,7 +10944,7 @@ function makeSessionCommand() {
|
|
|
10827
10944
|
logOk(`Switched to session: ${S.dim(runId.slice(0, 8))}`);
|
|
10828
10945
|
});
|
|
10829
10946
|
cmd.command("delete <run-id>").description("Delete a session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10830
|
-
const projectDir =
|
|
10947
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
10831
10948
|
if (!await loadSessionById(projectDir, runId)) {
|
|
10832
10949
|
logErr(`Session not found: ${runId}`);
|
|
10833
10950
|
process.exit(1);
|
|
@@ -10885,12 +11002,12 @@ function showOverview(am2) {
|
|
|
10885
11002
|
}
|
|
10886
11003
|
async function showAsset(am2, kind, name) {
|
|
10887
11004
|
const entry = await am2.info(`${kind}:${name}`);
|
|
10888
|
-
if (entry?.source &&
|
|
11005
|
+
if (entry?.source && fs8__default.existsSync(entry.source)) {
|
|
10889
11006
|
console.log();
|
|
10890
11007
|
console.log(` ${kindColor(entry.kind)} ${S.heading(entry.name)}`);
|
|
10891
11008
|
console.log(` ${S.rule(40)}`);
|
|
10892
11009
|
console.log();
|
|
10893
|
-
console.log(
|
|
11010
|
+
console.log(fs8__default.readFileSync(entry.source, "utf-8"));
|
|
10894
11011
|
return;
|
|
10895
11012
|
}
|
|
10896
11013
|
logErr(`Asset not found: ${kind}:${name}`);
|
|
@@ -10900,7 +11017,7 @@ function makeShowCommand() {
|
|
|
10900
11017
|
return new Command("show").description("Show deployed assets overview, or print asset content").argument("[kind]", "Asset kind (skill, agent, prompt, flow, preset, contract)").argument("[name]", "Asset name").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", `Agent framework (${TARGET_DEFAULT_HINT})`).action(async (kind, name, opts) => {
|
|
10901
11018
|
const am2 = new AssetManager({
|
|
10902
11019
|
registry: getKindRegistry(),
|
|
10903
|
-
projectDir:
|
|
11020
|
+
projectDir: path18__default.resolve(opts.projectDir),
|
|
10904
11021
|
driverTarget: opts.target
|
|
10905
11022
|
});
|
|
10906
11023
|
if (!kind) {
|
|
@@ -10963,14 +11080,14 @@ function makeStoreCommand() {
|
|
|
10963
11080
|
});
|
|
10964
11081
|
store.command("mode <auto|local|remote>").description("Set the catalog resolution mode (not yet wired)").action((_mode) => {
|
|
10965
11082
|
logErr(
|
|
10966
|
-
`\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${
|
|
11083
|
+
`\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${path18__default.join(globalSkaileDir(), "store", "config.yaml")}.`
|
|
10967
11084
|
);
|
|
10968
11085
|
process.exit(2);
|
|
10969
11086
|
});
|
|
10970
11087
|
store.command("search <query>").description("Search the AI Asset Store catalog by name, description, or publisher").option("--kind <kind>", "Filter by asset kind (skill, agent, prompt, flow, \u2026)").option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (query, opts) => {
|
|
10971
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-
|
|
11088
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-4QSUORI6.js');
|
|
10972
11089
|
try {
|
|
10973
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
11090
|
+
const remote = await openCatalogSource2({ projectDir: path18__default.resolve(opts.projectDir) });
|
|
10974
11091
|
const assets = await remote.listAssets(opts.kind ? { kind: opts.kind } : {});
|
|
10975
11092
|
const results = filterCatalogAssets(assets, query);
|
|
10976
11093
|
if (results.length === 0) {
|
|
@@ -10996,10 +11113,10 @@ function makeStoreCommand() {
|
|
|
10996
11113
|
}
|
|
10997
11114
|
});
|
|
10998
11115
|
store.command("show <ref>").description("Show a store asset's details + provenance (source, files, integrity)").option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (ref, opts) => {
|
|
10999
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-
|
|
11000
|
-
const { supportsInstallManifest } = await import('../project-
|
|
11116
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-4QSUORI6.js');
|
|
11117
|
+
const { supportsInstallManifest } = await import('../project-PAXP46RD.js');
|
|
11001
11118
|
try {
|
|
11002
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
11119
|
+
const remote = await openCatalogSource2({ projectDir: path18__default.resolve(opts.projectDir) });
|
|
11003
11120
|
const asset = await remote.resolve(ref);
|
|
11004
11121
|
if (!asset) {
|
|
11005
11122
|
logErr(`Not found in store: ${ref} (try a full ref, e.g. skill:@publisher/name#version)`);
|
|
@@ -11124,7 +11241,7 @@ function makeTreeCommand() {
|
|
|
11124
11241
|
return new Command("tree").description("Show full dependency tree").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
11125
11242
|
const am2 = new AssetManager({
|
|
11126
11243
|
registry: getKindRegistry(),
|
|
11127
|
-
projectDir:
|
|
11244
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
11128
11245
|
});
|
|
11129
11246
|
const root = await am2.tree();
|
|
11130
11247
|
if (root.children.length === 0) {
|
|
@@ -11146,13 +11263,19 @@ function makeTreeCommand() {
|
|
|
11146
11263
|
});
|
|
11147
11264
|
}
|
|
11148
11265
|
function makeUpdateCommand() {
|
|
11149
|
-
return new Command("update").description("Refresh the Catalog cache and re-deploy outdated assets in the current project").argument(
|
|
11150
|
-
|
|
11266
|
+
return new Command("update").description("Refresh the Catalog cache and re-deploy outdated assets in the current project").argument(
|
|
11267
|
+
"[name]",
|
|
11268
|
+
"Update only this declared asset (kind:@publisher/name, kind:name or name); exits 1 when none matches"
|
|
11269
|
+
).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(
|
|
11270
|
+
async (name, opts) => {
|
|
11271
|
+
const projectDir = path18__default.resolve(opts.projectDir);
|
|
11272
|
+
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
|
|
11273
|
+
const target = name !== void 0 && !opts.catalogOnly ? await resolveUpdateTarget(am2, name) : void 0;
|
|
11151
11274
|
if (opts.catalog !== false) {
|
|
11152
11275
|
const catalogSpinner = createSpinner();
|
|
11153
11276
|
catalogSpinner.start("Refreshing catalog cache");
|
|
11154
11277
|
try {
|
|
11155
|
-
const remote = await openCatalogSource({ projectDir:
|
|
11278
|
+
const remote = await openCatalogSource({ projectDir: path18__default.resolve(opts.projectDir) });
|
|
11156
11279
|
const result2 = await remote.refresh();
|
|
11157
11280
|
catalogSpinner.stop(
|
|
11158
11281
|
`Catalog refreshed: ${S.heading(String(result2.assetsCached))} assets cached`
|
|
@@ -11169,7 +11292,6 @@ function makeUpdateCommand() {
|
|
|
11169
11292
|
}
|
|
11170
11293
|
}
|
|
11171
11294
|
if (opts.catalogOnly) return;
|
|
11172
|
-
const projectDir = path23__default.resolve(opts.projectDir);
|
|
11173
11295
|
if (await shouldSyncSources(opts)) {
|
|
11174
11296
|
const syncSpinner = createSpinner();
|
|
11175
11297
|
syncSpinner.start("Syncing sources");
|
|
@@ -11178,13 +11300,16 @@ function makeUpdateCommand() {
|
|
|
11178
11300
|
total === 0 ? "No sources to sync." : `Synced ${S.heading(`${synced}/${total}`)} source(s)` + (failed ? ` (${failed} failed)` : "")
|
|
11179
11301
|
);
|
|
11180
11302
|
if (failed > 0) process.exitCode = 1;
|
|
11303
|
+
} else {
|
|
11304
|
+
for (const slug of divergedSourceClones(projectDir)) {
|
|
11305
|
+
logErr(`${slug}: git pull failed: Not possible to fast-forward, aborting.`);
|
|
11306
|
+
process.exitCode = 1;
|
|
11307
|
+
}
|
|
11308
|
+
}
|
|
11309
|
+
if (target) {
|
|
11310
|
+
await updateOne(am2, projectDir, target);
|
|
11311
|
+
return;
|
|
11181
11312
|
}
|
|
11182
|
-
const warnings = deferredWarnings();
|
|
11183
|
-
const am2 = new AssetManager({
|
|
11184
|
-
registry: getKindRegistry(),
|
|
11185
|
-
projectDir,
|
|
11186
|
-
onLibraryCollision: warnings.push
|
|
11187
|
-
});
|
|
11188
11313
|
const spinner = createSpinner();
|
|
11189
11314
|
spinner.start("Re-deploying assets");
|
|
11190
11315
|
let result;
|
|
@@ -11192,18 +11317,17 @@ function makeUpdateCommand() {
|
|
|
11192
11317
|
result = await am2.install();
|
|
11193
11318
|
} catch (err2) {
|
|
11194
11319
|
spinner.stop("Failed");
|
|
11195
|
-
warnings.flush();
|
|
11196
11320
|
logErr(String(err2));
|
|
11197
11321
|
process.exit(1);
|
|
11198
11322
|
}
|
|
11199
11323
|
spinner.stop("Done");
|
|
11200
|
-
warnings.flush();
|
|
11201
11324
|
if (result.deployed.length > 0) {
|
|
11202
11325
|
for (const d of result.deployed) logOk(`Updated ${d}`);
|
|
11203
11326
|
}
|
|
11204
11327
|
for (const r of result.removed) logWarn(`Removed: ${r}`);
|
|
11328
|
+
reportReplaced(result.replaced);
|
|
11205
11329
|
reportRelocked(result.relocked);
|
|
11206
|
-
const changed = result.deployed.length > 0 || result.removed.length > 0 || !!result.relocked?.length;
|
|
11330
|
+
const changed = result.deployed.length > 0 || result.removed.length > 0 || !!result.replaced?.length || !!result.relocked?.length;
|
|
11207
11331
|
if (result.lockWritten && changed) {
|
|
11208
11332
|
logInfo(`Lock file written: ${S.dim("skaile.lock.yaml")}`);
|
|
11209
11333
|
}
|
|
@@ -11216,6 +11340,73 @@ function makeUpdateCommand() {
|
|
|
11216
11340
|
}
|
|
11217
11341
|
);
|
|
11218
11342
|
}
|
|
11343
|
+
function declaredMatches(d, arg) {
|
|
11344
|
+
const declared = parseAssetRefLoose(d.ref);
|
|
11345
|
+
if (!declared) return false;
|
|
11346
|
+
const spec = arg.trim().replace(/#.*$/, "");
|
|
11347
|
+
const colon = spec.indexOf(":");
|
|
11348
|
+
const kindRaw = colon >= 0 ? spec.slice(0, colon) : void 0;
|
|
11349
|
+
const rest = colon >= 0 ? spec.slice(colon + 1) : spec;
|
|
11350
|
+
const kind = kindRaw === "mcp" ? "mcp-server" : kindRaw;
|
|
11351
|
+
let publisher;
|
|
11352
|
+
let name = rest;
|
|
11353
|
+
if (rest.startsWith("@")) {
|
|
11354
|
+
const slash = rest.indexOf("/");
|
|
11355
|
+
publisher = rest.slice(1, slash < 0 ? void 0 : slash);
|
|
11356
|
+
name = slash < 0 ? "" : rest.slice(slash + 1);
|
|
11357
|
+
}
|
|
11358
|
+
return (kind === void 0 || kind === declared.kind) && (publisher === void 0 || publisher === declared.publisher?.replace(/^@/, "")) && name === declared.name;
|
|
11359
|
+
}
|
|
11360
|
+
async function resolveUpdateTarget(am2, name) {
|
|
11361
|
+
let declared;
|
|
11362
|
+
try {
|
|
11363
|
+
declared = (await am2.listDeclared()).filter((d) => d.state !== "invalid");
|
|
11364
|
+
} catch (err2) {
|
|
11365
|
+
if (err2 instanceof MissingManifestError) {
|
|
11366
|
+
logErr("No skaile.yaml found in this directory. Run `skaile init` first.");
|
|
11367
|
+
} else {
|
|
11368
|
+
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
11369
|
+
}
|
|
11370
|
+
process.exit(1);
|
|
11371
|
+
}
|
|
11372
|
+
const hits = declared.filter((d) => declaredMatches(d, name));
|
|
11373
|
+
if (hits.length === 1) return hits[0];
|
|
11374
|
+
if (hits.length > 1) {
|
|
11375
|
+
logErr(`"${name}" matches ${hits.length} declared assets; name the one you mean:`);
|
|
11376
|
+
for (const h of hits) console.error(` ${h.ref}`);
|
|
11377
|
+
process.exit(1);
|
|
11378
|
+
}
|
|
11379
|
+
logErr(`No declared asset matches "${name}".`);
|
|
11380
|
+
if (declared.length > 0) logInfo(`Declared: ${declared.map((d) => d.ref).join(", ")}`);
|
|
11381
|
+
process.exit(1);
|
|
11382
|
+
}
|
|
11383
|
+
function readText2(file) {
|
|
11384
|
+
try {
|
|
11385
|
+
return readFileSync(file, "utf8");
|
|
11386
|
+
} catch {
|
|
11387
|
+
return "";
|
|
11388
|
+
}
|
|
11389
|
+
}
|
|
11390
|
+
async function updateOne(am2, projectDir, target) {
|
|
11391
|
+
const lockPath = path18__default.join(projectDir, "skaile.lock.yaml");
|
|
11392
|
+
const before = readText2(lockPath);
|
|
11393
|
+
const spinner = createSpinner();
|
|
11394
|
+
spinner.start(`Updating ${target.ref}`);
|
|
11395
|
+
let deployed;
|
|
11396
|
+
try {
|
|
11397
|
+
deployed = await am2.add(target.ref);
|
|
11398
|
+
} catch (err2) {
|
|
11399
|
+
spinner.stop("Failed");
|
|
11400
|
+
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
11401
|
+
process.exitCode = 1;
|
|
11402
|
+
return;
|
|
11403
|
+
}
|
|
11404
|
+
spinner.stop("Done");
|
|
11405
|
+
for (const d of deployed) logOk(`Updated ${d}`);
|
|
11406
|
+
if (deployed.length > 0) return;
|
|
11407
|
+
if (readText2(lockPath) !== before) logInfo(`Re-locked ${target.ref}`);
|
|
11408
|
+
else logInfo(`${target.ref} is up to date.`);
|
|
11409
|
+
}
|
|
11219
11410
|
async function shouldSyncSources(opts) {
|
|
11220
11411
|
if (opts.sync === false) return false;
|
|
11221
11412
|
if (opts.yes || !process.stdin.isTTY) return true;
|
|
@@ -11324,7 +11515,7 @@ function makeWhyCommand() {
|
|
|
11324
11515
|
return new Command("why").description("Show why an asset is installed (dependency chain)").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
11325
11516
|
const am2 = new AssetManager({
|
|
11326
11517
|
registry: getKindRegistry(),
|
|
11327
|
-
projectDir:
|
|
11518
|
+
projectDir: path18__default.resolve(opts.projectDir)
|
|
11328
11519
|
});
|
|
11329
11520
|
const chain = await am2.why(ref);
|
|
11330
11521
|
if (chain.length === 0) {
|
|
@@ -11333,9 +11524,11 @@ function makeWhyCommand() {
|
|
|
11333
11524
|
declared = await am2.listDeclared();
|
|
11334
11525
|
} catch {
|
|
11335
11526
|
logErr(`${ref} not found in lock file. Run \`skaile install\` first.`);
|
|
11527
|
+
process.exitCode = 1;
|
|
11336
11528
|
return;
|
|
11337
11529
|
}
|
|
11338
11530
|
logErr(whyEmptyMessage(ref, declared));
|
|
11531
|
+
process.exitCode = 1;
|
|
11339
11532
|
return;
|
|
11340
11533
|
}
|
|
11341
11534
|
console.log();
|
|
@@ -11359,7 +11552,7 @@ function makeWhyCommand() {
|
|
|
11359
11552
|
var _defaultFormatHelp = Help.prototype.formatHelp;
|
|
11360
11553
|
var pkg = JSON.parse(
|
|
11361
11554
|
readFileSync(
|
|
11362
|
-
|
|
11555
|
+
path18__default.resolve(path18__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
|
|
11363
11556
|
"utf-8"
|
|
11364
11557
|
)
|
|
11365
11558
|
);
|
|
@@ -11370,7 +11563,7 @@ for (const key of [
|
|
|
11370
11563
|
"SKAILE_CACHE_DIR"
|
|
11371
11564
|
]) {
|
|
11372
11565
|
const value = process.env[key];
|
|
11373
|
-
if (value) process.env[key] =
|
|
11566
|
+
if (value) process.env[key] = path18__default.resolve(value);
|
|
11374
11567
|
}
|
|
11375
11568
|
var program = new Command("skaile").description("AI asset manager").version(pkg.version, "-v, --version", "Show the skaile CLI version").enablePositionalOptions().configureHelp({
|
|
11376
11569
|
formatHelp(cmd, helper) {
|
|
@@ -11490,7 +11683,7 @@ program.command("init [project-dir]").description("Initialize a project director
|
|
|
11490
11683
|
(projectDir, opts) => runInit(projectDir, opts)
|
|
11491
11684
|
);
|
|
11492
11685
|
async function runInit(projectDir, opts) {
|
|
11493
|
-
const { mkdirSync: mkdirSync5, writeFileSync:
|
|
11686
|
+
const { mkdirSync: mkdirSync5, writeFileSync: writeFileSync6 } = await import('fs');
|
|
11494
11687
|
const { stringify: stringify2 } = await import('yaml');
|
|
11495
11688
|
const { DRIVER_TARGETS, SUPPORTED_DRIVER_TARGETS: SUPPORTED_DRIVER_TARGETS2 } = await import('../core/index.js');
|
|
11496
11689
|
const harness = opts.harness;
|
|
@@ -11499,31 +11692,31 @@ async function runInit(projectDir, opts) {
|
|
|
11499
11692
|
process.exitCode = 1;
|
|
11500
11693
|
return;
|
|
11501
11694
|
}
|
|
11502
|
-
const resolved =
|
|
11503
|
-
const projectName =
|
|
11695
|
+
const resolved = path18__default.resolve(projectDir ?? ".");
|
|
11696
|
+
const projectName = path18__default.basename(resolved);
|
|
11504
11697
|
const created = [];
|
|
11505
11698
|
const { existsSync: existsSync18 } = await import('fs');
|
|
11506
11699
|
if (!existsSync18(resolved)) {
|
|
11507
11700
|
mkdirSync5(resolved, { recursive: true });
|
|
11508
11701
|
created.push(".");
|
|
11509
11702
|
}
|
|
11510
|
-
const skaileDir =
|
|
11703
|
+
const skaileDir = path18__default.join(resolved, ".skaile");
|
|
11511
11704
|
if (!existsSync18(skaileDir)) {
|
|
11512
|
-
mkdirSync5(
|
|
11705
|
+
mkdirSync5(path18__default.join(skaileDir, "sessions"), { recursive: true });
|
|
11513
11706
|
created.push(".skaile/");
|
|
11514
11707
|
}
|
|
11515
|
-
const settingsPath =
|
|
11708
|
+
const settingsPath = path18__default.join(skaileDir, "settings.json");
|
|
11516
11709
|
if (!existsSync18(settingsPath)) {
|
|
11517
|
-
|
|
11710
|
+
writeFileSync6(settingsPath, "{}\n");
|
|
11518
11711
|
created.push(".skaile/settings.json");
|
|
11519
11712
|
}
|
|
11520
|
-
const wsConfigPath =
|
|
11713
|
+
const wsConfigPath = path18__default.join(resolved, "skaile.yaml");
|
|
11521
11714
|
if (!existsSync18(wsConfigPath)) {
|
|
11522
|
-
|
|
11715
|
+
writeFileSync6(wsConfigPath, stringify2(buildInitWorkspaceConfig(projectName, harness)));
|
|
11523
11716
|
created.push("skaile.yaml");
|
|
11524
11717
|
}
|
|
11525
11718
|
for (const dir of new Set(Object.values(DRIVER_TARGETS[harness].local))) {
|
|
11526
|
-
const full =
|
|
11719
|
+
const full = path18__default.join(resolved, dir);
|
|
11527
11720
|
if (!existsSync18(full)) {
|
|
11528
11721
|
mkdirSync5(full, { recursive: true });
|
|
11529
11722
|
created.push(`${dir}/`);
|
|
@@ -11554,8 +11747,8 @@ function buildInitWorkspaceConfig(projectName, harness) {
|
|
|
11554
11747
|
}
|
|
11555
11748
|
async function initGitScaffold(resolved, created) {
|
|
11556
11749
|
const { execSync: execSync2 } = await import('child_process');
|
|
11557
|
-
const { existsSync: existsSync18, readFileSync: readFileSync10, writeFileSync:
|
|
11558
|
-
const gitignorePath =
|
|
11750
|
+
const { existsSync: existsSync18, readFileSync: readFileSync10, writeFileSync: writeFileSync6 } = await import('fs');
|
|
11751
|
+
const gitignorePath = path18__default.join(resolved, ".gitignore");
|
|
11559
11752
|
const entries = [
|
|
11560
11753
|
"node_modules/",
|
|
11561
11754
|
".skaile/sessions/",
|
|
@@ -11577,11 +11770,11 @@ async function initGitScaffold(resolved, created) {
|
|
|
11577
11770
|
const append = entries.filter((e) => !have.has(e));
|
|
11578
11771
|
if (append.length > 0) {
|
|
11579
11772
|
const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
11580
|
-
|
|
11773
|
+
writeFileSync6(gitignorePath, `${existing + prefix}${append.join("\n")}
|
|
11581
11774
|
`);
|
|
11582
11775
|
if (!existing) created.push(".gitignore");
|
|
11583
11776
|
}
|
|
11584
|
-
if (!existsSync18(
|
|
11777
|
+
if (!existsSync18(path18__default.join(resolved, ".git"))) {
|
|
11585
11778
|
try {
|
|
11586
11779
|
execSync2("git init", { cwd: resolved, stdio: "pipe" });
|
|
11587
11780
|
created.push(".git/");
|
|
@@ -11593,10 +11786,10 @@ async function initGitScaffold(resolved, created) {
|
|
|
11593
11786
|
}
|
|
11594
11787
|
async function bootstrapUserConfig() {
|
|
11595
11788
|
try {
|
|
11596
|
-
const
|
|
11789
|
+
const fs13 = await import('fs');
|
|
11597
11790
|
const { userConfigPath: userConfigPath2, saveConfig, getConfigDefaults } = await import('../library/index.js');
|
|
11598
11791
|
const userCfgPath = userConfigPath2();
|
|
11599
|
-
if (!
|
|
11792
|
+
if (!fs13.existsSync(userCfgPath)) {
|
|
11600
11793
|
const defaults = getConfigDefaults();
|
|
11601
11794
|
saveConfig(userCfgPath, {
|
|
11602
11795
|
catalog: { url: defaults.catalog.url, cache_ttl: defaults.catalog.cache_ttl }
|
|
@@ -11611,7 +11804,7 @@ async function bootstrapUserConfig() {
|
|
|
11611
11804
|
}
|
|
11612
11805
|
async function hydrateInitSources(resolved, created) {
|
|
11613
11806
|
try {
|
|
11614
|
-
const { ensureSourcesCloned } = await import('../ensure-sources-
|
|
11807
|
+
const { ensureSourcesCloned } = await import('../ensure-sources-5ISVIA4T.js');
|
|
11615
11808
|
const hydrate = ensureSourcesCloned(resolved, { quiet: true });
|
|
11616
11809
|
for (const n of hydrate.cloned) created.push(`~/.skaile/cache/sources/${n}/`);
|
|
11617
11810
|
if (hydrate.failed.length > 0) {
|
|
@@ -11627,7 +11820,7 @@ function printInitSummary(resolved, projectDir, created) {
|
|
|
11627
11820
|
logOk(`Initialized project at ${S.heading(resolved)}`);
|
|
11628
11821
|
console.log();
|
|
11629
11822
|
console.log(S.heading(" Next steps:"));
|
|
11630
|
-
const isCurrentDir = resolved ===
|
|
11823
|
+
const isCurrentDir = resolved === path18__default.resolve(".");
|
|
11631
11824
|
let step = 1;
|
|
11632
11825
|
if (!isCurrentDir) {
|
|
11633
11826
|
console.log(` ${S.dim(`${step}.`)} ${S.cmd(`cd ${projectDir}`)}`);
|
|
@@ -11651,7 +11844,7 @@ function printInitSummary(resolved, projectDir, created) {
|
|
|
11651
11844
|
console.log();
|
|
11652
11845
|
}
|
|
11653
11846
|
program.command("setup").description("Interactive provider setup wizard").action(async () => {
|
|
11654
|
-
const { cmdSetup } = await import('../setup-
|
|
11847
|
+
const { cmdSetup } = await import('../setup-BV55VHWC.js');
|
|
11655
11848
|
await cmdSetup([], { projectDir: process.cwd() });
|
|
11656
11849
|
});
|
|
11657
11850
|
program.addCommand(makeInstallCommand());
|
|
@@ -11733,7 +11926,7 @@ try {
|
|
|
11733
11926
|
await program.parseAsync();
|
|
11734
11927
|
} catch (err2) {
|
|
11735
11928
|
const { LibrarySyncError } = await import('../library/index.js');
|
|
11736
|
-
if (!(err2 instanceof LibrarySyncError)) throw err2;
|
|
11929
|
+
if (!(err2 instanceof LibrarySyncError || err2 instanceof SourceEntryError)) throw err2;
|
|
11737
11930
|
logErr(err2.message);
|
|
11738
11931
|
process.exit(1);
|
|
11739
11932
|
}
|