@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
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { scanDirectory, fromMcpServerMd } from './chunk-
|
|
2
|
-
import { parseAssetRef } from './chunk-
|
|
3
|
-
import { mkdirSync, existsSync, readFileSync, writeFileSync, lstatSync, symlinkSync, rmSync, readdirSync } from 'fs';
|
|
1
|
+
import { scanDirectory, parseFrontmatter, fromMcpServerMd } from './chunk-4AZKT2BU.js';
|
|
2
|
+
import { parseAssetRef } from './chunk-I3UEM3FX.js';
|
|
3
|
+
import { mkdirSync, existsSync, readFileSync, writeFileSync, lstatSync, symlinkSync, rmSync, readdirSync, statSync } from 'fs';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
|
-
import { join, resolve, parse as parse$1, dirname } from 'path';
|
|
5
|
+
import { join, resolve, relative, parse as parse$1, dirname } from 'path';
|
|
6
6
|
import { parse, stringify } from 'yaml';
|
|
7
7
|
import { spawnSync } from 'child_process';
|
|
8
|
+
import semver from 'semver';
|
|
9
|
+
import { createHash } from 'crypto';
|
|
10
|
+
import fg from 'fast-glob';
|
|
8
11
|
|
|
9
12
|
function getGlobalCacheDir() {
|
|
10
13
|
return process.env.SKAILE_CACHE_DIR ?? join(homedir(), ".skaile", "repos");
|
|
@@ -162,8 +165,8 @@ function scanRepo(repoDir, repoName) {
|
|
|
162
165
|
}
|
|
163
166
|
function resolveAsset(ref, repositories, reposDir, opts) {
|
|
164
167
|
let repoNames;
|
|
165
|
-
if (ref.
|
|
166
|
-
repoNames = [ref.
|
|
168
|
+
if (ref.publisher) {
|
|
169
|
+
repoNames = [ref.publisher];
|
|
167
170
|
} else if (opts?.preferRepo && opts.preferRepo in repositories) {
|
|
168
171
|
const rest = Object.keys(repositories).filter((n) => n !== opts.preferRepo);
|
|
169
172
|
repoNames = [opts.preferRepo, ...rest];
|
|
@@ -199,67 +202,149 @@ function resolveRepoDir(decl, name, reposDir, projectDir) {
|
|
|
199
202
|
if (existsSync(join(globalDest, ".git"))) return globalDest;
|
|
200
203
|
return null;
|
|
201
204
|
}
|
|
202
|
-
|
|
205
|
+
var CanonicalRefConflictError = class extends Error {
|
|
206
|
+
constructor(ref, candidates, depChain) {
|
|
207
|
+
super(
|
|
208
|
+
[
|
|
209
|
+
`error: divergent sha256 for ${ref}`,
|
|
210
|
+
"",
|
|
211
|
+
" pulled in via:",
|
|
212
|
+
...depChain.map((s, i) => ` ${" ".repeat(i * 2)}${s}`),
|
|
213
|
+
"",
|
|
214
|
+
" candidates:",
|
|
215
|
+
...candidates.map(
|
|
216
|
+
(c) => ` ${c.sourceUrl} @ ${c.commit.slice(0, 8)}
|
|
217
|
+
sha256: ${c.sha256}`
|
|
218
|
+
),
|
|
219
|
+
"",
|
|
220
|
+
"resolve by:",
|
|
221
|
+
" 1. removing one source from skaile.yaml,",
|
|
222
|
+
" 2. configuring a store and using its canonical digest, or",
|
|
223
|
+
" 3. adding to overrides: (with a non-empty reason:)"
|
|
224
|
+
].join("\n")
|
|
225
|
+
);
|
|
226
|
+
this.ref = ref;
|
|
227
|
+
this.candidates = candidates;
|
|
228
|
+
this.depChain = depChain;
|
|
229
|
+
this.name = "CanonicalRefConflictError";
|
|
230
|
+
}
|
|
231
|
+
ref;
|
|
232
|
+
candidates;
|
|
233
|
+
depChain;
|
|
234
|
+
};
|
|
235
|
+
var SHA_PIN_RE = /^[0-9a-f]{40}$/i;
|
|
236
|
+
async function resolveAll(deps, opts) {
|
|
203
237
|
const resolved = [];
|
|
204
238
|
const seen = /* @__PURE__ */ new Set();
|
|
205
239
|
const missing = [];
|
|
206
240
|
const resolvedBy = /* @__PURE__ */ new Map();
|
|
207
|
-
|
|
241
|
+
const overridesApplied = /* @__PURE__ */ new Set();
|
|
242
|
+
const overridesByRef = new Map(opts.overrides.map((o) => [o.ref, o]));
|
|
243
|
+
async function visit(refStr, parent, depChain) {
|
|
208
244
|
const ref = parseAssetRef(refStr);
|
|
209
|
-
|
|
245
|
+
if (!ref.publisher) throw new Error(`dep "${refStr}" missing publisher`);
|
|
246
|
+
const key = `${ref.publisher}/${ref.kind}:${ref.name}`;
|
|
210
247
|
if (seen.has(key)) return;
|
|
211
248
|
seen.add(key);
|
|
212
|
-
const
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
249
|
+
const sourceCandidates = opts.provenanceIndex.get(key) ?? [];
|
|
250
|
+
const storeCandidates = [];
|
|
251
|
+
if (opts.stores.length > 0 && opts.storeFetcher) {
|
|
252
|
+
const candidateVersions = enumerateVersionsForPin(
|
|
253
|
+
ref.pin,
|
|
254
|
+
sourceCandidates.map((c) => c.version)
|
|
255
|
+
);
|
|
256
|
+
for (const store of opts.stores) {
|
|
257
|
+
for (const v of candidateVersions) {
|
|
258
|
+
if (!v) continue;
|
|
259
|
+
const m = await opts.storeFetcher.getInstallManifest(
|
|
260
|
+
store.url,
|
|
261
|
+
`${ref.publisher}/${ref.kind}:${ref.name}@${v}`
|
|
262
|
+
);
|
|
263
|
+
if (m) {
|
|
264
|
+
storeCandidates.push({
|
|
265
|
+
publisher: ref.publisher,
|
|
266
|
+
kind: ref.kind,
|
|
267
|
+
name: ref.name,
|
|
268
|
+
version: v,
|
|
269
|
+
sourceUrl: m.sourceUrl,
|
|
270
|
+
commit: m.commit,
|
|
271
|
+
files: m.files,
|
|
272
|
+
sha256: m.sha256
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const all = [...sourceCandidates, ...storeCandidates];
|
|
279
|
+
if (all.length === 0) {
|
|
218
280
|
missing.push(refStr);
|
|
219
281
|
return;
|
|
220
282
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
283
|
+
const filtered = all.filter((c) => matchPin(ref.pin, c.version));
|
|
284
|
+
if (filtered.length === 0) {
|
|
285
|
+
missing.push(refStr);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const versions = Array.from(new Set(filtered.map((c) => c.version)));
|
|
289
|
+
const best = versions.sort((a, b) => semver.rcompare(coerceVersion(a), coerceVersion(b)))[0];
|
|
290
|
+
const finalists = filtered.filter((c) => c.version === best);
|
|
291
|
+
const canonicalRef = `${ref.publisher}/${ref.kind}:${ref.name}@${best}`;
|
|
292
|
+
const uniqueShas = Array.from(new Set(finalists.map((c) => c.sha256)));
|
|
293
|
+
let chosen;
|
|
294
|
+
if (uniqueShas.length > 1) {
|
|
295
|
+
const override = overridesByRef.get(canonicalRef);
|
|
296
|
+
if (!override) {
|
|
297
|
+
throw new CanonicalRefConflictError(canonicalRef, finalists, [...depChain, refStr]);
|
|
298
|
+
}
|
|
299
|
+
const pick = finalists.find((c) => c.sourceUrl === override.source);
|
|
300
|
+
if (!pick) {
|
|
301
|
+
throw new Error(
|
|
302
|
+
`override for ${canonicalRef} points at ${override.source}, which is not among the resolved candidates`
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
chosen = pick;
|
|
306
|
+
overridesApplied.add(canonicalRef);
|
|
307
|
+
} else {
|
|
308
|
+
chosen = [...finalists].sort((a, b) => a.sourceUrl.localeCompare(b.sourceUrl))[0];
|
|
225
309
|
}
|
|
226
|
-
|
|
227
|
-
|
|
310
|
+
if (opts.storeFetcher && opts.stores.length > 0 && sourceCandidates.some((c) => c.version === best) && storeCandidates.some((c) => c.version === best)) {
|
|
311
|
+
for (const store of opts.stores) {
|
|
312
|
+
const d = await opts.storeFetcher.getCanonicalDigest(store.url, canonicalRef);
|
|
313
|
+
if (d && d.sha256 !== chosen.sha256) {
|
|
314
|
+
throw new CanonicalRefConflictError(
|
|
315
|
+
canonicalRef,
|
|
316
|
+
[...finalists, { ...chosen, sourceUrl: store.url, sha256: d.sha256 }],
|
|
317
|
+
[...depChain, refStr]
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
228
321
|
}
|
|
229
|
-
resolved.push(
|
|
322
|
+
resolved.push(chosen);
|
|
323
|
+
resolvedBy.set(key, parent);
|
|
230
324
|
}
|
|
231
325
|
for (const dep of deps) {
|
|
232
|
-
visit(dep, "direct");
|
|
326
|
+
await visit(dep, "direct", []);
|
|
233
327
|
}
|
|
234
|
-
|
|
235
|
-
return { resolved, missing, resolvedBy, collisions };
|
|
328
|
+
return { resolved, missing, resolvedBy, overridesApplied };
|
|
236
329
|
}
|
|
237
|
-
function
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
const collisions = [];
|
|
249
|
-
for (const entry of resolved) {
|
|
250
|
-
const key = `${entry.kind}:${entry.name}`;
|
|
251
|
-
const shadowedIn = [];
|
|
252
|
-
for (const [repoName, entries] of repoEntries) {
|
|
253
|
-
if (repoName === entry.repository) continue;
|
|
254
|
-
if (entries.some((e) => e.kind === entry.kind && e.name === entry.name)) {
|
|
255
|
-
shadowedIn.push(repoName);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
if (shadowedIn.length > 0 && entry.repository) {
|
|
259
|
-
collisions.push({ key, resolvedFrom: entry.repository, shadowedIn });
|
|
260
|
-
}
|
|
330
|
+
function coerceVersion(v) {
|
|
331
|
+
return semver.valid(v) ? v : semver.coerce(v)?.version ?? "0.0.0";
|
|
332
|
+
}
|
|
333
|
+
function matchPin(pin, version) {
|
|
334
|
+
if (!pin) return true;
|
|
335
|
+
if (SHA_PIN_RE.test(pin)) {
|
|
336
|
+
return version === `0.0.0-sha.${pin.slice(0, 7)}`;
|
|
337
|
+
}
|
|
338
|
+
if (version.startsWith("0.0.0-sha.")) {
|
|
339
|
+
return version === pin;
|
|
261
340
|
}
|
|
262
|
-
return
|
|
341
|
+
if (!semver.valid(version)) return version === pin;
|
|
342
|
+
return semver.satisfies(version, pin, { includePrerelease: false });
|
|
343
|
+
}
|
|
344
|
+
function enumerateVersionsForPin(pin, sourceVersionsHint) {
|
|
345
|
+
if (!pin) return sourceVersionsHint.length > 0 ? sourceVersionsHint : [];
|
|
346
|
+
if (semver.valid(pin)) return [pin];
|
|
347
|
+
return sourceVersionsHint;
|
|
263
348
|
}
|
|
264
349
|
function checkRepoStatus(decl, name, reposDir, projectDir) {
|
|
265
350
|
if (projectDir) {
|
|
@@ -320,8 +405,185 @@ function checkRepoStatus(decl, name, reposDir, projectDir) {
|
|
|
320
405
|
base.upToDate = base.behind === 0;
|
|
321
406
|
return base;
|
|
322
407
|
}
|
|
408
|
+
function fileSha256(p) {
|
|
409
|
+
return createHash("sha256").update(readFileSync(p)).digest("hex");
|
|
410
|
+
}
|
|
411
|
+
function compositeSha256(files) {
|
|
412
|
+
const lines = files.slice().sort((a, b) => a.path.localeCompare(b.path)).map((f) => `${f.path}:${f.sha256}
|
|
413
|
+
`).join("");
|
|
414
|
+
return createHash("sha256").update(lines).digest("hex");
|
|
415
|
+
}
|
|
416
|
+
function publisherFromGithubUrl(url) {
|
|
417
|
+
const m = url.match(/github\.com[/:]([^/]+)\/[^/]+/);
|
|
418
|
+
return m?.[1];
|
|
419
|
+
}
|
|
420
|
+
function syntheticVersion(commit) {
|
|
421
|
+
return `0.0.0-sha.${commit.slice(0, 7)}`;
|
|
422
|
+
}
|
|
423
|
+
var KIND_DIRS = [
|
|
424
|
+
{ dir: "skills", kind: "skill", mdName: "SKILL.md" },
|
|
425
|
+
{ dir: "agents", kind: "agent", mdName: "AGENT.md" },
|
|
426
|
+
{ dir: "bundles", kind: "bundle", mdName: "BUNDLE.md" },
|
|
427
|
+
{ dir: "mcp-servers", kind: "mcp-server", mdName: "MCP.md" },
|
|
428
|
+
{ dir: "connectors", kind: "connector", mdName: "CONNECTOR.md" },
|
|
429
|
+
{ dir: "prompts", kind: "prompt", mdName: "PROMPT.md" },
|
|
430
|
+
{ dir: "contracts", kind: "contract", mdName: "CONTRACT.md" }
|
|
431
|
+
];
|
|
432
|
+
var MD_FILE_BY_KIND = Object.fromEntries(
|
|
433
|
+
KIND_DIRS.map((k) => [k.kind, k.mdName])
|
|
434
|
+
);
|
|
435
|
+
function buildProvenanceIndex(clones, _opts) {
|
|
436
|
+
const index = /* @__PURE__ */ new Map();
|
|
437
|
+
for (const clone of clones) walkOne(clone, index);
|
|
438
|
+
return index;
|
|
439
|
+
}
|
|
440
|
+
function walkOne(clone, index) {
|
|
441
|
+
const yamlPath = join(clone.localPath, "skaile.yaml");
|
|
442
|
+
if (existsSync(yamlPath)) {
|
|
443
|
+
walkWithManifest(clone, yamlPath, index);
|
|
444
|
+
} else {
|
|
445
|
+
walkFilenameConvention(clone, index);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
function walkWithManifest(clone, yamlPath, index) {
|
|
449
|
+
const raw = parse(readFileSync(yamlPath, "utf8")) ?? {};
|
|
450
|
+
const publisher = typeof raw.publisher === "string" && raw.publisher.length > 0 ? raw.publisher : publisherFromGithubUrl(clone.sourceUrl);
|
|
451
|
+
if (!publisher) {
|
|
452
|
+
throw new Error(
|
|
453
|
+
`${clone.sourceUrl}: publisher must be declared in skaile.yaml (non-GitHub source URL \u2014 auto-derivation not available).`
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
const sourceVersion = (typeof raw.version === "string" ? raw.version : void 0) ?? (clone.tag ? clone.tag.replace(/^v/, "") : void 0) ?? syntheticVersion(clone.commit);
|
|
457
|
+
const assets = Array.isArray(raw.assets) ? raw.assets : [];
|
|
458
|
+
if (assets.length === 0) {
|
|
459
|
+
walkFilenameConvention(clone, index, publisher, sourceVersion);
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
for (const a of assets) {
|
|
463
|
+
const assetPublisher = a.publisher ?? publisher;
|
|
464
|
+
const version = a.version ?? sourceVersion;
|
|
465
|
+
const files = expandAssetFiles(clone.localPath, a);
|
|
466
|
+
verifyNameMatch(clone.localPath, files, a.name, a.kind);
|
|
467
|
+
const metadata = readMetadata(clone.localPath, files, a.kind);
|
|
468
|
+
const candidate = {
|
|
469
|
+
publisher: assetPublisher,
|
|
470
|
+
kind: a.kind,
|
|
471
|
+
name: a.name,
|
|
472
|
+
version,
|
|
473
|
+
sourceUrl: clone.sourceUrl,
|
|
474
|
+
commit: clone.commit,
|
|
475
|
+
files,
|
|
476
|
+
sha256: compositeSha256(files),
|
|
477
|
+
metadata
|
|
478
|
+
};
|
|
479
|
+
push(index, `${assetPublisher}/${a.kind}:${a.name}`, candidate);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
function expandAssetFiles(repoRoot, a) {
|
|
483
|
+
const out = [];
|
|
484
|
+
if (a.root) {
|
|
485
|
+
walkDirRecursive(join(repoRoot, a.root), repoRoot, out);
|
|
486
|
+
}
|
|
487
|
+
if (a.files) {
|
|
488
|
+
const matches = fg.sync(a.files, { cwd: repoRoot, onlyFiles: true, dot: false });
|
|
489
|
+
for (const rel of matches) {
|
|
490
|
+
out.push({ path: rel, sha256: fileSha256(join(repoRoot, rel)) });
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
const seen = /* @__PURE__ */ new Set();
|
|
494
|
+
return out.filter((f) => seen.has(f.path) ? false : (seen.add(f.path), true));
|
|
495
|
+
}
|
|
496
|
+
function walkDirRecursive(abs, root, out) {
|
|
497
|
+
if (!existsSync(abs)) return;
|
|
498
|
+
for (const entry of readdirSync(abs, { withFileTypes: true })) {
|
|
499
|
+
if (entry.name === ".git" || entry.name === "node_modules") continue;
|
|
500
|
+
const childAbs = join(abs, entry.name);
|
|
501
|
+
if (entry.isDirectory()) {
|
|
502
|
+
walkDirRecursive(childAbs, root, out);
|
|
503
|
+
} else if (entry.isFile()) {
|
|
504
|
+
out.push({ path: relative(root, childAbs), sha256: fileSha256(childAbs) });
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
function walkFilenameConvention(clone, index, publisherOverride, versionOverride) {
|
|
509
|
+
const publisher = publisherOverride ?? publisherFromGithubUrl(clone.sourceUrl);
|
|
510
|
+
if (!publisher) {
|
|
511
|
+
throw new Error(
|
|
512
|
+
`${clone.sourceUrl}: publisher must be declared in skaile.yaml (non-GitHub source URL).`
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
const version = versionOverride ?? (clone.tag ? clone.tag.replace(/^v/, "") : void 0) ?? syntheticVersion(clone.commit);
|
|
516
|
+
for (const { dir, kind, mdName } of KIND_DIRS) {
|
|
517
|
+
const base = join(clone.localPath, dir);
|
|
518
|
+
if (!existsSync(base) || !statSync(base).isDirectory()) continue;
|
|
519
|
+
for (const entry of readdirSync(base, { withFileTypes: true })) {
|
|
520
|
+
if (!entry.isDirectory()) continue;
|
|
521
|
+
const assetDir = join(base, entry.name);
|
|
522
|
+
if (!existsSync(join(assetDir, mdName))) continue;
|
|
523
|
+
const files = [];
|
|
524
|
+
walkDirRecursive(assetDir, clone.localPath, files);
|
|
525
|
+
const metadata = readMetadata(clone.localPath, files, kind);
|
|
526
|
+
const candidate = {
|
|
527
|
+
publisher,
|
|
528
|
+
kind,
|
|
529
|
+
name: entry.name,
|
|
530
|
+
version,
|
|
531
|
+
sourceUrl: clone.sourceUrl,
|
|
532
|
+
commit: clone.commit,
|
|
533
|
+
files,
|
|
534
|
+
sha256: compositeSha256(files),
|
|
535
|
+
metadata
|
|
536
|
+
};
|
|
537
|
+
push(index, `${publisher}/${kind}:${entry.name}`, candidate);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
function verifyNameMatch(repoRoot, files, expectedName, kind) {
|
|
542
|
+
const mdName = MD_FILE_BY_KIND[kind];
|
|
543
|
+
if (!mdName) return;
|
|
544
|
+
const md = files.find((f) => f.path.endsWith(mdName));
|
|
545
|
+
if (!md) return;
|
|
546
|
+
const { data } = parseFrontmatter(readFileSync(join(repoRoot, md.path), "utf8"));
|
|
547
|
+
const declared = typeof data.name === "string" ? data.name : void 0;
|
|
548
|
+
if (declared && declared !== expectedName) {
|
|
549
|
+
throw new Error(
|
|
550
|
+
`name mismatch: ${mdName} says "${declared}", skaile.yaml says "${expectedName}" \u2014 index-time hard error.`
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
function readMetadata(repoRoot, files, kind) {
|
|
555
|
+
if (kind !== "mcp-server") return void 0;
|
|
556
|
+
const mcpMd = files.find((f) => f.path.endsWith("MCP.md"));
|
|
557
|
+
if (!mcpMd) return void 0;
|
|
558
|
+
const { data } = parseFrontmatter(readFileSync(join(repoRoot, mcpMd.path), "utf8"));
|
|
559
|
+
return data;
|
|
560
|
+
}
|
|
561
|
+
function push(index, key, candidate) {
|
|
562
|
+
const arr = index.get(key) ?? [];
|
|
563
|
+
arr.push(candidate);
|
|
564
|
+
index.set(key, arr);
|
|
565
|
+
}
|
|
323
566
|
|
|
324
567
|
// core/src/workspace-config.ts
|
|
568
|
+
var DEFAULT_RECIPE_ATTR = "default";
|
|
569
|
+
function validateAssetRecipeFlake(flake) {
|
|
570
|
+
if (typeof flake !== "string" || flake.length === 0) {
|
|
571
|
+
throw new Error("AssetRecipe.flake must be a non-empty string");
|
|
572
|
+
}
|
|
573
|
+
if (flake.length > 500) {
|
|
574
|
+
throw new Error(`AssetRecipe.flake too long (${flake.length} chars, max 500)`);
|
|
575
|
+
}
|
|
576
|
+
if (flake === ".") return;
|
|
577
|
+
const ALLOWED_SCHEME = /^(github:|git\+https:\/\/|git\+ssh:\/\/|path:\/)/;
|
|
578
|
+
if (!ALLOWED_SCHEME.test(flake)) {
|
|
579
|
+
throw new Error(
|
|
580
|
+
`AssetRecipe.flake "${flake}" has an unsupported source. Allowed: "." or a flake URL (github:, git+https://, git+ssh://, path:/).`
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
if (/[\s`$;|&<>(){}#\n\r]/.test(flake)) {
|
|
584
|
+
throw new Error(`AssetRecipe.flake "${flake}" contains forbidden characters.`);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
325
587
|
function validateAssetRecipeAttr(attr) {
|
|
326
588
|
if (typeof attr !== "string" || attr.length === 0) {
|
|
327
589
|
throw new Error("AssetRecipe.attr must be a non-empty string");
|
|
@@ -401,13 +663,20 @@ function listSkWorkspaceConfigs(dir) {
|
|
|
401
663
|
function resolveSkWorkspaceConfig(projectDir, opts) {
|
|
402
664
|
const name = opts?.name ?? SK_WORKSPACE_DEFAULT_NAME;
|
|
403
665
|
const configs = [];
|
|
666
|
+
const assertNoLegacyKey = (file) => {
|
|
667
|
+
const d = file?.diagnostics?.find((x) => x.code === "legacy_key_rejected");
|
|
668
|
+
if (d) throw new Error(d.message);
|
|
669
|
+
};
|
|
404
670
|
const userConfig = loadSkWorkspaceConfig(join(homedir(), ".skaile"), name);
|
|
671
|
+
assertNoLegacyKey(userConfig);
|
|
405
672
|
if (userConfig) configs.push(userConfig.config);
|
|
406
673
|
if (opts?.appDir) {
|
|
407
674
|
const appConfig = loadSkWorkspaceConfig(opts.appDir, name);
|
|
675
|
+
assertNoLegacyKey(appConfig);
|
|
408
676
|
if (appConfig) configs.push(appConfig.config);
|
|
409
677
|
}
|
|
410
678
|
const projectConfig = loadSkWorkspaceConfig(projectDir, name);
|
|
679
|
+
assertNoLegacyKey(projectConfig);
|
|
411
680
|
if (projectConfig) configs.push(projectConfig.config);
|
|
412
681
|
if (configs.length > 0) return configs.reduce(mergeSkWorkspaceConfigs);
|
|
413
682
|
return {};
|
|
@@ -443,10 +712,12 @@ function mergeSkWorkspaceConfigs(base, overlay) {
|
|
|
443
712
|
},
|
|
444
713
|
// startup: overlay wins (project-level only)
|
|
445
714
|
startup: overlay.startup ?? base.startup,
|
|
446
|
-
//
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
715
|
+
// publication half — scalars: overlay wins when defined; assets: by kind+name
|
|
716
|
+
publisher: overlay.publisher ?? base.publisher,
|
|
717
|
+
version: overlay.version ?? base.version,
|
|
718
|
+
assets: dedupeByKey(
|
|
719
|
+
[...base.assets ?? [], ...overlay.assets ?? []],
|
|
720
|
+
(a) => `${a.kind}:${a.name}`
|
|
450
721
|
),
|
|
451
722
|
// mounts: by id — overlay wins
|
|
452
723
|
mounts: mergeById(base.mounts ?? [], overlay.mounts ?? []),
|
|
@@ -511,14 +782,18 @@ function mergeSkWorkspaceConfigs(base, overlay) {
|
|
|
511
782
|
secrets: overlay.secrets ?? base.secrets,
|
|
512
783
|
// telemetry: overlay wins entirely (raw pass-through)
|
|
513
784
|
telemetry: overlay.telemetry ?? base.telemetry,
|
|
514
|
-
// repositories: always empty in merged output; the schema no longer
|
|
515
|
-
// accepts this key. The internal install pipeline builds its own map
|
|
516
|
-
// from `ai_resources[]` entries.
|
|
517
|
-
repositories: {},
|
|
518
785
|
// dependencies: concatenate and dedupe
|
|
519
786
|
dependencies: dedupe([...base.dependencies ?? [], ...overlay.dependencies ?? []]),
|
|
520
|
-
// sources: dedupe by
|
|
521
|
-
sources: dedupeByKey([...base.sources ?? [], ...overlay.sources ?? []], "
|
|
787
|
+
// sources: dedupe by url — overlay entry wins for the same url
|
|
788
|
+
sources: dedupeByKey([...base.sources ?? [], ...overlay.sources ?? []], "url"),
|
|
789
|
+
// stores: dedupe by url — overlay wins
|
|
790
|
+
stores: dedupeByKey([...base.stores ?? [], ...overlay.stores ?? []], "url"),
|
|
791
|
+
// overrides: dedupe by ref — overlay wins
|
|
792
|
+
overrides: dedupeByKey([...base.overrides ?? [], ...overlay.overrides ?? []], "ref"),
|
|
793
|
+
// plugins: concatenate + dedupe (like dependencies)
|
|
794
|
+
plugins: dedupe([...base.plugins ?? [], ...overlay.plugins ?? []]),
|
|
795
|
+
// deploy: overlay wins entirely (scalar-like selection)
|
|
796
|
+
deploy: overlay.deploy ?? base.deploy
|
|
522
797
|
};
|
|
523
798
|
}
|
|
524
799
|
var KNOWN_DRIVERS = ["omp", "claude-sdk", "codex"];
|
|
@@ -596,46 +871,75 @@ function normalizeConfigInternal(raw) {
|
|
|
596
871
|
if (Array.isArray(raw.startup)) {
|
|
597
872
|
config.startup = raw.startup;
|
|
598
873
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
aiResKey = "ai_resources";
|
|
604
|
-
} else if (raw.aiResources !== void 0) {
|
|
605
|
-
aiResRaw = raw.aiResources;
|
|
606
|
-
aiResKey = "aiResources";
|
|
607
|
-
}
|
|
608
|
-
if (aiResKey === "aiResources") {
|
|
609
|
-
diagnostics.push({
|
|
610
|
-
code: "legacy_key_camelcase",
|
|
611
|
-
severity: "warning",
|
|
612
|
-
message: 'Non-canonical key "aiResources" \u2014 use "ai_resources".',
|
|
613
|
-
path: "aiResources"
|
|
614
|
-
});
|
|
874
|
+
if (raw.repositories !== void 0) {
|
|
875
|
+
throw new Error(
|
|
876
|
+
"skaile.yaml: unknown top-level key `repositories:`. The schema changed in @skaile/workspaces 4.x \u2014 see docs/concepts/manifest-schema.md, or ask your AI assistant to apply the `migrate-skaile-manifest` skill."
|
|
877
|
+
);
|
|
615
878
|
}
|
|
616
|
-
if (
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
const
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
if (
|
|
635
|
-
|
|
636
|
-
if (
|
|
637
|
-
|
|
638
|
-
|
|
879
|
+
if (raw.ai_resources !== void 0 || raw.aiResources !== void 0) {
|
|
880
|
+
throw new Error(
|
|
881
|
+
"skaile.yaml: unknown top-level key `ai_resources:`. The schema changed in @skaile/workspaces 4.x \u2014 see docs/concepts/manifest-schema.md, or ask your AI assistant to apply the `migrate-skaile-manifest` skill."
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
if (typeof raw.publisher === "string" && raw.publisher.length > 0) {
|
|
885
|
+
config.publisher = raw.publisher;
|
|
886
|
+
}
|
|
887
|
+
if (typeof raw.version === "string" && raw.version.length > 0) {
|
|
888
|
+
config.version = raw.version;
|
|
889
|
+
}
|
|
890
|
+
if (Array.isArray(raw.assets)) {
|
|
891
|
+
const entries = [];
|
|
892
|
+
for (const item of raw.assets) {
|
|
893
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
894
|
+
const a = item;
|
|
895
|
+
const kind = typeof a.kind === "string" ? a.kind : "";
|
|
896
|
+
const name = typeof a.name === "string" ? a.name : "";
|
|
897
|
+
if (!kind || !name) continue;
|
|
898
|
+
const entry = { kind, name };
|
|
899
|
+
if (typeof a.root === "string") entry.root = a.root;
|
|
900
|
+
if (Array.isArray(a.files)) {
|
|
901
|
+
entry.files = a.files.filter(
|
|
902
|
+
(f) => typeof f === "string"
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
if (typeof a.version === "string") entry.version = a.version;
|
|
906
|
+
if (typeof a.publisher === "string") entry.publisher = a.publisher;
|
|
907
|
+
entries.push(entry);
|
|
908
|
+
}
|
|
909
|
+
if (entries.length > 0) config.assets = entries;
|
|
910
|
+
}
|
|
911
|
+
if (Array.isArray(raw.stores)) {
|
|
912
|
+
const entries = [];
|
|
913
|
+
for (const item of raw.stores) {
|
|
914
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
915
|
+
const s = item;
|
|
916
|
+
const url = typeof s.url === "string" ? s.url : "";
|
|
917
|
+
if (!url) continue;
|
|
918
|
+
entries.push({ url });
|
|
919
|
+
}
|
|
920
|
+
if (entries.length > 0) config.stores = entries;
|
|
921
|
+
}
|
|
922
|
+
if (Array.isArray(raw.overrides)) {
|
|
923
|
+
const entries = [];
|
|
924
|
+
for (const item of raw.overrides) {
|
|
925
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
926
|
+
const o = item;
|
|
927
|
+
const ref = typeof o.ref === "string" ? o.ref : "";
|
|
928
|
+
const source = typeof o.source === "string" ? o.source : "";
|
|
929
|
+
if (!ref || !source) continue;
|
|
930
|
+
if (typeof o.reason !== "string") {
|
|
931
|
+
throw new Error(
|
|
932
|
+
`skaile.yaml: overrides[] entry for ${ref}: reason is required and must be a non-empty string.`
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
if (o.reason.trim().length === 0) {
|
|
936
|
+
throw new Error(
|
|
937
|
+
`skaile.yaml: overrides[] entry for ${ref}: reason must not be empty.`
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
entries.push({ ref, source, reason: o.reason });
|
|
941
|
+
}
|
|
942
|
+
if (entries.length > 0) config.overrides = entries;
|
|
639
943
|
}
|
|
640
944
|
if (Array.isArray(raw.mounts)) {
|
|
641
945
|
config.mounts = raw.mounts;
|
|
@@ -646,6 +950,17 @@ function normalizeConfigInternal(raw) {
|
|
|
646
950
|
if (Array.isArray(raw.mcp_servers)) {
|
|
647
951
|
config.mcp_servers = raw.mcp_servers;
|
|
648
952
|
}
|
|
953
|
+
if (Array.isArray(raw.plugins)) {
|
|
954
|
+
const specs = raw.plugins.filter((p) => typeof p === "string" && p.length > 0);
|
|
955
|
+
if (specs.length > 0) config.plugins = specs;
|
|
956
|
+
}
|
|
957
|
+
if (raw.deploy && typeof raw.deploy === "object" && !Array.isArray(raw.deploy)) {
|
|
958
|
+
const d = raw.deploy;
|
|
959
|
+
if (typeof d.target === "string" && d.target.length > 0) {
|
|
960
|
+
config.deploy = { target: d.target };
|
|
961
|
+
if (d.config !== void 0) config.deploy.config = d.config;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
649
964
|
if (raw.agent) config.agent = raw.agent;
|
|
650
965
|
if (raw.workspace) config.workspace = raw.workspace;
|
|
651
966
|
if (raw.secrets && typeof raw.secrets === "object") {
|
|
@@ -663,13 +978,12 @@ function normalizeConfigInternal(raw) {
|
|
|
663
978
|
if (Array.isArray(raw.sources)) {
|
|
664
979
|
const entries = [];
|
|
665
980
|
for (const item of raw.sources) {
|
|
666
|
-
if (!item || typeof item !== "object") continue;
|
|
981
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
667
982
|
const s = item;
|
|
668
|
-
const name = typeof s.name === "string" ? s.name : "";
|
|
669
983
|
const url = typeof s.url === "string" ? s.url : "";
|
|
670
|
-
if (!
|
|
671
|
-
const entry = {
|
|
672
|
-
if (typeof s.
|
|
984
|
+
if (!url) continue;
|
|
985
|
+
const entry = { url };
|
|
986
|
+
if (typeof s.pin === "string" && s.pin.length > 0) entry.pin = s.pin;
|
|
673
987
|
entries.push(entry);
|
|
674
988
|
}
|
|
675
989
|
if (entries.length > 0) config.sources = entries;
|
|
@@ -707,7 +1021,21 @@ function decodeSkaileYaml(text) {
|
|
|
707
1021
|
]
|
|
708
1022
|
};
|
|
709
1023
|
}
|
|
710
|
-
|
|
1024
|
+
let result;
|
|
1025
|
+
try {
|
|
1026
|
+
result = normalizeConfigInternal(parsed);
|
|
1027
|
+
} catch (err) {
|
|
1028
|
+
return {
|
|
1029
|
+
config: {},
|
|
1030
|
+
diagnostics: [
|
|
1031
|
+
{
|
|
1032
|
+
code: "legacy_key_rejected",
|
|
1033
|
+
severity: "error",
|
|
1034
|
+
message: err instanceof Error ? err.message : String(err)
|
|
1035
|
+
}
|
|
1036
|
+
]
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
711
1039
|
validateConfigValues(result.config, result.diagnostics);
|
|
712
1040
|
return result;
|
|
713
1041
|
}
|
|
@@ -749,21 +1077,26 @@ function validateConfigValues(config, diagnostics) {
|
|
|
749
1077
|
var CANONICAL_KEY_ORDER = [
|
|
750
1078
|
"name",
|
|
751
1079
|
"description",
|
|
1080
|
+
"publisher",
|
|
1081
|
+
"version",
|
|
1082
|
+
"assets",
|
|
752
1083
|
"agent_config",
|
|
753
1084
|
"dependencies",
|
|
1085
|
+
"plugins",
|
|
754
1086
|
"sources",
|
|
1087
|
+
"stores",
|
|
1088
|
+
"overrides",
|
|
755
1089
|
"startup",
|
|
756
|
-
"ai_resources",
|
|
757
1090
|
"connectors",
|
|
758
1091
|
"mcp_servers",
|
|
1092
|
+
"deploy",
|
|
759
1093
|
"mounts",
|
|
760
1094
|
"agent",
|
|
761
1095
|
"workspace",
|
|
762
1096
|
"secrets",
|
|
763
1097
|
"telemetry",
|
|
764
1098
|
"compaction",
|
|
765
|
-
"patches"
|
|
766
|
-
"repositories"
|
|
1099
|
+
"patches"
|
|
767
1100
|
];
|
|
768
1101
|
var CONFIG_KEY_TO_YAML = {
|
|
769
1102
|
agent_config: "agent-config"
|
|
@@ -797,10 +1130,11 @@ function dedupe(arr) {
|
|
|
797
1130
|
return [...new Set(arr)];
|
|
798
1131
|
}
|
|
799
1132
|
function dedupeByKey(arr, key) {
|
|
1133
|
+
const keyOf = typeof key === "function" ? key : (item) => String(item[key] ?? "");
|
|
800
1134
|
const seen = /* @__PURE__ */ new Set();
|
|
801
1135
|
const result = [];
|
|
802
1136
|
for (let i = arr.length - 1; i >= 0; i--) {
|
|
803
|
-
const val =
|
|
1137
|
+
const val = keyOf(arr[i]);
|
|
804
1138
|
if (!seen.has(val)) {
|
|
805
1139
|
seen.add(val);
|
|
806
1140
|
result.unshift(arr[i]);
|
|
@@ -837,13 +1171,22 @@ function mcpDeclFromCatalogEntry(entry) {
|
|
|
837
1171
|
if (entry.description) decl.description = entry.description;
|
|
838
1172
|
if (m.recipe && typeof m.recipe === "object" && !Array.isArray(m.recipe)) {
|
|
839
1173
|
const r = m.recipe;
|
|
840
|
-
|
|
1174
|
+
const hasFlake = typeof r.flake === "string";
|
|
1175
|
+
const rawAttr = typeof r.attr === "string" ? r.attr : void 0;
|
|
1176
|
+
const effectiveAttr = rawAttr ?? (hasFlake ? DEFAULT_RECIPE_ATTR : void 0);
|
|
1177
|
+
if (effectiveAttr !== void 0) {
|
|
841
1178
|
try {
|
|
842
|
-
validateAssetRecipeAttr(
|
|
843
|
-
|
|
1179
|
+
validateAssetRecipeAttr(effectiveAttr);
|
|
1180
|
+
if (hasFlake) {
|
|
1181
|
+
validateAssetRecipeFlake(r.flake);
|
|
1182
|
+
decl.recipe = { attr: effectiveAttr, flake: r.flake };
|
|
1183
|
+
if (typeof r.publisher === "string") decl.recipe.publisher = r.publisher;
|
|
1184
|
+
} else {
|
|
1185
|
+
decl.recipe = { attr: effectiveAttr };
|
|
1186
|
+
}
|
|
844
1187
|
} catch (err) {
|
|
845
1188
|
console.warn(
|
|
846
|
-
`[workspace-config] mcpDeclFromCatalogEntry: invalid recipe
|
|
1189
|
+
`[workspace-config] mcpDeclFromCatalogEntry: invalid recipe for entry "${entry.name}": ${err instanceof Error ? err.message : String(err)}`
|
|
847
1190
|
);
|
|
848
1191
|
}
|
|
849
1192
|
}
|
|
@@ -915,33 +1258,49 @@ function loadMaterializedMcpDeclarations(projectDir) {
|
|
|
915
1258
|
}
|
|
916
1259
|
return result;
|
|
917
1260
|
}
|
|
1261
|
+
function sourceSlug(url) {
|
|
1262
|
+
return url.replace(/\.git$/, "").split(/[/:]/).pop() ?? "source";
|
|
1263
|
+
}
|
|
1264
|
+
function buildSourceClones(sources) {
|
|
1265
|
+
const home = process.env.SKAILE_HOME ?? join(homedir(), ".skaile");
|
|
1266
|
+
const sourcesDir = join(home, "sources");
|
|
1267
|
+
const clones = [];
|
|
1268
|
+
for (const s of sources) {
|
|
1269
|
+
const localPath = join(sourcesDir, sourceSlug(s.url));
|
|
1270
|
+
if (!existsSync(localPath)) continue;
|
|
1271
|
+
const commit = getRepoCommit(localPath) ?? "0".repeat(40);
|
|
1272
|
+
clones.push({ localPath, sourceUrl: s.url, commit, tag: s.pin });
|
|
1273
|
+
}
|
|
1274
|
+
return clones;
|
|
1275
|
+
}
|
|
1276
|
+
function catalogEntryFromCandidate(c) {
|
|
1277
|
+
const md = c.metadata ?? {};
|
|
1278
|
+
return {
|
|
1279
|
+
name: c.name,
|
|
1280
|
+
kind: c.kind,
|
|
1281
|
+
description: typeof md.description === "string" ? md.description : "",
|
|
1282
|
+
source: c.files[0]?.path ?? "",
|
|
1283
|
+
publisher: c.publisher,
|
|
1284
|
+
version: c.version,
|
|
1285
|
+
requires: [],
|
|
1286
|
+
dependencies: [],
|
|
1287
|
+
metadata: c.metadata
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
918
1290
|
function loadMcpServerDeclarations(projectDir) {
|
|
919
1291
|
const config = resolveSkWorkspaceConfig(projectDir);
|
|
920
1292
|
const explicit = config.mcp_servers ?? [];
|
|
921
1293
|
const materialized = loadMaterializedMcpDeclarations(projectDir);
|
|
922
1294
|
const mcpRefStrings = [];
|
|
923
1295
|
for (const dep of config.dependencies ?? []) {
|
|
924
|
-
|
|
925
|
-
if (ref.kind === "mcp-server") mcpRefStrings.push(dep);
|
|
926
|
-
}
|
|
927
|
-
for (const res of config.ai_resources ?? []) {
|
|
928
|
-
for (const dep of res.dependencies ?? []) {
|
|
1296
|
+
try {
|
|
929
1297
|
const ref = parseAssetRef(dep);
|
|
930
1298
|
if (ref.kind === "mcp-server") mcpRefStrings.push(dep);
|
|
1299
|
+
} catch {
|
|
931
1300
|
}
|
|
932
1301
|
}
|
|
933
|
-
const
|
|
934
|
-
const
|
|
935
|
-
for (const res of config.ai_resources ?? []) {
|
|
936
|
-
if (res.name && res.path && !(res.name in allRepos)) {
|
|
937
|
-
allRepos[res.name] = {
|
|
938
|
-
url: res.path.startsWith("/") ? void 0 : res.path,
|
|
939
|
-
path: res.path.startsWith("/") ? res.path : void 0,
|
|
940
|
-
branch: res.branch
|
|
941
|
-
};
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
const reposDir = getGlobalCacheDir();
|
|
1302
|
+
const sources = config.sources ?? [];
|
|
1303
|
+
const provenanceIndex = sources.length > 0 ? buildProvenanceIndex(buildSourceClones(sources)) : /* @__PURE__ */ new Map();
|
|
945
1304
|
const byId = /* @__PURE__ */ new Map();
|
|
946
1305
|
const order = [];
|
|
947
1306
|
const upsert = (decl) => {
|
|
@@ -955,12 +1314,29 @@ function loadMcpServerDeclarations(projectDir) {
|
|
|
955
1314
|
};
|
|
956
1315
|
const seen = /* @__PURE__ */ new Set();
|
|
957
1316
|
for (const refStr of mcpRefStrings) {
|
|
958
|
-
|
|
1317
|
+
let ref;
|
|
1318
|
+
try {
|
|
1319
|
+
ref = parseAssetRef(refStr);
|
|
1320
|
+
} catch {
|
|
1321
|
+
continue;
|
|
1322
|
+
}
|
|
959
1323
|
if (seen.has(ref.name)) continue;
|
|
960
1324
|
seen.add(ref.name);
|
|
961
|
-
|
|
962
|
-
if (
|
|
963
|
-
|
|
1325
|
+
let candidates;
|
|
1326
|
+
if (ref.publisher) {
|
|
1327
|
+
candidates = provenanceIndex.get(`${ref.publisher}/${ref.kind}:${ref.name}`);
|
|
1328
|
+
}
|
|
1329
|
+
if (!candidates) {
|
|
1330
|
+
for (const [key, arr] of provenanceIndex) {
|
|
1331
|
+
if (key.endsWith(`/${ref.kind}:${ref.name}`)) {
|
|
1332
|
+
candidates = arr;
|
|
1333
|
+
break;
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
const candidate = candidates?.[0];
|
|
1338
|
+
if (!candidate) continue;
|
|
1339
|
+
const catalogDecl = mcpDeclFromCatalogEntry(catalogEntryFromCandidate(candidate));
|
|
964
1340
|
if (!catalogDecl) continue;
|
|
965
1341
|
upsert(catalogDecl);
|
|
966
1342
|
}
|
|
@@ -994,16 +1370,11 @@ function resolveAgentDir(projectDir) {
|
|
|
994
1370
|
return join(aiAssetsDir, relPath);
|
|
995
1371
|
}
|
|
996
1372
|
if (definition.startsWith("agent:")) {
|
|
997
|
-
|
|
998
|
-
const repositories = config.repositories ?? {};
|
|
999
|
-
const reposDir = getGlobalCacheDir();
|
|
1000
|
-
const entry = resolveAsset(ref, repositories, reposDir, { projectDir });
|
|
1001
|
-
if (!entry) return void 0;
|
|
1002
|
-
return dirname(entry.source);
|
|
1373
|
+
return void 0;
|
|
1003
1374
|
}
|
|
1004
1375
|
return resolve(projectDir, definition);
|
|
1005
1376
|
}
|
|
1006
1377
|
|
|
1007
|
-
export { COMPACTION_DEFAULTS, SKAILE_YAML_DEFAULT, SKAILE_YAML_SUFFIX, SK_WORKSPACE_DEFAULT_NAME, SK_WORKSPACE_SUFFIX, checkRepoStatus, checkoutPin, cloneRepo, decodeSkaileYaml, encodeSkaileYaml, ensureRepo, findWorkspaceRoot, getGlobalCacheDir, getRepoCommit, isWorkspaceConfigFilename, linkRepo, listSkWorkspaceConfigs, loadMcpServerDeclarations, loadSkWorkspaceConfig, mergeSkWorkspaceConfigs, normalizeConfig, pullRepo, readLinks, resolveAgentDir, resolveAll, resolveAsset, resolveSkWorkspaceConfig, saveSkWorkspaceConfig, scanRepo, unlinkRepo, validateAssetRecipeAttr, workspaceConfigFilename, workspaceNameFromFilename, writeLinks };
|
|
1008
|
-
//# sourceMappingURL=chunk-
|
|
1009
|
-
//# sourceMappingURL=chunk-
|
|
1378
|
+
export { COMPACTION_DEFAULTS, CanonicalRefConflictError, DEFAULT_RECIPE_ATTR, SKAILE_YAML_DEFAULT, SKAILE_YAML_SUFFIX, SK_WORKSPACE_DEFAULT_NAME, SK_WORKSPACE_SUFFIX, buildProvenanceIndex, checkRepoStatus, checkoutPin, cloneRepo, decodeSkaileYaml, encodeSkaileYaml, ensureRepo, findWorkspaceRoot, getGlobalCacheDir, getRepoCommit, isWorkspaceConfigFilename, linkRepo, listSkWorkspaceConfigs, loadMcpServerDeclarations, loadSkWorkspaceConfig, mergeSkWorkspaceConfigs, normalizeConfig, pullRepo, readLinks, resolveAgentDir, resolveAll, resolveAsset, resolveSkWorkspaceConfig, saveSkWorkspaceConfig, scanRepo, unlinkRepo, validateAssetRecipeAttr, validateAssetRecipeFlake, workspaceConfigFilename, workspaceNameFromFilename, writeLinks };
|
|
1379
|
+
//# sourceMappingURL=chunk-J3VKAEQP.js.map
|
|
1380
|
+
//# sourceMappingURL=chunk-J3VKAEQP.js.map
|