@xagent-ai/cli 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.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 +37 -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 +23 -18
- 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 +83 -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 +8 -7
- 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 +40 -4
- package/src/cli.ts +154 -37
- package/src/config.ts +1 -1
- package/src/context-compressor.ts +28 -23
- 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 +86 -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 +9 -8
- 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,12 @@
|
|
|
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';
|
|
3
5
|
|
|
4
6
|
export interface MCPTool {
|
|
5
7
|
name: string;
|
|
6
8
|
description: string;
|
|
7
|
-
inputSchema:
|
|
9
|
+
inputSchema: Record<string, unknown>;
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
export class MCPServer {
|
|
@@ -44,9 +46,14 @@ export class MCPServer {
|
|
|
44
46
|
await this.waitForTools(10000);
|
|
45
47
|
|
|
46
48
|
this.isConnected = true;
|
|
47
|
-
|
|
49
|
+
const session = getSingletonSession();
|
|
50
|
+
if (session?.getIsSdkMode()) {
|
|
51
|
+
// SDK 模式下不输出
|
|
52
|
+
} else {
|
|
53
|
+
await logOutput('success', `�?MCP Server connected`);
|
|
54
|
+
}
|
|
48
55
|
} catch (error) {
|
|
49
|
-
|
|
56
|
+
await logOutput('error', `�?[mcp] Failed to connect MCP Server`, { error: error instanceof Error ? error.message : String(error) });
|
|
50
57
|
throw error;
|
|
51
58
|
}
|
|
52
59
|
}
|
|
@@ -60,7 +67,7 @@ export class MCPServer {
|
|
|
60
67
|
return; // Tools already loaded
|
|
61
68
|
}
|
|
62
69
|
|
|
63
|
-
return new Promise((resolve,
|
|
70
|
+
return new Promise((resolve, _reject) => {
|
|
64
71
|
const checkInterval = 100;
|
|
65
72
|
const startTime = Date.now();
|
|
66
73
|
|
|
@@ -70,14 +77,14 @@ export class MCPServer {
|
|
|
70
77
|
resolve();
|
|
71
78
|
} else if (Date.now() - startTime > timeoutMs) {
|
|
72
79
|
clearInterval(checkInterval);
|
|
73
|
-
|
|
80
|
+
logOutput('warning', `[MCP] Timeout waiting for tools (${timeoutMs}ms), proceeding anyway`);
|
|
74
81
|
resolve(); // Don't reject, just proceed without tools
|
|
75
82
|
} else {
|
|
76
83
|
// Continue checking
|
|
77
84
|
}
|
|
78
85
|
};
|
|
79
86
|
|
|
80
|
-
const
|
|
87
|
+
const _intervalId = setInterval(check, checkInterval);
|
|
81
88
|
check(); // Check immediately first
|
|
82
89
|
});
|
|
83
90
|
}
|
|
@@ -96,12 +103,12 @@ export class MCPServer {
|
|
|
96
103
|
});
|
|
97
104
|
|
|
98
105
|
this.process.on('error', (error) => {
|
|
99
|
-
|
|
106
|
+
logOutput('error', 'MCP Server error', { error: error.message });
|
|
100
107
|
reject(error);
|
|
101
108
|
});
|
|
102
109
|
|
|
103
110
|
this.process.on('exit', (code, signal) => {
|
|
104
|
-
|
|
111
|
+
logOutput('info', `MCP Server exited with code ${code}, signal ${signal}`);
|
|
105
112
|
this.isConnected = false;
|
|
106
113
|
});
|
|
107
114
|
|
|
@@ -113,7 +120,7 @@ export class MCPServer {
|
|
|
113
120
|
|
|
114
121
|
if (this.process.stderr) {
|
|
115
122
|
this.process.stderr.on('data', (data) => {
|
|
116
|
-
|
|
123
|
+
logOutput('error', 'MCP Server stderr', { error: data.toString() });
|
|
117
124
|
});
|
|
118
125
|
}
|
|
119
126
|
|
|
@@ -140,7 +147,10 @@ export class MCPServer {
|
|
|
140
147
|
}
|
|
141
148
|
|
|
142
149
|
const transportType = this.getTransportType();
|
|
143
|
-
|
|
150
|
+
const session = getSingletonSession();
|
|
151
|
+
if (!session?.getIsSdkMode()) {
|
|
152
|
+
console.log(`Connecting to MCP Server at ${this.config.url} (${transportType})`);
|
|
153
|
+
}
|
|
144
154
|
|
|
145
155
|
// Build headers with auth token
|
|
146
156
|
const headers: Record<string, string> = {
|
|
@@ -149,7 +159,8 @@ export class MCPServer {
|
|
|
149
159
|
...this.config.headers
|
|
150
160
|
};
|
|
151
161
|
|
|
152
|
-
if
|
|
162
|
+
// Only add Authorization if not already present in headers
|
|
163
|
+
if (this.config.authToken && !headers['Authorization']) {
|
|
153
164
|
if (this.config.authToken.startsWith('Bearer ')) {
|
|
154
165
|
headers['Authorization'] = this.config.authToken;
|
|
155
166
|
} else {
|
|
@@ -191,7 +202,8 @@ export class MCPServer {
|
|
|
191
202
|
// which handles both regular JSON and SSE format responses
|
|
192
203
|
await this.loadTools(headers);
|
|
193
204
|
} catch (error: any) {
|
|
194
|
-
|
|
205
|
+
const errorMsg = `HTTP connection failed: ${error.message}`;
|
|
206
|
+
await logOutput('error', errorMsg, { error: error.message });
|
|
195
207
|
if (error.response) {
|
|
196
208
|
console.error(`Response status: ${error.response.status}`);
|
|
197
209
|
if (error.response.data?.message) {
|
|
@@ -247,6 +259,7 @@ export class MCPServer {
|
|
|
247
259
|
const decoder = new TextDecoder();
|
|
248
260
|
let buffer = '';
|
|
249
261
|
|
|
262
|
+
// eslint-disable-next-line no-constant-condition
|
|
250
263
|
while (true) {
|
|
251
264
|
const { done, value } = await reader.read();
|
|
252
265
|
if (done) break;
|
|
@@ -260,7 +273,7 @@ export class MCPServer {
|
|
|
260
273
|
try {
|
|
261
274
|
const data = JSON.parse(line.slice(6));
|
|
262
275
|
this.handleJsonRpcMessage(data);
|
|
263
|
-
} catch
|
|
276
|
+
} catch {
|
|
264
277
|
// Ignore parse errors
|
|
265
278
|
}
|
|
266
279
|
}
|
|
@@ -271,11 +284,11 @@ export class MCPServer {
|
|
|
271
284
|
clearTimeout(timeoutId);
|
|
272
285
|
const serverInfo = this.config.url || this.config.command || 'MCP server';
|
|
273
286
|
if (error.name === 'AbortError') {
|
|
274
|
-
console.error(`\n
|
|
287
|
+
console.error(`\n�?SSE connection timed out`);
|
|
275
288
|
console.error(` Server: ${serverInfo}`);
|
|
276
289
|
console.error(` The server is not responding. Please try again later.`);
|
|
277
290
|
} else {
|
|
278
|
-
console.error(`\n
|
|
291
|
+
console.error(`\n�?SSE connection failed`);
|
|
279
292
|
console.error(` Server: ${serverInfo}`);
|
|
280
293
|
console.error(` ${error.message}`);
|
|
281
294
|
}
|
|
@@ -308,6 +321,8 @@ export class MCPServer {
|
|
|
308
321
|
this.handleToolsList(message.params);
|
|
309
322
|
} else if (message.method === 'notifications/initialized') {
|
|
310
323
|
console.log('MCP Server initialized');
|
|
324
|
+
} else if (message.method === 'notifications/tools_changed' || message.method === 'tools/list_changed') {
|
|
325
|
+
this.handleToolsChanged();
|
|
311
326
|
}
|
|
312
327
|
}
|
|
313
328
|
|
|
@@ -323,7 +338,53 @@ export class MCPServer {
|
|
|
323
338
|
if (!tool.name || typeof tool.name !== 'string' || tool.name.trim() === '') continue;
|
|
324
339
|
this.tools.set(tool.name, tool);
|
|
325
340
|
}
|
|
326
|
-
|
|
341
|
+
const session = getSingletonSession();
|
|
342
|
+
if (session?.getIsSdkMode()) {
|
|
343
|
+
// SDK 模式下不输出
|
|
344
|
+
} else {
|
|
345
|
+
console.log(`Loaded ${result.tools.length} tools from MCP Server`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
private async handleToolsChanged(): Promise<void> {
|
|
351
|
+
const session = getSingletonSession();
|
|
352
|
+
if (session && !session.getIsSdkMode()) {
|
|
353
|
+
console.log(`MCP Server tools changed, reloading...`);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const transportType = this.getTransportType();
|
|
357
|
+
if (transportType === 'http' || transportType === 'sse') {
|
|
358
|
+
try {
|
|
359
|
+
const headers: Record<string, string> = {
|
|
360
|
+
'Content-Type': 'application/json',
|
|
361
|
+
...this.config.headers
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
if (this.config.authToken && !headers['Authorization']) {
|
|
365
|
+
if (this.config.authToken.startsWith('Bearer ')) {
|
|
366
|
+
headers['Authorization'] = this.config.authToken;
|
|
367
|
+
} else {
|
|
368
|
+
headers['Authorization'] = `Bearer ${this.config.authToken}`;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (this.sessionId) {
|
|
373
|
+
headers['MCP-session-id'] = this.sessionId;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
await this.loadTools(headers);
|
|
377
|
+
|
|
378
|
+
if (session && !session.getIsSdkMode()) {
|
|
379
|
+
console.log(`Reloaded ${this.tools.size} tools from MCP Server`);
|
|
380
|
+
}
|
|
381
|
+
} catch (error) {
|
|
382
|
+
if (session && !session.getIsSdkMode()) {
|
|
383
|
+
console.error(`Failed to reload tools: ${error instanceof Error ? error.message : String(error)}`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
} else {
|
|
387
|
+
await this.connectStdio();
|
|
327
388
|
}
|
|
328
389
|
}
|
|
329
390
|
|
|
@@ -387,12 +448,12 @@ export class MCPServer {
|
|
|
387
448
|
} else if (resultData?.tools) {
|
|
388
449
|
this.handleToolsList(resultData);
|
|
389
450
|
} else if (resultData?.error) {
|
|
390
|
-
console.error(`\n
|
|
451
|
+
console.error(`\n�?MCP server returned an error`);
|
|
391
452
|
console.error(` ${resultData.error.message || 'Unknown error'}`);
|
|
392
453
|
}
|
|
393
454
|
} catch (error: any) {
|
|
394
455
|
const serverInfo = this.config.url || this.config.command || 'MCP server';
|
|
395
|
-
console.error(`\n
|
|
456
|
+
console.error(`\n�?Failed to load MCP tools`);
|
|
396
457
|
console.error(` Server: ${serverInfo}`);
|
|
397
458
|
console.error(` ${error.message}`);
|
|
398
459
|
}
|
|
@@ -436,7 +497,8 @@ export class MCPServer {
|
|
|
436
497
|
...this.config.headers
|
|
437
498
|
};
|
|
438
499
|
|
|
439
|
-
if
|
|
500
|
+
// Only add Authorization if not already present in headers
|
|
501
|
+
if (this.config.authToken && !headers['Authorization']) {
|
|
440
502
|
if (this.config.authToken.startsWith('Bearer ')) {
|
|
441
503
|
headers['Authorization'] = this.config.authToken;
|
|
442
504
|
} else {
|
|
@@ -482,26 +544,26 @@ export class MCPServer {
|
|
|
482
544
|
resultData = parsed;
|
|
483
545
|
break;
|
|
484
546
|
}
|
|
485
|
-
} catch
|
|
547
|
+
} catch {
|
|
486
548
|
continue;
|
|
487
549
|
}
|
|
488
550
|
}
|
|
489
551
|
}
|
|
490
|
-
|
|
552
|
+
|
|
491
553
|
// Fallback: try to parse the last data block if no matching one found
|
|
492
554
|
if (!resultData) {
|
|
493
555
|
const dataMatch = responseStr.match(/data:({.*})/);
|
|
494
556
|
if (dataMatch) {
|
|
495
557
|
try {
|
|
496
558
|
resultData = JSON.parse(dataMatch[1]);
|
|
497
|
-
} catch
|
|
559
|
+
} catch {
|
|
498
560
|
throw new Error('Failed to parse SSE response');
|
|
499
561
|
}
|
|
500
562
|
} else if (!resultData) {
|
|
501
563
|
// Try to parse the entire response as JSON
|
|
502
564
|
try {
|
|
503
565
|
resultData = JSON.parse(responseStr);
|
|
504
|
-
} catch
|
|
566
|
+
} catch {
|
|
505
567
|
throw new Error('No valid data field found in SSE response');
|
|
506
568
|
}
|
|
507
569
|
}
|
|
@@ -728,3 +790,4 @@ export function getMCPManager(): MCPManager {
|
|
|
728
790
|
}
|
|
729
791
|
return mcpManagerInstance;
|
|
730
792
|
}
|
|
793
|
+
|
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
|
|