@darkiceinteractive/mcp-conductor 3.1.0-rc.2 → 3.1.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.
Files changed (84) hide show
  1. package/README.md +140 -12
  2. package/dist/bin/cli.d.ts +2 -2
  3. package/dist/bin/cli.js +37 -14
  4. package/dist/bin/cli.js.map +1 -1
  5. package/dist/cli/clients/adapter.d.ts +103 -0
  6. package/dist/cli/clients/adapter.d.ts.map +1 -0
  7. package/dist/cli/clients/adapter.js +24 -0
  8. package/dist/cli/clients/adapter.js.map +1 -0
  9. package/dist/cli/clients/claude-code.d.ts +15 -0
  10. package/dist/cli/clients/claude-code.d.ts.map +1 -0
  11. package/dist/cli/clients/claude-code.js +110 -0
  12. package/dist/cli/clients/claude-code.js.map +1 -0
  13. package/dist/cli/clients/claude-desktop.d.ts +26 -0
  14. package/dist/cli/clients/claude-desktop.d.ts.map +1 -0
  15. package/dist/cli/clients/claude-desktop.js +118 -0
  16. package/dist/cli/clients/claude-desktop.js.map +1 -0
  17. package/dist/cli/clients/cline.d.ts +40 -0
  18. package/dist/cli/clients/cline.d.ts.map +1 -0
  19. package/dist/cli/clients/cline.js +134 -0
  20. package/dist/cli/clients/cline.js.map +1 -0
  21. package/dist/cli/clients/codex.d.ts +30 -0
  22. package/dist/cli/clients/codex.d.ts.map +1 -0
  23. package/dist/cli/clients/codex.js +176 -0
  24. package/dist/cli/clients/codex.js.map +1 -0
  25. package/dist/cli/clients/continue.d.ts +41 -0
  26. package/dist/cli/clients/continue.d.ts.map +1 -0
  27. package/dist/cli/clients/continue.js +150 -0
  28. package/dist/cli/clients/continue.js.map +1 -0
  29. package/dist/cli/clients/cursor.d.ts +20 -0
  30. package/dist/cli/clients/cursor.d.ts.map +1 -0
  31. package/dist/cli/clients/cursor.js +110 -0
  32. package/dist/cli/clients/cursor.js.map +1 -0
  33. package/dist/cli/clients/gemini-cli.d.ts +42 -0
  34. package/dist/cli/clients/gemini-cli.d.ts.map +1 -0
  35. package/dist/cli/clients/gemini-cli.js +169 -0
  36. package/dist/cli/clients/gemini-cli.js.map +1 -0
  37. package/dist/cli/clients/index.d.ts +28 -0
  38. package/dist/cli/clients/index.d.ts.map +1 -0
  39. package/dist/cli/clients/index.js +44 -0
  40. package/dist/cli/clients/index.js.map +1 -0
  41. package/dist/cli/clients/kimi-code.d.ts +33 -0
  42. package/dist/cli/clients/kimi-code.d.ts.map +1 -0
  43. package/dist/cli/clients/kimi-code.js +177 -0
  44. package/dist/cli/clients/kimi-code.js.map +1 -0
  45. package/dist/cli/clients/opencode.d.ts +21 -0
  46. package/dist/cli/clients/opencode.d.ts.map +1 -0
  47. package/dist/cli/clients/opencode.js +150 -0
  48. package/dist/cli/clients/opencode.js.map +1 -0
  49. package/dist/cli/clients/registry.d.ts +51 -0
  50. package/dist/cli/clients/registry.d.ts.map +1 -0
  51. package/dist/cli/clients/registry.js +169 -0
  52. package/dist/cli/clients/registry.js.map +1 -0
  53. package/dist/cli/clients/zed.d.ts +41 -0
  54. package/dist/cli/clients/zed.d.ts.map +1 -0
  55. package/dist/cli/clients/zed.js +171 -0
  56. package/dist/cli/clients/zed.js.map +1 -0
  57. package/dist/cli/commands/doctor.d.ts +27 -0
  58. package/dist/cli/commands/doctor.d.ts.map +1 -1
  59. package/dist/cli/commands/doctor.js +71 -0
  60. package/dist/cli/commands/doctor.js.map +1 -1
  61. package/dist/cli/commands/export-servers.d.ts +60 -0
  62. package/dist/cli/commands/export-servers.d.ts.map +1 -1
  63. package/dist/cli/commands/export-servers.js +85 -1
  64. package/dist/cli/commands/export-servers.js.map +1 -1
  65. package/dist/cli/commands/import-servers.d.ts +1 -1
  66. package/dist/cli/commands/import-servers.js +2 -2
  67. package/dist/cli/commands/import-servers.js.map +1 -1
  68. package/dist/cli/wizard/setup.d.ts +29 -3
  69. package/dist/cli/wizard/setup.d.ts.map +1 -1
  70. package/dist/cli/wizard/setup.js +204 -7
  71. package/dist/cli/wizard/setup.js.map +1 -1
  72. package/dist/config/loader.d.ts +10 -1
  73. package/dist/config/loader.d.ts.map +1 -1
  74. package/dist/config/loader.js +14 -24
  75. package/dist/config/loader.js.map +1 -1
  76. package/dist/utils/backup.d.ts +24 -0
  77. package/dist/utils/backup.d.ts.map +1 -0
  78. package/dist/utils/backup.js +40 -0
  79. package/dist/utils/backup.js.map +1 -0
  80. package/dist/version.d.ts +3 -3
  81. package/dist/version.d.ts.map +1 -1
  82. package/dist/version.js +3 -3
  83. package/dist/version.js.map +1 -1
  84. package/package.json +3 -1
