@xagent-ai/cli 1.3.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/release.yml +76 -0
- package/.github/workflows/ci.yml +3 -0
- package/.github/workflows/release.yml +11 -17
- package/README.md +2 -2
- package/README_CN.md +2 -2
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +7 -3
- package/dist/agents.js.map +1 -1
- package/dist/ai-client/factory.d.ts +0 -12
- package/dist/ai-client/factory.d.ts.map +1 -1
- package/dist/ai-client/factory.js +0 -32
- package/dist/ai-client/factory.js.map +1 -1
- package/dist/ai-client/index.js +1 -1
- package/dist/ai-client/index.js.map +1 -1
- package/dist/ai-client/providers/anthropic.d.ts.map +1 -1
- package/dist/ai-client/providers/anthropic.js +10 -4
- package/dist/ai-client/providers/anthropic.js.map +1 -1
- package/dist/ai-client/providers/openai.d.ts.map +1 -1
- package/dist/ai-client/providers/openai.js +8 -4
- package/dist/ai-client/providers/openai.js.map +1 -1
- package/dist/ai-client/providers/remote.d.ts +0 -1
- package/dist/ai-client/providers/remote.d.ts.map +1 -1
- package/dist/ai-client/providers/remote.js +11 -10
- package/dist/ai-client/providers/remote.js.map +1 -1
- package/dist/ai-client/types.d.ts +14 -0
- package/dist/ai-client/types.d.ts.map +1 -1
- package/dist/ai-client/types.js +17 -0
- package/dist/ai-client/types.js.map +1 -1
- package/dist/ai-client-factory.d.ts.map +1 -1
- package/dist/ai-client-factory.js +4 -4
- package/dist/ai-client-factory.js.map +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +10 -12
- package/dist/auth.js.map +1 -1
- package/dist/cancellation.d.ts.map +1 -1
- package/dist/cancellation.js +3 -5
- package/dist/cancellation.js.map +1 -1
- package/dist/checkpoint.d.ts +1 -0
- package/dist/checkpoint.d.ts.map +1 -1
- package/dist/checkpoint.js +38 -4
- package/dist/checkpoint.js.map +1 -1
- package/dist/cli.js +132 -32
- package/dist/cli.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/context-compressor.d.ts +1 -2
- package/dist/context-compressor.d.ts.map +1 -1
- package/dist/context-compressor.js +22 -17
- package/dist/context-compressor.js.map +1 -1
- package/dist/conversation.d.ts +1 -1
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +8 -7
- package/dist/conversation.js.map +1 -1
- package/dist/gui-subagent/action-parser/actionParser.js +2 -2
- package/dist/gui-subagent/action-parser/actionParser.js.map +1 -1
- package/dist/gui-subagent/agent/gui-agent.d.ts +10 -0
- package/dist/gui-subagent/agent/gui-agent.d.ts.map +1 -1
- package/dist/gui-subagent/agent/gui-agent.js +105 -32
- package/dist/gui-subagent/agent/gui-agent.js.map +1 -1
- package/dist/gui-subagent/index.d.ts +7 -0
- package/dist/gui-subagent/index.d.ts.map +1 -1
- package/dist/gui-subagent/index.js +2 -0
- package/dist/gui-subagent/index.js.map +1 -1
- package/dist/gui-subagent/operator/computer-operator.d.ts.map +1 -1
- package/dist/gui-subagent/operator/computer-operator.js +2 -0
- package/dist/gui-subagent/operator/computer-operator.js.map +1 -1
- package/dist/input-processor.js +2 -2
- package/dist/input-processor.js.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/mcp.d.ts +2 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +84 -21
- package/dist/mcp.js.map +1 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +3 -3
- package/dist/memory.js.map +1 -1
- package/dist/output-util.d.ts +27 -0
- package/dist/output-util.d.ts.map +1 -0
- package/dist/output-util.js +74 -0
- package/dist/output-util.js.map +1 -0
- package/dist/retry.js +1 -1
- package/dist/retry.js.map +1 -1
- package/dist/ripgrep.d.ts.map +1 -1
- package/dist/ripgrep.js +5 -3
- package/dist/ripgrep.js.map +1 -1
- package/dist/sdk-output-adapter.d.ts +265 -0
- package/dist/sdk-output-adapter.d.ts.map +1 -0
- package/dist/sdk-output-adapter.js +701 -0
- package/dist/sdk-output-adapter.js.map +1 -0
- package/dist/sdk-session.d.ts +13 -0
- package/dist/sdk-session.d.ts.map +1 -0
- package/dist/sdk-session.js +50 -0
- package/dist/sdk-session.js.map +1 -0
- package/dist/session-manager.js +3 -3
- package/dist/session-manager.js.map +1 -1
- package/dist/session.d.ts +96 -2
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +849 -262
- package/dist/session.js.map +1 -1
- package/dist/shell.d.ts.map +1 -1
- package/dist/shell.js +5 -4
- package/dist/shell.js.map +1 -1
- package/dist/skill-installer.js +3 -3
- package/dist/skill-installer.js.map +1 -1
- package/dist/skill-invoker.d.ts +1 -1
- package/dist/skill-invoker.d.ts.map +1 -1
- package/dist/skill-invoker.js +2 -2
- package/dist/skill-invoker.js.map +1 -1
- package/dist/skill-loader.js +6 -5
- package/dist/skill-loader.js.map +1 -1
- package/dist/skill-manager.d.ts.map +1 -1
- package/dist/skill-manager.js +3 -2
- package/dist/skill-manager.js.map +1 -1
- package/dist/slash-commands.d.ts +1 -1
- package/dist/slash-commands.d.ts.map +1 -1
- package/dist/slash-commands.js +24 -11
- package/dist/slash-commands.js.map +1 -1
- package/dist/smart-approval.d.ts +20 -1
- package/dist/smart-approval.d.ts.map +1 -1
- package/dist/smart-approval.js +58 -1
- package/dist/smart-approval.js.map +1 -1
- package/dist/system-prompt-generator.js +3 -3
- package/dist/system-prompt-generator.js.map +1 -1
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +9 -8
- package/dist/theme.js.map +1 -1
- package/dist/tools.d.ts +15 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +487 -215
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +57 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +49 -0
- package/dist/types.js.map +1 -1
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +12 -9
- package/dist/update.js.map +1 -1
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +1 -2
- package/dist/workflow.js.map +1 -1
- package/docs/third-party-models.md +16 -15
- package/package.json +3 -1
- package/src/agents.ts +7 -3
- package/src/ai-client/factory.ts +1 -36
- package/src/ai-client/index.ts +1 -1
- package/src/ai-client/providers/anthropic.ts +12 -3
- package/src/ai-client/providers/openai.ts +10 -4
- package/src/ai-client/providers/remote.ts +13 -10
- package/src/ai-client/types.ts +19 -0
- package/src/ai-client-factory.ts +5 -5
- package/src/auth.ts +11 -13
- package/src/cancellation.ts +3 -6
- package/src/checkpoint.ts +41 -4
- package/src/cli.ts +154 -37
- package/src/config.ts +1 -1
- package/src/context-compressor.ts +27 -22
- package/src/conversation.ts +9 -7
- package/src/gui-subagent/action-parser/actionParser.ts +2 -2
- package/src/gui-subagent/agent/gui-agent.ts +117 -34
- package/src/gui-subagent/index.ts +8 -0
- package/src/gui-subagent/operator/computer-operator.ts +2 -1
- package/src/input-processor.ts +2 -2
- package/src/logger.ts +2 -4
- package/src/mcp.ts +87 -23
- package/src/memory.ts +3 -4
- package/src/output-util.ts +80 -0
- package/src/retry.ts +1 -1
- package/src/ripgrep.ts +5 -3
- package/src/sdk-output-adapter.ts +842 -0
- package/src/sdk-session.ts +62 -0
- package/src/session-manager.ts +3 -3
- package/src/session.ts +942 -302
- package/src/shell.ts +6 -5
- package/src/skill-installer.ts +3 -3
- package/src/skill-invoker.ts +3 -4
- package/src/skill-loader.ts +7 -7
- package/src/skill-manager.ts +4 -3
- package/src/slash-commands.ts +24 -16
- package/src/smart-approval.ts +76 -1
- package/src/system-prompt-generator.ts +3 -3
- package/src/theme.ts +10 -9
- package/src/tools.ts +563 -267
- package/src/types.ts +118 -0
- package/src/update.ts +12 -9
- package/src/workflow.ts +2 -4
- package/test/cli-launch.test.ts +279 -0
- package/vitest.config.ts +2 -0
- /package/{.eslintrc.js → .eslintrc.cjs} +0 -0
package/src/mcp.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { spawn, ChildProcess } from 'child_process';
|
|
2
2
|
import { MCPServerConfig } from './types.js';
|
|
3
|
+
import { getSingletonSession } from './session.js';
|
|
4
|
+
import { output as logOutput } from './output-util.js';
|
|
5
|
+
import { icons } from './theme.js';
|
|
3
6
|
|
|
4
7
|
export interface MCPTool {
|
|
5
8
|
name: string;
|
|
6
9
|
description: string;
|
|
7
|
-
inputSchema:
|
|
10
|
+
inputSchema: Record<string, unknown>;
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
export class MCPServer {
|
|
@@ -44,9 +47,14 @@ export class MCPServer {
|
|
|
44
47
|
await this.waitForTools(10000);
|
|
45
48
|
|
|
46
49
|
this.isConnected = true;
|
|
47
|
-
|
|
50
|
+
const session = getSingletonSession();
|
|
51
|
+
if (session?.getIsSdkMode()) {
|
|
52
|
+
// SDK 模式下不输出
|
|
53
|
+
} else {
|
|
54
|
+
await logOutput('success', `MCP Server connected`);
|
|
55
|
+
}
|
|
48
56
|
} catch (error) {
|
|
49
|
-
|
|
57
|
+
await logOutput('error', `[mcp] Failed to connect MCP Server`, { error: error instanceof Error ? error.message : String(error) });
|
|
50
58
|
throw error;
|
|
51
59
|
}
|
|
52
60
|
}
|
|
@@ -60,7 +68,7 @@ export class MCPServer {
|
|
|
60
68
|
return; // Tools already loaded
|
|
61
69
|
}
|
|
62
70
|
|
|
63
|
-
return new Promise((resolve,
|
|
71
|
+
return new Promise((resolve, _reject) => {
|
|
64
72
|
const checkInterval = 100;
|
|
65
73
|
const startTime = Date.now();
|
|
66
74
|
|
|
@@ -70,14 +78,14 @@ export class MCPServer {
|
|
|
70
78
|
resolve();
|
|
71
79
|
} else if (Date.now() - startTime > timeoutMs) {
|
|
72
80
|
clearInterval(checkInterval);
|
|
73
|
-
|
|
81
|
+
logOutput('warning', `[MCP] Timeout waiting for tools (${timeoutMs}ms), proceeding anyway`);
|
|
74
82
|
resolve(); // Don't reject, just proceed without tools
|
|
75
83
|
} else {
|
|
76
84
|
// Continue checking
|
|
77
85
|
}
|
|
78
86
|
};
|
|
79
87
|
|
|
80
|
-
const
|
|
88
|
+
const _intervalId = setInterval(check, checkInterval);
|
|
81
89
|
check(); // Check immediately first
|
|
82
90
|
});
|
|
83
91
|
}
|
|
@@ -96,12 +104,12 @@ export class MCPServer {
|
|
|
96
104
|
});
|
|
97
105
|
|
|
98
106
|
this.process.on('error', (error) => {
|
|
99
|
-
|
|
107
|
+
logOutput('error', 'MCP Server error', { error: error.message });
|
|
100
108
|
reject(error);
|
|
101
109
|
});
|
|
102
110
|
|
|
103
111
|
this.process.on('exit', (code, signal) => {
|
|
104
|
-
|
|
112
|
+
logOutput('info', `MCP Server exited with code ${code}, signal ${signal}`);
|
|
105
113
|
this.isConnected = false;
|
|
106
114
|
});
|
|
107
115
|
|
|
@@ -113,7 +121,7 @@ export class MCPServer {
|
|
|
113
121
|
|
|
114
122
|
if (this.process.stderr) {
|
|
115
123
|
this.process.stderr.on('data', (data) => {
|
|
116
|
-
|
|
124
|
+
logOutput('error', 'MCP Server stderr', { error: data.toString() });
|
|
117
125
|
});
|
|
118
126
|
}
|
|
119
127
|
|
|
@@ -140,7 +148,10 @@ export class MCPServer {
|
|
|
140
148
|
}
|
|
141
149
|
|
|
142
150
|
const transportType = this.getTransportType();
|
|
143
|
-
|
|
151
|
+
const session = getSingletonSession();
|
|
152
|
+
if (!session?.getIsSdkMode()) {
|
|
153
|
+
console.log(`Connecting to MCP Server at ${this.config.url} (${transportType})`);
|
|
154
|
+
}
|
|
144
155
|
|
|
145
156
|
// Build headers with auth token
|
|
146
157
|
const headers: Record<string, string> = {
|
|
@@ -149,7 +160,8 @@ export class MCPServer {
|
|
|
149
160
|
...this.config.headers
|
|
150
161
|
};
|
|
151
162
|
|
|
152
|
-
if
|
|
163
|
+
// Only add Authorization if not already present in headers
|
|
164
|
+
if (this.config.authToken && !headers['Authorization']) {
|
|
153
165
|
if (this.config.authToken.startsWith('Bearer ')) {
|
|
154
166
|
headers['Authorization'] = this.config.authToken;
|
|
155
167
|
} else {
|
|
@@ -191,7 +203,8 @@ export class MCPServer {
|
|
|
191
203
|
// which handles both regular JSON and SSE format responses
|
|
192
204
|
await this.loadTools(headers);
|
|
193
205
|
} catch (error: any) {
|
|
194
|
-
|
|
206
|
+
const errorMsg = `HTTP connection failed: ${error.message}`;
|
|
207
|
+
await logOutput('error', errorMsg, { error: error.message });
|
|
195
208
|
if (error.response) {
|
|
196
209
|
console.error(`Response status: ${error.response.status}`);
|
|
197
210
|
if (error.response.data?.message) {
|
|
@@ -247,6 +260,7 @@ export class MCPServer {
|
|
|
247
260
|
const decoder = new TextDecoder();
|
|
248
261
|
let buffer = '';
|
|
249
262
|
|
|
263
|
+
// eslint-disable-next-line no-constant-condition
|
|
250
264
|
while (true) {
|
|
251
265
|
const { done, value } = await reader.read();
|
|
252
266
|
if (done) break;
|
|
@@ -260,7 +274,7 @@ export class MCPServer {
|
|
|
260
274
|
try {
|
|
261
275
|
const data = JSON.parse(line.slice(6));
|
|
262
276
|
this.handleJsonRpcMessage(data);
|
|
263
|
-
} catch
|
|
277
|
+
} catch {
|
|
264
278
|
// Ignore parse errors
|
|
265
279
|
}
|
|
266
280
|
}
|
|
@@ -271,11 +285,11 @@ export class MCPServer {
|
|
|
271
285
|
clearTimeout(timeoutId);
|
|
272
286
|
const serverInfo = this.config.url || this.config.command || 'MCP server';
|
|
273
287
|
if (error.name === 'AbortError') {
|
|
274
|
-
console.error(`\n
|
|
288
|
+
console.error(`\n${icons.error} SSE connection timed out`);
|
|
275
289
|
console.error(` Server: ${serverInfo}`);
|
|
276
290
|
console.error(` The server is not responding. Please try again later.`);
|
|
277
291
|
} else {
|
|
278
|
-
console.error(`\n
|
|
292
|
+
console.error(`\n${icons.error} SSE connection failed`);
|
|
279
293
|
console.error(` Server: ${serverInfo}`);
|
|
280
294
|
console.error(` ${error.message}`);
|
|
281
295
|
}
|
|
@@ -308,6 +322,8 @@ export class MCPServer {
|
|
|
308
322
|
this.handleToolsList(message.params);
|
|
309
323
|
} else if (message.method === 'notifications/initialized') {
|
|
310
324
|
console.log('MCP Server initialized');
|
|
325
|
+
} else if (message.method === 'notifications/tools_changed' || message.method === 'tools/list_changed') {
|
|
326
|
+
this.handleToolsChanged();
|
|
311
327
|
}
|
|
312
328
|
}
|
|
313
329
|
|
|
@@ -323,7 +339,53 @@ export class MCPServer {
|
|
|
323
339
|
if (!tool.name || typeof tool.name !== 'string' || tool.name.trim() === '') continue;
|
|
324
340
|
this.tools.set(tool.name, tool);
|
|
325
341
|
}
|
|
326
|
-
|
|
342
|
+
const session = getSingletonSession();
|
|
343
|
+
if (session?.getIsSdkMode()) {
|
|
344
|
+
// SDK 模式下不输出
|
|
345
|
+
} else {
|
|
346
|
+
console.log(`Loaded ${result.tools.length} tools from MCP Server`);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
private async handleToolsChanged(): Promise<void> {
|
|
352
|
+
const session = getSingletonSession();
|
|
353
|
+
if (session && !session.getIsSdkMode()) {
|
|
354
|
+
console.log(`MCP Server tools changed, reloading...`);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const transportType = this.getTransportType();
|
|
358
|
+
if (transportType === 'http' || transportType === 'sse') {
|
|
359
|
+
try {
|
|
360
|
+
const headers: Record<string, string> = {
|
|
361
|
+
'Content-Type': 'application/json',
|
|
362
|
+
...this.config.headers
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
if (this.config.authToken && !headers['Authorization']) {
|
|
366
|
+
if (this.config.authToken.startsWith('Bearer ')) {
|
|
367
|
+
headers['Authorization'] = this.config.authToken;
|
|
368
|
+
} else {
|
|
369
|
+
headers['Authorization'] = `Bearer ${this.config.authToken}`;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (this.sessionId) {
|
|
374
|
+
headers['MCP-session-id'] = this.sessionId;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
await this.loadTools(headers);
|
|
378
|
+
|
|
379
|
+
if (session && !session.getIsSdkMode()) {
|
|
380
|
+
console.log(`Reloaded ${this.tools.size} tools from MCP Server`);
|
|
381
|
+
}
|
|
382
|
+
} catch (error) {
|
|
383
|
+
if (session && !session.getIsSdkMode()) {
|
|
384
|
+
console.error(`Failed to reload tools: ${error instanceof Error ? error.message : String(error)}`);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
} else {
|
|
388
|
+
await this.connectStdio();
|
|
327
389
|
}
|
|
328
390
|
}
|
|
329
391
|
|
|
@@ -387,12 +449,12 @@ export class MCPServer {
|
|
|
387
449
|
} else if (resultData?.tools) {
|
|
388
450
|
this.handleToolsList(resultData);
|
|
389
451
|
} else if (resultData?.error) {
|
|
390
|
-
console.error(`\n
|
|
452
|
+
console.error(`\n${icons.error} MCP server returned an error`);
|
|
391
453
|
console.error(` ${resultData.error.message || 'Unknown error'}`);
|
|
392
454
|
}
|
|
393
455
|
} catch (error: any) {
|
|
394
456
|
const serverInfo = this.config.url || this.config.command || 'MCP server';
|
|
395
|
-
console.error(`\n
|
|
457
|
+
console.error(`\n${icons.error} Failed to load MCP tools`);
|
|
396
458
|
console.error(` Server: ${serverInfo}`);
|
|
397
459
|
console.error(` ${error.message}`);
|
|
398
460
|
}
|
|
@@ -436,7 +498,8 @@ export class MCPServer {
|
|
|
436
498
|
...this.config.headers
|
|
437
499
|
};
|
|
438
500
|
|
|
439
|
-
if
|
|
501
|
+
// Only add Authorization if not already present in headers
|
|
502
|
+
if (this.config.authToken && !headers['Authorization']) {
|
|
440
503
|
if (this.config.authToken.startsWith('Bearer ')) {
|
|
441
504
|
headers['Authorization'] = this.config.authToken;
|
|
442
505
|
} else {
|
|
@@ -482,26 +545,26 @@ export class MCPServer {
|
|
|
482
545
|
resultData = parsed;
|
|
483
546
|
break;
|
|
484
547
|
}
|
|
485
|
-
} catch
|
|
548
|
+
} catch {
|
|
486
549
|
continue;
|
|
487
550
|
}
|
|
488
551
|
}
|
|
489
552
|
}
|
|
490
|
-
|
|
553
|
+
|
|
491
554
|
// Fallback: try to parse the last data block if no matching one found
|
|
492
555
|
if (!resultData) {
|
|
493
556
|
const dataMatch = responseStr.match(/data:({.*})/);
|
|
494
557
|
if (dataMatch) {
|
|
495
558
|
try {
|
|
496
559
|
resultData = JSON.parse(dataMatch[1]);
|
|
497
|
-
} catch
|
|
560
|
+
} catch {
|
|
498
561
|
throw new Error('Failed to parse SSE response');
|
|
499
562
|
}
|
|
500
563
|
} else if (!resultData) {
|
|
501
564
|
// Try to parse the entire response as JSON
|
|
502
565
|
try {
|
|
503
566
|
resultData = JSON.parse(responseStr);
|
|
504
|
-
} catch
|
|
567
|
+
} catch {
|
|
505
568
|
throw new Error('No valid data field found in SSE response');
|
|
506
569
|
}
|
|
507
570
|
}
|
|
@@ -728,3 +791,4 @@ export function getMCPManager(): MCPManager {
|
|
|
728
791
|
}
|
|
729
792
|
return mcpManagerInstance;
|
|
730
793
|
}
|
|
794
|
+
|
package/src/memory.ts
CHANGED
|
@@ -2,7 +2,6 @@ import fs from 'fs/promises';
|
|
|
2
2
|
import fsSync from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import os from 'os';
|
|
5
|
-
import { glob } from 'glob';
|
|
6
5
|
import crypto from 'crypto';
|
|
7
6
|
|
|
8
7
|
export interface MemoryFile {
|
|
@@ -35,7 +34,7 @@ export class MemoryManager {
|
|
|
35
34
|
|
|
36
35
|
private getProjectMemoryPath(projectRoot: string): string {
|
|
37
36
|
const hash = crypto.createHash('md5').update(projectRoot).digest('hex').substring(0, 16);
|
|
38
|
-
const sanitizedName = projectRoot.replace(/[
|
|
37
|
+
const sanitizedName = projectRoot.replace(/[:/\\]/g, '_').replace(/[^a-zA-Z0-9_-]/g, '');
|
|
39
38
|
const name = sanitizedName.length > 50 ? sanitizedName.substring(0, 50) : sanitizedName;
|
|
40
39
|
return path.join(this.memoriesDir, `project_${name}_${hash}.md`);
|
|
41
40
|
}
|
|
@@ -149,7 +148,7 @@ export class MemoryManager {
|
|
|
149
148
|
}
|
|
150
149
|
};
|
|
151
150
|
|
|
152
|
-
|
|
151
|
+
const maxIterations = 10;
|
|
153
152
|
let iterations = 0;
|
|
154
153
|
|
|
155
154
|
while (importRegex.test(processedContent) && iterations < maxIterations) {
|
|
@@ -298,7 +297,7 @@ export class MemoryManager {
|
|
|
298
297
|
try {
|
|
299
298
|
const content = await fs.readFile(filePath, 'utf-8');
|
|
300
299
|
return JSON.parse(content);
|
|
301
|
-
} catch
|
|
300
|
+
} catch {
|
|
302
301
|
return null;
|
|
303
302
|
}
|
|
304
303
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified Output Utility
|
|
3
|
+
*
|
|
4
|
+
* Provides a centralized output function that automatically chooses between
|
|
5
|
+
* SDK adapter (JSON output) and console output based on the current mode.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type OutputType = 'info' | 'error' | 'success' | 'warning';
|
|
9
|
+
|
|
10
|
+
let _sdkAdapter: any = null;
|
|
11
|
+
let _isSdkMode: boolean = false;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Initialize SDK mode (call this when session is available)
|
|
15
|
+
*/
|
|
16
|
+
export function initOutputMode(isSdkMode: boolean, adapter?: any): void {
|
|
17
|
+
_isSdkMode = isSdkMode;
|
|
18
|
+
_sdkAdapter = adapter;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get current SDK mode status
|
|
23
|
+
*/
|
|
24
|
+
export function isSdkMode(): boolean {
|
|
25
|
+
return _isSdkMode;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get current SDK adapter
|
|
30
|
+
*/
|
|
31
|
+
export function getSdkAdapter(): any {
|
|
32
|
+
return _sdkAdapter;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Unified output function that automatically chooses SDK or console
|
|
37
|
+
* @param type - Output type (info, error, success, warning)
|
|
38
|
+
* @param message - Message to output
|
|
39
|
+
* @param context - Optional context data (for error type)
|
|
40
|
+
*/
|
|
41
|
+
export async function output(type: OutputType, message: string, context?: Record<string, any>): Promise<void> {
|
|
42
|
+
// Try to use SDK adapter if available and in SDK mode
|
|
43
|
+
if (_isSdkMode && _sdkAdapter) {
|
|
44
|
+
try {
|
|
45
|
+
switch (type) {
|
|
46
|
+
case 'info':
|
|
47
|
+
_sdkAdapter.outputInfo(message);
|
|
48
|
+
break;
|
|
49
|
+
case 'error':
|
|
50
|
+
_sdkAdapter.outputError(message, context);
|
|
51
|
+
break;
|
|
52
|
+
case 'warning':
|
|
53
|
+
_sdkAdapter.outputWarning(message);
|
|
54
|
+
break;
|
|
55
|
+
case 'success':
|
|
56
|
+
_sdkAdapter.outputSuccess(message);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
return; // SDK output successful, don't use console
|
|
60
|
+
} catch {
|
|
61
|
+
// Fall through to console on error
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Console output
|
|
66
|
+
switch (type) {
|
|
67
|
+
case 'info':
|
|
68
|
+
console.log(message);
|
|
69
|
+
break;
|
|
70
|
+
case 'error':
|
|
71
|
+
console.error(message, context?.error || '');
|
|
72
|
+
break;
|
|
73
|
+
case 'warning':
|
|
74
|
+
console.warn(message);
|
|
75
|
+
break;
|
|
76
|
+
case 'success':
|
|
77
|
+
console.log(message);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
package/src/retry.ts
CHANGED
|
@@ -132,7 +132,7 @@ export async function withRetry<T>(
|
|
|
132
132
|
let lastError: Error | undefined;
|
|
133
133
|
|
|
134
134
|
for (let attempt = 0; attempt <= mergedConfig.maxRetries; attempt++) {
|
|
135
|
-
const
|
|
135
|
+
const _attemptStartTime = Date.now();
|
|
136
136
|
|
|
137
137
|
try {
|
|
138
138
|
const data = await fn();
|
package/src/ripgrep.ts
CHANGED
|
@@ -96,7 +96,7 @@ function execCommand(cmd: string, args: string[]): Promise<CmdResult> {
|
|
|
96
96
|
resolve({ stdout, stderr, exitCode: code });
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
child.on('error', (
|
|
99
|
+
child.on('error', (_error) => {
|
|
100
100
|
resolve({ stdout, stderr, exitCode: null });
|
|
101
101
|
});
|
|
102
102
|
});
|
|
@@ -106,7 +106,7 @@ function execCommand(cmd: string, args: string[]): Promise<CmdResult> {
|
|
|
106
106
|
* Download file from URL
|
|
107
107
|
*/
|
|
108
108
|
async function downloadFile(url: string, dest: string): Promise<void> {
|
|
109
|
-
const { exec } = await import('child_process');
|
|
109
|
+
const { exec: _exec } = await import('child_process');
|
|
110
110
|
const { finished } = await import('stream/promises');
|
|
111
111
|
const { Readable } = await import('stream');
|
|
112
112
|
|
|
@@ -232,7 +232,9 @@ async function downloadTool(config: RgConfig | FdConfig, version: string): Promi
|
|
|
232
232
|
try {
|
|
233
233
|
if (existsSync(archivePath)) unlinkSync(archivePath);
|
|
234
234
|
if (existsSync(extractDir)) rmSync(extractDir, { recursive: true });
|
|
235
|
-
} catch {
|
|
235
|
+
} catch {
|
|
236
|
+
// Ignore cleanup errors
|
|
237
|
+
}
|
|
236
238
|
}
|
|
237
239
|
}
|
|
238
240
|
|