@darkiceinteractive/mcp-conductor 1.1.0 → 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 +65 -1
- package/dist/bridge/http-server.d.ts.map +1 -1
- package/dist/bridge/http-server.js +192 -7
- 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/bridge/session-registry.d.ts +64 -0
- package/dist/bridge/session-registry.d.ts.map +1 -0
- package/dist/bridge/session-registry.js +124 -0
- package/dist/bridge/session-registry.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 +10 -0
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +14 -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 +19 -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 +12 -0
- package/dist/runtime/executor.d.ts.map +1 -1
- package/dist/runtime/executor.js +148 -16
- 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 +6 -0
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/mcp-server.js +610 -45
- 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 +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +5 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/orphan-watch.d.ts +34 -0
- package/dist/utils/orphan-watch.d.ts.map +1 -0
- package/dist/utils/orphan-watch.js +54 -0
- package/dist/utils/orphan-watch.js.map +1 -0
- package/dist/utils/redact.d.ts +15 -0
- package/dist/utils/redact.d.ts.map +1 -0
- package/dist/utils/redact.js +48 -0
- package/dist/utils/redact.js.map +1 -0
- 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 +13 -3
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* test-server command: transient connect, list tools, latency probe.
|
|
3
|
+
* @module cli/commands/test-server
|
|
4
|
+
*/
|
|
5
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
6
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
7
|
+
import { minimalChildEnv } from '../../utils/index.js';
|
|
8
|
+
import { loadConductorConfig } from '../../config/index.js';
|
|
9
|
+
/**
|
|
10
|
+
* Transiently connect to an MCP server, list its tools and measure latency.
|
|
11
|
+
* The connection is always closed afterwards — no persistent registration.
|
|
12
|
+
*/
|
|
13
|
+
export async function testServer(options) {
|
|
14
|
+
const name = options.name ?? 'unnamed';
|
|
15
|
+
let command;
|
|
16
|
+
let args;
|
|
17
|
+
let env;
|
|
18
|
+
if (options.command) {
|
|
19
|
+
command = options.command;
|
|
20
|
+
args = options.args ?? [];
|
|
21
|
+
env = options.env;
|
|
22
|
+
}
|
|
23
|
+
else if (options.name) {
|
|
24
|
+
const config = loadConductorConfig();
|
|
25
|
+
if (!config) {
|
|
26
|
+
return { success: false, serverName: name, connected: false, toolCount: 0, tools: [], latencyMs: 0, error: 'No conductor config found' };
|
|
27
|
+
}
|
|
28
|
+
const serverDef = config.servers[options.name];
|
|
29
|
+
if (!serverDef) {
|
|
30
|
+
return { success: false, serverName: name, connected: false, toolCount: 0, tools: [], latencyMs: 0, error: `Server '${options.name}' not found in conductor config` };
|
|
31
|
+
}
|
|
32
|
+
command = serverDef.command;
|
|
33
|
+
args = serverDef.args ?? [];
|
|
34
|
+
env = serverDef.env;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
return { success: false, serverName: name, connected: false, toolCount: 0, tools: [], latencyMs: 0, error: 'Either name or command must be provided' };
|
|
38
|
+
}
|
|
39
|
+
const timeoutMs = options.timeoutMs ?? 15000;
|
|
40
|
+
const t0 = Date.now();
|
|
41
|
+
const client = new Client({ name: 'mcp-conductor-test', version: '1.0.0' });
|
|
42
|
+
const transport = new StdioClientTransport({
|
|
43
|
+
command,
|
|
44
|
+
args,
|
|
45
|
+
env: { ...minimalChildEnv(), ...(env ?? {}) },
|
|
46
|
+
});
|
|
47
|
+
try {
|
|
48
|
+
const connectPromise = client.connect(transport);
|
|
49
|
+
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Connection timed out after ${timeoutMs}ms`)), timeoutMs));
|
|
50
|
+
await Promise.race([connectPromise, timeoutPromise]);
|
|
51
|
+
const listResult = await client.listTools();
|
|
52
|
+
const latencyMs = Date.now() - t0;
|
|
53
|
+
const tools = (listResult.tools ?? []).map((t) => ({
|
|
54
|
+
name: t.name,
|
|
55
|
+
description: t.description ?? '',
|
|
56
|
+
}));
|
|
57
|
+
return {
|
|
58
|
+
success: true,
|
|
59
|
+
serverName: name,
|
|
60
|
+
connected: true,
|
|
61
|
+
toolCount: tools.length,
|
|
62
|
+
tools,
|
|
63
|
+
latencyMs,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
return {
|
|
68
|
+
success: false,
|
|
69
|
+
serverName: name,
|
|
70
|
+
connected: false,
|
|
71
|
+
toolCount: 0,
|
|
72
|
+
tools: [],
|
|
73
|
+
latencyMs: Date.now() - t0,
|
|
74
|
+
error: String(err),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
try {
|
|
79
|
+
await client.close();
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// ignore cleanup errors
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=test-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-server.js","sourceRoot":"","sources":["../../../src/cli/commands/test-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daemon CLI subcommands for MCP Conductor.
|
|
3
|
+
*
|
|
4
|
+
* Designed as a self-contained module so Agent I (X2 lifecycle CLI) can
|
|
5
|
+
* import and register these commands without taking a dependency on the full
|
|
6
|
+
* daemon implementation at the top level.
|
|
7
|
+
*
|
|
8
|
+
* Usage (in the host CLI program):
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { Command } from 'commander';
|
|
12
|
+
* import { registerDaemonCommands } from './cli/daemon.js';
|
|
13
|
+
*
|
|
14
|
+
* const program = new Command();
|
|
15
|
+
* registerDaemonCommands(program);
|
|
16
|
+
* program.parse();
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Available subcommands:
|
|
20
|
+
* daemon start — Start the daemon in the background
|
|
21
|
+
* daemon stop — Stop a running daemon
|
|
22
|
+
* daemon status — Print daemon health and stats
|
|
23
|
+
* daemon logs — Tail the daemon log file
|
|
24
|
+
*
|
|
25
|
+
* @module cli/daemon
|
|
26
|
+
*/
|
|
27
|
+
declare function daemonStart(options: {
|
|
28
|
+
port?: string;
|
|
29
|
+
background?: boolean;
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
declare function daemonStop(): Promise<void>;
|
|
32
|
+
declare function daemonStatus(): Promise<void>;
|
|
33
|
+
declare function daemonLogs(options: {
|
|
34
|
+
lines?: string;
|
|
35
|
+
follow?: boolean;
|
|
36
|
+
}): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Register all daemon subcommands onto a Commander `program` instance.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* import { Command } from 'commander';
|
|
43
|
+
* import { registerDaemonCommands } from './cli/daemon.js';
|
|
44
|
+
* const program = new Command('mcp-conductor-cli');
|
|
45
|
+
* registerDaemonCommands(program);
|
|
46
|
+
* program.parse();
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function registerDaemonCommands(program: {
|
|
50
|
+
command: (name: string) => DaemonCommandBuilder;
|
|
51
|
+
}): void;
|
|
52
|
+
/** Minimal interface matching Commander's Command for type safety without the dep. */
|
|
53
|
+
interface DaemonCommandBuilder {
|
|
54
|
+
description: (d: string) => DaemonCommandBuilder;
|
|
55
|
+
option: (flags: string, description?: string, defaultValue?: string) => DaemonCommandBuilder;
|
|
56
|
+
action: (fn: (...args: unknown[]) => void | Promise<void>) => DaemonCommandBuilder;
|
|
57
|
+
command: (name: string) => DaemonCommandBuilder;
|
|
58
|
+
}
|
|
59
|
+
export { daemonStart, daemonStop, daemonStatus, daemonLogs };
|
|
60
|
+
//# sourceMappingURL=daemon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAgDH,iBAAe,WAAW,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC1F;AAED,iBAAe,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CA4BzC;AAED,iBAAe,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAoB3C;AAED,iBAAe,UAAU,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCtF;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE;IAC9C,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,oBAAoB,CAAC;CACjD,GAAG,IAAI,CAmCP;AAMD,sFAAsF;AACtF,UAAU,oBAAoB;IAC5B,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,oBAAoB,CAAC;IACjD,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,oBAAoB,CAAC;IAC7F,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,oBAAoB,CAAC;IACnF,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,oBAAoB,CAAC;CACjD;AAMD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daemon CLI subcommands for MCP Conductor.
|
|
3
|
+
*
|
|
4
|
+
* Designed as a self-contained module so Agent I (X2 lifecycle CLI) can
|
|
5
|
+
* import and register these commands without taking a dependency on the full
|
|
6
|
+
* daemon implementation at the top level.
|
|
7
|
+
*
|
|
8
|
+
* Usage (in the host CLI program):
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { Command } from 'commander';
|
|
12
|
+
* import { registerDaemonCommands } from './cli/daemon.js';
|
|
13
|
+
*
|
|
14
|
+
* const program = new Command();
|
|
15
|
+
* registerDaemonCommands(program);
|
|
16
|
+
* program.parse();
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Available subcommands:
|
|
20
|
+
* daemon start — Start the daemon in the background
|
|
21
|
+
* daemon stop — Stop a running daemon
|
|
22
|
+
* daemon status — Print daemon health and stats
|
|
23
|
+
* daemon logs — Tail the daemon log file
|
|
24
|
+
*
|
|
25
|
+
* @module cli/daemon
|
|
26
|
+
*/
|
|
27
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, statSync, createReadStream } from 'node:fs';
|
|
28
|
+
import { join } from 'node:path';
|
|
29
|
+
import { homedir } from 'node:os';
|
|
30
|
+
import { spawn } from 'node:child_process';
|
|
31
|
+
import { DaemonClient } from '../daemon/client.js';
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Paths
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
const CONDUCTOR_DIR = join(homedir(), '.mcp-conductor');
|
|
36
|
+
const PID_FILE = join(CONDUCTOR_DIR, 'daemon.pid');
|
|
37
|
+
const LOG_FILE = join(CONDUCTOR_DIR, 'daemon.log');
|
|
38
|
+
const SOCKET_PATH = join(CONDUCTOR_DIR, 'daemon.sock');
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Helpers
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
function ensureDir() {
|
|
43
|
+
mkdirSync(CONDUCTOR_DIR, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
function readPid() {
|
|
46
|
+
if (!existsSync(PID_FILE))
|
|
47
|
+
return null;
|
|
48
|
+
try {
|
|
49
|
+
return parseInt(readFileSync(PID_FILE, 'utf-8').trim(), 10);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function isRunning(pid) {
|
|
56
|
+
try {
|
|
57
|
+
process.kill(pid, 0);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Subcommand implementations
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
async function daemonStart(options) {
|
|
68
|
+
ensureDir();
|
|
69
|
+
const pid = readPid();
|
|
70
|
+
if (pid !== null && isRunning(pid)) {
|
|
71
|
+
console.log(`Daemon is already running (PID ${pid})`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const tcpPort = options.port ? parseInt(options.port, 10) : undefined;
|
|
75
|
+
// Build the daemon entry script args.
|
|
76
|
+
const args = ['--daemon-server'];
|
|
77
|
+
if (tcpPort)
|
|
78
|
+
args.push('--tcp-port', String(tcpPort));
|
|
79
|
+
// Spawn the daemon process detached.
|
|
80
|
+
const out = require('node:fs').openSync(LOG_FILE, 'a');
|
|
81
|
+
const child = spawn(process.execPath, [process.argv[1], ...args], {
|
|
82
|
+
detached: true,
|
|
83
|
+
stdio: ['ignore', out, out],
|
|
84
|
+
});
|
|
85
|
+
child.unref();
|
|
86
|
+
writeFileSync(PID_FILE, String(child.pid), 'utf-8');
|
|
87
|
+
// Brief wait for the socket to appear.
|
|
88
|
+
let ready = false;
|
|
89
|
+
for (let i = 0; i < 20; i++) {
|
|
90
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
91
|
+
if (existsSync(SOCKET_PATH)) {
|
|
92
|
+
ready = true;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (ready) {
|
|
97
|
+
console.log(`Daemon started (PID ${child.pid})`);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
console.warn(`Daemon spawned (PID ${child.pid}) but socket not yet visible. Check logs: ${LOG_FILE}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function daemonStop() {
|
|
104
|
+
const pid = readPid();
|
|
105
|
+
if (pid === null) {
|
|
106
|
+
console.log('No PID file found — daemon may not be running.');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!isRunning(pid)) {
|
|
110
|
+
console.log(`Daemon PID ${pid} is not running.`);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
process.kill(pid, 'SIGTERM');
|
|
115
|
+
// Wait up to 5 s for the process to exit.
|
|
116
|
+
for (let i = 0; i < 50; i++) {
|
|
117
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
118
|
+
if (!isRunning(pid))
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
if (!isRunning(pid)) {
|
|
122
|
+
console.log(`Daemon (PID ${pid}) stopped.`);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
console.warn(`Daemon (PID ${pid}) did not exit in 5 s. Sending SIGKILL.`);
|
|
126
|
+
process.kill(pid, 'SIGKILL');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
console.error(`Failed to stop daemon: ${String(err)}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async function daemonStatus() {
|
|
134
|
+
const pid = readPid();
|
|
135
|
+
if (pid === null || !isRunning(pid)) {
|
|
136
|
+
console.log('Daemon: STOPPED');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
console.log(`Daemon: RUNNING (PID ${pid})`);
|
|
140
|
+
// Try connecting to get live stats.
|
|
141
|
+
try {
|
|
142
|
+
const client = new DaemonClient({ connectTimeoutMs: 2000 });
|
|
143
|
+
await client.connect();
|
|
144
|
+
const stats = await client.stats();
|
|
145
|
+
console.log('Stats:', JSON.stringify(stats, null, 2));
|
|
146
|
+
await client.disconnect();
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
console.log(`(Could not fetch live stats: ${String(err)})`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async function daemonLogs(options) {
|
|
153
|
+
if (!existsSync(LOG_FILE)) {
|
|
154
|
+
console.log('No log file found at', LOG_FILE);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const n = parseInt(options.lines ?? '50', 10);
|
|
158
|
+
if (options.follow) {
|
|
159
|
+
// Simple tail -f implementation using a ReadStream.
|
|
160
|
+
const stat = statSync(LOG_FILE);
|
|
161
|
+
const stream = createReadStream(LOG_FILE, {
|
|
162
|
+
start: Math.max(0, stat.size - 8192),
|
|
163
|
+
encoding: 'utf-8',
|
|
164
|
+
});
|
|
165
|
+
stream.pipe(process.stdout);
|
|
166
|
+
stream.on('end', () => {
|
|
167
|
+
// Keep watching by polling — Node.js fs.watch is enough for a dev tool.
|
|
168
|
+
let lastSize = stat.size;
|
|
169
|
+
const interval = setInterval(() => {
|
|
170
|
+
try {
|
|
171
|
+
const newStat = statSync(LOG_FILE);
|
|
172
|
+
if (newStat.size > lastSize) {
|
|
173
|
+
const tail = createReadStream(LOG_FILE, {
|
|
174
|
+
start: lastSize,
|
|
175
|
+
encoding: 'utf-8',
|
|
176
|
+
});
|
|
177
|
+
tail.pipe(process.stdout);
|
|
178
|
+
lastSize = newStat.size;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
clearInterval(interval);
|
|
183
|
+
}
|
|
184
|
+
}, 500);
|
|
185
|
+
process.on('SIGINT', () => { clearInterval(interval); process.exit(0); });
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const content = readFileSync(LOG_FILE, 'utf-8');
|
|
190
|
+
const lines = content.split('\n').filter(Boolean);
|
|
191
|
+
const tail = lines.slice(-n).join('\n');
|
|
192
|
+
console.log(tail);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
// Registration function (Agent I integration point)
|
|
197
|
+
// ---------------------------------------------------------------------------
|
|
198
|
+
/**
|
|
199
|
+
* Register all daemon subcommands onto a Commander `program` instance.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```typescript
|
|
203
|
+
* import { Command } from 'commander';
|
|
204
|
+
* import { registerDaemonCommands } from './cli/daemon.js';
|
|
205
|
+
* const program = new Command('mcp-conductor-cli');
|
|
206
|
+
* registerDaemonCommands(program);
|
|
207
|
+
* program.parse();
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
export function registerDaemonCommands(program) {
|
|
211
|
+
const daemon = program.command('daemon').description('Manage the MCP Conductor daemon process');
|
|
212
|
+
// daemon start
|
|
213
|
+
daemon.command('start')
|
|
214
|
+
.description('Start the daemon in the background')
|
|
215
|
+
.option('--port <port>', 'TCP port for Tailscale clients')
|
|
216
|
+
.action(async (...args) => {
|
|
217
|
+
await daemonStart(args[0]);
|
|
218
|
+
});
|
|
219
|
+
// daemon stop
|
|
220
|
+
daemon.command('stop')
|
|
221
|
+
.description('Stop the running daemon')
|
|
222
|
+
.action(async () => {
|
|
223
|
+
await daemonStop();
|
|
224
|
+
});
|
|
225
|
+
// daemon status
|
|
226
|
+
daemon.command('status')
|
|
227
|
+
.description('Show daemon health and statistics')
|
|
228
|
+
.action(async () => {
|
|
229
|
+
await daemonStatus();
|
|
230
|
+
});
|
|
231
|
+
// daemon logs
|
|
232
|
+
daemon.command('logs')
|
|
233
|
+
.description('Show daemon log output')
|
|
234
|
+
.option('-n, --lines <n>', 'Number of lines to show', '50')
|
|
235
|
+
.option('-f, --follow', 'Follow log output')
|
|
236
|
+
.action(async (...args) => {
|
|
237
|
+
await daemonLogs(args[0]);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
// ---------------------------------------------------------------------------
|
|
241
|
+
// Exported individual action functions (for programmatic use and testing)
|
|
242
|
+
// ---------------------------------------------------------------------------
|
|
243
|
+
export { daemonStart, daemonStop, daemonStatus, daemonLogs };
|
|
244
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI — replay subcommand
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* mcp-conductor-cli replay <recordingPath> [--at <seq> --op replace|skip [--with <json>]] ...
|
|
6
|
+
* mcp-conductor-cli replay --list
|
|
7
|
+
*
|
|
8
|
+
* Options:
|
|
9
|
+
* --list List all available recordings
|
|
10
|
+
* --at <n> Sequence index for a modification
|
|
11
|
+
* --op replace|skip Operation to apply at that index
|
|
12
|
+
* --with <json> JSON value for replace operation
|
|
13
|
+
* --recordings-dir <path> Override the recordings directory
|
|
14
|
+
*/
|
|
15
|
+
export declare function runReplayCli(argv?: string[]): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=replay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/cli/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAyDH,wBAAsB,YAAY,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CA6CxF"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI — replay subcommand
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* mcp-conductor-cli replay <recordingPath> [--at <seq> --op replace|skip [--with <json>]] ...
|
|
6
|
+
* mcp-conductor-cli replay --list
|
|
7
|
+
*
|
|
8
|
+
* Options:
|
|
9
|
+
* --list List all available recordings
|
|
10
|
+
* --at <n> Sequence index for a modification
|
|
11
|
+
* --op replace|skip Operation to apply at that index
|
|
12
|
+
* --with <json> JSON value for replace operation
|
|
13
|
+
* --recordings-dir <path> Override the recordings directory
|
|
14
|
+
*/
|
|
15
|
+
import { ReplayRecorder } from '../observability/index.js';
|
|
16
|
+
import { homedir } from 'node:os';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
function parseArgs(argv) {
|
|
19
|
+
const result = { list: false, modifications: [] };
|
|
20
|
+
let i = 0;
|
|
21
|
+
while (i < argv.length) {
|
|
22
|
+
const arg = argv[i];
|
|
23
|
+
if (arg === '--list') {
|
|
24
|
+
result.list = true;
|
|
25
|
+
i++;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (arg === '--recordings-dir') {
|
|
29
|
+
result.recordingsDir = argv[++i];
|
|
30
|
+
i++;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (arg === '--at') {
|
|
34
|
+
const at = parseInt(argv[++i] ?? '0', 10);
|
|
35
|
+
i++;
|
|
36
|
+
const nextArg = argv[i];
|
|
37
|
+
const op = nextArg === '--op' ? (argv[++i] ?? 'replace') : 'replace';
|
|
38
|
+
if (nextArg === '--op')
|
|
39
|
+
i++;
|
|
40
|
+
let withValue;
|
|
41
|
+
if (i < argv.length && argv[i] === '--with') {
|
|
42
|
+
withValue = JSON.parse(argv[++i] ?? 'null');
|
|
43
|
+
i++;
|
|
44
|
+
}
|
|
45
|
+
result.modifications.push({ at, op: op, with: withValue });
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (arg && !arg.startsWith('--')) {
|
|
49
|
+
result.recordingPath = arg;
|
|
50
|
+
}
|
|
51
|
+
i++;
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
export async function runReplayCli(argv = process.argv.slice(2)) {
|
|
56
|
+
const args = parseArgs(argv);
|
|
57
|
+
const recordingsDir = args.recordingsDir
|
|
58
|
+
?? join(homedir(), '.mcp-conductor', 'recordings');
|
|
59
|
+
const recorder = new ReplayRecorder({ recordingsDir });
|
|
60
|
+
if (args.list) {
|
|
61
|
+
const recordings = recorder.listRecordings();
|
|
62
|
+
if (recordings.length === 0) {
|
|
63
|
+
process.stdout.write('No recordings found.\n');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
for (const r of recordings) {
|
|
67
|
+
const kb = (r.sizeBytes / 1024).toFixed(1);
|
|
68
|
+
const date = new Date(r.createdAt).toISOString();
|
|
69
|
+
process.stdout.write(`${r.sessionId} ${kb} KB ${date}\n`);
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!args.recordingPath) {
|
|
74
|
+
process.stderr.write('Usage: replay <recordingPath> [--at <seq> --op replace|skip [--with <json>]] ...\n' +
|
|
75
|
+
' replay --list\n');
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
const { result, divergence } = recorder.replay(args.recordingPath, args.modifications);
|
|
79
|
+
if (divergence) {
|
|
80
|
+
process.stderr.write(`Divergence detected at seq ${divergence.at}:\n` +
|
|
81
|
+
` expected: ${JSON.stringify(divergence.expected)}\n` +
|
|
82
|
+
` actual: ${JSON.stringify(divergence.actual)}\n`);
|
|
83
|
+
}
|
|
84
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
85
|
+
if (divergence) {
|
|
86
|
+
process.exit(2);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../../src/cli/replay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive setup wizard using @inquirer/prompts.
|
|
3
|
+
* Guides the user through discovering Claude configs, importing servers,
|
|
4
|
+
* and optionally cleaning up source configs.
|
|
5
|
+
* @module cli/wizard/setup
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Run the full interactive setup wizard.
|
|
9
|
+
* Falls back to non-interactive mode if TTY is not available (CI).
|
|
10
|
+
*/
|
|
11
|
+
export declare function runSetupWizard(): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/wizard/setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAmEpD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive setup wizard using @inquirer/prompts.
|
|
3
|
+
* Guides the user through discovering Claude configs, importing servers,
|
|
4
|
+
* and optionally cleaning up source configs.
|
|
5
|
+
* @module cli/wizard/setup
|
|
6
|
+
*/
|
|
7
|
+
import pc from 'picocolors';
|
|
8
|
+
import { findClaudeConfigsWithServers, importServers, formatImportResults } from '../commands/import-servers.js';
|
|
9
|
+
import { runDoctor, formatDoctorResults } from '../commands/doctor.js';
|
|
10
|
+
/**
|
|
11
|
+
* Run the full interactive setup wizard.
|
|
12
|
+
* Falls back to non-interactive mode if TTY is not available (CI).
|
|
13
|
+
*/
|
|
14
|
+
export async function runSetupWizard() {
|
|
15
|
+
const isTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
16
|
+
console.log(pc.bold(pc.cyan('\nMCP Conductor — Setup Wizard\n')));
|
|
17
|
+
console.log('This wizard will help you move your MCP servers into Conductor.');
|
|
18
|
+
console.log('Conductor proxies all your servers through a single MCP endpoint.\n');
|
|
19
|
+
// Step 1: discover Claude configs
|
|
20
|
+
const sources = findClaudeConfigsWithServers();
|
|
21
|
+
if (sources.length === 0) {
|
|
22
|
+
console.log(pc.yellow('No Claude config files with MCP servers found.'));
|
|
23
|
+
console.log('Add servers manually with: mcp-conductor-cli add <name> <command> [args...]');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.log(pc.green(`Found ${sources.length} config file(s) with MCP servers:\n`));
|
|
27
|
+
for (const src of sources) {
|
|
28
|
+
console.log(pc.dim(` ${src.path}`));
|
|
29
|
+
for (const name of Object.keys(src.servers)) {
|
|
30
|
+
console.log(` • ${name}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
console.log('');
|
|
34
|
+
let doImport = true;
|
|
35
|
+
let removeOriginals = false;
|
|
36
|
+
if (isTTY) {
|
|
37
|
+
// Dynamic import to avoid loading inquirer in non-TTY environments
|
|
38
|
+
const { confirm } = await import('@inquirer/prompts');
|
|
39
|
+
doImport = await confirm({
|
|
40
|
+
message: 'Import these servers into ~/.mcp-conductor.json?',
|
|
41
|
+
default: true,
|
|
42
|
+
});
|
|
43
|
+
if (doImport) {
|
|
44
|
+
removeOriginals = await confirm({
|
|
45
|
+
message: 'Remove imported servers from source configs after import?',
|
|
46
|
+
default: false,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
console.log(pc.dim('(Non-interactive mode — proceeding with import, keeping originals)\n'));
|
|
52
|
+
}
|
|
53
|
+
if (!doImport) {
|
|
54
|
+
console.log(pc.dim('Import skipped.'));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Step 2: perform import
|
|
58
|
+
const results = importServers({ yes: true, removeOriginals });
|
|
59
|
+
console.log(formatImportResults(results));
|
|
60
|
+
// Step 3: run doctor to confirm health
|
|
61
|
+
console.log(pc.bold('\nRunning health check...\n'));
|
|
62
|
+
const doctorResult = runDoctor();
|
|
63
|
+
console.log(formatDoctorResults(doctorResult));
|
|
64
|
+
// Step 4: next steps
|
|
65
|
+
console.log(pc.bold(pc.green('\nSetup complete!\n')));
|
|
66
|
+
console.log('Next steps:');
|
|
67
|
+
console.log(' 1. Restart Claude to pick up the new mcp-conductor config.');
|
|
68
|
+
console.log(' 2. Use mcp-conductor-cli list to verify all servers are visible.');
|
|
69
|
+
console.log(' 3. Use mcp-conductor-cli doctor to check for any issues.\n');
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/cli/wizard/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -62,6 +62,8 @@ export declare const DEFAULT_CONDUCTOR_CONFIG: {
|
|
|
62
62
|
* - `STREAM_STUCK_TTL_MS` — `StreamManager` cleanup for hung running streams
|
|
63
63
|
* - `STREAM_CLEANUP_INTERVAL_MS` — `StreamManager` tick rate for the sweep
|
|
64
64
|
* - `MEMORY_LOG_INTERVAL_MS` — periodic heap/RSS log from the main entry point
|
|
65
|
+
* - `BRIDGE_SESSION_TTL_MS` — HTTP bridge session idle expiry (Mcp-Session-Id)
|
|
66
|
+
* - `BRIDGE_SESSION_CLEANUP_INTERVAL_MS` — sweep cadence for expired sessions
|
|
65
67
|
*/
|
|
66
68
|
export declare const LIFECYCLE_TIMEOUTS: {
|
|
67
69
|
readonly SHUTDOWN_TIMEOUT_MS: 10000;
|
|
@@ -71,5 +73,13 @@ export declare const LIFECYCLE_TIMEOUTS: {
|
|
|
71
73
|
readonly STREAM_STUCK_TTL_MS: number;
|
|
72
74
|
readonly STREAM_CLEANUP_INTERVAL_MS: 60000;
|
|
73
75
|
readonly MEMORY_LOG_INTERVAL_MS: 60000;
|
|
76
|
+
readonly BRIDGE_SESSION_TTL_MS: number;
|
|
77
|
+
readonly BRIDGE_SESSION_CLEANUP_INTERVAL_MS: number;
|
|
78
|
+
readonly ORPHAN_CHECK_INTERVAL_MS: 10000;
|
|
74
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Cap on simultaneously tracked bridge sessions. Bounded to prevent the
|
|
82
|
+
* session registry from growing unbounded if a client keeps rotating IDs.
|
|
83
|
+
*/
|
|
84
|
+
export declare const MAX_BRIDGE_SESSIONS = 1000;
|
|
75
85
|
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,iBAqC5B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;CAeX,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB;;;CAGpC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;CAWrB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,mBAAmB,OAAO,CAAC"}
|