@@ -0,0 +1,150 @@
1
+ /**
2
+ * MCPClientAdapter for Continue.dev.
3
+ *
4
+ * Continue.dev stores its global configuration at `~/.continue/config.yaml`
5
+ * (YAML) and optionally accepts project-local drop-in files under
6
+ * `.continue/mcpServers/*.yaml` (also YAML, one file per server) or, in
7
+ * older releases, `.continue/config.json` (JSON).
8
+ *
9
+ * This adapter handles:
10
+ * - YAML parse/serialize for the primary global config
11
+ * - JSON fallback for any path whose extension is `.json`
12
+ * - Round-trip preservation of all non-`mcpServers` top-level keys
13
+ * (models, slashCommands, tabAutocompleteModel, contextProviders, etc.)
14
+ * - Timestamped `.bak.YYYYMMDDHHMMSS` backup before every write
15
+ *
16
+ * YAML edge cases:
17
+ * - **Comment preservation**: the `yaml` package (v2) does not preserve
18
+ * comments on stringify by default. Comments are silently dropped during a
19
+ * round-trip. This is a known limitation of virtually all YAML serialisers
20
+ * and is documented here so users are not surprised.
21
+ * - **Anchors / aliases**: the `yaml` package fully supports YAML anchors on
22
+ * parse. On stringify it emits plain scalar values (anchors are not
23
+ * re-emitted), which is the safest behaviour for a config-mutation tool.
24
+ * - **Multi-document streams**: Continue uses single-document YAML files.
25
+ * Only the first document is parsed; additional documents (if any) are
26
+ * ignored.
27
+ *
28
+ * @module cli/clients/continue
29
+ */
30
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
31
+ import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
32
+ import { writeBackup } from '../../utils/backup.js';
33
+ /**
34
+ * Parse a file as YAML or JSON depending on its extension.
35
+ *
36
+ * - `.json` → `JSON.parse`
37
+ * - anything else → `yaml.parse` (handles `.yaml` and `.yml`)
38
+ *
39
+ * Returns `null` on parse error or when the file does not exist.
40
+ */
41
+ function parseFile(path) {
42
+ if (!existsSync(path)) {
43
+ return null;
44
+ }
45
+ const raw = readFileSync(path, 'utf8');
46
+ try {
47
+ if (path.endsWith('.json')) {
48
+ return JSON.parse(raw);
49
+ }
50
+ // yaml.parse returns the first document and handles all YAML 1.2 features.
51
+ const doc = parseYaml(raw);
52
+ return doc ?? null;
53
+ }
54
+ catch {
55
+ return null;
56
+ }
57
+ }
58
+ /**
59
+ * Serialise `doc` back to the format implied by `path`'s extension.
60
+ */
61
+ function serialiseDoc(path, doc) {
62
+ if (path.endsWith('.json')) {
63
+ return JSON.stringify(doc, null, 2) + '\n';
64
+ }
65
+ // lineWidth: 0 disables line-wrapping so long command/args strings are not
66
+ // broken mid-token.
67
+ return stringifyYaml(doc, { lineWidth: 0 });
68
+ }
69
+ // ---------------------------------------------------------------------------
70
+ // Adapter implementation
71
+ // ---------------------------------------------------------------------------
72
+ class ContinueAdapter {
73
+ client = 'continue';
74
+ // -------------------------------------------------------------------------
75
+ // parse()
76
+ // -------------------------------------------------------------------------
77
+ parse(path) {
78
+ const doc = parseFile(path);
79
+ if (doc === null) {
80
+ return null;
81
+ }
82
+ const rawServers = doc.mcpServers;
83
+ if (!rawServers || typeof rawServers !== 'object' || Object.keys(rawServers).length === 0) {
84
+ // File exists but has no MCP server definitions — callers may skip it.
85
+ return null;
86
+ }
87
+ // Normalise each server entry into the common shape.
88
+ const servers = {};
89
+ for (const [name, entry] of Object.entries(rawServers)) {
90
+ if (!entry || typeof entry.command !== 'string') {
91
+ continue; // skip malformed entries
92
+ }
93
+ const normalised = { command: entry.command };
94
+ if (Array.isArray(entry.args)) {
95
+ normalised.args = entry.args;
96
+ }
97
+ if (entry.env && typeof entry.env === 'object') {
98
+ normalised.env = entry.env;
99
+ }
100
+ servers[name] = normalised;
101
+ }
102
+ return { servers, raw: doc };
103
+ }
104
+ // -------------------------------------------------------------------------
105
+ // serialize()
106
+ // -------------------------------------------------------------------------
107
+ serialize(path, config, options) {
108
+ // 1. Back up the current file before mutating it (skip if file is new).
109
+ if (existsSync(path)) {
110
+ writeBackup(path);
111
+ }
112
+ // 2. Build the updated mcpServers map.
113
+ let updatedServers;
114
+ if (options.keepOnlyConductor) {
115
+ // Migration mode: keep only the conductor entry.
116
+ updatedServers = { 'mcp-conductor': options.conductorEntry };
117
+ }
118
+ else {
119
+ // Merge mode: start from the existing normalised servers, then ensure
120
+ // the conductor entry is present / updated.
121
+ updatedServers = {
122
+ ...config.servers,
123
+ 'mcp-conductor': options.conductorEntry,
124
+ };
125
+ }
126
+ // 3. Reconstruct the full document, preserving all non-mcpServers keys
127
+ // from `config.raw` (models, slashCommands, contextProviders, etc.).
128
+ const baseDoc = config.raw ?? {};
129
+ const updatedDoc = {
130
+ ...baseDoc,
131
+ mcpServers: updatedServers,
132
+ };
133
+ // 4. Write the serialised output to disk.
134
+ writeFileSync(path, serialiseDoc(path, updatedDoc), 'utf8');
135
+ }
136
+ }
137
+ // ---------------------------------------------------------------------------
138
+ // Exported singleton
139
+ // ---------------------------------------------------------------------------
140
+ /**
141
+ * Continue.dev MCPClientAdapter instance.
142
+ *
143
+ * Registered in `src/cli/clients/index.ts`:
144
+ * ```ts
145
+ * import { CONTINUE_ADAPTER } from './continue.js';
146
+ * ADAPTERS.set('continue', CONTINUE_ADAPTER);
147
+ * ```
148
+ */
149
+ export const CONTINUE_ADAPTER = new ContinueAdapter();
150
+ //# sourceMappingURL=continue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"continue.js","sourceRoot":"","sources":["../../../src/cli/clients/continue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Cursor MCP client adapter.
3
+ *
4
+ * Cursor stores MCP server definitions in `~/.cursor/mcp.json` (global) and
5
+ * `.cursor/mcp.json` (project-local). Both files use a flat JSON object with
6
+ * an `mcpServers` key whose value is an Anthropic-compatible server map
7
+ * `{ [serverName]: { command, args?, env? } }`.
8
+ *
9
+ * This adapter handles:
10
+ * - Parsing `mcpServers` into the normalised shape.
11
+ * - Round-trip serialisation that preserves any extra top-level keys.
12
+ * - `.bak.YYYYMMDDHHMMSS` backups before every write.
13
+ * - `keepOnlyConductor` mode for the "migrate to conductor" setup flow.
14
+ *
15
+ * @module cli/clients/cursor
16
+ */
17
+ import type { MCPClientAdapter } from './adapter.js';
18
+ declare const CURSOR_ADAPTER: MCPClientAdapter;
19
+ export { CURSOR_ADAPTER };
20
+ //# sourceMappingURL=cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../../src/cli/clients/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAA4C,MAAM,cAAc,CAAC;AA8C/F,QAAA,MAAM,cAAc,EAAE,gBAqErB,CAAC;AAQF,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Cursor MCP client adapter.
3
+ *
4
+ * Cursor stores MCP server definitions in `~/.cursor/mcp.json` (global) and
5
+ * `.cursor/mcp.json` (project-local). Both files use a flat JSON object with
6
+ * an `mcpServers` key whose value is an Anthropic-compatible server map
7
+ * `{ [serverName]: { command, args?, env? } }`.
8
+ *
9
+ * This adapter handles:
10
+ * - Parsing `mcpServers` into the normalised shape.
11
+ * - Round-trip serialisation that preserves any extra top-level keys.
12
+ * - `.bak.YYYYMMDDHHMMSS` backups before every write.
13
+ * - `keepOnlyConductor` mode for the "migrate to conductor" setup flow.
14
+ *
15
+ * @module cli/clients/cursor
16
+ */
17
+ import { existsSync, readFileSync, writeFileSync, copyFileSync, mkdirSync } from 'node:fs';
18
+ import { dirname } from 'node:path';
19
+ import { ADAPTERS } from './adapter.js';
20
+ // ---------------------------------------------------------------------------
21
+ // Backup helper (mirrors the pattern in import-servers.ts)
22
+ // ---------------------------------------------------------------------------
23
+ /**
24
+ * Write a timestamped `.bak.YYYYMMDDHHMMSS` copy of the file beside it.
25
+ * If a file with the same timestamp already exists a 4-char hex salt is
26
+ * appended to avoid silent overwrites on sub-second repeat calls.
27
+ *
28
+ * @returns The path of the backup file that was written.
29
+ */
30
+ function writeBackup(filePath) {
31
+ const ts = new Date().toISOString().replace(/\D/g, '').slice(0, 14);
32
+ let backupPath = `${filePath}.bak.${ts}`;
33
+ if (existsSync(backupPath)) {
34
+ const salt = Math.floor(Math.random() * 0xffff)
35
+ .toString(16)
36
+ .padStart(4, '0');
37
+ backupPath = `${backupPath}.${salt}`;
38
+ }
39
+ copyFileSync(filePath, backupPath);
40
+ return backupPath;
41
+ }
42
+ // ---------------------------------------------------------------------------
43
+ // Adapter implementation
44
+ // ---------------------------------------------------------------------------
45
+ const CURSOR_ADAPTER = {
46
+ client: 'cursor',
47
+ parse(path) {
48
+ if (!existsSync(path))
49
+ return null;
50
+ let raw;
51
+ try {
52
+ const text = readFileSync(path, 'utf-8');
53
+ raw = JSON.parse(text);
54
+ }
55
+ catch {
56
+ return null;
57
+ }
58
+ const mcpServers = raw.mcpServers;
59
+ if (!mcpServers || typeof mcpServers !== 'object' || Object.keys(mcpServers).length === 0) {
60
+ return null;
61
+ }
62
+ const servers = {};
63
+ for (const [name, entry] of Object.entries(mcpServers)) {
64
+ if (!entry || typeof entry.command !== 'string')
65
+ continue;
66
+ servers[name] = {
67
+ command: entry.command,
68
+ ...(Array.isArray(entry.args) && { args: entry.args }),
69
+ ...(entry.env && typeof entry.env === 'object' && { env: entry.env }),
70
+ };
71
+ }
72
+ return { servers, raw };
73
+ },
74
+ serialize(path, config, options) {
75
+ // Back up the existing file before any write.
76
+ if (existsSync(path)) {
77
+ writeBackup(path);
78
+ }
79
+ // Start from the original parsed object so non-MCP keys are preserved.
80
+ const base = config.raw && typeof config.raw === 'object'
81
+ ? { ...config.raw }
82
+ : {};
83
+ // Determine which servers to write.
84
+ const serversToWrite = options.keepOnlyConductor
85
+ ? { 'mcp-conductor': options.conductorEntry }
86
+ : { ...config.servers, 'mcp-conductor': options.conductorEntry };
87
+ // Convert to the Cursor-native shape.
88
+ const mcpServers = {};
89
+ for (const [name, entry] of Object.entries(serversToWrite)) {
90
+ mcpServers[name] = {
91
+ command: entry.command,
92
+ ...(Array.isArray(entry.args) && { args: entry.args }),
93
+ ...(entry.env && typeof entry.env === 'object' && { env: entry.env }),
94
+ };
95
+ }
96
+ const output = { ...base, mcpServers };
97
+ // Ensure the parent directory exists (e.g. ~/.cursor/ may not yet exist).
98
+ const dir = dirname(path);
99
+ if (!existsSync(dir)) {
100
+ mkdirSync(dir, { recursive: true });
101
+ }
102
+ writeFileSync(path, JSON.stringify(output, null, 2) + '\n', 'utf-8');
103
+ },
104
+ };
105
+ // ---------------------------------------------------------------------------
106
+ // Self-registration
107
+ // ---------------------------------------------------------------------------
108
+ ADAPTERS.set('cursor', CURSOR_ADAPTER);
109
+ export { CURSOR_ADAPTER };
110
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../src/cli/clients/cursor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * MCPClientAdapter implementation for Google Gemini CLI.
3
+ *
4
+ * Gemini CLI stores MCP server definitions in:
5
+ * - Global: ~/.gemini/settings.json
6
+ * - Project: .gemini/settings.json (relative to cwd)
7
+ *
8
+ * Config schema (synthetic example):
9
+ * ```json
10
+ * {
11
+ * "mcpServers": {
12
+ * "my-server": {
13
+ * "command": "node",
14
+ * "args": ["dist/server.js"],
15
+ * "env": { "KEY": "value" },
16
+ * "timeout": 30000,
17
+ * "includeTools": ["tool_a"],
18
+ * "excludeTools": ["tool_b"]
19
+ * }
20
+ * }
21
+ * }
22
+ * ```
23
+ *
24
+ * Extra per-server fields (`timeout`, `includeTools`, `excludeTools`, and any
25
+ * future additions) are preserved verbatim in `config.raw` and round-tripped
26
+ * back to disk during serialize() when `keepOnlyConductor` is false.
27
+ *
28
+ * All non-`mcpServers` top-level keys (e.g. model settings, theme) are also
29
+ * preserved unchanged.
30
+ *
31
+ * @module cli/clients/gemini-cli
32
+ */
33
+ import type { MCPClientAdapter } from './adapter.js';
34
+ /**
35
+ * The Gemini CLI adapter singleton.
36
+ *
37
+ * Importing this module automatically registers the adapter in `ADAPTERS` so
38
+ * the wizard and doctor commands can discover it without explicitly referencing
39
+ * this module.
40
+ */
41
+ export declare const GEMINI_CLI_ADAPTER: MCPClientAdapter;
42
+ //# sourceMappingURL=gemini-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-cli.d.ts","sourceRoot":"","sources":["../../../src/cli/clients/gemini-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,KAAK,EACV,gBAAgB,EAIjB,MAAM,cAAc,CAAC;AAuKtB;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,kBAA0B,CAAC"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * MCPClientAdapter implementation for Google Gemini CLI.
3
+ *
4
+ * Gemini CLI stores MCP server definitions in:
5
+ * - Global: ~/.gemini/settings.json
6
+ * - Project: .gemini/settings.json (relative to cwd)
7
+ *
8
+ * Config schema (synthetic example):
9
+ * ```json
10
+ * {
11
+ * "mcpServers": {
12
+ * "my-server": {
13
+ * "command": "node",
14
+ * "args": ["dist/server.js"],
15
+ * "env": { "KEY": "value" },
16
+ * "timeout": 30000,
17
+ * "includeTools": ["tool_a"],
18
+ * "excludeTools": ["tool_b"]
19
+ * }
20
+ * }
21
+ * }
22
+ * ```
23
+ *
24
+ * Extra per-server fields (`timeout`, `includeTools`, `excludeTools`, and any
25
+ * future additions) are preserved verbatim in `config.raw` and round-tripped
26
+ * back to disk during serialize() when `keepOnlyConductor` is false.
27
+ *
28
+ * All non-`mcpServers` top-level keys (e.g. model settings, theme) are also
29
+ * preserved unchanged.
30
+ *
31
+ * @module cli/clients/gemini-cli
32
+ */
33
+ import { readFileSync, writeFileSync } from 'node:fs';
34
+ import { ADAPTERS } from './adapter.js';
35
+ import { createBackup } from '../../utils/backup.js';
36
+ // ---------------------------------------------------------------------------
37
+ // Normalisation helpers
38
+ // ---------------------------------------------------------------------------
39
+ /**
40
+ * Convert a raw Gemini server entry into the conductor's normalised shape.
41
+ *
42
+ * Only `command`, `args`, and `env` are promoted to the normalised entry; all
43
+ * other fields remain in `raw` and are reinjected verbatim during serialize().
44
+ */
45
+ function normaliseEntry(raw) {
46
+ const entry = { command: raw.command };
47
+ if (raw.args !== undefined)
48
+ entry.args = raw.args;
49
+ if (raw.env !== undefined)
50
+ entry.env = raw.env;
51
+ return entry;
52
+ }
53
+ // ---------------------------------------------------------------------------
54
+ // Adapter implementation
55
+ // ---------------------------------------------------------------------------
56
+ const GEMINI_CLI_ADAPTER_IMPL = {
57
+ client: 'gemini-cli',
58
+ /**
59
+ * Parse a Gemini CLI settings.json file into the normalised shape.
60
+ *
61
+ * Returns `null` when the file does not exist, cannot be parsed as JSON, or
62
+ * contains no `mcpServers` key.
63
+ */
64
+ parse(path) {
65
+ let text;
66
+ try {
67
+ text = readFileSync(path, 'utf8');
68
+ }
69
+ catch {
70
+ // File does not exist or is not readable.
71
+ return null;
72
+ }
73
+ let raw;
74
+ try {
75
+ raw = JSON.parse(text);
76
+ }
77
+ catch {
78
+ // Malformed JSON — skip gracefully.
79
+ return null;
80
+ }
81
+ if (!raw.mcpServers || typeof raw.mcpServers !== 'object') {
82
+ return null;
83
+ }
84
+ const servers = {};
85
+ for (const [name, serverRaw] of Object.entries(raw.mcpServers)) {
86
+ if (!serverRaw || typeof serverRaw.command !== 'string')
87
+ continue;
88
+ servers[name] = normaliseEntry(serverRaw);
89
+ }
90
+ return { servers, raw };
91
+ },
92
+ /**
93
+ * Write a (potentially modified) config back to disk.
94
+ *
95
+ * Before writing, a `.bak.YYYYMMDDHHMMSS` copy of the existing file is
96
+ * created via `createBackup()`. If the file did not previously exist no
97
+ * backup is attempted.
98
+ *
99
+ * When `keepOnlyConductor` is true, only the `mcp-conductor` entry is
100
+ * written to `mcpServers`; all other server definitions are dropped.
101
+ *
102
+ * When `keepOnlyConductor` is false, all servers from `config.servers` are
103
+ * written back, and per-server extra fields (`timeout`, `includeTools`,
104
+ * `excludeTools`, …) from `config.raw` are preserved verbatim.
105
+ */
106
+ serialize(path, config, options) {
107
+ const raw = config.raw;
108
+ // Back up the existing file before mutation (if it already exists).
109
+ try {
110
+ createBackup(path);
111
+ }
112
+ catch {
113
+ // File did not previously exist — no backup needed, proceed with write.
114
+ }
115
+ let mcpServers;
116
+ if (options.keepOnlyConductor) {
117
+ // Migration flow: strip all other servers, keep only conductor.
118
+ mcpServers = {
119
+ 'mcp-conductor': { ...options.conductorEntry },
120
+ };
121
+ }
122
+ else {
123
+ // Full round-trip: rebuild mcpServers from the normalised map while
124
+ // preserving extra per-server fields that were in the original config.
125
+ const rawServers = raw.mcpServers ?? {};
126
+ mcpServers = {};
127
+ for (const [name, entry] of Object.entries(config.servers)) {
128
+ const originalRaw = rawServers[name] ?? {};
129
+ // Start with original raw (preserves timeout, includeTools, etc.),
130
+ // then overlay the normalised fields so they are always up to date.
131
+ mcpServers[name] = {
132
+ ...originalRaw,
133
+ command: entry.command,
134
+ ...(entry.args !== undefined ? { args: entry.args } : {}),
135
+ ...(entry.env !== undefined ? { env: entry.env } : {}),
136
+ };
137
+ }
138
+ // Ensure the conductor entry is always present and up to date.
139
+ const existingConductorRaw = rawServers['mcp-conductor'] ?? {};
140
+ mcpServers['mcp-conductor'] = {
141
+ ...existingConductorRaw,
142
+ command: options.conductorEntry.command,
143
+ ...(options.conductorEntry.args !== undefined
144
+ ? { args: options.conductorEntry.args }
145
+ : {}),
146
+ ...(options.conductorEntry.env !== undefined
147
+ ? { env: options.conductorEntry.env }
148
+ : {}),
149
+ };
150
+ }
151
+ // Build the output object: preserve all non-mcpServers top-level keys.
152
+ const output = { ...raw, mcpServers };
153
+ writeFileSync(path, JSON.stringify(output, null, 2) + '\n', 'utf8');
154
+ },
155
+ };
156
+ // ---------------------------------------------------------------------------
157
+ // Export + auto-registration
158
+ // ---------------------------------------------------------------------------
159
+ /**
160
+ * The Gemini CLI adapter singleton.
161
+ *
162
+ * Importing this module automatically registers the adapter in `ADAPTERS` so
163
+ * the wizard and doctor commands can discover it without explicitly referencing
164
+ * this module.
165
+ */
166
+ export const GEMINI_CLI_ADAPTER = GEMINI_CLI_ADAPTER_IMPL;
167
+ // Self-register at module load time.
168
+ ADAPTERS.set('gemini-cli', GEMINI_CLI_ADAPTER_IMPL);
169
+ //# sourceMappingURL=gemini-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-cli.js","sourceRoot":"","sources":["../../../src/cli/clients/gemini-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Client adapter registry.
3
+ *
4
+ * Wave 2 agents fill this map with concrete `MCPClientAdapter` implementations.
5
+ * The key is the `MCPClientId` string; the value is the adapter instance.
6
+ *
7
+ * Usage example (Wave 2):
8
+ *
9
+ * ```ts
10
+ * import { ADAPTERS } from '../clients/index.js';
11
+ * import { ClaudeDesktopAdapter } from './claude-desktop.js';
12
+ *
13
+ * ADAPTERS.set('claude-desktop', new ClaudeDesktopAdapter());
14
+ * ```
15
+ *
16
+ * @module cli/clients/index
17
+ */
18
+ export type { MCPClientId } from './registry.js';
19
+ export { getMCPClientConfigPaths } from './registry.js';
20
+ export type { MCPClientConfigLocation, ConfigFormat, GetMCPClientConfigPathsOptions, } from './registry.js';
21
+ export type { MCPClientAdapter, NormalisedClientConfig, NormalisedServerEntry, SerializeOptions, } from './adapter.js';
22
+ export { ADAPTERS } from './adapter.js';
23
+ import './claude-code.js';
24
+ import './claude-desktop.js';
25
+ import './codex.js';
26
+ import './cursor.js';
27
+ import './gemini-cli.js';
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/clients/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,YAAY,EACV,uBAAuB,EACvB,YAAY,EACZ,8BAA8B,GAC/B,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAWxC,OAAO,kBAAkB,CAAC;AAC1B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,YAAY,CAAC;AACpB,OAAO,aAAa,CAAC;AACrB,OAAO,iBAAiB,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Client adapter registry.
3
+ *
4
+ * Wave 2 agents fill this map with concrete `MCPClientAdapter` implementations.
5
+ * The key is the `MCPClientId` string; the value is the adapter instance.
6
+ *
7
+ * Usage example (Wave 2):
8
+ *
9
+ * ```ts
10
+ * import { ADAPTERS } from '../clients/index.js';
11
+ * import { ClaudeDesktopAdapter } from './claude-desktop.js';
12
+ *
13
+ * ADAPTERS.set('claude-desktop', new ClaudeDesktopAdapter());
14
+ * ```
15
+ *
16
+ * @module cli/clients/index
17
+ */
18
+ export { getMCPClientConfigPaths } from './registry.js';
19
+ // Singleton lives in `adapter.ts` to avoid TDZ errors with side-effect imports.
20
+ export { ADAPTERS } from './adapter.js';
21
+ // ---------------------------------------------------------------------------
22
+ // Adapter registrations
23
+ // ---------------------------------------------------------------------------
24
+ // 5 adapters self-register at module load via top-level ADAPTERS.set()
25
+ // (claude-code, claude-desktop, codex, cursor, gemini-cli) — side-effect
26
+ // imports trigger them. The remaining 5 export the adapter only and are
27
+ // registered explicitly here.
28
+ import { ADAPTERS } from './adapter.js';
29
+ import './claude-code.js';
30
+ import './claude-desktop.js';
31
+ import './codex.js';
32
+ import './cursor.js';
33
+ import './gemini-cli.js';
34
+ import { ZED_ADAPTER } from './zed.js';
35
+ import { CONTINUE_ADAPTER } from './continue.js';
36
+ import { CLINE_ADAPTER } from './cline.js';
37
+ import { OPENCODE_ADAPTER } from './opencode.js';
38
+ import { KIMI_CODE_ADAPTER } from './kimi-code.js';
39
+ ADAPTERS.set('zed', ZED_ADAPTER);
40
+ ADAPTERS.set('continue', CONTINUE_ADAPTER);
41
+ ADAPTERS.set('cline', CLINE_ADAPTER);
42
+ ADAPTERS.set('opencode', OPENCODE_ADAPTER);
43
+ ADAPTERS.set('kimi-code', KIMI_CODE_ADAPTER);
44
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/clients/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAaxD,gFAAgF;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAC9E,uEAAuE;AACvE,yEAAyE;AACzE,wEAAwE;AACxE,8BAA8B;AAE9B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,kBAAkB,CAAC;AAC1B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,YAAY,CAAC;AACpB,OAAO,aAAa,CAAC;AACrB,OAAO,iBAAiB,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;AACjC,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;AAC3C,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;AACrC,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;AAC3C,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * MCPClientAdapter for Kimi Code (Moonshot AI).
3
+ *
4
+ * Kimi Code stores MCP server definitions in a JSON file whose location varies
5
+ * by platform (see registry.ts). The config uses the Anthropic-compatible
6
+ * `mcpServers` shape, so entries are either stdio (`{command, args, env}`) or
7
+ * HTTP (`{url, headers}`).
8
+ *
9
+ * HTTP entries cannot be proxied through conductor's stdio process. They are
10
+ * skipped during normalisation and flagged with a logged warning so the caller
11
+ * can surface actionable guidance to the user.
12
+ *
13
+ * The CLI also accepts `--mcp-config-file <path>` so users may point it at an
14
+ * arbitrary Anthropic-format config (e.g. a symlink to a Claude config). This
15
+ * adapter works with any path that carries an `mcpServers` top-level key.
16
+ *
17
+ * 4-fact preamble:
18
+ * 1. Config format: JSON with top-level `mcpServers` key.
19
+ * 2. Stdio shape: `{ command, args?, env? }` — Anthropic-compatible.
20
+ * 3. HTTP shape: `{ url, headers? }` — skipped with warning; carried in `raw`.
21
+ * 4. Backup: `.bak.YYYYMMDDHHMMSS` written before every serialize() call.
22
+ *
23
+ * @module cli/clients/kimi-code
24
+ */
25
+ import type { MCPClientAdapter } from './adapter.js';
26
+ /**
27
+ * MCPClientAdapter for Kimi Code.
28
+ *
29
+ * Exported as a named constant (singleton object literal) — stateless, so no
30
+ * class instance overhead is needed.
31
+ */
32
+ export declare const KIMI_CODE_ADAPTER: MCPClientAdapter;
33
+ //# sourceMappingURL=kimi-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kimi-code.d.ts","sourceRoot":"","sources":["../../../src/cli/clients/kimi-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,OAAO,KAAK,EACV,gBAAgB,EAIjB,MAAM,cAAc,CAAC;AA2DtB;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,gBAkH/B,CAAC"}