@dyyz1993/pi-coding-agent 0.70.2 → 0.70.3

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 (42) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/dist/core/agent-session.d.ts +4 -0
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +43 -0
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/index.d.ts +2 -0
  7. package/dist/core/index.d.ts.map +1 -1
  8. package/dist/core/index.js +1 -0
  9. package/dist/core/index.js.map +1 -1
  10. package/dist/core/mcp/errors.d.ts +16 -0
  11. package/dist/core/mcp/errors.d.ts.map +1 -0
  12. package/dist/core/mcp/errors.js +31 -0
  13. package/dist/core/mcp/errors.js.map +1 -0
  14. package/dist/core/mcp/logger.d.ts +12 -0
  15. package/dist/core/mcp/logger.d.ts.map +1 -0
  16. package/dist/core/mcp/logger.js +31 -0
  17. package/dist/core/mcp/logger.js.map +1 -0
  18. package/dist/core/mcp/mcp-manager.d.ts +42 -0
  19. package/dist/core/mcp/mcp-manager.d.ts.map +1 -0
  20. package/dist/core/mcp/mcp-manager.js +427 -0
  21. package/dist/core/mcp/mcp-manager.js.map +1 -0
  22. package/dist/core/mcp/tool-converter.d.ts +5 -0
  23. package/dist/core/mcp/tool-converter.d.ts.map +1 -0
  24. package/dist/core/mcp/tool-converter.js +39 -0
  25. package/dist/core/mcp/tool-converter.js.map +1 -0
  26. package/dist/core/mcp/types.d.ts +50 -0
  27. package/dist/core/mcp/types.d.ts.map +1 -0
  28. package/dist/core/mcp/types.js +2 -0
  29. package/dist/core/mcp/types.js.map +1 -0
  30. package/dist/core/settings-manager.d.ts +3 -0
  31. package/dist/core/settings-manager.d.ts.map +1 -1
  32. package/dist/core/settings-manager.js.map +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js.map +1 -1
  36. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  37. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  38. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  39. package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
  40. package/examples/extensions/with-deps/package-lock.json +2 -2
  41. package/examples/extensions/with-deps/package.json +1 -1
  42. package/package.json +5 -4
