@skaile/workspaces 4.36.0 → 4.38.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 +44 -0
- package/dist/app-sdk/index.js +1 -1
- package/dist/{asset-feeds-SJELMLNK.js → asset-feeds-UYIFZKKG.js} +16 -16
- package/dist/asset-feeds-UYIFZKKG.js.map +1 -0
- package/dist/asset-manager/catalog-deployer.js +9 -8
- package/dist/asset-manager/index.js +15 -14
- package/dist/asset-manager/installer.js +11 -10
- package/dist/asset-manager/renderers.js +2 -2
- package/dist/asset-manager/src/index.d.ts +77 -18
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts +11 -1
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/bridge/drivers/claude-sdk.js +14 -13
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +11 -10
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/continue.js +12 -11
- package/dist/bridge/drivers/continue.js.map +1 -1
- package/dist/bridge/drivers/echo.js +3 -3
- package/dist/bridge/drivers/gemini.js +6 -6
- package/dist/bridge/drivers/goose.js +12 -11
- package/dist/bridge/drivers/goose.js.map +1 -1
- package/dist/bridge/drivers/omp.js +4 -4
- package/dist/bridge/drivers/opencode.js +12 -11
- package/dist/bridge/drivers/opencode.js.map +1 -1
- package/dist/bridge/drivers/qwen.js +6 -6
- package/dist/bridge/index.js +15 -14
- package/dist/{chunk-3CLUU45N.js → chunk-27DN4DZD.js} +8 -8
- package/dist/{chunk-3CLUU45N.js.map → chunk-27DN4DZD.js.map} +1 -1
- package/dist/{chunk-VOEBLPXO.js → chunk-2EL2PBRC.js} +3 -3
- package/dist/{chunk-VOEBLPXO.js.map → chunk-2EL2PBRC.js.map} +1 -1
- package/dist/{chunk-VRFKCF3R.js → chunk-36ML6SFP.js} +4 -4
- package/dist/{chunk-VRFKCF3R.js.map → chunk-36ML6SFP.js.map} +1 -1
- package/dist/{chunk-O63QZ6XX.js → chunk-4WKZEMBD.js} +4 -4
- package/dist/{chunk-O63QZ6XX.js.map → chunk-4WKZEMBD.js.map} +1 -1
- package/dist/{chunk-2D3C4AJP.js → chunk-5CYEWBPB.js} +11 -4
- package/dist/chunk-5CYEWBPB.js.map +1 -0
- package/dist/{chunk-SQ7IN7KR.js → chunk-5K2VT6E2.js} +3 -3
- package/dist/{chunk-SQ7IN7KR.js.map → chunk-5K2VT6E2.js.map} +1 -1
- package/dist/{chunk-NTASYPDN.js → chunk-5NYBY6ZE.js} +3 -3
- package/dist/{chunk-NTASYPDN.js.map → chunk-5NYBY6ZE.js.map} +1 -1
- package/dist/{chunk-FQE2NBUH.js → chunk-6EMF4UZI.js} +8 -8
- package/dist/{chunk-FQE2NBUH.js.map → chunk-6EMF4UZI.js.map} +1 -1
- package/dist/{chunk-MQU632EK.js → chunk-6KPQDP7P.js} +2 -2
- package/dist/{chunk-MQU632EK.js.map → chunk-6KPQDP7P.js.map} +1 -1
- package/dist/{chunk-LVRKJW53.js → chunk-6VRZ6M2L.js} +10 -3
- package/dist/chunk-6VRZ6M2L.js.map +1 -0
- package/dist/{chunk-5L55HNNA.js → chunk-7FZSABQV.js} +5 -5
- package/dist/{chunk-5L55HNNA.js.map → chunk-7FZSABQV.js.map} +1 -1
- package/dist/{chunk-FLGLODDF.js → chunk-7RC37XFW.js} +3 -3
- package/dist/{chunk-FLGLODDF.js.map → chunk-7RC37XFW.js.map} +1 -1
- package/dist/{chunk-3VUHHDZW.js → chunk-7UL2SQQH.js} +4 -4
- package/dist/{chunk-3VUHHDZW.js.map → chunk-7UL2SQQH.js.map} +1 -1
- package/dist/{chunk-GEEW6SY2.js → chunk-A5EDMBFG.js} +2 -2
- package/dist/{chunk-GEEW6SY2.js.map → chunk-A5EDMBFG.js.map} +1 -1
- package/dist/{chunk-QABZZROM.js → chunk-ARUJBGAH.js} +3 -3
- package/dist/{chunk-QABZZROM.js.map → chunk-ARUJBGAH.js.map} +1 -1
- package/dist/{chunk-TILISP6X.js → chunk-BQ3HXZNT.js} +2 -2
- package/dist/{chunk-TILISP6X.js.map → chunk-BQ3HXZNT.js.map} +1 -1
- package/dist/{chunk-NVNKPWL4.js → chunk-CACCIOQL.js} +12 -12
- package/dist/{chunk-NVNKPWL4.js.map → chunk-CACCIOQL.js.map} +1 -1
- package/dist/{chunk-5JAO4MXA.js → chunk-DOVURNRK.js} +3 -3
- package/dist/{chunk-5JAO4MXA.js.map → chunk-DOVURNRK.js.map} +1 -1
- package/dist/{chunk-P4VHQA4N.js → chunk-DSB6X25D.js} +3 -3
- package/dist/{chunk-P4VHQA4N.js.map → chunk-DSB6X25D.js.map} +1 -1
- package/dist/{chunk-ZWTCXL3H.js → chunk-DV47JNI4.js} +3 -3
- package/dist/{chunk-ZWTCXL3H.js.map → chunk-DV47JNI4.js.map} +1 -1
- package/dist/{chunk-Q7SIVPM2.js → chunk-EETXMMZS.js} +3 -3
- package/dist/{chunk-Q7SIVPM2.js.map → chunk-EETXMMZS.js.map} +1 -1
- package/dist/{chunk-OEBAXTQ4.js → chunk-EOKAFBJ7.js} +3 -3
- package/dist/{chunk-OEBAXTQ4.js.map → chunk-EOKAFBJ7.js.map} +1 -1
- package/dist/{chunk-6BEGKO2Q.js → chunk-HUNZYTOS.js} +4 -3
- package/dist/chunk-HUNZYTOS.js.map +1 -0
- package/dist/{chunk-YOIENZHA.js → chunk-HXG6IZSF.js} +6 -6
- package/dist/{chunk-YOIENZHA.js.map → chunk-HXG6IZSF.js.map} +1 -1
- package/dist/{chunk-L22WTIIC.js → chunk-ILAZDNIA.js} +3 -3
- package/dist/{chunk-L22WTIIC.js.map → chunk-ILAZDNIA.js.map} +1 -1
- package/dist/{chunk-FWZTKSYI.js → chunk-J5UF3OOS.js} +10 -10
- package/dist/{chunk-FWZTKSYI.js.map → chunk-J5UF3OOS.js.map} +1 -1
- package/dist/{chunk-QKXDRBLL.js → chunk-JEPSP6XK.js} +11 -80
- package/dist/chunk-JEPSP6XK.js.map +1 -0
- package/dist/{chunk-KIFJWSNC.js → chunk-KAJH3XPW.js} +7 -3
- package/dist/chunk-KAJH3XPW.js.map +1 -0
- package/dist/chunk-LOHQTTUV.js +29 -0
- package/dist/chunk-LOHQTTUV.js.map +1 -0
- package/dist/{chunk-MDBAEEY5.js → chunk-MQ42OYKH.js} +159 -7
- package/dist/chunk-MQ42OYKH.js.map +1 -0
- package/dist/{chunk-5JJ5KQUM.js → chunk-MS2JK4V7.js} +6 -6
- package/dist/{chunk-5JJ5KQUM.js.map → chunk-MS2JK4V7.js.map} +1 -1
- package/dist/{chunk-JRSLMZOT.js → chunk-OKGUDNDT.js} +37 -7
- package/dist/chunk-OKGUDNDT.js.map +1 -0
- package/dist/{chunk-DFZDL62S.js → chunk-OLMNDIAU.js} +14 -9
- package/dist/chunk-OLMNDIAU.js.map +1 -0
- package/dist/{chunk-3SUWLY3H.js → chunk-OQRB7JUS.js} +3 -3
- package/dist/{chunk-3SUWLY3H.js.map → chunk-OQRB7JUS.js.map} +1 -1
- package/dist/{chunk-TTITGVXV.js → chunk-PRCUGFXV.js} +3 -3
- package/dist/{chunk-TTITGVXV.js.map → chunk-PRCUGFXV.js.map} +1 -1
- package/dist/{chunk-MRS5YHPI.js → chunk-QBQITQAM.js} +3 -3
- package/dist/{chunk-MRS5YHPI.js.map → chunk-QBQITQAM.js.map} +1 -1
- package/dist/{chunk-PKGI5QG7.js → chunk-QWWDDU5Z.js} +274 -67
- package/dist/chunk-QWWDDU5Z.js.map +1 -0
- package/dist/{chunk-NKYNDLCB.js → chunk-R2U346ER.js} +3 -3
- package/dist/{chunk-NKYNDLCB.js.map → chunk-R2U346ER.js.map} +1 -1
- package/dist/{chunk-KVDXSEQH.js → chunk-R5ARWJGE.js} +104 -63
- package/dist/chunk-R5ARWJGE.js.map +1 -0
- package/dist/chunk-TLKM4M47.js +78 -0
- package/dist/chunk-TLKM4M47.js.map +1 -0
- package/dist/{chunk-NFECHLV6.js → chunk-TNWXGHLD.js} +3 -3
- package/dist/{chunk-NFECHLV6.js.map → chunk-TNWXGHLD.js.map} +1 -1
- package/dist/{chunk-H3KXUUYQ.js → chunk-VDBP6Y5M.js} +4 -4
- package/dist/{chunk-H3KXUUYQ.js.map → chunk-VDBP6Y5M.js.map} +1 -1
- package/dist/{chunk-XN7DAZB7.js → chunk-VJNTB4DN.js} +5 -5
- package/dist/chunk-VJNTB4DN.js.map +1 -0
- package/dist/{chunk-BSIHJZKN.js → chunk-XU7JET5Z.js} +107 -26
- package/dist/chunk-XU7JET5Z.js.map +1 -0
- package/dist/{chunk-LIS5KT2X.js → chunk-YCJ3PJNB.js} +5 -5
- package/dist/{chunk-LIS5KT2X.js.map → chunk-YCJ3PJNB.js.map} +1 -1
- package/dist/{chunk-VCLN2IUM.js → chunk-YCMZHL4T.js} +31 -27
- package/dist/chunk-YCMZHL4T.js.map +1 -0
- package/dist/{chunk-JS7DCCDA.js → chunk-YNUBJY3L.js} +4 -4
- package/dist/chunk-YNUBJY3L.js.map +1 -0
- package/dist/{chunk-S63H4HDH.js → chunk-YQEF36D5.js} +4 -4
- package/dist/{chunk-S63H4HDH.js.map → chunk-YQEF36D5.js.map} +1 -1
- package/dist/{chunk-FJYOQMXT.js → chunk-YV3YI3TA.js} +32 -16
- package/dist/chunk-YV3YI3TA.js.map +1 -0
- package/dist/cli/index.js +755 -533
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/asset-feeds.d.ts.map +1 -1
- package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/cache.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +28 -3
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/complete-resolvers.d.ts +1 -7
- package/dist/cli/src/commands/complete-resolvers.d.ts.map +1 -1
- package/dist/cli/src/commands/complete.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 +8 -0
- package/dist/cli/src/commands/library-index.d.ts.map +1 -1
- package/dist/cli/src/commands/library-publish.d.ts +7 -2
- package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/outdated.d.ts +12 -2
- package/dist/cli/src/commands/outdated.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts +2 -2
- package/dist/cli/src/commands/publish-core.d.ts +21 -0
- package/dist/cli/src/commands/publish-core.d.ts.map +1 -1
- package/dist/cli/src/commands/skailify-lib.d.ts +18 -1
- package/dist/cli/src/commands/skailify-lib.d.ts.map +1 -1
- package/dist/cli/src/commands/source-manifest-publish.d.ts.map +1 -1
- package/dist/cli/src/commands/store.d.ts.map +1 -1
- package/dist/cli/src/commands/update.d.ts.map +1 -1
- package/dist/cli/src/commands/validate.d.ts.map +1 -1
- package/dist/cli/src/paths.d.ts +1 -1
- package/dist/cli/src/paths.d.ts.map +1 -1
- package/dist/cli/src/store-auth.d.ts.map +1 -1
- package/dist/connectors/config.js +6 -5
- package/dist/connectors/index.js +19 -18
- package/dist/connectors-shared/index.js +2 -2
- package/dist/core/index.js +8 -7
- 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 +6 -5
- package/dist/core/src/asset-roots.d.ts +2 -12
- package/dist/core/src/asset-roots.d.ts.map +1 -1
- package/dist/core/src/cache-paths.d.ts +7 -3
- package/dist/core/src/cache-paths.d.ts.map +1 -1
- package/dist/core/src/index.d.ts +3 -3
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/lock.d.ts +27 -4
- package/dist/core/src/lock.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +26 -6
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/settings.d.ts +2 -1
- package/dist/core/src/settings.d.ts.map +1 -1
- package/dist/core/src/store.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/store.js +2 -1
- package/dist/core/workspace-config.js +5 -4
- package/dist/deploy/index.js +8 -7
- package/dist/deploy/index.js.map +1 -1
- package/dist/discovery/index.js +5 -5
- package/dist/discovery/src/domains.d.ts +6 -1
- package/dist/discovery/src/domains.d.ts.map +1 -1
- package/dist/discovery/src/index.d.ts +1 -1
- package/dist/discovery/src/index.d.ts.map +1 -1
- package/dist/{ensure-sources-SYZO2HNP.js → ensure-sources-VX63EKY7.js} +18 -17
- package/dist/ensure-sources-VX63EKY7.js.map +1 -0
- package/dist/factory-assets/connectors/box.js +19 -18
- package/dist/factory-assets/connectors/deploy.js +19 -18
- package/dist/factory-assets/connectors/devserver.js +19 -18
- package/dist/factory-assets/connectors/flow/adapter.js +19 -18
- package/dist/factory-assets/connectors/flow/engine.js +9 -8
- package/dist/factory-assets/connectors/flow/run-flow.js +21 -20
- package/dist/factory-assets/connectors/flow.js +19 -18
- package/dist/factory-assets/connectors/git.js +19 -18
- package/dist/factory-assets/connectors/gmail.js +19 -18
- package/dist/factory-assets/connectors/googledrive.js +19 -18
- package/dist/factory-assets/connectors/local.js +19 -18
- package/dist/factory-assets/connectors/mattermost.js +19 -18
- package/dist/factory-assets/connectors/memory.js +19 -18
- package/dist/factory-assets/connectors/minio.js +19 -18
- package/dist/factory-assets/connectors/postgres.js +19 -18
- package/dist/factory-assets/connectors/s3.js +19 -18
- package/dist/factory-assets/connectors/sharepoint.js +19 -18
- package/dist/factory-assets/connectors/sqlite.js +19 -18
- package/dist/factory-assets/connectors/static-server.js +19 -18
- package/dist/factory-assets/connectors/tunnel.js +19 -18
- package/dist/factory-assets/connectors/webdav.js +19 -18
- package/dist/factory-assets/connectors/xstate-store.js +19 -18
- package/dist/factory-assets/connectors/xstate.js +19 -18
- package/dist/flows-PX53XFV7.js +25 -0
- package/dist/{flows-6MDMBQUZ.js.map → flows-PX53XFV7.js.map} +1 -1
- package/dist/{helpers-IMUCDNME.js → helpers-DF55G2YC.js} +18 -17
- package/dist/{helpers-IMUCDNME.js.map → helpers-DF55G2YC.js.map} +1 -1
- package/dist/library/index.js +12 -11
- package/dist/library/install.js +2 -2
- package/dist/library/src/config.d.ts +11 -9
- package/dist/library/src/config.d.ts.map +1 -1
- package/dist/library/src/index.d.ts +2 -2
- package/dist/library/src/index.d.ts.map +1 -1
- package/dist/library/src/local/db.d.ts.map +1 -1
- package/dist/library/src/local/library-manager.d.ts +7 -0
- package/dist/library/src/local/library-manager.d.ts.map +1 -1
- package/dist/library/src/local/library.d.ts +5 -4
- package/dist/library/src/local/library.d.ts.map +1 -1
- package/dist/library/src/local/schema.d.ts +2 -0
- package/dist/library/src/local/schema.d.ts.map +1 -1
- package/dist/library/src/local/sidecar-paths.d.ts.map +1 -1
- package/dist/library/src/local/store-paths.d.ts.map +1 -1
- package/dist/library/src/remote/cache.d.ts.map +1 -1
- package/dist/library/src/sync/git-driver.d.ts +34 -0
- package/dist/library/src/sync/git-driver.d.ts.map +1 -1
- package/dist/{library-publish-XAIAHKRL.js → library-publish-2PNWJJOY.js} +95 -41
- package/dist/library-publish-2PNWJJOY.js.map +1 -0
- package/dist/open-library-SUVOMIWZ.js +38 -0
- package/dist/{open-library-6N3XZ2XL.js.map → open-library-SUVOMIWZ.js.map} +1 -1
- package/dist/paths-W4LDORQQ.js +21 -0
- package/dist/{paths-4MTICP3T.js.map → paths-W4LDORQQ.js.map} +1 -1
- package/dist/{plugin-store-GQ4WQZJ2.js → plugin-store-D45CREMJ.js} +10 -9
- package/dist/plugin-store-D45CREMJ.js.map +1 -0
- package/dist/project-RTLVOXUU.js +34 -0
- package/dist/{project-HESTMGPU.js.map → project-RTLVOXUU.js.map} +1 -1
- package/dist/resolver/index.js +9 -8
- package/dist/runner/index.js +28 -27
- package/dist/runner/src/composition/bootstrap.d.ts +1 -1
- package/dist/runner/src/composition/bootstrap.d.ts.map +1 -1
- package/dist/runner/src/prompt-turn-queue.d.ts +27 -4
- package/dist/runner/src/prompt-turn-queue.d.ts.map +1 -1
- package/dist/runner/src/runtime-session-emit.d.ts +2 -1
- package/dist/runner/src/runtime-session-emit.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +15 -14
- package/dist/sdk/bridge.js +15 -14
- package/dist/sdk/core.js +8 -7
- package/dist/sdk/flow.js +9 -8
- package/dist/sdk/index.js +28 -27
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.js +9 -8
- package/dist/sdk/runner.js +28 -27
- package/dist/sdk/session.js +2 -2
- package/dist/sdk/store.js +1 -1
- package/dist/sdk/types.js +1 -1
- package/dist/secrets/index.js +18 -1
- package/dist/secrets/src/providers/local.d.ts.map +1 -1
- package/dist/session/index.js +2 -2
- package/dist/session/src/dispatcher.d.ts.map +1 -1
- package/dist/{setup-PQG5DH5Z.js → setup-ZA7VZL72.js} +25 -24
- package/dist/setup-ZA7VZL72.js.map +1 -0
- package/dist/skills-R3RPIPWP.js +25 -0
- package/dist/{skills-JHUY4DFE.js.map → skills-R3RPIPWP.js.map} +1 -1
- package/dist/{source-PNYNVVPM.js → source-Y5YQ7M53.js} +21 -20
- package/dist/{source-PNYNVVPM.js.map → source-Y5YQ7M53.js.map} +1 -1
- package/dist/{source-manifest-publish-6O6H4T2P.js → source-manifest-publish-RZIJNRIW.js} +24 -25
- package/dist/source-manifest-publish-RZIJNRIW.js.map +1 -0
- package/dist/store/index.js +1 -1
- package/dist/store/src/store.d.ts +9 -0
- package/dist/store/src/store.d.ts.map +1 -1
- package/dist/store/src/types.d.ts +17 -0
- package/dist/store/src/types.d.ts.map +1 -1
- package/dist/tui/index.js +28 -27
- package/dist/tui/index.js.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/manifests.js +1 -1
- package/dist/types/src/events.d.ts +28 -3
- package/dist/types/src/events.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/manifests/index.d.ts +1 -1
- package/dist/types/src/manifests/index.d.ts.map +1 -1
- package/dist/types/src/manifests/skill.d.ts +10 -0
- package/dist/types/src/manifests/skill.d.ts.map +1 -1
- package/dist/types/src/protocol.d.ts +2 -0
- package/dist/types/src/protocol.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +12 -1
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +15 -14
- package/dist/workspace-plugin/adapters/omp.js +7 -7
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -1
- package/dist/asset-feeds-SJELMLNK.js.map +0 -1
- package/dist/chunk-2D3C4AJP.js.map +0 -1
- package/dist/chunk-422WJ2QC.js +0 -158
- package/dist/chunk-422WJ2QC.js.map +0 -1
- package/dist/chunk-6BEGKO2Q.js.map +0 -1
- package/dist/chunk-BSIHJZKN.js.map +0 -1
- package/dist/chunk-DFZDL62S.js.map +0 -1
- package/dist/chunk-FJYOQMXT.js.map +0 -1
- package/dist/chunk-JRSLMZOT.js.map +0 -1
- package/dist/chunk-JS7DCCDA.js.map +0 -1
- package/dist/chunk-KIFJWSNC.js.map +0 -1
- package/dist/chunk-KVDXSEQH.js.map +0 -1
- package/dist/chunk-LVRKJW53.js.map +0 -1
- package/dist/chunk-MDBAEEY5.js.map +0 -1
- package/dist/chunk-PKGI5QG7.js.map +0 -1
- package/dist/chunk-QKXDRBLL.js.map +0 -1
- package/dist/chunk-VCLN2IUM.js.map +0 -1
- package/dist/chunk-XN7DAZB7.js.map +0 -1
- package/dist/ensure-sources-SYZO2HNP.js.map +0 -1
- package/dist/flows-6MDMBQUZ.js +0 -24
- package/dist/library-publish-XAIAHKRL.js.map +0 -1
- package/dist/open-library-6N3XZ2XL.js +0 -37
- package/dist/paths-4MTICP3T.js +0 -20
- package/dist/plugin-store-GQ4WQZJ2.js.map +0 -1
- package/dist/project-HESTMGPU.js +0 -33
- package/dist/setup-PQG5DH5Z.js.map +0 -1
- package/dist/skills-JHUY4DFE.js +0 -24
- package/dist/source-manifest-publish-6O6H4T2P.js.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { AI_RESOURCES } from '../chunk-
|
|
3
|
-
import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportInstalledSoftDeps } from '../chunk-
|
|
4
|
-
import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-
|
|
5
|
-
import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity } from '../chunk-
|
|
6
|
-
import { makeSourceCommand, syncProjectSources } from '../chunk-
|
|
7
|
-
import { openCatalogSource, openLibraryManager, createFullRegistry, openLibrary } from '../chunk-
|
|
8
|
-
import { logErr, S, logOk, logInfo, logWarn, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth } from '../chunk-
|
|
9
|
-
import { LocalSecretsProvider } from '../chunk-
|
|
10
|
-
import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-
|
|
11
|
-
import { buildClaudePluginFiles } from '../chunk-
|
|
12
|
-
import '../chunk-
|
|
13
|
-
import '../chunk-
|
|
14
|
-
import '../chunk-
|
|
15
|
-
import '../chunk-
|
|
2
|
+
import { AI_RESOURCES } from '../chunk-VJNTB4DN.js';
|
|
3
|
+
import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportInstalledSoftDeps } from '../chunk-6EMF4UZI.js';
|
|
4
|
+
import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-7FZSABQV.js';
|
|
5
|
+
import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, refFor } from '../chunk-MQ42OYKH.js';
|
|
6
|
+
import { makeSourceCommand, syncProjectSources } from '../chunk-CACCIOQL.js';
|
|
7
|
+
import { openCatalogSource, openLibraryManager, createFullRegistry, openLibrary } from '../chunk-MS2JK4V7.js';
|
|
8
|
+
import { logErr, S, logOk, logInfo, logWarn, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth, KIND_COL_WIDTH } from '../chunk-ILAZDNIA.js';
|
|
9
|
+
import { LocalSecretsProvider } from '../chunk-HUNZYTOS.js';
|
|
10
|
+
import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-R5ARWJGE.js';
|
|
11
|
+
import { buildClaudePluginFiles } from '../chunk-BQ3HXZNT.js';
|
|
12
|
+
import '../chunk-YCJ3PJNB.js';
|
|
13
|
+
import '../chunk-QBQITQAM.js';
|
|
14
|
+
import '../chunk-VDBP6Y5M.js';
|
|
15
|
+
import '../chunk-EOKAFBJ7.js';
|
|
16
16
|
import '../chunk-4ZTPYIBE.js';
|
|
17
17
|
import '../chunk-35G4M33T.js';
|
|
18
18
|
import '../chunk-R6O6YWU7.js';
|
|
@@ -24,51 +24,52 @@ import '../chunk-5LKOAX7I.js';
|
|
|
24
24
|
import '../chunk-32NA4TVC.js';
|
|
25
25
|
import '../chunk-W3UDISS2.js';
|
|
26
26
|
import '../chunk-HCYS7GFP.js';
|
|
27
|
-
import { runFlow, resumeFlow } from '../chunk-
|
|
27
|
+
import { runFlow, resumeFlow } from '../chunk-27DN4DZD.js';
|
|
28
28
|
import '../chunk-4R6DROGN.js';
|
|
29
|
-
import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-
|
|
30
|
-
import '../chunk-
|
|
29
|
+
import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-OQRB7JUS.js';
|
|
30
|
+
import '../chunk-DOVURNRK.js';
|
|
31
31
|
import '../chunk-6X4DHKHP.js';
|
|
32
|
-
import '../chunk-
|
|
33
|
-
import '../chunk-
|
|
34
|
-
import '../chunk-
|
|
35
|
-
import '../chunk-
|
|
36
|
-
import '../chunk-
|
|
32
|
+
import '../chunk-J5UF3OOS.js';
|
|
33
|
+
import '../chunk-DV47JNI4.js';
|
|
34
|
+
import '../chunk-YQEF36D5.js';
|
|
35
|
+
import '../chunk-7UL2SQQH.js';
|
|
36
|
+
import '../chunk-5NYBY6ZE.js';
|
|
37
37
|
import '../chunk-EINLFFP6.js';
|
|
38
38
|
import '../chunk-LOO5CB5M.js';
|
|
39
|
-
import '../chunk-
|
|
40
|
-
import '../chunk-
|
|
39
|
+
import '../chunk-PRCUGFXV.js';
|
|
40
|
+
import '../chunk-4WKZEMBD.js';
|
|
41
41
|
import '../chunk-XBSQ4KMC.js';
|
|
42
42
|
import '../chunk-YROR332M.js';
|
|
43
|
-
import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-
|
|
43
|
+
import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-6KPQDP7P.js';
|
|
44
44
|
import '../chunk-6E6PKKAD.js';
|
|
45
45
|
import '../chunk-IFGTRL2I.js';
|
|
46
|
-
import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-
|
|
46
|
+
import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-7RC37XFW.js';
|
|
47
47
|
import '../chunk-YYH5EVPM.js';
|
|
48
48
|
import '../chunk-DIQDYNXZ.js';
|
|
49
49
|
import '../chunk-K3IBZ2UZ.js';
|
|
50
50
|
import { nodeLabel, nodeSkillAsset, nodeIsInert, nodeIsOptional, nodeRunKind, flowSkillVersionPins } from '../chunk-UDFWBALP.js';
|
|
51
51
|
import '../chunk-ORH2BZEM.js';
|
|
52
|
-
import '../chunk-
|
|
53
|
-
import { AssetManager, NON_DEPLOYABLE_KINDS, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-
|
|
54
|
-
import { getStoreManifestsDir, getDefaultValue, isSecretPlaceholder } from '../chunk-
|
|
55
|
-
import '../chunk-
|
|
56
|
-
import '../chunk-
|
|
52
|
+
import '../chunk-YNUBJY3L.js';
|
|
53
|
+
import { AssetManager, NON_DEPLOYABLE_KINDS, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-QWWDDU5Z.js';
|
|
54
|
+
import { cloneOrInitGitRepo, ensureGitRepo, isGitRepo, getStoreManifestsDir, getDefaultValue, isSecretPlaceholder } from '../chunk-XU7JET5Z.js';
|
|
55
|
+
import { isValidDomainSlug, parseDomainMd } from '../chunk-OLMNDIAU.js';
|
|
56
|
+
import '../chunk-2EL2PBRC.js';
|
|
57
57
|
import '../chunk-R7FOF242.js';
|
|
58
58
|
import '../chunk-JXT46QFC.js';
|
|
59
|
-
import '../chunk-
|
|
59
|
+
import '../chunk-YCMZHL4T.js';
|
|
60
60
|
import '../chunk-CGYEHQOX.js';
|
|
61
|
-
import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, aiResourceRoots, readLock, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-
|
|
61
|
+
import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, aiResourceRoots, readLock, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-YV3YI3TA.js';
|
|
62
62
|
import '../chunk-4GY63JU6.js';
|
|
63
|
-
import { factoryAssetRoots } from '../chunk-
|
|
64
|
-
import '../chunk-
|
|
63
|
+
import { factoryAssetRoots } from '../chunk-36ML6SFP.js';
|
|
64
|
+
import '../chunk-KAJH3XPW.js';
|
|
65
65
|
import { DRIVER_DEFAULTS } from '../chunk-K5GBV4SA.js';
|
|
66
|
-
import {
|
|
67
|
-
import {
|
|
66
|
+
import { assetSearchDirs } from '../chunk-QVZA2MDT.js';
|
|
67
|
+
import { sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, matchPin, coerceVersion, loadSkWorkspaceConfig, resolveSkWorkspaceConfig, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-JEPSP6XK.js';
|
|
68
|
+
import { globalCacheRoot, globalSkaileDir } from '../chunk-TLKM4M47.js';
|
|
68
69
|
import { SUPPORTED_DRIVER_TARGETS } from '../chunk-EB4ZTESQ.js';
|
|
69
|
-
import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest, loadSkPublishManifest, saveSkPublishManifest } from '../chunk-
|
|
70
|
-
import { parseFrontmatter, scanDirectory } from '../chunk-
|
|
71
|
-
import { parseAssetRef, ASSET_KINDS, isValidAssetName, slugifyAssetName, ASSET_NAME_HINT, assetRefToStr } from '../chunk-
|
|
70
|
+
import { SKAILE_MANIFEST_FILENAME, decodeSkaileManifest, loadSkPublishManifest, saveSkPublishManifest } from '../chunk-DSB6X25D.js';
|
|
71
|
+
import { parseFrontmatter, scanDirectory } from '../chunk-5K2VT6E2.js';
|
|
72
|
+
import { parseAssetRef, ASSET_KINDS, isValidAssetName, slugifyAssetName, ASSET_NAME_HINT, assetRefToStr } from '../chunk-A5EDMBFG.js';
|
|
72
73
|
import { openSqlite } from '../chunk-JMKB7IB4.js';
|
|
73
74
|
import { portableSpawn, portableSpawnSync } from '../chunk-ICSCSM5D.js';
|
|
74
75
|
import { parseModelRef, resolveEntryBaseUrl } from '../chunk-MJHSLODD.js';
|
|
@@ -76,31 +77,43 @@ import '../chunk-C3CAXQMA.js';
|
|
|
76
77
|
import '../chunk-BOFL7GIF.js';
|
|
77
78
|
import '../chunk-KTBKW2FI.js';
|
|
78
79
|
import '../chunk-UQ6LFBPZ.js';
|
|
79
|
-
import '../chunk-
|
|
80
|
-
import { validatePreset } from '../chunk-
|
|
80
|
+
import '../chunk-TNWXGHLD.js';
|
|
81
|
+
import { validatePreset, SKILL_BODY_PLACEHOLDER } from '../chunk-5CYEWBPB.js';
|
|
81
82
|
import '../chunk-NSBPE2FW.js';
|
|
82
|
-
import * as
|
|
83
|
-
import
|
|
84
|
-
import * as
|
|
85
|
-
import
|
|
83
|
+
import * as fs11 from 'fs';
|
|
84
|
+
import fs11__default, { readFileSync, existsSync, mkdirSync, writeFileSync, lstatSync, rmSync, readdirSync, statSync } from 'fs';
|
|
85
|
+
import * as path35 from 'path';
|
|
86
|
+
import path35__default, { resolve, join } from 'path';
|
|
86
87
|
import { fileURLToPath } from 'url';
|
|
87
88
|
import { Help, Command, Option } from 'commander';
|
|
88
89
|
import { rcompare } from 'semver';
|
|
89
90
|
import * as p5 from '@clack/prompts';
|
|
90
91
|
import pc5 from 'picocolors';
|
|
91
92
|
import * as os from 'os';
|
|
92
|
-
import { homedir } from 'os';
|
|
93
93
|
import { parse, stringify, parseDocument } from 'yaml';
|
|
94
94
|
import * as readline from 'readline';
|
|
95
95
|
import { createInterface } from 'readline';
|
|
96
96
|
import fs5 from 'fs/promises';
|
|
97
97
|
import { parse as parse$1, stringify as stringify$1 } from 'smol-toml';
|
|
98
|
-
import { execSync } from 'child_process';
|
|
98
|
+
import { execSync, spawnSync } from 'child_process';
|
|
99
99
|
import * as readline2 from 'readline/promises';
|
|
100
100
|
import { createTRPCUntypedClient, httpLink, httpSubscriptionLink } from '@trpc/client';
|
|
101
101
|
|
|
102
102
|
function catalogAssetRef(a) {
|
|
103
|
-
return `${a.kind}:@${a.publisher}/${a.name}#${a.version}`;
|
|
103
|
+
return `${a.kind}:@${a.publisher.replace(/^@/, "")}/${a.name}#${a.version}`;
|
|
104
|
+
}
|
|
105
|
+
var DEFAULT_TERMINAL_WIDTH = 100;
|
|
106
|
+
var MIN_DESCRIPTION_WIDTH = 20;
|
|
107
|
+
var COLUMN_GAP = " ";
|
|
108
|
+
function terminalWidth() {
|
|
109
|
+
const cols = process.stdout.columns;
|
|
110
|
+
return typeof cols === "number" && cols > 0 ? cols : DEFAULT_TERMINAL_WIDTH;
|
|
111
|
+
}
|
|
112
|
+
function truncateText(text, max) {
|
|
113
|
+
const flat = text.replace(/\s+/g, " ").trim();
|
|
114
|
+
if (flat.length <= max) return flat;
|
|
115
|
+
if (max <= 1) return "\u2026".slice(0, Math.max(0, max));
|
|
116
|
+
return `${flat.slice(0, max - 1).trimEnd()}\u2026`;
|
|
104
117
|
}
|
|
105
118
|
function localEntryRef(e) {
|
|
106
119
|
return e.publisher ? `${e.kind}:@${e.publisher}/${e.name}` : e.name;
|
|
@@ -120,7 +133,7 @@ async function runSearch(kind, query, opts) {
|
|
|
120
133
|
const showLocal = !opts.store;
|
|
121
134
|
const showStore = !opts.local;
|
|
122
135
|
const { resolveConfig } = await import('../library/index.js');
|
|
123
|
-
const airGapped = resolveConfig({ projectDir:
|
|
136
|
+
const airGapped = resolveConfig({ projectDir: path35__default.resolve(opts.projectDir) }).catalog.cache_ttl === 0;
|
|
124
137
|
if (showLocal) {
|
|
125
138
|
await searchLocal(query, kind, opts, showStore, airGapped);
|
|
126
139
|
}
|
|
@@ -129,7 +142,7 @@ async function runSearch(kind, query, opts) {
|
|
|
129
142
|
}
|
|
130
143
|
}
|
|
131
144
|
async function searchIndex(query, kind) {
|
|
132
|
-
const { openLibrary: openLibrary2 } = await import('../open-library-
|
|
145
|
+
const { openLibrary: openLibrary2 } = await import('../open-library-SUVOMIWZ.js');
|
|
133
146
|
const library = await openLibrary2();
|
|
134
147
|
try {
|
|
135
148
|
const defs = await library.listAssetDefs(kind ? { kind } : {});
|
|
@@ -161,7 +174,7 @@ async function searchIndex(query, kind) {
|
|
|
161
174
|
}
|
|
162
175
|
}
|
|
163
176
|
async function searchFactory(projectDir, query, kind) {
|
|
164
|
-
const prefixes = factoryAssetRoots().map((r) => r.endsWith(
|
|
177
|
+
const prefixes = factoryAssetRoots().map((r) => r.endsWith(path35__default.sep) ? r : r + path35__default.sep);
|
|
165
178
|
const isFactoryPath = (p7) => prefixes.some((fp) => p7 === fp.slice(0, -1) || p7.startsWith(fp));
|
|
166
179
|
try {
|
|
167
180
|
const entries = await new AssetManager({ projectDir }).search(query, kind);
|
|
@@ -178,11 +191,11 @@ function unionEntries(indexed, factory) {
|
|
|
178
191
|
return [...indexed, ...factory.filter((e) => !seen.has(entryDedupKey(e)))];
|
|
179
192
|
}
|
|
180
193
|
async function searchLocal(query, kind, opts, showStore, airGapped) {
|
|
181
|
-
const projectDir =
|
|
194
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
182
195
|
const factory = await searchFactory(projectDir, query, kind);
|
|
183
196
|
let entries = unionEntries(await searchIndex(query, kind), factory);
|
|
184
197
|
if (entries.length === 0 && !query && !kind && !airGapped) {
|
|
185
|
-
const { autoSyncForSearch } = await import('../source-
|
|
198
|
+
const { autoSyncForSearch } = await import('../source-Y5YQ7M53.js');
|
|
186
199
|
if (await autoSyncForSearch(projectDir)) {
|
|
187
200
|
entries = unionEntries(await searchIndex(query, kind), factory);
|
|
188
201
|
}
|
|
@@ -201,23 +214,29 @@ async function searchLocal(query, kind, opts, showStore, airGapped) {
|
|
|
201
214
|
}
|
|
202
215
|
printLocalEntries(entries);
|
|
203
216
|
}
|
|
204
|
-
function printLocalEntries(entries) {
|
|
217
|
+
function printLocalEntries(entries, width = terminalWidth()) {
|
|
205
218
|
const byKind = /* @__PURE__ */ new Map();
|
|
206
219
|
for (const e of entries) {
|
|
207
220
|
if (!byKind.has(e.kind)) byKind.set(e.kind, []);
|
|
208
221
|
byKind.get(e.kind).push(e);
|
|
209
222
|
}
|
|
223
|
+
const verOf = (e) => e.version ? `v${e.version}` : "";
|
|
210
224
|
for (const [k, items] of byKind) {
|
|
211
225
|
const nameW = Math.max(4, ...items.map((e) => localEntryRef(e).length));
|
|
226
|
+
const verW = Math.max(0, ...items.map((e) => verOf(e).length));
|
|
227
|
+
const fixed = 2 + nameW + COLUMN_GAP.length + (verW > 0 ? COLUMN_GAP.length + verW : 0);
|
|
228
|
+
const descW = Math.max(MIN_DESCRIPTION_WIDTH, width - fixed);
|
|
212
229
|
console.log();
|
|
213
230
|
console.log(
|
|
214
231
|
` ${kindColor(k)} ${S.heading(`${k.toUpperCase()}S`)} ${S.dim(`(${items.length})`)}`
|
|
215
232
|
);
|
|
216
|
-
console.log(` ${S.rule(
|
|
233
|
+
console.log(` ${S.rule(fixed - 2 + descW)}`);
|
|
217
234
|
for (const e of items) {
|
|
218
|
-
const
|
|
235
|
+
const desc = truncateText(e.description, descW);
|
|
236
|
+
const ver = verOf(e);
|
|
237
|
+
const descCell = ver ? desc.padEnd(descW) : desc;
|
|
219
238
|
console.log(
|
|
220
|
-
` ${S.cmd(localEntryRef(e).padEnd(nameW))}
|
|
239
|
+
` ${S.cmd(localEntryRef(e).padEnd(nameW))}${COLUMN_GAP}${descCell}${ver ? `${COLUMN_GAP}${S.dim(ver)}` : ""}`
|
|
221
240
|
);
|
|
222
241
|
}
|
|
223
242
|
}
|
|
@@ -225,6 +244,16 @@ function printLocalEntries(entries) {
|
|
|
225
244
|
${S.dim(`${entries.length} total`)}
|
|
226
245
|
`);
|
|
227
246
|
}
|
|
247
|
+
function formatStoreRows(assets, indent, width = terminalWidth()) {
|
|
248
|
+
const refs = assets.map(catalogAssetRef);
|
|
249
|
+
const refW = Math.max(...refs.map((r) => r.length));
|
|
250
|
+
const fixed = indent.length + 2 + KIND_COL_WIDTH + COLUMN_GAP.length + refW + COLUMN_GAP.length;
|
|
251
|
+
const descW = Math.max(MIN_DESCRIPTION_WIDTH, width - fixed);
|
|
252
|
+
return assets.map((asset, i) => {
|
|
253
|
+
const pad = " ".repeat(refW - refs[i].length);
|
|
254
|
+
return `${indent}\u2B21 ${kindColorPad(asset.kind)}${COLUMN_GAP}${colorRef(refs[i])}${pad}${COLUMN_GAP}${S.dim(truncateText(asset.description ?? "", descW))}`;
|
|
255
|
+
});
|
|
256
|
+
}
|
|
228
257
|
async function searchStore(query, kind, opts, airGapped) {
|
|
229
258
|
if (airGapped) {
|
|
230
259
|
if (opts.store) {
|
|
@@ -236,20 +265,15 @@ async function searchStore(query, kind, opts, airGapped) {
|
|
|
236
265
|
logInfo("air-gapped (cache_ttl: 0) \u2014 local sources only");
|
|
237
266
|
return;
|
|
238
267
|
}
|
|
239
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-
|
|
268
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-SUVOMIWZ.js');
|
|
240
269
|
try {
|
|
241
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
270
|
+
const remote = await openCatalogSource2({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
242
271
|
const assets = await remote.listAssets(kind ? { kind } : {});
|
|
243
272
|
const results = filterCatalogAssets(assets, query);
|
|
244
273
|
if (results.length > 0) {
|
|
245
274
|
console.log(`
|
|
246
275
|
${S.heading("Store:")}`);
|
|
247
|
-
for (const
|
|
248
|
-
const ref = catalogAssetRef(asset);
|
|
249
|
-
console.log(
|
|
250
|
-
` \u2B21 ${kindColorPad(asset.kind)} ${colorRef(ref).padEnd(48)} ${S.dim(asset.description?.slice(0, 50) || "")}`
|
|
251
|
-
);
|
|
252
|
-
}
|
|
276
|
+
for (const row of formatStoreRows(results, " ")) console.log(row);
|
|
253
277
|
} else if (opts.store) {
|
|
254
278
|
logInfo("No results in store");
|
|
255
279
|
}
|
|
@@ -359,7 +383,7 @@ function makeAddCommand() {
|
|
|
359
383
|
}
|
|
360
384
|
const harnesses = parseHarnessFilter(opts.harness);
|
|
361
385
|
const am2 = new AssetManager({
|
|
362
|
-
projectDir:
|
|
386
|
+
projectDir: path35__default.resolve(opts.projectDir),
|
|
363
387
|
global: opts.global || harnesses !== void 0,
|
|
364
388
|
harnesses,
|
|
365
389
|
driverTarget: opts.target
|
|
@@ -403,7 +427,7 @@ function makeRemoveCommand() {
|
|
|
403
427
|
).option("--target <agent>", "Driver target", "claude-code").option("--no-soft-deps", "skip the orphaned-soft-dep prompt (don't remove, don't report)").action(async (ref, opts) => {
|
|
404
428
|
const harnesses = parseHarnessFilter(opts.harness);
|
|
405
429
|
const am2 = new AssetManager({
|
|
406
|
-
projectDir:
|
|
430
|
+
projectDir: path35__default.resolve(opts.projectDir),
|
|
407
431
|
global: opts.global || harnesses !== void 0,
|
|
408
432
|
harnesses,
|
|
409
433
|
driverTarget: opts.target
|
|
@@ -443,7 +467,7 @@ function makeListCommand() {
|
|
|
443
467
|
return;
|
|
444
468
|
}
|
|
445
469
|
const am2 = new AssetManager({
|
|
446
|
-
projectDir:
|
|
470
|
+
projectDir: path35__default.resolve(opts.projectDir),
|
|
447
471
|
driverTarget: opts.target
|
|
448
472
|
});
|
|
449
473
|
let declared;
|
|
@@ -488,7 +512,7 @@ function makeListCommand() {
|
|
|
488
512
|
}
|
|
489
513
|
function runGlobalList(kind, opts, harnesses) {
|
|
490
514
|
const am2 = new AssetManager({
|
|
491
|
-
projectDir:
|
|
515
|
+
projectDir: path35__default.resolve(opts.projectDir),
|
|
492
516
|
global: true,
|
|
493
517
|
harnesses
|
|
494
518
|
});
|
|
@@ -559,7 +583,7 @@ async function resolveInfoEntry(am2, ref, opts) {
|
|
|
559
583
|
return { entry: match ?? deployed };
|
|
560
584
|
}
|
|
561
585
|
const lookup = opts.storeLookup ?? (async (filter) => {
|
|
562
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
586
|
+
const { resolveCatalogSource } = await import('../open-library-SUVOMIWZ.js');
|
|
563
587
|
const { source, close } = await resolveCatalogSource({ projectDir: opts.projectDir });
|
|
564
588
|
try {
|
|
565
589
|
return await source.listAssets(filter);
|
|
@@ -575,7 +599,7 @@ async function resolveInfoEntry(am2, ref, opts) {
|
|
|
575
599
|
);
|
|
576
600
|
return { entry: hit ? catalogAssetToEntry(hit) : null };
|
|
577
601
|
} catch (err) {
|
|
578
|
-
const { LocalCatalogDisabledError } = await import('../open-library-
|
|
602
|
+
const { LocalCatalogDisabledError } = await import('../open-library-SUVOMIWZ.js');
|
|
579
603
|
const storeNote = err instanceof Error ? err.message : String(err);
|
|
580
604
|
const disabled = err instanceof LocalCatalogDisabledError || /catalog\.url/i.test(storeNote);
|
|
581
605
|
return { entry: null, storeNote, ...disabled ? { storeDisabled: true } : {} };
|
|
@@ -591,7 +615,7 @@ function infoNotFoundHint(ref, lookup) {
|
|
|
591
615
|
}
|
|
592
616
|
function makeInfoCommand() {
|
|
593
617
|
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) => {
|
|
594
|
-
const projectDir =
|
|
618
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
595
619
|
const am2 = new AssetManager({ projectDir });
|
|
596
620
|
const lookup = await resolveInfoEntry(am2, ref, { projectDir });
|
|
597
621
|
const entry = lookup.entry;
|
|
@@ -627,7 +651,7 @@ function makeCreateCommand() {
|
|
|
627
651
|
new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...ASSET_KINDS])
|
|
628
652
|
).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
|
|
629
653
|
const am2 = new AssetManager({ projectDir: process.cwd() });
|
|
630
|
-
const destDir = opts.dir ?
|
|
654
|
+
const destDir = opts.dir ? path35__default.resolve(opts.dir) : process.cwd();
|
|
631
655
|
const result = am2.create(name, opts.kind, destDir);
|
|
632
656
|
if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
|
|
633
657
|
else {
|
|
@@ -638,7 +662,7 @@ function makeCreateCommand() {
|
|
|
638
662
|
}
|
|
639
663
|
function makeDoctorCommand() {
|
|
640
664
|
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) => {
|
|
641
|
-
const am2 = new AssetManager({ projectDir:
|
|
665
|
+
const am2 = new AssetManager({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
642
666
|
const issues = await am2.doctor();
|
|
643
667
|
if (issues.length === 0) {
|
|
644
668
|
logOk("No missing dependencies.");
|
|
@@ -666,21 +690,21 @@ function claudeSkillRoots() {
|
|
|
666
690
|
const roots = [];
|
|
667
691
|
const override = process.env.SKAILE_CLAUDE_SKILLS_DIR;
|
|
668
692
|
if (override) roots.push(override);
|
|
669
|
-
roots.push(
|
|
693
|
+
roots.push(path35.join(os.homedir(), ".claude", "skills"));
|
|
670
694
|
return roots;
|
|
671
695
|
}
|
|
672
696
|
function resolveImportSource(nameOrPath) {
|
|
673
|
-
const asPath =
|
|
674
|
-
if (
|
|
675
|
-
const dir =
|
|
676
|
-
const skillFile =
|
|
677
|
-
if (
|
|
697
|
+
const asPath = path35.resolve(nameOrPath);
|
|
698
|
+
if (fs11.existsSync(asPath)) {
|
|
699
|
+
const dir = fs11.statSync(asPath).isDirectory() ? asPath : path35.dirname(asPath);
|
|
700
|
+
const skillFile = path35.join(dir, "SKILL.md");
|
|
701
|
+
if (fs11.existsSync(skillFile)) return { dir, skillFile, via: "path" };
|
|
678
702
|
}
|
|
679
|
-
if (!nameOrPath.includes(
|
|
703
|
+
if (!nameOrPath.includes(path35.sep) && !nameOrPath.startsWith(".")) {
|
|
680
704
|
for (const root of claudeSkillRoots()) {
|
|
681
|
-
const dir =
|
|
682
|
-
const skillFile =
|
|
683
|
-
if (
|
|
705
|
+
const dir = path35.join(root, nameOrPath);
|
|
706
|
+
const skillFile = path35.join(dir, "SKILL.md");
|
|
707
|
+
if (fs11.existsSync(skillFile)) return { dir, skillFile, via: "claude-skills" };
|
|
684
708
|
}
|
|
685
709
|
}
|
|
686
710
|
return null;
|
|
@@ -733,39 +757,59 @@ ${body}
|
|
|
733
757
|
const changed = notes.length > 0;
|
|
734
758
|
return { content, name, originalName, changed, notes };
|
|
735
759
|
}
|
|
736
|
-
var DOMAIN_TEMPLATE = (
|
|
737
|
-
const fm = stringify({
|
|
760
|
+
var DOMAIN_TEMPLATE = (slug, publisher, description) => {
|
|
761
|
+
const fm = stringify({ slug, title: slug, publisher, description }).trimEnd();
|
|
738
762
|
return `---
|
|
739
763
|
${fm}
|
|
740
764
|
---
|
|
741
765
|
|
|
742
|
-
# ${
|
|
766
|
+
# ${slug}
|
|
743
767
|
|
|
744
768
|
${description}
|
|
745
769
|
`;
|
|
746
770
|
};
|
|
747
771
|
function ensureDomain(libraryPath, domain, opts = {}) {
|
|
748
|
-
const dir =
|
|
749
|
-
const domainFile =
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
return {
|
|
772
|
+
const dir = path35.join(libraryPath, domain);
|
|
773
|
+
const domainFile = path35.join(dir, "DOMAIN.md");
|
|
774
|
+
if (fs11.existsSync(domainFile)) {
|
|
775
|
+
const existing = readDomainMd(libraryPath, domain);
|
|
776
|
+
return {
|
|
777
|
+
dir,
|
|
778
|
+
publisher: existing?.publisher ?? opts.publisher ?? slugifyAssetName(domain),
|
|
779
|
+
created: false
|
|
780
|
+
};
|
|
753
781
|
}
|
|
754
|
-
|
|
782
|
+
if (!isValidDomainSlug(domain)) {
|
|
783
|
+
throw new Error(
|
|
784
|
+
`Invalid domain name "${domain}": use lowercase a-z, 0-9 and single hyphens (max 39 chars), e.g. "my-domain".`
|
|
785
|
+
);
|
|
786
|
+
}
|
|
787
|
+
const publisher = opts.publisher ?? slugifyAssetName(domain);
|
|
788
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
755
789
|
const description = opts.description ?? `The ${domain} domain.`;
|
|
756
|
-
|
|
790
|
+
fs11.writeFileSync(domainFile, DOMAIN_TEMPLATE(domain, publisher, description), "utf8");
|
|
757
791
|
return { dir, publisher, created: true };
|
|
758
792
|
}
|
|
793
|
+
function readDomainMd(libraryPath, domain) {
|
|
794
|
+
const domainFile = path35.join(libraryPath, domain, "DOMAIN.md");
|
|
795
|
+
try {
|
|
796
|
+
const { data } = parseFrontmatter(fs11.readFileSync(domainFile, "utf8"));
|
|
797
|
+
return parseDomainMd(`${domain}/DOMAIN.md`, data);
|
|
798
|
+
} catch {
|
|
799
|
+
return void 0;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
759
802
|
function listDomains(libraryPath) {
|
|
760
|
-
if (!
|
|
761
|
-
return
|
|
803
|
+
if (!fs11.existsSync(libraryPath)) return [];
|
|
804
|
+
return fs11.readdirSync(libraryPath, { withFileTypes: true }).filter((e) => e.isDirectory() && fs11.existsSync(path35.join(libraryPath, e.name, "DOMAIN.md"))).map((e) => e.name).sort();
|
|
762
805
|
}
|
|
763
806
|
function upsertManifestAsset(libraryPath, input) {
|
|
764
807
|
const manifest = loadSkPublishManifest(libraryPath) ?? { assets: [] };
|
|
765
808
|
const assets = Array.isArray(manifest.assets) ? [...manifest.assets] : [];
|
|
809
|
+
const overridesTopLevel = !!input.publisher && input.publisher !== manifest.publisher;
|
|
766
810
|
const entry = { kind: input.kind, name: input.name, root: input.root };
|
|
767
811
|
if (input.version) entry.version = input.version;
|
|
768
|
-
if (
|
|
812
|
+
if (overridesTopLevel) entry.publisher = input.publisher;
|
|
769
813
|
if (input.description) entry.description = input.description;
|
|
770
814
|
if (input.keywords && input.keywords.length > 0) entry.keywords = input.keywords;
|
|
771
815
|
const idx = assets.findIndex((a) => a.kind === input.kind && a.name === input.name);
|
|
@@ -773,7 +817,9 @@ function upsertManifestAsset(libraryPath, input) {
|
|
|
773
817
|
if (added) {
|
|
774
818
|
assets.push(entry);
|
|
775
819
|
} else {
|
|
776
|
-
|
|
820
|
+
const merged = { ...assets[idx], ...entry };
|
|
821
|
+
if (input.publisher && !overridesTopLevel) delete merged.publisher;
|
|
822
|
+
assets[idx] = merged;
|
|
777
823
|
}
|
|
778
824
|
const manifestPath = saveSkPublishManifest(libraryPath, { ...manifest, assets });
|
|
779
825
|
return { manifestPath, added };
|
|
@@ -799,6 +845,9 @@ async function resolveDefByRef(library, ref, opts) {
|
|
|
799
845
|
matches.sort((a, b) => rcompare(coerceVersion(a.version), coerceVersion(b.version)));
|
|
800
846
|
return matches[0];
|
|
801
847
|
}
|
|
848
|
+
function withCanonicalRef(def) {
|
|
849
|
+
return { ref: catalogAssetRef(def), ...def };
|
|
850
|
+
}
|
|
802
851
|
function makeAssetCommand() {
|
|
803
852
|
const cmd = new Command("asset").description("Author and install AI assets");
|
|
804
853
|
cmd.command("import <name-or-path>").description("Import + skailify an existing coding-agent skill into a library").option("--to <library>", "Target library (default: auto / personal)").option("--domain <name>", "Place under this domain's skills/ (created if missing)").option("--version <semver>", "Version to stamp when the skill ships none").option("--stage <stage>", "Lifecycle stage to stamp (default: alpha)").option("--no-normalize", "Copy verbatim \u2014 skip frontmatter normalization").option("--commit", "Auto-commit in git-backed libraries", false).action(
|
|
@@ -817,22 +866,20 @@ function makeAssetCommand() {
|
|
|
817
866
|
if (opts.to) {
|
|
818
867
|
target = await manager.requireLibrary(opts.to);
|
|
819
868
|
} else {
|
|
820
|
-
const
|
|
821
|
-
const def =
|
|
822
|
-
(l) => l.isDefault && (l.ownership === "owner" || l.ownership === "contributor")
|
|
823
|
-
);
|
|
869
|
+
const found = await manager.findDefaultLibrary();
|
|
870
|
+
const def = found && found.ownership !== "reader" ? found : void 0;
|
|
824
871
|
target = def ?? (await manager.ensurePersonalLibrary(resolveLibraryDir())).library;
|
|
825
872
|
}
|
|
826
873
|
if (target.ownership === "reader") {
|
|
827
874
|
logErr(`Library "${target.name}" is read-only (ownership=reader). Choose --to.`);
|
|
828
875
|
process.exit(1);
|
|
829
876
|
}
|
|
830
|
-
const rawSkill =
|
|
877
|
+
const rawSkill = fs11.readFileSync(src.skillFile, "utf8");
|
|
831
878
|
const norm = opts.normalize ? normalizeSkillContent(rawSkill, {
|
|
832
|
-
fallbackName:
|
|
879
|
+
fallbackName: path35.basename(src.dir),
|
|
833
880
|
version: opts.version,
|
|
834
881
|
stage: opts.stage
|
|
835
|
-
}) : { content: rawSkill, name:
|
|
882
|
+
}) : { content: rawSkill, name: path35.basename(src.dir), changed: false, notes: [] };
|
|
836
883
|
if (!opts.normalize && !isValidAssetName(norm.name)) {
|
|
837
884
|
logWarn(
|
|
838
885
|
`Name "${norm.name}" is not canonical (kebab-case); \`skaile validate\` will reject this manifest entry. Drop --no-normalize to slugify it.`
|
|
@@ -841,19 +888,25 @@ function makeAssetCommand() {
|
|
|
841
888
|
let destParent = target.path;
|
|
842
889
|
let publisher;
|
|
843
890
|
if (opts.domain) {
|
|
844
|
-
|
|
891
|
+
let dom;
|
|
892
|
+
try {
|
|
893
|
+
dom = ensureDomain(target.path, opts.domain);
|
|
894
|
+
} catch (err) {
|
|
895
|
+
logErr(err instanceof Error ? err.message : String(err));
|
|
896
|
+
process.exit(1);
|
|
897
|
+
}
|
|
845
898
|
if (dom.created) logOk(`Scaffolded domain ${S.cmd(opts.domain)} \u2192 ${dom.dir}`);
|
|
846
|
-
destParent =
|
|
899
|
+
destParent = path35.join(dom.dir, "skills");
|
|
847
900
|
publisher = dom.publisher;
|
|
848
901
|
}
|
|
849
|
-
|
|
850
|
-
const destDir =
|
|
851
|
-
if (
|
|
902
|
+
fs11.mkdirSync(destParent, { recursive: true });
|
|
903
|
+
const destDir = path35.join(destParent, norm.name);
|
|
904
|
+
if (fs11.existsSync(destDir)) {
|
|
852
905
|
logErr(`Destination already exists: ${destDir}`);
|
|
853
906
|
process.exit(1);
|
|
854
907
|
}
|
|
855
|
-
|
|
856
|
-
|
|
908
|
+
fs11.cpSync(src.dir, destDir, { recursive: true });
|
|
909
|
+
fs11.writeFileSync(path35.join(destDir, "SKILL.md"), norm.content, "utf8");
|
|
857
910
|
for (const note of norm.notes) logInfo(` \u2022 ${note}`);
|
|
858
911
|
const fm = parseFrontmatter(norm.content).data;
|
|
859
912
|
const descRaw = fm.description;
|
|
@@ -861,7 +914,7 @@ function makeAssetCommand() {
|
|
|
861
914
|
for (const f of checkAgentSkillConformance(fm, { dirName: norm.name })) {
|
|
862
915
|
logWarn(`conformance: ${f.field} \u2014 ${f.message}`);
|
|
863
916
|
}
|
|
864
|
-
const root =
|
|
917
|
+
const root = path35.relative(target.path, destDir);
|
|
865
918
|
const up = upsertManifestAsset(target.path, {
|
|
866
919
|
kind: "skill",
|
|
867
920
|
name: norm.name,
|
|
@@ -872,9 +925,9 @@ function makeAssetCommand() {
|
|
|
872
925
|
});
|
|
873
926
|
logOk(`${up.added ? "Added" : "Updated"} manifest entry skill:${norm.name}`);
|
|
874
927
|
if (target.backend === "git" && opts.commit) {
|
|
875
|
-
const { spawnSync } = await import('child_process');
|
|
876
|
-
|
|
877
|
-
const r =
|
|
928
|
+
const { spawnSync: spawnSync2 } = await import('child_process');
|
|
929
|
+
spawnSync2("git", ["add", "--", destDir], { cwd: target.path, stdio: "inherit" });
|
|
930
|
+
const r = spawnSync2("git", ["commit", "-m", `skaile: import ${norm.name}`], {
|
|
878
931
|
cwd: target.path,
|
|
879
932
|
stdio: "inherit"
|
|
880
933
|
});
|
|
@@ -895,7 +948,7 @@ function makeAssetCommand() {
|
|
|
895
948
|
logErr(`Invalid --mode "${opts.mode}". Expected: copy | move | link.`);
|
|
896
949
|
process.exit(1);
|
|
897
950
|
}
|
|
898
|
-
if (!
|
|
951
|
+
if (!fs11.existsSync(srcPath)) {
|
|
899
952
|
logErr(`Source path does not exist: ${srcPath}`);
|
|
900
953
|
process.exit(1);
|
|
901
954
|
}
|
|
@@ -905,10 +958,8 @@ function makeAssetCommand() {
|
|
|
905
958
|
if (opts.to) {
|
|
906
959
|
target = await manager.requireLibrary(opts.to);
|
|
907
960
|
} else {
|
|
908
|
-
const
|
|
909
|
-
const def =
|
|
910
|
-
(l) => l.isDefault && (l.ownership === "owner" || l.ownership === "contributor")
|
|
911
|
-
);
|
|
961
|
+
const found = await manager.findDefaultLibrary();
|
|
962
|
+
const def = found && found.ownership !== "reader" ? found : void 0;
|
|
912
963
|
if (def) {
|
|
913
964
|
target = def;
|
|
914
965
|
} else {
|
|
@@ -922,29 +973,29 @@ function makeAssetCommand() {
|
|
|
922
973
|
);
|
|
923
974
|
process.exit(1);
|
|
924
975
|
}
|
|
925
|
-
const basename2 =
|
|
926
|
-
const destDir = target.structure === "domain" && opts.domain ?
|
|
927
|
-
|
|
928
|
-
const destPath =
|
|
929
|
-
if (
|
|
976
|
+
const basename2 = path35.basename(srcPath);
|
|
977
|
+
const destDir = target.structure === "domain" && opts.domain ? path35.join(target.path, opts.domain) : target.path;
|
|
978
|
+
fs11.mkdirSync(destDir, { recursive: true });
|
|
979
|
+
const destPath = path35.join(destDir, basename2);
|
|
980
|
+
if (fs11.existsSync(destPath)) {
|
|
930
981
|
logErr(`Destination already exists: ${destPath}`);
|
|
931
982
|
process.exit(1);
|
|
932
983
|
}
|
|
933
984
|
switch (opts.mode) {
|
|
934
985
|
case "copy":
|
|
935
|
-
|
|
986
|
+
fs11.cpSync(srcPath, destPath, { recursive: true });
|
|
936
987
|
break;
|
|
937
988
|
case "move":
|
|
938
|
-
|
|
989
|
+
fs11.renameSync(srcPath, destPath);
|
|
939
990
|
break;
|
|
940
991
|
case "link":
|
|
941
|
-
|
|
992
|
+
fs11.symlinkSync(path35.resolve(srcPath), destPath);
|
|
942
993
|
break;
|
|
943
994
|
}
|
|
944
995
|
if (target.backend === "git" && opts.commit) {
|
|
945
|
-
const { spawnSync } = await import('child_process');
|
|
946
|
-
|
|
947
|
-
const r =
|
|
996
|
+
const { spawnSync: spawnSync2 } = await import('child_process');
|
|
997
|
+
spawnSync2("git", ["add", "--", destPath], { cwd: target.path, stdio: "inherit" });
|
|
998
|
+
const r = spawnSync2("git", ["commit", "-m", `skaile: migrate ${basename2}`], {
|
|
948
999
|
cwd: target.path,
|
|
949
1000
|
stdio: "inherit"
|
|
950
1001
|
});
|
|
@@ -995,19 +1046,19 @@ function makeAssetCommand() {
|
|
|
995
1046
|
}
|
|
996
1047
|
const manifestPath = def.manifest.path;
|
|
997
1048
|
const candidateSubpath = typeof manifestPath === "string" && manifestPath.length > 0 ? manifestPath : def.name;
|
|
998
|
-
const srcPath =
|
|
999
|
-
if (!
|
|
1049
|
+
const srcPath = path35.join(lib.path, candidateSubpath);
|
|
1050
|
+
if (!fs11.existsSync(srcPath)) {
|
|
1000
1051
|
logErr(`Asset path not found: ${srcPath}`);
|
|
1001
1052
|
process.exit(1);
|
|
1002
1053
|
}
|
|
1003
|
-
const destPath =
|
|
1004
|
-
|
|
1054
|
+
const destPath = path35.join(target, candidateSubpath);
|
|
1055
|
+
fs11.mkdirSync(path35.dirname(destPath), { recursive: true });
|
|
1005
1056
|
if (opts.mode === "copy") {
|
|
1006
|
-
|
|
1057
|
+
fs11.cpSync(srcPath, destPath, { recursive: true });
|
|
1007
1058
|
} else {
|
|
1008
|
-
|
|
1059
|
+
fs11.symlinkSync(path35.resolve(srcPath), destPath);
|
|
1009
1060
|
}
|
|
1010
|
-
logOk(`Installed ${
|
|
1061
|
+
logOk(`Installed ${catalogAssetRef(def)} \u2192 ${destPath} (${opts.mode})`);
|
|
1011
1062
|
} finally {
|
|
1012
1063
|
close();
|
|
1013
1064
|
}
|
|
@@ -1022,7 +1073,7 @@ function makeAssetCommand() {
|
|
|
1022
1073
|
logErr(`Not found: ${ref}`);
|
|
1023
1074
|
process.exit(1);
|
|
1024
1075
|
}
|
|
1025
|
-
console.log(JSON.stringify(def, null, 2));
|
|
1076
|
+
console.log(JSON.stringify(withCanonicalRef(def), null, 2));
|
|
1026
1077
|
} finally {
|
|
1027
1078
|
close();
|
|
1028
1079
|
}
|
|
@@ -1070,14 +1121,14 @@ function makeAuthCommand() {
|
|
|
1070
1121
|
}
|
|
1071
1122
|
function collectCacheTargets(scope) {
|
|
1072
1123
|
const out = [];
|
|
1073
|
-
out.push(
|
|
1074
|
-
out.push(
|
|
1075
|
-
out.push(
|
|
1124
|
+
out.push(path35__default.join(scope.projectDir, ".skaile", "cache"));
|
|
1125
|
+
out.push(path35__default.join(scope.projectDir, ".skaile", "store-cache"));
|
|
1126
|
+
out.push(path35__default.join(scope.projectDir, ".skaile", "repos"));
|
|
1076
1127
|
if (scope.global) {
|
|
1077
1128
|
out.push(globalCacheRoot());
|
|
1078
|
-
const home =
|
|
1079
|
-
out.push(
|
|
1080
|
-
out.push(
|
|
1129
|
+
const home = globalSkaileDir();
|
|
1130
|
+
out.push(path35__default.join(home, "repos"));
|
|
1131
|
+
out.push(path35__default.join(home, "catalog-cache"));
|
|
1081
1132
|
}
|
|
1082
1133
|
return out;
|
|
1083
1134
|
}
|
|
@@ -1091,7 +1142,7 @@ function dirSize(target) {
|
|
|
1091
1142
|
function dirSizeOfDir(dir) {
|
|
1092
1143
|
let total = 0;
|
|
1093
1144
|
for (const ent of readdirSync(dir, { withFileTypes: true })) {
|
|
1094
|
-
const child =
|
|
1145
|
+
const child = path35__default.join(dir, ent.name);
|
|
1095
1146
|
if (ent.isSymbolicLink()) continue;
|
|
1096
1147
|
if (ent.isDirectory()) total += dirSizeOfDir(child);
|
|
1097
1148
|
else if (ent.isFile()) total += statSync(child).size;
|
|
@@ -1117,7 +1168,7 @@ function makeCacheCommand() {
|
|
|
1117
1168
|
const cmd = new Command("cache").description("Inspect and reclaim the re-derivable cache");
|
|
1118
1169
|
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) => {
|
|
1119
1170
|
const targets = collectCacheTargets({
|
|
1120
|
-
projectDir:
|
|
1171
|
+
projectDir: path35__default.resolve(opts.projectDir),
|
|
1121
1172
|
global: opts.global
|
|
1122
1173
|
}).filter((t) => existsSync(t));
|
|
1123
1174
|
if (targets.length === 0) {
|
|
@@ -1147,12 +1198,12 @@ function makeCacheCommand() {
|
|
|
1147
1198
|
for (const r of removed) logOk(`Removed ${r}`);
|
|
1148
1199
|
});
|
|
1149
1200
|
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) => {
|
|
1150
|
-
console.log(
|
|
1201
|
+
console.log(path35__default.join(path35__default.resolve(opts.projectDir), ".skaile", "cache"));
|
|
1151
1202
|
if (opts.global) console.log(globalCacheRoot());
|
|
1152
1203
|
});
|
|
1153
1204
|
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) => {
|
|
1154
1205
|
const targets = collectCacheTargets({
|
|
1155
|
-
projectDir:
|
|
1206
|
+
projectDir: path35__default.resolve(opts.projectDir),
|
|
1156
1207
|
global: opts.global
|
|
1157
1208
|
});
|
|
1158
1209
|
console.log();
|
|
@@ -1168,7 +1219,7 @@ function makeCatalogCommand() {
|
|
|
1168
1219
|
const catalog = new Command("catalog").description("Catalog source health and configuration");
|
|
1169
1220
|
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) => {
|
|
1170
1221
|
const { resolveConfig, isLocalCatalogUrl, trpcGetUrl } = await import('../library/index.js');
|
|
1171
|
-
const projectDir = opts.projectDir ?
|
|
1222
|
+
const projectDir = opts.projectDir ? path35__default.resolve(opts.projectDir) : void 0;
|
|
1172
1223
|
const cfg = resolveConfig({ projectDir });
|
|
1173
1224
|
const baseUrl = opts.url ?? cfg.catalog.url;
|
|
1174
1225
|
if (isLocalCatalogUrl(baseUrl)) {
|
|
@@ -1186,7 +1237,7 @@ function makeCatalogCommand() {
|
|
|
1186
1237
|
});
|
|
1187
1238
|
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) => {
|
|
1188
1239
|
const { resolveConfig } = await import('../library/index.js');
|
|
1189
|
-
const projectDir = opts.projectDir ?
|
|
1240
|
+
const projectDir = opts.projectDir ? path35__default.resolve(opts.projectDir) : void 0;
|
|
1190
1241
|
const cfg = resolveConfig({ projectDir });
|
|
1191
1242
|
console.log(`url: ${cfg.catalog.url}`);
|
|
1192
1243
|
console.log(`framing: ${cfg.catalog.framing}`);
|
|
@@ -1195,7 +1246,7 @@ function makeCatalogCommand() {
|
|
|
1195
1246
|
return catalog;
|
|
1196
1247
|
}
|
|
1197
1248
|
async function runLocalCatalogTest(projectDir) {
|
|
1198
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
1249
|
+
const { resolveCatalogSource } = await import('../open-library-SUVOMIWZ.js');
|
|
1199
1250
|
let resolved;
|
|
1200
1251
|
try {
|
|
1201
1252
|
resolved = await resolveCatalogSource({ projectDir });
|
|
@@ -1333,7 +1384,7 @@ function findSkills(domain) {
|
|
|
1333
1384
|
const found = [];
|
|
1334
1385
|
for (const root of aiResourceRoots()) {
|
|
1335
1386
|
for (const { dir, domain: dirDomain } of assetSearchDirs(root, "skills")) {
|
|
1336
|
-
if (
|
|
1387
|
+
if (fs11__default.existsSync(dir)) walkSkills(dir, dirDomain, found);
|
|
1337
1388
|
}
|
|
1338
1389
|
}
|
|
1339
1390
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -1346,11 +1397,11 @@ function findSkills(domain) {
|
|
|
1346
1397
|
return deduped;
|
|
1347
1398
|
}
|
|
1348
1399
|
function walkSkills(dir, domain, out) {
|
|
1349
|
-
for (const entry of
|
|
1350
|
-
const full =
|
|
1400
|
+
for (const entry of fs11__default.readdirSync(dir, { withFileTypes: true })) {
|
|
1401
|
+
const full = path35__default.join(dir, entry.name);
|
|
1351
1402
|
if (entry.isDirectory()) {
|
|
1352
|
-
const skillMd =
|
|
1353
|
-
if (
|
|
1403
|
+
const skillMd = path35__default.join(full, "SKILL.md");
|
|
1404
|
+
if (fs11__default.existsSync(skillMd)) {
|
|
1354
1405
|
out.push({ name: entry.name, path: full, skillPath: skillMd, domain });
|
|
1355
1406
|
} else {
|
|
1356
1407
|
walkSkills(full, domain, out);
|
|
@@ -1363,13 +1414,6 @@ function walkSkills(dir, domain, out) {
|
|
|
1363
1414
|
function resolveSkillNames() {
|
|
1364
1415
|
return findSkills().map((s) => s.name);
|
|
1365
1416
|
}
|
|
1366
|
-
function resolveDomains() {
|
|
1367
|
-
const domains = /* @__PURE__ */ new Set();
|
|
1368
|
-
for (const root of aiResourceRoots()) {
|
|
1369
|
-
for (const d of detectDomains(root)) domains.add(d.id);
|
|
1370
|
-
}
|
|
1371
|
-
return [...domains];
|
|
1372
|
-
}
|
|
1373
1417
|
function resolveFlowIds() {
|
|
1374
1418
|
try {
|
|
1375
1419
|
return discoverFlows().map((f) => f.id);
|
|
@@ -1378,10 +1422,10 @@ function resolveFlowIds() {
|
|
|
1378
1422
|
}
|
|
1379
1423
|
}
|
|
1380
1424
|
function resolveSessionIds(projectDir) {
|
|
1381
|
-
const sessionsDir =
|
|
1382
|
-
if (!
|
|
1425
|
+
const sessionsDir = path35__default.join(projectDir, ".skaile", "sessions");
|
|
1426
|
+
if (!fs11__default.existsSync(sessionsDir)) return [];
|
|
1383
1427
|
try {
|
|
1384
|
-
return
|
|
1428
|
+
return fs11__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
1385
1429
|
} catch {
|
|
1386
1430
|
return [];
|
|
1387
1431
|
}
|
|
@@ -1426,8 +1470,7 @@ function resolveDynamic(words, cword) {
|
|
|
1426
1470
|
const isLast = (i) => cword === i;
|
|
1427
1471
|
if (cmd === "run" && isLast(2)) return resolveFlowIds();
|
|
1428
1472
|
if (cmd === "flow" && sub === "show" && isLast(3)) return resolveFlowIds();
|
|
1429
|
-
if (cmd === "
|
|
1430
|
-
if (cmd === "skill" && sub === "list" && isLast(3)) return resolveDomains();
|
|
1473
|
+
if (cmd === "show" && sub === "skill" && isLast(3)) return resolveSkillNames();
|
|
1431
1474
|
if (cmd === "session" && ["show", "switch", "delete"].includes(sub) && isLast(3)) {
|
|
1432
1475
|
return resolveSessionIds(process.cwd());
|
|
1433
1476
|
}
|
|
@@ -1521,7 +1564,7 @@ function printResolvedPathsSection(config) {
|
|
|
1521
1564
|
console.log(` ${S.label("prompts:".padEnd(16))} ${config.promptsDir ?? paths.promptsDir}`);
|
|
1522
1565
|
}
|
|
1523
1566
|
async function showConfig(opts) {
|
|
1524
|
-
const projectDir = opts.projectDir ?
|
|
1567
|
+
const projectDir = opts.projectDir ? path35__default.resolve(opts.projectDir) : process.cwd();
|
|
1525
1568
|
let config;
|
|
1526
1569
|
let wsDefaults;
|
|
1527
1570
|
try {
|
|
@@ -1566,13 +1609,13 @@ function makeConfigCommand() {
|
|
|
1566
1609
|
const cmd = new Command("config").description("Manage personal config (.skaile/settings.json)");
|
|
1567
1610
|
cmd.command("show").description("Show effective config with sources").option("--project-dir <path>", "Project directory").action((opts) => showConfig(opts));
|
|
1568
1611
|
cmd.command("get <key>").description("Get an effective config value").option("--project-dir <path>", "Project directory").action(async (key, opts) => {
|
|
1569
|
-
const projectDir = opts.projectDir ?
|
|
1612
|
+
const projectDir = opts.projectDir ? path35__default.resolve(opts.projectDir) : process.cwd();
|
|
1570
1613
|
const config = await resolveSettings(projectDir);
|
|
1571
1614
|
const value = config[key];
|
|
1572
1615
|
console.log(value ?? S.dim("(not set)"));
|
|
1573
1616
|
});
|
|
1574
1617
|
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) => {
|
|
1575
|
-
const projectDir = opts.projectDir ?
|
|
1618
|
+
const projectDir = opts.projectDir ? path35__default.resolve(opts.projectDir) : process.cwd();
|
|
1576
1619
|
if (key === "provider" || key === "cloud" || key === "cloudConfig") {
|
|
1577
1620
|
logErr(
|
|
1578
1621
|
`'${key}' is no longer a setting \u2014 an endpoint is an AI provider registry entry and a session selects one with a model reference.
|
|
@@ -1912,8 +1955,8 @@ function makeConnectorCommand() {
|
|
|
1912
1955
|
async (driver, opts) => {
|
|
1913
1956
|
const { installNpmPackages } = await import('../connectors/index.js');
|
|
1914
1957
|
const { scanDirectory: scanDirectory2, factoryAssetRoots: factoryAssetRoots2, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
1915
|
-
const projectDir =
|
|
1916
|
-
const yamlPath =
|
|
1958
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
1959
|
+
const yamlPath = path35__default.join(projectDir, "skaile.yaml");
|
|
1917
1960
|
if (!existsSync(yamlPath)) {
|
|
1918
1961
|
logErr("No skaile.yaml found in current directory. Run 'skaile init' first.");
|
|
1919
1962
|
process.exit(1);
|
|
@@ -1973,8 +2016,8 @@ ${installResult.output}`);
|
|
|
1973
2016
|
);
|
|
1974
2017
|
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) => {
|
|
1975
2018
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
1976
|
-
const projectDir =
|
|
1977
|
-
const yamlPath =
|
|
2019
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2020
|
+
const yamlPath = path35__default.join(projectDir, "skaile.yaml");
|
|
1978
2021
|
if (!existsSync(yamlPath)) {
|
|
1979
2022
|
logErr("No skaile.yaml found in current directory.");
|
|
1980
2023
|
process.exit(1);
|
|
@@ -1991,7 +2034,7 @@ ${installResult.output}`);
|
|
|
1991
2034
|
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) => {
|
|
1992
2035
|
const res = await import('../connectors/index.js');
|
|
1993
2036
|
res.registerBuiltinConnectors();
|
|
1994
|
-
const projectDir =
|
|
2037
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
1995
2038
|
const declarations = res.loadConnectorDeclarations(projectDir);
|
|
1996
2039
|
if (declarations.length === 0) {
|
|
1997
2040
|
console.log("No connectors configured in skaile.yaml.");
|
|
@@ -2015,7 +2058,7 @@ ${installResult.output}`);
|
|
|
2015
2058
|
await manager.disconnectAll();
|
|
2016
2059
|
});
|
|
2017
2060
|
cmd.command("list").description("List all configured connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
2018
|
-
const projectDir =
|
|
2061
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2019
2062
|
const manager = await connectConnectors(projectDir);
|
|
2020
2063
|
try {
|
|
2021
2064
|
console.log(JSON.stringify(manager.listConnectors(), null, 2));
|
|
@@ -2024,7 +2067,7 @@ ${installResult.output}`);
|
|
|
2024
2067
|
}
|
|
2025
2068
|
});
|
|
2026
2069
|
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) => {
|
|
2027
|
-
const projectDir =
|
|
2070
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2028
2071
|
const manager = await connectConnectors(projectDir);
|
|
2029
2072
|
try {
|
|
2030
2073
|
if (opts.all) {
|
|
@@ -2048,7 +2091,7 @@ ${installResult.output}`);
|
|
|
2048
2091
|
}
|
|
2049
2092
|
});
|
|
2050
2093
|
cmd.command("ops <id>").description("List available operations for a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
|
|
2051
|
-
const projectDir =
|
|
2094
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2052
2095
|
const manager = await connectConnectors(projectDir);
|
|
2053
2096
|
try {
|
|
2054
2097
|
if (!manager.has(id)) {
|
|
@@ -2063,7 +2106,7 @@ ${installResult.output}`);
|
|
|
2063
2106
|
}
|
|
2064
2107
|
});
|
|
2065
2108
|
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) => {
|
|
2066
|
-
const projectDir =
|
|
2109
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2067
2110
|
const manager = await connectConnectors(projectDir);
|
|
2068
2111
|
try {
|
|
2069
2112
|
const content = await manager.read(id, resourcePath);
|
|
@@ -2073,7 +2116,7 @@ ${installResult.output}`);
|
|
|
2073
2116
|
}
|
|
2074
2117
|
});
|
|
2075
2118
|
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) => {
|
|
2076
|
-
const projectDir =
|
|
2119
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2077
2120
|
const manager = await connectConnectors(projectDir);
|
|
2078
2121
|
try {
|
|
2079
2122
|
await manager.write(id, resourcePath, { data: content });
|
|
@@ -2083,7 +2126,7 @@ ${installResult.output}`);
|
|
|
2083
2126
|
}
|
|
2084
2127
|
});
|
|
2085
2128
|
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) => {
|
|
2086
|
-
const projectDir =
|
|
2129
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2087
2130
|
const manager = await connectConnectors(projectDir);
|
|
2088
2131
|
try {
|
|
2089
2132
|
const entries = await manager.list(id, resourcePath, {
|
|
@@ -2096,7 +2139,7 @@ ${installResult.output}`);
|
|
|
2096
2139
|
}
|
|
2097
2140
|
});
|
|
2098
2141
|
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) => {
|
|
2099
|
-
const projectDir =
|
|
2142
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2100
2143
|
const manager = await connectConnectors(projectDir);
|
|
2101
2144
|
try {
|
|
2102
2145
|
const results = await manager.search(id, query);
|
|
@@ -2106,7 +2149,7 @@ ${installResult.output}`);
|
|
|
2106
2149
|
}
|
|
2107
2150
|
});
|
|
2108
2151
|
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) => {
|
|
2109
|
-
const projectDir =
|
|
2152
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2110
2153
|
const manager = await connectConnectors(projectDir);
|
|
2111
2154
|
try {
|
|
2112
2155
|
const ok = await manager.delete(id, resourcePath);
|
|
@@ -2116,7 +2159,7 @@ ${installResult.output}`);
|
|
|
2116
2159
|
}
|
|
2117
2160
|
});
|
|
2118
2161
|
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) => {
|
|
2119
|
-
const projectDir =
|
|
2162
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2120
2163
|
const manager = await connectConnectors(projectDir);
|
|
2121
2164
|
try {
|
|
2122
2165
|
if (!manager.has(id)) {
|
|
@@ -2225,7 +2268,7 @@ function envRecord() {
|
|
|
2225
2268
|
async function buildDeployContext(projectDir) {
|
|
2226
2269
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2227
2270
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
2228
|
-
const workspaceId = config.name ??
|
|
2271
|
+
const workspaceId = config.name ?? path35__default.basename(projectDir);
|
|
2229
2272
|
let log;
|
|
2230
2273
|
try {
|
|
2231
2274
|
const { createLogger } = await import('../core/logging.js');
|
|
@@ -2257,13 +2300,13 @@ async function ensureTargetsRegistered(projectDir) {
|
|
|
2257
2300
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2258
2301
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
2259
2302
|
if (config.plugins && config.plugins.length > 0) {
|
|
2260
|
-
const { ensurePluginsLoaded } = await import('../plugin-store-
|
|
2303
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-D45CREMJ.js');
|
|
2261
2304
|
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
2262
2305
|
for (const f of result.failed) logWarn(f.error);
|
|
2263
2306
|
}
|
|
2264
2307
|
}
|
|
2265
2308
|
async function runUp(opts) {
|
|
2266
|
-
const projectDir =
|
|
2309
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2267
2310
|
await ensureTargetsRegistered(projectDir);
|
|
2268
2311
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2269
2312
|
const { resolveDeployTarget, pluginRegistry } = await import('../plugin-registry/index.js');
|
|
@@ -2331,7 +2374,7 @@ async function restoreFromHandle(projectDir) {
|
|
|
2331
2374
|
return { target, handle, ctx };
|
|
2332
2375
|
}
|
|
2333
2376
|
async function runDown(opts) {
|
|
2334
|
-
const projectDir =
|
|
2377
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2335
2378
|
const restored = await restoreFromHandle(projectDir);
|
|
2336
2379
|
if (!restored) return;
|
|
2337
2380
|
await restored.handle.stop();
|
|
@@ -2340,7 +2383,7 @@ async function runDown(opts) {
|
|
|
2340
2383
|
logOk(`Stopped ${S.cmd(restored.target.id)} and cleared the handle.`);
|
|
2341
2384
|
}
|
|
2342
2385
|
async function runStatus(opts) {
|
|
2343
|
-
const projectDir =
|
|
2386
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2344
2387
|
const restored = await restoreFromHandle(projectDir);
|
|
2345
2388
|
if (!restored) return;
|
|
2346
2389
|
const health = await restored.handle.health();
|
|
@@ -2354,7 +2397,7 @@ async function runStatus(opts) {
|
|
|
2354
2397
|
console.log();
|
|
2355
2398
|
}
|
|
2356
2399
|
async function runLogs(opts) {
|
|
2357
|
-
const projectDir =
|
|
2400
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2358
2401
|
const restored = await restoreFromHandle(projectDir);
|
|
2359
2402
|
if (!restored) return;
|
|
2360
2403
|
if (!restored.handle.logs) {
|
|
@@ -2378,19 +2421,29 @@ function makeDeployCommand() {
|
|
|
2378
2421
|
}
|
|
2379
2422
|
function makeDiffCommand() {
|
|
2380
2423
|
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) => {
|
|
2381
|
-
const am2 = new AssetManager({ projectDir:
|
|
2424
|
+
const am2 = new AssetManager({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
2382
2425
|
const result = await am2.diff(ref);
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2426
|
+
switch (result.status) {
|
|
2427
|
+
case "not-found":
|
|
2428
|
+
logErr(`Asset not found: ${ref}`);
|
|
2429
|
+
process.exitCode = 1;
|
|
2430
|
+
return;
|
|
2431
|
+
case "not-deployed":
|
|
2432
|
+
logWarn(`${ref} is not deployed \u2014 run skaile install`);
|
|
2433
|
+
return;
|
|
2434
|
+
case "identical":
|
|
2435
|
+
logInfo("No differences.");
|
|
2436
|
+
return;
|
|
2437
|
+
case "differs":
|
|
2438
|
+
console.log(result.diff);
|
|
2439
|
+
return;
|
|
2386
2440
|
}
|
|
2387
|
-
console.log(result);
|
|
2388
2441
|
});
|
|
2389
2442
|
}
|
|
2390
2443
|
function makeFlowCommand() {
|
|
2391
2444
|
const cmd = new Command("flow").description("Manage flows");
|
|
2392
2445
|
cmd.command("list").description("List available flows").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
2393
|
-
const flows = discoverFlows(
|
|
2446
|
+
const flows = discoverFlows(path35__default.resolve(opts.projectDir));
|
|
2394
2447
|
if (flows.length === 0) {
|
|
2395
2448
|
logInfo("No flows found.");
|
|
2396
2449
|
return;
|
|
@@ -2405,7 +2458,7 @@ function makeFlowCommand() {
|
|
|
2405
2458
|
console.log();
|
|
2406
2459
|
});
|
|
2407
2460
|
cmd.command("show <id>").description("Show flow details and node graph").option("--project-dir <path>", "Project directory", process.cwd()).action(async (id, opts) => {
|
|
2408
|
-
const flows = discoverFlows(
|
|
2461
|
+
const flows = discoverFlows(path35__default.resolve(opts.projectDir));
|
|
2409
2462
|
const flow = flows.find((f) => f.id === id);
|
|
2410
2463
|
if (!flow) {
|
|
2411
2464
|
logErr(`Flow not found: ${id}`);
|
|
@@ -2437,7 +2490,7 @@ function makeFlowCommand() {
|
|
|
2437
2490
|
function makeHistoryCommand() {
|
|
2438
2491
|
const cmd = new Command("history").description("Show recent add/remove/update actions");
|
|
2439
2492
|
cmd.argument("[limit]", "Number of entries to show", "20").option("--project-dir <path>", "Project directory", process.cwd()).action((limitStr, opts) => {
|
|
2440
|
-
const am2 = new AssetManager({ projectDir:
|
|
2493
|
+
const am2 = new AssetManager({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
2441
2494
|
const limit = parseInt(limitStr, 10) || 20;
|
|
2442
2495
|
const entries = am2.history(limit);
|
|
2443
2496
|
if (entries.length === 0) {
|
|
@@ -2457,7 +2510,7 @@ function makeHistoryCommand() {
|
|
|
2457
2510
|
console.log();
|
|
2458
2511
|
});
|
|
2459
2512
|
cmd.command("clear").description("Clear action history").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
2460
|
-
const am2 = new AssetManager({ projectDir:
|
|
2513
|
+
const am2 = new AssetManager({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
2461
2514
|
am2.clearHistory();
|
|
2462
2515
|
logOk("History cleared.");
|
|
2463
2516
|
});
|
|
@@ -2470,7 +2523,7 @@ var MCP_SERVER_ENTRY = {
|
|
|
2470
2523
|
env: {}
|
|
2471
2524
|
};
|
|
2472
2525
|
function pluginDir(projectDir) {
|
|
2473
|
-
return
|
|
2526
|
+
return path35__default.join(projectDir, ".claude", "plugins", "skaile");
|
|
2474
2527
|
}
|
|
2475
2528
|
async function readJsonStrict(p7) {
|
|
2476
2529
|
let raw;
|
|
@@ -2488,7 +2541,7 @@ async function readJsonStrict(p7) {
|
|
|
2488
2541
|
}
|
|
2489
2542
|
}
|
|
2490
2543
|
async function writeJson(p7, value) {
|
|
2491
|
-
await fs5.mkdir(
|
|
2544
|
+
await fs5.mkdir(path35__default.dirname(p7), { recursive: true });
|
|
2492
2545
|
await fs5.writeFile(p7, `${JSON.stringify(value, null, 2)}
|
|
2493
2546
|
`);
|
|
2494
2547
|
}
|
|
@@ -2496,8 +2549,8 @@ async function copyDir(src, dest) {
|
|
|
2496
2549
|
await fs5.mkdir(dest, { recursive: true });
|
|
2497
2550
|
const entries = await fs5.readdir(src, { withFileTypes: true });
|
|
2498
2551
|
for (const entry of entries) {
|
|
2499
|
-
const srcPath =
|
|
2500
|
-
const destPath =
|
|
2552
|
+
const srcPath = path35__default.join(src, entry.name);
|
|
2553
|
+
const destPath = path35__default.join(dest, entry.name);
|
|
2501
2554
|
if (entry.isDirectory()) await copyDir(srcPath, destPath);
|
|
2502
2555
|
else await fs5.copyFile(srcPath, destPath);
|
|
2503
2556
|
}
|
|
@@ -2506,14 +2559,14 @@ async function install(projectDir, opts) {
|
|
|
2506
2559
|
return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);
|
|
2507
2560
|
}
|
|
2508
2561
|
async function installMcp(projectDir) {
|
|
2509
|
-
const mcpPath =
|
|
2562
|
+
const mcpPath = path35__default.join(projectDir, ".claude", "mcp.json");
|
|
2510
2563
|
const existing = await readJsonStrict(mcpPath) ?? {};
|
|
2511
2564
|
const mcpServers = { ...existing.mcpServers ?? {} };
|
|
2512
2565
|
const previous = mcpServers[SKAILE_MCP_NAME];
|
|
2513
2566
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);
|
|
2514
2567
|
let warning;
|
|
2515
2568
|
if (previous && !matches) {
|
|
2516
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${
|
|
2569
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path35__default.relative(projectDir, mcpPath)}`;
|
|
2517
2570
|
}
|
|
2518
2571
|
mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;
|
|
2519
2572
|
await writeJson(mcpPath, { ...existing, mcpServers });
|
|
@@ -2522,15 +2575,15 @@ async function installMcp(projectDir) {
|
|
|
2522
2575
|
async function installFullPlugin(projectDir) {
|
|
2523
2576
|
const dir = pluginDir(projectDir);
|
|
2524
2577
|
for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {
|
|
2525
|
-
const dest =
|
|
2526
|
-
await fs5.mkdir(
|
|
2578
|
+
const dest = path35__default.join(dir, rel);
|
|
2579
|
+
await fs5.mkdir(path35__default.dirname(dest), { recursive: true });
|
|
2527
2580
|
await fs5.writeFile(dest, content);
|
|
2528
2581
|
}
|
|
2529
|
-
const projectSkillsDir =
|
|
2582
|
+
const projectSkillsDir = path35__default.join(projectDir, ".skaile", "skills");
|
|
2530
2583
|
if (existsSync(projectSkillsDir)) {
|
|
2531
|
-
await copyDir(projectSkillsDir,
|
|
2584
|
+
await copyDir(projectSkillsDir, path35__default.join(dir, "skills"));
|
|
2532
2585
|
}
|
|
2533
|
-
const settingsPath =
|
|
2586
|
+
const settingsPath = path35__default.join(projectDir, ".claude", "settings.json");
|
|
2534
2587
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2535
2588
|
const plugins = settings.plugins ?? [];
|
|
2536
2589
|
if (!plugins.includes(dir)) plugins.push(dir);
|
|
@@ -2538,8 +2591,8 @@ async function installFullPlugin(projectDir) {
|
|
|
2538
2591
|
return { changed: true, method: "plugin" };
|
|
2539
2592
|
}
|
|
2540
2593
|
async function uninstall(projectDir) {
|
|
2541
|
-
const settingsPath =
|
|
2542
|
-
const mcpPath =
|
|
2594
|
+
const settingsPath = path35__default.join(projectDir, ".claude", "settings.json");
|
|
2595
|
+
const mcpPath = path35__default.join(projectDir, ".claude", "mcp.json");
|
|
2543
2596
|
const dir = pluginDir(projectDir);
|
|
2544
2597
|
let changed = false;
|
|
2545
2598
|
const settings = await readJsonStrict(settingsPath);
|
|
@@ -2573,12 +2626,12 @@ async function uninstall(projectDir) {
|
|
|
2573
2626
|
async function detectInstall(projectDir) {
|
|
2574
2627
|
const dir = pluginDir(projectDir);
|
|
2575
2628
|
const settings = await readJsonStrict(
|
|
2576
|
-
|
|
2629
|
+
path35__default.join(projectDir, ".claude", "settings.json")
|
|
2577
2630
|
);
|
|
2578
|
-
if (existsSync(
|
|
2631
|
+
if (existsSync(path35__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
|
|
2579
2632
|
return { method: "plugin", pluginPath: dir };
|
|
2580
2633
|
}
|
|
2581
|
-
const mcp = await readJsonStrict(
|
|
2634
|
+
const mcp = await readJsonStrict(path35__default.join(projectDir, ".claude", "mcp.json"));
|
|
2582
2635
|
if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {
|
|
2583
2636
|
return { method: "mcp" };
|
|
2584
2637
|
}
|
|
@@ -2587,7 +2640,7 @@ async function detectInstall(projectDir) {
|
|
|
2587
2640
|
async function enable(projectDir) {
|
|
2588
2641
|
const detected = await detectInstall(projectDir);
|
|
2589
2642
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
2590
|
-
const settingsPath =
|
|
2643
|
+
const settingsPath = path35__default.join(projectDir, ".claude", "settings.json");
|
|
2591
2644
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2592
2645
|
if (detected.method === "plugin") {
|
|
2593
2646
|
const disabled2 = settings.disabledPlugins ?? [];
|
|
@@ -2609,7 +2662,7 @@ async function enable(projectDir) {
|
|
|
2609
2662
|
async function disable(projectDir) {
|
|
2610
2663
|
const detected = await detectInstall(projectDir);
|
|
2611
2664
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
2612
|
-
const settingsPath =
|
|
2665
|
+
const settingsPath = path35__default.join(projectDir, ".claude", "settings.json");
|
|
2613
2666
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2614
2667
|
if (detected.method === "plugin") {
|
|
2615
2668
|
const list2 = settings.disabledPlugins ?? [];
|
|
@@ -2629,12 +2682,12 @@ async function disable(projectDir) {
|
|
|
2629
2682
|
return { changed: true };
|
|
2630
2683
|
}
|
|
2631
2684
|
async function status(projectDir) {
|
|
2632
|
-
const settingsPath =
|
|
2633
|
-
const mcpPath =
|
|
2685
|
+
const settingsPath = path35__default.join(projectDir, ".claude", "settings.json");
|
|
2686
|
+
const mcpPath = path35__default.join(projectDir, ".claude", "mcp.json");
|
|
2634
2687
|
const dir = pluginDir(projectDir);
|
|
2635
2688
|
const settings = await readJsonStrict(settingsPath);
|
|
2636
2689
|
const mcp = await readJsonStrict(mcpPath);
|
|
2637
|
-
const pluginInstalled = !!(existsSync(
|
|
2690
|
+
const pluginInstalled = !!(existsSync(path35__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
|
|
2638
2691
|
const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);
|
|
2639
2692
|
if (!pluginInstalled && !mcpInstalled) {
|
|
2640
2693
|
return {
|
|
@@ -2652,7 +2705,7 @@ async function status(projectDir) {
|
|
|
2652
2705
|
installed: "yes",
|
|
2653
2706
|
enabled: disabled2 ? "no" : "yes",
|
|
2654
2707
|
method: "plugin",
|
|
2655
|
-
location:
|
|
2708
|
+
location: path35__default.relative(projectDir, dir)
|
|
2656
2709
|
};
|
|
2657
2710
|
}
|
|
2658
2711
|
const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;
|
|
@@ -2661,7 +2714,7 @@ async function status(projectDir) {
|
|
|
2661
2714
|
installed: "yes",
|
|
2662
2715
|
enabled: disabled ? "no" : "yes",
|
|
2663
2716
|
method: "mcp",
|
|
2664
|
-
location:
|
|
2717
|
+
location: path35__default.relative(projectDir, mcpPath)
|
|
2665
2718
|
};
|
|
2666
2719
|
}
|
|
2667
2720
|
var SKAILE_MCP_NAME2 = "skaile-workspace";
|
|
@@ -2688,7 +2741,7 @@ async function readConfig(p7) {
|
|
|
2688
2741
|
}
|
|
2689
2742
|
}
|
|
2690
2743
|
async function writeConfig(p7, value) {
|
|
2691
|
-
await fs5.mkdir(
|
|
2744
|
+
await fs5.mkdir(path35__default.dirname(p7), { recursive: true });
|
|
2692
2745
|
const cleaned = {};
|
|
2693
2746
|
for (const [k, v] of Object.entries(value)) {
|
|
2694
2747
|
if (v === void 0) continue;
|
|
@@ -2697,7 +2750,7 @@ async function writeConfig(p7, value) {
|
|
|
2697
2750
|
await fs5.writeFile(p7, stringify$1(cleaned));
|
|
2698
2751
|
}
|
|
2699
2752
|
function configPath(projectDir) {
|
|
2700
|
-
return
|
|
2753
|
+
return path35__default.join(projectDir, ".codex", "config.toml");
|
|
2701
2754
|
}
|
|
2702
2755
|
async function install2(projectDir) {
|
|
2703
2756
|
const p7 = configPath(projectDir);
|
|
@@ -2708,7 +2761,7 @@ async function install2(projectDir) {
|
|
|
2708
2761
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
|
|
2709
2762
|
let warning;
|
|
2710
2763
|
if (previous && !matches) {
|
|
2711
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${
|
|
2764
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path35__default.relative(projectDir, p7)}`;
|
|
2712
2765
|
}
|
|
2713
2766
|
if (matches) return { changed: false, method: "toml" };
|
|
2714
2767
|
servers[SKAILE_MCP_NAME2] = next;
|
|
@@ -2749,12 +2802,12 @@ async function status2(projectDir) {
|
|
|
2749
2802
|
installed: "yes",
|
|
2750
2803
|
enabled: "n/a",
|
|
2751
2804
|
method: "mcp",
|
|
2752
|
-
location:
|
|
2805
|
+
location: path35__default.relative(projectDir, p7)
|
|
2753
2806
|
};
|
|
2754
2807
|
}
|
|
2755
2808
|
async function install3(projectDir) {
|
|
2756
|
-
const extDir =
|
|
2757
|
-
const extPath =
|
|
2809
|
+
const extDir = path35__default.join(projectDir, ".omp", "extensions");
|
|
2810
|
+
const extPath = path35__default.join(extDir, "skaile.ts");
|
|
2758
2811
|
await fs5.mkdir(extDir, { recursive: true });
|
|
2759
2812
|
const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
|
|
2760
2813
|
const plugin = new WorkspacePlugin({ projectDir });
|
|
@@ -2769,7 +2822,7 @@ async function install3(projectDir) {
|
|
|
2769
2822
|
return { changed: true, method: "generated" };
|
|
2770
2823
|
}
|
|
2771
2824
|
async function uninstall3(projectDir) {
|
|
2772
|
-
const extPath =
|
|
2825
|
+
const extPath = path35__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
2773
2826
|
try {
|
|
2774
2827
|
await fs5.unlink(extPath);
|
|
2775
2828
|
return { changed: true };
|
|
@@ -2778,14 +2831,14 @@ async function uninstall3(projectDir) {
|
|
|
2778
2831
|
}
|
|
2779
2832
|
}
|
|
2780
2833
|
async function status3(projectDir) {
|
|
2781
|
-
const extPath =
|
|
2834
|
+
const extPath = path35__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
2782
2835
|
if (existsSync(extPath)) {
|
|
2783
2836
|
return {
|
|
2784
2837
|
harness: "omp",
|
|
2785
2838
|
installed: "yes",
|
|
2786
2839
|
enabled: "n/a",
|
|
2787
2840
|
method: "extension",
|
|
2788
|
-
location:
|
|
2841
|
+
location: path35__default.relative(projectDir, extPath)
|
|
2789
2842
|
};
|
|
2790
2843
|
}
|
|
2791
2844
|
return {
|
|
@@ -2848,7 +2901,7 @@ async function installCodex(projectDir) {
|
|
|
2848
2901
|
console.log(` ${S.dim("\u2192")} Restart Codex CLI to pick up the change.`);
|
|
2849
2902
|
}
|
|
2850
2903
|
async function runInstall(opts) {
|
|
2851
|
-
const projectDir =
|
|
2904
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2852
2905
|
const targets = resolveDriver(opts.driver);
|
|
2853
2906
|
let exitCode = 0;
|
|
2854
2907
|
if (targets.includes("claude-code")) {
|
|
@@ -2882,7 +2935,7 @@ async function uninstallCodex(projectDir) {
|
|
|
2882
2935
|
else logInfo(`codex: not installed`);
|
|
2883
2936
|
}
|
|
2884
2937
|
async function runUninstall(opts) {
|
|
2885
|
-
const projectDir =
|
|
2938
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2886
2939
|
const targets = resolveDriver(opts.driver);
|
|
2887
2940
|
let exitCode = 0;
|
|
2888
2941
|
if (targets.includes("claude-code")) {
|
|
@@ -2925,7 +2978,7 @@ async function toggleTarget(t, projectDir, action3) {
|
|
|
2925
2978
|
});
|
|
2926
2979
|
}
|
|
2927
2980
|
async function runToggle(opts, action3) {
|
|
2928
|
-
const projectDir =
|
|
2981
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2929
2982
|
const requestedAll = opts.driver === "all";
|
|
2930
2983
|
const targets = resolveDriver(opts.driver);
|
|
2931
2984
|
const usageError = checkToggleSupported(targets, requestedAll, action3);
|
|
@@ -2937,7 +2990,7 @@ async function runToggle(opts, action3) {
|
|
|
2937
2990
|
return exitCode;
|
|
2938
2991
|
}
|
|
2939
2992
|
async function runStatus2(opts) {
|
|
2940
|
-
const projectDir =
|
|
2993
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
2941
2994
|
const targets = resolveDriver(opts.driver);
|
|
2942
2995
|
const rows = [];
|
|
2943
2996
|
let exitCode = 0;
|
|
@@ -3008,7 +3061,7 @@ async function runHook(event) {
|
|
|
3008
3061
|
await plugin.shutdown();
|
|
3009
3062
|
return;
|
|
3010
3063
|
}
|
|
3011
|
-
const store = new PluginStore(
|
|
3064
|
+
const store = new PluginStore(path35__default.join(projectDir, ".skaile", "plugin-state.json"));
|
|
3012
3065
|
await store.load();
|
|
3013
3066
|
const status4 = store.get("connector:status");
|
|
3014
3067
|
if (status4 && typeof status4 === "object" && Object.keys(status4).length > 0) {
|
|
@@ -3068,6 +3121,8 @@ function makeIntegrationCommand() {
|
|
|
3068
3121
|
cmd.action(() => cmd.help());
|
|
3069
3122
|
return cmd;
|
|
3070
3123
|
}
|
|
3124
|
+
|
|
3125
|
+
// cli/src/commands/library-index.ts
|
|
3071
3126
|
async function indexLibrary(lib, index) {
|
|
3072
3127
|
const { LocalCatalogSource } = await import('../library/index.js');
|
|
3073
3128
|
const own = index ?? await openLibrary();
|
|
@@ -3084,15 +3139,7 @@ async function indexLibrary(lib, index) {
|
|
|
3084
3139
|
}
|
|
3085
3140
|
}
|
|
3086
3141
|
function domainPublisher(libraryPath, domain) {
|
|
3087
|
-
|
|
3088
|
-
if (!fs12.existsSync(domainFile)) return void 0;
|
|
3089
|
-
try {
|
|
3090
|
-
const { data } = parseFrontmatter(fs12.readFileSync(domainFile, "utf8"));
|
|
3091
|
-
const pub = data.publisher;
|
|
3092
|
-
return typeof pub === "string" && pub.trim() ? pub.trim() : void 0;
|
|
3093
|
-
} catch {
|
|
3094
|
-
return void 0;
|
|
3095
|
-
}
|
|
3142
|
+
return readDomainMd(libraryPath, domain)?.publisher;
|
|
3096
3143
|
}
|
|
3097
3144
|
function resolveLibraryPublisher(lib, opts, domain, storeIdentity) {
|
|
3098
3145
|
if (opts.publisher?.trim()) return opts.publisher.trim();
|
|
@@ -3110,8 +3157,54 @@ function resolveLibraryPublisher(lib, opts, domain, storeIdentity) {
|
|
|
3110
3157
|
}
|
|
3111
3158
|
|
|
3112
3159
|
// cli/src/commands/library-cmd.ts
|
|
3160
|
+
function exitOnSyncError(err) {
|
|
3161
|
+
logErr(err instanceof Error ? err.message : String(err));
|
|
3162
|
+
process.exit(1);
|
|
3163
|
+
}
|
|
3164
|
+
async function assertLibraryPathFree(manager, dir, exceptId) {
|
|
3165
|
+
const clash = (await manager.listLibraries()).find(
|
|
3166
|
+
(l) => l.id !== exceptId && path35.resolve(l.path) === dir
|
|
3167
|
+
);
|
|
3168
|
+
if (clash) throw new Error(`${dir} is already registered as library "${clash.name}".`);
|
|
3169
|
+
}
|
|
3170
|
+
function scaffoldLibraryFiles(dir, name) {
|
|
3171
|
+
const readme = `# ${name}
|
|
3172
|
+
|
|
3173
|
+
A skaile library: a collection of AI assets (skills, agents, flows) authored with the
|
|
3174
|
+
\`skaile library\` commands.
|
|
3175
|
+
|
|
3176
|
+
## Add an asset
|
|
3177
|
+
|
|
3178
|
+
\`\`\`sh
|
|
3179
|
+
skaile library create skill <asset-name> --library ${name}
|
|
3180
|
+
\`\`\`
|
|
3181
|
+
|
|
3182
|
+
The asset is scaffolded in this directory and indexed right away. Edit it, then commit it.
|
|
3183
|
+
|
|
3184
|
+
## Consume it
|
|
3185
|
+
|
|
3186
|
+
\`\`\`sh
|
|
3187
|
+
skaile add skill:@<publisher>/<asset-name>
|
|
3188
|
+
\`\`\`
|
|
3189
|
+
|
|
3190
|
+
Once this library is published (\`skaile library publish ${name}\`), anyone can add its assets
|
|
3191
|
+
by the same ref.
|
|
3192
|
+
`;
|
|
3193
|
+
const files = [
|
|
3194
|
+
["README.md", readme],
|
|
3195
|
+
[".gitignore", ".DS_Store\nnode_modules/\n*.log\n"]
|
|
3196
|
+
];
|
|
3197
|
+
const written = [];
|
|
3198
|
+
for (const [file, content] of files) {
|
|
3199
|
+
const target = path35.join(dir, file);
|
|
3200
|
+
if (fs11.existsSync(target)) continue;
|
|
3201
|
+
fs11.writeFileSync(target, content, "utf8");
|
|
3202
|
+
written.push(file);
|
|
3203
|
+
}
|
|
3204
|
+
return written;
|
|
3205
|
+
}
|
|
3113
3206
|
function makeLibraryCommand() {
|
|
3114
|
-
const cmd = new Command("library").description("Manage user authoring libraries (local / git)");
|
|
3207
|
+
const cmd = new Command("library").description("Manage user authoring libraries (local / git)").enablePositionalOptions();
|
|
3115
3208
|
cmd.command("list").description("List all registered libraries").option("--json", "Output as JSON").action(async (opts) => {
|
|
3116
3209
|
const { manager, close } = await openLibraryManager();
|
|
3117
3210
|
try {
|
|
@@ -3124,10 +3217,13 @@ function makeLibraryCommand() {
|
|
|
3124
3217
|
console.log();
|
|
3125
3218
|
console.log(S.heading(" Libraries"));
|
|
3126
3219
|
console.log(` ${S.rule(80)}`);
|
|
3220
|
+
const nameW = Math.max(...ls.map((l) => l.name.length));
|
|
3221
|
+
const backendW = Math.max(...ls.map((l) => l.backend.length));
|
|
3222
|
+
const ownerW = Math.max(...ls.map((l) => l.ownership.length));
|
|
3127
3223
|
for (const l of ls) {
|
|
3128
3224
|
const def = l.isDefault ? pc5.green("\u25B8 ") : " ";
|
|
3129
3225
|
console.log(
|
|
3130
|
-
`${def}${S.cmd(l.name.padEnd(
|
|
3226
|
+
`${def}${S.cmd(l.name.padEnd(nameW))} ${pc5.dim(l.backend.padEnd(backendW))} ${pc5.dim(l.ownership.padEnd(ownerW))} ${pc5.dim(l.path)}`
|
|
3131
3227
|
);
|
|
3132
3228
|
}
|
|
3133
3229
|
console.log(`
|
|
@@ -3164,33 +3260,65 @@ function makeLibraryCommand() {
|
|
|
3164
3260
|
close();
|
|
3165
3261
|
}
|
|
3166
3262
|
});
|
|
3167
|
-
cmd.command("init <name>").description("Create
|
|
3263
|
+
cmd.command("init <name>").description("Create (or adopt) a library \u2014 default location ~/.skaile/libraries/<name>").option("--git <url>", "Initialize as a git library tracking <url>").option("--path <dir>", "Register the library at <dir> (created if missing) instead").option("--owner", "Mark as owner (the default)").option("--contributor", "Mark as contributor (needs --git)").option("--reader", "Mark as reader (needs --git)").action(
|
|
3168
3264
|
async (name, opts) => {
|
|
3169
|
-
const
|
|
3170
|
-
|
|
3171
|
-
|
|
3265
|
+
const flagged = ["owner", "contributor", "reader"].filter((o) => opts[o]);
|
|
3266
|
+
if (flagged.length > 1) {
|
|
3267
|
+
logErr("Pick one of --owner, --contributor, --reader.");
|
|
3268
|
+
process.exit(1);
|
|
3269
|
+
}
|
|
3270
|
+
const ownership = flagged[0] ?? "owner";
|
|
3271
|
+
if (ownership !== "owner" && !opts.git) {
|
|
3272
|
+
logErr(
|
|
3273
|
+
`--${ownership} needs --git <url>: ownership only governs sync with a git remote, and a local library is always owned by you.`
|
|
3274
|
+
);
|
|
3275
|
+
process.exit(1);
|
|
3276
|
+
}
|
|
3277
|
+
const libPath = opts.path ? path35.resolve(opts.path) : path35.join(resolveLibraryDir(), name);
|
|
3278
|
+
if (fs11.existsSync(libPath) && !fs11.statSync(libPath).isDirectory()) {
|
|
3279
|
+
logErr(`${libPath} exists and is not a directory.`);
|
|
3280
|
+
process.exit(1);
|
|
3281
|
+
}
|
|
3172
3282
|
const { manager, close } = await openLibraryManager();
|
|
3173
3283
|
try {
|
|
3284
|
+
if (await manager.getLibrary(name)) {
|
|
3285
|
+
logErr(`A library named "${name}" is already registered.`);
|
|
3286
|
+
process.exit(1);
|
|
3287
|
+
}
|
|
3288
|
+
await assertLibraryPathFree(manager, libPath);
|
|
3289
|
+
const hasDefault = (await manager.listLibraries()).some((l) => l.isDefault);
|
|
3290
|
+
let backend = "local";
|
|
3291
|
+
let backendConfig;
|
|
3174
3292
|
if (opts.git) {
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
}
|
|
3293
|
+
const { branch, reason } = cloneOrInitGitRepo(libPath, opts.git, "main");
|
|
3294
|
+
if (reason) {
|
|
3295
|
+
logWarn(
|
|
3296
|
+
`Could not clone ${opts.git}; initialised an empty repo with that origin instead. git said: ${reason}`
|
|
3297
|
+
);
|
|
3298
|
+
}
|
|
3299
|
+
backend = "git";
|
|
3300
|
+
backendConfig = { url: opts.git, branch, authHint: "ssh" };
|
|
3183
3301
|
} else {
|
|
3184
|
-
|
|
3185
|
-
await manager.addLibrary({
|
|
3186
|
-
name,
|
|
3187
|
-
path: libPath,
|
|
3188
|
-
backend: "local",
|
|
3189
|
-
ownership: "owner",
|
|
3190
|
-
structure: "domain"
|
|
3191
|
-
});
|
|
3302
|
+
fs11.mkdirSync(libPath, { recursive: true });
|
|
3192
3303
|
}
|
|
3193
|
-
|
|
3304
|
+
const blank = fs11.readdirSync(libPath).every((entry) => entry === ".git");
|
|
3305
|
+
const isDefault = !hasDefault && ownership !== "reader";
|
|
3306
|
+
await manager.addLibrary({
|
|
3307
|
+
name,
|
|
3308
|
+
path: libPath,
|
|
3309
|
+
backend,
|
|
3310
|
+
backendConfig,
|
|
3311
|
+
ownership,
|
|
3312
|
+
structure: backend === "local" && blank ? "domain" : void 0,
|
|
3313
|
+
isDefault
|
|
3314
|
+
});
|
|
3315
|
+
const scaffolded = blank ? scaffoldLibraryFiles(libPath, name) : [];
|
|
3316
|
+
logOk(
|
|
3317
|
+
`Library "${name}" ${blank ? "created" : "registered"} at ${libPath}${isDefault ? " (default)" : ""}`
|
|
3318
|
+
);
|
|
3319
|
+
if (scaffolded.length > 0) logInfo(`Scaffolded ${scaffolded.join(", ")}.`);
|
|
3320
|
+
} catch (err) {
|
|
3321
|
+
exitOnSyncError(err);
|
|
3194
3322
|
} finally {
|
|
3195
3323
|
close();
|
|
3196
3324
|
}
|
|
@@ -3206,59 +3334,67 @@ function makeLibraryCommand() {
|
|
|
3206
3334
|
);
|
|
3207
3335
|
process.exit(1);
|
|
3208
3336
|
}
|
|
3337
|
+
ensureGitRepo(lib.path, url, opts.branch);
|
|
3209
3338
|
await manager.updateLibrary(name, {
|
|
3210
3339
|
backend: "git",
|
|
3211
3340
|
backendConfig: { url, branch: opts.branch, authHint: "ssh" }
|
|
3212
3341
|
});
|
|
3213
3342
|
logOk(`Library "${name}" linked to ${url}.`);
|
|
3343
|
+
} catch (err) {
|
|
3344
|
+
exitOnSyncError(err);
|
|
3214
3345
|
} finally {
|
|
3215
3346
|
close();
|
|
3216
3347
|
}
|
|
3217
3348
|
});
|
|
3218
|
-
cmd.command("create <kind> <name>").description("Scaffold a new asset inside the default (or named) library").addOption(new Option("--kind <kind>", "Asset kind override").choices([...ASSET_KINDS])).option("--library <name>", "Target library (default: the default-marked one)").option("--dir <dir>", "Target directory inside the library (default: library root)").option("--publisher <name>", "Publisher for the new asset (default: the library's default)").
|
|
3349
|
+
cmd.command("create <kind> <name>").description("Scaffold a new asset inside the default (or named) library").addOption(new Option("--kind <kind>", "Asset kind override").choices([...ASSET_KINDS])).option("--library <name>", "Target library (default: the default-marked one)").option("--dir <dir>", "Target directory inside the library (default: library root)").option("--publisher <name>", "Publisher for the new asset (default: the library's default)").option(
|
|
3350
|
+
"--description <text>",
|
|
3351
|
+
"Description for the manifest \u2014 say what it does and when to use it (default: a TODO placeholder `skaile validate` rejects)"
|
|
3352
|
+
).action(
|
|
3219
3353
|
async (kind, name, opts) => {
|
|
3220
3354
|
if (!ASSET_KINDS.includes(kind)) {
|
|
3221
3355
|
logErr(`Unknown asset kind "${kind}". Expected: ${ASSET_KINDS.join(", ")}.`);
|
|
3222
3356
|
process.exit(1);
|
|
3223
3357
|
}
|
|
3358
|
+
if (opts.description !== void 0) {
|
|
3359
|
+
const len = opts.description.trim().length;
|
|
3360
|
+
if (len === 0 || len > 1024) {
|
|
3361
|
+
logErr("--description must be 1\u20131024 characters (Agent Skills spec).");
|
|
3362
|
+
process.exit(1);
|
|
3363
|
+
}
|
|
3364
|
+
}
|
|
3224
3365
|
const { manager, library, close } = await openLibraryManager();
|
|
3225
3366
|
try {
|
|
3226
|
-
|
|
3227
|
-
if (opts.library) {
|
|
3228
|
-
target = await manager.requireLibrary(opts.library);
|
|
3229
|
-
} else {
|
|
3230
|
-
const all = await manager.listLibraries();
|
|
3231
|
-
const def = all.find((l) => l.isDefault);
|
|
3232
|
-
if (!def) {
|
|
3233
|
-
logErr(
|
|
3234
|
-
"No default library set. Either run `skaile library default <name>` first or pass --library."
|
|
3235
|
-
);
|
|
3236
|
-
process.exit(1);
|
|
3237
|
-
}
|
|
3238
|
-
target = def;
|
|
3239
|
-
}
|
|
3367
|
+
const target = await resolveTargetLibrary(manager, opts.library);
|
|
3240
3368
|
const effectiveKind = opts.kind ?? kind;
|
|
3241
3369
|
const am2 = new AssetManager({ projectDir: process.cwd() });
|
|
3242
|
-
const destDir = opts.dir ?
|
|
3243
|
-
const res = am2.create(name, effectiveKind, destDir);
|
|
3370
|
+
const destDir = opts.dir ? path35.join(target.path, opts.dir) : target.path;
|
|
3371
|
+
const res = am2.create(name, effectiveKind, destDir, { description: opts.description });
|
|
3244
3372
|
if (!res.ok) {
|
|
3245
3373
|
logErr(res.path);
|
|
3246
3374
|
process.exit(1);
|
|
3247
3375
|
}
|
|
3248
3376
|
logOk(`Created ${effectiveKind}: ${pc5.dim(res.path)}`);
|
|
3249
|
-
|
|
3377
|
+
if (opts.description === void 0 && effectiveKind === "skill") {
|
|
3378
|
+
logWarn(
|
|
3379
|
+
"Description is a TODO placeholder \u2014 edit it (what the skill does and when to use it) or `skaile validate` will fail."
|
|
3380
|
+
);
|
|
3381
|
+
}
|
|
3382
|
+
const domain2 = opts.dir ? opts.dir.split(path35.sep)[0] : void 0;
|
|
3250
3383
|
const publisher = resolveLibraryPublisher(target, opts, domain2, getStoreIdentity());
|
|
3251
3384
|
stampAssetPublisher(res.path, publisher);
|
|
3252
3385
|
ensureManifestPublisher(target.path, publisher);
|
|
3253
3386
|
upsertManifestAsset(target.path, {
|
|
3254
3387
|
kind: effectiveKind,
|
|
3255
3388
|
name,
|
|
3256
|
-
root:
|
|
3257
|
-
version: "0.1.0"
|
|
3389
|
+
root: path35.relative(target.path, res.path) || name,
|
|
3390
|
+
version: "0.1.0",
|
|
3391
|
+
publisher
|
|
3258
3392
|
});
|
|
3259
3393
|
const idx = await indexLibrary(target, library);
|
|
3260
3394
|
for (const e of idx.errors) logWarn(e);
|
|
3261
|
-
logOk(
|
|
3395
|
+
logOk(
|
|
3396
|
+
`Indexed \u2014 add it with \`skaile add ${refFor(effectiveKind, publisher, name, "0.1.0")}\``
|
|
3397
|
+
);
|
|
3262
3398
|
} finally {
|
|
3263
3399
|
close();
|
|
3264
3400
|
}
|
|
@@ -3267,11 +3403,9 @@ function makeLibraryCommand() {
|
|
|
3267
3403
|
const domain = cmd.command("domain").description("Manage domains (publisher namespaces) inside a library");
|
|
3268
3404
|
async function resolveTargetLibrary(manager, libraryName) {
|
|
3269
3405
|
if (libraryName) return manager.requireLibrary(libraryName);
|
|
3270
|
-
const
|
|
3271
|
-
const def = all.find((l) => l.isDefault);
|
|
3406
|
+
const def = await manager.findDefaultLibrary();
|
|
3272
3407
|
if (def) return def;
|
|
3273
|
-
if (
|
|
3274
|
-
if (all.length === 0) {
|
|
3408
|
+
if ((await manager.listLibraries()).length === 0) {
|
|
3275
3409
|
logErr("No libraries registered. Run `skaile library init <name>` first.");
|
|
3276
3410
|
process.exit(1);
|
|
3277
3411
|
}
|
|
@@ -3287,10 +3421,16 @@ function makeLibraryCommand() {
|
|
|
3287
3421
|
logErr(`Library "${target.name}" is read-only (ownership=reader).`);
|
|
3288
3422
|
process.exit(1);
|
|
3289
3423
|
}
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3424
|
+
let res;
|
|
3425
|
+
try {
|
|
3426
|
+
res = ensureDomain(target.path, name, {
|
|
3427
|
+
publisher: opts.publisher,
|
|
3428
|
+
description: opts.description
|
|
3429
|
+
});
|
|
3430
|
+
} catch (err) {
|
|
3431
|
+
logErr(err instanceof Error ? err.message : String(err));
|
|
3432
|
+
process.exit(1);
|
|
3433
|
+
}
|
|
3294
3434
|
if (target.structure !== "domain") {
|
|
3295
3435
|
await manager.updateLibrary(target.id, { structure: "domain" });
|
|
3296
3436
|
}
|
|
@@ -3328,12 +3468,12 @@ function makeLibraryCommand() {
|
|
|
3328
3468
|
const { manager, close } = await openLibraryManager();
|
|
3329
3469
|
try {
|
|
3330
3470
|
const target = await resolveTargetLibrary(manager, opts.library);
|
|
3331
|
-
const domainFile =
|
|
3471
|
+
const domainFile = path35.join(target.path, name, "DOMAIN.md");
|
|
3332
3472
|
if (!existsSync(domainFile)) {
|
|
3333
3473
|
logErr(`Domain "${name}" not found in "${target.name}" (no ${domainFile}).`);
|
|
3334
3474
|
process.exit(1);
|
|
3335
3475
|
}
|
|
3336
|
-
console.log(
|
|
3476
|
+
console.log(fs11.readFileSync(domainFile, "utf8"));
|
|
3337
3477
|
} finally {
|
|
3338
3478
|
close();
|
|
3339
3479
|
}
|
|
@@ -3351,20 +3491,22 @@ function makeLibraryCommand() {
|
|
|
3351
3491
|
const { manager, close } = await openLibraryManager();
|
|
3352
3492
|
try {
|
|
3353
3493
|
const lib = await manager.requireLibrary(oldName);
|
|
3354
|
-
const parent =
|
|
3355
|
-
const newPath =
|
|
3356
|
-
if (
|
|
3494
|
+
const parent = path35.dirname(lib.path);
|
|
3495
|
+
const newPath = path35.join(parent, newName);
|
|
3496
|
+
if (fs11.existsSync(newPath)) {
|
|
3357
3497
|
logErr(`Target directory already exists: ${newPath}`);
|
|
3358
3498
|
process.exit(1);
|
|
3359
3499
|
}
|
|
3360
|
-
|
|
3500
|
+
fs11.renameSync(lib.path, newPath);
|
|
3361
3501
|
await manager.updateLibrary(lib.id, { name: newName, path: newPath });
|
|
3362
3502
|
logOk(`Renamed ${oldName} \u2192 ${newName}`);
|
|
3363
3503
|
} finally {
|
|
3364
3504
|
close();
|
|
3365
3505
|
}
|
|
3366
3506
|
});
|
|
3367
|
-
cmd.command("set <name> <field=value>").description(
|
|
3507
|
+
cmd.command("set <name> <field=value>").description(
|
|
3508
|
+
"Update a single library field (ownership, structure, isDefault, path, backendConfig.<key>)"
|
|
3509
|
+
).action(async (name, expr) => {
|
|
3368
3510
|
const [field, ...rest] = expr.split("=");
|
|
3369
3511
|
const value = rest.join("=");
|
|
3370
3512
|
const { manager, close } = await openLibraryManager();
|
|
@@ -3374,8 +3516,20 @@ function makeLibraryCommand() {
|
|
|
3374
3516
|
if (field === "ownership") patch.ownership = value;
|
|
3375
3517
|
else if (field === "structure") patch.structure = value;
|
|
3376
3518
|
else if (field === "isDefault") patch.isDefault = value === "true";
|
|
3377
|
-
else if (field
|
|
3519
|
+
else if (field === "path") {
|
|
3520
|
+
const dir = path35.resolve(value);
|
|
3521
|
+
if (!fs11.existsSync(dir) || !fs11.statSync(dir).isDirectory()) {
|
|
3522
|
+
logErr(`Directory does not exist: ${dir}. \`library set path=\` does not move files.`);
|
|
3523
|
+
process.exit(1);
|
|
3524
|
+
}
|
|
3525
|
+
await assertLibraryPathFree(manager, dir, lib.id);
|
|
3526
|
+
patch.path = dir;
|
|
3527
|
+
} else if (field.startsWith("backendConfig.")) {
|
|
3378
3528
|
const key = field.split(".")[1];
|
|
3529
|
+
if (key === "url" && lib.backend === "git") {
|
|
3530
|
+
const branch = lib.backendConfig.branch ?? "main";
|
|
3531
|
+
ensureGitRepo(lib.path, value, branch);
|
|
3532
|
+
}
|
|
3379
3533
|
patch.backendConfig = { ...lib.backendConfig, [key]: value };
|
|
3380
3534
|
} else {
|
|
3381
3535
|
logErr(`Unsupported field: ${field}`);
|
|
@@ -3383,6 +3537,11 @@ function makeLibraryCommand() {
|
|
|
3383
3537
|
}
|
|
3384
3538
|
await manager.updateLibrary(name, patch);
|
|
3385
3539
|
logOk(`Updated ${name}.${field}`);
|
|
3540
|
+
if (field === "path") {
|
|
3541
|
+
logInfo(`Run \`skaile library index ${name}\` to re-index its assets from the new path.`);
|
|
3542
|
+
}
|
|
3543
|
+
} catch (err) {
|
|
3544
|
+
exitOnSyncError(err);
|
|
3386
3545
|
} finally {
|
|
3387
3546
|
close();
|
|
3388
3547
|
}
|
|
@@ -3419,6 +3578,8 @@ function makeLibraryCommand() {
|
|
|
3419
3578
|
}
|
|
3420
3579
|
await manager.updateLibrary(name, { lastSyncAt: /* @__PURE__ */ new Date() });
|
|
3421
3580
|
logOk(`Synced ${name}.`);
|
|
3581
|
+
} catch (err) {
|
|
3582
|
+
exitOnSyncError(err);
|
|
3422
3583
|
} finally {
|
|
3423
3584
|
close();
|
|
3424
3585
|
}
|
|
@@ -3427,7 +3588,7 @@ function makeLibraryCommand() {
|
|
|
3427
3588
|
const { manager, library, close } = await openLibraryManager();
|
|
3428
3589
|
try {
|
|
3429
3590
|
const lib = await manager.requireLibrary(name);
|
|
3430
|
-
await syncManifestWithDisk(lib
|
|
3591
|
+
await syncManifestWithDisk(lib);
|
|
3431
3592
|
const res = await indexLibrary(lib, library);
|
|
3432
3593
|
for (const e of res.errors) logWarn(e);
|
|
3433
3594
|
logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
|
|
@@ -3445,6 +3606,8 @@ function makeLibraryCommand() {
|
|
|
3445
3606
|
} else {
|
|
3446
3607
|
logOk(`Pulled ${res.applied} change(s).`);
|
|
3447
3608
|
}
|
|
3609
|
+
} catch (err) {
|
|
3610
|
+
exitOnSyncError(err);
|
|
3448
3611
|
} finally {
|
|
3449
3612
|
close();
|
|
3450
3613
|
}
|
|
@@ -3456,8 +3619,7 @@ function makeLibraryCommand() {
|
|
|
3456
3619
|
const res = await manager.driverFor(lib.backend).push(lib, { force: opts.force });
|
|
3457
3620
|
logOk(`Pushed (${res.pushed}).`);
|
|
3458
3621
|
} catch (err) {
|
|
3459
|
-
|
|
3460
|
-
process.exit(1);
|
|
3622
|
+
exitOnSyncError(err);
|
|
3461
3623
|
} finally {
|
|
3462
3624
|
close();
|
|
3463
3625
|
}
|
|
@@ -3469,8 +3631,7 @@ function makeLibraryCommand() {
|
|
|
3469
3631
|
const res = await manager.driverFor(lib.backend).propose(lib, opts);
|
|
3470
3632
|
logOk(`PR opened: ${res.prUrl}`);
|
|
3471
3633
|
} catch (err) {
|
|
3472
|
-
|
|
3473
|
-
process.exit(1);
|
|
3634
|
+
exitOnSyncError(err);
|
|
3474
3635
|
} finally {
|
|
3475
3636
|
close();
|
|
3476
3637
|
}
|
|
@@ -3483,45 +3644,72 @@ function makeLibraryCommand() {
|
|
|
3483
3644
|
logErr("`library commit` only applies to git-backed libraries.");
|
|
3484
3645
|
process.exit(1);
|
|
3485
3646
|
}
|
|
3486
|
-
|
|
3487
|
-
|
|
3647
|
+
if (!isGitRepo(lib.path)) {
|
|
3648
|
+
logErr(
|
|
3649
|
+
`${lib.path} is not a git repository. Run \`skaile library link ${name} <url>\` to initialise it.`
|
|
3650
|
+
);
|
|
3651
|
+
process.exit(1);
|
|
3652
|
+
}
|
|
3653
|
+
const add = spawnSync("git", ["add", "-A"], { cwd: lib.path, stdio: "inherit" });
|
|
3654
|
+
if (add.status !== 0) {
|
|
3655
|
+
logErr(`git add failed in ${lib.path}.`);
|
|
3656
|
+
process.exit(1);
|
|
3657
|
+
}
|
|
3658
|
+
const pending = spawnSync("git", ["status", "--porcelain"], {
|
|
3659
|
+
cwd: lib.path,
|
|
3660
|
+
encoding: "utf-8"
|
|
3661
|
+
});
|
|
3662
|
+
if (pending.status !== 0) {
|
|
3663
|
+
logErr(`git status failed in ${lib.path}: ${pending.stderr.trim()}`);
|
|
3664
|
+
process.exit(1);
|
|
3665
|
+
}
|
|
3666
|
+
if (pending.stdout.trim() === "") {
|
|
3667
|
+
logWarn("Nothing to commit (working tree clean).");
|
|
3668
|
+
return;
|
|
3669
|
+
}
|
|
3488
3670
|
const r = spawnSync("git", ["commit", "-m", opts.message], {
|
|
3489
3671
|
cwd: lib.path,
|
|
3490
3672
|
stdio: "inherit"
|
|
3491
3673
|
});
|
|
3492
3674
|
if (r.status !== 0) {
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
logOk(`Committed in ${name}.`);
|
|
3675
|
+
logErr("git commit failed.");
|
|
3676
|
+
process.exit(1);
|
|
3496
3677
|
}
|
|
3678
|
+
logOk(`Committed in ${name}.`);
|
|
3497
3679
|
} finally {
|
|
3498
3680
|
close();
|
|
3499
3681
|
}
|
|
3500
3682
|
});
|
|
3501
|
-
cmd.command("git <name>").description("Pass-through: run arbitrary git commands inside the library").allowUnknownOption().action(async (name,
|
|
3502
|
-
const args =
|
|
3683
|
+
cmd.command("git <name> [args...]").description("Pass-through: run arbitrary git commands inside the library").allowUnknownOption().passThroughOptions().action(async (name, rawArgs) => {
|
|
3684
|
+
const args = rawArgs[0] === "--" ? rawArgs.slice(1) : rawArgs;
|
|
3503
3685
|
const { manager, close } = await openLibraryManager();
|
|
3504
3686
|
try {
|
|
3505
3687
|
const lib = await manager.requireLibrary(name);
|
|
3506
|
-
const { spawnSync } = await import('child_process');
|
|
3507
3688
|
const r = spawnSync("git", args, { cwd: lib.path, stdio: "inherit" });
|
|
3508
|
-
|
|
3689
|
+
if (r.error) {
|
|
3690
|
+
logErr(`Could not run git: ${r.error.message}`);
|
|
3691
|
+
process.exit(1);
|
|
3692
|
+
}
|
|
3693
|
+
process.exit(r.status ?? 1);
|
|
3509
3694
|
} finally {
|
|
3510
3695
|
close();
|
|
3511
3696
|
}
|
|
3512
3697
|
});
|
|
3513
|
-
cmd.command("publish <lib>").description("Push + register the library's manifest atomically (needs git backend)").option("--asset <ref>", "Publish only the single asset matching this ref/name").option("--create-repo", "Provision + link a
|
|
3698
|
+
cmd.command("publish <lib>").description("Push + register the library's manifest atomically (needs git backend)").option("--asset <ref>", "Publish only the single asset matching this ref/name").option("--create-repo", "Provision + link a github repo if the library has no remote").option(
|
|
3699
|
+
"--private",
|
|
3700
|
+
"With --create-repo: create the repo private (the store only accepts public repos)"
|
|
3701
|
+
).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(
|
|
3514
3702
|
async (lib, opts) => {
|
|
3515
|
-
const { runLibraryPublish } = await import('../library-publish-
|
|
3703
|
+
const { runLibraryPublish } = await import('../library-publish-2PNWJJOY.js');
|
|
3516
3704
|
await withStoreErrorHandling(() => runLibraryPublish(lib, opts));
|
|
3517
3705
|
}
|
|
3518
3706
|
);
|
|
3519
3707
|
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) => {
|
|
3520
|
-
const { runLibraryRegister } = await import('../library-publish-
|
|
3708
|
+
const { runLibraryRegister } = await import('../library-publish-2PNWJJOY.js');
|
|
3521
3709
|
await withStoreErrorHandling(() => runLibraryRegister(lib, opts));
|
|
3522
3710
|
});
|
|
3523
3711
|
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) => {
|
|
3524
|
-
const { runLibraryYank } = await import('../library-publish-
|
|
3712
|
+
const { runLibraryYank } = await import('../library-publish-2PNWJJOY.js');
|
|
3525
3713
|
await withStoreErrorHandling(() => runLibraryYank(lib, opts));
|
|
3526
3714
|
});
|
|
3527
3715
|
return cmd;
|
|
@@ -3538,24 +3726,24 @@ function stampAssetPublisher(assetDir, publisher) {
|
|
|
3538
3726
|
const markers = ["SKILL.md", "AGENT.md", "CONTRACT.md"];
|
|
3539
3727
|
let markerFile;
|
|
3540
3728
|
for (const m of markers) {
|
|
3541
|
-
if (
|
|
3542
|
-
markerFile =
|
|
3729
|
+
if (fs11.existsSync(path35.join(assetDir, m))) {
|
|
3730
|
+
markerFile = path35.join(assetDir, m);
|
|
3543
3731
|
break;
|
|
3544
3732
|
}
|
|
3545
3733
|
}
|
|
3546
3734
|
if (!markerFile) {
|
|
3547
|
-
const promptMd =
|
|
3548
|
-
if (promptMd) markerFile =
|
|
3735
|
+
const promptMd = fs11.readdirSync(assetDir).find((f) => f.endsWith(".prompt.md"));
|
|
3736
|
+
if (promptMd) markerFile = path35.join(assetDir, promptMd);
|
|
3549
3737
|
}
|
|
3550
3738
|
if (!markerFile) return;
|
|
3551
3739
|
try {
|
|
3552
|
-
const { data, body } = parseFrontmatter(
|
|
3740
|
+
const { data, body } = parseFrontmatter(fs11.readFileSync(markerFile, "utf8"));
|
|
3553
3741
|
const meta = data.metadata && typeof data.metadata === "object" && !Array.isArray(data.metadata) ? { ...data.metadata } : {};
|
|
3554
3742
|
if (meta.publisher != null) return;
|
|
3555
3743
|
meta.publisher = publisher;
|
|
3556
3744
|
data.metadata = meta;
|
|
3557
3745
|
const fm = stringify(data).trimEnd();
|
|
3558
|
-
|
|
3746
|
+
fs11.writeFileSync(markerFile, `---
|
|
3559
3747
|
${fm}
|
|
3560
3748
|
---
|
|
3561
3749
|
|
|
@@ -3569,11 +3757,28 @@ function ensureManifestPublisher(libraryPath, publisher) {
|
|
|
3569
3757
|
if (manifest.publisher) return;
|
|
3570
3758
|
saveSkPublishManifest(libraryPath, { ...manifest, publisher });
|
|
3571
3759
|
}
|
|
3572
|
-
async function syncManifestWithDisk(
|
|
3573
|
-
const
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3760
|
+
async function syncManifestWithDisk(lib) {
|
|
3761
|
+
const libraryPath = lib.path;
|
|
3762
|
+
if (!loadSkPublishManifest(libraryPath)?.publisher) {
|
|
3763
|
+
ensureManifestPublisher(
|
|
3764
|
+
libraryPath,
|
|
3765
|
+
resolveLibraryPublisher(lib, {}, void 0, getStoreIdentity())
|
|
3766
|
+
);
|
|
3767
|
+
}
|
|
3768
|
+
const manifest = loadSkPublishManifest(libraryPath);
|
|
3769
|
+
const repoName = manifest?.publisher ?? slugifyAssetName(lib.name);
|
|
3770
|
+
for (const e of await scanDirectory(libraryPath, repoName)) {
|
|
3771
|
+
const root = path35.relative(libraryPath, path35.dirname(e.source)) || e.name;
|
|
3772
|
+
const existing = manifest?.assets?.find((a) => a.kind === e.kind && a.name === e.name);
|
|
3773
|
+
const segments = root.split(/[\\/]/);
|
|
3774
|
+
const publisher = existing?.publisher || segments.length < 2 ? void 0 : domainPublisher(libraryPath, segments[0]);
|
|
3775
|
+
upsertManifestAsset(libraryPath, {
|
|
3776
|
+
kind: e.kind,
|
|
3777
|
+
name: e.name,
|
|
3778
|
+
root,
|
|
3779
|
+
version: e.version,
|
|
3780
|
+
publisher
|
|
3781
|
+
});
|
|
3577
3782
|
}
|
|
3578
3783
|
}
|
|
3579
3784
|
async function printPerLibraryStatus(name, asJson) {
|
|
@@ -3614,9 +3819,9 @@ async function printOverallStatus(projectDir, asJson) {
|
|
|
3614
3819
|
} catch {
|
|
3615
3820
|
secretsStrategy = "unavailable";
|
|
3616
3821
|
}
|
|
3617
|
-
const resolvedProjectDir =
|
|
3618
|
-
const hasWorkspaceConfig = existsSync(
|
|
3619
|
-
const hasLockFile = existsSync(
|
|
3822
|
+
const resolvedProjectDir = path35.resolve(projectDir);
|
|
3823
|
+
const hasWorkspaceConfig = existsSync(path35.join(resolvedProjectDir, "skaile.yaml"));
|
|
3824
|
+
const hasLockFile = existsSync(path35.join(resolvedProjectDir, "skaile.lock.yaml"));
|
|
3620
3825
|
let assignments = [];
|
|
3621
3826
|
if (hasWorkspaceConfig) {
|
|
3622
3827
|
try {
|
|
@@ -4243,7 +4448,7 @@ function scheduleSoftDepPreview() {
|
|
|
4243
4448
|
}
|
|
4244
4449
|
async function loadAssets() {
|
|
4245
4450
|
softDepPreviewCache.clear();
|
|
4246
|
-
const { gatherAssetFeeds } = await import('../asset-feeds-
|
|
4451
|
+
const { gatherAssetFeeds } = await import('../asset-feeds-UYIFZKKG.js');
|
|
4247
4452
|
const { entries, domains, notes } = await gatherAssetFeeds(am, am.projectDir);
|
|
4248
4453
|
if (notes.length > 0) {
|
|
4249
4454
|
state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
|
|
@@ -4265,7 +4470,7 @@ function rebuildSourceTree() {
|
|
|
4265
4470
|
rebuildVisibleSources();
|
|
4266
4471
|
}
|
|
4267
4472
|
function sourceOrgRepo(s) {
|
|
4268
|
-
const parts = s.path.split(
|
|
4473
|
+
const parts = s.path.split(path35__default.sep).filter(Boolean);
|
|
4269
4474
|
if (parts.length < 2) return null;
|
|
4270
4475
|
return { org: parts[parts.length - 2], repo: parts[parts.length - 1] };
|
|
4271
4476
|
}
|
|
@@ -4448,15 +4653,14 @@ function reconcileCollapsedSets(rows) {
|
|
|
4448
4653
|
}
|
|
4449
4654
|
async function loadSourcesAndLibraries() {
|
|
4450
4655
|
try {
|
|
4451
|
-
const [{ openLibraryManager: openLibraryManager2 }, {
|
|
4452
|
-
import('../open-library-
|
|
4453
|
-
import('../library/index.js'),
|
|
4656
|
+
const [{ openLibraryManager: openLibraryManager2 }, { getGlobalCacheDir: getGlobalCacheDir2, globalSkaileDir: globalSkaileDir2 }] = await Promise.all([
|
|
4657
|
+
import('../open-library-SUVOMIWZ.js'),
|
|
4454
4658
|
import('../core/index.js')
|
|
4455
4659
|
]);
|
|
4456
4660
|
const { manager, library, close } = await openLibraryManager2();
|
|
4457
4661
|
try {
|
|
4458
4662
|
const newRoot = getGlobalCacheDir2();
|
|
4459
|
-
const legacyRoot =
|
|
4663
|
+
const legacyRoot = path35__default.join(globalSkaileDir2(), "sources");
|
|
4460
4664
|
const isSourceRow = (l) => l.path.startsWith(newRoot) || l.path.startsWith(legacyRoot);
|
|
4461
4665
|
const libs = await manager.listLibraries();
|
|
4462
4666
|
const defs = await library.listAssetDefs();
|
|
@@ -5516,13 +5720,13 @@ async function run(projectDir) {
|
|
|
5516
5720
|
}
|
|
5517
5721
|
function makeManageCommand() {
|
|
5518
5722
|
return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
5519
|
-
await run(
|
|
5723
|
+
await run(path35__default.resolve(opts.projectDir));
|
|
5520
5724
|
});
|
|
5521
5725
|
}
|
|
5522
5726
|
function makeMcpServerCommand() {
|
|
5523
5727
|
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) => {
|
|
5524
|
-
const
|
|
5525
|
-
const projectDir =
|
|
5728
|
+
const path38 = await import('path');
|
|
5729
|
+
const projectDir = path38.default.resolve(opts.projectDir);
|
|
5526
5730
|
const { LogStore, StdoutSink, registerLogStore } = await import('../core/logging.js');
|
|
5527
5731
|
registerLogStore(
|
|
5528
5732
|
new LogStore({
|
|
@@ -5692,7 +5896,7 @@ function workspaceConfigFiles(dir) {
|
|
|
5692
5896
|
} catch {
|
|
5693
5897
|
return [];
|
|
5694
5898
|
}
|
|
5695
|
-
return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) =>
|
|
5899
|
+
return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) => path35__default.join(dir, name));
|
|
5696
5900
|
}
|
|
5697
5901
|
function readAgentConfigBlock(raw) {
|
|
5698
5902
|
const key = AGENT_CONFIG_KEYS.find((candidate) => raw[candidate] !== void 0);
|
|
@@ -5704,7 +5908,7 @@ function readAgentConfigBlock(raw) {
|
|
|
5704
5908
|
return flat ? { key, profiles: { default: profiles }, flat } : { key, profiles, flat };
|
|
5705
5909
|
}
|
|
5706
5910
|
function planProviderMigration(options) {
|
|
5707
|
-
const projectDir =
|
|
5911
|
+
const projectDir = path35__default.resolve(options.projectDir);
|
|
5708
5912
|
const registryPath = options.workspace ? workspaceProviderRegistryPath(projectDir) : userProviderRegistryPath();
|
|
5709
5913
|
const plan = {
|
|
5710
5914
|
registryPath,
|
|
@@ -5720,7 +5924,7 @@ function planProviderMigration(options) {
|
|
|
5720
5924
|
raw = parseDocument(readFileSync(file, "utf-8")).toJS() ?? {};
|
|
5721
5925
|
} catch (error) {
|
|
5722
5926
|
plan.warnings.push(
|
|
5723
|
-
`${
|
|
5927
|
+
`${path35__default.basename(file)}: not valid YAML (${error instanceof Error ? error.message : String(error)}) \u2014 skipped`
|
|
5724
5928
|
);
|
|
5725
5929
|
continue;
|
|
5726
5930
|
}
|
|
@@ -5769,7 +5973,7 @@ function planProviderMigration(options) {
|
|
|
5769
5973
|
});
|
|
5770
5974
|
if (!model) {
|
|
5771
5975
|
plan.warnings.push(
|
|
5772
|
-
`${
|
|
5976
|
+
`${path35__default.basename(file)}: profile '${profile}' had no model: \u2014 it now resolves against registry order. Pin it with 'model: ${providerId}/<modelId>'.`
|
|
5773
5977
|
);
|
|
5774
5978
|
}
|
|
5775
5979
|
touched = true;
|
|
@@ -5836,7 +6040,7 @@ function printPlan(plan) {
|
|
|
5836
6040
|
for (const entry of plan.entries) {
|
|
5837
6041
|
const base = entry.entry.base_url ?? S.dim("(transport-derived)");
|
|
5838
6042
|
console.log(
|
|
5839
|
-
` ${S.label(`${
|
|
6043
|
+
` ${S.label(`${path35__default.basename(entry.file)} ${entry.profile}`)} provider: ${entry.legacy.provider}, cloud: ${entry.legacy.cloud}`
|
|
5840
6044
|
);
|
|
5841
6045
|
console.log(` \u2192 providers.yml ${S.bold(entry.providerId)} ${base}`);
|
|
5842
6046
|
console.log(
|
|
@@ -5852,7 +6056,7 @@ function printPlan(plan) {
|
|
|
5852
6056
|
console.log();
|
|
5853
6057
|
}
|
|
5854
6058
|
async function runMigrateProviders(opts) {
|
|
5855
|
-
const projectDir = opts.projectDir ?
|
|
6059
|
+
const projectDir = opts.projectDir ? path35__default.resolve(opts.projectDir) : process.cwd();
|
|
5856
6060
|
const plan = planProviderMigration({ projectDir, workspace: opts.workspace });
|
|
5857
6061
|
for (const warning of plan.warnings) logWarn(warning);
|
|
5858
6062
|
if (plan.entries.length === 0 && Object.keys(plan.providers).length === 0) {
|
|
@@ -5912,8 +6116,8 @@ function makeNpxCommand() {
|
|
|
5912
6116
|
skills.command("add <url>").description(
|
|
5913
6117
|
"Clone a repo, register it in the project's skaile.yaml sources[], and install a skill from it"
|
|
5914
6118
|
).requiredOption("--skill <name>", "Skill name to install from the repo").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", "Agent framework", "claude-code").option("--global", "Deploy globally").action(async (url, opts) => {
|
|
5915
|
-
const projectDir =
|
|
5916
|
-
const projYaml =
|
|
6119
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
6120
|
+
const projYaml = path35__default.join(projectDir, "skaile.yaml");
|
|
5917
6121
|
if (!existsSync(projYaml)) {
|
|
5918
6122
|
logErr(`No skaile.yaml in ${projectDir} \u2014 run \`skaile init\` first.`);
|
|
5919
6123
|
process.exit(1);
|
|
@@ -5926,11 +6130,11 @@ function makeNpxCommand() {
|
|
|
5926
6130
|
}
|
|
5927
6131
|
const spinner4 = p5.spinner();
|
|
5928
6132
|
const key = sourceCacheKey(url);
|
|
5929
|
-
const clonePath =
|
|
6133
|
+
const clonePath = path35__default.join(getGlobalCacheDir(), key);
|
|
5930
6134
|
spinner4.start(`Cloning ${url}`);
|
|
5931
6135
|
try {
|
|
5932
6136
|
if (!existsSync(clonePath)) {
|
|
5933
|
-
mkdirSync(
|
|
6137
|
+
mkdirSync(path35__default.dirname(clonePath), { recursive: true });
|
|
5934
6138
|
execSync(`git clone ${url} ${clonePath}`, { stdio: "ignore" });
|
|
5935
6139
|
}
|
|
5936
6140
|
spinner4.stop(`Cloned to ${key}`);
|
|
@@ -5976,7 +6180,7 @@ function makeNpxCommand() {
|
|
|
5976
6180
|
return npx;
|
|
5977
6181
|
}
|
|
5978
6182
|
function resolvePublisher(clonePath, url) {
|
|
5979
|
-
const manifestPath =
|
|
6183
|
+
const manifestPath = path35__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
|
|
5980
6184
|
if (existsSync(manifestPath)) {
|
|
5981
6185
|
try {
|
|
5982
6186
|
const { manifest } = decodeSkaileManifest(readFileSync(manifestPath, "utf8"));
|
|
@@ -5989,12 +6193,12 @@ function resolvePublisher(clonePath, url) {
|
|
|
5989
6193
|
return url.match(/github\.com[/:]([^/]+)\/[^/]+/)?.[1];
|
|
5990
6194
|
}
|
|
5991
6195
|
function resolveSkillName(clonePath, requested) {
|
|
5992
|
-
const skillsDir =
|
|
5993
|
-
if (existsSync(
|
|
6196
|
+
const skillsDir = path35__default.join(clonePath, "skills");
|
|
6197
|
+
if (existsSync(path35__default.join(skillsDir, requested, "SKILL.md"))) return requested;
|
|
5994
6198
|
if (!existsSync(skillsDir)) return requested;
|
|
5995
6199
|
for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
|
|
5996
6200
|
if (!entry.isDirectory()) continue;
|
|
5997
|
-
const md =
|
|
6201
|
+
const md = path35__default.join(skillsDir, entry.name, "SKILL.md");
|
|
5998
6202
|
if (!existsSync(md)) continue;
|
|
5999
6203
|
try {
|
|
6000
6204
|
const { data } = parseFrontmatter(readFileSync(md, "utf8"));
|
|
@@ -6004,31 +6208,45 @@ function resolveSkillName(clonePath, requested) {
|
|
|
6004
6208
|
}
|
|
6005
6209
|
return requested;
|
|
6006
6210
|
}
|
|
6211
|
+
function outdatedRef(e) {
|
|
6212
|
+
const publisher = e.publisher?.replace(/^@/, "");
|
|
6213
|
+
return publisher ? `${e.kind}:@${publisher}/${e.name}` : `${e.kind}:${e.name}`;
|
|
6214
|
+
}
|
|
6215
|
+
function matchesOutdatedFilter(e, filter) {
|
|
6216
|
+
if (`${e.kind}:${e.name}` === filter || e.name === filter) return true;
|
|
6217
|
+
try {
|
|
6218
|
+
const want = parseAssetRef(filter);
|
|
6219
|
+
return want.kind === e.kind && want.name === e.name && want.publisher === e.publisher?.replace(/^@/, "");
|
|
6220
|
+
} catch {
|
|
6221
|
+
return false;
|
|
6222
|
+
}
|
|
6223
|
+
}
|
|
6007
6224
|
function makeOutdatedCommand() {
|
|
6008
|
-
return new Command("outdated").description("Check for assets behind their repo").argument("[
|
|
6225
|
+
return new Command("outdated").description("Check for assets behind their repo or library").argument("[ref]", "Check a specific asset (kind:@publisher/name)").option("--project-dir <path>", "Project directory", process.cwd()).addOption(
|
|
6009
6226
|
new Option("--target <agent>", "Driver target").default("claude-code").choices(SUPPORTED_DRIVER_TARGETS)
|
|
6010
|
-
).action((
|
|
6227
|
+
).action(async (filter, opts) => {
|
|
6011
6228
|
const am2 = new AssetManager({
|
|
6012
|
-
projectDir:
|
|
6229
|
+
projectDir: path35__default.resolve(opts.projectDir),
|
|
6013
6230
|
driverTarget: opts.target
|
|
6014
6231
|
});
|
|
6015
|
-
const entries = am2.outdated();
|
|
6232
|
+
const entries = await am2.outdated();
|
|
6016
6233
|
if (entries.length === 0) {
|
|
6017
6234
|
logInfo("All assets are up to date.");
|
|
6018
6235
|
return;
|
|
6019
6236
|
}
|
|
6020
|
-
const filtered =
|
|
6237
|
+
const filtered = filter ? entries.filter((e) => matchesOutdatedFilter(e, filter)) : entries;
|
|
6021
6238
|
if (filtered.length === 0) {
|
|
6022
|
-
logInfo(`${
|
|
6239
|
+
logInfo(`${filter} is up to date.`);
|
|
6023
6240
|
return;
|
|
6024
6241
|
}
|
|
6025
|
-
const
|
|
6242
|
+
const refW = Math.max(4, ...filtered.map((e) => outdatedRef(e).length));
|
|
6026
6243
|
console.log();
|
|
6027
6244
|
console.log(S.heading(" Outdated Assets"));
|
|
6028
|
-
console.log(` ${S.rule(
|
|
6245
|
+
console.log(` ${S.rule(refW + 34)}`);
|
|
6029
6246
|
for (const e of filtered) {
|
|
6247
|
+
const status4 = e.library !== void 0 ? `${e.currentVersion} \u2192 ${e.latestVersion} ${S.dim(`(library ${e.library})`)}` : `${e.behind} commit(s) behind`;
|
|
6030
6248
|
console.log(
|
|
6031
|
-
` ${
|
|
6249
|
+
` ${colorRef(outdatedRef(e))}${" ".repeat(refW - outdatedRef(e).length)} ${pc5.yellow(status4)}`
|
|
6032
6250
|
);
|
|
6033
6251
|
}
|
|
6034
6252
|
console.log();
|
|
@@ -6038,7 +6256,7 @@ function makeOutdatedCommand() {
|
|
|
6038
6256
|
function makePatchCommand() {
|
|
6039
6257
|
const cmd = new Command("patch").description("Patch workflow for skill improvement");
|
|
6040
6258
|
cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
6041
|
-
const am2 = new AssetManager({ projectDir:
|
|
6259
|
+
const am2 = new AssetManager({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
6042
6260
|
try {
|
|
6043
6261
|
const dest = await am2.patch(ref);
|
|
6044
6262
|
logOk(`Extracted to ${S.dim(dest)}`);
|
|
@@ -6049,7 +6267,7 @@ function makePatchCommand() {
|
|
|
6049
6267
|
}
|
|
6050
6268
|
});
|
|
6051
6269
|
cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
6052
|
-
const am2 = new AssetManager({ projectDir:
|
|
6270
|
+
const am2 = new AssetManager({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
6053
6271
|
try {
|
|
6054
6272
|
const patchFile = await am2.patchCommit(ref);
|
|
6055
6273
|
logOk(`Patch saved to ${S.dim(patchFile)}`);
|
|
@@ -6060,7 +6278,7 @@ function makePatchCommand() {
|
|
|
6060
6278
|
}
|
|
6061
6279
|
});
|
|
6062
6280
|
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) => {
|
|
6063
|
-
const am2 = new AssetManager({ projectDir:
|
|
6281
|
+
const am2 = new AssetManager({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
6064
6282
|
try {
|
|
6065
6283
|
await am2.patchSubmit(ref);
|
|
6066
6284
|
logOk("Patch applied to repo clone and committed.");
|
|
@@ -6073,7 +6291,7 @@ function makePatchCommand() {
|
|
|
6073
6291
|
}
|
|
6074
6292
|
});
|
|
6075
6293
|
cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
6076
|
-
const am2 = new AssetManager({ projectDir:
|
|
6294
|
+
const am2 = new AssetManager({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
6077
6295
|
am2.patchRemove(ref);
|
|
6078
6296
|
logOk(`Patch removed for ${ref}`);
|
|
6079
6297
|
});
|
|
@@ -6091,7 +6309,7 @@ function action2(fn) {
|
|
|
6091
6309
|
};
|
|
6092
6310
|
}
|
|
6093
6311
|
async function reconcileAndReport(projectDir, plugins) {
|
|
6094
|
-
const { reconcilePlugins } = await import('../plugin-store-
|
|
6312
|
+
const { reconcilePlugins } = await import('../plugin-store-D45CREMJ.js');
|
|
6095
6313
|
if (plugins.length === 0) {
|
|
6096
6314
|
logInfo("No plugins declared \u2014 nothing to reconcile.");
|
|
6097
6315
|
return;
|
|
@@ -6105,10 +6323,10 @@ async function reconcileAndReport(projectDir, plugins) {
|
|
|
6105
6323
|
}
|
|
6106
6324
|
}
|
|
6107
6325
|
async function runInstall2(spec, opts) {
|
|
6108
|
-
const projectDir =
|
|
6326
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
6109
6327
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
6110
|
-
const { specName } = await import('../plugin-store-
|
|
6111
|
-
const yamlPath =
|
|
6328
|
+
const { specName } = await import('../plugin-store-D45CREMJ.js');
|
|
6329
|
+
const yamlPath = path35__default.join(projectDir, "skaile.yaml");
|
|
6112
6330
|
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
6113
6331
|
const replaced = editor.addPlugin(spec, specName);
|
|
6114
6332
|
editor.save();
|
|
@@ -6117,10 +6335,10 @@ async function runInstall2(spec, opts) {
|
|
|
6117
6335
|
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
6118
6336
|
}
|
|
6119
6337
|
async function runRemove(name, opts) {
|
|
6120
|
-
const projectDir =
|
|
6338
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
6121
6339
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
6122
|
-
const { specName } = await import('../plugin-store-
|
|
6123
|
-
const yamlPath =
|
|
6340
|
+
const { specName } = await import('../plugin-store-D45CREMJ.js');
|
|
6341
|
+
const yamlPath = path35__default.join(projectDir, "skaile.yaml");
|
|
6124
6342
|
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
6125
6343
|
const removed = editor.removePlugin(name, specName);
|
|
6126
6344
|
if (!removed) {
|
|
@@ -6132,7 +6350,7 @@ async function runRemove(name, opts) {
|
|
|
6132
6350
|
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
6133
6351
|
}
|
|
6134
6352
|
async function runList(opts) {
|
|
6135
|
-
const projectDir =
|
|
6353
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
6136
6354
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
6137
6355
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
6138
6356
|
const declared = config.plugins ?? [];
|
|
@@ -6147,7 +6365,7 @@ async function runList(opts) {
|
|
|
6147
6365
|
const registry = createPluginRegistry();
|
|
6148
6366
|
if (declared.length > 0) {
|
|
6149
6367
|
try {
|
|
6150
|
-
const { loadPlugins } = await import('../plugin-store-
|
|
6368
|
+
const { loadPlugins } = await import('../plugin-store-D45CREMJ.js');
|
|
6151
6369
|
const result = await loadPlugins(projectDir, declared, registry);
|
|
6152
6370
|
for (const f of result.failed) logWarn(f.error);
|
|
6153
6371
|
} catch (err) {
|
|
@@ -6322,7 +6540,7 @@ function neededSources(config, lock) {
|
|
|
6322
6540
|
}
|
|
6323
6541
|
function sourcesWithSidecar(sources) {
|
|
6324
6542
|
const dir = getStoreManifestsDir();
|
|
6325
|
-
return sources.filter((s) => existsSync(
|
|
6543
|
+
return sources.filter((s) => existsSync(path35.join(dir, `${storeManifestSlug(s.url)}.yaml`))).map((s) => s.url);
|
|
6326
6544
|
}
|
|
6327
6545
|
function compact(obj) {
|
|
6328
6546
|
const out = {};
|
|
@@ -6414,8 +6632,8 @@ function redactSecrets(preset, findings) {
|
|
|
6414
6632
|
}
|
|
6415
6633
|
return { preset: next, keys };
|
|
6416
6634
|
}
|
|
6417
|
-
function placeholderKey(itemId,
|
|
6418
|
-
return `${itemId}_${
|
|
6635
|
+
function placeholderKey(itemId, path38) {
|
|
6636
|
+
return `${itemId}_${path38}`.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
|
|
6419
6637
|
}
|
|
6420
6638
|
function setAtPath(root, segments, value) {
|
|
6421
6639
|
let node = root;
|
|
@@ -6438,7 +6656,7 @@ function makePresetCommand() {
|
|
|
6438
6656
|
cmd.command("init [name]").description("Scaffold a new .preset.yaml file").option("--dir <path>", "Output directory", process.cwd()).action(async (name, opts) => {
|
|
6439
6657
|
const presetName = name ?? "my-preset";
|
|
6440
6658
|
const filename = `${presetName}.preset.yaml`;
|
|
6441
|
-
const outPath =
|
|
6659
|
+
const outPath = path35__default.join(path35__default.resolve(opts.dir), filename);
|
|
6442
6660
|
if (existsSync(outPath)) {
|
|
6443
6661
|
logErr(`File already exists: ${outPath}`);
|
|
6444
6662
|
logInfo("Choose a different name or remove the existing file.");
|
|
@@ -6471,7 +6689,7 @@ function makePresetCommand() {
|
|
|
6471
6689
|
return cmd;
|
|
6472
6690
|
}
|
|
6473
6691
|
async function runPresetExport(name, opts) {
|
|
6474
|
-
const projectDir =
|
|
6692
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
6475
6693
|
const file = loadSkWorkspaceConfig(projectDir);
|
|
6476
6694
|
if (!file) {
|
|
6477
6695
|
logErr(`No skaile.yaml found in ${projectDir}`);
|
|
@@ -6481,7 +6699,7 @@ async function runPresetExport(name, opts) {
|
|
|
6481
6699
|
const presetName = name ?? file.config.name ?? "my-preset";
|
|
6482
6700
|
let lock = null;
|
|
6483
6701
|
try {
|
|
6484
|
-
lock = readLock(
|
|
6702
|
+
lock = readLock(path35__default.join(projectDir, "skaile.lock.yaml"));
|
|
6485
6703
|
} catch {
|
|
6486
6704
|
lock = null;
|
|
6487
6705
|
}
|
|
@@ -6522,7 +6740,7 @@ async function runPresetExport(name, opts) {
|
|
|
6522
6740
|
const contents = header ? `${header}
|
|
6523
6741
|
${body}` : body;
|
|
6524
6742
|
if (opts.out && opts.dir !== process.cwd()) logWarn("--dir is ignored when --out is set.");
|
|
6525
|
-
const outPath = opts.out ?
|
|
6743
|
+
const outPath = opts.out ? path35__default.resolve(opts.out) : path35__default.join(path35__default.resolve(opts.dir), `${presetName}.preset.yaml`);
|
|
6526
6744
|
if (existsSync(outPath) && !opts.force) {
|
|
6527
6745
|
logErr(`File already exists: ${outPath}`);
|
|
6528
6746
|
logInfo("Pass --force to overwrite, or choose a different --out/--dir.");
|
|
@@ -6534,7 +6752,7 @@ ${body}` : body;
|
|
|
6534
6752
|
logErr(`Failed to write ${outPath}: ${e.message}`);
|
|
6535
6753
|
process.exit(1);
|
|
6536
6754
|
}
|
|
6537
|
-
logOk(`Exported ${S.brand(
|
|
6755
|
+
logOk(`Exported ${S.brand(path35__default.basename(outPath))}`);
|
|
6538
6756
|
logInfo(`Path: ${outPath}`);
|
|
6539
6757
|
if (unresolved.length > 0) {
|
|
6540
6758
|
console.error(S.err("This file is NOT safe to share."));
|
|
@@ -6575,13 +6793,13 @@ function collectInput(value, acc) {
|
|
|
6575
6793
|
return acc;
|
|
6576
6794
|
}
|
|
6577
6795
|
async function runPresetApply(filePath, opts) {
|
|
6578
|
-
const projectDir =
|
|
6796
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
6579
6797
|
const file = loadSkWorkspaceConfig(projectDir);
|
|
6580
6798
|
if (!file) {
|
|
6581
6799
|
logErr("No skaile.yaml \u2014 run `skaile init` first");
|
|
6582
6800
|
process.exit(1);
|
|
6583
6801
|
}
|
|
6584
|
-
const resolved =
|
|
6802
|
+
const resolved = path35__default.resolve(filePath);
|
|
6585
6803
|
if (!existsSync(resolved)) {
|
|
6586
6804
|
logErr(`File not found: ${resolved}`);
|
|
6587
6805
|
process.exit(1);
|
|
@@ -6797,7 +7015,7 @@ async function reportNestedPresetRefs(preset) {
|
|
|
6797
7015
|
}
|
|
6798
7016
|
async function checkPresetCycles(preset, resolved) {
|
|
6799
7017
|
const { detectCycles } = await import('../discovery/index.js');
|
|
6800
|
-
const presetRef =
|
|
7018
|
+
const presetRef = path35__default.basename(resolved, ".preset.yaml");
|
|
6801
7019
|
const edges = [];
|
|
6802
7020
|
for (const item of preset.items) {
|
|
6803
7021
|
if (item.ref) {
|
|
@@ -6849,7 +7067,7 @@ function printPresetSummary(preset, placeholderCount, hasWarnings) {
|
|
|
6849
7067
|
}
|
|
6850
7068
|
}
|
|
6851
7069
|
async function runPresetValidate(filePath) {
|
|
6852
|
-
const resolved =
|
|
7070
|
+
const resolved = path35__default.resolve(filePath);
|
|
6853
7071
|
const preset = await loadPresetForValidation(resolved);
|
|
6854
7072
|
await reportNestedPresetRefs(preset);
|
|
6855
7073
|
await checkPresetCycles(preset, resolved);
|
|
@@ -6899,11 +7117,11 @@ items:
|
|
|
6899
7117
|
}
|
|
6900
7118
|
function makeRebuildCommand() {
|
|
6901
7119
|
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) => {
|
|
6902
|
-
const projectDir =
|
|
7120
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
6903
7121
|
let agentDir;
|
|
6904
7122
|
if (agentArg) {
|
|
6905
7123
|
if (agentArg.includes("/") || agentArg.includes("\\")) {
|
|
6906
|
-
agentDir =
|
|
7124
|
+
agentDir = path35__default.resolve(projectDir, agentArg);
|
|
6907
7125
|
} else {
|
|
6908
7126
|
let resolved;
|
|
6909
7127
|
try {
|
|
@@ -6912,7 +7130,7 @@ function makeRebuildCommand() {
|
|
|
6912
7130
|
if (!(err instanceof AgentRefResolutionError)) throw err;
|
|
6913
7131
|
logWarn(`${err.message} \u2014 using "${agentArg}"`);
|
|
6914
7132
|
}
|
|
6915
|
-
agentDir = resolved ??
|
|
7133
|
+
agentDir = resolved ?? path35__default.resolve(projectDir, agentArg);
|
|
6916
7134
|
}
|
|
6917
7135
|
} else {
|
|
6918
7136
|
let resolved;
|
|
@@ -7013,7 +7231,7 @@ function makeFlowEventHandler() {
|
|
|
7013
7231
|
}
|
|
7014
7232
|
function makeRunCommand() {
|
|
7015
7233
|
const cmd = new Command("run").description("Start a flow or run a single-shot text prompt").argument("[flow-id-or-text...]", "Flow ID or text prompt").option("--project-dir <path>", "Project directory", process.cwd()).option("--driver <name>", "Harness to run (claude-sdk, codex, omp)").option("--model <name>", "Model override").option("--label <label>", "Human-readable session label").option("--dry-run", "Print plan without executing").option("--skill <name>", "Skill name (for single-shot mode)").action(async (positional, opts) => {
|
|
7016
|
-
const projectDir =
|
|
7234
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
7017
7235
|
const cliDriver = opts.driver;
|
|
7018
7236
|
const dryRun = opts.dryRun ?? false;
|
|
7019
7237
|
let flowId = positional[0];
|
|
@@ -7110,7 +7328,7 @@ function makeRunCommand() {
|
|
|
7110
7328
|
}
|
|
7111
7329
|
function makeResumeCommand() {
|
|
7112
7330
|
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) => {
|
|
7113
|
-
const projectDir =
|
|
7331
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
7114
7332
|
const sessionId = opts.session;
|
|
7115
7333
|
const dryRun = opts.dryRun ?? false;
|
|
7116
7334
|
const session = sessionId ? await loadSessionById(projectDir, sessionId) : await loadSession(projectDir);
|
|
@@ -7137,7 +7355,7 @@ function makeResumeCommand() {
|
|
|
7137
7355
|
}
|
|
7138
7356
|
function makeStatusCommand() {
|
|
7139
7357
|
return new Command("status").description("Show current session state").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
7140
|
-
const projectDir =
|
|
7358
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
7141
7359
|
const session = await loadSession(projectDir);
|
|
7142
7360
|
if (!session) {
|
|
7143
7361
|
logInfo("No active session.");
|
|
@@ -7162,7 +7380,7 @@ function makeStatusCommand() {
|
|
|
7162
7380
|
}
|
|
7163
7381
|
function makeClearCommand() {
|
|
7164
7382
|
return new Command("clear").description("Unset current session pointer").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
7165
|
-
const projectDir =
|
|
7383
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
7166
7384
|
await clearSession(projectDir);
|
|
7167
7385
|
logOk("Session cleared.");
|
|
7168
7386
|
});
|
|
@@ -7172,7 +7390,7 @@ function makeReplCommand() {
|
|
|
7172
7390
|
const { findWorkspaceRoot } = await import('../core/index.js');
|
|
7173
7391
|
const { startRepl } = await import('../tui/index.js');
|
|
7174
7392
|
const os2 = await import('os');
|
|
7175
|
-
const userCwd =
|
|
7393
|
+
const userCwd = path35__default.resolve(opts.projectDir ?? process.cwd());
|
|
7176
7394
|
const workspaceRoot = findWorkspaceRoot(userCwd);
|
|
7177
7395
|
let projectDir;
|
|
7178
7396
|
let agentCwd;
|
|
@@ -7194,13 +7412,13 @@ function makeReplCommand() {
|
|
|
7194
7412
|
p5.cancel("Cancelled.");
|
|
7195
7413
|
process.exit(0);
|
|
7196
7414
|
}
|
|
7197
|
-
const tmpDir =
|
|
7415
|
+
const tmpDir = fs11__default.mkdtempSync(path35__default.join(os2.tmpdir(), "skaile-repl-"));
|
|
7198
7416
|
projectDir = tmpDir;
|
|
7199
7417
|
agentCwd = userCwd;
|
|
7200
7418
|
logOk(`Temporary workspace: ${S.cmd(tmpDir)}`);
|
|
7201
7419
|
if (!driverOverride) {
|
|
7202
|
-
const claudeDir =
|
|
7203
|
-
if (
|
|
7420
|
+
const claudeDir = path35__default.join(os2.homedir(), ".claude");
|
|
7421
|
+
if (fs11__default.existsSync(claudeDir)) {
|
|
7204
7422
|
driverOverride = "claude-sdk";
|
|
7205
7423
|
logInfo(`Detected ${S.cmd("~/.claude")} \u2192 using ${S.cmd("claude-sdk")} harness`);
|
|
7206
7424
|
} else {
|
|
@@ -7272,12 +7490,12 @@ function makeServeCommand() {
|
|
|
7272
7490
|
);
|
|
7273
7491
|
}
|
|
7274
7492
|
async function ensurePluginsLoadedForServe(projectDir) {
|
|
7275
|
-
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-
|
|
7493
|
+
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-DF55G2YC.js');
|
|
7276
7494
|
try {
|
|
7277
7495
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
7278
7496
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
7279
7497
|
if (!config.plugins || config.plugins.length === 0) return;
|
|
7280
|
-
const { ensurePluginsLoaded } = await import('../plugin-store-
|
|
7498
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-D45CREMJ.js');
|
|
7281
7499
|
const { pluginRegistry } = await import('../plugin-registry/index.js');
|
|
7282
7500
|
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
7283
7501
|
if (result.loaded.length > 0) {
|
|
@@ -7291,21 +7509,21 @@ async function ensurePluginsLoadedForServe(projectDir) {
|
|
|
7291
7509
|
}
|
|
7292
7510
|
}
|
|
7293
7511
|
async function runCompileTest(opts) {
|
|
7294
|
-
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-
|
|
7512
|
+
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-DF55G2YC.js');
|
|
7295
7513
|
const { tmpdir } = await import('os');
|
|
7296
|
-
const { dirname: dirname4, join:
|
|
7514
|
+
const { dirname: dirname4, join: join6, resolve: resolve5 } = await import('path');
|
|
7297
7515
|
const { fileURLToPath: fileURLToPath2 } = await import('url');
|
|
7298
|
-
const { unlinkSync, existsSync:
|
|
7516
|
+
const { unlinkSync, existsSync: existsSync14 } = await import('fs');
|
|
7299
7517
|
const { spawn } = await import('child_process');
|
|
7300
7518
|
const { portableSpawnSync: portableSpawnSync2 } = await import('../core/index.js');
|
|
7301
|
-
const { MONOREPO_ROOT } = await import('../paths-
|
|
7519
|
+
const { MONOREPO_ROOT } = await import('../paths-W4LDORQQ.js');
|
|
7302
7520
|
if (MONOREPO_ROOT === null) {
|
|
7303
7521
|
logErr2("--compile-test is only available inside the skaile-dev workspace.");
|
|
7304
7522
|
logInfo2("Run it from a checkout of skaile-ai/skaile-dev (the monorepo shell).");
|
|
7305
7523
|
process.exitCode = 2;
|
|
7306
7524
|
return;
|
|
7307
7525
|
}
|
|
7308
|
-
const outfile =
|
|
7526
|
+
const outfile = join6(tmpdir(), `skaile-compile-test-${Date.now()}`);
|
|
7309
7527
|
const __thisFile = fileURLToPath2(import.meta.url);
|
|
7310
7528
|
const entryPoint = resolve5(dirname4(__thisFile), "..", "index.ts");
|
|
7311
7529
|
logInfo2(`Building compiled binary...`);
|
|
@@ -7360,7 +7578,7 @@ async function runCompileTest(opts) {
|
|
|
7360
7578
|
} catch {
|
|
7361
7579
|
}
|
|
7362
7580
|
try {
|
|
7363
|
-
if (
|
|
7581
|
+
if (existsSync14(outfile)) unlinkSync(outfile);
|
|
7364
7582
|
} catch {
|
|
7365
7583
|
}
|
|
7366
7584
|
}
|
|
@@ -7781,7 +7999,7 @@ function resolveMode(opts) {
|
|
|
7781
7999
|
if (opts.forceLocal && opts.forceRemote) {
|
|
7782
8000
|
throw new Error("Cannot use both --local and --remote");
|
|
7783
8001
|
}
|
|
7784
|
-
const startDir =
|
|
8002
|
+
const startDir = path35__default.resolve(opts.projectDir ?? process.cwd());
|
|
7785
8003
|
const localDb = findLogsDb(startDir);
|
|
7786
8004
|
if (opts.forceLocal) {
|
|
7787
8005
|
if (!localDb) {
|
|
@@ -7814,14 +8032,14 @@ function resolveMode(opts) {
|
|
|
7814
8032
|
function findLogsDb(startDir) {
|
|
7815
8033
|
let dir = startDir;
|
|
7816
8034
|
for (let i = 0; i < MAX_WALK_LEVELS; i++) {
|
|
7817
|
-
const candidate =
|
|
8035
|
+
const candidate = path35__default.join(dir, ".skaile", "logs.db");
|
|
7818
8036
|
if (existsSync(candidate)) {
|
|
7819
8037
|
try {
|
|
7820
8038
|
if (statSync(candidate).isFile()) return candidate;
|
|
7821
8039
|
} catch {
|
|
7822
8040
|
}
|
|
7823
8041
|
}
|
|
7824
|
-
const parent =
|
|
8042
|
+
const parent = path35__default.dirname(dir);
|
|
7825
8043
|
if (parent === dir) return void 0;
|
|
7826
8044
|
dir = parent;
|
|
7827
8045
|
}
|
|
@@ -7847,7 +8065,7 @@ function readApiToken() {
|
|
|
7847
8065
|
}
|
|
7848
8066
|
function readGlobalSettings() {
|
|
7849
8067
|
try {
|
|
7850
|
-
const settingsPath =
|
|
8068
|
+
const settingsPath = globalSettingsPath();
|
|
7851
8069
|
if (!existsSync(settingsPath)) return {};
|
|
7852
8070
|
return JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
7853
8071
|
} catch {
|
|
@@ -7996,7 +8214,7 @@ function parsePositiveInt(value, flag) {
|
|
|
7996
8214
|
function makeSessionCommand() {
|
|
7997
8215
|
const cmd = new Command("session").description("Manage sessions");
|
|
7998
8216
|
cmd.command("list").description("List all sessions for a project").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
7999
|
-
const projectDir =
|
|
8217
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
8000
8218
|
const sessions = await listSessions(projectDir);
|
|
8001
8219
|
const current = await loadSession(projectDir);
|
|
8002
8220
|
if (sessions.length === 0) {
|
|
@@ -8024,7 +8242,7 @@ function makeSessionCommand() {
|
|
|
8024
8242
|
console.log();
|
|
8025
8243
|
});
|
|
8026
8244
|
cmd.command("show <run-id>").description("Show a specific session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
8027
|
-
const projectDir =
|
|
8245
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
8028
8246
|
const session = await loadSessionById(projectDir, runId);
|
|
8029
8247
|
if (!session) {
|
|
8030
8248
|
logErr(`Session not found: ${runId}`);
|
|
@@ -8033,12 +8251,12 @@ function makeSessionCommand() {
|
|
|
8033
8251
|
console.log(JSON.stringify(session, null, 2));
|
|
8034
8252
|
});
|
|
8035
8253
|
cmd.command("switch <run-id>").description("Switch the current session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
8036
|
-
const projectDir =
|
|
8254
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
8037
8255
|
await setCurrentSession(projectDir, runId);
|
|
8038
8256
|
logOk(`Switched to session: ${S.dim(runId.slice(0, 8))}`);
|
|
8039
8257
|
});
|
|
8040
8258
|
cmd.command("delete <run-id>").description("Delete a session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
8041
|
-
const projectDir =
|
|
8259
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
8042
8260
|
await deleteSession(projectDir, runId);
|
|
8043
8261
|
logOk(`Deleted session: ${S.dim(runId.slice(0, 8))}`);
|
|
8044
8262
|
});
|
|
@@ -8092,12 +8310,12 @@ function showOverview(am2) {
|
|
|
8092
8310
|
}
|
|
8093
8311
|
async function showAsset(am2, kind, name) {
|
|
8094
8312
|
const entry = await am2.info(`${kind}:${name}`);
|
|
8095
|
-
if (entry?.source &&
|
|
8313
|
+
if (entry?.source && fs11__default.existsSync(entry.source)) {
|
|
8096
8314
|
console.log();
|
|
8097
8315
|
console.log(` ${kindColor(entry.kind)} ${S.heading(entry.name)}`);
|
|
8098
8316
|
console.log(` ${S.rule(40)}`);
|
|
8099
8317
|
console.log();
|
|
8100
|
-
console.log(
|
|
8318
|
+
console.log(fs11__default.readFileSync(entry.source, "utf-8"));
|
|
8101
8319
|
return;
|
|
8102
8320
|
}
|
|
8103
8321
|
logErr(`Asset not found: ${kind}:${name}`);
|
|
@@ -8106,7 +8324,7 @@ async function showAsset(am2, kind, name) {
|
|
|
8106
8324
|
function makeShowCommand() {
|
|
8107
8325
|
return new Command("show").description("Show deployed assets overview, or print asset content").argument("[kind]", "Asset kind (skill, agent, prompt, flow, bundle, contract)").argument("[name]", "Asset name").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", "Agent framework", "claude-code").action(async (kind, name, opts) => {
|
|
8108
8326
|
const am2 = new AssetManager({
|
|
8109
|
-
projectDir:
|
|
8327
|
+
projectDir: path35__default.resolve(opts.projectDir),
|
|
8110
8328
|
driverTarget: opts.target
|
|
8111
8329
|
});
|
|
8112
8330
|
if (!kind) {
|
|
@@ -8174,9 +8392,9 @@ function makeStoreCommand() {
|
|
|
8174
8392
|
process.exit(2);
|
|
8175
8393
|
});
|
|
8176
8394
|
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) => {
|
|
8177
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-
|
|
8395
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-SUVOMIWZ.js');
|
|
8178
8396
|
try {
|
|
8179
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
8397
|
+
const remote = await openCatalogSource2({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
8180
8398
|
const assets = await remote.listAssets(opts.kind ? { kind: opts.kind } : {});
|
|
8181
8399
|
const results = filterCatalogAssets(assets, query);
|
|
8182
8400
|
if (results.length === 0) {
|
|
@@ -8184,12 +8402,7 @@ function makeStoreCommand() {
|
|
|
8184
8402
|
return;
|
|
8185
8403
|
}
|
|
8186
8404
|
console.log();
|
|
8187
|
-
for (const
|
|
8188
|
-
const ref = catalogAssetRef(a);
|
|
8189
|
-
console.log(
|
|
8190
|
-
` \u2B21 ${kindColorPad(a.kind)} ${colorRef(ref).padEnd(48)} ${S.dim((a.description ?? "").slice(0, 60))}`
|
|
8191
|
-
);
|
|
8192
|
-
}
|
|
8405
|
+
for (const row of formatStoreRows(results, " ")) console.log(row);
|
|
8193
8406
|
console.log(
|
|
8194
8407
|
`
|
|
8195
8408
|
${S.dim(`${results.length} result(s) \xB7 \`skaile store show <ref>\` for details`)}
|
|
@@ -8207,10 +8420,10 @@ function makeStoreCommand() {
|
|
|
8207
8420
|
}
|
|
8208
8421
|
});
|
|
8209
8422
|
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) => {
|
|
8210
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-
|
|
8211
|
-
const { supportsInstallManifest } = await import('../project-
|
|
8423
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-SUVOMIWZ.js');
|
|
8424
|
+
const { supportsInstallManifest } = await import('../project-RTLVOXUU.js');
|
|
8212
8425
|
try {
|
|
8213
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
8426
|
+
const remote = await openCatalogSource2({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
8214
8427
|
const asset = await remote.resolve(ref);
|
|
8215
8428
|
if (!asset) {
|
|
8216
8429
|
logErr(`Not found in store: ${ref} (try a full ref, e.g. skill:@publisher/name#version)`);
|
|
@@ -8223,9 +8436,7 @@ function makeStoreCommand() {
|
|
|
8223
8436
|
}
|
|
8224
8437
|
const field = (label, value) => ` ${S.label(label.padEnd(11))}${value}`;
|
|
8225
8438
|
console.log();
|
|
8226
|
-
console.log(
|
|
8227
|
-
` ${kindColorPad(asset.kind)} ${S.heading(`@${asset.publisher}/${asset.name}`)} ${S.dim(`v${asset.version}`)}`
|
|
8228
|
-
);
|
|
8439
|
+
console.log(` ${kindColorPad(asset.kind)} ${S.heading(canonical)}`);
|
|
8229
8440
|
console.log(` ${S.rule(52)}`);
|
|
8230
8441
|
if (asset.description) {
|
|
8231
8442
|
console.log();
|
|
@@ -8286,19 +8497,24 @@ function makeStoreCommand() {
|
|
|
8286
8497
|
logErr("`skaile store push` is scaffolded but not yet wired.");
|
|
8287
8498
|
process.exit(2);
|
|
8288
8499
|
});
|
|
8289
|
-
store.command("yank <version>").description("Yank (soft-delete) a published version").option("--asset <ref>", "Asset reference (
|
|
8500
|
+
store.command("yank <version>").description("Yank (soft-delete) a published version").option("--asset <ref>", "Asset reference (kind:@publisher/name)").action(async (version, opts) => {
|
|
8290
8501
|
if (!isStoreAuthenticated()) {
|
|
8291
8502
|
logErr("Not signed in. Run: skaile store login");
|
|
8292
8503
|
process.exit(1);
|
|
8293
8504
|
}
|
|
8294
8505
|
if (!opts.asset) {
|
|
8295
|
-
logErr("--asset is required (e.g. --asset
|
|
8506
|
+
logErr("--asset is required (e.g. --asset skill:@alice/my-skill)");
|
|
8296
8507
|
process.exit(1);
|
|
8297
8508
|
}
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
|
|
8509
|
+
let publisher;
|
|
8510
|
+
let slug;
|
|
8511
|
+
try {
|
|
8512
|
+
const ref = parseAssetRef(opts.asset);
|
|
8513
|
+
if (!ref.publisher) throw new Error("publisher required");
|
|
8514
|
+
publisher = ref.publisher;
|
|
8515
|
+
slug = ref.name;
|
|
8516
|
+
} catch {
|
|
8517
|
+
logErr("Invalid asset ref. Use format: kind:@publisher/name");
|
|
8302
8518
|
process.exit(1);
|
|
8303
8519
|
}
|
|
8304
8520
|
try {
|
|
@@ -8329,7 +8545,7 @@ function printTree(node, prefix = "", isLast = true) {
|
|
|
8329
8545
|
}
|
|
8330
8546
|
function makeTreeCommand() {
|
|
8331
8547
|
return new Command("tree").description("Show full dependency tree").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
8332
|
-
const am2 = new AssetManager({ projectDir:
|
|
8548
|
+
const am2 = new AssetManager({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
8333
8549
|
const root = am2.tree();
|
|
8334
8550
|
if (root.children.length === 0) {
|
|
8335
8551
|
logInfo("No dependencies in lock file. Run `skaile install` first.");
|
|
@@ -8352,22 +8568,23 @@ function makeUpdateCommand() {
|
|
|
8352
8568
|
return new Command("update").description("Refresh the Catalog cache and re-deploy outdated assets in the current project").argument("[name]", "Update a specific asset (kind:name)").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(
|
|
8353
8569
|
async (_name, opts) => {
|
|
8354
8570
|
if (opts.catalog !== false) {
|
|
8571
|
+
const catalogSpinner = p5.spinner();
|
|
8572
|
+
catalogSpinner.start("Refreshing catalog cache");
|
|
8355
8573
|
try {
|
|
8356
|
-
const
|
|
8357
|
-
catalogSpinner.start("Refreshing catalog cache");
|
|
8358
|
-
const remote = await openCatalogSource({ projectDir: path36__default.resolve(opts.projectDir) });
|
|
8574
|
+
const remote = await openCatalogSource({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
8359
8575
|
const result2 = await remote.refresh();
|
|
8360
8576
|
catalogSpinner.stop(
|
|
8361
8577
|
`Catalog refreshed: ${S.heading(String(result2.assetsCached))} assets cached`
|
|
8362
8578
|
);
|
|
8363
8579
|
logInfo(`Source: ${remote.baseUrl}`);
|
|
8364
8580
|
} catch (err) {
|
|
8581
|
+
catalogSpinner.stop("Catalog refresh failed");
|
|
8365
8582
|
logErr(`Catalog refresh failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
8366
8583
|
logInfo("Continuing with asset re-deploy. Run `skaile catalog test` to debug.");
|
|
8367
8584
|
}
|
|
8368
8585
|
}
|
|
8369
8586
|
if (opts.catalogOnly) return;
|
|
8370
|
-
const projectDir =
|
|
8587
|
+
const projectDir = path35__default.resolve(opts.projectDir);
|
|
8371
8588
|
if (await shouldSyncSources(opts)) {
|
|
8372
8589
|
const syncSpinner = p5.spinner();
|
|
8373
8590
|
syncSpinner.start("Syncing sources");
|
|
@@ -8423,12 +8640,12 @@ function findManifestCandidates(rootPath) {
|
|
|
8423
8640
|
function walk(dir) {
|
|
8424
8641
|
let entries;
|
|
8425
8642
|
try {
|
|
8426
|
-
entries =
|
|
8643
|
+
entries = fs11__default.readdirSync(dir, { withFileTypes: true });
|
|
8427
8644
|
} catch {
|
|
8428
8645
|
return;
|
|
8429
8646
|
}
|
|
8430
8647
|
for (const entry of entries) {
|
|
8431
|
-
const fullPath =
|
|
8648
|
+
const fullPath = path35__default.join(dir, entry.name);
|
|
8432
8649
|
if (entry.isDirectory()) {
|
|
8433
8650
|
if (!SKIP_DIRS.has(entry.name)) walk(fullPath);
|
|
8434
8651
|
} else if (entry.isFile()) {
|
|
@@ -8445,9 +8662,9 @@ function findManifestCandidates(rootPath) {
|
|
|
8445
8662
|
return candidates;
|
|
8446
8663
|
}
|
|
8447
8664
|
function parseMdFrontmatter(content) {
|
|
8448
|
-
const fmMatch = content.match(/^---\n([\s\S]*?)\n
|
|
8665
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
8449
8666
|
if (!fmMatch) return null;
|
|
8450
|
-
return parse(fmMatch[1]);
|
|
8667
|
+
return { frontmatter: parse(fmMatch[1]), body: content.slice(fmMatch[0].length).trim() };
|
|
8451
8668
|
}
|
|
8452
8669
|
function checkManifestIdentity(kind, parsed) {
|
|
8453
8670
|
if (parsed === null || typeof parsed !== "object") return null;
|
|
@@ -8469,25 +8686,25 @@ function checkManifestIdentity(kind, parsed) {
|
|
|
8469
8686
|
return null;
|
|
8470
8687
|
}
|
|
8471
8688
|
function parseManifestCandidate(c, absRoot) {
|
|
8472
|
-
const content =
|
|
8689
|
+
const content = fs11__default.readFileSync(c.filePath, "utf-8");
|
|
8473
8690
|
if (c.filePath.endsWith(".md")) {
|
|
8474
|
-
const
|
|
8475
|
-
if (
|
|
8691
|
+
const md = parseMdFrontmatter(content);
|
|
8692
|
+
if (md === null) {
|
|
8476
8693
|
return { kind: "skip" };
|
|
8477
8694
|
}
|
|
8478
|
-
return { kind: "value", parsed };
|
|
8695
|
+
return { kind: "value", parsed: md.frontmatter, body: md.body };
|
|
8479
8696
|
}
|
|
8480
8697
|
try {
|
|
8481
8698
|
const parsed = c.filePath.endsWith(".json") ? JSON.parse(content) : parse(content);
|
|
8482
8699
|
return { kind: "value", parsed };
|
|
8483
8700
|
} catch (e) {
|
|
8484
|
-
const relPath =
|
|
8701
|
+
const relPath = path35__default.relative(absRoot, c.filePath);
|
|
8485
8702
|
logErr(`${relPath} \u2014 parse error: ${e instanceof Error ? e.message : String(e)}`);
|
|
8486
8703
|
return { kind: "error" };
|
|
8487
8704
|
}
|
|
8488
8705
|
}
|
|
8489
|
-
function validateManifestCandidate(c, parsed, absRoot, registry, strictConformance) {
|
|
8490
|
-
const relPath =
|
|
8706
|
+
function validateManifestCandidate(c, parsed, body, absRoot, registry, strictConformance) {
|
|
8707
|
+
const relPath = path35__default.relative(absRoot, c.filePath);
|
|
8491
8708
|
let errors = 0;
|
|
8492
8709
|
let warnings = 0;
|
|
8493
8710
|
const identityError = checkManifestIdentity(c.kind, parsed);
|
|
@@ -8496,7 +8713,7 @@ function validateManifestCandidate(c, parsed, absRoot, registry, strictConforman
|
|
|
8496
8713
|
errors++;
|
|
8497
8714
|
}
|
|
8498
8715
|
if (c.kind === "skill" && parsed && typeof parsed === "object") {
|
|
8499
|
-
const dirName =
|
|
8716
|
+
const dirName = path35__default.basename(path35__default.dirname(c.filePath));
|
|
8500
8717
|
const findings = checkAgentSkillConformance(parsed, { dirName });
|
|
8501
8718
|
for (const f of findings) {
|
|
8502
8719
|
const line = `${relPath} [skill conformance] \u2014 ${f.field}: ${f.message}`;
|
|
@@ -8509,6 +8726,10 @@ function validateManifestCandidate(c, parsed, absRoot, registry, strictConforman
|
|
|
8509
8726
|
}
|
|
8510
8727
|
}
|
|
8511
8728
|
}
|
|
8729
|
+
if (c.kind === "skill" && body?.replace(/^#[^\n]*\n+/, "") === SKILL_BODY_PLACEHOLDER) {
|
|
8730
|
+
logWarn(`${relPath} [skill] \u2014 body is still the scaffold placeholder; write the skill prompt`);
|
|
8731
|
+
warnings++;
|
|
8732
|
+
}
|
|
8512
8733
|
const provider = registry.getProvider(c.kind);
|
|
8513
8734
|
if (!provider) {
|
|
8514
8735
|
logWarn(`${relPath} [${c.kind}] \u2014 kind "${c.kind}" is not registered, skipping validation`);
|
|
@@ -8524,8 +8745,8 @@ function validateManifestCandidate(c, parsed, absRoot, registry, strictConforman
|
|
|
8524
8745
|
return { errors, warnings };
|
|
8525
8746
|
}
|
|
8526
8747
|
function validateManifests(rootPath, strictConformance) {
|
|
8527
|
-
const absRoot =
|
|
8528
|
-
if (!
|
|
8748
|
+
const absRoot = path35__default.resolve(rootPath);
|
|
8749
|
+
if (!fs11__default.existsSync(absRoot)) {
|
|
8529
8750
|
logErr(`Path does not exist: ${absRoot}`);
|
|
8530
8751
|
return { total: 0, errors: 1, warnings: 0 };
|
|
8531
8752
|
}
|
|
@@ -8543,6 +8764,7 @@ function validateManifests(rootPath, strictConformance) {
|
|
|
8543
8764
|
const delta = validateManifestCandidate(
|
|
8544
8765
|
c,
|
|
8545
8766
|
parseResult.parsed,
|
|
8767
|
+
parseResult.body,
|
|
8546
8768
|
absRoot,
|
|
8547
8769
|
registry,
|
|
8548
8770
|
strictConformance
|
|
@@ -8557,12 +8779,12 @@ function findWorkspaceManifests(rootPath) {
|
|
|
8557
8779
|
function walk(dir) {
|
|
8558
8780
|
let entries;
|
|
8559
8781
|
try {
|
|
8560
|
-
entries =
|
|
8782
|
+
entries = fs11__default.readdirSync(dir, { withFileTypes: true });
|
|
8561
8783
|
} catch {
|
|
8562
8784
|
return;
|
|
8563
8785
|
}
|
|
8564
8786
|
for (const entry of entries) {
|
|
8565
|
-
const full =
|
|
8787
|
+
const full = path35__default.join(dir, entry.name);
|
|
8566
8788
|
if (entry.isDirectory()) {
|
|
8567
8789
|
if (!SKIP_DIRS.has(entry.name)) walk(full);
|
|
8568
8790
|
} else if (entry.isFile() && /(^|\.)skaile\.yaml$/.test(entry.name)) {
|
|
@@ -8625,14 +8847,14 @@ function validateWorkspaceAssets(parsed, relPath) {
|
|
|
8625
8847
|
return errors;
|
|
8626
8848
|
}
|
|
8627
8849
|
function validateWorkspaceManifests(rootPath) {
|
|
8628
|
-
const absRoot =
|
|
8850
|
+
const absRoot = path35__default.resolve(rootPath);
|
|
8629
8851
|
const files = findWorkspaceManifests(absRoot);
|
|
8630
8852
|
let errors = 0;
|
|
8631
8853
|
for (const file of files) {
|
|
8632
|
-
const relPath =
|
|
8854
|
+
const relPath = path35__default.relative(absRoot, file);
|
|
8633
8855
|
let parsed;
|
|
8634
8856
|
try {
|
|
8635
|
-
parsed = parse(
|
|
8857
|
+
parsed = parse(fs11__default.readFileSync(file, "utf-8")) ?? {};
|
|
8636
8858
|
} catch (e) {
|
|
8637
8859
|
logErr(`${relPath} \u2014 parse error: ${e instanceof Error ? e.message : String(e)}`);
|
|
8638
8860
|
errors++;
|
|
@@ -8646,34 +8868,34 @@ function validateWorkspaceManifests(rootPath) {
|
|
|
8646
8868
|
var EXCLUDED_DOMAINS = /* @__PURE__ */ new Set(["skaileup-shared", "external", "docs"]);
|
|
8647
8869
|
function collectAssetVersions() {
|
|
8648
8870
|
const assets = [];
|
|
8649
|
-
if (!
|
|
8650
|
-
const domains =
|
|
8871
|
+
if (!fs11__default.existsSync(AI_RESOURCES)) return assets;
|
|
8872
|
+
const domains = fs11__default.readdirSync(AI_RESOURCES, { withFileTypes: true }).filter((d) => d.isDirectory() && !EXCLUDED_DOMAINS.has(d.name));
|
|
8651
8873
|
for (const d of domains) {
|
|
8652
|
-
const domainDir =
|
|
8653
|
-
const skillsDir =
|
|
8654
|
-
if (
|
|
8874
|
+
const domainDir = path35__default.join(AI_RESOURCES, d.name);
|
|
8875
|
+
const skillsDir = path35__default.join(domainDir, "skills");
|
|
8876
|
+
if (fs11__default.existsSync(skillsDir)) {
|
|
8655
8877
|
collectSkillVersions(skillsDir, d.name, assets);
|
|
8656
8878
|
}
|
|
8657
|
-
const agentsDir =
|
|
8658
|
-
if (
|
|
8879
|
+
const agentsDir = path35__default.join(domainDir, "agents");
|
|
8880
|
+
if (fs11__default.existsSync(agentsDir)) {
|
|
8659
8881
|
collectAgentVersions(agentsDir, d.name, assets);
|
|
8660
8882
|
}
|
|
8661
|
-
const flowsDir =
|
|
8662
|
-
if (
|
|
8883
|
+
const flowsDir = path35__default.join(domainDir, "flows");
|
|
8884
|
+
if (fs11__default.existsSync(flowsDir)) {
|
|
8663
8885
|
collectFlowVersions(flowsDir, d.name, assets);
|
|
8664
8886
|
}
|
|
8665
|
-
const promptsDir =
|
|
8666
|
-
if (
|
|
8887
|
+
const promptsDir = path35__default.join(domainDir, "prompts");
|
|
8888
|
+
if (fs11__default.existsSync(promptsDir)) {
|
|
8667
8889
|
collectPromptVersions(promptsDir, d.name, assets);
|
|
8668
8890
|
}
|
|
8669
8891
|
}
|
|
8670
8892
|
return assets;
|
|
8671
8893
|
}
|
|
8672
8894
|
function collectFlowVersions(dir, domain, out) {
|
|
8673
|
-
for (const f of
|
|
8895
|
+
for (const f of fs11__default.readdirSync(dir)) {
|
|
8674
8896
|
if (!f.endsWith(".flow.yaml")) continue;
|
|
8675
|
-
const fp =
|
|
8676
|
-
const content =
|
|
8897
|
+
const fp = path35__default.join(dir, f);
|
|
8898
|
+
const content = fs11__default.readFileSync(fp, "utf-8");
|
|
8677
8899
|
const parsed = parse(content);
|
|
8678
8900
|
out.push({
|
|
8679
8901
|
kind: "flow",
|
|
@@ -8685,10 +8907,10 @@ function collectFlowVersions(dir, domain, out) {
|
|
|
8685
8907
|
}
|
|
8686
8908
|
}
|
|
8687
8909
|
function collectPromptVersions(dir, domain, out) {
|
|
8688
|
-
for (const f of
|
|
8910
|
+
for (const f of fs11__default.readdirSync(dir)) {
|
|
8689
8911
|
if (!f.endsWith(".prompt.md")) continue;
|
|
8690
|
-
const fp =
|
|
8691
|
-
const content =
|
|
8912
|
+
const fp = path35__default.join(dir, f);
|
|
8913
|
+
const content = fs11__default.readFileSync(fp, "utf-8");
|
|
8692
8914
|
const fm = parseSkillFrontmatter(content);
|
|
8693
8915
|
out.push({
|
|
8694
8916
|
kind: "prompt",
|
|
@@ -8700,12 +8922,12 @@ function collectPromptVersions(dir, domain, out) {
|
|
|
8700
8922
|
}
|
|
8701
8923
|
}
|
|
8702
8924
|
function collectSkillVersions(dir, domain, out) {
|
|
8703
|
-
for (const entry of
|
|
8925
|
+
for (const entry of fs11__default.readdirSync(dir, { withFileTypes: true })) {
|
|
8704
8926
|
if (!entry.isDirectory()) continue;
|
|
8705
|
-
const full =
|
|
8706
|
-
const skillMd =
|
|
8707
|
-
if (
|
|
8708
|
-
const content =
|
|
8927
|
+
const full = path35__default.join(dir, entry.name);
|
|
8928
|
+
const skillMd = path35__default.join(full, "SKILL.md");
|
|
8929
|
+
if (fs11__default.existsSync(skillMd)) {
|
|
8930
|
+
const content = fs11__default.readFileSync(skillMd, "utf-8");
|
|
8709
8931
|
const fm = parseSkillFrontmatter(content);
|
|
8710
8932
|
out.push({
|
|
8711
8933
|
kind: "skill",
|
|
@@ -8720,11 +8942,11 @@ function collectSkillVersions(dir, domain, out) {
|
|
|
8720
8942
|
}
|
|
8721
8943
|
}
|
|
8722
8944
|
function collectAgentVersions(dir, domain, out) {
|
|
8723
|
-
for (const entry of
|
|
8945
|
+
for (const entry of fs11__default.readdirSync(dir, { withFileTypes: true })) {
|
|
8724
8946
|
if (!entry.isDirectory()) continue;
|
|
8725
|
-
const agentYaml =
|
|
8726
|
-
if (!
|
|
8727
|
-
const content =
|
|
8947
|
+
const agentYaml = path35__default.join(dir, entry.name, "agent.yaml");
|
|
8948
|
+
if (!fs11__default.existsSync(agentYaml)) continue;
|
|
8949
|
+
const content = fs11__default.readFileSync(agentYaml, "utf-8");
|
|
8728
8950
|
const parsed = parse(content);
|
|
8729
8951
|
out.push({
|
|
8730
8952
|
kind: "agent",
|
|
@@ -8755,7 +8977,7 @@ function filterToChangedAssets(assets) {
|
|
|
8755
8977
|
encoding: "utf-8"
|
|
8756
8978
|
});
|
|
8757
8979
|
const changedFiles = new Set(
|
|
8758
|
-
diffOutput.trim().split("\n").filter(Boolean).map((f) =>
|
|
8980
|
+
diffOutput.trim().split("\n").filter(Boolean).map((f) => path35__default.resolve(AI_RESOURCES, f))
|
|
8759
8981
|
);
|
|
8760
8982
|
return assets.filter((a) => changedFiles.has(a.filePath));
|
|
8761
8983
|
} catch {
|
|
@@ -8781,7 +9003,7 @@ function checkVersionBumps(assets) {
|
|
|
8781
9003
|
let warnings = 0;
|
|
8782
9004
|
for (const a of assets) {
|
|
8783
9005
|
if (!a.version) continue;
|
|
8784
|
-
const relPath =
|
|
9006
|
+
const relPath = path35__default.relative(AI_RESOURCES, a.filePath);
|
|
8785
9007
|
try {
|
|
8786
9008
|
const headContent = execSync(`git show HEAD:${relPath}`, {
|
|
8787
9009
|
cwd: AI_RESOURCES,
|
|
@@ -8813,7 +9035,7 @@ function checkFlowVersionPins(assets) {
|
|
|
8813
9035
|
pins = flowSkillVersionPins(loadFlow(f.filePath));
|
|
8814
9036
|
} catch (err) {
|
|
8815
9037
|
logWarn(
|
|
8816
|
-
`flow:${f.name} (${
|
|
9038
|
+
`flow:${f.name} (${path35__default.relative(AI_RESOURCES, f.filePath)}) \u2014 could not be read: ${err instanceof Error ? err.message : err}`
|
|
8817
9039
|
);
|
|
8818
9040
|
warnings++;
|
|
8819
9041
|
continue;
|
|
@@ -8863,7 +9085,7 @@ function makeValidateCommand() {
|
|
|
8863
9085
|
"--strict-conformance",
|
|
8864
9086
|
"Treat Agent Skills (agentskills.io) standard findings as errors"
|
|
8865
9087
|
).action((targetPath, opts) => {
|
|
8866
|
-
const absPath =
|
|
9088
|
+
const absPath = path35__default.resolve(targetPath);
|
|
8867
9089
|
logInfo(`Validating manifests in ${absPath}`);
|
|
8868
9090
|
const { total, errors, warnings } = validateManifests(
|
|
8869
9091
|
absPath,
|
|
@@ -8873,7 +9095,7 @@ function makeValidateCommand() {
|
|
|
8873
9095
|
const totalErrors = errors + ws.errors;
|
|
8874
9096
|
console.log();
|
|
8875
9097
|
logInfo(`Scanned ${total} asset manifest(s) and ${ws.total} skaile.yaml file(s)`);
|
|
8876
|
-
if (warnings > 0) logWarn(`${warnings}
|
|
9098
|
+
if (warnings > 0) logWarn(`${warnings} warning(s)`);
|
|
8877
9099
|
if (totalErrors === 0) {
|
|
8878
9100
|
logOk("All manifests valid");
|
|
8879
9101
|
} else {
|
|
@@ -8913,7 +9135,7 @@ function makeValidateCommand() {
|
|
|
8913
9135
|
let errors = 0;
|
|
8914
9136
|
for (const domain of modifiedDomains) {
|
|
8915
9137
|
const changelogModified = modifiedFiles.some(
|
|
8916
|
-
(f) => f === `${domain}/CHANGELOG.md` || f ===
|
|
9138
|
+
(f) => f === `${domain}/CHANGELOG.md` || f === path35__default.join(domain, "CHANGELOG.md")
|
|
8917
9139
|
);
|
|
8918
9140
|
if (changelogModified) {
|
|
8919
9141
|
logOk(`${domain}/CHANGELOG.md updated`);
|
|
@@ -9019,7 +9241,7 @@ function whyEmptyMessage(ref, declared) {
|
|
|
9019
9241
|
}
|
|
9020
9242
|
function makeWhyCommand() {
|
|
9021
9243
|
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) => {
|
|
9022
|
-
const am2 = new AssetManager({ projectDir:
|
|
9244
|
+
const am2 = new AssetManager({ projectDir: path35__default.resolve(opts.projectDir) });
|
|
9023
9245
|
const chain = am2.why(ref);
|
|
9024
9246
|
if (chain.length === 0) {
|
|
9025
9247
|
let declared;
|
|
@@ -9053,7 +9275,7 @@ function makeWhyCommand() {
|
|
|
9053
9275
|
var _defaultFormatHelp = Help.prototype.formatHelp;
|
|
9054
9276
|
var pkg = JSON.parse(
|
|
9055
9277
|
readFileSync(
|
|
9056
|
-
|
|
9278
|
+
path35__default.resolve(path35__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
|
|
9057
9279
|
"utf-8"
|
|
9058
9280
|
)
|
|
9059
9281
|
);
|
|
@@ -9138,10 +9360,11 @@ Libraries (your authoring workspaces):
|
|
|
9138
9360
|
library create <kind> <name> Scaffold a new asset in a library
|
|
9139
9361
|
library list / show / status Library inspection
|
|
9140
9362
|
library default <name> Set the default library
|
|
9363
|
+
library domain / index Domains (publisher namespaces), re-index assets
|
|
9141
9364
|
library rename / set / remove
|
|
9142
9365
|
library commit / pull / push / propose / git Git ops (git backend only)
|
|
9143
9366
|
library sync <name> Pull then push (as backend permits)
|
|
9144
|
-
library publish / register / yank <
|
|
9367
|
+
library publish / register / yank <lib> Push + register in the store
|
|
9145
9368
|
|
|
9146
9369
|
Store (manifest catalog + auth):
|
|
9147
9370
|
store login / logout / whoami / yank Auth + admin
|
|
@@ -9166,9 +9389,9 @@ Advanced:
|
|
|
9166
9389
|
}
|
|
9167
9390
|
});
|
|
9168
9391
|
var HARNESS_DEFAULTS = {
|
|
9169
|
-
"claude-code": { driver: "claude-sdk"
|
|
9392
|
+
"claude-code": { driver: "claude-sdk" },
|
|
9170
9393
|
omp: { driver: "omp" },
|
|
9171
|
-
codex: { driver: "codex"
|
|
9394
|
+
codex: { driver: "codex" }
|
|
9172
9395
|
};
|
|
9173
9396
|
program.command("init [project-dir]").description("Initialize a project directory (defaults to current directory)").option("--harness <name>", "Coding-agent harness (claude-code | omp | codex)", "claude-code").option("--no-git", "Skip git init and .gitignore").action(
|
|
9174
9397
|
(projectDir, opts) => runInit(projectDir, opts)
|
|
@@ -9183,32 +9406,32 @@ async function runInit(projectDir, opts) {
|
|
|
9183
9406
|
process.exitCode = 1;
|
|
9184
9407
|
return;
|
|
9185
9408
|
}
|
|
9186
|
-
const resolved =
|
|
9187
|
-
const projectName =
|
|
9409
|
+
const resolved = path35__default.resolve(projectDir ?? ".");
|
|
9410
|
+
const projectName = path35__default.basename(resolved);
|
|
9188
9411
|
const created = [];
|
|
9189
|
-
const { existsSync:
|
|
9190
|
-
if (!
|
|
9412
|
+
const { existsSync: existsSync14 } = await import('fs');
|
|
9413
|
+
if (!existsSync14(resolved)) {
|
|
9191
9414
|
mkdirSync5(resolved, { recursive: true });
|
|
9192
9415
|
created.push(".");
|
|
9193
9416
|
}
|
|
9194
|
-
const skaileDir =
|
|
9195
|
-
if (!
|
|
9196
|
-
mkdirSync5(
|
|
9417
|
+
const skaileDir = path35__default.join(resolved, ".skaile");
|
|
9418
|
+
if (!existsSync14(skaileDir)) {
|
|
9419
|
+
mkdirSync5(path35__default.join(skaileDir, "sessions"), { recursive: true });
|
|
9197
9420
|
created.push(".skaile/");
|
|
9198
9421
|
}
|
|
9199
|
-
const settingsPath =
|
|
9200
|
-
if (!
|
|
9422
|
+
const settingsPath = path35__default.join(skaileDir, "settings.json");
|
|
9423
|
+
if (!existsSync14(settingsPath)) {
|
|
9201
9424
|
writeFileSync6(settingsPath, "{}\n");
|
|
9202
9425
|
created.push(".skaile/settings.json");
|
|
9203
9426
|
}
|
|
9204
|
-
const wsConfigPath =
|
|
9205
|
-
if (!
|
|
9427
|
+
const wsConfigPath = path35__default.join(resolved, "skaile.yaml");
|
|
9428
|
+
if (!existsSync14(wsConfigPath)) {
|
|
9206
9429
|
writeFileSync6(wsConfigPath, stringify2(buildInitWorkspaceConfig(projectName, harness)));
|
|
9207
9430
|
created.push("skaile.yaml");
|
|
9208
9431
|
}
|
|
9209
9432
|
for (const dir of new Set(Object.values(DRIVER_TARGETS[harness].local))) {
|
|
9210
|
-
const full =
|
|
9211
|
-
if (!
|
|
9433
|
+
const full = path35__default.join(resolved, dir);
|
|
9434
|
+
if (!existsSync14(full)) {
|
|
9212
9435
|
mkdirSync5(full, { recursive: true });
|
|
9213
9436
|
created.push(`${dir}/`);
|
|
9214
9437
|
}
|
|
@@ -9228,8 +9451,7 @@ function buildInitWorkspaceConfig(projectName, harness) {
|
|
|
9228
9451
|
"agent-config": {
|
|
9229
9452
|
default: {
|
|
9230
9453
|
agent: harness,
|
|
9231
|
-
//
|
|
9232
|
-
...harnessDefaults.provider ? { provider: harnessDefaults.provider } : {},
|
|
9454
|
+
// model is omitted unless a harness fixes it (none do today).
|
|
9233
9455
|
...harnessDefaults.model ? { model: harnessDefaults.model } : {},
|
|
9234
9456
|
driver: harnessDefaults.driver,
|
|
9235
9457
|
max_turns: 200
|
|
@@ -9239,8 +9461,8 @@ function buildInitWorkspaceConfig(projectName, harness) {
|
|
|
9239
9461
|
}
|
|
9240
9462
|
async function initGitScaffold(resolved, created) {
|
|
9241
9463
|
const { execSync: execSync3 } = await import('child_process');
|
|
9242
|
-
const { existsSync:
|
|
9243
|
-
const gitignorePath =
|
|
9464
|
+
const { existsSync: existsSync14, readFileSync: readFileSync10, writeFileSync: writeFileSync6 } = await import('fs');
|
|
9465
|
+
const gitignorePath = path35__default.join(resolved, ".gitignore");
|
|
9244
9466
|
const entries = [
|
|
9245
9467
|
"node_modules/",
|
|
9246
9468
|
".skaile/sessions/",
|
|
@@ -9257,7 +9479,7 @@ async function initGitScaffold(resolved, created) {
|
|
|
9257
9479
|
".env",
|
|
9258
9480
|
".env.local"
|
|
9259
9481
|
];
|
|
9260
|
-
const existing =
|
|
9482
|
+
const existing = existsSync14(gitignorePath) ? readFileSync10(gitignorePath, "utf-8") : "";
|
|
9261
9483
|
const have = new Set(existing.split("\n").map((l) => l.trim()));
|
|
9262
9484
|
const append = entries.filter((e) => !have.has(e));
|
|
9263
9485
|
if (append.length > 0) {
|
|
@@ -9266,7 +9488,7 @@ async function initGitScaffold(resolved, created) {
|
|
|
9266
9488
|
`);
|
|
9267
9489
|
if (!existing) created.push(".gitignore");
|
|
9268
9490
|
}
|
|
9269
|
-
if (!
|
|
9491
|
+
if (!existsSync14(path35__default.join(resolved, ".git"))) {
|
|
9270
9492
|
try {
|
|
9271
9493
|
execSync3("git init", { cwd: resolved, stdio: "pipe" });
|
|
9272
9494
|
created.push(".git/");
|
|
@@ -9278,10 +9500,10 @@ async function initGitScaffold(resolved, created) {
|
|
|
9278
9500
|
}
|
|
9279
9501
|
async function bootstrapUserConfig() {
|
|
9280
9502
|
try {
|
|
9281
|
-
const
|
|
9503
|
+
const fs12 = await import('fs');
|
|
9282
9504
|
const { userConfigPath, saveConfig, getConfigDefaults } = await import('../library/index.js');
|
|
9283
9505
|
const userCfgPath = userConfigPath();
|
|
9284
|
-
if (!
|
|
9506
|
+
if (!fs12.existsSync(userCfgPath)) {
|
|
9285
9507
|
const defaults = getConfigDefaults();
|
|
9286
9508
|
saveConfig(userCfgPath, {
|
|
9287
9509
|
catalog: { url: defaults.catalog.url, cache_ttl: defaults.catalog.cache_ttl }
|
|
@@ -9296,7 +9518,7 @@ async function bootstrapUserConfig() {
|
|
|
9296
9518
|
}
|
|
9297
9519
|
async function hydrateInitSources(resolved, created) {
|
|
9298
9520
|
try {
|
|
9299
|
-
const { ensureSourcesCloned } = await import('../ensure-sources-
|
|
9521
|
+
const { ensureSourcesCloned } = await import('../ensure-sources-VX63EKY7.js');
|
|
9300
9522
|
const hydrate = ensureSourcesCloned(resolved, { quiet: true });
|
|
9301
9523
|
for (const n of hydrate.cloned) created.push(`~/.skaile/cache/sources/${n}/`);
|
|
9302
9524
|
if (hydrate.failed.length > 0) {
|
|
@@ -9312,7 +9534,7 @@ function printInitSummary(resolved, projectDir, created) {
|
|
|
9312
9534
|
logOk(`Initialized project at ${S.heading(resolved)}`);
|
|
9313
9535
|
console.log();
|
|
9314
9536
|
console.log(S.heading(" Next steps:"));
|
|
9315
|
-
const isCurrentDir = resolved ===
|
|
9537
|
+
const isCurrentDir = resolved === path35__default.resolve(".");
|
|
9316
9538
|
let step = 1;
|
|
9317
9539
|
if (!isCurrentDir) {
|
|
9318
9540
|
console.log(` ${S.dim(`${step}.`)} ${S.cmd(`cd ${projectDir}`)}`);
|
|
@@ -9336,7 +9558,7 @@ function printInitSummary(resolved, projectDir, created) {
|
|
|
9336
9558
|
console.log();
|
|
9337
9559
|
}
|
|
9338
9560
|
program.command("setup").description("Interactive provider setup wizard").action(async () => {
|
|
9339
|
-
const { cmdSetup } = await import('../setup-
|
|
9561
|
+
const { cmdSetup } = await import('../setup-ZA7VZL72.js');
|
|
9340
9562
|
await cmdSetup([], { projectDir: process.cwd() });
|
|
9341
9563
|
});
|
|
9342
9564
|
program.addCommand(makeInstallCommand());
|