@skaile/workspaces 1.16.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +309 -0
- package/dist/{asset-feeds-WIBEP37F.js → asset-feeds-FBGBQEYD.js} +25 -24
- package/dist/asset-feeds-FBGBQEYD.js.map +1 -0
- package/dist/asset-manager/catalog-deployer.js +13 -1
- package/dist/asset-manager/index.js +10 -9
- package/dist/asset-manager/installer.js +7 -6
- package/dist/asset-manager/src/catalog-deployer.d.ts +70 -5
- package/dist/asset-manager/src/catalog-deployer.d.ts.map +1 -1
- package/dist/asset-manager/src/index.d.ts +41 -17
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/mcp-config.d.ts +58 -0
- package/dist/asset-manager/src/mcp-config.d.ts.map +1 -0
- package/dist/bridge/drivers/claude-sdk.js +108 -56
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +3 -2
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/continue.js +4 -3
- package/dist/bridge/drivers/continue.js.map +1 -1
- package/dist/bridge/drivers/echo.js +3 -2
- package/dist/bridge/drivers/echo.js.map +1 -1
- package/dist/bridge/drivers/gemini.js +5 -4
- package/dist/bridge/drivers/goose.js +4 -3
- package/dist/bridge/drivers/goose.js.map +1 -1
- package/dist/bridge/drivers/omp.js +3 -2
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/drivers/opencode.js +4 -3
- package/dist/bridge/drivers/opencode.js.map +1 -1
- package/dist/bridge/drivers/qwen.js +5 -4
- package/dist/bridge/drivers/qwen.js.map +1 -1
- package/dist/bridge/index.js +4 -3
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/scrub-transcript.d.ts +21 -1
- package/dist/bridge/src/drivers/scrub-transcript.d.ts.map +1 -1
- package/dist/{chunk-MO43URUI.js → chunk-2BSXXTUP.js} +7 -7
- package/dist/{chunk-MO43URUI.js.map → chunk-2BSXXTUP.js.map} +1 -1
- package/dist/{chunk-FIUGSIKC.js → chunk-43TAGQ3Z.js} +19 -11
- package/dist/chunk-43TAGQ3Z.js.map +1 -0
- package/dist/{chunk-7J7LQP6T.js → chunk-5BGEYZ7I.js} +31 -19
- package/dist/chunk-5BGEYZ7I.js.map +1 -0
- package/dist/chunk-7GOCNYUV.js +300 -0
- package/dist/chunk-7GOCNYUV.js.map +1 -0
- package/dist/{chunk-KY5NY7LB.js → chunk-BCTU4TN7.js} +11 -11
- package/dist/chunk-BCTU4TN7.js.map +1 -0
- package/dist/chunk-BEAIJRVF.js +159 -0
- package/dist/chunk-BEAIJRVF.js.map +1 -0
- package/dist/{chunk-2TSSCHCQ.js → chunk-BHLNQ4L5.js} +5 -5
- package/dist/{chunk-2TSSCHCQ.js.map → chunk-BHLNQ4L5.js.map} +1 -1
- package/dist/chunk-BK3WL3QK.js +10 -0
- package/dist/chunk-BK3WL3QK.js.map +1 -0
- package/dist/{chunk-TFIFNDT2.js → chunk-BTR3ZJ7S.js} +4 -4
- package/dist/{chunk-TFIFNDT2.js.map → chunk-BTR3ZJ7S.js.map} +1 -1
- package/dist/{chunk-BI2NKPA4.js → chunk-CA5CWLGN.js} +3 -2
- package/dist/chunk-CA5CWLGN.js.map +1 -0
- package/dist/{chunk-STQOPWPS.js → chunk-CTWE7I7Z.js} +4 -4
- package/dist/{chunk-STQOPWPS.js.map → chunk-CTWE7I7Z.js.map} +1 -1
- package/dist/{chunk-GXC3TYMQ.js → chunk-CZZRDYT4.js} +70 -32
- package/dist/chunk-CZZRDYT4.js.map +1 -0
- package/dist/chunk-DYMWJAL4.js +552 -0
- package/dist/chunk-DYMWJAL4.js.map +1 -0
- package/dist/{chunk-ACXLKNIM.js → chunk-E7HKNQTH.js} +10 -4
- package/dist/chunk-E7HKNQTH.js.map +1 -0
- package/dist/{chunk-2BQBWWFX.js → chunk-GUKMNUQK.js} +6 -6
- package/dist/chunk-GUKMNUQK.js.map +1 -0
- package/dist/{chunk-6POODADP.js → chunk-HOL5KD7U.js} +453 -250
- package/dist/chunk-HOL5KD7U.js.map +1 -0
- package/dist/{chunk-C4KVFALU.js → chunk-L26NGI43.js} +3 -3
- package/dist/{chunk-C4KVFALU.js.map → chunk-L26NGI43.js.map} +1 -1
- package/dist/{chunk-MZV6WCF3.js → chunk-MAN7AGQJ.js} +3 -3
- package/dist/{chunk-MZV6WCF3.js.map → chunk-MAN7AGQJ.js.map} +1 -1
- package/dist/{chunk-YULV7UTU.js → chunk-MLYV6WEM.js} +10 -10
- package/dist/{chunk-YULV7UTU.js.map → chunk-MLYV6WEM.js.map} +1 -1
- package/dist/{chunk-O5VCUU6D.js → chunk-N6TYW6EB.js} +4 -4
- package/dist/{chunk-O5VCUU6D.js.map → chunk-N6TYW6EB.js.map} +1 -1
- package/dist/{chunk-EPWY2ABE.js → chunk-PSVF3LDU.js} +5 -5
- package/dist/{chunk-EPWY2ABE.js.map → chunk-PSVF3LDU.js.map} +1 -1
- package/dist/{chunk-M5GJT3D7.js → chunk-PYYL5XMA.js} +3 -3
- package/dist/{chunk-M5GJT3D7.js.map → chunk-PYYL5XMA.js.map} +1 -1
- package/dist/{chunk-BG4XVMG2.js → chunk-RBOPTTTK.js} +286 -151
- package/dist/chunk-RBOPTTTK.js.map +1 -0
- package/dist/{chunk-2IJFUAZB.js → chunk-RK3HU3H3.js} +123 -18
- package/dist/chunk-RK3HU3H3.js.map +1 -0
- package/dist/{chunk-5NZ56R63.js → chunk-RTLQAZAE.js} +18 -6
- package/dist/chunk-RTLQAZAE.js.map +1 -0
- package/dist/{chunk-MNKUZUN2.js → chunk-SGLGA2AZ.js} +3 -3
- package/dist/{chunk-MNKUZUN2.js.map → chunk-SGLGA2AZ.js.map} +1 -1
- package/dist/{chunk-JB35MVBN.js → chunk-U5POE4BA.js} +4 -298
- package/dist/chunk-U5POE4BA.js.map +1 -0
- package/dist/{chunk-A22KZ7GZ.js → chunk-VPXBAEWE.js} +274 -40
- package/dist/chunk-VPXBAEWE.js.map +1 -0
- package/dist/{chunk-ACWCVB5Q.js → chunk-WVPL4OGD.js} +3 -3
- package/dist/{chunk-ACWCVB5Q.js.map → chunk-WVPL4OGD.js.map} +1 -1
- package/dist/{chunk-MB6563TL.js → chunk-XQVP6XWR.js} +3 -3
- package/dist/{chunk-MB6563TL.js.map → chunk-XQVP6XWR.js.map} +1 -1
- package/dist/{chunk-344DEXZS.js → chunk-XSIXGVH6.js} +4 -4
- package/dist/{chunk-344DEXZS.js.map → chunk-XSIXGVH6.js.map} +1 -1
- package/dist/{chunk-BYS6JDZB.js → chunk-Y6VSFX2A.js} +3 -3
- package/dist/{chunk-BYS6JDZB.js.map → chunk-Y6VSFX2A.js.map} +1 -1
- package/dist/{chunk-ISA7R7PK.js → chunk-YODP3STD.js} +90 -40
- package/dist/chunk-YODP3STD.js.map +1 -0
- package/dist/{chunk-WSTY3AWY.js → chunk-ZWFLEMI4.js} +4 -4
- package/dist/{chunk-WSTY3AWY.js.map → chunk-ZWFLEMI4.js.map} +1 -1
- package/dist/cli/index.js +347 -127
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/asset-feeds.d.ts +2 -2
- package/dist/cli/src/asset-feeds.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +51 -2
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/connector.d.ts +1 -1
- package/dist/cli/src/commands/connector.d.ts.map +1 -1
- package/dist/cli/src/commands/logs.d.ts.map +1 -1
- package/dist/cli/src/commands/manage.d.ts +30 -3
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts +5 -2
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/connectors/config.js +7 -6
- package/dist/connectors/index.js +8 -7
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/connectors/src/watcher.d.ts.map +1 -1
- package/dist/connectors/src/worktree.d.ts +20 -2
- package/dist/connectors/src/worktree.d.ts.map +1 -1
- package/dist/core/index.js +6 -5
- package/dist/core/logging.js +2 -1
- package/dist/core/manifest.js +2 -1
- package/dist/core/runtime-assets.js +4 -3
- package/dist/core/src/fs-deadline.d.ts +84 -0
- package/dist/core/src/fs-deadline.d.ts.map +1 -0
- package/dist/core/src/index.d.ts +4 -3
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +142 -18
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts +2 -2
- 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/subprocess.d.ts +33 -1
- package/dist/core/src/subprocess.d.ts.map +1 -1
- package/dist/core/src/walker.d.ts +1 -1
- package/dist/core/src/walker.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +19 -2
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/workspace-config.js +3 -2
- package/dist/deploy/index.js +12 -7
- package/dist/deploy/index.js.map +1 -1
- package/dist/deploy/src/targets/container-runtime.d.ts.map +1 -1
- package/dist/discovery/index.js +3 -2
- package/dist/{ensure-sources-RSTZONIE.js → ensure-sources-AVCVX7CV.js} +13 -12
- package/dist/ensure-sources-AVCVX7CV.js.map +1 -0
- package/dist/factory-assets/connectors/box.js +8 -7
- package/dist/factory-assets/connectors/deploy/CONNECTOR.md +19 -0
- package/dist/factory-assets/connectors/deploy/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/deploy.js +8 -7
- package/dist/factory-assets/connectors/devserver/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/devserver.js +8 -7
- package/dist/factory-assets/connectors/flow/adapter.js +8 -7
- package/dist/factory-assets/connectors/flow/engine.js +6 -5
- package/dist/factory-assets/connectors/flow/run-flow.js +10 -9
- package/dist/factory-assets/connectors/flow.js +8 -7
- package/dist/factory-assets/connectors/git/driver.d.ts +12 -1
- package/dist/factory-assets/connectors/git/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/git.js +8 -7
- package/dist/factory-assets/connectors/gmail.js +8 -7
- package/dist/factory-assets/connectors/googledrive.js +8 -7
- package/dist/factory-assets/connectors/local/driver.d.ts +25 -1
- package/dist/factory-assets/connectors/local/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/local.js +8 -7
- package/dist/factory-assets/connectors/mattermost.js +8 -7
- package/dist/factory-assets/connectors/memory.js +8 -7
- package/dist/factory-assets/connectors/minio.js +8 -7
- package/dist/factory-assets/connectors/postgres.js +8 -7
- package/dist/factory-assets/connectors/s3/driver.d.ts +15 -0
- package/dist/factory-assets/connectors/s3/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/s3.js +8 -7
- package/dist/factory-assets/connectors/sharepoint.js +8 -7
- package/dist/factory-assets/connectors/sqlite/adapter.d.ts +8 -1
- package/dist/factory-assets/connectors/sqlite/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/sqlite.js +8 -7
- package/dist/factory-assets/connectors/static-server/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/static-server.js +8 -7
- package/dist/factory-assets/connectors/tunnel.js +8 -7
- package/dist/factory-assets/connectors/webdav.js +8 -7
- package/dist/factory-assets/connectors/xstate/adapter.d.ts +6 -0
- package/dist/factory-assets/connectors/xstate/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/xstate-store.js +8 -7
- package/dist/factory-assets/connectors/xstate.js +8 -7
- package/dist/flows-CXVFGR27.js +20 -0
- package/dist/{flows-FHWBCLXF.js.map → flows-CXVFGR27.js.map} +1 -1
- package/dist/{helpers-GUUWPPAX.js → helpers-M5SXB4LL.js} +13 -12
- package/dist/{helpers-GUUWPPAX.js.map → helpers-M5SXB4LL.js.map} +1 -1
- package/dist/library/index.js +8 -7
- package/dist/library/install.js +6 -5
- package/dist/{library-publish-UKKSJP7V.js → library-publish-HVIIQMI6.js} +16 -15
- package/dist/library-publish-HVIIQMI6.js.map +1 -0
- package/dist/{open-library-VALRYGFV.js → open-library-EJQISBWV.js} +14 -13
- package/dist/{open-library-VALRYGFV.js.map → open-library-EJQISBWV.js.map} +1 -1
- package/dist/{paths-5QJJBAND.js → paths-2HMHL25W.js} +11 -10
- package/dist/{paths-5QJJBAND.js.map → paths-2HMHL25W.js.map} +1 -1
- package/dist/plugin-registry/src/deploy-helpers.d.ts +1 -1
- package/dist/{plugin-store-ZBJZ7F6D.js → plugin-store-TLBQ5XRS.js} +8 -7
- package/dist/plugin-store-TLBQ5XRS.js.map +1 -0
- package/dist/{project-IRUJLIVX.js → project-M2COJFPZ.js} +14 -13
- package/dist/{project-IRUJLIVX.js.map → project-M2COJFPZ.js.map} +1 -1
- package/dist/resolver/index.js +13 -1
- package/dist/resolver/src/types.d.ts +7 -0
- package/dist/resolver/src/types.d.ts.map +1 -1
- package/dist/resolver/src/validator.d.ts +8 -1
- package/dist/resolver/src/validator.d.ts.map +1 -1
- package/dist/runner/index.js +13 -12
- package/dist/runner/src/external-mcp.d.ts +1 -1
- package/dist/runner/src/external-mcp.d.ts.map +1 -1
- package/dist/runner/src/mcp-prompt.d.ts +7 -3
- package/dist/runner/src/mcp-prompt.d.ts.map +1 -1
- package/dist/runner/src/mcp-runtime-handlers.d.ts +12 -0
- package/dist/runner/src/mcp-runtime-handlers.d.ts.map +1 -1
- package/dist/runner/src/mixin-resolver.d.ts.map +1 -1
- package/dist/runner/src/recipe-resolver.d.ts +20 -6
- package/dist/runner/src/recipe-resolver.d.ts.map +1 -1
- package/dist/runner/src/resource-handler.d.ts +43 -0
- package/dist/runner/src/resource-handler.d.ts.map +1 -1
- package/dist/runner/src/resources.d.ts +12 -5
- package/dist/runner/src/resources.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts +31 -5
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts +9 -0
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/runner/src/session-capability-wiring.d.ts +5 -0
- package/dist/runner/src/session-capability-wiring.d.ts.map +1 -1
- package/dist/runner/src/workspace-migration.d.ts +37 -3
- package/dist/runner/src/workspace-migration.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +10 -9
- package/dist/sdk/bridge.js +4 -3
- package/dist/sdk/core.js +6 -5
- package/dist/sdk/flow.js +6 -5
- package/dist/sdk/index.js +13 -12
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.js +13 -1
- package/dist/sdk/runner.js +13 -12
- package/dist/sdk/session.js +1 -1
- package/dist/sdk/store.js +1 -1
- package/dist/session/index.js +1 -1
- package/dist/session/src/dispatcher.d.ts.map +1 -1
- package/dist/{setup-WJPNUE32.js → setup-GWXEG3G2.js} +10 -9
- package/dist/setup-GWXEG3G2.js.map +1 -0
- package/dist/skills-YTMGG23D.js +20 -0
- package/dist/{skills-BMI6H7HI.js.map → skills-YTMGG23D.js.map} +1 -1
- package/dist/{source-5KDURFBS.js → source-WMXH2OBW.js} +15 -14
- package/dist/{source-5KDURFBS.js.map → source-WMXH2OBW.js.map} +1 -1
- package/dist/{source-manifest-publish-DPQI44D3.js → source-manifest-publish-MTHUGBAY.js} +17 -16
- package/dist/source-manifest-publish-MTHUGBAY.js.map +1 -0
- package/dist/store/index.js +1 -1
- package/dist/store/src/store.d.ts +9 -0
- package/dist/store/src/store.d.ts.map +1 -1
- package/dist/tui/index.js +13 -12
- package/dist/tui/index.js.map +1 -1
- package/dist/validator-RN64BKFW.js +5 -0
- package/dist/{validator-VF5M764T.js.map → validator-RN64BKFW.js.map} +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +18 -5
- package/dist/workspace-plugin/adapters/mcp.js.map +1 -1
- package/dist/workspace-plugin/adapters/omp.js +10 -10
- package/dist/workspace-plugin/index.js +3 -2
- package/dist/workspace-plugin/src/tools/validator.d.ts.map +1 -1
- package/dist/workspace-plugin/src/utils/ai-assets.d.ts +11 -6
- package/dist/workspace-plugin/src/utils/ai-assets.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/asset-feeds-WIBEP37F.js.map +0 -1
- package/dist/chunk-2BQBWWFX.js.map +0 -1
- package/dist/chunk-2IJFUAZB.js.map +0 -1
- package/dist/chunk-5NZ56R63.js.map +0 -1
- package/dist/chunk-6POODADP.js.map +0 -1
- package/dist/chunk-7J7LQP6T.js.map +0 -1
- package/dist/chunk-A22KZ7GZ.js.map +0 -1
- package/dist/chunk-ACXLKNIM.js.map +0 -1
- package/dist/chunk-BG4XVMG2.js.map +0 -1
- package/dist/chunk-BI2NKPA4.js.map +0 -1
- package/dist/chunk-BQCGFPHW.js +0 -345
- package/dist/chunk-BQCGFPHW.js.map +0 -1
- package/dist/chunk-FIUGSIKC.js.map +0 -1
- package/dist/chunk-GXC3TYMQ.js.map +0 -1
- package/dist/chunk-ISA7R7PK.js.map +0 -1
- package/dist/chunk-JB35MVBN.js.map +0 -1
- package/dist/chunk-KY5NY7LB.js.map +0 -1
- package/dist/chunk-LV2HPH3C.js +0 -73
- package/dist/chunk-LV2HPH3C.js.map +0 -1
- package/dist/chunk-XCBG2KDC.js +0 -23
- package/dist/chunk-XCBG2KDC.js.map +0 -1
- package/dist/ensure-sources-RSTZONIE.js.map +0 -1
- package/dist/flows-FHWBCLXF.js +0 -7
- package/dist/library-publish-UKKSJP7V.js.map +0 -1
- package/dist/plugin-store-ZBJZ7F6D.js.map +0 -1
- package/dist/setup-WJPNUE32.js.map +0 -1
- package/dist/skills-BMI6H7HI.js +0 -7
- package/dist/source-manifest-publish-DPQI44D3.js.map +0 -1
- package/dist/validator-VF5M764T.js +0 -5
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { ulid } from 'ulid';
|
|
3
|
+
|
|
4
|
+
// core/src/logging/log-store.ts
|
|
5
|
+
var LEVEL_RANK = {
|
|
6
|
+
debug: 10,
|
|
7
|
+
info: 20,
|
|
8
|
+
warn: 30,
|
|
9
|
+
error: 40
|
|
10
|
+
};
|
|
11
|
+
var LogStore = class {
|
|
12
|
+
sessionId;
|
|
13
|
+
level;
|
|
14
|
+
sinks;
|
|
15
|
+
flushIntervalMs;
|
|
16
|
+
flushBatchSize;
|
|
17
|
+
buffer = [];
|
|
18
|
+
timer = null;
|
|
19
|
+
emitter = new EventEmitter();
|
|
20
|
+
closed = false;
|
|
21
|
+
constructor(opts) {
|
|
22
|
+
this.sessionId = opts.sessionId;
|
|
23
|
+
this.level = opts.level;
|
|
24
|
+
this.sinks = opts.sinks;
|
|
25
|
+
this.flushIntervalMs = opts.flushIntervalMs ?? 50;
|
|
26
|
+
this.flushBatchSize = opts.flushBatchSize ?? 100;
|
|
27
|
+
this.emitter.setMaxListeners(0);
|
|
28
|
+
}
|
|
29
|
+
getLevel() {
|
|
30
|
+
return this.level;
|
|
31
|
+
}
|
|
32
|
+
setLevel(level) {
|
|
33
|
+
this.level = level;
|
|
34
|
+
}
|
|
35
|
+
/** Append a sink after construction. Used by bridges (e.g. OnLogBridgeSink). */
|
|
36
|
+
addSink(sink) {
|
|
37
|
+
this.sinks.push(sink);
|
|
38
|
+
}
|
|
39
|
+
/** Returns true if the level is enabled. Used by createLogger to short-circuit. */
|
|
40
|
+
isEnabled(level) {
|
|
41
|
+
return LEVEL_RANK[level] >= LEVEL_RANK[this.level];
|
|
42
|
+
}
|
|
43
|
+
record(input) {
|
|
44
|
+
if (this.closed) return;
|
|
45
|
+
if (!this.isEnabled(input.level)) return;
|
|
46
|
+
const entry = {
|
|
47
|
+
id: ulid(),
|
|
48
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
49
|
+
sessionId: this.sessionId,
|
|
50
|
+
source: input.source,
|
|
51
|
+
level: input.level,
|
|
52
|
+
message: input.message,
|
|
53
|
+
data: input.data,
|
|
54
|
+
error: input.error
|
|
55
|
+
};
|
|
56
|
+
this.emitter.emit("entry", entry);
|
|
57
|
+
this.buffer.push(entry);
|
|
58
|
+
if (this.buffer.length >= this.flushBatchSize) {
|
|
59
|
+
this.flushSync();
|
|
60
|
+
} else if (this.flushIntervalMs > 0 && this.timer === null) {
|
|
61
|
+
this.timer = setTimeout(() => this.flushSync(), this.flushIntervalMs);
|
|
62
|
+
} else if (this.flushIntervalMs === 0) {
|
|
63
|
+
this.flushSync();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Subscribe to live entries. Returns an unsubscribe function. */
|
|
67
|
+
subscribe(handler) {
|
|
68
|
+
this.emitter.on("entry", handler);
|
|
69
|
+
return () => this.emitter.off("entry", handler);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Query stored log entries.
|
|
73
|
+
*
|
|
74
|
+
* Queries the first sink that supports querying (typically SQLiteSink).
|
|
75
|
+
* Returns empty result if no sink supports querying.
|
|
76
|
+
*
|
|
77
|
+
* @param q - Query parameters including filters and pagination
|
|
78
|
+
* @returns Query result with matching entries
|
|
79
|
+
*/
|
|
80
|
+
query(q) {
|
|
81
|
+
for (const sink of this.sinks) {
|
|
82
|
+
if (sink.query) return sink.query(q);
|
|
83
|
+
}
|
|
84
|
+
return { entries: [] };
|
|
85
|
+
}
|
|
86
|
+
/** Force-flush. SQLite writes are synchronous, so this returns once writes complete. */
|
|
87
|
+
flush() {
|
|
88
|
+
this.flushSync();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Close the log store and release resources.
|
|
92
|
+
*
|
|
93
|
+
* Flushes any pending entries, marks the store as closed, and closes
|
|
94
|
+
* all registered sinks.
|
|
95
|
+
*/
|
|
96
|
+
close() {
|
|
97
|
+
if (this.closed) return;
|
|
98
|
+
this.flushSync();
|
|
99
|
+
this.closed = true;
|
|
100
|
+
if (this.timer) {
|
|
101
|
+
clearTimeout(this.timer);
|
|
102
|
+
this.timer = null;
|
|
103
|
+
}
|
|
104
|
+
for (const sink of this.sinks) sink.close();
|
|
105
|
+
this.emitter.removeAllListeners();
|
|
106
|
+
}
|
|
107
|
+
flushSync() {
|
|
108
|
+
if (this.timer) {
|
|
109
|
+
clearTimeout(this.timer);
|
|
110
|
+
this.timer = null;
|
|
111
|
+
}
|
|
112
|
+
if (this.buffer.length === 0) return;
|
|
113
|
+
const batch = this.buffer;
|
|
114
|
+
this.buffer = [];
|
|
115
|
+
for (const sink of this.sinks) {
|
|
116
|
+
try {
|
|
117
|
+
sink.writeBatch(batch);
|
|
118
|
+
} catch (err) {
|
|
119
|
+
process.stderr.write(`LogStore sink write failed: ${String(err)}
|
|
120
|
+
`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// core/src/logging/sinks/types.ts
|
|
127
|
+
var LogStoreDisabledError = class extends Error {
|
|
128
|
+
constructor() {
|
|
129
|
+
super("LogStore is disabled (mode=off); query is unavailable");
|
|
130
|
+
this.name = "LogStoreDisabledError";
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// core/src/logging/sinks/no-op-sink.ts
|
|
135
|
+
var NoOpSink = class {
|
|
136
|
+
write(_entry) {
|
|
137
|
+
}
|
|
138
|
+
writeBatch(_entries) {
|
|
139
|
+
}
|
|
140
|
+
query(_q) {
|
|
141
|
+
throw new LogStoreDisabledError();
|
|
142
|
+
}
|
|
143
|
+
close() {
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// core/src/logging/sinks/stdout-sink.ts
|
|
148
|
+
function formatSource(source) {
|
|
149
|
+
const parts = [source.kind, source.subkind];
|
|
150
|
+
if (source.instance) parts.push(source.instance);
|
|
151
|
+
return `[${parts.join(":")}]`;
|
|
152
|
+
}
|
|
153
|
+
function formatTime(iso) {
|
|
154
|
+
return iso.slice(11, 23);
|
|
155
|
+
}
|
|
156
|
+
var LEVEL_LABEL = {
|
|
157
|
+
debug: "DEBUG",
|
|
158
|
+
info: "INFO ",
|
|
159
|
+
warn: "WARN ",
|
|
160
|
+
error: "ERROR"
|
|
161
|
+
};
|
|
162
|
+
var StdoutSink = class {
|
|
163
|
+
format;
|
|
164
|
+
stream;
|
|
165
|
+
constructor(opts = {}) {
|
|
166
|
+
this.stream = opts.stream === "stderr" ? process.stderr : process.stdout;
|
|
167
|
+
this.format = opts.format ?? (this.stream.isTTY ? "pretty" : "json");
|
|
168
|
+
}
|
|
169
|
+
write(entry) {
|
|
170
|
+
this.stream.write(`${this.render(entry)}
|
|
171
|
+
`);
|
|
172
|
+
}
|
|
173
|
+
writeBatch(entries) {
|
|
174
|
+
for (const e of entries) this.write(e);
|
|
175
|
+
}
|
|
176
|
+
close() {
|
|
177
|
+
}
|
|
178
|
+
render(entry) {
|
|
179
|
+
if (this.format === "json") {
|
|
180
|
+
return JSON.stringify(entry);
|
|
181
|
+
}
|
|
182
|
+
const head = `${formatTime(entry.timestamp)} ${LEVEL_LABEL[entry.level]} ${formatSource(entry.source)}`;
|
|
183
|
+
const tail = entry.message;
|
|
184
|
+
const detail = entry.data ? `
|
|
185
|
+
> ${JSON.stringify(entry.data)}` : "";
|
|
186
|
+
const err = entry.error ? `
|
|
187
|
+
! ${entry.error.name}: ${entry.error.message}` : "";
|
|
188
|
+
return `${head} ${tail}${detail}${err}`;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
// core/src/logging/sanitize.ts
|
|
193
|
+
function normalizeError(value) {
|
|
194
|
+
if (value === void 0 || value === null) return void 0;
|
|
195
|
+
if (value instanceof Error) {
|
|
196
|
+
return {
|
|
197
|
+
name: value.name,
|
|
198
|
+
message: value.message,
|
|
199
|
+
stack: value.stack
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
if (typeof value === "string") {
|
|
203
|
+
return { name: "Error", message: value };
|
|
204
|
+
}
|
|
205
|
+
try {
|
|
206
|
+
return { name: "Error", message: JSON.stringify(value) };
|
|
207
|
+
} catch {
|
|
208
|
+
return { name: "Error", message: String(value) };
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function sanitizeData(value) {
|
|
212
|
+
if (value === void 0 || value === null) return void 0;
|
|
213
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
214
|
+
const walk = (v) => {
|
|
215
|
+
if (v === null || v === void 0) return v;
|
|
216
|
+
if (typeof v === "bigint") return v.toString();
|
|
217
|
+
if (typeof v === "function") return "[Function]";
|
|
218
|
+
if (typeof v === "symbol") return v.toString();
|
|
219
|
+
if (v instanceof Error) return normalizeError(v);
|
|
220
|
+
if (typeof v !== "object") return v;
|
|
221
|
+
if (seen.has(v)) return "[Circular]";
|
|
222
|
+
seen.add(v);
|
|
223
|
+
if (Array.isArray(v)) return v.map(walk);
|
|
224
|
+
const out = {};
|
|
225
|
+
for (const [k, child] of Object.entries(v)) {
|
|
226
|
+
out[k] = walk(child);
|
|
227
|
+
}
|
|
228
|
+
return out;
|
|
229
|
+
};
|
|
230
|
+
const result = walk(value);
|
|
231
|
+
if (typeof result !== "object" || result === null || Array.isArray(result)) {
|
|
232
|
+
return { value: result };
|
|
233
|
+
}
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// core/src/logging/create-logger.ts
|
|
238
|
+
var ACTIVE_STORE_KEY = /* @__PURE__ */ Symbol.for("@skaile/workspaces:logging:activeStore");
|
|
239
|
+
var globalStoreSlot = globalThis;
|
|
240
|
+
function registerLogStore(store) {
|
|
241
|
+
globalStoreSlot[ACTIVE_STORE_KEY] = store;
|
|
242
|
+
}
|
|
243
|
+
function getLogStore() {
|
|
244
|
+
return globalStoreSlot[ACTIVE_STORE_KEY] ?? null;
|
|
245
|
+
}
|
|
246
|
+
function resetLogStore() {
|
|
247
|
+
globalStoreSlot[ACTIVE_STORE_KEY] = null;
|
|
248
|
+
}
|
|
249
|
+
function ensureLogStore() {
|
|
250
|
+
const existing = globalStoreSlot[ACTIVE_STORE_KEY];
|
|
251
|
+
if (existing) return existing;
|
|
252
|
+
const fallback = new LogStore({
|
|
253
|
+
sessionId: "no-session",
|
|
254
|
+
level: "info",
|
|
255
|
+
sinks: [new NoOpSink(), new StdoutSink()]
|
|
256
|
+
});
|
|
257
|
+
globalStoreSlot[ACTIVE_STORE_KEY] = fallback;
|
|
258
|
+
return fallback;
|
|
259
|
+
}
|
|
260
|
+
function createLogger(source, opts = {}) {
|
|
261
|
+
const fallback = opts.fallback !== false;
|
|
262
|
+
if (!getLogStore() && !fallback) {
|
|
263
|
+
throw new Error("createLogger: no LogStore registered. Call registerLogStore() first.");
|
|
264
|
+
}
|
|
265
|
+
const store = ensureLogStore();
|
|
266
|
+
return makeLogger(source, store);
|
|
267
|
+
}
|
|
268
|
+
function makeLogger(source, store) {
|
|
269
|
+
const emit = (level, message, data, err) => {
|
|
270
|
+
if (!store.isEnabled(level)) return;
|
|
271
|
+
store.record({
|
|
272
|
+
source,
|
|
273
|
+
level,
|
|
274
|
+
message,
|
|
275
|
+
data: sanitizeData(data),
|
|
276
|
+
error: normalizeError(err)
|
|
277
|
+
});
|
|
278
|
+
};
|
|
279
|
+
return {
|
|
280
|
+
debug(message, data) {
|
|
281
|
+
emit("debug", message, data);
|
|
282
|
+
},
|
|
283
|
+
info(message, data) {
|
|
284
|
+
emit("info", message, data);
|
|
285
|
+
},
|
|
286
|
+
warn(message, data) {
|
|
287
|
+
emit("warn", message, data);
|
|
288
|
+
},
|
|
289
|
+
error(message, err, data) {
|
|
290
|
+
emit("error", message, data, err);
|
|
291
|
+
},
|
|
292
|
+
child(partial) {
|
|
293
|
+
return makeLogger({ ...source, ...partial }, store);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export { LogStore, LogStoreDisabledError, NoOpSink, StdoutSink, createLogger, getLogStore, normalizeError, registerLogStore, resetLogStore, sanitizeData };
|
|
299
|
+
//# sourceMappingURL=chunk-7GOCNYUV.js.map
|
|
300
|
+
//# sourceMappingURL=chunk-7GOCNYUV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../core/src/logging/log-store.ts","../core/src/logging/sinks/types.ts","../core/src/logging/sinks/no-op-sink.ts","../core/src/logging/sinks/stdout-sink.ts","../core/src/logging/sanitize.ts","../core/src/logging/create-logger.ts"],"names":[],"mappings":"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","file":"chunk-7GOCNYUV.js","sourcesContent":["import { EventEmitter } from \"node:events\";\nimport type {\n LogEntry,\n LogLevel,\n LogQuery,\n LogQueryResult,\n LogSource,\n} from \"@skaile/workspaces/types\";\nimport { ulid } from \"ulid\";\nimport type { LogSink } from \"./sinks/types.js\";\n\nexport interface LogStoreOptions {\n sessionId: string;\n level: LogLevel;\n sinks: LogSink[];\n flushIntervalMs?: number; // default 50\n flushBatchSize?: number; // default 100\n}\n\nexport interface RecordInput {\n source: LogSource;\n level: LogLevel;\n message: string;\n data?: Record<string, unknown>;\n error?: { name: string; message: string; stack?: string };\n}\n\nconst LEVEL_RANK: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n};\n\n/**\n * In-memory log buffer with periodic flush to sinks.\n *\n * The LogStore buffers log entries and flushes them to registered sinks\n * either when the buffer reaches a certain size, after a time interval,\n * or when explicitly flushed. Supports subscribing to live log entries.\n *\n * @see {@link LogStoreOptions} for configuration\n * @see {@link LogEntry} for the log entry format\n * @category Logging\n * @since 2.0.0\n */\nexport class LogStore {\n private sessionId: string;\n private level: LogLevel;\n private sinks: LogSink[];\n private flushIntervalMs: number;\n private flushBatchSize: number;\n private buffer: LogEntry[] = [];\n private timer: NodeJS.Timeout | null = null;\n private emitter = new EventEmitter();\n private closed = false;\n\n constructor(opts: LogStoreOptions) {\n this.sessionId = opts.sessionId;\n this.level = opts.level;\n this.sinks = opts.sinks;\n this.flushIntervalMs = opts.flushIntervalMs ?? 50;\n this.flushBatchSize = opts.flushBatchSize ?? 100;\n this.emitter.setMaxListeners(0);\n }\n\n getLevel(): LogLevel {\n return this.level;\n }\n\n setLevel(level: LogLevel): void {\n this.level = level;\n }\n\n /** Append a sink after construction. Used by bridges (e.g. OnLogBridgeSink). */\n addSink(sink: LogSink): void {\n this.sinks.push(sink);\n }\n\n /** Returns true if the level is enabled. Used by createLogger to short-circuit. */\n isEnabled(level: LogLevel): boolean {\n return LEVEL_RANK[level] >= LEVEL_RANK[this.level];\n }\n\n record(input: RecordInput): void {\n if (this.closed) return;\n if (!this.isEnabled(input.level)) return;\n const entry: LogEntry = {\n id: ulid(),\n timestamp: new Date().toISOString(),\n sessionId: this.sessionId,\n source: input.source,\n level: input.level,\n message: input.message,\n data: input.data,\n error: input.error,\n };\n this.emitter.emit(\"entry\", entry);\n this.buffer.push(entry);\n if (this.buffer.length >= this.flushBatchSize) {\n this.flushSync();\n } else if (this.flushIntervalMs > 0 && this.timer === null) {\n this.timer = setTimeout(() => this.flushSync(), this.flushIntervalMs);\n } else if (this.flushIntervalMs === 0) {\n this.flushSync();\n }\n }\n\n /** Subscribe to live entries. Returns an unsubscribe function. */\n subscribe(handler: (entry: LogEntry) => void): () => void {\n this.emitter.on(\"entry\", handler);\n return () => this.emitter.off(\"entry\", handler);\n }\n\n /**\n * Query stored log entries.\n *\n * Queries the first sink that supports querying (typically SQLiteSink).\n * Returns empty result if no sink supports querying.\n *\n * @param q - Query parameters including filters and pagination\n * @returns Query result with matching entries\n */\n query(q: LogQuery): LogQueryResult {\n for (const sink of this.sinks) {\n if (sink.query) return sink.query(q);\n }\n return { entries: [] };\n }\n\n /** Force-flush. SQLite writes are synchronous, so this returns once writes complete. */\n flush(): void {\n this.flushSync();\n }\n\n /**\n * Close the log store and release resources.\n *\n * Flushes any pending entries, marks the store as closed, and closes\n * all registered sinks.\n */\n close(): void {\n if (this.closed) return;\n this.flushSync();\n this.closed = true;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n for (const sink of this.sinks) sink.close();\n this.emitter.removeAllListeners();\n }\n\n private flushSync(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n if (this.buffer.length === 0) return;\n const batch = this.buffer;\n this.buffer = [];\n for (const sink of this.sinks) {\n try {\n sink.writeBatch(batch);\n } catch (err) {\n // Last-resort: log to stderr; never let a sink failure crash the producer.\n process.stderr.write(`LogStore sink write failed: ${String(err)}\\n`);\n }\n }\n }\n}\n","// LogSink interface lives in @skaile/workspaces/types so consumers can type-check\n// sink instances without depending on core. Runtime errors live here.\nexport type { LogSink } from \"@skaile/workspaces/types\";\n\nexport class LogStoreDisabledError extends Error {\n constructor() {\n super(\"LogStore is disabled (mode=off); query is unavailable\");\n this.name = \"LogStoreDisabledError\";\n }\n}\n","import type { LogEntry, LogQuery, LogQueryResult } from \"@skaile/workspaces/types\";\nimport { type LogSink, LogStoreDisabledError } from \"./types.js\";\n\nexport class NoOpSink implements LogSink {\n write(_entry: LogEntry): void {}\n writeBatch(_entries: LogEntry[]): void {}\n query(_q: LogQuery): LogQueryResult {\n throw new LogStoreDisabledError();\n }\n close(): void {}\n}\n","import type { LogEntry, LogSource } from \"@skaile/workspaces/types\";\nimport type { LogSink } from \"./types.js\";\n\nexport type StdoutFormat = \"pretty\" | \"json\";\n\n/** Which standard stream the sink writes to. */\nexport type StdoutStream = \"stdout\" | \"stderr\";\n\nexport interface StdoutSinkOptions {\n format?: StdoutFormat;\n /**\n * Standard stream to write to. Default: `\"stdout\"`. Set to `\"stderr\"` for\n * processes whose stdout is a reserved channel — e.g. a stdio MCP server,\n * where stdout carries JSON-RPC and any log line would corrupt the protocol.\n */\n stream?: StdoutStream;\n}\n\nfunction formatSource(source: LogSource): string {\n const parts = [source.kind, source.subkind];\n if (source.instance) parts.push(source.instance);\n return `[${parts.join(\":\")}]`;\n}\n\nfunction formatTime(iso: string): string {\n // HH:MM:SS.sss\n return iso.slice(11, 23);\n}\n\nconst LEVEL_LABEL = {\n debug: \"DEBUG\",\n info: \"INFO \",\n warn: \"WARN \",\n error: \"ERROR\",\n} as const;\n\nexport class StdoutSink implements LogSink {\n private format: StdoutFormat;\n private stream: NodeJS.WriteStream;\n\n constructor(opts: StdoutSinkOptions = {}) {\n this.stream = opts.stream === \"stderr\" ? process.stderr : process.stdout;\n this.format = opts.format ?? (this.stream.isTTY ? \"pretty\" : \"json\");\n }\n\n write(entry: LogEntry): void {\n this.stream.write(`${this.render(entry)}\\n`);\n }\n\n writeBatch(entries: LogEntry[]): void {\n for (const e of entries) this.write(e);\n }\n\n close(): void {}\n\n private render(entry: LogEntry): string {\n if (this.format === \"json\") {\n return JSON.stringify(entry);\n }\n const head = `${formatTime(entry.timestamp)} ${LEVEL_LABEL[entry.level]} ${formatSource(entry.source)}`;\n const tail = entry.message;\n const detail = entry.data ? `\\n > ${JSON.stringify(entry.data)}` : \"\";\n const err = entry.error ? `\\n ! ${entry.error.name}: ${entry.error.message}` : \"\";\n return `${head} ${tail}${detail}${err}`;\n }\n}\n","import type { NormalizedError } from \"@skaile/workspaces/types\";\n\nexport function normalizeError(value: unknown): NormalizedError | undefined {\n if (value === undefined || value === null) return undefined;\n if (value instanceof Error) {\n return {\n name: value.name,\n message: value.message,\n stack: value.stack,\n };\n }\n if (typeof value === \"string\") {\n return { name: \"Error\", message: value };\n }\n try {\n return { name: \"Error\", message: JSON.stringify(value) };\n } catch {\n return { name: \"Error\", message: String(value) };\n }\n}\n\nexport function sanitizeData(value: unknown): Record<string, unknown> | undefined {\n if (value === undefined || value === null) return undefined;\n const seen = new WeakSet<object>();\n const walk = (v: unknown): unknown => {\n if (v === null || v === undefined) return v;\n if (typeof v === \"bigint\") return v.toString();\n if (typeof v === \"function\") return \"[Function]\";\n if (typeof v === \"symbol\") return v.toString();\n if (v instanceof Error) return normalizeError(v);\n if (typeof v !== \"object\") return v;\n if (seen.has(v as object)) return \"[Circular]\";\n seen.add(v as object);\n if (Array.isArray(v)) return v.map(walk);\n const out: Record<string, unknown> = {};\n for (const [k, child] of Object.entries(v as Record<string, unknown>)) {\n out[k] = walk(child);\n }\n return out;\n };\n const result = walk(value);\n if (typeof result !== \"object\" || result === null || Array.isArray(result)) {\n return { value: result };\n }\n return result as Record<string, unknown>;\n}\n","import type { Logger, LogSource } from \"@skaile/workspaces/types\";\nimport { LogStore } from \"./log-store.js\";\nimport { normalizeError, sanitizeData } from \"./sanitize.js\";\nimport { NoOpSink } from \"./sinks/no-op-sink.js\";\nimport { StdoutSink } from \"./sinks/stdout-sink.js\";\n\n/**\n * The active LogStore is a process-singleton. It is stored on `globalThis`\n * under a `Symbol.for` key so it survives module duplication — under vitest's\n * `skaile-src` aliasing and the runner's lazy `import(\"@skaile/workspaces/runner\")`,\n * `core/logging` can be evaluated as two distinct module instances. A plain\n * module-scoped `let` would give each instance its own store, so a logger\n * created on one instance would not see a store registered on the other.\n * The `globalThis` slot makes the singleton genuinely process-wide.\n */\nconst ACTIVE_STORE_KEY = Symbol.for(\"@skaile/workspaces:logging:activeStore\");\n\ntype GlobalWithStore = typeof globalThis & {\n [ACTIVE_STORE_KEY]?: LogStore | null;\n};\n\nconst globalStoreSlot = globalThis as GlobalWithStore;\n\nexport function registerLogStore(store: LogStore): void {\n globalStoreSlot[ACTIVE_STORE_KEY] = store;\n}\n\nexport function getLogStore(): LogStore | null {\n return globalStoreSlot[ACTIVE_STORE_KEY] ?? null;\n}\n\nexport function resetLogStore(): void {\n globalStoreSlot[ACTIVE_STORE_KEY] = null;\n}\n\nexport interface CreateLoggerOptions {\n /**\n * When true (default), create + register a lazy off-mode LogStore if none\n * is registered. When false, throw if no store has been registered.\n */\n fallback?: boolean;\n}\n\nfunction ensureLogStore(): LogStore {\n const existing = globalStoreSlot[ACTIVE_STORE_KEY];\n if (existing) return existing;\n // Lazy off-mode fallback: NoOp + Stdout, no SQLite, no sessionId.\n const fallback = new LogStore({\n sessionId: \"no-session\",\n level: \"info\",\n sinks: [new NoOpSink(), new StdoutSink()],\n });\n globalStoreSlot[ACTIVE_STORE_KEY] = fallback;\n return fallback;\n}\n\n/**\n * Creates a logger for the given source.\n *\n * If no LogStore is registered and fallback is enabled (default), a lazy\n * off-mode fallback store (NoOp + Stdout) is created.\n *\n * @param source - The log source (e.g., { kind: 'agent', name: 'my-agent' })\n * @param opts - Configuration options for logger creation\n * @param opts.fallback - When true (default), creates a fallback store if none registered\n * @returns A logger instance\n * @throws {Error} When no LogStore is registered and fallback is false\n *\n * @example\n * ```typescript\n * const logger = createLogger({ kind: 'agent', name: 'my-agent' });\n * logger.info('Agent started');\n * ```\n */\nexport function createLogger(source: LogSource, opts: CreateLoggerOptions = {}): Logger {\n const fallback = opts.fallback !== false;\n if (!getLogStore() && !fallback) {\n throw new Error(\"createLogger: no LogStore registered. Call registerLogStore() first.\");\n }\n const store = ensureLogStore();\n return makeLogger(source, store);\n}\n\nfunction makeLogger(source: LogSource, store: LogStore): Logger {\n const emit = (\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n data?: object,\n err?: unknown,\n ) => {\n if (!store.isEnabled(level)) return;\n store.record({\n source,\n level,\n message,\n data: sanitizeData(data),\n error: normalizeError(err),\n });\n };\n return {\n debug(message, data) {\n emit(\"debug\", message, data);\n },\n info(message, data) {\n emit(\"info\", message, data);\n },\n warn(message, data) {\n emit(\"warn\", message, data);\n },\n error(message, err, data) {\n emit(\"error\", message, data, err);\n },\n child(partial) {\n return makeLogger({ ...source, ...partial }, store);\n },\n };\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { findAiAssetsRoot } from './chunk-
|
|
2
|
-
import { parseSkillRequirements, validateRequirements, buildRequiresPreamble, parseSkillFrontmatter } from './chunk-
|
|
1
|
+
import { findAiAssetsRoot } from './chunk-BK3WL3QK.js';
|
|
2
|
+
import { parseSkillRequirements, validateRequirements, buildRequiresPreamble, parseSkillFrontmatter } from './chunk-CZZRDYT4.js';
|
|
3
3
|
import { okJson, err, ok } from './chunk-X5YPJV4N.js';
|
|
4
4
|
import fs from 'fs/promises';
|
|
5
5
|
import path from 'path';
|
|
@@ -64,7 +64,7 @@ async function scanSkills(aiAssetsRoot, domainFilter) {
|
|
|
64
64
|
}
|
|
65
65
|
async function skillList(projectDir, domain) {
|
|
66
66
|
try {
|
|
67
|
-
const aiAssetsRoot = findAiAssetsRoot(projectDir);
|
|
67
|
+
const aiAssetsRoot = await findAiAssetsRoot(projectDir);
|
|
68
68
|
if (!aiAssetsRoot) return okJson([]);
|
|
69
69
|
const skills = await scanSkills(aiAssetsRoot, domain);
|
|
70
70
|
return okJson(
|
|
@@ -84,7 +84,7 @@ async function skillList(projectDir, domain) {
|
|
|
84
84
|
}
|
|
85
85
|
async function skillListDomains(projectDir) {
|
|
86
86
|
try {
|
|
87
|
-
const aiAssetsRoot = findAiAssetsRoot(projectDir);
|
|
87
|
+
const aiAssetsRoot = await findAiAssetsRoot(projectDir);
|
|
88
88
|
if (!aiAssetsRoot) return okJson([]);
|
|
89
89
|
const entries = await fs.readdir(aiAssetsRoot, { withFileTypes: true });
|
|
90
90
|
const domains = entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, path: path.join(aiAssetsRoot, e.name) }));
|
|
@@ -95,7 +95,7 @@ async function skillListDomains(projectDir) {
|
|
|
95
95
|
}
|
|
96
96
|
async function skillShow(projectDir, skillId) {
|
|
97
97
|
try {
|
|
98
|
-
const aiAssetsRoot = findAiAssetsRoot(projectDir);
|
|
98
|
+
const aiAssetsRoot = await findAiAssetsRoot(projectDir);
|
|
99
99
|
if (!aiAssetsRoot) return err(`Skill not found: ${skillId}`);
|
|
100
100
|
const skills = await scanSkills(aiAssetsRoot, void 0);
|
|
101
101
|
const skill = skills.find((s) => s.id === skillId);
|
|
@@ -108,7 +108,7 @@ async function skillShow(projectDir, skillId) {
|
|
|
108
108
|
}
|
|
109
109
|
async function skillSearch(projectDir, query) {
|
|
110
110
|
try {
|
|
111
|
-
const aiAssetsRoot = findAiAssetsRoot(projectDir);
|
|
111
|
+
const aiAssetsRoot = await findAiAssetsRoot(projectDir);
|
|
112
112
|
if (!aiAssetsRoot) return okJson([]);
|
|
113
113
|
const skills = await scanSkills(aiAssetsRoot, void 0);
|
|
114
114
|
const q = query.toLowerCase();
|
|
@@ -132,14 +132,14 @@ async function skillSearch(projectDir, query) {
|
|
|
132
132
|
}
|
|
133
133
|
async function skillCheckRequirements(projectDir, skillId, targetDir) {
|
|
134
134
|
try {
|
|
135
|
-
const aiAssetsRoot = findAiAssetsRoot(projectDir);
|
|
135
|
+
const aiAssetsRoot = await findAiAssetsRoot(projectDir);
|
|
136
136
|
if (!aiAssetsRoot) return err(`Skill not found: ${skillId}`);
|
|
137
137
|
const skills = await scanSkills(aiAssetsRoot, void 0);
|
|
138
138
|
const skill = skills.find((s) => s.id === skillId);
|
|
139
139
|
if (!skill) return err(`Skill not found: ${skillId}`);
|
|
140
140
|
const content = await fs.readFile(skill.path, "utf-8");
|
|
141
141
|
const requirements = parseSkillRequirements(content);
|
|
142
|
-
const report = validateRequirements(skillId, requirements, targetDir);
|
|
142
|
+
const report = await validateRequirements(skillId, requirements, targetDir);
|
|
143
143
|
return okJson(report);
|
|
144
144
|
} catch (e) {
|
|
145
145
|
return err(e instanceof Error ? e.message : String(e));
|
|
@@ -147,7 +147,7 @@ async function skillCheckRequirements(projectDir, skillId, targetDir) {
|
|
|
147
147
|
}
|
|
148
148
|
async function skillGetPreamble(projectDir, skillId) {
|
|
149
149
|
try {
|
|
150
|
-
const aiAssetsRoot = findAiAssetsRoot(projectDir);
|
|
150
|
+
const aiAssetsRoot = await findAiAssetsRoot(projectDir);
|
|
151
151
|
if (!aiAssetsRoot) return err(`Skill not found: ${skillId}`);
|
|
152
152
|
const skills = await scanSkills(aiAssetsRoot, void 0);
|
|
153
153
|
const skill = skills.find((s) => s.id === skillId);
|
|
@@ -162,5 +162,5 @@ async function skillGetPreamble(projectDir, skillId) {
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
export { skillCheckRequirements, skillGetPreamble, skillList, skillListDomains, skillSearch, skillShow };
|
|
165
|
-
//# sourceMappingURL=chunk-
|
|
166
|
-
//# sourceMappingURL=chunk-
|
|
165
|
+
//# sourceMappingURL=chunk-BCTU4TN7.js.map
|
|
166
|
+
//# sourceMappingURL=chunk-BCTU4TN7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../workspace-plugin/src/tools/skills.ts"],"names":[],"mappings":"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","file":"chunk-BCTU4TN7.js","sourcesContent":["// src/tools/skills.ts\n\nimport type { Dirent } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n buildRequiresPreamble,\n parseSkillFrontmatter,\n parseSkillRequirements,\n validateRequirements,\n} from \"@skaile/workspaces/resolver\";\nimport type { ToolResult } from \"../types.js\";\nimport { err, ok, okJson } from \"../types.js\";\nimport { findAiAssetsRoot } from \"../utils/ai-assets.js\";\n\ninterface SkillEntry {\n id: string;\n name: string;\n description: string;\n source?: string;\n version?: string;\n keywords?: string[];\n path: string;\n domain: string;\n}\n\nasync function walkForSkillMd(dir: string, domain: string, acc: SkillEntry[]): Promise<void> {\n let entries: Dirent<string>[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n // Check if this directory contains a SKILL.md\n const hasSkillMd = entries.some((e) => e.isFile() && e.name === \"SKILL.md\");\n if (hasSkillMd) {\n const skillMdPath = path.join(dir, \"SKILL.md\");\n try {\n const content = await fs.readFile(skillMdPath, \"utf-8\");\n const fm = parseSkillFrontmatter(content);\n const name = typeof fm.name === \"string\" ? fm.name : path.basename(dir);\n const description = typeof fm.description === \"string\" ? fm.description : \"\";\n const source = typeof fm.source === \"string\" ? fm.source : undefined;\n const version = typeof fm.version === \"string\" ? fm.version : undefined;\n const keywords = Array.isArray(fm.keywords) ? (fm.keywords as string[]) : undefined;\n acc.push({\n id: path.basename(dir),\n name,\n description,\n source,\n version,\n keywords,\n path: skillMdPath,\n domain,\n });\n } catch {\n // skip unreadable files\n }\n return; // don't recurse inside a skill directory\n }\n\n // Recurse into subdirectories\n for (const entry of entries) {\n if (entry.isDirectory()) {\n await walkForSkillMd(path.join(dir, entry.name), domain, acc);\n }\n }\n}\n\nasync function scanSkills(aiAssetsRoot: string, domainFilter?: string): Promise<SkillEntry[]> {\n let domains: string[];\n try {\n const entries = await fs.readdir(aiAssetsRoot, { withFileTypes: true });\n domains = entries\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .filter((name) => !domainFilter || name === domainFilter);\n } catch {\n return [];\n }\n\n const acc: SkillEntry[] = [];\n for (const domain of domains) {\n const skillsDir = path.join(aiAssetsRoot, domain, \"skills\");\n try {\n await fs.access(skillsDir);\n } catch {\n continue; // no skills/ dir in this domain\n }\n await walkForSkillMd(skillsDir, domain, acc);\n }\n return acc;\n}\n\n// ── Exported tool functions ────────────────────────────────────────────────────\n\n/**\n * List all skills in the `ai-assets` catalog, optionally filtered by domain.\n *\n * Walks every `<domain>/skills/` directory under the `ai-assets` root looking\n * for `SKILL.md` files. Returns a JSON array of skill summaries\n * `{ id, name, description, source, version, keywords, domain }`.\n *\n * @param projectDir - Absolute path to the skaile project root.\n * @param domain - Optional domain name filter (e.g. `\"skaile-development\"`).\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function skillList(\n projectDir: string,\n domain: string | undefined,\n): Promise<ToolResult> {\n try {\n const aiAssetsRoot = await findAiAssetsRoot(projectDir);\n if (!aiAssetsRoot) return okJson([]);\n const skills = await scanSkills(aiAssetsRoot, domain);\n return okJson(\n skills.map((s) => ({\n id: s.id,\n name: s.name,\n description: s.description,\n source: s.source,\n version: s.version,\n keywords: s.keywords,\n domain: s.domain,\n })),\n );\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * List all skill domains — the top-level directories under `ai-assets` that\n * contain a `skills/` subdirectory.\n *\n * Returns a JSON array of `{ name, path }` objects.\n *\n * @param projectDir - Absolute path to the skaile project root.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function skillListDomains(projectDir: string): Promise<ToolResult> {\n try {\n const aiAssetsRoot = await findAiAssetsRoot(projectDir);\n if (!aiAssetsRoot) return okJson([]);\n const entries = await fs.readdir(aiAssetsRoot, { withFileTypes: true });\n const domains = entries\n .filter((e) => e.isDirectory())\n .map((e) => ({ name: e.name, path: path.join(aiAssetsRoot, e.name) }));\n return okJson(domains);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Show the full `SKILL.md` content for a skill.\n *\n * @param projectDir - Absolute path to the skaile project root.\n * @param skillId - Skill ID (directory name) as returned by {@link skillList}.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function skillShow(projectDir: string, skillId: string): Promise<ToolResult> {\n try {\n const aiAssetsRoot = await findAiAssetsRoot(projectDir);\n if (!aiAssetsRoot) return err(`Skill not found: ${skillId}`);\n const skills = await scanSkills(aiAssetsRoot, undefined);\n const skill = skills.find((s) => s.id === skillId);\n if (!skill) return err(`Skill not found: ${skillId}`);\n const content = await fs.readFile(skill.path, \"utf-8\");\n return ok(content);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Search skills by name, description, ID, or keywords.\n *\n * Case-insensitive substring match against all text fields in every skill\n * entry. Returns the same summary shape as {@link skillList}.\n *\n * @param projectDir - Absolute path to the skaile project root.\n * @param query - Search string.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function skillSearch(projectDir: string, query: string): Promise<ToolResult> {\n try {\n const aiAssetsRoot = await findAiAssetsRoot(projectDir);\n if (!aiAssetsRoot) return okJson([]);\n const skills = await scanSkills(aiAssetsRoot, undefined);\n const q = query.toLowerCase();\n const matched = skills.filter(\n (s) =>\n s.name.toLowerCase().includes(q) ||\n s.description.toLowerCase().includes(q) ||\n s.id.toLowerCase().includes(q) ||\n (s.keywords ?? []).some((k) => k.toLowerCase().includes(q)),\n );\n return okJson(\n matched.map((s) => ({\n id: s.id,\n name: s.name,\n description: s.description,\n source: s.source,\n version: s.version,\n keywords: s.keywords,\n domain: s.domain,\n })),\n );\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Validate that all prerequisites declared in a skill's `SKILL.md` are\n * satisfied in `targetDir`.\n *\n * Uses `@skaile/workspaces/resolver` to parse the `REQUIRES` / `READS` / `WRITES`\n * DSL and run the requirement checks against the filesystem. Returns a\n * validation report as JSON.\n *\n * @param projectDir - Absolute path to the skaile project root (for skill lookup).\n * @param skillId - Skill ID as returned by {@link skillList}.\n * @param targetDir - Directory to validate against (typically the user's project).\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function skillCheckRequirements(\n projectDir: string,\n skillId: string,\n targetDir: string,\n): Promise<ToolResult> {\n try {\n const aiAssetsRoot = await findAiAssetsRoot(projectDir);\n if (!aiAssetsRoot) return err(`Skill not found: ${skillId}`);\n const skills = await scanSkills(aiAssetsRoot, undefined);\n const skill = skills.find((s) => s.id === skillId);\n if (!skill) return err(`Skill not found: ${skillId}`);\n const content = await fs.readFile(skill.path, \"utf-8\");\n\n const requirements = parseSkillRequirements(content);\n const report = await validateRequirements(skillId, requirements, targetDir);\n return okJson(report);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Get the formatted `REQUIRES`/`INPUT`/`READS`/`WRITES` DSL preamble for a skill.\n *\n * Uses `@skaile/workspaces/resolver` to build the requirements preamble that can be\n * prepended to the skill prompt for injection into the agent's context.\n * Returns `\"(no requirements declared)\"` when the skill has no requirements.\n *\n * @param projectDir - Absolute path to the skaile project root.\n * @param skillId - Skill ID as returned by {@link skillList}.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function skillGetPreamble(projectDir: string, skillId: string): Promise<ToolResult> {\n try {\n const aiAssetsRoot = await findAiAssetsRoot(projectDir);\n if (!aiAssetsRoot) return err(`Skill not found: ${skillId}`);\n const skills = await scanSkills(aiAssetsRoot, undefined);\n const skill = skills.find((s) => s.id === skillId);\n if (!skill) return err(`Skill not found: ${skillId}`);\n const content = await fs.readFile(skill.path, \"utf-8\");\n\n const requirements = parseSkillRequirements(content);\n const preamble = buildRequiresPreamble(requirements, skillId);\n return ok(preamble || \"(no requirements declared)\");\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n"]}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { tryWithFsDeadline, withFsDeadline, fsDeadlineMs } from './chunk-DYMWJAL4.js';
|
|
2
|
+
import { createLogger } from './chunk-7GOCNYUV.js';
|
|
3
|
+
import { stat, mkdir, cp, writeFile, rm } from 'fs/promises';
|
|
4
|
+
import { resolve, sep, join } from 'path';
|
|
5
|
+
|
|
6
|
+
var TREE_OP_DEADLINE_FACTOR = 4;
|
|
7
|
+
var AI_ASSETS_WALK_LEVELS = 6;
|
|
8
|
+
var deployerLogger;
|
|
9
|
+
function log() {
|
|
10
|
+
deployerLogger ??= createLogger({ kind: "runner", subkind: "catalog-deployer" });
|
|
11
|
+
return deployerLogger;
|
|
12
|
+
}
|
|
13
|
+
var DEFAULT_WORKSPACE_MOUNT_DIR = "/skaile/workspace";
|
|
14
|
+
var WORKSPACE_MOUNT_ENV_VAR = "SKAILE_WORKSPACE_MOUNT_DIR";
|
|
15
|
+
function workspaceMountDirs() {
|
|
16
|
+
const raw = process.env[WORKSPACE_MOUNT_ENV_VAR];
|
|
17
|
+
if (raw === void 0) return [DEFAULT_WORKSPACE_MOUNT_DIR];
|
|
18
|
+
return raw.split(",").map((segment) => segment.trim()).filter((segment) => segment.length > 0).map((segment) => resolve(segment));
|
|
19
|
+
}
|
|
20
|
+
function isUnderWorkspaceMount(candidate, mountDirs = workspaceMountDirs()) {
|
|
21
|
+
const target = resolve(candidate);
|
|
22
|
+
return mountDirs.some((dir) => {
|
|
23
|
+
const root = resolve(dir);
|
|
24
|
+
return target === root || target.startsWith(root + sep);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async function findAiAssetsRoot(startDir, opts) {
|
|
28
|
+
const mountDirs = opts?.mountDirs ?? workspaceMountDirs();
|
|
29
|
+
const levels = opts?.levels ?? AI_ASSETS_WALK_LEVELS;
|
|
30
|
+
let dir = resolve(startDir);
|
|
31
|
+
const refused = [];
|
|
32
|
+
for (let i = 0; i < levels; i++) {
|
|
33
|
+
const candidate = join(dir, "ai-assets");
|
|
34
|
+
if (isUnderWorkspaceMount(candidate, mountDirs)) {
|
|
35
|
+
refused.push(candidate);
|
|
36
|
+
} else {
|
|
37
|
+
const isDir = await tryWithFsDeadline(
|
|
38
|
+
`stat ${candidate}`,
|
|
39
|
+
async () => (await stat(candidate)).isDirectory(),
|
|
40
|
+
false
|
|
41
|
+
);
|
|
42
|
+
if (isDir) {
|
|
43
|
+
if (refused.length > 0) warnRefused(refused, mountDirs);
|
|
44
|
+
return candidate;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const parent = resolve(dir, "..");
|
|
48
|
+
if (parent === dir) break;
|
|
49
|
+
dir = parent;
|
|
50
|
+
}
|
|
51
|
+
if (refused.length > 0) warnRefused(refused, mountDirs);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
function warnRefused(refused, mountDirs) {
|
|
55
|
+
log().warn(
|
|
56
|
+
"findAiAssetsRoot refused candidates under a workspace mount \u2014 deploying skills from a network mount can stall the session",
|
|
57
|
+
{ refused, mountDirs }
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
async function deployCatalogEntry(entry, options) {
|
|
61
|
+
const { assetsRoot, skillsDir, context } = options;
|
|
62
|
+
if (entry.kind !== "skill") {
|
|
63
|
+
return { success: false, error: `Cannot deploy ${entry.kind} directly \u2014 only skills` };
|
|
64
|
+
}
|
|
65
|
+
const sourcePath = join(assetsRoot, entry.source_path);
|
|
66
|
+
const skillMdPath = join(sourcePath, "SKILL.md");
|
|
67
|
+
const hasSkillMd = await tryWithFsDeadline(
|
|
68
|
+
`stat ${skillMdPath}`,
|
|
69
|
+
async () => {
|
|
70
|
+
await stat(skillMdPath);
|
|
71
|
+
return true;
|
|
72
|
+
},
|
|
73
|
+
false
|
|
74
|
+
);
|
|
75
|
+
if (!hasSkillMd) {
|
|
76
|
+
return { success: false, error: `SKILL.md not found at ${skillMdPath}` };
|
|
77
|
+
}
|
|
78
|
+
const destDir = join(skillsDir, entry.name);
|
|
79
|
+
try {
|
|
80
|
+
await withFsDeadline(`mkdir ${destDir}`, () => mkdir(destDir, { recursive: true }));
|
|
81
|
+
await withFsDeadline(
|
|
82
|
+
`cp ${sourcePath} -> ${destDir}`,
|
|
83
|
+
() => cp(sourcePath, destDir, { recursive: true }),
|
|
84
|
+
fsDeadlineMs() * TREE_OP_DEADLINE_FACTOR
|
|
85
|
+
);
|
|
86
|
+
const contextPath = join(destDir, "CONTEXT.md");
|
|
87
|
+
if (context) {
|
|
88
|
+
await withFsDeadline(
|
|
89
|
+
`write ${contextPath}`,
|
|
90
|
+
() => writeFile(contextPath, `# Additional Context
|
|
91
|
+
|
|
92
|
+
${context}
|
|
93
|
+
`, "utf8")
|
|
94
|
+
);
|
|
95
|
+
} else {
|
|
96
|
+
await withFsDeadline(`rm ${contextPath}`, () => rm(contextPath, { force: true }));
|
|
97
|
+
}
|
|
98
|
+
} catch (err) {
|
|
99
|
+
return { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
100
|
+
}
|
|
101
|
+
return { success: true };
|
|
102
|
+
}
|
|
103
|
+
async function undeployCatalogEntry(name, skillsDir) {
|
|
104
|
+
const destDir = join(skillsDir, name);
|
|
105
|
+
const exists = await tryWithFsDeadline(
|
|
106
|
+
`stat ${destDir}`,
|
|
107
|
+
async () => {
|
|
108
|
+
await stat(destDir);
|
|
109
|
+
return true;
|
|
110
|
+
},
|
|
111
|
+
false
|
|
112
|
+
);
|
|
113
|
+
if (!exists) return false;
|
|
114
|
+
await withFsDeadline(
|
|
115
|
+
`rm -r ${destDir}`,
|
|
116
|
+
() => rm(destDir, { recursive: true, force: true }),
|
|
117
|
+
fsDeadlineMs() * TREE_OP_DEADLINE_FACTOR
|
|
118
|
+
);
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
async function deployAll(entries, options) {
|
|
122
|
+
const result = { deployed: [], skipped: [], errors: [] };
|
|
123
|
+
for (const entry of entries) {
|
|
124
|
+
if (entry.kind !== "skill") {
|
|
125
|
+
result.skipped.push(entry.id);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const r = await deployCatalogEntry(entry, options);
|
|
129
|
+
if (r.success) {
|
|
130
|
+
result.deployed.push(entry.id);
|
|
131
|
+
} else {
|
|
132
|
+
result.errors.push(`${entry.id}: ${r.error}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
function resolveFlowSkills(flow, allEntries) {
|
|
138
|
+
const skillsByName = /* @__PURE__ */ new Map();
|
|
139
|
+
for (const e of allEntries) {
|
|
140
|
+
if (e.kind === "skill") skillsByName.set(e.name, e);
|
|
141
|
+
}
|
|
142
|
+
const required = [];
|
|
143
|
+
const optional = [];
|
|
144
|
+
const missing = [];
|
|
145
|
+
for (const name of flow.required_skills ?? []) {
|
|
146
|
+
const entry = skillsByName.get(name);
|
|
147
|
+
if (entry) required.push(entry);
|
|
148
|
+
else missing.push(name);
|
|
149
|
+
}
|
|
150
|
+
for (const name of flow.optional_skills ?? []) {
|
|
151
|
+
const entry = skillsByName.get(name);
|
|
152
|
+
if (entry) optional.push(entry);
|
|
153
|
+
}
|
|
154
|
+
return { required, optional, missing };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export { WORKSPACE_MOUNT_ENV_VAR, deployAll, deployCatalogEntry, findAiAssetsRoot, isUnderWorkspaceMount, resolveFlowSkills, undeployCatalogEntry, workspaceMountDirs };
|
|
158
|
+
//# sourceMappingURL=chunk-BEAIJRVF.js.map
|
|
159
|
+
//# sourceMappingURL=chunk-BEAIJRVF.js.map
|