@skaile/workspaces 0.21.0 → 0.22.0-beta.1
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 +176 -0
- package/dist/{asset-feeds-CI76R7FI.js → asset-feeds-QXCSAJRN.js} +11 -11
- package/dist/{asset-feeds-CI76R7FI.js.map → asset-feeds-QXCSAJRN.js.map} +1 -1
- package/dist/asset-manager/catalog-deployer.d.ts +2 -0
- package/dist/asset-manager/contrib.d.ts +2 -0
- package/dist/asset-manager/fragments.d.ts +2 -0
- package/dist/asset-manager/history.d.ts +2 -0
- package/dist/asset-manager/index.d.ts +2 -0
- package/dist/asset-manager/index.js +9 -9
- package/dist/asset-manager/installer.d.ts +2 -0
- package/dist/asset-manager/installer.js +8 -8
- package/dist/asset-manager/renderers.d.ts +2 -0
- package/dist/asset-manager/src/index.d.ts +18 -7
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts +3 -3
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/base-assets/connectors/deploy.d.ts +2 -0
- package/dist/base-assets/connectors/deploy.js +10 -9
- package/dist/base-assets/connectors/devserver.d.ts +2 -0
- package/dist/base-assets/connectors/devserver.js +10 -9
- package/dist/base-assets/connectors/flow/adapter.js +10 -9
- package/dist/base-assets/connectors/flow/engine.d.ts +2 -0
- package/dist/base-assets/connectors/flow/run-flow.js +11 -10
- package/dist/base-assets/connectors/flow.d.ts +2 -0
- package/dist/base-assets/connectors/flow.js +10 -9
- package/dist/base-assets/connectors/git.d.ts +2 -0
- package/dist/base-assets/connectors/git.js +10 -9
- package/dist/base-assets/connectors/gmail.d.ts +2 -0
- package/dist/base-assets/connectors/gmail.js +10 -9
- package/dist/base-assets/connectors/googledrive.d.ts +2 -0
- package/dist/base-assets/connectors/googledrive.js +10 -9
- package/dist/base-assets/connectors/local.d.ts +2 -0
- package/dist/base-assets/connectors/local.js +10 -9
- package/dist/base-assets/connectors/mattermost.d.ts +2 -0
- package/dist/base-assets/connectors/mattermost.js +10 -9
- package/dist/base-assets/connectors/memory.d.ts +2 -0
- package/dist/base-assets/connectors/memory.js +10 -9
- package/dist/base-assets/connectors/minio.d.ts +2 -0
- package/dist/base-assets/connectors/minio.js +10 -9
- package/dist/base-assets/connectors/postgres.d.ts +2 -0
- package/dist/base-assets/connectors/postgres.js +10 -9
- package/dist/base-assets/connectors/s3.d.ts +2 -0
- package/dist/base-assets/connectors/s3.js +10 -9
- package/dist/base-assets/connectors/sharepoint.d.ts +2 -0
- package/dist/base-assets/connectors/sharepoint.js +10 -9
- package/dist/base-assets/connectors/sqlite.d.ts +2 -0
- package/dist/base-assets/connectors/sqlite.js +10 -9
- package/dist/base-assets/connectors/static-server.d.ts +2 -0
- package/dist/base-assets/connectors/static-server.js +10 -9
- package/dist/base-assets/connectors/tunnel.d.ts +2 -0
- package/dist/base-assets/connectors/tunnel.js +10 -9
- package/dist/base-assets/connectors/webdav.d.ts +2 -0
- package/dist/base-assets/connectors/webdav.js +10 -9
- package/dist/base-assets/connectors/xstate-store.d.ts +2 -0
- package/dist/base-assets/connectors/xstate-store.js +10 -9
- package/dist/base-assets/connectors/xstate.d.ts +2 -0
- package/dist/base-assets/connectors/xstate.js +10 -9
- package/dist/bridge/drivers/claude-sdk.d.ts +2 -0
- package/dist/bridge/drivers/claude-sdk.js +13 -3
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.d.ts +2 -0
- package/dist/bridge/drivers/codex.js +13 -3
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/echo.d.ts +2 -0
- package/dist/bridge/drivers/echo.js +13 -4
- package/dist/bridge/drivers/echo.js.map +1 -1
- package/dist/bridge/drivers/omp.d.ts +2 -0
- package/dist/bridge/drivers/omp.js +13 -3
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/index.d.ts +2 -0
- package/dist/bridge/index.js +3 -2
- package/dist/bridge/src/drivers/claude-sdk.d.ts +7 -0
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/codex.d.ts +7 -0
- package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
- package/dist/bridge/src/drivers/echo.d.ts +6 -0
- package/dist/bridge/src/drivers/echo.d.ts.map +1 -1
- package/dist/bridge/src/drivers/omp.d.ts +6 -0
- package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
- package/dist/bridge/src/registry.d.ts +34 -34
- package/dist/bridge/src/registry.d.ts.map +1 -1
- package/dist/{chunk-ZWIG55ZX.js → chunk-2XY6732A.js} +3 -3
- package/dist/{chunk-ZWIG55ZX.js.map → chunk-2XY6732A.js.map} +1 -1
- package/dist/{chunk-NCUTHLRV.js → chunk-3ECS5PFD.js} +4 -4
- package/dist/{chunk-NCUTHLRV.js.map → chunk-3ECS5PFD.js.map} +1 -1
- package/dist/{chunk-FRPKLIEZ.js → chunk-4AZKT2BU.js} +13 -13
- package/dist/chunk-4AZKT2BU.js.map +1 -0
- package/dist/chunk-6E6PKKAD.js +161 -0
- package/dist/chunk-6E6PKKAD.js.map +1 -0
- package/dist/{chunk-4ACWI5YT.js → chunk-6VTG73UY.js} +48 -36
- package/dist/chunk-6VTG73UY.js.map +1 -0
- package/dist/{chunk-H45ANMIU.js → chunk-APAOQLPT.js} +3 -3
- package/dist/{chunk-H45ANMIU.js.map → chunk-APAOQLPT.js.map} +1 -1
- package/dist/{chunk-4S4TZDCD.js → chunk-D7K72XEY.js} +3 -3
- package/dist/{chunk-4S4TZDCD.js.map → chunk-D7K72XEY.js.map} +1 -1
- package/dist/{chunk-2WVQMRIE.js → chunk-DKGDOALM.js} +5 -5
- package/dist/{chunk-2WVQMRIE.js.map → chunk-DKGDOALM.js.map} +1 -1
- package/dist/{chunk-DFUXWNTS.js → chunk-GFNW72LW.js} +17 -5
- package/dist/chunk-GFNW72LW.js.map +1 -0
- package/dist/{chunk-37JKX6D7.js → chunk-I3UEM3FX.js} +36 -8
- package/dist/chunk-I3UEM3FX.js.map +1 -0
- package/dist/{chunk-5QNQLSBW.js → chunk-J3VKAEQP.js} +514 -143
- package/dist/chunk-J3VKAEQP.js.map +1 -0
- package/dist/{chunk-BSY56QS7.js → chunk-JHF66MCK.js} +49 -3
- package/dist/chunk-JHF66MCK.js.map +1 -0
- package/dist/{chunk-XAVM2BAJ.js → chunk-LT4DLEYE.js} +114 -619
- package/dist/chunk-LT4DLEYE.js.map +1 -0
- package/dist/{chunk-S2OVTCAL.js → chunk-M5TE6YI5.js} +3 -3
- package/dist/{chunk-S2OVTCAL.js.map → chunk-M5TE6YI5.js.map} +1 -1
- package/dist/{chunk-RDH4SSMH.js → chunk-NJLHHZIW.js} +2 -2
- package/dist/{chunk-RDH4SSMH.js.map → chunk-NJLHHZIW.js.map} +1 -1
- package/dist/{chunk-XGWGLIHZ.js → chunk-PTIHB2TV.js} +5 -5
- package/dist/{chunk-XGWGLIHZ.js.map → chunk-PTIHB2TV.js.map} +1 -1
- package/dist/{chunk-W5DFC35Z.js → chunk-UMOENHVH.js} +279 -133
- package/dist/chunk-UMOENHVH.js.map +1 -0
- package/dist/{chunk-G4BR355S.js → chunk-V3QMSM5I.js} +38 -43
- package/dist/chunk-V3QMSM5I.js.map +1 -0
- package/dist/{chunk-DEQ3OOTU.js → chunk-VCYXVP2S.js} +263 -177
- package/dist/chunk-VCYXVP2S.js.map +1 -0
- package/dist/{chunk-KFDTS7RX.js → chunk-XIHFJVOD.js} +3 -3
- package/dist/{chunk-KFDTS7RX.js.map → chunk-XIHFJVOD.js.map} +1 -1
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +762 -472
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/deploy.d.ts +24 -0
- package/dist/cli/src/commands/deploy.d.ts.map +1 -0
- package/dist/cli/src/commands/integration.d.ts +19 -0
- package/dist/cli/src/commands/integration.d.ts.map +1 -0
- package/dist/cli/src/commands/manage.d.ts +1 -1
- package/dist/cli/src/commands/plugin-registry-cmd.d.ts +22 -0
- package/dist/cli/src/commands/plugin-registry-cmd.d.ts.map +1 -0
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/serve.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/update.d.ts.map +1 -1
- package/dist/cli/src/ensure-sources.d.ts.map +1 -1
- package/dist/cli/src/plugin-store/index.d.ts +37 -0
- package/dist/cli/src/plugin-store/index.d.ts.map +1 -0
- package/dist/cli/src/plugin-store/load.d.ts +35 -0
- package/dist/cli/src/plugin-store/load.d.ts.map +1 -0
- package/dist/cli/src/plugin-store/paths.d.ts +23 -0
- package/dist/cli/src/plugin-store/paths.d.ts.map +1 -0
- package/dist/cli/src/plugin-store/reconcile.d.ts +50 -0
- package/dist/cli/src/plugin-store/reconcile.d.ts.map +1 -0
- package/dist/cli/src/plugin-store/spec.d.ts +25 -0
- package/dist/cli/src/plugin-store/spec.d.ts.map +1 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/connectors/config.d.ts +2 -0
- package/dist/connectors/config.js +8 -8
- package/dist/connectors/index.d.ts +2 -0
- package/dist/connectors/index.js +10 -9
- package/dist/connectors/rclone-config.d.ts +2 -0
- package/dist/connectors/rclone.d.ts +2 -0
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/connectors/src/connector-registry.d.ts +42 -22
- package/dist/connectors/src/connector-registry.d.ts.map +1 -1
- package/dist/connectors/src/index.d.ts +2 -3
- package/dist/connectors/src/index.d.ts.map +1 -1
- package/dist/connectors-shared/index.d.ts +2 -0
- package/dist/connectors-shared/index.js +8 -0
- package/dist/connectors-shared/index.js.map +1 -0
- package/dist/connectors-shared/src/index.d.ts +11 -0
- package/dist/connectors-shared/src/index.d.ts.map +1 -0
- package/dist/connectors-shared/src/schemas.d.ts +10 -0
- package/dist/connectors-shared/src/schemas.d.ts.map +1 -0
- package/dist/connectors-shared/src/types.d.ts +11 -0
- package/dist/connectors-shared/src/types.d.ts.map +1 -0
- package/dist/core/discovery.d.ts +2 -0
- package/dist/core/driver-targets.d.ts +2 -0
- package/dist/core/framework.d.ts +2 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +7 -7
- package/dist/core/logging.d.ts +2 -0
- package/dist/core/manifest.d.ts +2 -0
- package/dist/core/manifest.js +2 -2
- package/dist/core/models.d.ts +2 -0
- package/dist/core/models.js +1 -1
- package/dist/core/runtime-assets.d.ts +2 -0
- package/dist/core/runtime-assets.js +4 -4
- package/dist/core/src/index.d.ts +8 -6
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/lock.d.ts +64 -24
- package/dist/core/src/lock.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +66 -47
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts +62 -34
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/runtime-assets.d.ts.map +1 -1
- package/dist/core/src/walker.d.ts +52 -0
- package/dist/core/src/walker.d.ts.map +1 -0
- package/dist/core/src/workspace-config.d.ts +174 -45
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/src/workspace-yaml-editor.d.ts +53 -16
- package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
- package/dist/core/store.d.ts +2 -0
- package/dist/core/workspace-config.d.ts +2 -0
- package/dist/core/workspace-config.js +3 -3
- package/dist/deploy/index.d.ts +2 -0
- package/dist/deploy/index.js +473 -0
- package/dist/deploy/index.js.map +1 -0
- package/dist/deploy/src/handle-store.d.ts +22 -0
- package/dist/deploy/src/handle-store.d.ts.map +1 -0
- package/dist/deploy/src/index.d.ts +21 -0
- package/dist/deploy/src/index.d.ts.map +1 -0
- package/dist/deploy/src/targets/container-runtime.d.ts +39 -0
- package/dist/deploy/src/targets/container-runtime.d.ts.map +1 -0
- package/dist/deploy/src/targets/docker.d.ts +19 -0
- package/dist/deploy/src/targets/docker.d.ts.map +1 -0
- package/dist/deploy/src/targets/local.d.ts +30 -0
- package/dist/deploy/src/targets/local.d.ts.map +1 -0
- package/dist/deploy/src/targets/podman.d.ts +19 -0
- package/dist/deploy/src/targets/podman.d.ts.map +1 -0
- package/dist/deploy/src/targets/port.d.ts +10 -0
- package/dist/deploy/src/targets/port.d.ts.map +1 -0
- package/dist/deploy/src/targets/stream-lines.d.ts +44 -0
- package/dist/deploy/src/targets/stream-lines.d.ts.map +1 -0
- package/dist/discovery/index.d.ts +2 -0
- package/dist/discovery/index.js +3 -3
- package/dist/discovery/src/source-config.d.ts +2 -2
- package/dist/{ensure-sources-IDVQ77NJ.js → ensure-sources-SL2S4UEX.js} +22 -18
- package/dist/ensure-sources-SL2S4UEX.js.map +1 -0
- package/dist/{flows-6BNO4GKK.js → flows-DYFTPCPM.js} +4 -4
- package/dist/{flows-6BNO4GKK.js.map → flows-DYFTPCPM.js.map} +1 -1
- package/dist/library/index.d.ts +2 -0
- package/dist/library/index.js +4 -4
- package/dist/library/src/remote/remote-catalog-source.d.ts +17 -0
- package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
- package/dist/open-library-M4DB3D3J.js +13 -0
- package/dist/{open-library-IOYWFK7M.js.map → open-library-M4DB3D3J.js.map} +1 -1
- package/dist/plugin-registry/index.d.ts +2 -0
- package/dist/plugin-registry/index.js +4 -0
- package/dist/plugin-registry/index.js.map +1 -0
- package/dist/plugin-registry/src/context.d.ts +29 -0
- package/dist/plugin-registry/src/context.d.ts.map +1 -0
- package/dist/plugin-registry/src/deploy-handle.d.ts +76 -0
- package/dist/plugin-registry/src/deploy-handle.d.ts.map +1 -0
- package/dist/plugin-registry/src/deploy-helpers.d.ts +69 -0
- package/dist/plugin-registry/src/deploy-helpers.d.ts.map +1 -0
- package/dist/plugin-registry/src/errors.d.ts +23 -0
- package/dist/plugin-registry/src/errors.d.ts.map +1 -0
- package/dist/plugin-registry/src/index.d.ts +18 -0
- package/dist/plugin-registry/src/index.d.ts.map +1 -0
- package/dist/plugin-registry/src/internal.d.ts +13 -0
- package/dist/plugin-registry/src/internal.d.ts.map +1 -0
- package/dist/plugin-registry/src/registry.d.ts +26 -0
- package/dist/plugin-registry/src/registry.d.ts.map +1 -0
- package/dist/plugin-registry/src/targets.d.ts +46 -0
- package/dist/plugin-registry/src/targets.d.ts.map +1 -0
- package/dist/plugin-store-AJ3FGXIC.js +144 -0
- package/dist/plugin-store-AJ3FGXIC.js.map +1 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/resolver/index.d.ts +2 -0
- package/dist/runner/index.d.ts +2 -0
- package/dist/runner/index.js +15 -14
- package/dist/runner/prompt-assembly.d.ts +2 -0
- package/dist/runner/src/resources.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.d.ts +2 -0
- package/dist/sdk/asset-manager.js +9 -9
- package/dist/sdk/bridge.d.ts +2 -0
- package/dist/sdk/bridge.js +3 -2
- package/dist/sdk/client.d.ts +2 -0
- package/dist/sdk/core.d.ts +2 -0
- package/dist/sdk/core.js +7 -7
- package/dist/sdk/flow.d.ts +2 -0
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.js +51 -17
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.d.ts +2 -0
- package/dist/sdk/runner.d.ts +2 -0
- package/dist/sdk/runner.js +15 -14
- package/dist/sdk/session.d.ts +2 -0
- package/dist/sdk/src/local-runtime.d.ts +8 -0
- package/dist/sdk/src/local-runtime.d.ts.map +1 -1
- package/dist/sdk/src/transport.d.ts +7 -1
- package/dist/sdk/src/transport.d.ts.map +1 -1
- package/dist/sdk/store.d.ts +2 -0
- package/dist/sdk/telemetry.d.ts +2 -0
- package/dist/sdk/transport/ws/client.d.ts +2 -0
- package/dist/sdk/transport/ws/server.d.ts +2 -0
- package/dist/sdk/transport/ws.d.ts +2 -0
- package/dist/sdk/transport.d.ts +2 -0
- package/dist/sdk/types.d.ts +2 -0
- package/dist/secrets/index.d.ts +2 -0
- package/dist/session/index.d.ts +2 -0
- package/dist/{setup-AIOLUTKV.js → setup-GBSQX7JF.js} +12 -11
- package/dist/setup-GBSQX7JF.js.map +1 -0
- package/dist/store/index.d.ts +2 -0
- package/dist/store/react.d.ts +2 -0
- package/dist/store/vue.d.ts +2 -0
- package/dist/store-client-5WBRUC5U.js +14 -0
- package/dist/{store-client-CYEH2GKC.js.map → store-client-5WBRUC5U.js.map} +1 -1
- package/dist/telemetry/index.d.ts +2 -0
- package/dist/transport/index.d.ts +2 -0
- package/dist/transport/ws/client.d.ts +2 -0
- package/dist/transport/ws/server.d.ts +2 -0
- package/dist/transport/ws.d.ts +2 -0
- package/dist/tui/index.d.ts +2 -0
- package/dist/tui/index.js +15 -14
- package/dist/tui/index.js.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/manifests.d.ts +2 -0
- package/dist/workspace-plugin/adapters/mcp.d.ts +2 -0
- package/dist/workspace-plugin/adapters/mcp.js +2 -2
- package/dist/workspace-plugin/adapters/omp.d.ts +2 -0
- package/dist/workspace-plugin/adapters/omp.js +3 -3
- package/dist/workspace-plugin/index.d.ts +2 -0
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +23 -24
- package/dist/base-assets/connectors/redis/adapter.d.ts +0 -39
- package/dist/base-assets/connectors/redis/adapter.d.ts.map +0 -1
- package/dist/base-assets/connectors/redis.js +0 -20
- package/dist/base-assets/connectors/redis.js.map +0 -1
- package/dist/base-assets/connectors/yjs/adapter.d.ts +0 -50
- package/dist/base-assets/connectors/yjs/adapter.d.ts.map +0 -1
- package/dist/base-assets/connectors/yjs.js +0 -20
- package/dist/base-assets/connectors/yjs.js.map +0 -1
- package/dist/chunk-37JKX6D7.js.map +0 -1
- package/dist/chunk-4ACWI5YT.js.map +0 -1
- package/dist/chunk-5QNQLSBW.js.map +0 -1
- package/dist/chunk-BSY56QS7.js.map +0 -1
- package/dist/chunk-DEQ3OOTU.js.map +0 -1
- package/dist/chunk-DFUXWNTS.js.map +0 -1
- package/dist/chunk-FRPKLIEZ.js.map +0 -1
- package/dist/chunk-G4BR355S.js.map +0 -1
- package/dist/chunk-W5DFC35Z.js.map +0 -1
- package/dist/chunk-XAVM2BAJ.js.map +0 -1
- package/dist/cli/src/commands/plugin.d.ts +0 -14
- package/dist/cli/src/commands/plugin.d.ts.map +0 -1
- package/dist/ensure-sources-IDVQ77NJ.js.map +0 -1
- package/dist/open-library-IOYWFK7M.js +0 -13
- package/dist/setup-AIOLUTKV.js.map +0 -1
- package/dist/store-client-CYEH2GKC.js +0 -14
package/dist/cli/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { openCatalogSource, openLibrary, createFullRegistry, openLibraryManager } from '../chunk-
|
|
2
|
+
import { openCatalogSource, openLibrary, createFullRegistry, openLibraryManager } from '../chunk-3ECS5PFD.js';
|
|
3
3
|
import { logErr, S, logOk, colorRef, logInfo, logWarn, kindColorPad, kindColor, formatRelativeTime } from '../chunk-4NDWKA64.js';
|
|
4
|
-
import { getStoreConfig, storeFetch, saveStoreTokens, clearStoreTokens, isStoreAuthenticated } from '../chunk-
|
|
4
|
+
import { getStoreConfig, storeFetch, saveStoreTokens, clearStoreTokens, isStoreAuthenticated } from '../chunk-XIHFJVOD.js';
|
|
5
5
|
import { AI_RESOURCES } from '../chunk-2M3XTMOL.js';
|
|
6
6
|
import { LocalSecretsProvider } from '../chunk-JDX54X4Y.js';
|
|
7
|
-
import { resolveLibraryDir, LocalCatalogSource, skaileHomeDir } from '../chunk-
|
|
7
|
+
import { resolveLibraryDir, LocalCatalogSource, skaileHomeDir } from '../chunk-JHF66MCK.js';
|
|
8
8
|
import '../chunk-R7FOF242.js';
|
|
9
|
-
import '../chunk-
|
|
9
|
+
import '../chunk-D7K72XEY.js';
|
|
10
10
|
import '../chunk-OKRUTSG7.js';
|
|
11
|
-
import { runFlow, resumeFlow } from '../chunk-
|
|
11
|
+
import { runFlow, resumeFlow } from '../chunk-DKGDOALM.js';
|
|
12
12
|
import '../chunk-GCJXPUHG.js';
|
|
13
13
|
import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-IPUYL6TD.js';
|
|
14
|
-
import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-
|
|
15
|
-
import { buildClaudePluginFiles } from '../chunk-
|
|
14
|
+
import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-V3QMSM5I.js';
|
|
15
|
+
import { buildClaudePluginFiles } from '../chunk-NJLHHZIW.js';
|
|
16
16
|
import '../chunk-X5YPJV4N.js';
|
|
17
17
|
import '../chunk-O7SG5PC2.js';
|
|
18
18
|
import '../chunk-W2O5LWYU.js';
|
|
@@ -20,41 +20,42 @@ import '../chunk-7PTP3SQJ.js';
|
|
|
20
20
|
import '../chunk-PBWMV5GM.js';
|
|
21
21
|
import '../chunk-W3UDISS2.js';
|
|
22
22
|
import '../chunk-TDSRLMDB.js';
|
|
23
|
-
import '../chunk-
|
|
23
|
+
import '../chunk-M5TE6YI5.js';
|
|
24
24
|
import '../chunk-DQWREFRQ.js';
|
|
25
25
|
import '../chunk-KOVLSBXK.js';
|
|
26
26
|
import '../chunk-RRVQAE5D.js';
|
|
27
|
-
import '../chunk-
|
|
28
|
-
import '../chunk-
|
|
29
|
-
import '../chunk-
|
|
27
|
+
import '../chunk-6VTG73UY.js';
|
|
28
|
+
import '../chunk-LV2HPH3C.js';
|
|
29
|
+
import '../chunk-LT4DLEYE.js';
|
|
30
|
+
import '../chunk-APAOQLPT.js';
|
|
30
31
|
import '../chunk-6MB7CRME.js';
|
|
31
32
|
import '../chunk-QAVZOJCV.js';
|
|
33
|
+
import '../chunk-6E6PKKAD.js';
|
|
32
34
|
import { loadAllFlows } from '../chunk-ICS76R4T.js';
|
|
33
35
|
import '../chunk-GZWJGNNN.js';
|
|
34
36
|
import '../chunk-FVTV7M76.js';
|
|
35
|
-
import { AssetManager } from '../chunk-
|
|
36
|
-
import '../chunk-
|
|
37
|
-
import { readLock, resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, portableSpawn, portableSpawnSync, WorkspaceYamlEditor } from '../chunk-
|
|
38
|
-
import '../chunk-JKNWJ64A.js';
|
|
39
|
-
import { SUPPORTED_DRIVER_TARGETS } from '../chunk-O4JH3KUE.js';
|
|
37
|
+
import { AssetManager } from '../chunk-VCYXVP2S.js';
|
|
38
|
+
import '../chunk-PTIHB2TV.js';
|
|
39
|
+
import { readLock, resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, portableSpawn, portableSpawnSync, WorkspaceYamlEditor } from '../chunk-UMOENHVH.js';
|
|
40
40
|
import { DRIVER_DEFAULTS } from '../chunk-K5GBV4SA.js';
|
|
41
41
|
import '../chunk-KLNL7QHN.js';
|
|
42
|
-
import '../chunk-
|
|
43
|
-
import { resolveSkWorkspaceConfig, resolveAgentDir, findWorkspaceRoot, workspaceConfigFilename } from '../chunk-
|
|
44
|
-
import '../chunk-
|
|
45
|
-
import { ASSET_KINDS } from '../chunk-
|
|
42
|
+
import '../chunk-GFNW72LW.js';
|
|
43
|
+
import { resolveSkWorkspaceConfig, resolveAgentDir, findWorkspaceRoot, workspaceConfigFilename } from '../chunk-J3VKAEQP.js';
|
|
44
|
+
import '../chunk-4AZKT2BU.js';
|
|
45
|
+
import { ASSET_KINDS } from '../chunk-I3UEM3FX.js';
|
|
46
|
+
import '../chunk-JKNWJ64A.js';
|
|
47
|
+
import { SUPPORTED_DRIVER_TARGETS } from '../chunk-O4JH3KUE.js';
|
|
46
48
|
import { openSqlite } from '../chunk-24UIWON4.js';
|
|
47
49
|
import '../chunk-KTBKW2FI.js';
|
|
48
50
|
import '../chunk-UQ6LFBPZ.js';
|
|
49
51
|
import '../chunk-6FNCZYJY.js';
|
|
50
52
|
import '../chunk-NELZIQ2E.js';
|
|
51
53
|
import '../chunk-CGYEHQOX.js';
|
|
52
|
-
import '../chunk-LV2HPH3C.js';
|
|
53
54
|
import '../chunk-NSBPE2FW.js';
|
|
54
55
|
import * as fs10 from 'fs';
|
|
55
56
|
import fs10__default, { readFileSync, existsSync, writeFileSync, rmSync, statSync } from 'fs';
|
|
56
|
-
import * as
|
|
57
|
-
import
|
|
57
|
+
import * as path14 from 'path';
|
|
58
|
+
import path14__default, { resolve, join } from 'path';
|
|
58
59
|
import { fileURLToPath } from 'url';
|
|
59
60
|
import { Help, Command, Option } from 'commander';
|
|
60
61
|
import * as p5 from '@clack/prompts';
|
|
@@ -103,10 +104,10 @@ function makeAssetCommand() {
|
|
|
103
104
|
);
|
|
104
105
|
process.exit(1);
|
|
105
106
|
}
|
|
106
|
-
const basename2 =
|
|
107
|
-
const destDir = target.structure === "domain" && opts.domain ?
|
|
107
|
+
const basename2 = path14.basename(srcPath);
|
|
108
|
+
const destDir = target.structure === "domain" && opts.domain ? path14.join(target.path, opts.domain) : target.path;
|
|
108
109
|
fs10.mkdirSync(destDir, { recursive: true });
|
|
109
|
-
const destPath =
|
|
110
|
+
const destPath = path14.join(destDir, basename2);
|
|
110
111
|
if (fs10.existsSync(destPath)) {
|
|
111
112
|
logErr(`Destination already exists: ${destPath}`);
|
|
112
113
|
process.exit(1);
|
|
@@ -119,7 +120,7 @@ function makeAssetCommand() {
|
|
|
119
120
|
fs10.renameSync(srcPath, destPath);
|
|
120
121
|
break;
|
|
121
122
|
case "link":
|
|
122
|
-
fs10.symlinkSync(
|
|
123
|
+
fs10.symlinkSync(path14.resolve(srcPath), destPath);
|
|
123
124
|
break;
|
|
124
125
|
}
|
|
125
126
|
if (target.backend === "git" && opts.commit) {
|
|
@@ -167,17 +168,17 @@ function makeAssetCommand() {
|
|
|
167
168
|
}
|
|
168
169
|
const manifestPath = def.manifest.path;
|
|
169
170
|
const candidateSubpath = typeof manifestPath === "string" && manifestPath.length > 0 ? manifestPath : def.name;
|
|
170
|
-
const srcPath =
|
|
171
|
+
const srcPath = path14.join(lib.path, candidateSubpath);
|
|
171
172
|
if (!fs10.existsSync(srcPath)) {
|
|
172
173
|
logErr(`Asset path not found: ${srcPath}`);
|
|
173
174
|
process.exit(1);
|
|
174
175
|
}
|
|
175
|
-
const destPath =
|
|
176
|
-
fs10.mkdirSync(
|
|
176
|
+
const destPath = path14.join(target, candidateSubpath);
|
|
177
|
+
fs10.mkdirSync(path14.dirname(destPath), { recursive: true });
|
|
177
178
|
if (opts.mode === "copy") {
|
|
178
179
|
fs10.cpSync(srcPath, destPath, { recursive: true });
|
|
179
180
|
} else {
|
|
180
|
-
fs10.symlinkSync(
|
|
181
|
+
fs10.symlinkSync(path14.resolve(srcPath), destPath);
|
|
181
182
|
}
|
|
182
183
|
logOk(`Installed ${ref} \u2192 ${destPath} (${opts.mode})`);
|
|
183
184
|
} finally {
|
|
@@ -271,7 +272,7 @@ function makeSearchCommand() {
|
|
|
271
272
|
const showLocal = !opts.store;
|
|
272
273
|
const showStore = !opts.local;
|
|
273
274
|
if (showLocal) {
|
|
274
|
-
const am2 = new AssetManager({ projectDir:
|
|
275
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
275
276
|
const entries = am2.search(query, kind);
|
|
276
277
|
if (entries.length === 0) {
|
|
277
278
|
if (!showStore) {
|
|
@@ -308,7 +309,7 @@ function makeSearchCommand() {
|
|
|
308
309
|
}
|
|
309
310
|
if (showStore) {
|
|
310
311
|
try {
|
|
311
|
-
const { getStoreConfig: getStoreConfig2, storeFetch: storeFetch2 } = await import('../store-client-
|
|
312
|
+
const { getStoreConfig: getStoreConfig2, storeFetch: storeFetch2 } = await import('../store-client-5WBRUC5U.js');
|
|
312
313
|
const config = getStoreConfig2();
|
|
313
314
|
const params = {};
|
|
314
315
|
if (query) params.q = query;
|
|
@@ -335,16 +336,16 @@ function makeSearchCommand() {
|
|
|
335
336
|
});
|
|
336
337
|
}
|
|
337
338
|
function makeAddCommand() {
|
|
338
|
-
return new Command("add").description("Add to skaile.yaml + deploy").argument("<ref>", "Asset reference (kind:name[@repo])").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Deploy to global dir (~/.claude)").option("--target <agent>", "Driver target", "claude-code").action((ref, opts) => {
|
|
339
|
+
return new Command("add").description("Add to skaile.yaml + deploy").argument("<ref>", "Asset reference (kind:name[@repo])").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Deploy to global dir (~/.claude)").option("--target <agent>", "Driver target", "claude-code").action(async (ref, opts) => {
|
|
339
340
|
const am2 = new AssetManager({
|
|
340
|
-
projectDir:
|
|
341
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
341
342
|
global: opts.global,
|
|
342
343
|
driverTarget: opts.target
|
|
343
344
|
});
|
|
344
345
|
const spinner5 = p5.spinner();
|
|
345
346
|
spinner5.start(`Adding ${ref}`);
|
|
346
347
|
try {
|
|
347
|
-
const added = am2.add(ref);
|
|
348
|
+
const added = await am2.add(ref);
|
|
348
349
|
spinner5.stop("Done");
|
|
349
350
|
if (added.length === 0) logInfo("Nothing added (already up to date or not found).");
|
|
350
351
|
else for (const a of added) logOk(a);
|
|
@@ -358,7 +359,7 @@ function makeAddCommand() {
|
|
|
358
359
|
function makeRemoveCommand() {
|
|
359
360
|
return new Command("remove").description("Remove from skaile.yaml + undeploy").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Remove from global dir").option("--target <agent>", "Driver target", "claude-code").action((ref, opts) => {
|
|
360
361
|
const am2 = new AssetManager({
|
|
361
|
-
projectDir:
|
|
362
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
362
363
|
global: opts.global,
|
|
363
364
|
driverTarget: opts.target
|
|
364
365
|
});
|
|
@@ -372,7 +373,7 @@ function makeListCommand() {
|
|
|
372
373
|
new Option("--target <agent>", "Driver target").default("claude-code").choices(SUPPORTED_DRIVER_TARGETS)
|
|
373
374
|
).action((kind, opts) => {
|
|
374
375
|
const am2 = new AssetManager({
|
|
375
|
-
projectDir:
|
|
376
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
376
377
|
global: opts.global,
|
|
377
378
|
driverTarget: opts.target
|
|
378
379
|
});
|
|
@@ -396,7 +397,7 @@ function makeListCommand() {
|
|
|
396
397
|
}
|
|
397
398
|
function makeInfoCommand() {
|
|
398
399
|
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((ref, opts) => {
|
|
399
|
-
const am2 = new AssetManager({ projectDir:
|
|
400
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
400
401
|
const entry = am2.info(ref);
|
|
401
402
|
if (!entry) {
|
|
402
403
|
logErr(
|
|
@@ -410,7 +411,7 @@ function makeInfoCommand() {
|
|
|
410
411
|
console.log(` kind: ${kindColor(entry.kind)}`);
|
|
411
412
|
if (entry.version) console.log(` version: ${entry.version}`);
|
|
412
413
|
if (entry.description) console.log(` description: ${entry.description}`);
|
|
413
|
-
if (entry.
|
|
414
|
+
if (entry.publisher) console.log(` repository: ${S.dim(entry.publisher)}`);
|
|
414
415
|
console.log(` source: ${S.dim(entry.source)}`);
|
|
415
416
|
if (entry.requires.length) {
|
|
416
417
|
console.log(` requires:`);
|
|
@@ -429,7 +430,7 @@ function makeCreateCommand() {
|
|
|
429
430
|
new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...ASSET_KINDS])
|
|
430
431
|
).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
|
|
431
432
|
const am2 = new AssetManager({ projectDir: process.cwd() });
|
|
432
|
-
const destDir = opts.dir ?
|
|
433
|
+
const destDir = opts.dir ? path14__default.resolve(opts.dir) : process.cwd();
|
|
433
434
|
const result = am2.create(name, opts.kind, destDir);
|
|
434
435
|
if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
|
|
435
436
|
else {
|
|
@@ -440,7 +441,7 @@ function makeCreateCommand() {
|
|
|
440
441
|
}
|
|
441
442
|
function makeDoctorCommand() {
|
|
442
443
|
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((name, opts) => {
|
|
443
|
-
const am2 = new AssetManager({ projectDir:
|
|
444
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
444
445
|
const issues = am2.doctor();
|
|
445
446
|
if (issues.length === 0) {
|
|
446
447
|
logOk("No missing dependencies.");
|
|
@@ -466,11 +467,11 @@ function makeCatalogCommand() {
|
|
|
466
467
|
const catalog = new Command("catalog").description("Catalog source health and configuration");
|
|
467
468
|
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) => {
|
|
468
469
|
const { resolveConfig, isLocalCatalogUrl, trpcGetUrl } = await import('../library/index.js');
|
|
469
|
-
const projectDir = opts.projectDir ?
|
|
470
|
+
const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : void 0;
|
|
470
471
|
const cfg = resolveConfig({ projectDir });
|
|
471
472
|
const baseUrl = opts.url ?? cfg.catalog.url;
|
|
472
473
|
if (isLocalCatalogUrl(baseUrl)) {
|
|
473
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
474
|
+
const { resolveCatalogSource } = await import('../open-library-M4DB3D3J.js');
|
|
474
475
|
let resolved;
|
|
475
476
|
try {
|
|
476
477
|
resolved = await resolveCatalogSource({ projectDir: opts.projectDir });
|
|
@@ -559,7 +560,7 @@ function makeCatalogCommand() {
|
|
|
559
560
|
});
|
|
560
561
|
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) => {
|
|
561
562
|
const { resolveConfig } = await import('../library/index.js');
|
|
562
|
-
const projectDir = opts.projectDir ?
|
|
563
|
+
const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : void 0;
|
|
563
564
|
const cfg = resolveConfig({ projectDir });
|
|
564
565
|
console.log(`url: ${cfg.catalog.url}`);
|
|
565
566
|
console.log(`framing: ${cfg.catalog.framing}`);
|
|
@@ -616,7 +617,7 @@ function findSkills(domain) {
|
|
|
616
617
|
if (!fs10__default.existsSync(AI_RESOURCES)) return skills;
|
|
617
618
|
const domains = fs10__default.readdirSync(AI_RESOURCES, { withFileTypes: true }).filter((d) => d.isDirectory()).filter((d) => true);
|
|
618
619
|
for (const d of domains) {
|
|
619
|
-
const skillsDir =
|
|
620
|
+
const skillsDir = path14__default.join(AI_RESOURCES, d.name, "skills");
|
|
620
621
|
if (!fs10__default.existsSync(skillsDir)) continue;
|
|
621
622
|
walkSkills(skillsDir, d.name, skills);
|
|
622
623
|
}
|
|
@@ -624,9 +625,9 @@ function findSkills(domain) {
|
|
|
624
625
|
}
|
|
625
626
|
function walkSkills(dir, domain, out) {
|
|
626
627
|
for (const entry of fs10__default.readdirSync(dir, { withFileTypes: true })) {
|
|
627
|
-
const full =
|
|
628
|
+
const full = path14__default.join(dir, entry.name);
|
|
628
629
|
if (entry.isDirectory()) {
|
|
629
|
-
const skillMd =
|
|
630
|
+
const skillMd = path14__default.join(full, "SKILL.md");
|
|
630
631
|
if (fs10__default.existsSync(skillMd)) {
|
|
631
632
|
out.push({ name: entry.name, path: full, skillPath: skillMd, domain });
|
|
632
633
|
} else {
|
|
@@ -652,7 +653,7 @@ function resolveFlowIds() {
|
|
|
652
653
|
}
|
|
653
654
|
}
|
|
654
655
|
function resolveSessionIds(projectDir) {
|
|
655
|
-
const sessionsDir =
|
|
656
|
+
const sessionsDir = path14__default.join(projectDir, ".skaile", "sessions");
|
|
656
657
|
if (!fs10__default.existsSync(sessionsDir)) return [];
|
|
657
658
|
try {
|
|
658
659
|
return fs10__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
@@ -713,7 +714,7 @@ var API_KEY_PREFIX = "apiKey.";
|
|
|
713
714
|
function makeConfigCommand() {
|
|
714
715
|
const cmd = new Command("config").description("Manage personal config (.skaile/settings.json)");
|
|
715
716
|
cmd.command("show").description("Show effective config with sources").option("--project-dir <path>", "Project directory").action(async (opts) => {
|
|
716
|
-
const projectDir = opts.projectDir ?
|
|
717
|
+
const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : process.cwd();
|
|
717
718
|
const config = await resolveSettings(projectDir);
|
|
718
719
|
const wsDefaults = {};
|
|
719
720
|
try {
|
|
@@ -770,13 +771,13 @@ function makeConfigCommand() {
|
|
|
770
771
|
console.log();
|
|
771
772
|
});
|
|
772
773
|
cmd.command("get <key>").description("Get an effective config value").option("--project-dir <path>", "Project directory").action(async (key, opts) => {
|
|
773
|
-
const projectDir = opts.projectDir ?
|
|
774
|
+
const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : process.cwd();
|
|
774
775
|
const config = await resolveSettings(projectDir);
|
|
775
776
|
const value = config[key];
|
|
776
777
|
console.log(value ?? S.dim("(not set)"));
|
|
777
778
|
});
|
|
778
779
|
cmd.command("set <key> <value>").description("Set a personal config value (driver, model, provider, apiKey.<provider>)").option("--project-dir <path>", "Project directory").option("--global", "Write to ~/.skaile/settings.json instead of project-local").action(async (key, value, opts) => {
|
|
779
|
-
const projectDir = opts.projectDir ?
|
|
780
|
+
const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : process.cwd();
|
|
780
781
|
const isApiKey = key.startsWith(API_KEY_PREFIX);
|
|
781
782
|
if (!PERSONAL_KEYS.has(key) && !isApiKey) {
|
|
782
783
|
logErr(
|
|
@@ -1083,8 +1084,8 @@ function makeConnectorCommand() {
|
|
|
1083
1084
|
async (driver, opts) => {
|
|
1084
1085
|
const { installNpmPackages } = await import('../connectors/index.js');
|
|
1085
1086
|
const { scanDirectory, resolveBaseAssetsRoot, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
1086
|
-
const projectDir =
|
|
1087
|
-
const yamlPath =
|
|
1087
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1088
|
+
const yamlPath = path14__default.join(projectDir, "skaile.yaml");
|
|
1088
1089
|
if (!existsSync(yamlPath)) {
|
|
1089
1090
|
logErr("No skaile.yaml found in current directory. Run 'skaile init' first.");
|
|
1090
1091
|
process.exit(1);
|
|
@@ -1147,8 +1148,8 @@ ${installResult.output}`);
|
|
|
1147
1148
|
);
|
|
1148
1149
|
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) => {
|
|
1149
1150
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
1150
|
-
const projectDir =
|
|
1151
|
-
const yamlPath =
|
|
1151
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1152
|
+
const yamlPath = path14__default.join(projectDir, "skaile.yaml");
|
|
1152
1153
|
if (!existsSync(yamlPath)) {
|
|
1153
1154
|
logErr("No skaile.yaml found in current directory.");
|
|
1154
1155
|
process.exit(1);
|
|
@@ -1165,7 +1166,7 @@ ${installResult.output}`);
|
|
|
1165
1166
|
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) => {
|
|
1166
1167
|
const res = await import('../connectors/index.js');
|
|
1167
1168
|
res.registerBuiltinConnectors();
|
|
1168
|
-
const projectDir =
|
|
1169
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1169
1170
|
const declarations = res.loadConnectorDeclarations(projectDir);
|
|
1170
1171
|
if (declarations.length === 0) {
|
|
1171
1172
|
console.log("No connectors configured in skaile.yaml.");
|
|
@@ -1189,7 +1190,7 @@ ${installResult.output}`);
|
|
|
1189
1190
|
await manager.disconnectAll();
|
|
1190
1191
|
});
|
|
1191
1192
|
cmd.command("list").description("List all configured connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
1192
|
-
const projectDir =
|
|
1193
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1193
1194
|
const manager = await connectConnectors(projectDir);
|
|
1194
1195
|
try {
|
|
1195
1196
|
console.log(JSON.stringify(manager.listConnectors(), null, 2));
|
|
@@ -1198,7 +1199,7 @@ ${installResult.output}`);
|
|
|
1198
1199
|
}
|
|
1199
1200
|
});
|
|
1200
1201
|
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) => {
|
|
1201
|
-
const projectDir =
|
|
1202
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1202
1203
|
const manager = await connectConnectors(projectDir);
|
|
1203
1204
|
try {
|
|
1204
1205
|
if (opts.all) {
|
|
@@ -1222,7 +1223,7 @@ ${installResult.output}`);
|
|
|
1222
1223
|
}
|
|
1223
1224
|
});
|
|
1224
1225
|
cmd.command("ops <id>").description("List available operations for a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
|
|
1225
|
-
const projectDir =
|
|
1226
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1226
1227
|
const manager = await connectConnectors(projectDir);
|
|
1227
1228
|
try {
|
|
1228
1229
|
if (!manager.has(id)) {
|
|
@@ -1237,7 +1238,7 @@ ${installResult.output}`);
|
|
|
1237
1238
|
}
|
|
1238
1239
|
});
|
|
1239
1240
|
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) => {
|
|
1240
|
-
const projectDir =
|
|
1241
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1241
1242
|
const manager = await connectConnectors(projectDir);
|
|
1242
1243
|
try {
|
|
1243
1244
|
const content = await manager.read(id, resourcePath);
|
|
@@ -1247,7 +1248,7 @@ ${installResult.output}`);
|
|
|
1247
1248
|
}
|
|
1248
1249
|
});
|
|
1249
1250
|
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) => {
|
|
1250
|
-
const projectDir =
|
|
1251
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1251
1252
|
const manager = await connectConnectors(projectDir);
|
|
1252
1253
|
try {
|
|
1253
1254
|
await manager.write(id, resourcePath, { data: content });
|
|
@@ -1257,7 +1258,7 @@ ${installResult.output}`);
|
|
|
1257
1258
|
}
|
|
1258
1259
|
});
|
|
1259
1260
|
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", parseInt).action(async (id, resourcePath, opts) => {
|
|
1260
|
-
const projectDir =
|
|
1261
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1261
1262
|
const manager = await connectConnectors(projectDir);
|
|
1262
1263
|
try {
|
|
1263
1264
|
const entries = await manager.list(id, resourcePath, {
|
|
@@ -1270,7 +1271,7 @@ ${installResult.output}`);
|
|
|
1270
1271
|
}
|
|
1271
1272
|
});
|
|
1272
1273
|
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) => {
|
|
1273
|
-
const projectDir =
|
|
1274
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1274
1275
|
const manager = await connectConnectors(projectDir);
|
|
1275
1276
|
try {
|
|
1276
1277
|
const results = await manager.search(id, query);
|
|
@@ -1280,7 +1281,7 @@ ${installResult.output}`);
|
|
|
1280
1281
|
}
|
|
1281
1282
|
});
|
|
1282
1283
|
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) => {
|
|
1283
|
-
const projectDir =
|
|
1284
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1284
1285
|
const manager = await connectConnectors(projectDir);
|
|
1285
1286
|
try {
|
|
1286
1287
|
const ok = await manager.delete(id, resourcePath);
|
|
@@ -1290,7 +1291,7 @@ ${installResult.output}`);
|
|
|
1290
1291
|
}
|
|
1291
1292
|
});
|
|
1292
1293
|
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) => {
|
|
1293
|
-
const projectDir =
|
|
1294
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1294
1295
|
const manager = await connectConnectors(projectDir);
|
|
1295
1296
|
try {
|
|
1296
1297
|
if (!manager.has(id)) {
|
|
@@ -1379,9 +1380,180 @@ function makeDebugCommand() {
|
|
|
1379
1380
|
});
|
|
1380
1381
|
return cmd;
|
|
1381
1382
|
}
|
|
1383
|
+
function action(fn) {
|
|
1384
|
+
return async (...args) => {
|
|
1385
|
+
try {
|
|
1386
|
+
await fn(...args);
|
|
1387
|
+
} catch (err) {
|
|
1388
|
+
logErr(err instanceof Error ? err.message : String(err));
|
|
1389
|
+
process.exitCode = 1;
|
|
1390
|
+
}
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
function envRecord() {
|
|
1394
|
+
const out = {};
|
|
1395
|
+
for (const [k, v] of Object.entries(process.env)) {
|
|
1396
|
+
if (typeof v === "string") out[k] = v;
|
|
1397
|
+
}
|
|
1398
|
+
return out;
|
|
1399
|
+
}
|
|
1400
|
+
async function buildDeployContext(projectDir) {
|
|
1401
|
+
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
1402
|
+
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
1403
|
+
const workspaceId = config.name ?? path14__default.basename(projectDir);
|
|
1404
|
+
let log;
|
|
1405
|
+
try {
|
|
1406
|
+
const { createLogger } = await import('../core/logging.js');
|
|
1407
|
+
log = createLogger({ kind: "gateway", subkind: "deploy" });
|
|
1408
|
+
} catch {
|
|
1409
|
+
const shim = {
|
|
1410
|
+
debug: (m) => console.error(S.dim(` \xB7 ${m}`)),
|
|
1411
|
+
info: (m) => console.error(S.dim(` \xB7 ${m}`)),
|
|
1412
|
+
warn: (m) => logWarn(m),
|
|
1413
|
+
error: (m, e) => logErr(`${m}${e ? `: ${e instanceof Error ? e.message : String(e)}` : ""}`),
|
|
1414
|
+
child: () => shim
|
|
1415
|
+
};
|
|
1416
|
+
log = shim;
|
|
1417
|
+
}
|
|
1418
|
+
const controller = new AbortController();
|
|
1419
|
+
const ctx = {
|
|
1420
|
+
workspaceId,
|
|
1421
|
+
env: envRecord(),
|
|
1422
|
+
log,
|
|
1423
|
+
signal: controller.signal,
|
|
1424
|
+
...process.env.SKAILE_WS_AUTH_TOKEN ? { wsAuth: process.env.SKAILE_WS_AUTH_TOKEN } : {}
|
|
1425
|
+
};
|
|
1426
|
+
return { ctx, controller };
|
|
1427
|
+
}
|
|
1428
|
+
async function ensureTargetsRegistered(projectDir) {
|
|
1429
|
+
const { registerBuiltinDeployTargets } = await import('../deploy/index.js');
|
|
1430
|
+
const { pluginRegistry } = await import('../plugin-registry/index.js');
|
|
1431
|
+
registerBuiltinDeployTargets(pluginRegistry);
|
|
1432
|
+
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
1433
|
+
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
1434
|
+
if (config.plugins && config.plugins.length > 0) {
|
|
1435
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-AJ3FGXIC.js');
|
|
1436
|
+
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
1437
|
+
for (const f of result.failed) logWarn(f.error);
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
async function runUp(opts) {
|
|
1441
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1442
|
+
await ensureTargetsRegistered(projectDir);
|
|
1443
|
+
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
1444
|
+
const { resolveDeployTarget, pluginRegistry } = await import('../plugin-registry/index.js');
|
|
1445
|
+
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
1446
|
+
const overrideConfig = opts.target === config.deploy?.target ? config.deploy?.config : void 0;
|
|
1447
|
+
const resolution = await resolveDeployTarget(
|
|
1448
|
+
{ deploy: config.deploy },
|
|
1449
|
+
opts.target ? { target: opts.target, config: overrideConfig, reason: "cli --target" } : void 0,
|
|
1450
|
+
pluginRegistry
|
|
1451
|
+
);
|
|
1452
|
+
const { ctx, controller } = await buildDeployContext(projectDir);
|
|
1453
|
+
ctx.log.debug(`deploy target resolved`, {
|
|
1454
|
+
target: resolution.target.id,
|
|
1455
|
+
source: resolution.provenance.source,
|
|
1456
|
+
reason: resolution.provenance.reason
|
|
1457
|
+
});
|
|
1458
|
+
logInfo(`Deploying to ${S.cmd(resolution.target.id)} (${S.dim(resolution.provenance.source)})\u2026`);
|
|
1459
|
+
const handle = await resolution.target.create(resolution.config, ctx);
|
|
1460
|
+
await handle.waitReady();
|
|
1461
|
+
logOk(`Ready at ${S.cmd(handle.wsUrl)}`);
|
|
1462
|
+
console.log(` ${S.dim("source")} ${resolution.provenance.source}`);
|
|
1463
|
+
if (opts.detach) {
|
|
1464
|
+
const { writeHandle } = await import('../deploy/index.js');
|
|
1465
|
+
await writeHandle(projectDir, resolution.target.id, handle.payload);
|
|
1466
|
+
logInfo(`Detached \u2014 handle written to ${S.cmd(".skaile/deploy/handle.json")}`);
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1469
|
+
logInfo("Holding deploy in the foreground \u2014 press Ctrl-C to stop.");
|
|
1470
|
+
await holdUntilSignal(handle, controller);
|
|
1471
|
+
}
|
|
1472
|
+
function holdUntilSignal(handle, controller) {
|
|
1473
|
+
return new Promise((resolve4) => {
|
|
1474
|
+
const onSig = () => {
|
|
1475
|
+
process.removeListener("SIGINT", onSig);
|
|
1476
|
+
controller.abort();
|
|
1477
|
+
logInfo("Stopping\u2026");
|
|
1478
|
+
handle.stop().then(() => logOk("Stopped.")).catch((e) => logErr(`stop failed: ${e instanceof Error ? e.message : String(e)}`)).finally(() => resolve4());
|
|
1479
|
+
};
|
|
1480
|
+
process.on("SIGINT", onSig);
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1483
|
+
async function restoreFromHandle(projectDir) {
|
|
1484
|
+
const { readHandle } = await import('../deploy/index.js');
|
|
1485
|
+
const stored = await readHandle(projectDir);
|
|
1486
|
+
if (!stored) {
|
|
1487
|
+
logInfo("No active deploy \u2014 nothing to do (no .skaile/deploy/handle.json).");
|
|
1488
|
+
return null;
|
|
1489
|
+
}
|
|
1490
|
+
await ensureTargetsRegistered(projectDir);
|
|
1491
|
+
const { pluginRegistry } = await import('../plugin-registry/index.js');
|
|
1492
|
+
const target = pluginRegistry.get("deployTarget", stored.targetId);
|
|
1493
|
+
if (!target) {
|
|
1494
|
+
logErr(`unknown deploy target "${stored.targetId}" \u2014 is its plugin installed?`);
|
|
1495
|
+
return null;
|
|
1496
|
+
}
|
|
1497
|
+
const parsed = target.payloadSchema.safeParse(stored.payload);
|
|
1498
|
+
if (!parsed.success) {
|
|
1499
|
+
logErr(
|
|
1500
|
+
`deploy handle for "${stored.targetId}" is malformed: ${parsed.error.message}. Remove ${S.cmd(".skaile/deploy/handle.json")} to reset.`
|
|
1501
|
+
);
|
|
1502
|
+
return null;
|
|
1503
|
+
}
|
|
1504
|
+
const { ctx } = await buildDeployContext(projectDir);
|
|
1505
|
+
const handle = await target.restore(parsed.data, ctx);
|
|
1506
|
+
return { target, handle, ctx };
|
|
1507
|
+
}
|
|
1508
|
+
async function runDown(opts) {
|
|
1509
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1510
|
+
const restored = await restoreFromHandle(projectDir);
|
|
1511
|
+
if (!restored) return;
|
|
1512
|
+
await restored.handle.stop();
|
|
1513
|
+
const { clearHandle } = await import('../deploy/index.js');
|
|
1514
|
+
await clearHandle(projectDir);
|
|
1515
|
+
logOk(`Stopped ${S.cmd(restored.target.id)} and cleared the handle.`);
|
|
1516
|
+
}
|
|
1517
|
+
async function runStatus(opts) {
|
|
1518
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1519
|
+
const restored = await restoreFromHandle(projectDir);
|
|
1520
|
+
if (!restored) return;
|
|
1521
|
+
const health = await restored.handle.health();
|
|
1522
|
+
console.log();
|
|
1523
|
+
console.log(` ${S.label("target")} ${S.cmd(restored.target.id)}`);
|
|
1524
|
+
console.log(` ${S.label("state")} ${restored.handle.state}`);
|
|
1525
|
+
console.log(` ${S.label("wsUrl")} ${S.cmd(restored.handle.wsUrl)}`);
|
|
1526
|
+
console.log(
|
|
1527
|
+
` ${S.label("health")} ${health.healthy ? S.ok("healthy") : S.err("unhealthy")}${health.detail ? ` ${S.dim(`(${health.detail})`)}` : ""}`
|
|
1528
|
+
);
|
|
1529
|
+
console.log();
|
|
1530
|
+
}
|
|
1531
|
+
async function runLogs(opts) {
|
|
1532
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1533
|
+
const restored = await restoreFromHandle(projectDir);
|
|
1534
|
+
if (!restored) return;
|
|
1535
|
+
if (!restored.handle.logs) {
|
|
1536
|
+
logInfo(`logs not supported by target ${S.cmd(restored.target.id)}`);
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1539
|
+
for await (const entry of restored.handle.logs({ follow: opts.follow })) {
|
|
1540
|
+
console.log(entry.line);
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
function makeDeployCommand() {
|
|
1544
|
+
const cmd = new Command("deploy").description(
|
|
1545
|
+
"Deploy a workspace to a target (up / down / status / logs)"
|
|
1546
|
+
);
|
|
1547
|
+
cmd.command("up").description("Resolve a deploy target, stand the workspace up, and wait until ready").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <id>", "Override the deploy target (precedence: override > yaml > default)").option("--detach", "Persist the handle and return instead of holding in the foreground").action(action(runUp));
|
|
1548
|
+
cmd.command("down").description("Tear down the active deploy and clear its handle").option("--project-dir <path>", "Project directory", process.cwd()).action(action(runDown));
|
|
1549
|
+
cmd.command("status").description("Show the active deploy's state, ws URL, and health").option("--project-dir <path>", "Project directory", process.cwd()).action(action(runStatus));
|
|
1550
|
+
cmd.command("logs").description("Stream logs from the active deploy (if the target supports it)").option("--project-dir <path>", "Project directory", process.cwd()).option("--follow", "Keep streaming new log lines").action(action(runLogs));
|
|
1551
|
+
cmd.action(() => cmd.help());
|
|
1552
|
+
return cmd;
|
|
1553
|
+
}
|
|
1382
1554
|
function makeDiffCommand() {
|
|
1383
1555
|
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((ref, opts) => {
|
|
1384
|
-
const am2 = new AssetManager({ projectDir:
|
|
1556
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
1385
1557
|
const result = am2.diff(ref);
|
|
1386
1558
|
if (result === null) {
|
|
1387
1559
|
logInfo("No differences (or asset not found).");
|
|
@@ -1434,7 +1606,7 @@ function makeFlowCommand() {
|
|
|
1434
1606
|
function makeHistoryCommand() {
|
|
1435
1607
|
const cmd = new Command("history").description("Show recent add/remove/update actions");
|
|
1436
1608
|
cmd.argument("[limit]", "Number of entries to show", "20").option("--project-dir <path>", "Project directory", process.cwd()).action((limitStr, opts) => {
|
|
1437
|
-
const am2 = new AssetManager({ projectDir:
|
|
1609
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
1438
1610
|
const limit = parseInt(limitStr, 10) || 20;
|
|
1439
1611
|
const entries = am2.history(limit);
|
|
1440
1612
|
if (entries.length === 0) {
|
|
@@ -1454,7 +1626,7 @@ function makeHistoryCommand() {
|
|
|
1454
1626
|
console.log();
|
|
1455
1627
|
});
|
|
1456
1628
|
cmd.command("clear").description("Clear action history").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
1457
|
-
const am2 = new AssetManager({ projectDir:
|
|
1629
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
1458
1630
|
am2.clearHistory();
|
|
1459
1631
|
logOk("History cleared.");
|
|
1460
1632
|
});
|
|
@@ -1522,7 +1694,7 @@ function makeLibraryCommand() {
|
|
|
1522
1694
|
cmd.command("init <name>").description("Create a new local library at ~/.skaile/libraries/<name>").option("--git <url>", "Initialize as a git library tracking <url>").option("--owner", "Mark as owner (default for local)").option("--contributor", "Mark as contributor").option("--reader", "Mark as reader").action(
|
|
1523
1695
|
async (name, opts) => {
|
|
1524
1696
|
const libDir = resolveLibraryDir();
|
|
1525
|
-
const libPath =
|
|
1697
|
+
const libPath = path14.join(libDir, name);
|
|
1526
1698
|
const ownership = opts.contributor ? "contributor" : opts.reader ? "reader" : "owner";
|
|
1527
1699
|
const { manager, close } = await openLibraryManager();
|
|
1528
1700
|
try {
|
|
@@ -1595,7 +1767,7 @@ function makeLibraryCommand() {
|
|
|
1595
1767
|
target = def;
|
|
1596
1768
|
}
|
|
1597
1769
|
const am2 = new AssetManager({ projectDir: process.cwd() });
|
|
1598
|
-
const destDir = opts.dir ?
|
|
1770
|
+
const destDir = opts.dir ? path14.join(target.path, opts.dir) : target.path;
|
|
1599
1771
|
const res = am2.create(name, opts.kind ?? kind, destDir);
|
|
1600
1772
|
if (res.ok) {
|
|
1601
1773
|
logOk(`Created ${opts.kind ?? kind}: ${pc5.dim(res.path)}`);
|
|
@@ -1621,8 +1793,8 @@ function makeLibraryCommand() {
|
|
|
1621
1793
|
const { manager, close } = await openLibraryManager();
|
|
1622
1794
|
try {
|
|
1623
1795
|
const lib = await manager.requireLibrary(oldName);
|
|
1624
|
-
const parent =
|
|
1625
|
-
const newPath =
|
|
1796
|
+
const parent = path14.dirname(lib.path);
|
|
1797
|
+
const newPath = path14.join(parent, newName);
|
|
1626
1798
|
if (fs10.existsSync(newPath)) {
|
|
1627
1799
|
logErr(`Target directory already exists: ${newPath}`);
|
|
1628
1800
|
process.exit(1);
|
|
@@ -1813,9 +1985,9 @@ async function printOverallStatus(projectDir, asJson) {
|
|
|
1813
1985
|
} catch {
|
|
1814
1986
|
secretsStrategy = "unavailable";
|
|
1815
1987
|
}
|
|
1816
|
-
const resolvedProjectDir =
|
|
1817
|
-
const hasWorkspaceConfig = existsSync(
|
|
1818
|
-
const hasLockFile = existsSync(
|
|
1988
|
+
const resolvedProjectDir = path14.resolve(projectDir);
|
|
1989
|
+
const hasWorkspaceConfig = existsSync(path14.join(resolvedProjectDir, "skaile.yaml"));
|
|
1990
|
+
const hasLockFile = existsSync(path14.join(resolvedProjectDir, "skaile.lock.yaml"));
|
|
1819
1991
|
let subscriptions = [];
|
|
1820
1992
|
if (hasWorkspaceConfig) {
|
|
1821
1993
|
try {
|
|
@@ -2043,7 +2215,7 @@ function buildVisibleRows(rows, collapsedSources, collapsedDomains) {
|
|
|
2043
2215
|
if (collapsedSources.has(row.source)) return false;
|
|
2044
2216
|
return !hasCollapsedAncestor(row.source, row.domain, collapsedDomains, true);
|
|
2045
2217
|
}
|
|
2046
|
-
const source = row.entry?.
|
|
2218
|
+
const source = row.entry?.publisher || "other";
|
|
2047
2219
|
const domain = row.entry?.domain || "other";
|
|
2048
2220
|
if (collapsedSources.has(source)) return false;
|
|
2049
2221
|
return !hasCollapsedAncestor(source, domain, collapsedDomains, false);
|
|
@@ -2078,7 +2250,7 @@ function isAsset(r) {
|
|
|
2078
2250
|
return r.type === "asset";
|
|
2079
2251
|
}
|
|
2080
2252
|
function inSource(r, source) {
|
|
2081
|
-
return (r.entry?.
|
|
2253
|
+
return (r.entry?.publisher || "other") === source;
|
|
2082
2254
|
}
|
|
2083
2255
|
function inDomain(r, source, domain) {
|
|
2084
2256
|
if (!inSource(r, source)) return false;
|
|
@@ -2092,16 +2264,16 @@ function assetRefOf(r) {
|
|
|
2092
2264
|
function findAssetRow(ref) {
|
|
2093
2265
|
return state.assetRows.find((r) => isAsset(r) && assetRefOf(r) === ref);
|
|
2094
2266
|
}
|
|
2095
|
-
function setSelection(ref,
|
|
2267
|
+
function setSelection(ref, action3) {
|
|
2096
2268
|
const row = findAssetRow(ref);
|
|
2097
2269
|
if (!row) return;
|
|
2098
|
-
if (
|
|
2270
|
+
if (action3 === "clear") {
|
|
2099
2271
|
state.pendingAdds.delete(ref);
|
|
2100
2272
|
state.pendingRemoves.delete(ref);
|
|
2101
2273
|
return;
|
|
2102
2274
|
}
|
|
2103
2275
|
let resolved;
|
|
2104
|
-
if (
|
|
2276
|
+
if (action3 === "toggle") {
|
|
2105
2277
|
if (state.pendingAdds.has(ref) || state.pendingRemoves.has(ref)) {
|
|
2106
2278
|
state.pendingAdds.delete(ref);
|
|
2107
2279
|
state.pendingRemoves.delete(ref);
|
|
@@ -2109,7 +2281,7 @@ function setSelection(ref, action) {
|
|
|
2109
2281
|
}
|
|
2110
2282
|
resolved = row.installed ? "remove" : "add";
|
|
2111
2283
|
} else {
|
|
2112
|
-
resolved =
|
|
2284
|
+
resolved = action3;
|
|
2113
2285
|
}
|
|
2114
2286
|
if (resolved === "add") {
|
|
2115
2287
|
state.pendingRemoves.delete(ref);
|
|
@@ -2121,22 +2293,22 @@ function setSelection(ref, action) {
|
|
|
2121
2293
|
state.pendingRemoves.add(ref);
|
|
2122
2294
|
}
|
|
2123
2295
|
}
|
|
2124
|
-
function bulkSelection(refs,
|
|
2125
|
-
for (const ref of refs) setSelection(ref,
|
|
2296
|
+
function bulkSelection(refs, action3) {
|
|
2297
|
+
for (const ref of refs) setSelection(ref, action3);
|
|
2126
2298
|
}
|
|
2127
|
-
function actOnHeader(row,
|
|
2299
|
+
function actOnHeader(row, action3) {
|
|
2128
2300
|
if (row.type === "source-header") {
|
|
2129
|
-
bulkSelection(sourceAssetRefs(state.assetRows, row.source),
|
|
2301
|
+
bulkSelection(sourceAssetRefs(state.assetRows, row.source), action3);
|
|
2130
2302
|
return true;
|
|
2131
2303
|
}
|
|
2132
2304
|
if (row.type === "header") {
|
|
2133
|
-
bulkSelection(domainAssetRefs(state.assetRows, row.source, row.domain),
|
|
2305
|
+
bulkSelection(domainAssetRefs(state.assetRows, row.source, row.domain), action3);
|
|
2134
2306
|
return true;
|
|
2135
2307
|
}
|
|
2136
2308
|
return false;
|
|
2137
2309
|
}
|
|
2138
2310
|
async function loadAssets() {
|
|
2139
|
-
const { gatherAssetFeeds } = await import('../asset-feeds-
|
|
2311
|
+
const { gatherAssetFeeds } = await import('../asset-feeds-QXCSAJRN.js');
|
|
2140
2312
|
const { entries, notes } = await gatherAssetFeeds(am, am.projectDir);
|
|
2141
2313
|
if (notes.length > 0) {
|
|
2142
2314
|
state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
|
|
@@ -2144,7 +2316,7 @@ async function loadAssets() {
|
|
|
2144
2316
|
const installed = new Set(am.listDeployed().map((e) => `${e.kind}:${e.name}`));
|
|
2145
2317
|
const bySource = /* @__PURE__ */ new Map();
|
|
2146
2318
|
for (const e of entries) {
|
|
2147
|
-
const source = e.
|
|
2319
|
+
const source = e.publisher || "other";
|
|
2148
2320
|
const domain = e.domain || "other";
|
|
2149
2321
|
if (!bySource.has(source)) bySource.set(source, /* @__PURE__ */ new Map());
|
|
2150
2322
|
const domainMap = bySource.get(source);
|
|
@@ -2193,12 +2365,12 @@ async function loadAssets() {
|
|
|
2193
2365
|
async function loadSourcesAndLibraries() {
|
|
2194
2366
|
try {
|
|
2195
2367
|
const [{ openLibraryManager: openLibraryManager2 }, { skaileHomeDir: skaileHomeDir2 }] = await Promise.all([
|
|
2196
|
-
import('../open-library-
|
|
2368
|
+
import('../open-library-M4DB3D3J.js'),
|
|
2197
2369
|
import('../library/index.js')
|
|
2198
2370
|
]);
|
|
2199
2371
|
const { manager, library, close } = await openLibraryManager2();
|
|
2200
2372
|
try {
|
|
2201
|
-
const sourcesDir2 =
|
|
2373
|
+
const sourcesDir2 = path14__default.join(skaileHomeDir2(), "sources");
|
|
2202
2374
|
const isSourceRow = (l) => l.path.startsWith(sourcesDir2);
|
|
2203
2375
|
const libs = await manager.listLibraries();
|
|
2204
2376
|
const defs = await library.listAssetDefs();
|
|
@@ -2469,14 +2641,14 @@ async function syncAll() {
|
|
|
2469
2641
|
"Sync is not yet driven from the manage TUI. Run `skaile source sync` (sources) or `skaile library sync <name>` (git-backed libraries) from the shell."
|
|
2470
2642
|
);
|
|
2471
2643
|
}
|
|
2472
|
-
function sourceShellHint(
|
|
2644
|
+
function sourceShellHint(action3) {
|
|
2473
2645
|
state.message = pc5.yellow(
|
|
2474
|
-
`${
|
|
2646
|
+
`${action3} is a shell command. Run \`skaile source \u2026\` from the shell.`
|
|
2475
2647
|
);
|
|
2476
2648
|
}
|
|
2477
|
-
function libraryShellHint(
|
|
2649
|
+
function libraryShellHint(action3) {
|
|
2478
2650
|
state.message = pc5.yellow(
|
|
2479
|
-
`${
|
|
2651
|
+
`${action3} is a shell command. Run \`skaile library \u2026\` from the shell.`
|
|
2480
2652
|
);
|
|
2481
2653
|
}
|
|
2482
2654
|
async function showInfo() {
|
|
@@ -2490,7 +2662,7 @@ async function showInfo() {
|
|
|
2490
2662
|
console.log(` ${S.rule(50)}`);
|
|
2491
2663
|
if (e.version) console.log(` version: ${e.version}`);
|
|
2492
2664
|
if (e.description) console.log(` description: ${e.description}`);
|
|
2493
|
-
if (e.
|
|
2665
|
+
if (e.publisher) console.log(` source: ${pc5.dim(e.publisher)}`);
|
|
2494
2666
|
console.log(` manifest: ${pc5.dim(e.source)}`);
|
|
2495
2667
|
console.log(` installed: ${row.installed ? pc5.green("yes") : pc5.red("no")}`);
|
|
2496
2668
|
if (e.requires.length) {
|
|
@@ -2700,13 +2872,13 @@ async function run(projectDir) {
|
|
|
2700
2872
|
}
|
|
2701
2873
|
function makeManageCommand() {
|
|
2702
2874
|
return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
2703
|
-
await run(
|
|
2875
|
+
await run(path14__default.resolve(opts.projectDir));
|
|
2704
2876
|
});
|
|
2705
2877
|
}
|
|
2706
2878
|
function makeMcpServerCommand() {
|
|
2707
2879
|
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) => {
|
|
2708
|
-
const
|
|
2709
|
-
const projectDir =
|
|
2880
|
+
const path34 = await import('path');
|
|
2881
|
+
const projectDir = path34.default.resolve(opts.projectDir);
|
|
2710
2882
|
const { LogStore, StdoutSink, registerLogStore } = await import('../core/logging.js');
|
|
2711
2883
|
registerLogStore(
|
|
2712
2884
|
new LogStore({
|
|
@@ -2741,7 +2913,7 @@ function makeNpxCommand() {
|
|
|
2741
2913
|
const npx = new Command("npx").description("Compatibility shim for npx skills syntax");
|
|
2742
2914
|
const skills = npx.command("skills").description("Skill installation from external repos");
|
|
2743
2915
|
skills.command("add <url>").description("Register a repo as a Library Source and install a skill from it").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) => {
|
|
2744
|
-
const projectDir =
|
|
2916
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
2745
2917
|
const spinner5 = p5.spinner();
|
|
2746
2918
|
let sourcePath;
|
|
2747
2919
|
const isUrl = /^(https?:|git@|git:)/.test(url);
|
|
@@ -2752,14 +2924,14 @@ function makeNpxCommand() {
|
|
|
2752
2924
|
if (!existsSync(sourcePath)) {
|
|
2753
2925
|
execSync(`git clone ${url} ${sourcePath}`, { stdio: "ignore" });
|
|
2754
2926
|
}
|
|
2755
|
-
spinner5.stop(`Cloned to ${
|
|
2927
|
+
spinner5.stop(`Cloned to ${path14__default.basename(sourcePath)}`);
|
|
2756
2928
|
} catch (err) {
|
|
2757
2929
|
spinner5.stop("Clone failed");
|
|
2758
2930
|
logErr(err instanceof Error ? err.message : String(err));
|
|
2759
2931
|
process.exit(1);
|
|
2760
2932
|
}
|
|
2761
2933
|
} else {
|
|
2762
|
-
sourcePath =
|
|
2934
|
+
sourcePath = path14__default.resolve(url);
|
|
2763
2935
|
if (!existsSync(sourcePath)) {
|
|
2764
2936
|
logErr(`Path does not exist: ${sourcePath}`);
|
|
2765
2937
|
process.exit(1);
|
|
@@ -2772,7 +2944,7 @@ function makeNpxCommand() {
|
|
|
2772
2944
|
if (!source) {
|
|
2773
2945
|
source = await library.addSource({
|
|
2774
2946
|
backend: "local",
|
|
2775
|
-
name:
|
|
2947
|
+
name: path14__default.basename(sourcePath),
|
|
2776
2948
|
path: sourcePath,
|
|
2777
2949
|
ownership: "owner"
|
|
2778
2950
|
});
|
|
@@ -2791,7 +2963,7 @@ function makeNpxCommand() {
|
|
|
2791
2963
|
const am2 = new AssetManager({ projectDir, global: opts.global, driverTarget: opts.target });
|
|
2792
2964
|
spinner5.start(`Installing ${skillRef}`);
|
|
2793
2965
|
try {
|
|
2794
|
-
const added = am2.add(skillRef);
|
|
2966
|
+
const added = await am2.add(skillRef);
|
|
2795
2967
|
spinner5.stop("Done");
|
|
2796
2968
|
if (added.length === 0) {
|
|
2797
2969
|
logInfo(`${opts.skill} already deployed or not found in source.`);
|
|
@@ -2813,7 +2985,7 @@ function makeNpxCommand() {
|
|
|
2813
2985
|
}
|
|
2814
2986
|
function cloneDestination(url) {
|
|
2815
2987
|
const cleaned = url.replace(/\.git$/, "");
|
|
2816
|
-
const root =
|
|
2988
|
+
const root = path14__default.join(homedir(), ".skaile", "clones");
|
|
2817
2989
|
let host = "unknown";
|
|
2818
2990
|
let pathPart = cleaned;
|
|
2819
2991
|
const httpMatch = cleaned.match(/^https?:\/\/([^/]+)\/(.+)$/);
|
|
@@ -2829,83 +3001,7 @@ function cloneDestination(url) {
|
|
|
2829
3001
|
host = gitProtoMatch[1];
|
|
2830
3002
|
pathPart = gitProtoMatch[2];
|
|
2831
3003
|
}
|
|
2832
|
-
return
|
|
2833
|
-
}
|
|
2834
|
-
function makeOutdatedCommand() {
|
|
2835
|
-
return new Command("outdated").description("Check for assets behind their repo").argument("[name]", "Check a specific asset (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).addOption(
|
|
2836
|
-
new Option("--target <agent>", "Driver target").default("claude-code").choices(SUPPORTED_DRIVER_TARGETS)
|
|
2837
|
-
).action((name, opts) => {
|
|
2838
|
-
const am2 = new AssetManager({
|
|
2839
|
-
projectDir: path15__default.resolve(opts.projectDir),
|
|
2840
|
-
driverTarget: opts.target
|
|
2841
|
-
});
|
|
2842
|
-
const entries = am2.outdated();
|
|
2843
|
-
if (entries.length === 0) {
|
|
2844
|
-
logInfo("All assets are up to date.");
|
|
2845
|
-
return;
|
|
2846
|
-
}
|
|
2847
|
-
const filtered = name ? entries.filter((e) => `${e.kind}:${e.name}` === name || e.name === name) : entries;
|
|
2848
|
-
if (filtered.length === 0) {
|
|
2849
|
-
logInfo(`${name} is up to date.`);
|
|
2850
|
-
return;
|
|
2851
|
-
}
|
|
2852
|
-
const nameW = Math.max(4, ...filtered.map((e) => e.name.length));
|
|
2853
|
-
console.log();
|
|
2854
|
-
console.log(S.heading(" Outdated Assets"));
|
|
2855
|
-
console.log(` ${S.rule(nameW + 40)}`);
|
|
2856
|
-
for (const e of filtered) {
|
|
2857
|
-
console.log(
|
|
2858
|
-
` ${kindColorPad(e.kind)} ${e.name.padEnd(nameW)} ${S.dim(e.repository)} ${pc5.yellow(`${e.behind} commit(s) behind`)}`
|
|
2859
|
-
);
|
|
2860
|
-
}
|
|
2861
|
-
console.log();
|
|
2862
|
-
logWarn(`Run ${S.cmd("skaile update")} to re-deploy.`);
|
|
2863
|
-
});
|
|
2864
|
-
}
|
|
2865
|
-
function makePatchCommand() {
|
|
2866
|
-
const cmd = new Command("patch").description("Patch workflow for skill improvement");
|
|
2867
|
-
cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
2868
|
-
const am2 = new AssetManager({ projectDir: path15__default.resolve(opts.projectDir) });
|
|
2869
|
-
try {
|
|
2870
|
-
const dest = am2.patch(ref);
|
|
2871
|
-
logOk(`Extracted to ${S.dim(dest)}`);
|
|
2872
|
-
console.log(` Edit the files, then run ${S.cmd(`skaile patch commit ${ref}`)}`);
|
|
2873
|
-
} catch (err) {
|
|
2874
|
-
logErr(String(err));
|
|
2875
|
-
process.exit(1);
|
|
2876
|
-
}
|
|
2877
|
-
});
|
|
2878
|
-
cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
2879
|
-
const am2 = new AssetManager({ projectDir: path15__default.resolve(opts.projectDir) });
|
|
2880
|
-
try {
|
|
2881
|
-
const patchFile = am2.patchCommit(ref);
|
|
2882
|
-
logOk(`Patch saved to ${S.dim(patchFile)}`);
|
|
2883
|
-
console.log(` Add to skaile.yaml patches section, then run ${S.cmd("skaile install")}`);
|
|
2884
|
-
} catch (err) {
|
|
2885
|
-
logErr(String(err));
|
|
2886
|
-
process.exit(1);
|
|
2887
|
-
}
|
|
2888
|
-
});
|
|
2889
|
-
cmd.command("submit <ref>").description("Apply patch to repo clone and prepare for PR").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
2890
|
-
const am2 = new AssetManager({ projectDir: path15__default.resolve(opts.projectDir) });
|
|
2891
|
-
try {
|
|
2892
|
-
am2.patchSubmit(ref);
|
|
2893
|
-
logOk("Patch applied to repo clone and committed.");
|
|
2894
|
-
console.log(
|
|
2895
|
-
` Push upstream from the source repo directly \u2014 the legacy ${S.cmd("skaile repo contrib push")} command was removed on 2026-05-12.`
|
|
2896
|
-
);
|
|
2897
|
-
} catch (err) {
|
|
2898
|
-
logErr(String(err));
|
|
2899
|
-
process.exit(1);
|
|
2900
|
-
}
|
|
2901
|
-
});
|
|
2902
|
-
cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
2903
|
-
const am2 = new AssetManager({ projectDir: path15__default.resolve(opts.projectDir) });
|
|
2904
|
-
am2.patchRemove(ref);
|
|
2905
|
-
logOk(`Patch removed for ${ref}`);
|
|
2906
|
-
});
|
|
2907
|
-
cmd.action(() => cmd.help());
|
|
2908
|
-
return cmd;
|
|
3004
|
+
return path14__default.join(root, host, pathPart);
|
|
2909
3005
|
}
|
|
2910
3006
|
var SKAILE_MCP_NAME = "skaile-workspace";
|
|
2911
3007
|
var MCP_SERVER_ENTRY = {
|
|
@@ -2914,7 +3010,7 @@ var MCP_SERVER_ENTRY = {
|
|
|
2914
3010
|
env: {}
|
|
2915
3011
|
};
|
|
2916
3012
|
function pluginDir(projectDir) {
|
|
2917
|
-
return
|
|
3013
|
+
return path14__default.join(projectDir, ".claude", "plugins", "skaile");
|
|
2918
3014
|
}
|
|
2919
3015
|
async function readJsonStrict(p7) {
|
|
2920
3016
|
let raw;
|
|
@@ -2932,7 +3028,7 @@ async function readJsonStrict(p7) {
|
|
|
2932
3028
|
}
|
|
2933
3029
|
}
|
|
2934
3030
|
async function writeJson(p7, value) {
|
|
2935
|
-
await fs5.mkdir(
|
|
3031
|
+
await fs5.mkdir(path14__default.dirname(p7), { recursive: true });
|
|
2936
3032
|
await fs5.writeFile(p7, `${JSON.stringify(value, null, 2)}
|
|
2937
3033
|
`);
|
|
2938
3034
|
}
|
|
@@ -2940,8 +3036,8 @@ async function copyDir(src, dest) {
|
|
|
2940
3036
|
await fs5.mkdir(dest, { recursive: true });
|
|
2941
3037
|
const entries = await fs5.readdir(src, { withFileTypes: true });
|
|
2942
3038
|
for (const entry of entries) {
|
|
2943
|
-
const srcPath =
|
|
2944
|
-
const destPath =
|
|
3039
|
+
const srcPath = path14__default.join(src, entry.name);
|
|
3040
|
+
const destPath = path14__default.join(dest, entry.name);
|
|
2945
3041
|
if (entry.isDirectory()) await copyDir(srcPath, destPath);
|
|
2946
3042
|
else await fs5.copyFile(srcPath, destPath);
|
|
2947
3043
|
}
|
|
@@ -2950,14 +3046,14 @@ async function install(projectDir, opts) {
|
|
|
2950
3046
|
return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);
|
|
2951
3047
|
}
|
|
2952
3048
|
async function installMcp(projectDir) {
|
|
2953
|
-
const mcpPath =
|
|
3049
|
+
const mcpPath = path14__default.join(projectDir, ".claude", "mcp.json");
|
|
2954
3050
|
const existing = await readJsonStrict(mcpPath) ?? {};
|
|
2955
3051
|
const mcpServers = { ...existing.mcpServers ?? {} };
|
|
2956
3052
|
const previous = mcpServers[SKAILE_MCP_NAME];
|
|
2957
3053
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);
|
|
2958
3054
|
let warning;
|
|
2959
3055
|
if (previous && !matches) {
|
|
2960
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${
|
|
3056
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path14__default.relative(projectDir, mcpPath)}`;
|
|
2961
3057
|
}
|
|
2962
3058
|
mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;
|
|
2963
3059
|
await writeJson(mcpPath, { ...existing, mcpServers });
|
|
@@ -2966,15 +3062,15 @@ async function installMcp(projectDir) {
|
|
|
2966
3062
|
async function installFullPlugin(projectDir) {
|
|
2967
3063
|
const dir = pluginDir(projectDir);
|
|
2968
3064
|
for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {
|
|
2969
|
-
const dest =
|
|
2970
|
-
await fs5.mkdir(
|
|
3065
|
+
const dest = path14__default.join(dir, rel);
|
|
3066
|
+
await fs5.mkdir(path14__default.dirname(dest), { recursive: true });
|
|
2971
3067
|
await fs5.writeFile(dest, content);
|
|
2972
3068
|
}
|
|
2973
|
-
const projectSkillsDir =
|
|
3069
|
+
const projectSkillsDir = path14__default.join(projectDir, ".skaile", "skills");
|
|
2974
3070
|
if (existsSync(projectSkillsDir)) {
|
|
2975
|
-
await copyDir(projectSkillsDir,
|
|
3071
|
+
await copyDir(projectSkillsDir, path14__default.join(dir, "skills"));
|
|
2976
3072
|
}
|
|
2977
|
-
const settingsPath =
|
|
3073
|
+
const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
|
|
2978
3074
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2979
3075
|
const plugins = settings.plugins ?? [];
|
|
2980
3076
|
if (!plugins.includes(dir)) plugins.push(dir);
|
|
@@ -2982,8 +3078,8 @@ async function installFullPlugin(projectDir) {
|
|
|
2982
3078
|
return { changed: true, method: "plugin" };
|
|
2983
3079
|
}
|
|
2984
3080
|
async function uninstall(projectDir) {
|
|
2985
|
-
const settingsPath =
|
|
2986
|
-
const mcpPath =
|
|
3081
|
+
const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
|
|
3082
|
+
const mcpPath = path14__default.join(projectDir, ".claude", "mcp.json");
|
|
2987
3083
|
const dir = pluginDir(projectDir);
|
|
2988
3084
|
let changed = false;
|
|
2989
3085
|
const settings = await readJsonStrict(settingsPath);
|
|
@@ -3017,12 +3113,12 @@ async function uninstall(projectDir) {
|
|
|
3017
3113
|
async function detectInstall(projectDir) {
|
|
3018
3114
|
const dir = pluginDir(projectDir);
|
|
3019
3115
|
const settings = await readJsonStrict(
|
|
3020
|
-
|
|
3116
|
+
path14__default.join(projectDir, ".claude", "settings.json")
|
|
3021
3117
|
);
|
|
3022
|
-
if (existsSync(
|
|
3118
|
+
if (existsSync(path14__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
|
|
3023
3119
|
return { method: "plugin", pluginPath: dir };
|
|
3024
3120
|
}
|
|
3025
|
-
const mcp = await readJsonStrict(
|
|
3121
|
+
const mcp = await readJsonStrict(path14__default.join(projectDir, ".claude", "mcp.json"));
|
|
3026
3122
|
if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {
|
|
3027
3123
|
return { method: "mcp" };
|
|
3028
3124
|
}
|
|
@@ -3031,7 +3127,7 @@ async function detectInstall(projectDir) {
|
|
|
3031
3127
|
async function enable(projectDir) {
|
|
3032
3128
|
const detected = await detectInstall(projectDir);
|
|
3033
3129
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
3034
|
-
const settingsPath =
|
|
3130
|
+
const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
|
|
3035
3131
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
3036
3132
|
if (detected.method === "plugin") {
|
|
3037
3133
|
const disabled2 = settings.disabledPlugins ?? [];
|
|
@@ -3053,7 +3149,7 @@ async function enable(projectDir) {
|
|
|
3053
3149
|
async function disable(projectDir) {
|
|
3054
3150
|
const detected = await detectInstall(projectDir);
|
|
3055
3151
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
3056
|
-
const settingsPath =
|
|
3152
|
+
const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
|
|
3057
3153
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
3058
3154
|
if (detected.method === "plugin") {
|
|
3059
3155
|
const list2 = settings.disabledPlugins ?? [];
|
|
@@ -3073,12 +3169,12 @@ async function disable(projectDir) {
|
|
|
3073
3169
|
return { changed: true };
|
|
3074
3170
|
}
|
|
3075
3171
|
async function status(projectDir) {
|
|
3076
|
-
const settingsPath =
|
|
3077
|
-
const mcpPath =
|
|
3172
|
+
const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
|
|
3173
|
+
const mcpPath = path14__default.join(projectDir, ".claude", "mcp.json");
|
|
3078
3174
|
const dir = pluginDir(projectDir);
|
|
3079
3175
|
const settings = await readJsonStrict(settingsPath);
|
|
3080
3176
|
const mcp = await readJsonStrict(mcpPath);
|
|
3081
|
-
const pluginInstalled = !!(existsSync(
|
|
3177
|
+
const pluginInstalled = !!(existsSync(path14__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
|
|
3082
3178
|
const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);
|
|
3083
3179
|
if (!pluginInstalled && !mcpInstalled) {
|
|
3084
3180
|
return {
|
|
@@ -3096,7 +3192,7 @@ async function status(projectDir) {
|
|
|
3096
3192
|
installed: "yes",
|
|
3097
3193
|
enabled: disabled2 ? "no" : "yes",
|
|
3098
3194
|
method: "plugin",
|
|
3099
|
-
location:
|
|
3195
|
+
location: path14__default.relative(projectDir, dir)
|
|
3100
3196
|
};
|
|
3101
3197
|
}
|
|
3102
3198
|
const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;
|
|
@@ -3105,7 +3201,7 @@ async function status(projectDir) {
|
|
|
3105
3201
|
installed: "yes",
|
|
3106
3202
|
enabled: disabled ? "no" : "yes",
|
|
3107
3203
|
method: "mcp",
|
|
3108
|
-
location:
|
|
3204
|
+
location: path14__default.relative(projectDir, mcpPath)
|
|
3109
3205
|
};
|
|
3110
3206
|
}
|
|
3111
3207
|
var SKAILE_MCP_NAME2 = "skaile-workspace";
|
|
@@ -3132,7 +3228,7 @@ async function readConfig(p7) {
|
|
|
3132
3228
|
}
|
|
3133
3229
|
}
|
|
3134
3230
|
async function writeConfig(p7, value) {
|
|
3135
|
-
await fs5.mkdir(
|
|
3231
|
+
await fs5.mkdir(path14__default.dirname(p7), { recursive: true });
|
|
3136
3232
|
const cleaned = {};
|
|
3137
3233
|
for (const [k, v] of Object.entries(value)) {
|
|
3138
3234
|
if (v === void 0) continue;
|
|
@@ -3141,7 +3237,7 @@ async function writeConfig(p7, value) {
|
|
|
3141
3237
|
await fs5.writeFile(p7, stringify(cleaned));
|
|
3142
3238
|
}
|
|
3143
3239
|
function configPath(projectDir) {
|
|
3144
|
-
return
|
|
3240
|
+
return path14__default.join(projectDir, ".codex", "config.toml");
|
|
3145
3241
|
}
|
|
3146
3242
|
async function install2(projectDir) {
|
|
3147
3243
|
const p7 = configPath(projectDir);
|
|
@@ -3152,7 +3248,7 @@ async function install2(projectDir) {
|
|
|
3152
3248
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
|
|
3153
3249
|
let warning;
|
|
3154
3250
|
if (previous && !matches) {
|
|
3155
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${
|
|
3251
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path14__default.relative(projectDir, p7)}`;
|
|
3156
3252
|
}
|
|
3157
3253
|
if (matches) return { changed: false, method: "toml" };
|
|
3158
3254
|
servers[SKAILE_MCP_NAME2] = next;
|
|
@@ -3193,12 +3289,12 @@ async function status2(projectDir) {
|
|
|
3193
3289
|
installed: "yes",
|
|
3194
3290
|
enabled: "n/a",
|
|
3195
3291
|
method: "mcp",
|
|
3196
|
-
location:
|
|
3292
|
+
location: path14__default.relative(projectDir, p7)
|
|
3197
3293
|
};
|
|
3198
3294
|
}
|
|
3199
3295
|
async function install3(projectDir) {
|
|
3200
|
-
const extDir =
|
|
3201
|
-
const extPath =
|
|
3296
|
+
const extDir = path14__default.join(projectDir, ".omp", "extensions");
|
|
3297
|
+
const extPath = path14__default.join(extDir, "skaile.ts");
|
|
3202
3298
|
await fs5.mkdir(extDir, { recursive: true });
|
|
3203
3299
|
const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
|
|
3204
3300
|
const plugin = new WorkspacePlugin({ projectDir });
|
|
@@ -3213,7 +3309,7 @@ async function install3(projectDir) {
|
|
|
3213
3309
|
return { changed: true, method: "generated" };
|
|
3214
3310
|
}
|
|
3215
3311
|
async function uninstall3(projectDir) {
|
|
3216
|
-
const extPath =
|
|
3312
|
+
const extPath = path14__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3217
3313
|
try {
|
|
3218
3314
|
await fs5.unlink(extPath);
|
|
3219
3315
|
return { changed: true };
|
|
@@ -3222,14 +3318,14 @@ async function uninstall3(projectDir) {
|
|
|
3222
3318
|
}
|
|
3223
3319
|
}
|
|
3224
3320
|
async function status3(projectDir) {
|
|
3225
|
-
const extPath =
|
|
3321
|
+
const extPath = path14__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3226
3322
|
if (existsSync(extPath)) {
|
|
3227
3323
|
return {
|
|
3228
3324
|
backend: "omp",
|
|
3229
3325
|
installed: "yes",
|
|
3230
3326
|
enabled: "n/a",
|
|
3231
3327
|
method: "extension",
|
|
3232
|
-
location:
|
|
3328
|
+
location: path14__default.relative(projectDir, extPath)
|
|
3233
3329
|
};
|
|
3234
3330
|
}
|
|
3235
3331
|
return {
|
|
@@ -3241,7 +3337,7 @@ async function status3(projectDir) {
|
|
|
3241
3337
|
};
|
|
3242
3338
|
}
|
|
3243
3339
|
|
|
3244
|
-
// cli/src/commands/
|
|
3340
|
+
// cli/src/commands/integration.ts
|
|
3245
3341
|
var ALL_BACKENDS = ["claude-code", "omp", "codex"];
|
|
3246
3342
|
var TOGGLE_SUPPORTED = ["claude-code"];
|
|
3247
3343
|
function resolveDriver(driver) {
|
|
@@ -3250,7 +3346,7 @@ function resolveDriver(driver) {
|
|
|
3250
3346
|
throw new Error(`unknown driver: ${driver} (expected: claude-code | omp | codex | all)`);
|
|
3251
3347
|
}
|
|
3252
3348
|
async function runInstall(opts) {
|
|
3253
|
-
const projectDir =
|
|
3349
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3254
3350
|
const targets = resolveDriver(opts.driver);
|
|
3255
3351
|
let exitCode = 0;
|
|
3256
3352
|
if (targets.includes("claude-code")) {
|
|
@@ -3305,7 +3401,7 @@ async function runInstall(opts) {
|
|
|
3305
3401
|
return exitCode;
|
|
3306
3402
|
}
|
|
3307
3403
|
async function runUninstall(opts) {
|
|
3308
|
-
const projectDir =
|
|
3404
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3309
3405
|
const targets = resolveDriver(opts.driver);
|
|
3310
3406
|
let exitCode = 0;
|
|
3311
3407
|
if (targets.includes("claude-code")) {
|
|
@@ -3341,15 +3437,15 @@ async function runUninstall(opts) {
|
|
|
3341
3437
|
if (exitCode === 0) logOk("Plugin uninstalled.");
|
|
3342
3438
|
return exitCode;
|
|
3343
3439
|
}
|
|
3344
|
-
async function runToggle(opts,
|
|
3345
|
-
const projectDir =
|
|
3440
|
+
async function runToggle(opts, action3) {
|
|
3441
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3346
3442
|
const requestedAll = opts.driver === "all";
|
|
3347
3443
|
const targets = resolveDriver(opts.driver);
|
|
3348
3444
|
if (!requestedAll) {
|
|
3349
3445
|
const unsupported = targets.filter((t) => !TOGGLE_SUPPORTED.includes(t));
|
|
3350
3446
|
if (unsupported.length > 0) {
|
|
3351
3447
|
logErr(
|
|
3352
|
-
`${
|
|
3448
|
+
`${action3} is only supported for claude-code; for ${unsupported.join(", ")} use uninstall/install`
|
|
3353
3449
|
);
|
|
3354
3450
|
return 2;
|
|
3355
3451
|
}
|
|
@@ -3357,27 +3453,27 @@ async function runToggle(opts, action) {
|
|
|
3357
3453
|
let exitCode = 0;
|
|
3358
3454
|
for (const t of targets) {
|
|
3359
3455
|
if (!TOGGLE_SUPPORTED.includes(t)) {
|
|
3360
|
-
logInfo(`${t}: ${
|
|
3456
|
+
logInfo(`${t}: ${action3} not supported; skipping`);
|
|
3361
3457
|
continue;
|
|
3362
3458
|
}
|
|
3363
3459
|
if (t === "claude-code") {
|
|
3364
3460
|
try {
|
|
3365
|
-
const r =
|
|
3461
|
+
const r = action3 === "enable" ? await enable(projectDir) : await disable(projectDir);
|
|
3366
3462
|
if (r.changed) {
|
|
3367
|
-
logOk(`claude-code: ${
|
|
3463
|
+
logOk(`claude-code: ${action3}d`);
|
|
3368
3464
|
} else {
|
|
3369
|
-
logInfo(`claude-code: already ${
|
|
3465
|
+
logInfo(`claude-code: already ${action3}d`);
|
|
3370
3466
|
}
|
|
3371
3467
|
} catch (e) {
|
|
3372
|
-
logErr(`claude-code ${
|
|
3468
|
+
logErr(`claude-code ${action3}: ${e instanceof Error ? e.message : String(e)}`);
|
|
3373
3469
|
exitCode = 1;
|
|
3374
3470
|
}
|
|
3375
3471
|
}
|
|
3376
3472
|
}
|
|
3377
3473
|
return exitCode;
|
|
3378
3474
|
}
|
|
3379
|
-
async function
|
|
3380
|
-
const projectDir =
|
|
3475
|
+
async function runStatus2(opts) {
|
|
3476
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3381
3477
|
const targets = resolveDriver(opts.driver);
|
|
3382
3478
|
const rows = [];
|
|
3383
3479
|
let exitCode = 0;
|
|
@@ -3448,7 +3544,7 @@ async function runHook(event) {
|
|
|
3448
3544
|
await plugin.shutdown();
|
|
3449
3545
|
return;
|
|
3450
3546
|
}
|
|
3451
|
-
const store = new PluginStore(
|
|
3547
|
+
const store = new PluginStore(path14__default.join(projectDir, ".skaile", "plugin-state.json"));
|
|
3452
3548
|
await store.load();
|
|
3453
3549
|
const status4 = store.get("connector:status");
|
|
3454
3550
|
if (status4 && typeof status4 === "object" && Object.keys(status4).length > 0) {
|
|
@@ -3463,9 +3559,9 @@ async function runHook(event) {
|
|
|
3463
3559
|
);
|
|
3464
3560
|
}
|
|
3465
3561
|
}
|
|
3466
|
-
function
|
|
3467
|
-
const cmd = new Command("
|
|
3468
|
-
"Manage skaile workspace
|
|
3562
|
+
function makeIntegrationCommand() {
|
|
3563
|
+
const cmd = new Command("integration").description(
|
|
3564
|
+
"Manage skaile agent integration / workspace-plugin adapter (Claude Code / OMP / Codex)"
|
|
3469
3565
|
);
|
|
3470
3566
|
cmd.command("install").description("Install skaile workspace plugin").option("--driver <name>", "Target: claude-code | omp | codex | all", "all").option("--project-dir <path>", "Project directory", process.cwd()).option(
|
|
3471
3567
|
"--full",
|
|
@@ -3483,7 +3579,7 @@ function makePluginCommand() {
|
|
|
3483
3579
|
process.exitCode = await runToggle(opts, "disable");
|
|
3484
3580
|
});
|
|
3485
3581
|
cmd.command("status").description("Show install / enable status across backends").option("--driver <name>", "Target: claude-code | omp | codex | all", "all").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
3486
|
-
process.exitCode = await
|
|
3582
|
+
process.exitCode = await runStatus2(opts);
|
|
3487
3583
|
});
|
|
3488
3584
|
cmd.command("hook <event>").description(
|
|
3489
3585
|
"Run a Claude Code lifecycle hook (session-start | session-end | user-prompt-submit)"
|
|
@@ -3508,12 +3604,189 @@ function makePluginCommand() {
|
|
|
3508
3604
|
cmd.action(() => cmd.help());
|
|
3509
3605
|
return cmd;
|
|
3510
3606
|
}
|
|
3607
|
+
function makeOutdatedCommand() {
|
|
3608
|
+
return new Command("outdated").description("Check for assets behind their repo").argument("[name]", "Check a specific asset (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).addOption(
|
|
3609
|
+
new Option("--target <agent>", "Driver target").default("claude-code").choices(SUPPORTED_DRIVER_TARGETS)
|
|
3610
|
+
).action((name, opts) => {
|
|
3611
|
+
const am2 = new AssetManager({
|
|
3612
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
3613
|
+
driverTarget: opts.target
|
|
3614
|
+
});
|
|
3615
|
+
const entries = am2.outdated();
|
|
3616
|
+
if (entries.length === 0) {
|
|
3617
|
+
logInfo("All assets are up to date.");
|
|
3618
|
+
return;
|
|
3619
|
+
}
|
|
3620
|
+
const filtered = name ? entries.filter((e) => `${e.kind}:${e.name}` === name || e.name === name) : entries;
|
|
3621
|
+
if (filtered.length === 0) {
|
|
3622
|
+
logInfo(`${name} is up to date.`);
|
|
3623
|
+
return;
|
|
3624
|
+
}
|
|
3625
|
+
const nameW = Math.max(4, ...filtered.map((e) => e.name.length));
|
|
3626
|
+
console.log();
|
|
3627
|
+
console.log(S.heading(" Outdated Assets"));
|
|
3628
|
+
console.log(` ${S.rule(nameW + 40)}`);
|
|
3629
|
+
for (const e of filtered) {
|
|
3630
|
+
console.log(
|
|
3631
|
+
` ${kindColorPad(e.kind)} ${e.name.padEnd(nameW)} ${S.dim(e.publisher)} ${pc5.yellow(`${e.behind} commit(s) behind`)}`
|
|
3632
|
+
);
|
|
3633
|
+
}
|
|
3634
|
+
console.log();
|
|
3635
|
+
logWarn(`Run ${S.cmd("skaile update")} to re-deploy.`);
|
|
3636
|
+
});
|
|
3637
|
+
}
|
|
3638
|
+
function makePatchCommand() {
|
|
3639
|
+
const cmd = new Command("patch").description("Patch workflow for skill improvement");
|
|
3640
|
+
cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
3641
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3642
|
+
try {
|
|
3643
|
+
const dest = am2.patch(ref);
|
|
3644
|
+
logOk(`Extracted to ${S.dim(dest)}`);
|
|
3645
|
+
console.log(` Edit the files, then run ${S.cmd(`skaile patch commit ${ref}`)}`);
|
|
3646
|
+
} catch (err) {
|
|
3647
|
+
logErr(String(err));
|
|
3648
|
+
process.exit(1);
|
|
3649
|
+
}
|
|
3650
|
+
});
|
|
3651
|
+
cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
3652
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3653
|
+
try {
|
|
3654
|
+
const patchFile = am2.patchCommit(ref);
|
|
3655
|
+
logOk(`Patch saved to ${S.dim(patchFile)}`);
|
|
3656
|
+
console.log(` Add to skaile.yaml patches section, then run ${S.cmd("skaile install")}`);
|
|
3657
|
+
} catch (err) {
|
|
3658
|
+
logErr(String(err));
|
|
3659
|
+
process.exit(1);
|
|
3660
|
+
}
|
|
3661
|
+
});
|
|
3662
|
+
cmd.command("submit <ref>").description("Apply patch to repo clone and prepare for PR").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
3663
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3664
|
+
try {
|
|
3665
|
+
am2.patchSubmit(ref);
|
|
3666
|
+
logOk("Patch applied to repo clone and committed.");
|
|
3667
|
+
console.log(
|
|
3668
|
+
` Push upstream from the source repo directly \u2014 the legacy ${S.cmd("skaile repo contrib push")} command was removed on 2026-05-12.`
|
|
3669
|
+
);
|
|
3670
|
+
} catch (err) {
|
|
3671
|
+
logErr(String(err));
|
|
3672
|
+
process.exit(1);
|
|
3673
|
+
}
|
|
3674
|
+
});
|
|
3675
|
+
cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
3676
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3677
|
+
am2.patchRemove(ref);
|
|
3678
|
+
logOk(`Patch removed for ${ref}`);
|
|
3679
|
+
});
|
|
3680
|
+
cmd.action(() => cmd.help());
|
|
3681
|
+
return cmd;
|
|
3682
|
+
}
|
|
3683
|
+
function action2(fn) {
|
|
3684
|
+
return async (...args) => {
|
|
3685
|
+
try {
|
|
3686
|
+
await fn(...args);
|
|
3687
|
+
} catch (err) {
|
|
3688
|
+
logErr(err instanceof Error ? err.message : String(err));
|
|
3689
|
+
process.exitCode = 1;
|
|
3690
|
+
}
|
|
3691
|
+
};
|
|
3692
|
+
}
|
|
3693
|
+
async function reconcileAndReport(projectDir, plugins) {
|
|
3694
|
+
const { reconcilePlugins } = await import('../plugin-store-AJ3FGXIC.js');
|
|
3695
|
+
if (plugins.length === 0) {
|
|
3696
|
+
logInfo("No plugins declared \u2014 nothing to reconcile.");
|
|
3697
|
+
return;
|
|
3698
|
+
}
|
|
3699
|
+
try {
|
|
3700
|
+
const result = await reconcilePlugins(projectDir, plugins);
|
|
3701
|
+
if (result.changed) logOk(`Reconciled plugin store (${result.reason}).`);
|
|
3702
|
+
else logInfo(`Plugin store ${result.reason}.`);
|
|
3703
|
+
} catch (err) {
|
|
3704
|
+
logWarn(`reconcile skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
async function runInstall2(spec, opts) {
|
|
3708
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3709
|
+
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
3710
|
+
const { specName } = await import('../plugin-store-AJ3FGXIC.js');
|
|
3711
|
+
const yamlPath = path14__default.join(projectDir, "skaile.yaml");
|
|
3712
|
+
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
3713
|
+
const replaced = editor.addPlugin(spec, specName);
|
|
3714
|
+
editor.save();
|
|
3715
|
+
if (replaced) logOk(`Updated ${S.cmd(specName(spec))} \u2192 ${S.cmd(spec)} in skaile.yaml`);
|
|
3716
|
+
else logOk(`Added ${S.cmd(spec)} to skaile.yaml plugins`);
|
|
3717
|
+
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
3718
|
+
}
|
|
3719
|
+
async function runRemove(name, opts) {
|
|
3720
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3721
|
+
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
3722
|
+
const { specName } = await import('../plugin-store-AJ3FGXIC.js');
|
|
3723
|
+
const yamlPath = path14__default.join(projectDir, "skaile.yaml");
|
|
3724
|
+
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
3725
|
+
const removed = editor.removePlugin(name, specName);
|
|
3726
|
+
if (!removed) {
|
|
3727
|
+
logInfo(`No plugin matching ${S.cmd(name)} in skaile.yaml plugins.`);
|
|
3728
|
+
return;
|
|
3729
|
+
}
|
|
3730
|
+
editor.save();
|
|
3731
|
+
logOk(`Removed ${S.cmd(name)} from skaile.yaml plugins`);
|
|
3732
|
+
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
3733
|
+
}
|
|
3734
|
+
async function runList(opts) {
|
|
3735
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3736
|
+
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
3737
|
+
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
3738
|
+
const declared = config.plugins ?? [];
|
|
3739
|
+
console.log();
|
|
3740
|
+
console.log(S.heading(" Declared plugins (skaile.yaml):"));
|
|
3741
|
+
if (declared.length === 0) {
|
|
3742
|
+
console.log(` ${S.dim("(none)")}`);
|
|
3743
|
+
} else {
|
|
3744
|
+
for (const spec of declared) console.log(` ${S.dim("\xB7")} ${S.cmd(spec)}`);
|
|
3745
|
+
}
|
|
3746
|
+
const { createPluginRegistry } = await import('../plugin-registry/index.js');
|
|
3747
|
+
const registry = createPluginRegistry();
|
|
3748
|
+
if (declared.length > 0) {
|
|
3749
|
+
try {
|
|
3750
|
+
const { loadPlugins } = await import('../plugin-store-AJ3FGXIC.js');
|
|
3751
|
+
const result = await loadPlugins(projectDir, declared, registry);
|
|
3752
|
+
for (const f of result.failed) logWarn(f.error);
|
|
3753
|
+
} catch (err) {
|
|
3754
|
+
logWarn(`could not load plugins: ${err instanceof Error ? err.message : String(err)}`);
|
|
3755
|
+
}
|
|
3756
|
+
}
|
|
3757
|
+
const kinds = [
|
|
3758
|
+
{ kind: "driver", label: "drivers" },
|
|
3759
|
+
{ kind: "connector", label: "connectors" },
|
|
3760
|
+
{ kind: "deployTarget", label: "deploy targets" }
|
|
3761
|
+
];
|
|
3762
|
+
console.log();
|
|
3763
|
+
console.log(S.heading(" Contributed targets:"));
|
|
3764
|
+
let any = false;
|
|
3765
|
+
for (const { kind, label } of kinds) {
|
|
3766
|
+
const metas = registry.list(kind);
|
|
3767
|
+
if (metas.length === 0) continue;
|
|
3768
|
+
any = true;
|
|
3769
|
+
console.log(` ${S.label(label)}: ${metas.map((m) => S.cmd(m.id)).join(", ")}`);
|
|
3770
|
+
}
|
|
3771
|
+
if (!any) console.log(` ${S.dim("(none \u2014 plugins not installed, or contribute nothing)")}`);
|
|
3772
|
+
console.log();
|
|
3773
|
+
}
|
|
3774
|
+
function makePluginCommand() {
|
|
3775
|
+
const cmd = new Command("plugin").description(
|
|
3776
|
+
"Manage registry plugins (drivers / connectors / deploy targets) declared in skaile.yaml"
|
|
3777
|
+
);
|
|
3778
|
+
cmd.command("install <spec>").description("Add a plugin spec to skaile.yaml plugins and reconcile the store").option("--project-dir <path>", "Project directory", process.cwd()).action(action2(runInstall2));
|
|
3779
|
+
cmd.command("remove <name>").description("Remove a plugin (by package name) from skaile.yaml plugins and reconcile").option("--project-dir <path>", "Project directory", process.cwd()).action(action2(runRemove));
|
|
3780
|
+
cmd.command("list").description("List declared plugins and the targets they contribute").option("--project-dir <path>", "Project directory", process.cwd()).action(action2(runList));
|
|
3781
|
+
cmd.action(() => cmd.help());
|
|
3782
|
+
return cmd;
|
|
3783
|
+
}
|
|
3511
3784
|
function makePresetCommand() {
|
|
3512
3785
|
const cmd = new Command("preset").description("Scaffold and validate preset YAML files");
|
|
3513
3786
|
cmd.command("init [name]").description("Scaffold a new .preset.yaml file").option("--dir <path>", "Output directory", process.cwd()).action(async (name, opts) => {
|
|
3514
3787
|
const presetName = name ?? "my-preset";
|
|
3515
3788
|
const filename = `${presetName}.preset.yaml`;
|
|
3516
|
-
const outPath =
|
|
3789
|
+
const outPath = path14__default.join(path14__default.resolve(opts.dir), filename);
|
|
3517
3790
|
if (existsSync(outPath)) {
|
|
3518
3791
|
logErr(`File already exists: ${outPath}`);
|
|
3519
3792
|
logInfo("Choose a different name or remove the existing file.");
|
|
@@ -3527,7 +3800,7 @@ function makePresetCommand() {
|
|
|
3527
3800
|
logInfo(` skaile preset validate ${filename}`);
|
|
3528
3801
|
});
|
|
3529
3802
|
cmd.command("validate <path>").description("Validate a preset YAML file (schema + cycles + nesting depth)").action(async (filePath) => {
|
|
3530
|
-
const resolved =
|
|
3803
|
+
const resolved = path14__default.resolve(filePath);
|
|
3531
3804
|
if (!existsSync(resolved)) {
|
|
3532
3805
|
logErr(`File not found: ${resolved}`);
|
|
3533
3806
|
process.exit(1);
|
|
@@ -3553,7 +3826,7 @@ function makePresetCommand() {
|
|
|
3553
3826
|
logInfo(`Nested preset refs: ${nestedRefs.length} (depth validated at apply-time)`);
|
|
3554
3827
|
}
|
|
3555
3828
|
const { detectCycles } = await import('../discovery/index.js');
|
|
3556
|
-
const presetRef =
|
|
3829
|
+
const presetRef = path14__default.basename(resolved, ".preset.yaml");
|
|
3557
3830
|
const edges = [];
|
|
3558
3831
|
for (const item of preset.items) {
|
|
3559
3832
|
if (item.ref) {
|
|
@@ -3677,8 +3950,8 @@ function makeInstallCommand() {
|
|
|
3677
3950
|
const spinner6 = p5.spinner();
|
|
3678
3951
|
spinner6.start(`Installing ${ref}`);
|
|
3679
3952
|
try {
|
|
3680
|
-
const { openCatalogSource: openCatalogSource2, openLibrary: openLibrary2 } = await import('../open-library-
|
|
3681
|
-
const catalog = await openCatalogSource2({ projectDir:
|
|
3953
|
+
const { openCatalogSource: openCatalogSource2, openLibrary: openLibrary2 } = await import('../open-library-M4DB3D3J.js');
|
|
3954
|
+
const catalog = await openCatalogSource2({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3682
3955
|
if (!supportsInstallManifest(catalog)) {
|
|
3683
3956
|
throw new Error(
|
|
3684
3957
|
"pointer-only install (skaile install <ref>) requires a tRPC-framed Catalog. The configured catalog uses REST framing, which does not serve install manifests. Set catalog.url to https://skaile.store, or catalog.framing: trpc, in ~/.skaile/config.yaml."
|
|
@@ -3707,9 +3980,9 @@ function makeInstallCommand() {
|
|
|
3707
3980
|
}
|
|
3708
3981
|
return;
|
|
3709
3982
|
}
|
|
3710
|
-
const projectDir =
|
|
3983
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3711
3984
|
try {
|
|
3712
|
-
const { ensureSourcesCloned } = await import('../ensure-sources-
|
|
3985
|
+
const { ensureSourcesCloned } = await import('../ensure-sources-SL2S4UEX.js');
|
|
3713
3986
|
const hydrate = ensureSourcesCloned(projectDir, { quiet: true });
|
|
3714
3987
|
if (hydrate.cloned.length > 0) {
|
|
3715
3988
|
logOk(`Cloned source(s): ${hydrate.cloned.join(", ")}`);
|
|
@@ -3743,13 +4016,6 @@ function makeInstallCommand() {
|
|
|
3743
4016
|
if (result.missing.length > 0) {
|
|
3744
4017
|
for (const m of result.missing) logErr(`Missing: ${m}`);
|
|
3745
4018
|
}
|
|
3746
|
-
if (result.collisions.length > 0) {
|
|
3747
|
-
for (const c of result.collisions) {
|
|
3748
|
-
logWarn(
|
|
3749
|
-
`${c.key} resolved from ${S.bold(c.resolvedFrom)}, also found in: ${c.shadowedIn.join(", ")}. Use @repo qualifier to pin.`
|
|
3750
|
-
);
|
|
3751
|
-
}
|
|
3752
|
-
}
|
|
3753
4019
|
if (result.lockWritten) {
|
|
3754
4020
|
logInfo(`Lock file written: ${S.dim("skaile.lock.yaml")}`);
|
|
3755
4021
|
}
|
|
@@ -3762,7 +4028,7 @@ function makeInstallCommand() {
|
|
|
3762
4028
|
}
|
|
3763
4029
|
function makeCheckCommand() {
|
|
3764
4030
|
return new Command("check").description("Check for unmet requirements").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
3765
|
-
const am2 = new AssetManager({ projectDir:
|
|
4031
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3766
4032
|
const issues = am2.doctor();
|
|
3767
4033
|
if (issues.length === 0) {
|
|
3768
4034
|
logOk("All dependencies satisfied.");
|
|
@@ -3779,10 +4045,10 @@ function makeCheckCommand() {
|
|
|
3779
4045
|
function makeCleanCommand() {
|
|
3780
4046
|
return new Command("clean").description("Remove all skaile-managed assets from the workspace").option("--all", "Full reset: also remove history, patches, repos, and lock file").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()).option("--target <agent>", "Agent framework", "claude-code").action(async (opts) => {
|
|
3781
4047
|
const am2 = new AssetManager({
|
|
3782
|
-
projectDir:
|
|
4048
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
3783
4049
|
driverTarget: opts.target
|
|
3784
4050
|
});
|
|
3785
|
-
const lock = readLock(
|
|
4051
|
+
const lock = readLock(path14__default.resolve(opts.projectDir, "skaile.lock.yaml"));
|
|
3786
4052
|
if (!lock || Object.keys(lock.assets).length === 0) {
|
|
3787
4053
|
logInfo("Nothing to clean (no skaile-managed assets found).");
|
|
3788
4054
|
return;
|
|
@@ -3835,14 +4101,14 @@ function makeCleanCommand() {
|
|
|
3835
4101
|
}
|
|
3836
4102
|
function makeRebuildCommand() {
|
|
3837
4103
|
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) => {
|
|
3838
|
-
const projectDir =
|
|
4104
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3839
4105
|
let agentDir;
|
|
3840
4106
|
if (agentArg) {
|
|
3841
4107
|
if (agentArg.includes("/") || agentArg.includes("\\")) {
|
|
3842
|
-
agentDir =
|
|
4108
|
+
agentDir = path14__default.resolve(projectDir, agentArg);
|
|
3843
4109
|
} else {
|
|
3844
4110
|
const resolved = resolveAgentDir(projectDir);
|
|
3845
|
-
agentDir = resolved ??
|
|
4111
|
+
agentDir = resolved ?? path14__default.resolve(projectDir, agentArg);
|
|
3846
4112
|
}
|
|
3847
4113
|
} else {
|
|
3848
4114
|
const resolved = resolveAgentDir(projectDir);
|
|
@@ -3920,7 +4186,7 @@ function makeFlowEventHandler() {
|
|
|
3920
4186
|
}
|
|
3921
4187
|
function makeRunCommand() {
|
|
3922
4188
|
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>", "Driver backend (claude-sdk, codex, omp)").option("--provider <name>", "LLM provider").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) => {
|
|
3923
|
-
const projectDir =
|
|
4189
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3924
4190
|
const cliDriver = opts.driver;
|
|
3925
4191
|
const dryRun = opts.dryRun ?? false;
|
|
3926
4192
|
let flowId = positional[0];
|
|
@@ -3974,15 +4240,15 @@ function makeRunCommand() {
|
|
|
3974
4240
|
let flowPath;
|
|
3975
4241
|
let dir = projectDir;
|
|
3976
4242
|
for (let i = 0; i < 6; i++) {
|
|
3977
|
-
const candidate =
|
|
4243
|
+
const candidate = path14__default.join(dir, "ai-assets");
|
|
3978
4244
|
if (fs10__default.existsSync(candidate)) {
|
|
3979
4245
|
for (const domain of fs10__default.readdirSync(candidate)) {
|
|
3980
|
-
const p_ =
|
|
4246
|
+
const p_ = path14__default.join(candidate, domain, "flows", `${flowId}.flow.yaml`);
|
|
3981
4247
|
if (fs10__default.existsSync(p_)) {
|
|
3982
4248
|
flowPath = p_;
|
|
3983
4249
|
break;
|
|
3984
4250
|
}
|
|
3985
|
-
const legacy =
|
|
4251
|
+
const legacy = path14__default.join(candidate, domain, "flows", `${flowId}.json`);
|
|
3986
4252
|
if (fs10__default.existsSync(legacy)) {
|
|
3987
4253
|
flowPath = legacy;
|
|
3988
4254
|
break;
|
|
@@ -3990,16 +4256,16 @@ function makeRunCommand() {
|
|
|
3990
4256
|
}
|
|
3991
4257
|
break;
|
|
3992
4258
|
}
|
|
3993
|
-
dir =
|
|
4259
|
+
dir = path14__default.dirname(dir);
|
|
3994
4260
|
}
|
|
3995
4261
|
if (!flowPath) {
|
|
3996
4262
|
for (const domain of fs10__default.readdirSync(AI_RESOURCES)) {
|
|
3997
|
-
const p_ =
|
|
4263
|
+
const p_ = path14__default.join(AI_RESOURCES, domain, "flows", `${flowId}.flow.yaml`);
|
|
3998
4264
|
if (fs10__default.existsSync(p_)) {
|
|
3999
4265
|
flowPath = p_;
|
|
4000
4266
|
break;
|
|
4001
4267
|
}
|
|
4002
|
-
const legacy =
|
|
4268
|
+
const legacy = path14__default.join(AI_RESOURCES, domain, "flows", `${flowId}.json`);
|
|
4003
4269
|
if (fs10__default.existsSync(legacy)) {
|
|
4004
4270
|
flowPath = legacy;
|
|
4005
4271
|
break;
|
|
@@ -4033,7 +4299,7 @@ function makeRunCommand() {
|
|
|
4033
4299
|
}
|
|
4034
4300
|
function makeResumeCommand() {
|
|
4035
4301
|
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) => {
|
|
4036
|
-
const projectDir =
|
|
4302
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4037
4303
|
const sessionId = opts.session;
|
|
4038
4304
|
const dryRun = opts.dryRun ?? false;
|
|
4039
4305
|
const session = sessionId ? await loadSessionById(projectDir, sessionId) : await loadSession(projectDir);
|
|
@@ -4060,7 +4326,7 @@ function makeResumeCommand() {
|
|
|
4060
4326
|
}
|
|
4061
4327
|
function makeStatusCommand() {
|
|
4062
4328
|
return new Command("status").description("Show current session state").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
4063
|
-
const projectDir =
|
|
4329
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4064
4330
|
const session = await loadSession(projectDir);
|
|
4065
4331
|
if (!session) {
|
|
4066
4332
|
logInfo("No active session.");
|
|
@@ -4085,7 +4351,7 @@ function makeStatusCommand() {
|
|
|
4085
4351
|
}
|
|
4086
4352
|
function makeClearCommand() {
|
|
4087
4353
|
return new Command("clear").description("Unset current session pointer").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
4088
|
-
const projectDir =
|
|
4354
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4089
4355
|
await clearSession(projectDir);
|
|
4090
4356
|
logOk("Session cleared.");
|
|
4091
4357
|
});
|
|
@@ -4095,7 +4361,7 @@ function makeReplCommand() {
|
|
|
4095
4361
|
const { findWorkspaceRoot: findWorkspaceRoot2 } = await import('../core/index.js');
|
|
4096
4362
|
const { startRepl } = await import('../tui/index.js');
|
|
4097
4363
|
const os = await import('os');
|
|
4098
|
-
const userCwd =
|
|
4364
|
+
const userCwd = path14__default.resolve(opts.projectDir ?? process.cwd());
|
|
4099
4365
|
const workspaceRoot = findWorkspaceRoot2(userCwd);
|
|
4100
4366
|
let projectDir;
|
|
4101
4367
|
let agentCwd;
|
|
@@ -4117,12 +4383,12 @@ function makeReplCommand() {
|
|
|
4117
4383
|
p5.cancel("Cancelled.");
|
|
4118
4384
|
process.exit(0);
|
|
4119
4385
|
}
|
|
4120
|
-
const tmpDir = fs10__default.mkdtempSync(
|
|
4386
|
+
const tmpDir = fs10__default.mkdtempSync(path14__default.join(os.tmpdir(), "skaile-repl-"));
|
|
4121
4387
|
projectDir = tmpDir;
|
|
4122
4388
|
agentCwd = userCwd;
|
|
4123
4389
|
logOk(`Temporary workspace: ${S.cmd(tmpDir)}`);
|
|
4124
4390
|
if (!driverOverride) {
|
|
4125
|
-
const claudeDir =
|
|
4391
|
+
const claudeDir = path14__default.join(os.homedir(), ".claude");
|
|
4126
4392
|
if (fs10__default.existsSync(claudeDir)) {
|
|
4127
4393
|
driverOverride = "claude-sdk";
|
|
4128
4394
|
logInfo(`Detected ${S.cmd("~/.claude")} \u2192 using ${S.cmd("claude-sdk")} backend`);
|
|
@@ -4154,6 +4420,7 @@ function makeServeCommand() {
|
|
|
4154
4420
|
await runCompileTest({ ...opts, withCodex: opts.withCodex ?? false });
|
|
4155
4421
|
return;
|
|
4156
4422
|
}
|
|
4423
|
+
await ensurePluginsLoadedForServe(opts.projectDir);
|
|
4157
4424
|
const { startAgentServer } = await import('../runner/index.js');
|
|
4158
4425
|
await startAgentServer({
|
|
4159
4426
|
port: parseInt(opts.port, 10),
|
|
@@ -4167,6 +4434,25 @@ function makeServeCommand() {
|
|
|
4167
4434
|
}
|
|
4168
4435
|
);
|
|
4169
4436
|
}
|
|
4437
|
+
async function ensurePluginsLoadedForServe(projectDir) {
|
|
4438
|
+
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-I3SREIC3.js');
|
|
4439
|
+
try {
|
|
4440
|
+
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
4441
|
+
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
4442
|
+
if (!config.plugins || config.plugins.length === 0) return;
|
|
4443
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-AJ3FGXIC.js');
|
|
4444
|
+
const { pluginRegistry } = await import('../plugin-registry/index.js');
|
|
4445
|
+
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
4446
|
+
if (result.loaded.length > 0) {
|
|
4447
|
+
logInfo2(`Loaded ${result.loaded.length} plugin(s): ${result.loaded.join(", ")}`);
|
|
4448
|
+
}
|
|
4449
|
+
for (const f of result.failed) {
|
|
4450
|
+
logWarn2(f.error);
|
|
4451
|
+
}
|
|
4452
|
+
} catch (err) {
|
|
4453
|
+
logWarn2(`plugin store skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
4454
|
+
}
|
|
4455
|
+
}
|
|
4170
4456
|
async function runCompileTest(opts) {
|
|
4171
4457
|
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-I3SREIC3.js');
|
|
4172
4458
|
const { tmpdir } = await import('os');
|
|
@@ -4645,7 +4931,7 @@ function resolveMode(opts) {
|
|
|
4645
4931
|
if (opts.forceLocal && opts.forceRemote) {
|
|
4646
4932
|
throw new Error("Cannot use both --local and --remote");
|
|
4647
4933
|
}
|
|
4648
|
-
const startDir =
|
|
4934
|
+
const startDir = path14__default.resolve(opts.projectDir ?? process.cwd());
|
|
4649
4935
|
const localDb = findLogsDb(startDir);
|
|
4650
4936
|
if (opts.forceLocal) {
|
|
4651
4937
|
if (!localDb) {
|
|
@@ -4678,14 +4964,14 @@ function resolveMode(opts) {
|
|
|
4678
4964
|
function findLogsDb(startDir) {
|
|
4679
4965
|
let dir = startDir;
|
|
4680
4966
|
for (let i = 0; i < MAX_WALK_LEVELS; i++) {
|
|
4681
|
-
const candidate =
|
|
4967
|
+
const candidate = path14__default.join(dir, ".skaile", "logs.db");
|
|
4682
4968
|
if (existsSync(candidate)) {
|
|
4683
4969
|
try {
|
|
4684
4970
|
if (statSync(candidate).isFile()) return candidate;
|
|
4685
4971
|
} catch {
|
|
4686
4972
|
}
|
|
4687
4973
|
}
|
|
4688
|
-
const parent =
|
|
4974
|
+
const parent = path14__default.dirname(dir);
|
|
4689
4975
|
if (parent === dir) return void 0;
|
|
4690
4976
|
dir = parent;
|
|
4691
4977
|
}
|
|
@@ -4711,7 +4997,7 @@ function readApiToken() {
|
|
|
4711
4997
|
}
|
|
4712
4998
|
function readGlobalSettings() {
|
|
4713
4999
|
try {
|
|
4714
|
-
const settingsPath =
|
|
5000
|
+
const settingsPath = path14__default.join(homedir(), ".skaile", "settings.json");
|
|
4715
5001
|
if (!existsSync(settingsPath)) return {};
|
|
4716
5002
|
return JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
4717
5003
|
} catch {
|
|
@@ -4859,7 +5145,7 @@ function parsePositiveInt(value, flag) {
|
|
|
4859
5145
|
function makeSessionCommand() {
|
|
4860
5146
|
const cmd = new Command("session").description("Manage sessions");
|
|
4861
5147
|
cmd.command("list").description("List all sessions for a project").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
4862
|
-
const projectDir =
|
|
5148
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4863
5149
|
const sessions = await listSessions(projectDir);
|
|
4864
5150
|
const current = await loadSession(projectDir);
|
|
4865
5151
|
if (sessions.length === 0) {
|
|
@@ -4887,7 +5173,7 @@ function makeSessionCommand() {
|
|
|
4887
5173
|
console.log();
|
|
4888
5174
|
});
|
|
4889
5175
|
cmd.command("show <run-id>").description("Show a specific session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
4890
|
-
const projectDir =
|
|
5176
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4891
5177
|
const session = await loadSessionById(projectDir, runId);
|
|
4892
5178
|
if (!session) {
|
|
4893
5179
|
logErr(`Session not found: ${runId}`);
|
|
@@ -4896,12 +5182,12 @@ function makeSessionCommand() {
|
|
|
4896
5182
|
console.log(JSON.stringify(session, null, 2));
|
|
4897
5183
|
});
|
|
4898
5184
|
cmd.command("switch <run-id>").description("Switch the current session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
4899
|
-
const projectDir =
|
|
5185
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4900
5186
|
await setCurrentSession(projectDir, runId);
|
|
4901
5187
|
logOk(`Switched to session: ${S.dim(runId.slice(0, 8))}`);
|
|
4902
5188
|
});
|
|
4903
5189
|
cmd.command("delete <run-id>").description("Delete a session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
4904
|
-
const projectDir =
|
|
5190
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4905
5191
|
await deleteSession(projectDir, runId);
|
|
4906
5192
|
logOk(`Deleted session: ${S.dim(runId.slice(0, 8))}`);
|
|
4907
5193
|
});
|
|
@@ -4964,7 +5250,7 @@ function showAsset(am2, kind, name) {
|
|
|
4964
5250
|
function makeShowCommand() {
|
|
4965
5251
|
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((kind, name, opts) => {
|
|
4966
5252
|
const am2 = new AssetManager({
|
|
4967
|
-
projectDir:
|
|
5253
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
4968
5254
|
driverTarget: opts.target
|
|
4969
5255
|
});
|
|
4970
5256
|
if (!kind) {
|
|
@@ -5002,10 +5288,10 @@ function addSourceManifestCommands(src) {
|
|
|
5002
5288
|
|
|
5003
5289
|
// cli/src/commands/source.ts
|
|
5004
5290
|
function sourcesDir() {
|
|
5005
|
-
return
|
|
5291
|
+
return path14.join(skaileHomeDir(), "sources");
|
|
5006
5292
|
}
|
|
5007
5293
|
function sourceClonePath(name) {
|
|
5008
|
-
return
|
|
5294
|
+
return path14.join(sourcesDir(), name);
|
|
5009
5295
|
}
|
|
5010
5296
|
function deriveSlug(url) {
|
|
5011
5297
|
return url.replace(/\.git$/, "").split(/[/:]/).pop() ?? "source";
|
|
@@ -5018,7 +5304,7 @@ function requireProjectYamlPath() {
|
|
|
5018
5304
|
);
|
|
5019
5305
|
process.exit(1);
|
|
5020
5306
|
}
|
|
5021
|
-
return
|
|
5307
|
+
return path14.join(root, workspaceConfigFilename());
|
|
5022
5308
|
}
|
|
5023
5309
|
function readProjectSources(yamlPath) {
|
|
5024
5310
|
if (!existsSync(yamlPath)) return [];
|
|
@@ -5030,13 +5316,14 @@ function readProjectSources(yamlPath) {
|
|
|
5030
5316
|
}
|
|
5031
5317
|
}
|
|
5032
5318
|
function ensureClone(entry, opts = {}) {
|
|
5033
|
-
const
|
|
5319
|
+
const slug = deriveSlug(entry.url);
|
|
5320
|
+
const dest = sourceClonePath(slug);
|
|
5034
5321
|
if (existsSync(dest)) {
|
|
5035
5322
|
if (!opts.force) return false;
|
|
5036
5323
|
rmSync(dest, { recursive: true, force: true });
|
|
5037
5324
|
}
|
|
5038
5325
|
const args = ["clone", entry.url, dest];
|
|
5039
|
-
if (entry.
|
|
5326
|
+
if (entry.pin) args.splice(1, 0, "--branch", entry.pin);
|
|
5040
5327
|
const clone = spawnSync("git", args, { stdio: "inherit" });
|
|
5041
5328
|
if (clone.status !== 0) {
|
|
5042
5329
|
logErr(`git clone failed for ${entry.url}`);
|
|
@@ -5047,13 +5334,14 @@ function ensureClone(entry, opts = {}) {
|
|
|
5047
5334
|
async function refreshManifestCache(entry, includeDev = false) {
|
|
5048
5335
|
const { manager, library, close } = await openLibraryManager();
|
|
5049
5336
|
try {
|
|
5050
|
-
const
|
|
5051
|
-
const
|
|
5337
|
+
const slug = deriveSlug(entry.url);
|
|
5338
|
+
const dest = sourceClonePath(slug);
|
|
5339
|
+
const existing = (await manager.listLibraries()).find((l) => l.name === slug);
|
|
5052
5340
|
const lib = existing ?? await manager.addLibrary({
|
|
5053
|
-
name:
|
|
5341
|
+
name: slug,
|
|
5054
5342
|
path: dest,
|
|
5055
5343
|
backend: "git",
|
|
5056
|
-
backendConfig: { url: entry.url, branch: entry.
|
|
5344
|
+
backendConfig: { url: entry.url, branch: entry.pin ?? "main", authHint: "ssh" },
|
|
5057
5345
|
ownership: "reader"
|
|
5058
5346
|
});
|
|
5059
5347
|
const catalog = new LocalCatalogSource(library, lib.id, dest, createFullRegistry());
|
|
@@ -5083,20 +5371,19 @@ function makeSourceCommand() {
|
|
|
5083
5371
|
const cmd = new Command("source").description(
|
|
5084
5372
|
"Manage github sources for the current project (recorded in skaile.yaml)"
|
|
5085
5373
|
);
|
|
5086
|
-
cmd.command("add <git-url>").description("Clone a github repo and register it in this project's skaile.yaml").option("--name <slug>", "
|
|
5374
|
+
cmd.command("add <git-url>").description("Clone a github repo and register it in this project's skaile.yaml").option("--name <slug>", "[deprecated] no-op \u2014 the source entry stores only the URL").option("--pin <ref>", "Pin a branch, tag, or 40-char SHA").option("--branch <branch>", "[deprecated] alias for --pin").option("--force", "Remove an existing clone and re-clone", false).option("--dev", "Also index dev-only assets under the source's dev_paths", false).action(
|
|
5087
5375
|
async (url, opts) => {
|
|
5088
5376
|
const yamlPath = requireProjectYamlPath();
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
const editor = WorkspaceYamlEditor.load(yamlPath);
|
|
5093
|
-
const existing = editor.getSources().find((s) => s.name === slug);
|
|
5094
|
-
if (existing && existing.url !== url) {
|
|
5095
|
-
logErr(
|
|
5096
|
-
`A source named "${slug}" already exists in ${yamlPath} with a different url (${existing.url}). Pass --name to use a different slug.`
|
|
5377
|
+
if (opts.name) {
|
|
5378
|
+
logWarn(
|
|
5379
|
+
"the --name flag is deprecated; the source entry now stores only the URL (the cache slug is derived from it)."
|
|
5097
5380
|
);
|
|
5098
|
-
process.exit(1);
|
|
5099
5381
|
}
|
|
5382
|
+
const pin = opts.pin ?? opts.branch;
|
|
5383
|
+
const slug = deriveSlug(url);
|
|
5384
|
+
const entry = { url };
|
|
5385
|
+
if (pin) entry.pin = pin;
|
|
5386
|
+
const editor = WorkspaceYamlEditor.load(yamlPath);
|
|
5100
5387
|
editor.setSource(entry);
|
|
5101
5388
|
editor.save();
|
|
5102
5389
|
const dest = sourceClonePath(slug);
|
|
@@ -5112,7 +5399,7 @@ function makeSourceCommand() {
|
|
|
5112
5399
|
const result = await refreshManifestCache(entry, opts.dev);
|
|
5113
5400
|
logOk(`Indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s) from "${slug}".`);
|
|
5114
5401
|
for (const err of result.errors) logWarn(err);
|
|
5115
|
-
logOk(`Source "${slug}" registered in ${
|
|
5402
|
+
logOk(`Source "${slug}" registered in ${path14.relative(process.cwd(), yamlPath)}.`);
|
|
5116
5403
|
}
|
|
5117
5404
|
);
|
|
5118
5405
|
cmd.command("list").description("List sources registered in this project's skaile.yaml").option("--json", "Output as JSON").action(async (opts) => {
|
|
@@ -5126,69 +5413,77 @@ function makeSourceCommand() {
|
|
|
5126
5413
|
console.log();
|
|
5127
5414
|
console.log(S.heading(" Sources"));
|
|
5128
5415
|
for (const s of sources) {
|
|
5129
|
-
const
|
|
5130
|
-
|
|
5416
|
+
const slug = deriveSlug(s.url);
|
|
5417
|
+
const cached = existsSync(sourceClonePath(slug)) ? "" : S.warn(" (not cached)");
|
|
5418
|
+
console.log(` ${S.cmd(slug.padEnd(24))} ${S.dim(s.url)}${cached}`);
|
|
5131
5419
|
}
|
|
5132
5420
|
console.log(`
|
|
5133
5421
|
${S.dim(`${sources.length} source(s)`)}
|
|
5134
5422
|
`);
|
|
5135
5423
|
});
|
|
5136
|
-
cmd.command("show <name>").description("Show details for a source").action(async (
|
|
5424
|
+
cmd.command("show <name-or-url>").description("Show details for a source (matched by URL or derived slug)").action(async (key) => {
|
|
5137
5425
|
const yamlPath = requireProjectYamlPath();
|
|
5138
|
-
const entry = readProjectSources(yamlPath).find(
|
|
5426
|
+
const entry = readProjectSources(yamlPath).find(
|
|
5427
|
+
(s) => s.url === key || deriveSlug(s.url) === key
|
|
5428
|
+
);
|
|
5139
5429
|
if (!entry) {
|
|
5140
|
-
logErr(`No source
|
|
5430
|
+
logErr(`No source matching "${key}" in ${yamlPath}.`);
|
|
5141
5431
|
process.exit(1);
|
|
5142
5432
|
}
|
|
5433
|
+
const slug = deriveSlug(entry.url);
|
|
5143
5434
|
console.log(
|
|
5144
5435
|
JSON.stringify(
|
|
5145
5436
|
{
|
|
5146
5437
|
...entry,
|
|
5147
|
-
|
|
5148
|
-
|
|
5438
|
+
slug,
|
|
5439
|
+
clonePath: sourceClonePath(slug),
|
|
5440
|
+
cached: existsSync(sourceClonePath(slug))
|
|
5149
5441
|
},
|
|
5150
5442
|
null,
|
|
5151
5443
|
2
|
|
5152
5444
|
)
|
|
5153
5445
|
);
|
|
5154
5446
|
});
|
|
5155
|
-
cmd.command("remove <name>").description("Remove a source from this project's skaile.yaml").option("--purge", "Also delete the cached clone from ~/.skaile/sources/", false).action(async (
|
|
5447
|
+
cmd.command("remove <name-or-url>").description("Remove a source from this project's skaile.yaml (matched by URL or slug)").option("--purge", "Also delete the cached clone from ~/.skaile/sources/", false).action(async (key, opts) => {
|
|
5156
5448
|
const yamlPath = requireProjectYamlPath();
|
|
5157
5449
|
const editor = WorkspaceYamlEditor.load(yamlPath);
|
|
5158
|
-
const
|
|
5159
|
-
if (!
|
|
5160
|
-
logErr(`No source
|
|
5450
|
+
const match = editor.getSources().find((s) => s.url === key || deriveSlug(s.url) === key);
|
|
5451
|
+
if (!match) {
|
|
5452
|
+
logErr(`No source matching "${key}" in ${yamlPath}.`);
|
|
5161
5453
|
process.exit(1);
|
|
5162
5454
|
}
|
|
5455
|
+
const slug = deriveSlug(match.url);
|
|
5456
|
+
editor.removeSource(match.url);
|
|
5163
5457
|
editor.save();
|
|
5164
|
-
await dropManifestCache(
|
|
5458
|
+
await dropManifestCache(slug, opts.purge);
|
|
5165
5459
|
logOk(
|
|
5166
|
-
opts.purge ? `Removed source "${
|
|
5460
|
+
opts.purge ? `Removed source "${slug}" and purged its clone.` : `Removed source "${slug}" from skaile.yaml (clone left in ~/.skaile/sources/).`
|
|
5167
5461
|
);
|
|
5168
5462
|
});
|
|
5169
|
-
cmd.command("sync [name]").description("Pull upstream changes and refresh the manifest cache").option("--dev", "Also index dev-only assets under each source's dev_paths", false).action(async (
|
|
5463
|
+
cmd.command("sync [name]").description("Pull upstream changes and refresh the manifest cache").option("--dev", "Also index dev-only assets under each source's dev_paths", false).action(async (key, opts) => {
|
|
5170
5464
|
const yamlPath = requireProjectYamlPath();
|
|
5171
5465
|
const all = readProjectSources(yamlPath);
|
|
5172
|
-
const targets =
|
|
5466
|
+
const targets = key ? all.filter((s) => s.url === key || deriveSlug(s.url) === key) : all;
|
|
5173
5467
|
if (targets.length === 0) {
|
|
5174
|
-
logInfo(
|
|
5468
|
+
logInfo(key ? `No source matching "${key}".` : "No sources in skaile.yaml.");
|
|
5175
5469
|
return;
|
|
5176
5470
|
}
|
|
5177
5471
|
for (const entry of targets) {
|
|
5178
|
-
const
|
|
5472
|
+
const slug = deriveSlug(entry.url);
|
|
5473
|
+
const dest = sourceClonePath(slug);
|
|
5179
5474
|
if (!existsSync(dest)) {
|
|
5180
5475
|
ensureClone(entry);
|
|
5181
|
-
logOk(`${
|
|
5476
|
+
logOk(`${slug}: cloned to ${dest}.`);
|
|
5182
5477
|
} else {
|
|
5183
5478
|
const pull = spawnSync("git", ["pull", "--ff-only"], { cwd: dest, stdio: "inherit" });
|
|
5184
5479
|
if (pull.status !== 0) {
|
|
5185
|
-
logWarn(`${
|
|
5480
|
+
logWarn(`${slug}: git pull failed, skipping manifest refresh.`);
|
|
5186
5481
|
continue;
|
|
5187
5482
|
}
|
|
5188
5483
|
}
|
|
5189
5484
|
const result = await refreshManifestCache(entry, opts.dev);
|
|
5190
|
-
logOk(`${
|
|
5191
|
-
for (const err of result.errors) logWarn(`${
|
|
5485
|
+
logOk(`${slug}: indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s).`);
|
|
5486
|
+
for (const err of result.errors) logWarn(`${slug}: ${err}`);
|
|
5192
5487
|
}
|
|
5193
5488
|
});
|
|
5194
5489
|
cmd.command("patch <ref>").description("Extract an asset for editing against the source").action((_ref) => {
|
|
@@ -5371,7 +5666,7 @@ function printTree(node, prefix = "", isLast = true) {
|
|
|
5371
5666
|
}
|
|
5372
5667
|
function makeTreeCommand() {
|
|
5373
5668
|
return new Command("tree").description("Show full dependency tree").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
5374
|
-
const am2 = new AssetManager({ projectDir:
|
|
5669
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
5375
5670
|
const root = am2.tree();
|
|
5376
5671
|
if (root.children.length === 0) {
|
|
5377
5672
|
logInfo("No dependencies in lock file. Run `skaile install` first.");
|
|
@@ -5389,7 +5684,7 @@ function makeUpdateCommand() {
|
|
|
5389
5684
|
try {
|
|
5390
5685
|
const catalogSpinner = p5.spinner();
|
|
5391
5686
|
catalogSpinner.start("Refreshing catalog cache");
|
|
5392
|
-
const remote = await openCatalogSource({ projectDir:
|
|
5687
|
+
const remote = await openCatalogSource({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
5393
5688
|
const result2 = await remote.refresh();
|
|
5394
5689
|
catalogSpinner.stop(
|
|
5395
5690
|
`Catalog refreshed: ${S.heading(String(result2.assetsCached))} assets cached`
|
|
@@ -5401,7 +5696,7 @@ function makeUpdateCommand() {
|
|
|
5401
5696
|
}
|
|
5402
5697
|
}
|
|
5403
5698
|
if (opts.catalogOnly) return;
|
|
5404
|
-
const am2 = new AssetManager({ projectDir:
|
|
5699
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
5405
5700
|
const spinner5 = p5.spinner();
|
|
5406
5701
|
spinner5.start("Re-deploying assets");
|
|
5407
5702
|
const result = await am2.install();
|
|
@@ -5411,13 +5706,6 @@ function makeUpdateCommand() {
|
|
|
5411
5706
|
} else {
|
|
5412
5707
|
logInfo("Nothing to update.");
|
|
5413
5708
|
}
|
|
5414
|
-
if (result.collisions.length > 0) {
|
|
5415
|
-
for (const c of result.collisions) {
|
|
5416
|
-
logWarn(
|
|
5417
|
-
`${c.key} resolved from ${S.heading(c.resolvedFrom)}, also found in: ${c.shadowedIn.join(", ")}`
|
|
5418
|
-
);
|
|
5419
|
-
}
|
|
5420
|
-
}
|
|
5421
5709
|
}
|
|
5422
5710
|
);
|
|
5423
5711
|
}
|
|
@@ -5447,7 +5735,7 @@ function findManifestCandidates(rootPath) {
|
|
|
5447
5735
|
return;
|
|
5448
5736
|
}
|
|
5449
5737
|
for (const entry of entries) {
|
|
5450
|
-
const fullPath =
|
|
5738
|
+
const fullPath = path14__default.join(dir, entry.name);
|
|
5451
5739
|
if (entry.isDirectory()) {
|
|
5452
5740
|
if (!SKIP_DIRS.has(entry.name)) walk(fullPath);
|
|
5453
5741
|
} else if (entry.isFile()) {
|
|
@@ -5469,7 +5757,7 @@ function parseMdFrontmatter(content) {
|
|
|
5469
5757
|
return parse(fmMatch[1]);
|
|
5470
5758
|
}
|
|
5471
5759
|
function validateManifests(rootPath) {
|
|
5472
|
-
const absRoot =
|
|
5760
|
+
const absRoot = path14__default.resolve(rootPath);
|
|
5473
5761
|
if (!fs10__default.existsSync(absRoot)) {
|
|
5474
5762
|
logErr(`Path does not exist: ${absRoot}`);
|
|
5475
5763
|
return { total: 0, errors: 1, warnings: 0 };
|
|
@@ -5490,14 +5778,14 @@ function validateManifests(rootPath) {
|
|
|
5490
5778
|
try {
|
|
5491
5779
|
parsed = c.filePath.endsWith(".json") ? JSON.parse(content) : parse(content);
|
|
5492
5780
|
} catch (e) {
|
|
5493
|
-
const relPath2 =
|
|
5781
|
+
const relPath2 = path14__default.relative(absRoot, c.filePath);
|
|
5494
5782
|
logErr(`${relPath2} \u2014 parse error: ${e instanceof Error ? e.message : String(e)}`);
|
|
5495
5783
|
errors++;
|
|
5496
5784
|
continue;
|
|
5497
5785
|
}
|
|
5498
5786
|
}
|
|
5499
5787
|
const provider = registry.getProvider(c.kind);
|
|
5500
|
-
const relPath =
|
|
5788
|
+
const relPath = path14__default.relative(absRoot, c.filePath);
|
|
5501
5789
|
if (!provider) {
|
|
5502
5790
|
logWarn(`${relPath} [${c.kind}] \u2014 kind "${c.kind}" is not registered, skipping validation`);
|
|
5503
5791
|
warnings++;
|
|
@@ -5519,20 +5807,20 @@ function collectAssetVersions() {
|
|
|
5519
5807
|
if (!fs10__default.existsSync(AI_RESOURCES)) return assets;
|
|
5520
5808
|
const domains = fs10__default.readdirSync(AI_RESOURCES, { withFileTypes: true }).filter((d) => d.isDirectory() && !EXCLUDED_DOMAINS.has(d.name));
|
|
5521
5809
|
for (const d of domains) {
|
|
5522
|
-
const domainDir =
|
|
5523
|
-
const skillsDir =
|
|
5810
|
+
const domainDir = path14__default.join(AI_RESOURCES, d.name);
|
|
5811
|
+
const skillsDir = path14__default.join(domainDir, "skills");
|
|
5524
5812
|
if (fs10__default.existsSync(skillsDir)) {
|
|
5525
5813
|
collectSkillVersions(skillsDir, d.name, assets);
|
|
5526
5814
|
}
|
|
5527
|
-
const agentsDir =
|
|
5815
|
+
const agentsDir = path14__default.join(domainDir, "agents");
|
|
5528
5816
|
if (fs10__default.existsSync(agentsDir)) {
|
|
5529
5817
|
collectAgentVersions(agentsDir, d.name, assets);
|
|
5530
5818
|
}
|
|
5531
|
-
const flowsDir =
|
|
5819
|
+
const flowsDir = path14__default.join(domainDir, "flows");
|
|
5532
5820
|
if (fs10__default.existsSync(flowsDir)) {
|
|
5533
5821
|
for (const f of fs10__default.readdirSync(flowsDir)) {
|
|
5534
5822
|
if (!f.endsWith(".flow.yaml")) continue;
|
|
5535
|
-
const fp =
|
|
5823
|
+
const fp = path14__default.join(flowsDir, f);
|
|
5536
5824
|
const content = fs10__default.readFileSync(fp, "utf-8");
|
|
5537
5825
|
const parsed = parse(content);
|
|
5538
5826
|
assets.push({
|
|
@@ -5544,11 +5832,11 @@ function collectAssetVersions() {
|
|
|
5544
5832
|
});
|
|
5545
5833
|
}
|
|
5546
5834
|
}
|
|
5547
|
-
const promptsDir =
|
|
5835
|
+
const promptsDir = path14__default.join(domainDir, "prompts");
|
|
5548
5836
|
if (fs10__default.existsSync(promptsDir)) {
|
|
5549
5837
|
for (const f of fs10__default.readdirSync(promptsDir)) {
|
|
5550
5838
|
if (!f.endsWith(".prompt.md")) continue;
|
|
5551
|
-
const fp =
|
|
5839
|
+
const fp = path14__default.join(promptsDir, f);
|
|
5552
5840
|
const content = fs10__default.readFileSync(fp, "utf-8");
|
|
5553
5841
|
const fm = parseSkillFrontmatter(content);
|
|
5554
5842
|
assets.push({
|
|
@@ -5566,8 +5854,8 @@ function collectAssetVersions() {
|
|
|
5566
5854
|
function collectSkillVersions(dir, domain, out) {
|
|
5567
5855
|
for (const entry of fs10__default.readdirSync(dir, { withFileTypes: true })) {
|
|
5568
5856
|
if (!entry.isDirectory()) continue;
|
|
5569
|
-
const full =
|
|
5570
|
-
const skillMd =
|
|
5857
|
+
const full = path14__default.join(dir, entry.name);
|
|
5858
|
+
const skillMd = path14__default.join(full, "SKILL.md");
|
|
5571
5859
|
if (fs10__default.existsSync(skillMd)) {
|
|
5572
5860
|
const content = fs10__default.readFileSync(skillMd, "utf-8");
|
|
5573
5861
|
const fm = parseSkillFrontmatter(content);
|
|
@@ -5586,7 +5874,7 @@ function collectSkillVersions(dir, domain, out) {
|
|
|
5586
5874
|
function collectAgentVersions(dir, domain, out) {
|
|
5587
5875
|
for (const entry of fs10__default.readdirSync(dir, { withFileTypes: true })) {
|
|
5588
5876
|
if (!entry.isDirectory()) continue;
|
|
5589
|
-
const agentYaml =
|
|
5877
|
+
const agentYaml = path14__default.join(dir, entry.name, "agent.yaml");
|
|
5590
5878
|
if (!fs10__default.existsSync(agentYaml)) continue;
|
|
5591
5879
|
const content = fs10__default.readFileSync(agentYaml, "utf-8");
|
|
5592
5880
|
const parsed = parse(content);
|
|
@@ -5617,7 +5905,7 @@ function makeValidateCommand() {
|
|
|
5617
5905
|
"Validate asset manifests, versions, and changelogs"
|
|
5618
5906
|
);
|
|
5619
5907
|
cmd.argument("[path]", "Path to asset repo or directory to validate", ".").action((targetPath) => {
|
|
5620
|
-
const absPath =
|
|
5908
|
+
const absPath = path14__default.resolve(targetPath);
|
|
5621
5909
|
logInfo(`Validating manifests in ${absPath}`);
|
|
5622
5910
|
const { total, errors } = validateManifests(absPath);
|
|
5623
5911
|
console.log();
|
|
@@ -5638,7 +5926,7 @@ function makeValidateCommand() {
|
|
|
5638
5926
|
encoding: "utf-8"
|
|
5639
5927
|
});
|
|
5640
5928
|
const changedFiles = new Set(
|
|
5641
|
-
diffOutput.trim().split("\n").filter(Boolean).map((f) =>
|
|
5929
|
+
diffOutput.trim().split("\n").filter(Boolean).map((f) => path14__default.resolve(AI_RESOURCES, f))
|
|
5642
5930
|
);
|
|
5643
5931
|
assets = assets.filter((a) => changedFiles.has(a.filePath));
|
|
5644
5932
|
} catch {
|
|
@@ -5660,7 +5948,7 @@ function makeValidateCommand() {
|
|
|
5660
5948
|
if (opts.changedOnly) {
|
|
5661
5949
|
for (const a of assets) {
|
|
5662
5950
|
if (!a.version) continue;
|
|
5663
|
-
const relPath =
|
|
5951
|
+
const relPath = path14__default.relative(AI_RESOURCES, a.filePath);
|
|
5664
5952
|
try {
|
|
5665
5953
|
const headContent = execSync(`git show HEAD:${relPath}`, {
|
|
5666
5954
|
cwd: AI_RESOURCES,
|
|
@@ -5740,7 +6028,7 @@ function makeValidateCommand() {
|
|
|
5740
6028
|
let errors = 0;
|
|
5741
6029
|
for (const domain of modifiedDomains) {
|
|
5742
6030
|
const changelogModified = modifiedFiles.some(
|
|
5743
|
-
(f) => f === `${domain}/CHANGELOG.md` || f ===
|
|
6031
|
+
(f) => f === `${domain}/CHANGELOG.md` || f === path14__default.join(domain, "CHANGELOG.md")
|
|
5744
6032
|
);
|
|
5745
6033
|
if (changelogModified) {
|
|
5746
6034
|
logOk(`${domain}/CHANGELOG.md updated`);
|
|
@@ -5822,7 +6110,7 @@ function makeVerifyCommand() {
|
|
|
5822
6110
|
}
|
|
5823
6111
|
function makeWhyCommand() {
|
|
5824
6112
|
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((ref, opts) => {
|
|
5825
|
-
const am2 = new AssetManager({ projectDir:
|
|
6113
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
5826
6114
|
const chain = am2.why(ref);
|
|
5827
6115
|
if (chain.length === 0) {
|
|
5828
6116
|
logErr(`${ref} not found in lock file. Run \`skaile install\` first.`);
|
|
@@ -5843,7 +6131,7 @@ function makeWhyCommand() {
|
|
|
5843
6131
|
var _defaultFormatHelp = Help.prototype.formatHelp;
|
|
5844
6132
|
var pkg = JSON.parse(
|
|
5845
6133
|
readFileSync(
|
|
5846
|
-
|
|
6134
|
+
path14__default.resolve(path14__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
|
|
5847
6135
|
"utf-8"
|
|
5848
6136
|
)
|
|
5849
6137
|
);
|
|
@@ -5891,11 +6179,18 @@ Execution:
|
|
|
5891
6179
|
resume Resume last session
|
|
5892
6180
|
serve [--compile-test] Start WebSocket agent server
|
|
5893
6181
|
mcp-server Start workspace MCP server (for .claude/mcp.json)
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
6182
|
+
integration install [--driver all] Install agent integration (claude-code | omp | codex)
|
|
6183
|
+
integration uninstall [--driver all] Uninstall agent integration
|
|
6184
|
+
integration enable Enable integration (claude-code only)
|
|
6185
|
+
integration disable Disable integration (claude-code only)
|
|
6186
|
+
integration status Show install / enable state across backends
|
|
6187
|
+
plugin install <spec> Add a registry plugin to skaile.yaml + reconcile
|
|
6188
|
+
plugin remove <name> Remove a registry plugin from skaile.yaml
|
|
6189
|
+
plugin list List declared plugins + the targets they contribute
|
|
6190
|
+
deploy up [--target] [--detach] Stand the workspace up on a deploy target
|
|
6191
|
+
deploy down Tear down the active deploy
|
|
6192
|
+
deploy status Show the active deploy's state + ws URL
|
|
6193
|
+
deploy logs [--follow] Stream logs from the active deploy
|
|
5899
6194
|
debug tools|connectors|mcp|config|state Inspect running container state
|
|
5900
6195
|
connect <url> Interactive WebSocket REPL
|
|
5901
6196
|
logs [--follow] [--filter] Tail skaile container logs
|
|
@@ -5947,136 +6242,129 @@ Advanced:
|
|
|
5947
6242
|
`;
|
|
5948
6243
|
}
|
|
5949
6244
|
});
|
|
5950
|
-
program.command("init [project-dir]").description("Initialize a project directory (defaults to current directory)").option(
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
}
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
provider: "anthropic",
|
|
5996
|
-
model: "claude-sonnet-4-6",
|
|
5997
|
-
driver: "claude-sdk",
|
|
5998
|
-
max_turns: 200
|
|
5999
|
-
}
|
|
6000
|
-
},
|
|
6001
|
-
ai_resources: []
|
|
6002
|
-
})
|
|
6003
|
-
);
|
|
6004
|
-
created.push("skaile.yaml");
|
|
6005
|
-
}
|
|
6006
|
-
for (const dir of new Set(Object.values(DRIVER_TARGETS[backend].local))) {
|
|
6007
|
-
const full = path15__default.join(resolved, dir);
|
|
6008
|
-
if (!existsSync12(full)) {
|
|
6009
|
-
mkdirSync3(full, { recursive: true });
|
|
6010
|
-
created.push(`${dir}/`);
|
|
6011
|
-
}
|
|
6012
|
-
}
|
|
6013
|
-
if (opts.git) {
|
|
6014
|
-
const gitignorePath = path15__default.join(resolved, ".gitignore");
|
|
6015
|
-
const entries = ["node_modules/", ".skaile/sessions/", "*.log", ".env", ".env.local"];
|
|
6016
|
-
const existing = existsSync12(gitignorePath) ? readFileSync5(gitignorePath, "utf-8") : "";
|
|
6017
|
-
const have = new Set(existing.split("\n").map((l) => l.trim()));
|
|
6018
|
-
const append = entries.filter((e) => !have.has(e));
|
|
6019
|
-
if (append.length > 0) {
|
|
6020
|
-
const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
6021
|
-
writeFileSync2(gitignorePath, existing + prefix + `${append.join("\n")}
|
|
6022
|
-
`);
|
|
6023
|
-
if (!existing) created.push(".gitignore");
|
|
6024
|
-
}
|
|
6025
|
-
if (!existsSync12(path15__default.join(resolved, ".git"))) {
|
|
6026
|
-
try {
|
|
6027
|
-
execSync3("git init", { cwd: resolved, stdio: "pipe" });
|
|
6028
|
-
created.push(".git/");
|
|
6029
|
-
} catch (err) {
|
|
6030
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
6031
|
-
console.log(` ${S.dim(`\u26A0 git init failed: ${msg}`)}`);
|
|
6245
|
+
program.command("init [project-dir]").description("Initialize a project directory (defaults to current directory)").option("--backend <name>", "Coding-agent backend (claude-code | omp | codex)", "claude-code").option("--no-git", "Skip git init and .gitignore").action(async (projectDir, opts) => {
|
|
6246
|
+
const { execSync: execSync3 } = await import('child_process');
|
|
6247
|
+
const { existsSync: existsSync12, mkdirSync: mkdirSync3, readFileSync: readFileSync5, writeFileSync: writeFileSync2 } = await import('fs');
|
|
6248
|
+
const { stringify } = await import('yaml');
|
|
6249
|
+
const { DRIVER_TARGETS, SUPPORTED_DRIVER_TARGETS: SUPPORTED_DRIVER_TARGETS2 } = await import('../core/index.js');
|
|
6250
|
+
const backend = opts.backend;
|
|
6251
|
+
if (!SUPPORTED_DRIVER_TARGETS2.includes(backend)) {
|
|
6252
|
+
logErr(
|
|
6253
|
+
`Unknown backend "${opts.backend}". Supported: ${SUPPORTED_DRIVER_TARGETS2.join(", ")}`
|
|
6254
|
+
);
|
|
6255
|
+
process.exitCode = 1;
|
|
6256
|
+
return;
|
|
6257
|
+
}
|
|
6258
|
+
const resolved = path14__default.resolve(projectDir ?? ".");
|
|
6259
|
+
const projectName = path14__default.basename(resolved);
|
|
6260
|
+
const created = [];
|
|
6261
|
+
if (!existsSync12(resolved)) {
|
|
6262
|
+
mkdirSync3(resolved, { recursive: true });
|
|
6263
|
+
created.push(".");
|
|
6264
|
+
}
|
|
6265
|
+
const skaileDir = path14__default.join(resolved, ".skaile");
|
|
6266
|
+
if (!existsSync12(skaileDir)) {
|
|
6267
|
+
mkdirSync3(path14__default.join(skaileDir, "sessions"), { recursive: true });
|
|
6268
|
+
created.push(".skaile/");
|
|
6269
|
+
}
|
|
6270
|
+
const settingsPath = path14__default.join(skaileDir, "settings.json");
|
|
6271
|
+
if (!existsSync12(settingsPath)) {
|
|
6272
|
+
writeFileSync2(settingsPath, "{}\n");
|
|
6273
|
+
created.push(".skaile/settings.json");
|
|
6274
|
+
}
|
|
6275
|
+
const wsConfigPath = path14__default.join(resolved, "skaile.yaml");
|
|
6276
|
+
if (!existsSync12(wsConfigPath)) {
|
|
6277
|
+
writeFileSync2(
|
|
6278
|
+
wsConfigPath,
|
|
6279
|
+
stringify({
|
|
6280
|
+
name: projectName,
|
|
6281
|
+
description: `${projectName} AI skill dependencies`,
|
|
6282
|
+
"agent-config": {
|
|
6283
|
+
default: {
|
|
6284
|
+
agent: backend,
|
|
6285
|
+
provider: "anthropic",
|
|
6286
|
+
model: "claude-sonnet-4-6",
|
|
6287
|
+
driver: "claude-sdk",
|
|
6288
|
+
max_turns: 200
|
|
6289
|
+
}
|
|
6032
6290
|
}
|
|
6033
|
-
}
|
|
6291
|
+
})
|
|
6292
|
+
);
|
|
6293
|
+
created.push("skaile.yaml");
|
|
6294
|
+
}
|
|
6295
|
+
for (const dir of new Set(Object.values(DRIVER_TARGETS[backend].local))) {
|
|
6296
|
+
const full = path14__default.join(resolved, dir);
|
|
6297
|
+
if (!existsSync12(full)) {
|
|
6298
|
+
mkdirSync3(full, { recursive: true });
|
|
6299
|
+
created.push(`${dir}/`);
|
|
6300
|
+
}
|
|
6301
|
+
}
|
|
6302
|
+
if (opts.git) {
|
|
6303
|
+
const gitignorePath = path14__default.join(resolved, ".gitignore");
|
|
6304
|
+
const entries = ["node_modules/", ".skaile/sessions/", "*.log", ".env", ".env.local"];
|
|
6305
|
+
const existing = existsSync12(gitignorePath) ? readFileSync5(gitignorePath, "utf-8") : "";
|
|
6306
|
+
const have = new Set(existing.split("\n").map((l) => l.trim()));
|
|
6307
|
+
const append = entries.filter((e) => !have.has(e));
|
|
6308
|
+
if (append.length > 0) {
|
|
6309
|
+
const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
6310
|
+
writeFileSync2(gitignorePath, `${existing + prefix}${append.join("\n")}
|
|
6311
|
+
`);
|
|
6312
|
+
if (!existing) created.push(".gitignore");
|
|
6034
6313
|
}
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
const
|
|
6041
|
-
|
|
6042
|
-
catalog: { url: defaults.catalog.url, cache_ttl: defaults.catalog.cache_ttl }
|
|
6043
|
-
});
|
|
6044
|
-
console.log(` ${S.dim(`\u2713 wrote default user config at ${userCfgPath}`)}`);
|
|
6314
|
+
if (!existsSync12(path14__default.join(resolved, ".git"))) {
|
|
6315
|
+
try {
|
|
6316
|
+
execSync3("git init", { cwd: resolved, stdio: "pipe" });
|
|
6317
|
+
created.push(".git/");
|
|
6318
|
+
} catch (err) {
|
|
6319
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6320
|
+
console.log(` ${S.dim(`\u26A0 git init failed: ${msg}`)}`);
|
|
6045
6321
|
}
|
|
6046
|
-
} catch (err) {
|
|
6047
|
-
console.log(
|
|
6048
|
-
` ${S.dim(`\u26A0 could not bootstrap user config: ${err instanceof Error ? err.message : String(err)}`)}`
|
|
6049
|
-
);
|
|
6050
6322
|
}
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6323
|
+
}
|
|
6324
|
+
try {
|
|
6325
|
+
const fs11 = await import('fs');
|
|
6326
|
+
const { userConfigPath, saveConfig, getConfigDefaults } = await import('../library/index.js');
|
|
6327
|
+
const userCfgPath = userConfigPath();
|
|
6328
|
+
if (!fs11.existsSync(userCfgPath)) {
|
|
6329
|
+
const defaults = getConfigDefaults();
|
|
6330
|
+
saveConfig(userCfgPath, {
|
|
6331
|
+
catalog: { url: defaults.catalog.url, cache_ttl: defaults.catalog.cache_ttl }
|
|
6332
|
+
});
|
|
6333
|
+
console.log(` ${S.dim(`\u2713 wrote default user config at ${userCfgPath}`)}`);
|
|
6061
6334
|
}
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6335
|
+
} catch (err) {
|
|
6336
|
+
console.log(
|
|
6337
|
+
` ${S.dim(`\u26A0 could not bootstrap user config: ${err instanceof Error ? err.message : String(err)}`)}`
|
|
6338
|
+
);
|
|
6339
|
+
}
|
|
6340
|
+
try {
|
|
6341
|
+
const { ensureSourcesCloned } = await import('../ensure-sources-SL2S4UEX.js');
|
|
6342
|
+
const hydrate = ensureSourcesCloned(resolved, { quiet: true });
|
|
6343
|
+
for (const n of hydrate.cloned) created.push(`~/.skaile/sources/${n}/`);
|
|
6344
|
+
if (hydrate.failed.length > 0) {
|
|
6345
|
+
logErr(`Failed to clone source(s): ${hydrate.failed.join(", ")}`);
|
|
6346
|
+
}
|
|
6347
|
+
} catch (err) {
|
|
6348
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6349
|
+
console.log(` ${S.dim(`\u26A0 source hydration skipped: ${msg}`)}`);
|
|
6350
|
+
}
|
|
6351
|
+
for (const c of created) console.log(` ${S.dim(`+ ${c}`)}`);
|
|
6352
|
+
logOk(`Initialized project at ${S.heading(resolved)}`);
|
|
6353
|
+
console.log();
|
|
6354
|
+
console.log(S.heading(" Next steps:"));
|
|
6355
|
+
const isCurrentDir = resolved === path14__default.resolve(".");
|
|
6356
|
+
let step = 1;
|
|
6357
|
+
if (!isCurrentDir) {
|
|
6358
|
+
console.log(` ${S.dim(`${step}.`)} ${S.cmd(`cd ${projectDir}`)}`);
|
|
6073
6359
|
step++;
|
|
6074
|
-
console.log(` ${S.dim(`${step}.`)} ${S.cmd("skaile install")}`);
|
|
6075
|
-
console.log();
|
|
6076
6360
|
}
|
|
6077
|
-
);
|
|
6361
|
+
console.log(` ${S.dim(`${step}.`)} Edit ${S.cmd("skaile.yaml")} to add dependencies`);
|
|
6362
|
+
step++;
|
|
6363
|
+
console.log(` ${S.dim(`${step}.`)} ${S.cmd("skaile install")}`);
|
|
6364
|
+
console.log();
|
|
6365
|
+
});
|
|
6078
6366
|
program.command("setup").description("Interactive provider setup wizard").action(async () => {
|
|
6079
|
-
const { cmdSetup } = await import('../setup-
|
|
6367
|
+
const { cmdSetup } = await import('../setup-GBSQX7JF.js');
|
|
6080
6368
|
await cmdSetup([], { projectDir: process.cwd() });
|
|
6081
6369
|
});
|
|
6082
6370
|
program.addCommand(makeInstallCommand());
|
|
@@ -6105,7 +6393,9 @@ program.addCommand(makeReplCommand());
|
|
|
6105
6393
|
program.addCommand(makeResumeCommand());
|
|
6106
6394
|
program.addCommand(makeServeCommand());
|
|
6107
6395
|
program.addCommand(makeMcpServerCommand());
|
|
6396
|
+
program.addCommand(makeIntegrationCommand());
|
|
6108
6397
|
program.addCommand(makePluginCommand());
|
|
6398
|
+
program.addCommand(makeDeployCommand());
|
|
6109
6399
|
program.addCommand(makeDebugCommand());
|
|
6110
6400
|
program.addCommand(makeConnectCommand());
|
|
6111
6401
|
program.addCommand(makeLogsCommand());
|