@@ -0,0 +1,427 @@
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3
+ import { McpConnectionError, McpError, McpTimeoutError, McpToolCallError } from "./errors.js";
4
+ import { McpLogger } from "./logger.js";
5
+ export class McpManager {
6
+ connections = new Map();
7
+ toolMap = new Map();
8
+ logger;
9
+ events;
10
+ connectTimeoutMs;
11
+ callTimeoutMs;
12
+ maxReconnectAttempts;
13
+ callSemaphore;
14
+ reconnectTimers = new Map();
15
+ baseReconnectDelay = 1000;
16
+ maxReconnectDelay = 30000;
17
+ cleanupHandler;
18
+ constructor(optionsOrEvents) {
19
+ const hasOptions = optionsOrEvents &&
20
+ ("logLevel" in optionsOrEvents ||
21
+ "connectTimeoutMs" in optionsOrEvents ||
22
+ "callTimeoutMs" in optionsOrEvents ||
23
+ "maxReconnectAttempts" in optionsOrEvents ||
24
+ "maxConcurrentCalls" in optionsOrEvents);
25
+ const opts = hasOptions ? optionsOrEvents : undefined;
26
+ const eventsCallback = optionsOrEvents?.onConnectionChange;
27
+ this.events = eventsCallback ? { onConnectionChange: eventsCallback } : {};
28
+ this.logger = new McpLogger(opts?.logLevel ?? "info");
29
+ this.connectTimeoutMs = opts?.connectTimeoutMs ?? 30_000;
30
+ this.callTimeoutMs = opts?.callTimeoutMs ?? 60_000;
31
+ this.maxReconnectAttempts = opts?.maxReconnectAttempts ?? 3;
32
+ if (opts?.maxConcurrentCalls) {
33
+ this.callSemaphore = { current: 0, max: opts.maxConcurrentCalls, queue: [] };
34
+ }
35
+ this.registerCleanup();
36
+ }
37
+ registerCleanup() {
38
+ this.cleanupHandler = () => {
39
+ this.disconnectAll().catch(() => { });
40
+ };
41
+ process.on("beforeExit", this.cleanupHandler);
42
+ process.on("SIGTERM", this.cleanupHandler);
43
+ process.on("SIGINT", this.cleanupHandler);
44
+ }
45
+ dispose() {
46
+ if (this.cleanupHandler) {
47
+ process.off("beforeExit", this.cleanupHandler);
48
+ process.off("SIGTERM", this.cleanupHandler);
49
+ process.off("SIGINT", this.cleanupHandler);
50
+ this.cleanupHandler = undefined;
51
+ }
52
+ for (const timer of this.reconnectTimers.values())
53
+ clearTimeout(timer);
54
+ this.reconnectTimers.clear();
55
+ return this.disconnectAll();
56
+ }
57
+ notifyChange(conn) {
58
+ this.events.onConnectionChange?.(conn);
59
+ }
60
+ async connectAll(servers) {
61
+ const entries = Object.entries(servers).filter(([_, c]) => !c.disabled);
62
+ if (entries.length === 0)
63
+ return;
64
+ const results = await Promise.allSettled(entries.map(([name, config]) => this.connectServer(name, config)));
65
+ const succeeded = results.filter((r) => r.status === "fulfilled").length;
66
+ const failed = results.filter((r) => r.status === "rejected").length;
67
+ this.logger.info("*", `${succeeded} server(s) connected${failed > 0 ? `, ${failed} failed` : ""}`);
68
+ }
69
+ async connectServer(name, config) {
70
+ const existing = this.connections.get(name);
71
+ if (existing?.client) {
72
+ try {
73
+ await existing.client.close();
74
+ }
75
+ catch { }
76
+ }
77
+ const entry = { name, config, status: "connecting", tools: [] };
78
+ this.connections.set(name, entry);
79
+ this.notifyChange(entry);
80
+ try {
81
+ await this.doConnectWithTimeout(name, config);
82
+ }
83
+ catch (e) {
84
+ entry.status = "error";
85
+ entry.error = e instanceof Error ? e.message : String(e);
86
+ this.logger.error(name, `Connection failed: ${entry.error}`);
87
+ this.notifyChange(entry);
88
+ throw e instanceof McpError ? e : new McpConnectionError(name, entry.error);
89
+ }
90
+ }
91
+ async doConnectWithTimeout(name, config, timeoutMs = this.connectTimeoutMs) {
92
+ const controller = new AbortController();
93
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
94
+ try {
95
+ await this.doConnectServer(name, config, controller.signal);
96
+ }
97
+ catch (e) {
98
+ if (controller.signal.aborted) {
99
+ throw new McpTimeoutError("connect", name, timeoutMs);
100
+ }
101
+ throw e;
102
+ }
103
+ finally {
104
+ clearTimeout(timer);
105
+ }
106
+ }
107
+ async doConnectServer(name, config, signal) {
108
+ const entry = this.connections.get(name);
109
+ if (!entry)
110
+ return;
111
+ const transport = await this.createTransport(config);
112
+ const client = new Client({ name: "pi-mcp", version: "1.0.0" }, { capabilities: {} });
113
+ await client.connect(transport, { signal });
114
+ const { tools } = await client.listTools();
115
+ entry.client = client;
116
+ entry.status = "connected";
117
+ entry.error = undefined;
118
+ for (const oldKey of [...this.toolMap.keys()]) {
119
+ if (this.toolMap.get(oldKey)?.serverName === name) {
120
+ this.toolMap.delete(oldKey);
121
+ }
122
+ }
123
+ entry.tools = (tools ?? []).map((tool) => {
124
+ const fullName = `mcp__${name}__${tool.name}`;
125
+ this.toolMap.set(fullName, { serverName: name, toolName: tool.name });
126
+ return {
127
+ serverName: name,
128
+ originalName: tool.name,
129
+ fullName,
130
+ description: tool.description ?? "",
131
+ inputSchema: tool.inputSchema ?? { type: "object", properties: {} },
132
+ };
133
+ });
134
+ this.logger.info(name, `${entry.tools.length} tool(s) discovered`);
135
+ this.notifyChange(entry);
136
+ client.onclose = () => {
137
+ const conn = this.connections.get(name);
138
+ if (!conn || conn.status === "disconnected")
139
+ return;
140
+ conn.status = "error";
141
+ conn.error = "Connection closed unexpectedly";
142
+ this.logger.warn(name, "Connection closed unexpectedly");
143
+ this.notifyChange(conn);
144
+ this.scheduleReconnect(name, 0);
145
+ };
146
+ client.onerror = (err) => {
147
+ const conn = this.connections.get(name);
148
+ if (!conn)
149
+ return;
150
+ conn.status = "error";
151
+ conn.error = err.message;
152
+ this.logger.error(name, `Client error: ${err.message}`);
153
+ this.notifyChange(conn);
154
+ };
155
+ }
156
+ scheduleReconnect(name, attempt) {
157
+ if (attempt >= this.maxReconnectAttempts) {
158
+ this.logger.warn(name, `Max reconnect attempts (${this.maxReconnectAttempts}) reached`);
159
+ return;
160
+ }
161
+ const existing = this.reconnectTimers.get(name);
162
+ if (existing) {
163
+ clearTimeout(existing);
164
+ }
165
+ const delay = Math.min(this.baseReconnectDelay * 2 ** attempt, this.maxReconnectDelay);
166
+ this.logger.info(name, `Reconnecting in ${delay}ms (attempt ${attempt + 1}/${this.maxReconnectAttempts})`);
167
+ const timer = setTimeout(() => {
168
+ this.reconnectTimers.delete(name);
169
+ this.reconnectServer(name, attempt + 1);
170
+ }, delay);
171
+ this.reconnectTimers.set(name, timer);
172
+ }
173
+ async reconnectServer(name, attempt) {
174
+ const conn = this.connections.get(name);
175
+ if (!conn || conn.config.disabled)
176
+ return;
177
+ conn.status = "connecting";
178
+ conn.error = undefined;
179
+ this.notifyChange(conn);
180
+ try {
181
+ if (conn.client) {
182
+ try {
183
+ await conn.client.close();
184
+ }
185
+ catch { }
186
+ conn.client = undefined;
187
+ }
188
+ await this.doConnectServer(name, conn.config);
189
+ this.logger.info(name, "Reconnected successfully");
190
+ }
191
+ catch (e) {
192
+ conn.status = "error";
193
+ conn.error = e instanceof Error ? e.message : String(e);
194
+ this.notifyChange(conn);
195
+ this.scheduleReconnect(name, attempt);
196
+ }
197
+ }
198
+ async addServer(name, config) {
199
+ await this.connectServer(name, config);
200
+ }
201
+ async removeServer(name) {
202
+ const timer = this.reconnectTimers.get(name);
203
+ if (timer) {
204
+ clearTimeout(timer);
205
+ this.reconnectTimers.delete(name);
206
+ }
207
+ const conn = this.connections.get(name);
208
+ if (conn?.client) {
209
+ try {
210
+ await conn.client.close();
211
+ }
212
+ catch { }
213
+ }
214
+ for (const oldKey of [...this.toolMap.keys()]) {
215
+ if (this.toolMap.get(oldKey)?.serverName === name) {
216
+ this.toolMap.delete(oldKey);
217
+ }
218
+ }
219
+ this.connections.delete(name);
220
+ }
221
+ async setServerEnabled(name, enabled) {
222
+ const conn = this.connections.get(name);
223
+ if (!conn)
224
+ return;
225
+ conn.config = { ...conn.config, disabled: !enabled };
226
+ if (!enabled) {
227
+ const timer = this.reconnectTimers.get(name);
228
+ if (timer) {
229
+ clearTimeout(timer);
230
+ this.reconnectTimers.delete(name);
231
+ }
232
+ if (conn.client) {
233
+ try {
234
+ await conn.client.close();
235
+ }
236
+ catch { }
237
+ conn.client = undefined;
238
+ }
239
+ conn.status = "disconnected";
240
+ this.notifyChange(conn);
241
+ }
242
+ else {
243
+ await this.connectServer(name, conn.config);
244
+ }
245
+ }
246
+ async refreshTools(serverName) {
247
+ if (serverName) {
248
+ const conn = this.connections.get(serverName);
249
+ if (!conn?.client)
250
+ return [];
251
+ try {
252
+ const { tools } = await conn.client.listTools();
253
+ for (const oldKey of [...this.toolMap.keys()]) {
254
+ if (this.toolMap.get(oldKey)?.serverName === serverName) {
255
+ this.toolMap.delete(oldKey);
256
+ }
257
+ }
258
+ conn.tools = (tools ?? []).map((tool) => {
259
+ const fullName = `mcp__${serverName}__${tool.name}`;
260
+ this.toolMap.set(fullName, { serverName, toolName: tool.name });
261
+ return {
262
+ serverName,
263
+ originalName: tool.name,
264
+ fullName,
265
+ description: tool.description ?? "",
266
+ inputSchema: tool.inputSchema ?? { type: "object", properties: {} },
267
+ };
268
+ });
269
+ this.logger.info(serverName, `Refreshed: ${conn.tools.length} tool(s)`);
270
+ this.notifyChange(conn);
271
+ }
272
+ catch (e) {
273
+ this.logger.error(serverName, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);
274
+ }
275
+ return conn.tools;
276
+ }
277
+ const allTools = [];
278
+ for (const [name, conn] of this.connections) {
279
+ if (conn.client && conn.status === "connected") {
280
+ try {
281
+ const { tools } = await conn.client.listTools();
282
+ for (const oldKey of [...this.toolMap.keys()]) {
283
+ if (this.toolMap.get(oldKey)?.serverName === name) {
284
+ this.toolMap.delete(oldKey);
285
+ }
286
+ }
287
+ conn.tools = (tools ?? []).map((tool) => {
288
+ const fullName = `mcp__${name}__${tool.name}`;
289
+ this.toolMap.set(fullName, { serverName: name, toolName: tool.name });
290
+ return {
291
+ serverName: name,
292
+ originalName: tool.name,
293
+ fullName,
294
+ description: tool.description ?? "",
295
+ inputSchema: tool.inputSchema ?? { type: "object", properties: {} },
296
+ };
297
+ });
298
+ allTools.push(...conn.tools);
299
+ this.notifyChange(conn);
300
+ }
301
+ catch (e) {
302
+ this.logger.error(name, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);
303
+ }
304
+ }
305
+ }
306
+ return allTools;
307
+ }
308
+ getConnections() {
309
+ return [...this.connections.values()];
310
+ }
311
+ getConnection(name) {
312
+ return this.connections.get(name);
313
+ }
314
+ getToolsByServer(serverName) {
315
+ return this.connections.get(serverName)?.tools ?? [];
316
+ }
317
+ async callTool(fullName, args, timeoutMs = this.callTimeoutMs) {
318
+ const slotPromise = this.acquireCallSlot();
319
+ if (slotPromise)
320
+ await slotPromise;
321
+ try {
322
+ const mapping = this.toolMap.get(fullName);
323
+ if (!mapping)
324
+ throw new McpToolCallError("", fullName, `Unknown MCP tool: ${fullName}`);
325
+ const connection = this.connections.get(mapping.serverName);
326
+ if (!connection?.client)
327
+ throw new McpToolCallError(mapping.serverName, mapping.toolName, `MCP server "${mapping.serverName}" not connected`);
328
+ const controller = new AbortController();
329
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
330
+ try {
331
+ return await connection.client.callTool({ name: mapping.toolName, arguments: args }, undefined, {
332
+ signal: controller.signal,
333
+ });
334
+ }
335
+ catch (e) {
336
+ if (controller.signal.aborted) {
337
+ throw new McpTimeoutError(`callTool(${fullName})`, mapping.serverName, timeoutMs);
338
+ }
339
+ throw new McpToolCallError(mapping.serverName, mapping.toolName, e instanceof Error ? e.message : String(e));
340
+ }
341
+ finally {
342
+ clearTimeout(timer);
343
+ }
344
+ }
345
+ finally {
346
+ this.releaseCallSlot();
347
+ }
348
+ }
349
+ acquireCallSlot() {
350
+ if (!this.callSemaphore)
351
+ return undefined;
352
+ if (this.callSemaphore.current < this.callSemaphore.max) {
353
+ this.callSemaphore.current++;
354
+ return undefined;
355
+ }
356
+ return new Promise((resolve) => {
357
+ this.callSemaphore.queue.push(() => {
358
+ this.callSemaphore.current++;
359
+ resolve();
360
+ });
361
+ });
362
+ }
363
+ releaseCallSlot() {
364
+ if (!this.callSemaphore)
365
+ return;
366
+ this.callSemaphore.current--;
367
+ const next = this.callSemaphore.queue.shift();
368
+ if (next)
369
+ next();
370
+ }
371
+ getAllTools() {
372
+ const tools = [];
373
+ for (const connection of this.connections.values()) {
374
+ if (connection.status === "connected")
375
+ tools.push(...connection.tools);
376
+ }
377
+ return tools;
378
+ }
379
+ async disconnectAll() {
380
+ for (const timer of this.reconnectTimers.values())
381
+ clearTimeout(timer);
382
+ this.reconnectTimers.clear();
383
+ for (const connection of this.connections.values()) {
384
+ try {
385
+ if (connection.client)
386
+ await connection.client.close();
387
+ connection.status = "disconnected";
388
+ }
389
+ catch { }
390
+ }
391
+ this.connections.clear();
392
+ this.toolMap.clear();
393
+ }
394
+ async createTransport(config) {
395
+ if (this.isStdioConfig(config)) {
396
+ return new StdioClientTransport({
397
+ command: config.command,
398
+ args: config.args,
399
+ env: config.env
400
+ ? Object.fromEntries(Object.entries({ ...process.env, ...config.env }).filter(([, v]) => v !== undefined))
401
+ : undefined,
402
+ stderr: "pipe",
403
+ });
404
+ }
405
+ if (config.type === "sse") {
406
+ const { SSEClientTransport } = await import("@modelcontextprotocol/sdk/client/sse.js");
407
+ return new SSEClientTransport(new URL(config.url), config.headers
408
+ ? {
409
+ requestInit: { headers: config.headers },
410
+ }
411
+ : undefined);
412
+ }
413
+ if (config.type === "streamable-http") {
414
+ const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
415
+ return new StreamableHTTPClientTransport(new URL(config.url), config.headers
416
+ ? {
417
+ requestInit: { headers: config.headers },
418
+ }
419
+ : undefined);
420
+ }
421
+ throw new Error(`Unknown MCP transport type: ${config.type}`);
422
+ }
423
+ isStdioConfig(config) {
424
+ return "command" in config;
425
+ }
426
+ }
427
+ //# sourceMappingURL=mcp-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-manager.js","sourceRoot":"","sources":["../../../src/core/mcp/mcp-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9F,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAoBxC,MAAM,OAAO,UAAU;IACd,WAAW,GAAG,IAAI,GAAG,EAA6B,CAAC;IACnD,OAAO,GAAG,IAAI,GAAG,EAAoD,CAAC;IAC7D,MAAM,CAAY;IAClB,MAAM,CAAmB;IACzB,gBAAgB,CAAS;IACzB,aAAa,CAAS;IACtB,oBAAoB,CAAS;IAC7B,aAAa,CAAwB;IAE9C,eAAe,GAAG,IAAI,GAAG,EAAyC,CAAC;IACnE,kBAAkB,GAAG,IAAI,CAAC;IAC1B,iBAAiB,GAAG,KAAK,CAAC;IAE1B,cAAc,CAA2B;IAEjD,YACC,eAEwF,EACvF;QACD,MAAM,UAAU,GACf,eAAe;YACf,CAAC,UAAU,IAAI,eAAe;gBAC7B,kBAAkB,IAAI,eAAe;gBACrC,eAAe,IAAI,eAAe;gBAClC,sBAAsB,IAAI,eAAe;gBACzC,oBAAoB,IAAI,eAAe,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAE,eAAqC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7E,MAAM,cAAc,GAAI,eAA2C,EAAE,kBAEzD,CAAC;QAEb,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE,QAAQ,IAAI,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,gBAAgB,GAAG,IAAI,EAAE,gBAAgB,IAAI,MAAM,CAAC;QACzD,IAAI,CAAC,aAAa,GAAG,IAAI,EAAE,aAAa,IAAI,MAAM,CAAC;QACnD,IAAI,CAAC,oBAAoB,GAAG,IAAI,EAAE,oBAAoB,IAAI,CAAC,CAAC;QAC5D,IAAI,IAAI,EAAE,kBAAkB,EAAE,CAAC;YAC9B,IAAI,CAAC,aAAa,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,kBAAkB,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC9E,CAAC;QACD,IAAI,CAAC,eAAe,EAAE,CAAC;IAAA,CACvB;IAEO,eAAe,GAAG;QACzB,IAAI,CAAC,cAAc,GAAG,GAAG,EAAE,CAAC;YAC3B,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC;QAAA,CACrC,CAAC;QACF,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC9C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3C,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;IAAA,CAC1C;IAED,OAAO,GAAkB;QACxB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAC3C,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QACjC,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QACvE,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CAC5B;IAEO,YAAY,CAAC,IAAmB,EAAE;QACzC,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC;IAAA,CACvC;IAED,KAAK,CAAC,UAAU,CAAC,OAAwC,EAAiB;QACzE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACxE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEjC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAE5G,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;QACzE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,MAAM,CAAC;QACrE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,uBAAuB,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAAA,CACnG;IAED,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,MAAuB,EAAiB;QACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,QAAQ,EAAE,MAAM,EAAE,CAAC;YACtB,IAAI,CAAC;gBACJ,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACX,CAAC;QAED,MAAM,KAAK,GAAsB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QACnF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAEzB,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC;YACvB,KAAK,CAAC,KAAK,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACzD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,sBAAsB,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAC7D,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACzB,MAAM,CAAC,YAAY,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7E,CAAC;IAAA,CACD;IAEO,KAAK,CAAC,oBAAoB,CACjC,IAAY,EACZ,MAAuB,EACvB,SAAS,GAAG,IAAI,CAAC,gBAAgB,EACjB;QAChB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;QAC9D,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC/B,MAAM,IAAI,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;YACvD,CAAC;YACD,MAAM,CAAC,CAAC;QACT,CAAC;gBAAS,CAAC;YACV,YAAY,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IAAA,CACD;IAEO,KAAK,CAAC,eAAe,CAAC,IAAY,EAAE,MAAuB,EAAE,MAAoB,EAAiB;QACzG,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QAEtF,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;QAE3C,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QACtB,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC;QAC3B,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;QAExB,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC/C,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,UAAU,KAAK,IAAI,EAAE,CAAC;gBACnD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;QACF,CAAC;QAED,KAAK,CAAC,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,QAAQ,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACtE,OAAO;gBACN,UAAU,EAAE,IAAI;gBAChB,YAAY,EAAE,IAAI,CAAC,IAAI;gBACvB,QAAQ;gBACR,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;gBACnC,WAAW,EAAG,IAAI,CAAC,WAAuC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;aAChG,CAAC;QAAA,CACF,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,qBAAqB,CAAC,CAAC;QACnE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAEzB,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,cAAc;gBAAE,OAAO;YACpD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,gCAAgC,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,gCAAgC,CAAC,CAAC;YACzD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YACxB,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAAA,CAChC,CAAC;QAEF,MAAM,CAAC,OAAO,GAAG,CAAC,GAAU,EAAE,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAAA,CACxB,CAAC;IAAA,CACF;IAEO,iBAAiB,CAAC,IAAY,EAAE,OAAe,EAAE;QACxD,IAAI,OAAO,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,2BAA2B,IAAI,CAAC,oBAAoB,WAAW,CAAC,CAAC;YACxF,OAAO;QACR,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,QAAQ,EAAE,CAAC;YACd,YAAY,CAAC,QAAQ,CAAC,CAAC;QACxB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,GAAG,CAAC,IAAI,OAAO,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACvF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,KAAK,eAAe,OAAO,GAAG,CAAC,IAAI,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;QAE3G,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;YAC9B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;QAAA,CACxC,EAAE,KAAK,CAAC,CAAC;QACV,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAAA,CACtC;IAEO,KAAK,CAAC,eAAe,CAAC,IAAY,EAAE,OAAe,EAAiB;QAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,OAAO;QAE1C,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAExB,IAAI,CAAC;YACJ,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC;oBACJ,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC3B,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;gBACV,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;YACzB,CAAC;YACD,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACxD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YACxB,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvC,CAAC;IAAA,CACD;IAED,KAAK,CAAC,SAAS,CAAC,IAAY,EAAE,MAAuB,EAAiB;QACrE,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAAA,CACvC;IAED,KAAK,CAAC,YAAY,CAAC,IAAY,EAAiB;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,KAAK,EAAE,CAAC;YACX,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;YAClB,IAAI,CAAC;gBACJ,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACX,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC/C,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,UAAU,KAAK,IAAI,EAAE,CAAC;gBACnD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;QACF,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAAA,CAC9B;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,OAAgB,EAAiB;QACrE,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAqB,CAAC;QAExE,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,KAAK,EAAE,CAAC;gBACX,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACnC,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC;oBACJ,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC3B,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;gBACV,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;YACzB,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC;YAC7B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7C,CAAC;IAAA,CACD;IAED,KAAK,CAAC,YAAY,CAAC,UAAmB,EAA6B;QAClE,IAAI,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC9C,IAAI,CAAC,IAAI,EAAE,MAAM;gBAAE,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACJ,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBAChD,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;oBAC/C,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,UAAU,KAAK,UAAU,EAAE,CAAC;wBACzD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBAC7B,CAAC;gBACF,CAAC;gBACD,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;oBACxC,MAAM,QAAQ,GAAG,QAAQ,UAAU,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;oBACpD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;oBAChE,OAAO;wBACN,UAAU;wBACV,YAAY,EAAE,IAAI,CAAC,IAAI;wBACvB,QAAQ;wBACR,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;wBACnC,WAAW,EAAG,IAAI,CAAC,WAAuC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;qBAChG,CAAC;gBAAA,CACF,CAAC,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,IAAI,CAAC,KAAK,CAAC,MAAM,UAAU,CAAC,CAAC;gBACxE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,mBAAmB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAChG,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC;QACnB,CAAC;QAED,MAAM,QAAQ,GAAqB,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC7C,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAChD,IAAI,CAAC;oBACJ,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;oBAChD,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;wBAC/C,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,UAAU,KAAK,IAAI,EAAE,CAAC;4BACnD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;wBAC7B,CAAC;oBACF,CAAC;oBACD,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;wBACxC,MAAM,QAAQ,GAAG,QAAQ,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;wBAC9C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;wBACtE,OAAO;4BACN,UAAU,EAAE,IAAI;4BAChB,YAAY,EAAE,IAAI,CAAC,IAAI;4BACvB,QAAQ;4BACR,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;4BACnC,WAAW,EAAG,IAAI,CAAC,WAAuC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;yBAChG,CAAC;oBAAA,CACF,CAAC,CAAC;oBACH,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC7B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;gBACzB,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACZ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,mBAAmB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC1F,CAAC;YACF,CAAC;QACF,CAAC;QACD,OAAO,QAAQ,CAAC;IAAA,CAChB;IAED,cAAc,GAAoB;QACjC,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IAAA,CACtC;IAED,aAAa,CAAC,IAAY,EAA6B;QACtD,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAAA,CAClC;IAED,gBAAgB,CAAC,UAAkB,EAAoB;QACtD,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;IAAA,CACrD;IAED,KAAK,CAAC,QAAQ,CAAC,QAAgB,EAAE,IAA6B,EAAE,SAAS,GAAG,IAAI,CAAC,aAAa,EAAoB;QACjH,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAC3C,IAAI,WAAW;YAAE,MAAM,WAAW,CAAC;QACnC,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC3C,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,qBAAqB,QAAQ,EAAE,CAAC,CAAC;YAExF,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC5D,IAAI,CAAC,UAAU,EAAE,MAAM;gBACtB,MAAM,IAAI,gBAAgB,CACzB,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,QAAQ,EAChB,eAAe,OAAO,CAAC,UAAU,iBAAiB,CAClD,CAAC;YAEH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;YAC9D,IAAI,CAAC;gBACJ,OAAO,MAAM,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE;oBAC/F,MAAM,EAAE,UAAU,CAAC,MAAM;iBACzB,CAAC,CAAC;YACJ,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBAC/B,MAAM,IAAI,eAAe,CAAC,YAAY,QAAQ,GAAG,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;gBACnF,CAAC;gBACD,MAAM,IAAI,gBAAgB,CACzB,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,QAAQ,EAChB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAC1C,CAAC;YACH,CAAC;oBAAS,CAAC;gBACV,YAAY,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,eAAe,EAAE,CAAC;QACxB,CAAC;IAAA,CACD;IAEO,eAAe,GAA8B;QACpD,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,OAAO,SAAS,CAAC;QAC1C,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC;YACzD,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;YAC7B,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACrC,IAAI,CAAC,aAAc,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACpC,IAAI,CAAC,aAAc,CAAC,OAAO,EAAE,CAAC;gBAC9B,OAAO,EAAE,CAAC;YAAA,CACV,CAAC,CAAC;QAAA,CACH,CAAC,CAAC;IAAA,CACH;IAEO,eAAe,GAAS;QAC/B,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,OAAO;QAChC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAC9C,IAAI,IAAI;YAAE,IAAI,EAAE,CAAC;IAAA,CACjB;IAED,WAAW,GAAqB;QAC/B,MAAM,KAAK,GAAqB,EAAE,CAAC;QACnC,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACpD,IAAI,UAAU,CAAC,MAAM,KAAK,WAAW;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACxE,CAAC;QACD,OAAO,KAAK,CAAC;IAAA,CACb;IAED,KAAK,CAAC,aAAa,GAAkB;QACpC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QACvE,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAE7B,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC;gBACJ,IAAI,UAAU,CAAC,MAAM;oBAAE,MAAM,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBACvD,UAAU,CAAC,MAAM,GAAG,cAAc,CAAC;YACpC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACX,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAAA,CACrB;IAEO,KAAK,CAAC,eAAe,CAAC,MAAuB,EAAE;QACtD,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,oBAAoB,CAAC;gBAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,GAAG,EAAE,MAAM,CAAC,GAAG;oBACd,CAAC,CAAE,MAAM,CAAC,WAAW,CACnB,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CACzD;oBAC7B,CAAC,CAAC,SAAS;gBACZ,MAAM,EAAE,MAAM;aACd,CAAC,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC3B,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,yCAAyC,CAAC,CAAC;YACvF,OAAO,IAAI,kBAAkB,CAC5B,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EACnB,MAAM,CAAC,OAAO;gBACb,CAAC,CAAC;oBACA,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE;iBACxC;gBACF,CAAC,CAAC,SAAS,CACZ,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACvC,MAAM,EAAE,6BAA6B,EAAE,GAAG,MAAM,MAAM,CAAC,oDAAoD,CAAC,CAAC;YAC7G,OAAO,IAAI,6BAA6B,CACvC,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EACnB,MAAM,CAAC,OAAO;gBACb,CAAC,CAAC;oBACA,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE;iBACxC;gBACF,CAAC,CAAC,SAAS,CACZ,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,+BAAgC,MAA2B,CAAC,IAAI,EAAE,CAAC,CAAC;IAAA,CACpF;IAEO,aAAa,CAAC,MAAuB,EAAkC;QAC9E,OAAO,SAAS,IAAI,MAAM,CAAC;IAAA,CAC3B;CACD","sourcesContent":["import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { McpConnectionError, McpError, McpTimeoutError, McpToolCallError } from \"./errors.js\";\nimport { McpLogger } from \"./logger.js\";\nimport type {\n\tDiscoveredTool,\n\tMcpConnection,\n\tMcpManagerEvents,\n\tMcpManagerOptions,\n\tMcpServerConfig,\n\tMcpStdioServerConfig,\n} from \"./types.js\";\n\ninterface ManagedConnection extends McpConnection {\n\tclient?: Client;\n}\n\ninterface Semaphore {\n\tcurrent: number;\n\tmax: number;\n\tqueue: Array<() => void>;\n}\n\nexport class McpManager {\n\tprivate connections = new Map<string, ManagedConnection>();\n\tprivate toolMap = new Map<string, { serverName: string; toolName: string }>();\n\tprivate readonly logger: McpLogger;\n\tprivate readonly events: McpManagerEvents;\n\tprivate readonly connectTimeoutMs: number;\n\tprivate readonly callTimeoutMs: number;\n\tprivate readonly maxReconnectAttempts: number;\n\tprivate readonly callSemaphore: Semaphore | undefined;\n\n\tprivate reconnectTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\tprivate baseReconnectDelay = 1000;\n\tprivate maxReconnectDelay = 30000;\n\n\tprivate cleanupHandler: (() => void) | undefined;\n\n\tconstructor(\n\t\toptionsOrEvents?:\n\t\t\t| McpManagerEvents\n\t\t\t| (McpManagerOptions & { onConnectionChange?: McpManagerEvents[\"onConnectionChange\"] }),\n\t) {\n\t\tconst hasOptions =\n\t\t\toptionsOrEvents &&\n\t\t\t(\"logLevel\" in optionsOrEvents ||\n\t\t\t\t\"connectTimeoutMs\" in optionsOrEvents ||\n\t\t\t\t\"callTimeoutMs\" in optionsOrEvents ||\n\t\t\t\t\"maxReconnectAttempts\" in optionsOrEvents ||\n\t\t\t\t\"maxConcurrentCalls\" in optionsOrEvents);\n\t\tconst opts = hasOptions ? (optionsOrEvents as McpManagerOptions) : undefined;\n\t\tconst eventsCallback = (optionsOrEvents as Record<string, unknown>)?.onConnectionChange as\n\t\t\t| McpManagerEvents[\"onConnectionChange\"]\n\t\t\t| undefined;\n\n\t\tthis.events = eventsCallback ? { onConnectionChange: eventsCallback } : {};\n\t\tthis.logger = new McpLogger(opts?.logLevel ?? \"info\");\n\t\tthis.connectTimeoutMs = opts?.connectTimeoutMs ?? 30_000;\n\t\tthis.callTimeoutMs = opts?.callTimeoutMs ?? 60_000;\n\t\tthis.maxReconnectAttempts = opts?.maxReconnectAttempts ?? 3;\n\t\tif (opts?.maxConcurrentCalls) {\n\t\t\tthis.callSemaphore = { current: 0, max: opts.maxConcurrentCalls, queue: [] };\n\t\t}\n\t\tthis.registerCleanup();\n\t}\n\n\tprivate registerCleanup() {\n\t\tthis.cleanupHandler = () => {\n\t\t\tthis.disconnectAll().catch(() => {});\n\t\t};\n\t\tprocess.on(\"beforeExit\", this.cleanupHandler);\n\t\tprocess.on(\"SIGTERM\", this.cleanupHandler);\n\t\tprocess.on(\"SIGINT\", this.cleanupHandler);\n\t}\n\n\tdispose(): Promise<void> {\n\t\tif (this.cleanupHandler) {\n\t\t\tprocess.off(\"beforeExit\", this.cleanupHandler);\n\t\t\tprocess.off(\"SIGTERM\", this.cleanupHandler);\n\t\t\tprocess.off(\"SIGINT\", this.cleanupHandler);\n\t\t\tthis.cleanupHandler = undefined;\n\t\t}\n\t\tfor (const timer of this.reconnectTimers.values()) clearTimeout(timer);\n\t\tthis.reconnectTimers.clear();\n\t\treturn this.disconnectAll();\n\t}\n\n\tprivate notifyChange(conn: McpConnection) {\n\t\tthis.events.onConnectionChange?.(conn);\n\t}\n\n\tasync connectAll(servers: Record<string, McpServerConfig>): Promise<void> {\n\t\tconst entries = Object.entries(servers).filter(([_, c]) => !c.disabled);\n\t\tif (entries.length === 0) return;\n\n\t\tconst results = await Promise.allSettled(entries.map(([name, config]) => this.connectServer(name, config)));\n\n\t\tconst succeeded = results.filter((r) => r.status === \"fulfilled\").length;\n\t\tconst failed = results.filter((r) => r.status === \"rejected\").length;\n\t\tthis.logger.info(\"*\", `${succeeded} server(s) connected${failed > 0 ? `, ${failed} failed` : \"\"}`);\n\t}\n\n\tasync connectServer(name: string, config: McpServerConfig): Promise<void> {\n\t\tconst existing = this.connections.get(name);\n\t\tif (existing?.client) {\n\t\t\ttry {\n\t\t\t\tawait existing.client.close();\n\t\t\t} catch {}\n\t\t}\n\n\t\tconst entry: ManagedConnection = { name, config, status: \"connecting\", tools: [] };\n\t\tthis.connections.set(name, entry);\n\t\tthis.notifyChange(entry);\n\n\t\ttry {\n\t\t\tawait this.doConnectWithTimeout(name, config);\n\t\t} catch (e) {\n\t\t\tentry.status = \"error\";\n\t\t\tentry.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.logger.error(name, `Connection failed: ${entry.error}`);\n\t\t\tthis.notifyChange(entry);\n\t\t\tthrow e instanceof McpError ? e : new McpConnectionError(name, entry.error);\n\t\t}\n\t}\n\n\tprivate async doConnectWithTimeout(\n\t\tname: string,\n\t\tconfig: McpServerConfig,\n\t\ttimeoutMs = this.connectTimeoutMs,\n\t): Promise<void> {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\ttry {\n\t\t\tawait this.doConnectServer(name, config, controller.signal);\n\t\t} catch (e) {\n\t\t\tif (controller.signal.aborted) {\n\t\t\t\tthrow new McpTimeoutError(\"connect\", name, timeoutMs);\n\t\t\t}\n\t\t\tthrow e;\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n\n\tprivate async doConnectServer(name: string, config: McpServerConfig, signal?: AbortSignal): Promise<void> {\n\t\tconst entry = this.connections.get(name);\n\t\tif (!entry) return;\n\n\t\tconst transport = await this.createTransport(config);\n\t\tconst client = new Client({ name: \"pi-mcp\", version: \"1.0.0\" }, { capabilities: {} });\n\n\t\tawait client.connect(transport, { signal });\n\t\tconst { tools } = await client.listTools();\n\n\t\tentry.client = client;\n\t\tentry.status = \"connected\";\n\t\tentry.error = undefined;\n\n\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t}\n\t\t}\n\n\t\tentry.tools = (tools ?? []).map((tool) => {\n\t\t\tconst fullName = `mcp__${name}__${tool.name}`;\n\t\t\tthis.toolMap.set(fullName, { serverName: name, toolName: tool.name });\n\t\t\treturn {\n\t\t\t\tserverName: name,\n\t\t\t\toriginalName: tool.name,\n\t\t\t\tfullName,\n\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t};\n\t\t});\n\n\t\tthis.logger.info(name, `${entry.tools.length} tool(s) discovered`);\n\t\tthis.notifyChange(entry);\n\n\t\tclient.onclose = () => {\n\t\t\tconst conn = this.connections.get(name);\n\t\t\tif (!conn || conn.status === \"disconnected\") return;\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = \"Connection closed unexpectedly\";\n\t\t\tthis.logger.warn(name, \"Connection closed unexpectedly\");\n\t\t\tthis.notifyChange(conn);\n\t\t\tthis.scheduleReconnect(name, 0);\n\t\t};\n\n\t\tclient.onerror = (err: Error) => {\n\t\t\tconst conn = this.connections.get(name);\n\t\t\tif (!conn) return;\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = err.message;\n\t\t\tthis.logger.error(name, `Client error: ${err.message}`);\n\t\t\tthis.notifyChange(conn);\n\t\t};\n\t}\n\n\tprivate scheduleReconnect(name: string, attempt: number) {\n\t\tif (attempt >= this.maxReconnectAttempts) {\n\t\t\tthis.logger.warn(name, `Max reconnect attempts (${this.maxReconnectAttempts}) reached`);\n\t\t\treturn;\n\t\t}\n\t\tconst existing = this.reconnectTimers.get(name);\n\t\tif (existing) {\n\t\t\tclearTimeout(existing);\n\t\t}\n\n\t\tconst delay = Math.min(this.baseReconnectDelay * 2 ** attempt, this.maxReconnectDelay);\n\t\tthis.logger.info(name, `Reconnecting in ${delay}ms (attempt ${attempt + 1}/${this.maxReconnectAttempts})`);\n\n\t\tconst timer = setTimeout(() => {\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t\tthis.reconnectServer(name, attempt + 1);\n\t\t}, delay);\n\t\tthis.reconnectTimers.set(name, timer);\n\t}\n\n\tprivate async reconnectServer(name: string, attempt: number): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn || conn.config.disabled) return;\n\n\t\tconn.status = \"connecting\";\n\t\tconn.error = undefined;\n\t\tthis.notifyChange(conn);\n\n\t\ttry {\n\t\t\tif (conn.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait conn.client.close();\n\t\t\t\t} catch {}\n\t\t\t\tconn.client = undefined;\n\t\t\t}\n\t\t\tawait this.doConnectServer(name, conn.config);\n\t\t\tthis.logger.info(name, \"Reconnected successfully\");\n\t\t} catch (e) {\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.notifyChange(conn);\n\t\t\tthis.scheduleReconnect(name, attempt);\n\t\t}\n\t}\n\n\tasync addServer(name: string, config: McpServerConfig): Promise<void> {\n\t\tawait this.connectServer(name, config);\n\t}\n\n\tasync removeServer(name: string): Promise<void> {\n\t\tconst timer = this.reconnectTimers.get(name);\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t}\n\n\t\tconst conn = this.connections.get(name);\n\t\tif (conn?.client) {\n\t\t\ttry {\n\t\t\t\tawait conn.client.close();\n\t\t\t} catch {}\n\t\t}\n\n\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t}\n\t\t}\n\n\t\tthis.connections.delete(name);\n\t}\n\n\tasync setServerEnabled(name: string, enabled: boolean): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn) return;\n\n\t\tconn.config = { ...conn.config, disabled: !enabled } as McpServerConfig;\n\n\t\tif (!enabled) {\n\t\t\tconst timer = this.reconnectTimers.get(name);\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis.reconnectTimers.delete(name);\n\t\t\t}\n\t\t\tif (conn.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait conn.client.close();\n\t\t\t\t} catch {}\n\t\t\t\tconn.client = undefined;\n\t\t\t}\n\t\t\tconn.status = \"disconnected\";\n\t\t\tthis.notifyChange(conn);\n\t\t} else {\n\t\t\tawait this.connectServer(name, conn.config);\n\t\t}\n\t}\n\n\tasync refreshTools(serverName?: string): Promise<DiscoveredTool[]> {\n\t\tif (serverName) {\n\t\t\tconst conn = this.connections.get(serverName);\n\t\t\tif (!conn?.client) return [];\n\t\t\ttry {\n\t\t\t\tconst { tools } = await conn.client.listTools();\n\t\t\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\t\t\tif (this.toolMap.get(oldKey)?.serverName === serverName) {\n\t\t\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconn.tools = (tools ?? []).map((tool) => {\n\t\t\t\t\tconst fullName = `mcp__${serverName}__${tool.name}`;\n\t\t\t\t\tthis.toolMap.set(fullName, { serverName, toolName: tool.name });\n\t\t\t\t\treturn {\n\t\t\t\t\t\tserverName,\n\t\t\t\t\t\toriginalName: tool.name,\n\t\t\t\t\t\tfullName,\n\t\t\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t\tthis.logger.info(serverName, `Refreshed: ${conn.tools.length} tool(s)`);\n\t\t\t\tthis.notifyChange(conn);\n\t\t\t} catch (e) {\n\t\t\t\tthis.logger.error(serverName, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);\n\t\t\t}\n\t\t\treturn conn.tools;\n\t\t}\n\n\t\tconst allTools: DiscoveredTool[] = [];\n\t\tfor (const [name, conn] of this.connections) {\n\t\t\tif (conn.client && conn.status === \"connected\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst { tools } = await conn.client.listTools();\n\t\t\t\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\t\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconn.tools = (tools ?? []).map((tool) => {\n\t\t\t\t\t\tconst fullName = `mcp__${name}__${tool.name}`;\n\t\t\t\t\t\tthis.toolMap.set(fullName, { serverName: name, toolName: tool.name });\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tserverName: name,\n\t\t\t\t\t\t\toriginalName: tool.name,\n\t\t\t\t\t\t\tfullName,\n\t\t\t\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t\tallTools.push(...conn.tools);\n\t\t\t\t\tthis.notifyChange(conn);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.logger.error(name, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn allTools;\n\t}\n\n\tgetConnections(): McpConnection[] {\n\t\treturn [...this.connections.values()];\n\t}\n\n\tgetConnection(name: string): McpConnection | undefined {\n\t\treturn this.connections.get(name);\n\t}\n\n\tgetToolsByServer(serverName: string): DiscoveredTool[] {\n\t\treturn this.connections.get(serverName)?.tools ?? [];\n\t}\n\n\tasync callTool(fullName: string, args: Record<string, unknown>, timeoutMs = this.callTimeoutMs): Promise<unknown> {\n\t\tconst slotPromise = this.acquireCallSlot();\n\t\tif (slotPromise) await slotPromise;\n\t\ttry {\n\t\t\tconst mapping = this.toolMap.get(fullName);\n\t\t\tif (!mapping) throw new McpToolCallError(\"\", fullName, `Unknown MCP tool: ${fullName}`);\n\n\t\t\tconst connection = this.connections.get(mapping.serverName);\n\t\t\tif (!connection?.client)\n\t\t\t\tthrow new McpToolCallError(\n\t\t\t\t\tmapping.serverName,\n\t\t\t\t\tmapping.toolName,\n\t\t\t\t\t`MCP server \"${mapping.serverName}\" not connected`,\n\t\t\t\t);\n\n\t\t\tconst controller = new AbortController();\n\t\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\t\ttry {\n\t\t\t\treturn await connection.client.callTool({ name: mapping.toolName, arguments: args }, undefined, {\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tif (controller.signal.aborted) {\n\t\t\t\t\tthrow new McpTimeoutError(`callTool(${fullName})`, mapping.serverName, timeoutMs);\n\t\t\t\t}\n\t\t\t\tthrow new McpToolCallError(\n\t\t\t\t\tmapping.serverName,\n\t\t\t\t\tmapping.toolName,\n\t\t\t\t\te instanceof Error ? e.message : String(e),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.releaseCallSlot();\n\t\t}\n\t}\n\n\tprivate acquireCallSlot(): Promise<void> | undefined {\n\t\tif (!this.callSemaphore) return undefined;\n\t\tif (this.callSemaphore.current < this.callSemaphore.max) {\n\t\t\tthis.callSemaphore.current++;\n\t\t\treturn undefined;\n\t\t}\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tthis.callSemaphore!.queue.push(() => {\n\t\t\t\tthis.callSemaphore!.current++;\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate releaseCallSlot(): void {\n\t\tif (!this.callSemaphore) return;\n\t\tthis.callSemaphore.current--;\n\t\tconst next = this.callSemaphore.queue.shift();\n\t\tif (next) next();\n\t}\n\n\tgetAllTools(): DiscoveredTool[] {\n\t\tconst tools: DiscoveredTool[] = [];\n\t\tfor (const connection of this.connections.values()) {\n\t\t\tif (connection.status === \"connected\") tools.push(...connection.tools);\n\t\t}\n\t\treturn tools;\n\t}\n\n\tasync disconnectAll(): Promise<void> {\n\t\tfor (const timer of this.reconnectTimers.values()) clearTimeout(timer);\n\t\tthis.reconnectTimers.clear();\n\n\t\tfor (const connection of this.connections.values()) {\n\t\t\ttry {\n\t\t\t\tif (connection.client) await connection.client.close();\n\t\t\t\tconnection.status = \"disconnected\";\n\t\t\t} catch {}\n\t\t}\n\t\tthis.connections.clear();\n\t\tthis.toolMap.clear();\n\t}\n\n\tprivate async createTransport(config: McpServerConfig) {\n\t\tif (this.isStdioConfig(config)) {\n\t\t\treturn new StdioClientTransport({\n\t\t\t\tcommand: config.command,\n\t\t\t\targs: config.args,\n\t\t\t\tenv: config.env\n\t\t\t\t\t? (Object.fromEntries(\n\t\t\t\t\t\t\tObject.entries({ ...process.env, ...config.env }).filter(([, v]) => v !== undefined),\n\t\t\t\t\t\t) as Record<string, string>)\n\t\t\t\t\t: undefined,\n\t\t\t\tstderr: \"pipe\",\n\t\t\t});\n\t\t}\n\t\tif (config.type === \"sse\") {\n\t\t\tconst { SSEClientTransport } = await import(\"@modelcontextprotocol/sdk/client/sse.js\");\n\t\t\treturn new SSEClientTransport(\n\t\t\t\tnew URL(config.url),\n\t\t\t\tconfig.headers\n\t\t\t\t\t? {\n\t\t\t\t\t\t\trequestInit: { headers: config.headers },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\t\tif (config.type === \"streamable-http\") {\n\t\t\tconst { StreamableHTTPClientTransport } = await import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\");\n\t\t\treturn new StreamableHTTPClientTransport(\n\t\t\t\tnew URL(config.url),\n\t\t\t\tconfig.headers\n\t\t\t\t\t? {\n\t\t\t\t\t\t\trequestInit: { headers: config.headers },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\t\tthrow new Error(`Unknown MCP transport type: ${(config as { type: string }).type}`);\n\t}\n\n\tprivate isStdioConfig(config: McpServerConfig): config is McpStdioServerConfig {\n\t\treturn \"command\" in config;\n\t}\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import { type ToolDefinition } from "../extensions/types.js";
2
+ import type { McpManager } from "./mcp-manager.js";
3
+ import type { DiscoveredTool } from "./types.js";
4
+ export declare function createMcpToolDefinition(tool: DiscoveredTool, manager: McpManager): ToolDefinition;
5
+ //# sourceMappingURL=tool-converter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-converter.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/tool-converter.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOjD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,UAAU,GAAG,cAAc,CAmBjG","sourcesContent":["import { Type } from \"@dyyz1993/pi-ai\";\nimport { defineTool, type ToolDefinition } from \"../extensions/types.js\";\nimport type { McpManager } from \"./mcp-manager.js\";\nimport type { DiscoveredTool } from \"./types.js\";\n\ninterface McpToolResult {\n\tcontent?: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t[key: string]: unknown;\n}\n\nexport function createMcpToolDefinition(tool: DiscoveredTool, manager: McpManager): ToolDefinition {\n\treturn defineTool({\n\t\tname: tool.fullName,\n\t\tlabel: `${tool.serverName}/${tool.originalName}`,\n\t\tdescription: tool.description || `MCP tool: ${tool.originalName} (from ${tool.serverName})`,\n\t\t// MCP servers return JSON Schema which may not conform to TypeBox's stricter\n\t\t// internal representation. Using Type.Unsafe preserves the schema for runtime\n\t\t// validation while bridging the type gap.\n\t\tparameters: Type.Unsafe(tool.inputSchema) as any,\n\t\tasync execute(_toolCallId: string, params: Record<string, unknown>) {\n\t\t\ttry {\n\t\t\t\tconst result = (await manager.callTool(tool.fullName, params)) as McpToolResult;\n\t\t\t\treturn formatResult(result);\n\t\t\t} catch (e) {\n\t\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\t\treturn { content: [{ type: \"text\" as const, text: `MCP error: ${msg}` }], details: undefined };\n\t\t\t}\n\t\t},\n\t});\n}\n\nfunction formatResult(result: McpToolResult): { content: Array<{ type: \"text\"; text: string }>; details: undefined } {\n\tif (result?.content && Array.isArray(result.content)) {\n\t\tconst text = result.content\n\t\t\t.map((c) => {\n\t\t\t\tif (c.type === \"text\") return c.text ?? \"\";\n\t\t\t\tif (c.type === \"image\" && c.data) return `[image: ${c.mimeType}]`;\n\t\t\t\treturn JSON.stringify(c);\n\t\t\t})\n\t\t\t.join(\"\\n\");\n\t\treturn { content: [{ type: \"text\" as const, text }], details: undefined };\n\t}\n\treturn { content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }], details: undefined };\n}\n"]}
@@ -0,0 +1,39 @@
1
+ import { Type } from "@dyyz1993/pi-ai";
2
+ import { defineTool } from "../extensions/types.js";
3
+ export function createMcpToolDefinition(tool, manager) {
4
+ return defineTool({
5
+ name: tool.fullName,
6
+ label: `${tool.serverName}/${tool.originalName}`,
7
+ description: tool.description || `MCP tool: ${tool.originalName} (from ${tool.serverName})`,
8
+ // MCP servers return JSON Schema which may not conform to TypeBox's stricter
9
+ // internal representation. Using Type.Unsafe preserves the schema for runtime
10
+ // validation while bridging the type gap.
11
+ parameters: Type.Unsafe(tool.inputSchema),
12
+ async execute(_toolCallId, params) {
13
+ try {
14
+ const result = (await manager.callTool(tool.fullName, params));
15
+ return formatResult(result);
16
+ }
17
+ catch (e) {
18
+ const msg = e instanceof Error ? e.message : String(e);
19
+ return { content: [{ type: "text", text: `MCP error: ${msg}` }], details: undefined };
20
+ }
21
+ },
22
+ });
23
+ }
24
+ function formatResult(result) {
25
+ if (result?.content && Array.isArray(result.content)) {
26
+ const text = result.content
27
+ .map((c) => {
28
+ if (c.type === "text")
29
+ return c.text ?? "";
30
+ if (c.type === "image" && c.data)
31
+ return `[image: ${c.mimeType}]`;
32
+ return JSON.stringify(c);
33
+ })
34
+ .join("\n");
35
+ return { content: [{ type: "text", text }], details: undefined };
36
+ }
37
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }], details: undefined };
38
+ }
39
+ //# sourceMappingURL=tool-converter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-converter.js","sourceRoot":"","sources":["../../../src/core/mcp/tool-converter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAuB,MAAM,wBAAwB,CAAC;AASzE,MAAM,UAAU,uBAAuB,CAAC,IAAoB,EAAE,OAAmB,EAAkB;IAClG,OAAO,UAAU,CAAC;QACjB,IAAI,EAAE,IAAI,CAAC,QAAQ;QACnB,KAAK,EAAE,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE;QAChD,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,aAAa,IAAI,CAAC,YAAY,UAAU,IAAI,CAAC,UAAU,GAAG;QAC3F,6EAA6E;QAC7E,8EAA8E;QAC9E,0CAA0C;QAC1C,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAQ;QAChD,KAAK,CAAC,OAAO,CAAC,WAAmB,EAAE,MAA+B,EAAE;YACnE,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAkB,CAAC;gBAChF,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBACvD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,cAAc,GAAG,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;YAChG,CAAC;QAAA,CACD;KACD,CAAC,CAAC;AAAA,CACH;AAED,SAAS,YAAY,CAAC,MAAqB,EAA0E;IACpH,IAAI,MAAM,EAAE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;gBAAE,OAAO,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YAC3C,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI;gBAAE,OAAO,WAAW,CAAC,CAAC,QAAQ,GAAG,CAAC;YAClE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAAA,CACzB,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAC3E,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAAA,CAC3G","sourcesContent":["import { Type } from \"@dyyz1993/pi-ai\";\nimport { defineTool, type ToolDefinition } from \"../extensions/types.js\";\nimport type { McpManager } from \"./mcp-manager.js\";\nimport type { DiscoveredTool } from \"./types.js\";\n\ninterface McpToolResult {\n\tcontent?: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t[key: string]: unknown;\n}\n\nexport function createMcpToolDefinition(tool: DiscoveredTool, manager: McpManager): ToolDefinition {\n\treturn defineTool({\n\t\tname: tool.fullName,\n\t\tlabel: `${tool.serverName}/${tool.originalName}`,\n\t\tdescription: tool.description || `MCP tool: ${tool.originalName} (from ${tool.serverName})`,\n\t\t// MCP servers return JSON Schema which may not conform to TypeBox's stricter\n\t\t// internal representation. Using Type.Unsafe preserves the schema for runtime\n\t\t// validation while bridging the type gap.\n\t\tparameters: Type.Unsafe(tool.inputSchema) as any,\n\t\tasync execute(_toolCallId: string, params: Record<string, unknown>) {\n\t\t\ttry {\n\t\t\t\tconst result = (await manager.callTool(tool.fullName, params)) as McpToolResult;\n\t\t\t\treturn formatResult(result);\n\t\t\t} catch (e) {\n\t\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\t\treturn { content: [{ type: \"text\" as const, text: `MCP error: ${msg}` }], details: undefined };\n\t\t\t}\n\t\t},\n\t});\n}\n\nfunction formatResult(result: McpToolResult): { content: Array<{ type: \"text\"; text: string }>; details: undefined } {\n\tif (result?.content && Array.isArray(result.content)) {\n\t\tconst text = result.content\n\t\t\t.map((c) => {\n\t\t\t\tif (c.type === \"text\") return c.text ?? \"\";\n\t\t\t\tif (c.type === \"image\" && c.data) return `[image: ${c.mimeType}]`;\n\t\t\t\treturn JSON.stringify(c);\n\t\t\t})\n\t\t\t.join(\"\\n\");\n\t\treturn { content: [{ type: \"text\" as const, text }], details: undefined };\n\t}\n\treturn { content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }], details: undefined };\n}\n"]}
@@ -0,0 +1,50 @@
1
+ export interface McpStdioServerConfig {
2
+ command: string;
3
+ args?: string[];
4
+ env?: Record<string, string>;
5
+ cwd?: string;
6
+ disabled?: boolean;
7
+ }
8
+ export interface McpSseServerConfig {
9
+ type: "sse";
10
+ url: string;
11
+ headers?: Record<string, string>;
12
+ disabled?: boolean;
13
+ }
14
+ export interface McpStreamableHttpServerConfig {
15
+ type: "streamable-http";
16
+ url: string;
17
+ headers?: Record<string, string>;
18
+ disabled?: boolean;
19
+ }
20
+ export type McpServerConfig = McpStdioServerConfig | McpSseServerConfig | McpStreamableHttpServerConfig;
21
+ export interface McpManagerOptions {
22
+ logLevel?: "debug" | "info" | "warn" | "error";
23
+ connectTimeoutMs?: number;
24
+ callTimeoutMs?: number;
25
+ maxReconnectAttempts?: number;
26
+ maxConcurrentCalls?: number;
27
+ }
28
+ export interface McpSettings {
29
+ servers?: Record<string, McpServerConfig>;
30
+ options?: Omit<McpManagerOptions, "maxConcurrentCalls">;
31
+ }
32
+ export interface DiscoveredTool {
33
+ serverName: string;
34
+ originalName: string;
35
+ fullName: string;
36
+ description: string;
37
+ inputSchema: Record<string, unknown>;
38
+ }
39
+ export type ConnectionStatus = "connecting" | "connected" | "error" | "disconnected";
40
+ export interface McpConnection {
41
+ name: string;
42
+ config: McpServerConfig;
43
+ status: ConnectionStatus;
44
+ error?: string;
45
+ tools: DiscoveredTool[];
46
+ }
47
+ export interface McpManagerEvents {
48
+ onConnectionChange?: (connection: McpConnection) => void;
49
+ }
50
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,6BAA6B;IAC7C,IAAI,EAAE,iBAAiB,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,eAAe,GAAG,oBAAoB,GAAG,kBAAkB,GAAG,6BAA6B,CAAC;AAExG,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;CACxD;AAED,MAAM,WAAW,cAAc;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,GAAG,cAAc,CAAC;AAErF,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,cAAc,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAChC,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;CACzD","sourcesContent":["export interface McpStdioServerConfig {\n\tcommand: string;\n\targs?: string[];\n\tenv?: Record<string, string>;\n\tcwd?: string;\n\tdisabled?: boolean;\n}\n\nexport interface McpSseServerConfig {\n\ttype: \"sse\";\n\turl: string;\n\theaders?: Record<string, string>;\n\tdisabled?: boolean;\n}\n\nexport interface McpStreamableHttpServerConfig {\n\ttype: \"streamable-http\";\n\turl: string;\n\theaders?: Record<string, string>;\n\tdisabled?: boolean;\n}\n\nexport type McpServerConfig = McpStdioServerConfig | McpSseServerConfig | McpStreamableHttpServerConfig;\n\nexport interface McpManagerOptions {\n\tlogLevel?: \"debug\" | \"info\" | \"warn\" | \"error\";\n\tconnectTimeoutMs?: number;\n\tcallTimeoutMs?: number;\n\tmaxReconnectAttempts?: number;\n\tmaxConcurrentCalls?: number;\n}\n\nexport interface McpSettings {\n\tservers?: Record<string, McpServerConfig>;\n\toptions?: Omit<McpManagerOptions, \"maxConcurrentCalls\">;\n}\n\nexport interface DiscoveredTool {\n\tserverName: string;\n\toriginalName: string;\n\tfullName: string;\n\tdescription: string;\n\tinputSchema: Record<string, unknown>;\n}\n\nexport type ConnectionStatus = \"connecting\" | \"connected\" | \"error\" | \"disconnected\";\n\nexport interface McpConnection {\n\tname: string;\n\tconfig: McpServerConfig;\n\tstatus: ConnectionStatus;\n\terror?: string;\n\ttools: DiscoveredTool[];\n}\n\nexport interface McpManagerEvents {\n\tonConnectionChange?: (connection: McpConnection) => void;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/mcp/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface McpStdioServerConfig {\n\tcommand: string;\n\targs?: string[];\n\tenv?: Record<string, string>;\n\tcwd?: string;\n\tdisabled?: boolean;\n}\n\nexport interface McpSseServerConfig {\n\ttype: \"sse\";\n\turl: string;\n\theaders?: Record<string, string>;\n\tdisabled?: boolean;\n}\n\nexport interface McpStreamableHttpServerConfig {\n\ttype: \"streamable-http\";\n\turl: string;\n\theaders?: Record<string, string>;\n\tdisabled?: boolean;\n}\n\nexport type McpServerConfig = McpStdioServerConfig | McpSseServerConfig | McpStreamableHttpServerConfig;\n\nexport interface McpManagerOptions {\n\tlogLevel?: \"debug\" | \"info\" | \"warn\" | \"error\";\n\tconnectTimeoutMs?: number;\n\tcallTimeoutMs?: number;\n\tmaxReconnectAttempts?: number;\n\tmaxConcurrentCalls?: number;\n}\n\nexport interface McpSettings {\n\tservers?: Record<string, McpServerConfig>;\n\toptions?: Omit<McpManagerOptions, \"maxConcurrentCalls\">;\n}\n\nexport interface DiscoveredTool {\n\tserverName: string;\n\toriginalName: string;\n\tfullName: string;\n\tdescription: string;\n\tinputSchema: Record<string, unknown>;\n}\n\nexport type ConnectionStatus = \"connecting\" | \"connected\" | \"error\" | \"disconnected\";\n\nexport interface McpConnection {\n\tname: string;\n\tconfig: McpServerConfig;\n\tstatus: ConnectionStatus;\n\terror?: string;\n\ttools: DiscoveredTool[];\n}\n\nexport interface McpManagerEvents {\n\tonConnectionChange?: (connection: McpConnection) => void;\n}\n"]}
@@ -45,6 +45,8 @@ export type PackageSource = string | {
45
45
  prompts?: string[];
46
46
  themes?: string[];
47
47
  };
48
+ import type { McpSettings } from "./mcp/types.js";
49
+ export type { McpManagerOptions, McpServerConfig, McpSettings, McpSseServerConfig, McpStdioServerConfig, McpStreamableHttpServerConfig, } from "./mcp/types.js";
48
50
  export interface Settings {
49
51
  lastChangelogVersion?: string;
50
52
  defaultProvider?: string;
@@ -81,6 +83,7 @@ export interface Settings {
81
83
  showHardwareCursor?: boolean;
82
84
  markdown?: MarkdownSettings;
83
85
  sessionDir?: string;
86
+ mcp?: McpSettings;
84
87
  }
85
88
  export type SettingsScope = "global" | "project";
86
89
  export interface SettingsStorage {