@darkiceinteractive/mcp-conductor 2.0.0-alpha.1 → 3.0.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/README.md +35 -5
- package/dist/bin/cli.d.ts +20 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +260 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/bridge/http-server.d.ts +26 -0
- package/dist/bridge/http-server.d.ts.map +1 -1
- package/dist/bridge/http-server.js +30 -2
- package/dist/bridge/http-server.js.map +1 -1
- package/dist/bridge/index.d.ts +1 -0
- package/dist/bridge/index.d.ts.map +1 -1
- package/dist/bridge/index.js +1 -0
- package/dist/bridge/index.js.map +1 -1
- package/dist/bridge/pool.d.ts +95 -0
- package/dist/bridge/pool.d.ts.map +1 -0
- package/dist/bridge/pool.js +384 -0
- package/dist/bridge/pool.js.map +1 -0
- package/dist/cache/cache.d.ts +43 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +167 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/delta.d.ts +32 -0
- package/dist/cache/delta.d.ts.map +1 -0
- package/dist/cache/delta.js +131 -0
- package/dist/cache/delta.js.map +1 -0
- package/dist/cache/disk.d.ts +65 -0
- package/dist/cache/disk.d.ts.map +1 -0
- package/dist/cache/disk.js +238 -0
- package/dist/cache/disk.js.map +1 -0
- package/dist/cache/index.d.ts +53 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +12 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/key.d.ts +44 -0
- package/dist/cache/key.d.ts.map +1 -0
- package/dist/cache/key.js +83 -0
- package/dist/cache/key.js.map +1 -0
- package/dist/cache/lru.d.ts +57 -0
- package/dist/cache/lru.d.ts.map +1 -0
- package/dist/cache/lru.js +112 -0
- package/dist/cache/lru.js.map +1 -0
- package/dist/cache/policy.d.ts +34 -0
- package/dist/cache/policy.d.ts.map +1 -0
- package/dist/cache/policy.js +95 -0
- package/dist/cache/policy.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +33 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +135 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/export-servers.d.ts +22 -0
- package/dist/cli/commands/export-servers.d.ts.map +1 -0
- package/dist/cli/commands/export-servers.js +45 -0
- package/dist/cli/commands/export-servers.js.map +1 -0
- package/dist/cli/commands/import-servers.d.ts +57 -0
- package/dist/cli/commands/import-servers.d.ts.map +1 -0
- package/dist/cli/commands/import-servers.js +137 -0
- package/dist/cli/commands/import-servers.js.map +1 -0
- package/dist/cli/commands/routing.d.ts +34 -0
- package/dist/cli/commands/routing.d.ts.map +1 -0
- package/dist/cli/commands/routing.js +60 -0
- package/dist/cli/commands/routing.js.map +1 -0
- package/dist/cli/commands/test-server.d.ts +34 -0
- package/dist/cli/commands/test-server.d.ts.map +1 -0
- package/dist/cli/commands/test-server.js +86 -0
- package/dist/cli/commands/test-server.js.map +1 -0
- package/dist/cli/daemon.d.ts +60 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +244 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/replay.d.ts +16 -0
- package/dist/cli/replay.d.ts.map +1 -0
- package/dist/cli/replay.js +89 -0
- package/dist/cli/replay.js.map +1 -0
- package/dist/cli/wizard/setup.d.ts +12 -0
- package/dist/cli/wizard/setup.d.ts.map +1 -0
- package/dist/cli/wizard/setup.js +71 -0
- package/dist/cli/wizard/setup.js.map +1 -0
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +4 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/schema.d.ts +34 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/daemon/client.d.ts +97 -0
- package/dist/daemon/client.d.ts.map +1 -0
- package/dist/daemon/client.js +279 -0
- package/dist/daemon/client.js.map +1 -0
- package/dist/daemon/discovery.d.ts +50 -0
- package/dist/daemon/discovery.d.ts.map +1 -0
- package/dist/daemon/discovery.js +104 -0
- package/dist/daemon/discovery.js.map +1 -0
- package/dist/daemon/index.d.ts +16 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +11 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/sandbox-api.d.ts +45 -0
- package/dist/daemon/sandbox-api.d.ts.map +1 -0
- package/dist/daemon/sandbox-api.js +74 -0
- package/dist/daemon/sandbox-api.js.map +1 -0
- package/dist/daemon/server.d.ts +65 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +351 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/shared-kv.d.ts +81 -0
- package/dist/daemon/shared-kv.d.ts.map +1 -0
- package/dist/daemon/shared-kv.js +215 -0
- package/dist/daemon/shared-kv.js.map +1 -0
- package/dist/daemon/shared-lock.d.ts +71 -0
- package/dist/daemon/shared-lock.d.ts.map +1 -0
- package/dist/daemon/shared-lock.js +119 -0
- package/dist/daemon/shared-lock.js.map +1 -0
- package/dist/hub/mcp-hub.d.ts +23 -0
- package/dist/hub/mcp-hub.d.ts.map +1 -1
- package/dist/hub/mcp-hub.js +34 -1
- package/dist/hub/mcp-hub.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/observability/anomaly.d.ts +67 -0
- package/dist/observability/anomaly.d.ts.map +1 -0
- package/dist/observability/anomaly.js +141 -0
- package/dist/observability/anomaly.js.map +1 -0
- package/dist/observability/cost-predictor.d.ts +49 -0
- package/dist/observability/cost-predictor.d.ts.map +1 -0
- package/dist/observability/cost-predictor.js +145 -0
- package/dist/observability/cost-predictor.js.map +1 -0
- package/dist/observability/hot-path.d.ts +49 -0
- package/dist/observability/hot-path.d.ts.map +1 -0
- package/dist/observability/hot-path.js +125 -0
- package/dist/observability/hot-path.js.map +1 -0
- package/dist/observability/index.d.ts +10 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +10 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/replay.d.ts +104 -0
- package/dist/observability/replay.d.ts.map +1 -0
- package/dist/observability/replay.js +239 -0
- package/dist/observability/replay.js.map +1 -0
- package/dist/registry/built-in-recommendations.d.ts +54 -0
- package/dist/registry/built-in-recommendations.d.ts.map +1 -0
- package/dist/registry/built-in-recommendations.js +65 -0
- package/dist/registry/built-in-recommendations.js.map +1 -0
- package/dist/registry/events.d.ts +26 -0
- package/dist/registry/events.d.ts.map +1 -0
- package/dist/registry/events.js +22 -0
- package/dist/registry/events.js.map +1 -0
- package/dist/registry/index.d.ts +159 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +12 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/registry.d.ts +87 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +294 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/registry/snapshot.d.ts +42 -0
- package/dist/registry/snapshot.d.ts.map +1 -0
- package/dist/registry/snapshot.js +71 -0
- package/dist/registry/snapshot.js.map +1 -0
- package/dist/registry/typegen.d.ts +48 -0
- package/dist/registry/typegen.d.ts.map +1 -0
- package/dist/registry/typegen.js +200 -0
- package/dist/registry/typegen.js.map +1 -0
- package/dist/registry/validator.d.ts +23 -0
- package/dist/registry/validator.d.ts.map +1 -0
- package/dist/registry/validator.js +50 -0
- package/dist/registry/validator.js.map +1 -0
- package/dist/reliability/breaker.d.ts +57 -0
- package/dist/reliability/breaker.d.ts.map +1 -0
- package/dist/reliability/breaker.js +130 -0
- package/dist/reliability/breaker.js.map +1 -0
- package/dist/reliability/errors.d.ts +78 -0
- package/dist/reliability/errors.d.ts.map +1 -0
- package/dist/reliability/errors.js +160 -0
- package/dist/reliability/errors.js.map +1 -0
- package/dist/reliability/gateway.d.ts +88 -0
- package/dist/reliability/gateway.d.ts.map +1 -0
- package/dist/reliability/gateway.js +180 -0
- package/dist/reliability/gateway.js.map +1 -0
- package/dist/reliability/index.d.ts +20 -0
- package/dist/reliability/index.d.ts.map +1 -0
- package/dist/reliability/index.js +16 -0
- package/dist/reliability/index.js.map +1 -0
- package/dist/reliability/profile.d.ts +49 -0
- package/dist/reliability/profile.d.ts.map +1 -0
- package/dist/reliability/profile.js +58 -0
- package/dist/reliability/profile.js.map +1 -0
- package/dist/reliability/retry.d.ts +39 -0
- package/dist/reliability/retry.d.ts.map +1 -0
- package/dist/reliability/retry.js +51 -0
- package/dist/reliability/retry.js.map +1 -0
- package/dist/reliability/timeout.d.ts +34 -0
- package/dist/reliability/timeout.d.ts.map +1 -0
- package/dist/reliability/timeout.js +53 -0
- package/dist/reliability/timeout.js.map +1 -0
- package/dist/runtime/executor.d.ts.map +1 -1
- package/dist/runtime/executor.js +78 -13
- package/dist/runtime/executor.js.map +1 -1
- package/dist/runtime/findtool/embed.d.ts +28 -0
- package/dist/runtime/findtool/embed.d.ts.map +1 -0
- package/dist/runtime/findtool/embed.js +85 -0
- package/dist/runtime/findtool/embed.js.map +1 -0
- package/dist/runtime/findtool/index.d.ts +52 -0
- package/dist/runtime/findtool/index.d.ts.map +1 -0
- package/dist/runtime/findtool/index.js +78 -0
- package/dist/runtime/findtool/index.js.map +1 -0
- package/dist/runtime/findtool/vector-index.d.ts +53 -0
- package/dist/runtime/findtool/vector-index.d.ts.map +1 -0
- package/dist/runtime/findtool/vector-index.js +71 -0
- package/dist/runtime/findtool/vector-index.js.map +1 -0
- package/dist/runtime/helpers/budget.d.ts +27 -0
- package/dist/runtime/helpers/budget.d.ts.map +1 -0
- package/dist/runtime/helpers/budget.js +103 -0
- package/dist/runtime/helpers/budget.js.map +1 -0
- package/dist/runtime/helpers/compact.d.ts +32 -0
- package/dist/runtime/helpers/compact.d.ts.map +1 -0
- package/dist/runtime/helpers/compact.js +93 -0
- package/dist/runtime/helpers/compact.js.map +1 -0
- package/dist/runtime/helpers/delta.d.ts +45 -0
- package/dist/runtime/helpers/delta.d.ts.map +1 -0
- package/dist/runtime/helpers/delta.js +116 -0
- package/dist/runtime/helpers/delta.js.map +1 -0
- package/dist/runtime/helpers/index.d.ts +16 -0
- package/dist/runtime/helpers/index.d.ts.map +1 -0
- package/dist/runtime/helpers/index.js +13 -0
- package/dist/runtime/helpers/index.js.map +1 -0
- package/dist/runtime/helpers/summarize.d.ts +24 -0
- package/dist/runtime/helpers/summarize.d.ts.map +1 -0
- package/dist/runtime/helpers/summarize.js +124 -0
- package/dist/runtime/helpers/summarize.js.map +1 -0
- package/dist/runtime/helpers/worker-preload.d.ts +25 -0
- package/dist/runtime/helpers/worker-preload.d.ts.map +1 -0
- package/dist/runtime/helpers/worker-preload.js +223 -0
- package/dist/runtime/helpers/worker-preload.js.map +1 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/pool/index.d.ts +11 -0
- package/dist/runtime/pool/index.d.ts.map +1 -0
- package/dist/runtime/pool/index.js +8 -0
- package/dist/runtime/pool/index.js.map +1 -0
- package/dist/runtime/pool/recycle.d.ts +44 -0
- package/dist/runtime/pool/recycle.d.ts.map +1 -0
- package/dist/runtime/pool/recycle.js +50 -0
- package/dist/runtime/pool/recycle.js.map +1 -0
- package/dist/runtime/pool/worker-pool.d.ts +77 -0
- package/dist/runtime/pool/worker-pool.d.ts.map +1 -0
- package/dist/runtime/pool/worker-pool.js +216 -0
- package/dist/runtime/pool/worker-pool.js.map +1 -0
- package/dist/runtime/pool/worker.d.ts +80 -0
- package/dist/runtime/pool/worker.d.ts.map +1 -0
- package/dist/runtime/pool/worker.js +324 -0
- package/dist/runtime/pool/worker.js.map +1 -0
- package/dist/server/mcp-server.d.ts +1 -0
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/mcp-server.js +423 -2
- package/dist/server/mcp-server.js.map +1 -1
- package/dist/server/passthrough-registrar.d.ts +73 -0
- package/dist/server/passthrough-registrar.d.ts.map +1 -0
- package/dist/server/passthrough-registrar.js +110 -0
- package/dist/server/passthrough-registrar.js.map +1 -0
- package/dist/skills/skills-engine.d.ts +9 -1
- package/dist/skills/skills-engine.d.ts.map +1 -1
- package/dist/skills/skills-engine.js +20 -3
- package/dist/skills/skills-engine.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/tokenize.d.ts +55 -0
- package/dist/utils/tokenize.d.ts.map +1 -0
- package/dist/utils/tokenize.js +205 -0
- package/dist/utils/tokenize.js.map +1 -0
- package/dist/version.d.ts +3 -3
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +3 -3
- package/dist/version.js.map +1 -1
- package/package.json +12 -2
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox `mcp.shared.*` API.
|
|
3
|
+
*
|
|
4
|
+
* Provides the shared KV, lock, broadcast, and subscribe surfaces that are
|
|
5
|
+
* injected into the sandbox runtime when a DaemonClient is available.
|
|
6
|
+
*
|
|
7
|
+
* When no daemon is available (v2 mode), all operations are no-ops or return
|
|
8
|
+
* null so existing code paths are not broken.
|
|
9
|
+
*
|
|
10
|
+
* This module is imported by the worker preload hook (Agent D's Phase 5 hook)
|
|
11
|
+
* via:
|
|
12
|
+
*
|
|
13
|
+
* import { createSharedApi } from '../daemon/sandbox-api.js';
|
|
14
|
+
* const mcp = { ..., shared: createSharedApi(daemonClient) };
|
|
15
|
+
*
|
|
16
|
+
* @module daemon/sandbox-api
|
|
17
|
+
*/
|
|
18
|
+
import type { DaemonClient } from './client.js';
|
|
19
|
+
export interface SharedKVApi {
|
|
20
|
+
get<T>(key: string): Promise<T | null>;
|
|
21
|
+
set<T>(key: string, value: T, options?: {
|
|
22
|
+
ttl?: number;
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
delete(key: string): Promise<void>;
|
|
25
|
+
list(prefix?: string): Promise<string[]>;
|
|
26
|
+
}
|
|
27
|
+
export interface SharedApi {
|
|
28
|
+
kv: SharedKVApi;
|
|
29
|
+
lock(key: string, options?: {
|
|
30
|
+
timeoutMs?: number;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
release: () => Promise<void>;
|
|
33
|
+
}>;
|
|
34
|
+
broadcast(channel: string, message: unknown): Promise<void>;
|
|
35
|
+
subscribe(channel: string, handler: (msg: unknown) => void): Promise<{
|
|
36
|
+
unsubscribe: () => void;
|
|
37
|
+
}>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Create the `mcp.shared` API bound to a live DaemonClient.
|
|
41
|
+
*
|
|
42
|
+
* Pass `null` for `client` to get a no-op stub (standalone mode).
|
|
43
|
+
*/
|
|
44
|
+
export declare function createSharedApi(client: DaemonClient | null): SharedApi;
|
|
45
|
+
//# sourceMappingURL=sandbox-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-api.d.ts","sourceRoot":"","sources":["../../src/daemon/sandbox-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACvC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,WAAW,CAAC;IAChB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC,CAAC;IAC/F,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAC;CACnG;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,CAiCtE"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox `mcp.shared.*` API.
|
|
3
|
+
*
|
|
4
|
+
* Provides the shared KV, lock, broadcast, and subscribe surfaces that are
|
|
5
|
+
* injected into the sandbox runtime when a DaemonClient is available.
|
|
6
|
+
*
|
|
7
|
+
* When no daemon is available (v2 mode), all operations are no-ops or return
|
|
8
|
+
* null so existing code paths are not broken.
|
|
9
|
+
*
|
|
10
|
+
* This module is imported by the worker preload hook (Agent D's Phase 5 hook)
|
|
11
|
+
* via:
|
|
12
|
+
*
|
|
13
|
+
* import { createSharedApi } from '../daemon/sandbox-api.js';
|
|
14
|
+
* const mcp = { ..., shared: createSharedApi(daemonClient) };
|
|
15
|
+
*
|
|
16
|
+
* @module daemon/sandbox-api
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Create the `mcp.shared` API bound to a live DaemonClient.
|
|
20
|
+
*
|
|
21
|
+
* Pass `null` for `client` to get a no-op stub (standalone mode).
|
|
22
|
+
*/
|
|
23
|
+
export function createSharedApi(client) {
|
|
24
|
+
if (client === null) {
|
|
25
|
+
return createNoopSharedApi();
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
kv: {
|
|
29
|
+
async get(key) {
|
|
30
|
+
return client.kvGet(key);
|
|
31
|
+
},
|
|
32
|
+
async set(key, value, options) {
|
|
33
|
+
return client.kvSet(key, value, options);
|
|
34
|
+
},
|
|
35
|
+
async delete(key) {
|
|
36
|
+
return client.kvDelete(key);
|
|
37
|
+
},
|
|
38
|
+
async list(prefix) {
|
|
39
|
+
return client.kvList(prefix);
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
async lock(key, options) {
|
|
43
|
+
return client.lockAcquire(key, options);
|
|
44
|
+
},
|
|
45
|
+
async broadcast(channel, message) {
|
|
46
|
+
return client.broadcast(channel, message);
|
|
47
|
+
},
|
|
48
|
+
async subscribe(channel, handler) {
|
|
49
|
+
return Promise.resolve(client.subscribe(channel, handler));
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* No-op shared API for when no daemon is available (v2 standalone mode).
|
|
55
|
+
* All KV operations return null / empty results; locks are immediate no-ops.
|
|
56
|
+
*/
|
|
57
|
+
function createNoopSharedApi() {
|
|
58
|
+
return {
|
|
59
|
+
kv: {
|
|
60
|
+
async get(_key) { return null; },
|
|
61
|
+
async set(_key, _value) { },
|
|
62
|
+
async delete(_key) { },
|
|
63
|
+
async list(_prefix) { return []; },
|
|
64
|
+
},
|
|
65
|
+
async lock(_key) {
|
|
66
|
+
return { release: async () => { } };
|
|
67
|
+
},
|
|
68
|
+
async broadcast(_channel, _message) { },
|
|
69
|
+
async subscribe(_channel, _handler) {
|
|
70
|
+
return { unsubscribe: () => { } };
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=sandbox-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-api.js","sourceRoot":"","sources":["../../src/daemon/sandbox-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAkBH;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAA2B;IACzD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,mBAAmB,EAAE,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,EAAE,EAAE;YACF,KAAK,CAAC,GAAG,CAAI,GAAW;gBACtB,OAAO,MAAM,CAAC,KAAK,CAAI,GAAG,CAAC,CAAC;YAC9B,CAAC;YACD,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,KAAQ,EAAE,OAA0B;gBAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAC3C,CAAC;YACD,KAAK,CAAC,MAAM,CAAC,GAAW;gBACtB,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9B,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,MAAe;gBACxB,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;SACF;QAED,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,OAAgC;YACtD,OAAO,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;QAED,KAAK,CAAC,SAAS,CAAC,OAAe,EAAE,OAAgB;YAC/C,OAAO,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;QAED,KAAK,CAAC,SAAS,CAAC,OAAe,EAAE,OAA+B;YAC9D,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7D,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB;IAC1B,OAAO;QACL,EAAE,EAAE;YACF,KAAK,CAAC,GAAG,CAAI,IAAY,IAAuB,OAAO,IAAI,CAAC,CAAC,CAAC;YAC9D,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,MAAe,IAAkB,CAAC;YAC1D,KAAK,CAAC,MAAM,CAAC,IAAY,IAAkB,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAC,OAAgB,IAAuB,OAAO,EAAE,CAAC,CAAC,CAAC;SAC/D;QACD,KAAK,CAAC,IAAI,CAAC,IAAY;YACrB,OAAO,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC,EAAE,CAAC;QACrC,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,QAAgB,EAAE,QAAiB,IAAG,CAAC;QACvD,KAAK,CAAC,SAAS,CAAC,QAAgB,EAAE,QAAgC;YAChE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Conductor Daemon Server.
|
|
3
|
+
*
|
|
4
|
+
* Listens on a Unix domain socket (primary) and optionally a TCP port (for
|
|
5
|
+
* Tailscale-mesh clients). Enforces HMAC-SHA256 auth on every connection using
|
|
6
|
+
* the shared secret loaded from `~/.mcp-conductor/daemon-auth.json`.
|
|
7
|
+
*
|
|
8
|
+
* Protocol (newline-delimited JSON):
|
|
9
|
+
* Client → Server: { id, method, params }
|
|
10
|
+
* Server → Client: { id, result } | { id, error }
|
|
11
|
+
*
|
|
12
|
+
* The daemon owns a SharedKV, SharedLock, and in-process pub/sub bus that all
|
|
13
|
+
* connected clients share.
|
|
14
|
+
*
|
|
15
|
+
* @module daemon/server
|
|
16
|
+
*/
|
|
17
|
+
import { SharedKV } from './shared-kv.js';
|
|
18
|
+
import { SharedLock } from './shared-lock.js';
|
|
19
|
+
export interface DaemonStats {
|
|
20
|
+
uptime: number;
|
|
21
|
+
connectedClients: number;
|
|
22
|
+
kvKeys: number;
|
|
23
|
+
activeLocks: boolean;
|
|
24
|
+
requestsHandled: number;
|
|
25
|
+
}
|
|
26
|
+
export interface DaemonServerOptions {
|
|
27
|
+
socketPath?: string;
|
|
28
|
+
tcpPort?: number;
|
|
29
|
+
tailscaleHostname?: string;
|
|
30
|
+
auth?: {
|
|
31
|
+
sharedSecretPath?: string;
|
|
32
|
+
sharedSecret?: string;
|
|
33
|
+
};
|
|
34
|
+
kvOptions?: ConstructorParameters<typeof SharedKV>[0];
|
|
35
|
+
}
|
|
36
|
+
export declare class DaemonServer {
|
|
37
|
+
private readonly socketPath;
|
|
38
|
+
private readonly tcpPort?;
|
|
39
|
+
private readonly sharedSecret;
|
|
40
|
+
private readonly kv;
|
|
41
|
+
private readonly lock;
|
|
42
|
+
private readonly bus;
|
|
43
|
+
private unixServer?;
|
|
44
|
+
private tcpServer?;
|
|
45
|
+
/** Map from socket to per-client state (including lock handles). */
|
|
46
|
+
private readonly clients;
|
|
47
|
+
private readonly startTime;
|
|
48
|
+
private requestsHandled;
|
|
49
|
+
private running;
|
|
50
|
+
constructor(options?: DaemonServerOptions);
|
|
51
|
+
start(): Promise<void>;
|
|
52
|
+
shutdown(): Promise<void>;
|
|
53
|
+
stats(): DaemonStats;
|
|
54
|
+
private startUnixServer;
|
|
55
|
+
private startTcpServer;
|
|
56
|
+
private closeServer;
|
|
57
|
+
private handleConnection;
|
|
58
|
+
private handleAuth;
|
|
59
|
+
private handleRequest;
|
|
60
|
+
private dispatch;
|
|
61
|
+
private sendRaw;
|
|
62
|
+
get kvStore(): SharedKV;
|
|
63
|
+
get lockRegistry(): SharedLock;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAWH,OAAO,EAAE,QAAQ,EAAqB,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAmB,MAAM,kBAAkB,CAAC;AAqF/D,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACzB;AAMD,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE;QACL,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,SAAS,CAAC,EAAE,qBAAqB,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;CACvD;AAMD,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAmB;IAEvC,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,mBAAwB;IAevC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B/B,KAAK,IAAI,WAAW;IAcpB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,gBAAgB;IA2DxB,OAAO,CAAC,UAAU;YAgCJ,aAAa;YAcb,QAAQ;IA0FtB,OAAO,CAAC,OAAO;IAcf,IAAI,OAAO,IAAI,QAAQ,CAAoB;IAC3C,IAAI,YAAY,IAAI,UAAU,CAAsB;CACrD"}
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Conductor Daemon Server.
|
|
3
|
+
*
|
|
4
|
+
* Listens on a Unix domain socket (primary) and optionally a TCP port (for
|
|
5
|
+
* Tailscale-mesh clients). Enforces HMAC-SHA256 auth on every connection using
|
|
6
|
+
* the shared secret loaded from `~/.mcp-conductor/daemon-auth.json`.
|
|
7
|
+
*
|
|
8
|
+
* Protocol (newline-delimited JSON):
|
|
9
|
+
* Client → Server: { id, method, params }
|
|
10
|
+
* Server → Client: { id, result } | { id, error }
|
|
11
|
+
*
|
|
12
|
+
* The daemon owns a SharedKV, SharedLock, and in-process pub/sub bus that all
|
|
13
|
+
* connected clients share.
|
|
14
|
+
*
|
|
15
|
+
* @module daemon/server
|
|
16
|
+
*/
|
|
17
|
+
import { createServer } from 'node:net';
|
|
18
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, chmodSync, unlinkSync, } from 'node:fs';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
import { homedir } from 'node:os';
|
|
21
|
+
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
22
|
+
import { EventEmitter } from 'node:events';
|
|
23
|
+
import { logger } from '../utils/logger.js';
|
|
24
|
+
import { SharedKV } from './shared-kv.js';
|
|
25
|
+
import { SharedLock } from './shared-lock.js';
|
|
26
|
+
const DEFAULT_AUTH_PATH = join(homedir(), '.mcp-conductor', 'daemon-auth.json');
|
|
27
|
+
const DEFAULT_SOCKET_PATH = join(homedir(), '.mcp-conductor', 'daemon.sock');
|
|
28
|
+
const CONDUCTOR_DIR = join(homedir(), '.mcp-conductor');
|
|
29
|
+
function loadOrCreateSecret(authPath) {
|
|
30
|
+
if (existsSync(authPath)) {
|
|
31
|
+
const raw = readFileSync(authPath, 'utf-8');
|
|
32
|
+
return JSON.parse(raw).sharedSecret;
|
|
33
|
+
}
|
|
34
|
+
mkdirSync(CONDUCTOR_DIR, { recursive: true });
|
|
35
|
+
const secret = randomBytes(32).toString('hex');
|
|
36
|
+
const content = { sharedSecret: secret };
|
|
37
|
+
writeFileSync(authPath, JSON.stringify(content, null, 2), 'utf-8');
|
|
38
|
+
chmodSync(authPath, 0o600);
|
|
39
|
+
logger.info('DaemonServer: generated new shared secret', { authPath });
|
|
40
|
+
return secret;
|
|
41
|
+
}
|
|
42
|
+
function hmacToken(secret, nonce) {
|
|
43
|
+
return createHmac('sha256', secret).update(nonce).digest('hex');
|
|
44
|
+
}
|
|
45
|
+
class PubSubBus {
|
|
46
|
+
emitter = new EventEmitter();
|
|
47
|
+
subscribe(channel, handler) {
|
|
48
|
+
this.emitter.on(channel, handler);
|
|
49
|
+
return { unsubscribe: () => this.emitter.off(channel, handler) };
|
|
50
|
+
}
|
|
51
|
+
broadcast(channel, message) {
|
|
52
|
+
this.emitter.emit(channel, message);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// DaemonServer
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
export class DaemonServer {
|
|
59
|
+
socketPath;
|
|
60
|
+
tcpPort;
|
|
61
|
+
sharedSecret;
|
|
62
|
+
kv;
|
|
63
|
+
lock;
|
|
64
|
+
bus = new PubSubBus();
|
|
65
|
+
unixServer;
|
|
66
|
+
tcpServer;
|
|
67
|
+
/** Map from socket to per-client state (including lock handles). */
|
|
68
|
+
clients = new Map();
|
|
69
|
+
startTime = Date.now();
|
|
70
|
+
requestsHandled = 0;
|
|
71
|
+
running = false;
|
|
72
|
+
constructor(options = {}) {
|
|
73
|
+
this.socketPath = options.socketPath ?? DEFAULT_SOCKET_PATH;
|
|
74
|
+
this.tcpPort = options.tcpPort;
|
|
75
|
+
const authPath = options.auth?.sharedSecretPath ?? DEFAULT_AUTH_PATH;
|
|
76
|
+
this.sharedSecret = options.auth?.sharedSecret ?? loadOrCreateSecret(authPath);
|
|
77
|
+
this.kv = new SharedKV(options.kvOptions);
|
|
78
|
+
this.lock = new SharedLock();
|
|
79
|
+
}
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Lifecycle
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
async start() {
|
|
84
|
+
if (this.running)
|
|
85
|
+
throw new Error('DaemonServer is already running');
|
|
86
|
+
this.running = true;
|
|
87
|
+
mkdirSync(CONDUCTOR_DIR, { recursive: true });
|
|
88
|
+
if (existsSync(this.socketPath)) {
|
|
89
|
+
unlinkSync(this.socketPath);
|
|
90
|
+
}
|
|
91
|
+
await this.startUnixServer();
|
|
92
|
+
if (this.tcpPort !== undefined) {
|
|
93
|
+
await this.startTcpServer();
|
|
94
|
+
}
|
|
95
|
+
logger.info('DaemonServer: started', {
|
|
96
|
+
socketPath: this.socketPath,
|
|
97
|
+
tcpPort: this.tcpPort,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async shutdown() {
|
|
101
|
+
this.running = false;
|
|
102
|
+
const closePromises = [];
|
|
103
|
+
for (const [socket] of this.clients) {
|
|
104
|
+
closePromises.push(new Promise((resolve) => {
|
|
105
|
+
socket.once('close', resolve);
|
|
106
|
+
socket.end();
|
|
107
|
+
setTimeout(() => { socket.destroy(); resolve(); }, 2000);
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
await Promise.all(closePromises);
|
|
111
|
+
this.clients.clear();
|
|
112
|
+
await Promise.all([
|
|
113
|
+
this.closeServer(this.unixServer),
|
|
114
|
+
this.closeServer(this.tcpServer),
|
|
115
|
+
]);
|
|
116
|
+
if (existsSync(this.socketPath)) {
|
|
117
|
+
try {
|
|
118
|
+
unlinkSync(this.socketPath);
|
|
119
|
+
}
|
|
120
|
+
catch { /* ignore */ }
|
|
121
|
+
}
|
|
122
|
+
await this.kv.shutdown();
|
|
123
|
+
logger.info('DaemonServer: shutdown complete');
|
|
124
|
+
}
|
|
125
|
+
stats() {
|
|
126
|
+
return {
|
|
127
|
+
uptime: Date.now() - this.startTime,
|
|
128
|
+
connectedClients: this.clients.size,
|
|
129
|
+
kvKeys: this.kv.size,
|
|
130
|
+
activeLocks: this.lock.hasActiveLocks,
|
|
131
|
+
requestsHandled: this.requestsHandled,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// Server startup helpers
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
startUnixServer() {
|
|
138
|
+
return new Promise((resolve, reject) => {
|
|
139
|
+
const server = createServer((socket) => this.handleConnection(socket));
|
|
140
|
+
this.unixServer = server;
|
|
141
|
+
server.once('error', reject);
|
|
142
|
+
server.listen(this.socketPath, () => {
|
|
143
|
+
try {
|
|
144
|
+
chmodSync(this.socketPath, 0o600);
|
|
145
|
+
}
|
|
146
|
+
catch { /* ignore */ }
|
|
147
|
+
server.removeListener('error', reject);
|
|
148
|
+
server.on('error', (err) => {
|
|
149
|
+
logger.error('DaemonServer Unix socket error', { error: String(err) });
|
|
150
|
+
});
|
|
151
|
+
resolve();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
startTcpServer() {
|
|
156
|
+
return new Promise((resolve, reject) => {
|
|
157
|
+
const server = createServer((socket) => this.handleConnection(socket));
|
|
158
|
+
this.tcpServer = server;
|
|
159
|
+
server.once('error', reject);
|
|
160
|
+
server.listen(this.tcpPort, '127.0.0.1', () => {
|
|
161
|
+
server.removeListener('error', reject);
|
|
162
|
+
server.on('error', (err) => {
|
|
163
|
+
logger.error('DaemonServer TCP error', { error: String(err) });
|
|
164
|
+
});
|
|
165
|
+
logger.info('DaemonServer: TCP listening', { port: this.tcpPort });
|
|
166
|
+
resolve();
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
closeServer(server) {
|
|
171
|
+
if (!server)
|
|
172
|
+
return Promise.resolve();
|
|
173
|
+
return new Promise((resolve) => {
|
|
174
|
+
server.close(() => resolve());
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
// Connection handling
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
handleConnection(socket) {
|
|
181
|
+
const state = { socket, lockHandles: new Map() };
|
|
182
|
+
this.clients.set(socket, state);
|
|
183
|
+
logger.debug('DaemonServer: client connected', { clients: this.clients.size });
|
|
184
|
+
let authenticated = false;
|
|
185
|
+
let buffer = '';
|
|
186
|
+
const nonce = randomBytes(16).toString('hex');
|
|
187
|
+
this.sendRaw(socket, { id: '__auth_challenge__', result: { nonce } });
|
|
188
|
+
socket.setEncoding('utf-8');
|
|
189
|
+
socket.on('data', (chunk) => {
|
|
190
|
+
buffer += chunk;
|
|
191
|
+
const lines = buffer.split('\n');
|
|
192
|
+
buffer = lines.pop() ?? '';
|
|
193
|
+
for (const line of lines) {
|
|
194
|
+
const trimmed = line.trim();
|
|
195
|
+
if (!trimmed)
|
|
196
|
+
continue;
|
|
197
|
+
try {
|
|
198
|
+
const msg = JSON.parse(trimmed);
|
|
199
|
+
if (!authenticated) {
|
|
200
|
+
this.handleAuth(socket, msg, nonce, (ok) => {
|
|
201
|
+
authenticated = ok;
|
|
202
|
+
if (!ok)
|
|
203
|
+
socket.destroy();
|
|
204
|
+
});
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
// Handle requests without blocking the data handler.
|
|
208
|
+
this.handleRequest(socket, state, msg).catch((err) => {
|
|
209
|
+
logger.error('DaemonServer: request handler error', { error: String(err) });
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
logger.warn('DaemonServer: malformed JSON from client');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
socket.on('close', () => {
|
|
218
|
+
// Release all locks held by this client on disconnect.
|
|
219
|
+
for (const [key, handle] of state.lockHandles) {
|
|
220
|
+
handle.release().catch(() => { });
|
|
221
|
+
logger.debug('DaemonServer: auto-released lock on disconnect', { key });
|
|
222
|
+
}
|
|
223
|
+
state.lockHandles.clear();
|
|
224
|
+
this.clients.delete(socket);
|
|
225
|
+
logger.debug('DaemonServer: client disconnected', { clients: this.clients.size });
|
|
226
|
+
});
|
|
227
|
+
socket.on('error', (err) => {
|
|
228
|
+
logger.debug('DaemonServer: client socket error', { error: String(err) });
|
|
229
|
+
this.clients.delete(socket);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
handleAuth(socket, msg, nonce, callback) {
|
|
233
|
+
const params = msg.params;
|
|
234
|
+
const token = params?.token;
|
|
235
|
+
if (!token) {
|
|
236
|
+
this.sendRaw(socket, { id: msg.id, error: { code: 401, message: 'Missing auth token' } });
|
|
237
|
+
callback(false);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const expected = hmacToken(this.sharedSecret, nonce);
|
|
241
|
+
const expectedBuf = Buffer.from(expected, 'utf-8');
|
|
242
|
+
const providedBuf = Buffer.from(token, 'utf-8');
|
|
243
|
+
const ok = expectedBuf.length === providedBuf.length &&
|
|
244
|
+
timingSafeEqual(expectedBuf, providedBuf);
|
|
245
|
+
if (ok) {
|
|
246
|
+
this.sendRaw(socket, { id: msg.id, result: { authenticated: true } });
|
|
247
|
+
callback(true);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
this.sendRaw(socket, { id: msg.id, error: { code: 401, message: 'Invalid auth token' } });
|
|
251
|
+
callback(false);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
async handleRequest(socket, state, msg) {
|
|
255
|
+
this.requestsHandled++;
|
|
256
|
+
try {
|
|
257
|
+
const result = await this.dispatch(msg.method, msg.params, socket, state);
|
|
258
|
+
this.sendRaw(socket, { id: msg.id, result });
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
this.sendRaw(socket, {
|
|
262
|
+
id: msg.id,
|
|
263
|
+
error: { code: 500, message: String(err) },
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
async dispatch(method, params, socket, state) {
|
|
268
|
+
const p = params;
|
|
269
|
+
switch (method) {
|
|
270
|
+
// KV
|
|
271
|
+
case 'kv.get':
|
|
272
|
+
return this.kv.get(p?.key);
|
|
273
|
+
case 'kv.set':
|
|
274
|
+
this.kv.set(p?.key, p?.value, p?.options);
|
|
275
|
+
return null;
|
|
276
|
+
case 'kv.delete':
|
|
277
|
+
this.kv.delete(p?.key);
|
|
278
|
+
return null;
|
|
279
|
+
case 'kv.list':
|
|
280
|
+
return this.kv.list(p?.prefix);
|
|
281
|
+
// Locks
|
|
282
|
+
case 'lock.acquire': {
|
|
283
|
+
const key = p?.key;
|
|
284
|
+
const timeoutMs = p?.timeoutMs;
|
|
285
|
+
// Acquire the lock — this awaits until the lock is free.
|
|
286
|
+
// Node.js is async; concurrent awaits on different sockets yield to
|
|
287
|
+
// the event loop, so release RPCs from other clients can proceed.
|
|
288
|
+
const handle = await this.lock.acquire(key, { timeoutMs });
|
|
289
|
+
// Persist the handle so lock.release can find and call it.
|
|
290
|
+
// Use a composite key of lockKey + requestId to support multiple
|
|
291
|
+
// concurrent locks per client on different keys.
|
|
292
|
+
state.lockHandles.set(key, handle);
|
|
293
|
+
return { acquired: true, key };
|
|
294
|
+
}
|
|
295
|
+
case 'lock.release': {
|
|
296
|
+
const key = p?.key;
|
|
297
|
+
const handle = state.lockHandles.get(key);
|
|
298
|
+
if (handle) {
|
|
299
|
+
state.lockHandles.delete(key);
|
|
300
|
+
await handle.release();
|
|
301
|
+
return { released: true };
|
|
302
|
+
}
|
|
303
|
+
return { released: false, reason: 'no handle found for key' };
|
|
304
|
+
}
|
|
305
|
+
// Pub/sub
|
|
306
|
+
case 'broadcast': {
|
|
307
|
+
const channel = p?.channel;
|
|
308
|
+
const message = p?.message;
|
|
309
|
+
this.bus.broadcast(channel, message);
|
|
310
|
+
const pushPayload = JSON.stringify({ id: '__push__', result: { channel, message } });
|
|
311
|
+
for (const [client] of this.clients) {
|
|
312
|
+
if (!client.destroyed) {
|
|
313
|
+
client.write(pushPayload + '\n');
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
case 'subscribe':
|
|
319
|
+
return { subscribed: true };
|
|
320
|
+
// Meta
|
|
321
|
+
case 'ping':
|
|
322
|
+
return { pong: true };
|
|
323
|
+
case 'stats':
|
|
324
|
+
return this.stats();
|
|
325
|
+
case 'tool.call':
|
|
326
|
+
// Placeholder — actual tool dispatch handled by the MCP server layer.
|
|
327
|
+
throw new Error('tool.call not implemented in daemon v3.0 (agents use direct mode)');
|
|
328
|
+
default:
|
|
329
|
+
throw new Error(`Unknown method: ${method}`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// ---------------------------------------------------------------------------
|
|
333
|
+
// Wire helpers
|
|
334
|
+
// ---------------------------------------------------------------------------
|
|
335
|
+
sendRaw(socket, msg) {
|
|
336
|
+
if (!socket.destroyed) {
|
|
337
|
+
try {
|
|
338
|
+
socket.write(JSON.stringify(msg) + '\n');
|
|
339
|
+
}
|
|
340
|
+
catch (err) {
|
|
341
|
+
logger.debug('DaemonServer: failed to write to client', { error: String(err) });
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// ---------------------------------------------------------------------------
|
|
346
|
+
// Expose internals for integration tests
|
|
347
|
+
// ---------------------------------------------------------------------------
|
|
348
|
+
get kvStore() { return this.kv; }
|
|
349
|
+
get lockRegistry() { return this.lock; }
|
|
350
|
+
}
|
|
351
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Key-Value Store for MCP Conductor Daemon.
|
|
3
|
+
*
|
|
4
|
+
* Provides in-memory storage with optional disk persistence and TTL support.
|
|
5
|
+
* Each KV entry can carry an expiry timestamp; a background sweep runs every
|
|
6
|
+
* 30 s to evict stale entries and sync the on-disk snapshot.
|
|
7
|
+
*
|
|
8
|
+
* @module daemon/shared-kv
|
|
9
|
+
*/
|
|
10
|
+
/** Options accepted by {@link SharedKV.set}. */
|
|
11
|
+
export interface KVSetOptions {
|
|
12
|
+
/** Time-to-live in milliseconds. Entry is deleted after this duration. */
|
|
13
|
+
ttl?: number;
|
|
14
|
+
}
|
|
15
|
+
/** Options for constructing a {@link SharedKV} instance. */
|
|
16
|
+
export interface SharedKVOptions {
|
|
17
|
+
/** Directory for disk persistence. Defaults to `~/.mcp-conductor/kv/`. */
|
|
18
|
+
persistDir?: string;
|
|
19
|
+
/** Sweep interval for TTL expiry, in milliseconds. Defaults to 30 000. */
|
|
20
|
+
sweepIntervalMs?: number;
|
|
21
|
+
/** Namespace / shard name used for the snapshot file. Defaults to `default`. */
|
|
22
|
+
namespace?: string;
|
|
23
|
+
/** Whether to skip loading from disk on construction. Useful in tests. */
|
|
24
|
+
skipLoad?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Shared key-value store with TTL expiry and disk persistence.
|
|
28
|
+
*
|
|
29
|
+
* Thread-safety note: Node.js is single-threaded; all mutations are
|
|
30
|
+
* synchronous operations on the in-memory Map, so no locking is required
|
|
31
|
+
* within a single process. Cross-process sharing is handled by the daemon
|
|
32
|
+
* server, which owns a single SharedKV instance.
|
|
33
|
+
*/
|
|
34
|
+
export declare class SharedKV {
|
|
35
|
+
private readonly store;
|
|
36
|
+
private readonly persistDir;
|
|
37
|
+
private readonly snapshotPath;
|
|
38
|
+
private readonly sweepIntervalMs;
|
|
39
|
+
private sweepTimer;
|
|
40
|
+
private dirty;
|
|
41
|
+
constructor(options?: SharedKVOptions);
|
|
42
|
+
/**
|
|
43
|
+
* Retrieve a value by key.
|
|
44
|
+
* Returns `null` if the key does not exist or has expired.
|
|
45
|
+
*/
|
|
46
|
+
get<T>(key: string): T | null;
|
|
47
|
+
/**
|
|
48
|
+
* Store a value, with an optional TTL.
|
|
49
|
+
*/
|
|
50
|
+
set<T>(key: string, value: T, options?: KVSetOptions): void;
|
|
51
|
+
/**
|
|
52
|
+
* Delete a key. No-op if the key does not exist.
|
|
53
|
+
*/
|
|
54
|
+
delete(key: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* List all non-expired keys, optionally filtered by a string prefix.
|
|
57
|
+
*/
|
|
58
|
+
list(prefix?: string): string[];
|
|
59
|
+
/**
|
|
60
|
+
* Remove all entries (optionally matching a prefix).
|
|
61
|
+
*/
|
|
62
|
+
clear(prefix?: string): void;
|
|
63
|
+
/** Total number of (potentially expired) entries currently held in memory. */
|
|
64
|
+
get size(): number;
|
|
65
|
+
/**
|
|
66
|
+
* Flush the in-memory state to disk and stop the sweep timer.
|
|
67
|
+
* Call this before process exit or daemon shutdown.
|
|
68
|
+
*/
|
|
69
|
+
shutdown(): Promise<void>;
|
|
70
|
+
private loadFromDisk;
|
|
71
|
+
/** Write the current (non-expired) state to disk. */
|
|
72
|
+
flushToDisk(): void;
|
|
73
|
+
private startSweep;
|
|
74
|
+
private evictExpired;
|
|
75
|
+
/**
|
|
76
|
+
* Delete all snapshot files under `persistDir`.
|
|
77
|
+
* Used in tests for clean-up between runs.
|
|
78
|
+
*/
|
|
79
|
+
static clearAllSnapshots(persistDir: string): void;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=shared-kv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-kv.d.ts","sourceRoot":"","sources":["../../src/daemon/shared-kv.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,gDAAgD;AAChD,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAeD,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,GAAE,eAAoB;IAgBzC;;;OAGG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAa7B;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAS3D;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMzB;;OAEG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAY/B;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAW5B,8EAA8E;IAC9E,IAAI,IAAI,IAAI,MAAM,CAEjB;IAMD;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAa/B,OAAO,CAAC,YAAY;IA2BpB,qDAAqD;IACrD,WAAW,IAAI,IAAI;IAqBnB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,YAAY;IAUpB;;;OAGG;IACH,MAAM,CAAC,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;CAQnD"}
|