@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.
Files changed (190) hide show
  1. package/.github/release.yml +76 -0
  2. package/.github/workflows/ci.yml +3 -0
  3. package/.github/workflows/release.yml +11 -17
  4. package/README.md +2 -2
  5. package/README_CN.md +2 -2
  6. package/dist/agents.d.ts.map +1 -1
  7. package/dist/agents.js +7 -3
  8. package/dist/agents.js.map +1 -1
  9. package/dist/ai-client/factory.d.ts +0 -12
  10. package/dist/ai-client/factory.d.ts.map +1 -1
  11. package/dist/ai-client/factory.js +0 -32
  12. package/dist/ai-client/factory.js.map +1 -1
  13. package/dist/ai-client/index.js +1 -1
  14. package/dist/ai-client/index.js.map +1 -1
  15. package/dist/ai-client/providers/anthropic.d.ts.map +1 -1
  16. package/dist/ai-client/providers/anthropic.js +10 -4
  17. package/dist/ai-client/providers/anthropic.js.map +1 -1
  18. package/dist/ai-client/providers/openai.d.ts.map +1 -1
  19. package/dist/ai-client/providers/openai.js +8 -4
  20. package/dist/ai-client/providers/openai.js.map +1 -1
  21. package/dist/ai-client/providers/remote.d.ts +0 -1
  22. package/dist/ai-client/providers/remote.d.ts.map +1 -1
  23. package/dist/ai-client/providers/remote.js +11 -10
  24. package/dist/ai-client/providers/remote.js.map +1 -1
  25. package/dist/ai-client/types.d.ts +14 -0
  26. package/dist/ai-client/types.d.ts.map +1 -1
  27. package/dist/ai-client/types.js +17 -0
  28. package/dist/ai-client/types.js.map +1 -1
  29. package/dist/ai-client-factory.d.ts.map +1 -1
  30. package/dist/ai-client-factory.js +4 -4
  31. package/dist/ai-client-factory.js.map +1 -1
  32. package/dist/auth.d.ts.map +1 -1
  33. package/dist/auth.js +10 -12
  34. package/dist/auth.js.map +1 -1
  35. package/dist/cancellation.d.ts.map +1 -1
  36. package/dist/cancellation.js +3 -5
  37. package/dist/cancellation.js.map +1 -1
  38. package/dist/checkpoint.d.ts +1 -0
  39. package/dist/checkpoint.d.ts.map +1 -1
  40. package/dist/checkpoint.js +38 -4
  41. package/dist/checkpoint.js.map +1 -1
  42. package/dist/cli.js +132 -32
  43. package/dist/cli.js.map +1 -1
  44. package/dist/config.js +1 -1
  45. package/dist/config.js.map +1 -1
  46. package/dist/context-compressor.d.ts +1 -2
  47. package/dist/context-compressor.d.ts.map +1 -1
  48. package/dist/context-compressor.js +22 -17
  49. package/dist/context-compressor.js.map +1 -1
  50. package/dist/conversation.d.ts +1 -1
  51. package/dist/conversation.d.ts.map +1 -1
  52. package/dist/conversation.js +8 -7
  53. package/dist/conversation.js.map +1 -1
  54. package/dist/gui-subagent/action-parser/actionParser.js +2 -2
  55. package/dist/gui-subagent/action-parser/actionParser.js.map +1 -1
  56. package/dist/gui-subagent/agent/gui-agent.d.ts +10 -0
  57. package/dist/gui-subagent/agent/gui-agent.d.ts.map +1 -1
  58. package/dist/gui-subagent/agent/gui-agent.js +105 -32
  59. package/dist/gui-subagent/agent/gui-agent.js.map +1 -1
  60. package/dist/gui-subagent/index.d.ts +7 -0
  61. package/dist/gui-subagent/index.d.ts.map +1 -1
  62. package/dist/gui-subagent/index.js +2 -0
  63. package/dist/gui-subagent/index.js.map +1 -1
  64. package/dist/gui-subagent/operator/computer-operator.d.ts.map +1 -1
  65. package/dist/gui-subagent/operator/computer-operator.js +2 -0
  66. package/dist/gui-subagent/operator/computer-operator.js.map +1 -1
  67. package/dist/input-processor.js +2 -2
  68. package/dist/input-processor.js.map +1 -1
  69. package/dist/logger.d.ts.map +1 -1
  70. package/dist/logger.js +1 -1
  71. package/dist/logger.js.map +1 -1
  72. package/dist/mcp.d.ts +2 -1
  73. package/dist/mcp.d.ts.map +1 -1
  74. package/dist/mcp.js +84 -21
  75. package/dist/mcp.js.map +1 -1
  76. package/dist/memory.d.ts.map +1 -1
  77. package/dist/memory.js +3 -3
  78. package/dist/memory.js.map +1 -1
  79. package/dist/output-util.d.ts +27 -0
  80. package/dist/output-util.d.ts.map +1 -0
  81. package/dist/output-util.js +74 -0
  82. package/dist/output-util.js.map +1 -0
  83. package/dist/retry.js +1 -1
  84. package/dist/retry.js.map +1 -1
  85. package/dist/ripgrep.d.ts.map +1 -1
  86. package/dist/ripgrep.js +5 -3
  87. package/dist/ripgrep.js.map +1 -1
  88. package/dist/sdk-output-adapter.d.ts +265 -0
  89. package/dist/sdk-output-adapter.d.ts.map +1 -0
  90. package/dist/sdk-output-adapter.js +701 -0
  91. package/dist/sdk-output-adapter.js.map +1 -0
  92. package/dist/sdk-session.d.ts +13 -0
  93. package/dist/sdk-session.d.ts.map +1 -0
  94. package/dist/sdk-session.js +50 -0
  95. package/dist/sdk-session.js.map +1 -0
  96. package/dist/session-manager.js +3 -3
  97. package/dist/session-manager.js.map +1 -1
  98. package/dist/session.d.ts +96 -2
  99. package/dist/session.d.ts.map +1 -1
  100. package/dist/session.js +849 -262
  101. package/dist/session.js.map +1 -1
  102. package/dist/shell.d.ts.map +1 -1
  103. package/dist/shell.js +5 -4
  104. package/dist/shell.js.map +1 -1
  105. package/dist/skill-installer.js +3 -3
  106. package/dist/skill-installer.js.map +1 -1
  107. package/dist/skill-invoker.d.ts +1 -1
  108. package/dist/skill-invoker.d.ts.map +1 -1
  109. package/dist/skill-invoker.js +2 -2
  110. package/dist/skill-invoker.js.map +1 -1
  111. package/dist/skill-loader.js +6 -5
  112. package/dist/skill-loader.js.map +1 -1
  113. package/dist/skill-manager.d.ts.map +1 -1
  114. package/dist/skill-manager.js +3 -2
  115. package/dist/skill-manager.js.map +1 -1
  116. package/dist/slash-commands.d.ts +1 -1
  117. package/dist/slash-commands.d.ts.map +1 -1
  118. package/dist/slash-commands.js +24 -11
  119. package/dist/slash-commands.js.map +1 -1
  120. package/dist/smart-approval.d.ts +20 -1
  121. package/dist/smart-approval.d.ts.map +1 -1
  122. package/dist/smart-approval.js +58 -1
  123. package/dist/smart-approval.js.map +1 -1
  124. package/dist/system-prompt-generator.js +3 -3
  125. package/dist/system-prompt-generator.js.map +1 -1
  126. package/dist/theme.d.ts.map +1 -1
  127. package/dist/theme.js +9 -8
  128. package/dist/theme.js.map +1 -1
  129. package/dist/tools.d.ts +15 -0
  130. package/dist/tools.d.ts.map +1 -1
  131. package/dist/tools.js +487 -215
  132. package/dist/tools.js.map +1 -1
  133. package/dist/types.d.ts +57 -0
  134. package/dist/types.d.ts.map +1 -1
  135. package/dist/types.js +49 -0
  136. package/dist/types.js.map +1 -1
  137. package/dist/update.d.ts.map +1 -1
  138. package/dist/update.js +12 -9
  139. package/dist/update.js.map +1 -1
  140. package/dist/workflow.d.ts.map +1 -1
  141. package/dist/workflow.js +1 -2
  142. package/dist/workflow.js.map +1 -1
  143. package/docs/third-party-models.md +16 -15
  144. package/package.json +3 -1
  145. package/src/agents.ts +7 -3
  146. package/src/ai-client/factory.ts +1 -36
  147. package/src/ai-client/index.ts +1 -1
  148. package/src/ai-client/providers/anthropic.ts +12 -3
  149. package/src/ai-client/providers/openai.ts +10 -4
  150. package/src/ai-client/providers/remote.ts +13 -10
  151. package/src/ai-client/types.ts +19 -0
  152. package/src/ai-client-factory.ts +5 -5
  153. package/src/auth.ts +11 -13
  154. package/src/cancellation.ts +3 -6
  155. package/src/checkpoint.ts +41 -4
  156. package/src/cli.ts +154 -37
  157. package/src/config.ts +1 -1
  158. package/src/context-compressor.ts +27 -22
  159. package/src/conversation.ts +9 -7
  160. package/src/gui-subagent/action-parser/actionParser.ts +2 -2
  161. package/src/gui-subagent/agent/gui-agent.ts +117 -34
  162. package/src/gui-subagent/index.ts +8 -0
  163. package/src/gui-subagent/operator/computer-operator.ts +2 -1
  164. package/src/input-processor.ts +2 -2
  165. package/src/logger.ts +2 -4
  166. package/src/mcp.ts +87 -23
  167. package/src/memory.ts +3 -4
  168. package/src/output-util.ts +80 -0
  169. package/src/retry.ts +1 -1
  170. package/src/ripgrep.ts +5 -3
  171. package/src/sdk-output-adapter.ts +842 -0
  172. package/src/sdk-session.ts +62 -0
  173. package/src/session-manager.ts +3 -3
  174. package/src/session.ts +942 -302
  175. package/src/shell.ts +6 -5
  176. package/src/skill-installer.ts +3 -3
  177. package/src/skill-invoker.ts +3 -4
  178. package/src/skill-loader.ts +7 -7
  179. package/src/skill-manager.ts +4 -3
  180. package/src/slash-commands.ts +24 -16
  181. package/src/smart-approval.ts +76 -1
  182. package/src/system-prompt-generator.ts +3 -3
  183. package/src/theme.ts +10 -9
  184. package/src/tools.ts +563 -267
  185. package/src/types.ts +118 -0
  186. package/src/update.ts +12 -9
  187. package/src/workflow.ts +2 -4
  188. package/test/cli-launch.test.ts +279 -0
  189. package/vitest.config.ts +2 -0
  190. /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: any;
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
- console.log(`✅ MCP Server connected`);
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
- console.error(`❌ [mcp] Failed to connect MCP Server: ${error instanceof Error ? error.message : String(error)}`);
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, reject) => {
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
- console.warn(`[MCP] Timeout waiting for tools (${timeoutMs}ms), proceeding anyway`);
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 intervalId = setInterval(check, checkInterval);
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
- console.error('MCP Server error:', error);
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
- console.log(`MCP Server exited with code ${code}, signal ${signal}`);
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
- console.error('MCP Server stderr:', data.toString());
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
- console.log(`Connecting to MCP Server at ${this.config.url} (${transportType})`);
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 (this.config.authToken) {
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
- console.error(`HTTP connection failed: ${error.message}`);
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 (e) {
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 SSE connection timed out`);
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 SSE connection failed`);
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
- console.log(`Loaded ${result.tools.length} tools from MCP Server`);
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 MCP server returned an error`);
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 Failed to load MCP tools`);
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 (this.config.authToken) {
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 (e) {
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 (e) {
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 (e) {
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(/[:\\\/]/g, '_').replace(/[^a-zA-Z0-9_\-]/g, '');
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
- let maxIterations = 10;
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 (error) {
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 attemptStartTime = Date.now();
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', (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