wave-agent-sdk 0.6.4 → 0.7.0

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 (174) hide show
  1. package/dist/agent.d.ts +8 -0
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +49 -240
  4. package/dist/constants/tools.d.ts +0 -2
  5. package/dist/constants/tools.d.ts.map +1 -1
  6. package/dist/constants/tools.js +0 -2
  7. package/dist/core/plugin.d.ts +86 -0
  8. package/dist/core/plugin.d.ts.map +1 -0
  9. package/dist/core/plugin.js +164 -0
  10. package/dist/index.d.ts +1 -4
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +1 -5
  13. package/dist/managers/MemoryRuleManager.d.ts +3 -1
  14. package/dist/managers/MemoryRuleManager.d.ts.map +1 -1
  15. package/dist/managers/MemoryRuleManager.js +2 -1
  16. package/dist/managers/aiManager.d.ts +13 -23
  17. package/dist/managers/aiManager.d.ts.map +1 -1
  18. package/dist/managers/aiManager.js +59 -32
  19. package/dist/managers/backgroundTaskManager.d.ts +3 -1
  20. package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
  21. package/dist/managers/backgroundTaskManager.js +2 -1
  22. package/dist/managers/bashManager.d.ts +4 -4
  23. package/dist/managers/bashManager.d.ts.map +1 -1
  24. package/dist/managers/bashManager.js +5 -2
  25. package/dist/managers/foregroundTaskManager.d.ts +3 -0
  26. package/dist/managers/foregroundTaskManager.d.ts.map +1 -1
  27. package/dist/managers/foregroundTaskManager.js +2 -1
  28. package/dist/managers/hookManager.d.ts +3 -3
  29. package/dist/managers/hookManager.d.ts.map +1 -1
  30. package/dist/managers/hookManager.js +20 -19
  31. package/dist/managers/liveConfigManager.d.ts +6 -13
  32. package/dist/managers/liveConfigManager.d.ts.map +1 -1
  33. package/dist/managers/liveConfigManager.js +50 -45
  34. package/dist/managers/lspManager.d.ts +4 -5
  35. package/dist/managers/lspManager.d.ts.map +1 -1
  36. package/dist/managers/lspManager.js +13 -12
  37. package/dist/managers/mcpManager.d.ts +3 -2
  38. package/dist/managers/mcpManager.d.ts.map +1 -1
  39. package/dist/managers/mcpManager.js +16 -15
  40. package/dist/managers/messageManager.d.ts +5 -7
  41. package/dist/managers/messageManager.d.ts.map +1 -1
  42. package/dist/managers/messageManager.js +12 -7
  43. package/dist/managers/permissionManager.d.ts +6 -4
  44. package/dist/managers/permissionManager.d.ts.map +1 -1
  45. package/dist/managers/permissionManager.js +39 -63
  46. package/dist/managers/planManager.d.ts +4 -6
  47. package/dist/managers/planManager.d.ts.map +1 -1
  48. package/dist/managers/planManager.js +18 -4
  49. package/dist/managers/pluginManager.d.ts +10 -22
  50. package/dist/managers/pluginManager.d.ts.map +1 -1
  51. package/dist/managers/pluginManager.js +27 -14
  52. package/dist/managers/reversionManager.d.ts +4 -3
  53. package/dist/managers/reversionManager.d.ts.map +1 -1
  54. package/dist/managers/reversionManager.js +5 -2
  55. package/dist/managers/skillManager.d.ts +3 -2
  56. package/dist/managers/skillManager.d.ts.map +1 -1
  57. package/dist/managers/skillManager.js +15 -14
  58. package/dist/managers/slashCommandManager.d.ts +9 -16
  59. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  60. package/dist/managers/slashCommandManager.js +21 -10
  61. package/dist/managers/subagentManager.d.ts +7 -17
  62. package/dist/managers/subagentManager.d.ts.map +1 -1
  63. package/dist/managers/subagentManager.js +41 -34
  64. package/dist/managers/toolManager.d.ts +15 -38
  65. package/dist/managers/toolManager.d.ts.map +1 -1
  66. package/dist/managers/toolManager.js +66 -56
  67. package/dist/prompts/index.d.ts +6 -3
  68. package/dist/prompts/index.d.ts.map +1 -1
  69. package/dist/prompts/index.js +8 -16
  70. package/dist/services/MarketplaceService.d.ts.map +1 -1
  71. package/dist/services/MarketplaceService.js +13 -0
  72. package/dist/services/aiService.d.ts +4 -0
  73. package/dist/services/aiService.d.ts.map +1 -1
  74. package/dist/services/aiService.js +47 -7
  75. package/dist/services/configurationService.d.ts.map +1 -1
  76. package/dist/services/configurationService.js +30 -11
  77. package/dist/services/taskManager.d.ts +3 -1
  78. package/dist/services/taskManager.d.ts.map +1 -1
  79. package/dist/services/taskManager.js +2 -1
  80. package/dist/tools/bashTool.js +2 -2
  81. package/dist/tools/editTool.d.ts.map +1 -1
  82. package/dist/tools/editTool.js +9 -1
  83. package/dist/tools/readTool.d.ts.map +1 -1
  84. package/dist/tools/readTool.js +2 -2
  85. package/dist/tools/skillTool.d.ts +2 -4
  86. package/dist/tools/skillTool.d.ts.map +1 -1
  87. package/dist/tools/skillTool.js +61 -61
  88. package/dist/tools/taskOutputTool.js +1 -1
  89. package/dist/tools/taskTool.d.ts +2 -4
  90. package/dist/tools/taskTool.d.ts.map +1 -1
  91. package/dist/tools/taskTool.js +192 -187
  92. package/dist/tools/types.d.ts +11 -1
  93. package/dist/tools/types.d.ts.map +1 -1
  94. package/dist/tools/writeTool.d.ts.map +1 -1
  95. package/dist/tools/writeTool.js +4 -2
  96. package/dist/types/marketplace.d.ts +8 -0
  97. package/dist/types/marketplace.d.ts.map +1 -1
  98. package/dist/types/permissions.d.ts +1 -1
  99. package/dist/types/permissions.d.ts.map +1 -1
  100. package/dist/types/permissions.js +1 -3
  101. package/dist/types/skills.d.ts +0 -2
  102. package/dist/types/skills.d.ts.map +1 -1
  103. package/dist/types/tools.d.ts +0 -15
  104. package/dist/types/tools.d.ts.map +1 -1
  105. package/dist/utils/container.d.ts +31 -0
  106. package/dist/utils/container.d.ts.map +1 -0
  107. package/dist/utils/container.js +79 -0
  108. package/dist/utils/containerSetup.d.ts +26 -0
  109. package/dist/utils/containerSetup.d.ts.map +1 -0
  110. package/dist/utils/containerSetup.js +165 -0
  111. package/dist/utils/editUtils.d.ts +0 -3
  112. package/dist/utils/editUtils.d.ts.map +1 -1
  113. package/dist/utils/editUtils.js +4 -3
  114. package/dist/utils/hookMatcher.d.ts +1 -1
  115. package/dist/utils/hookMatcher.d.ts.map +1 -1
  116. package/dist/utils/hookMatcher.js +2 -2
  117. package/dist/utils/openaiClient.js +2 -2
  118. package/dist/utils/stringUtils.d.ts +6 -0
  119. package/dist/utils/stringUtils.d.ts.map +1 -1
  120. package/dist/utils/stringUtils.js +8 -0
  121. package/package.json +1 -1
  122. package/src/agent.ts +60 -282
  123. package/src/constants/tools.ts +0 -2
  124. package/src/core/plugin.ts +224 -0
  125. package/src/index.ts +1 -6
  126. package/src/managers/MemoryRuleManager.ts +6 -1
  127. package/src/managers/aiManager.ts +83 -58
  128. package/src/managers/backgroundTaskManager.ts +5 -1
  129. package/src/managers/bashManager.ts +9 -4
  130. package/src/managers/foregroundTaskManager.ts +3 -0
  131. package/src/managers/hookManager.ts +21 -23
  132. package/src/managers/liveConfigManager.ts +57 -53
  133. package/src/managers/lspManager.ts +14 -19
  134. package/src/managers/mcpManager.ts +20 -20
  135. package/src/managers/messageManager.ts +19 -12
  136. package/src/managers/permissionManager.ts +45 -70
  137. package/src/managers/planManager.ts +26 -7
  138. package/src/managers/pluginManager.ts +37 -33
  139. package/src/managers/reversionManager.ts +5 -3
  140. package/src/managers/skillManager.ts +19 -20
  141. package/src/managers/slashCommandManager.ts +30 -25
  142. package/src/managers/subagentManager.ts +53 -53
  143. package/src/managers/toolManager.ts +91 -90
  144. package/src/prompts/index.ts +12 -24
  145. package/src/services/MarketplaceService.ts +13 -0
  146. package/src/services/aiService.ts +61 -15
  147. package/src/services/configurationService.ts +34 -13
  148. package/src/services/taskManager.ts +5 -1
  149. package/src/tools/bashTool.ts +2 -2
  150. package/src/tools/editTool.ts +9 -1
  151. package/src/tools/readTool.ts +2 -2
  152. package/src/tools/skillTool.ts +75 -71
  153. package/src/tools/taskOutputTool.ts +1 -1
  154. package/src/tools/taskTool.ts +224 -225
  155. package/src/tools/types.ts +12 -1
  156. package/src/tools/writeTool.ts +4 -2
  157. package/src/types/marketplace.ts +9 -0
  158. package/src/types/permissions.ts +0 -4
  159. package/src/types/skills.ts +0 -3
  160. package/src/types/tools.ts +0 -17
  161. package/src/utils/container.ts +92 -0
  162. package/src/utils/containerSetup.ts +256 -0
  163. package/src/utils/editUtils.ts +4 -3
  164. package/src/utils/hookMatcher.ts +2 -2
  165. package/src/utils/openaiClient.ts +2 -2
  166. package/src/utils/stringUtils.ts +9 -0
  167. package/dist/tools/deleteFileTool.d.ts +0 -6
  168. package/dist/tools/deleteFileTool.d.ts.map +0 -1
  169. package/dist/tools/deleteFileTool.js +0 -100
  170. package/dist/tools/multiEditTool.d.ts +0 -6
  171. package/dist/tools/multiEditTool.d.ts.map +0 -1
  172. package/dist/tools/multiEditTool.js +0 -246
  173. package/src/tools/deleteFileTool.ts +0 -127
  174. package/src/tools/multiEditTool.ts +0 -306
@@ -8,7 +8,6 @@
8
8
  */
9
9
 
10
10
  import { existsSync } from "fs";
11
- import type { Logger } from "../types/index.js";
12
11
  import type { PermissionMode } from "../types/permissions.js";
13
12
  import type { Scope } from "../types/configuration.js";
14
13
  import {
@@ -25,27 +24,22 @@ import type { HookValidationResult } from "../types/hooks.js";
25
24
  import { isValidHookEvent, isValidHookEventConfig } from "../types/hooks.js";
26
25
  import { ConfigurationService } from "../services/configurationService.js";
27
26
  import { ensureGlobalGitIgnore } from "../utils/fileUtils.js";
27
+ import { Container } from "../utils/container.js";
28
28
 
29
29
  import type {
30
30
  ConfigurationLoadResult,
31
31
  WaveConfiguration,
32
32
  } from "../types/configuration.js";
33
33
 
34
+ import { logger } from "../utils/globalLogger.js";
35
+
34
36
  export interface LiveConfigManagerOptions {
35
37
  workdir: string;
36
- logger?: Logger;
37
- hookManager?: HookManager;
38
- permissionManager?: PermissionManager;
39
- configurationService?: ConfigurationService;
40
38
  }
41
39
 
42
40
  export class LiveConfigManager {
43
41
  private readonly workdir: string;
44
- private readonly logger?: Logger;
45
- private readonly hookManager?: HookManager;
46
- private readonly permissionManager?: PermissionManager;
47
42
  private isInitialized: boolean = false;
48
- private readonly configurationService: ConfigurationService;
49
43
 
50
44
  // Configuration state
51
45
  private currentConfiguration: WaveConfiguration | null = null;
@@ -58,17 +52,27 @@ export class LiveConfigManager {
58
52
  private isWatching: boolean = false;
59
53
  private reloadInProgress: boolean = false;
60
54
 
61
- constructor(options: LiveConfigManagerOptions) {
55
+ constructor(
56
+ private container: Container,
57
+ options: LiveConfigManagerOptions,
58
+ ) {
62
59
  this.workdir = options.workdir;
63
- this.logger = options.logger;
64
- this.hookManager = options.hookManager;
65
- this.permissionManager = options.permissionManager;
66
- this.configurationService =
67
- options.configurationService || new ConfigurationService();
68
- this.fileWatcher = new FileWatcherService(this.logger);
60
+ this.fileWatcher = new FileWatcherService(logger);
69
61
  this.setupFileWatcherEvents();
70
62
  }
71
63
 
64
+ private get hookManager(): HookManager | undefined {
65
+ return this.container.get<HookManager>("HookManager");
66
+ }
67
+
68
+ private get permissionManager(): PermissionManager | undefined {
69
+ return this.container.get<PermissionManager>("PermissionManager");
70
+ }
71
+
72
+ private get configurationService(): ConfigurationService {
73
+ return this.container.get<ConfigurationService>("ConfigurationService")!;
74
+ }
75
+
72
76
  /**
73
77
  * Initialize configuration watching
74
78
  * Maps to FR-004: System MUST watch settings.json files
@@ -79,7 +83,7 @@ export class LiveConfigManager {
79
83
  projectPaths?: string[],
80
84
  ): Promise<void> {
81
85
  try {
82
- this.logger?.debug("Live Config: Initializing configuration watching...");
86
+ logger?.debug("Live Config: Initializing configuration watching...");
83
87
 
84
88
  this.userConfigPaths = userPaths;
85
89
  this.projectConfigPaths = projectPaths;
@@ -90,14 +94,14 @@ export class LiveConfigManager {
90
94
  // Start watching user configs that exist
91
95
  for (const userPath of userPaths) {
92
96
  if (existsSync(userPath)) {
93
- this.logger?.debug(
97
+ logger?.debug(
94
98
  `Live Config: Starting to watch user config: ${userPath}`,
95
99
  );
96
100
  await this.fileWatcher.watchFile(userPath, (event) =>
97
101
  this.handleFileChange(event, "user"),
98
102
  );
99
103
  } else {
100
- this.logger?.debug(
104
+ logger?.debug(
101
105
  `Live Config: User config file does not exist: ${userPath}`,
102
106
  );
103
107
  }
@@ -110,14 +114,14 @@ export class LiveConfigManager {
110
114
  if (projectPath.endsWith("settings.local.json")) {
111
115
  await ensureGlobalGitIgnore("**/.wave/settings.local.json");
112
116
  }
113
- this.logger?.debug(
117
+ logger?.debug(
114
118
  `Live Config: Starting to watch project config: ${projectPath}`,
115
119
  );
116
120
  await this.fileWatcher.watchFile(projectPath, (event) =>
117
121
  this.handleFileChange(event, "project"),
118
122
  );
119
123
  } else {
120
- this.logger?.debug(
124
+ logger?.debug(
121
125
  `Live Config: Project config file does not exist: ${projectPath}`,
122
126
  );
123
127
  }
@@ -125,12 +129,12 @@ export class LiveConfigManager {
125
129
  }
126
130
 
127
131
  this.isWatching = true;
128
- this.logger?.debug(
132
+ logger?.debug(
129
133
  "Live Config: Configuration watching initialized successfully",
130
134
  );
131
135
  } catch (error) {
132
136
  const errorMessage = `Failed to initialize configuration watching: ${(error as Error).message}`;
133
- this.logger?.error(`Live Config: ${errorMessage}`);
137
+ logger?.error(`Live Config: ${errorMessage}`);
134
138
  throw new Error(errorMessage);
135
139
  }
136
140
  }
@@ -147,7 +151,7 @@ export class LiveConfigManager {
147
151
  */
148
152
  async initialize(): Promise<void> {
149
153
  if (this.isInitialized) {
150
- this.logger?.debug("Already initialized");
154
+ logger?.debug("Already initialized");
151
155
  return;
152
156
  }
153
157
 
@@ -159,11 +163,11 @@ export class LiveConfigManager {
159
163
  await this.initializeWatching(userPaths, projectPaths);
160
164
 
161
165
  this.isInitialized = true;
162
- this.logger?.debug(
166
+ logger?.debug(
163
167
  "Live configuration management initialized with file watching",
164
168
  );
165
169
  } catch (error) {
166
- this.logger?.error(`Failed to initialize: ${(error as Error).message}`);
170
+ logger?.error(`Failed to initialize: ${(error as Error).message}`);
167
171
  throw error;
168
172
  }
169
173
  }
@@ -177,7 +181,7 @@ export class LiveConfigManager {
177
181
  }
178
182
 
179
183
  try {
180
- this.logger?.debug("Live Config: Shutting down configuration manager...");
184
+ logger?.debug("Live Config: Shutting down configuration manager...");
181
185
 
182
186
  this.isWatching = false;
183
187
 
@@ -189,9 +193,9 @@ export class LiveConfigManager {
189
193
  this.lastValidConfiguration = null;
190
194
 
191
195
  this.isInitialized = false;
192
- this.logger?.debug("Live configuration management shutdown completed");
196
+ logger?.debug("Live configuration management shutdown completed");
193
197
  } catch (error) {
194
- this.logger?.error(`Error during shutdown: ${(error as Error).message}`);
198
+ logger?.error(`Error during shutdown: ${(error as Error).message}`);
195
199
  throw error;
196
200
  }
197
201
  }
@@ -202,14 +206,14 @@ export class LiveConfigManager {
202
206
  */
203
207
  private async reloadConfiguration(): Promise<WaveConfiguration> {
204
208
  if (this.reloadInProgress) {
205
- this.logger?.debug("Live Config: Reload already in progress, skipping");
209
+ logger?.debug("Live Config: Reload already in progress, skipping");
206
210
  return this.currentConfiguration || {};
207
211
  }
208
212
 
209
213
  this.reloadInProgress = true;
210
214
 
211
215
  try {
212
- this.logger?.debug("Live Config: Reloading configuration from files...");
216
+ logger?.debug("Live Config: Reloading configuration from files...");
213
217
 
214
218
  // Load merged configuration using ConfigurationService
215
219
  const loadResult: ConfigurationLoadResult =
@@ -220,20 +224,20 @@ export class LiveConfigManager {
220
224
  if (!loadResult.success) {
221
225
  const errorMessage =
222
226
  loadResult.error || "Configuration loading failed with unknown error";
223
- this.logger?.error(
227
+ logger?.error(
224
228
  `Live Config: Configuration loading failed: ${errorMessage}`,
225
229
  );
226
230
 
227
231
  // Log warnings if any
228
232
  if (loadResult.warnings && loadResult.warnings.length > 0) {
229
- this.logger?.warn(
233
+ logger?.warn(
230
234
  `Live Config: Configuration warnings: ${loadResult.warnings.join("; ")}`,
231
235
  );
232
236
  }
233
237
 
234
238
  // Use fallback configuration if available
235
239
  if (this.lastValidConfiguration) {
236
- this.logger?.debug(
240
+ logger?.debug(
237
241
  "Live Config: Using previous valid configuration due to loading errors",
238
242
  );
239
243
  this.currentConfiguration = this.lastValidConfiguration;
@@ -254,7 +258,7 @@ export class LiveConfigManager {
254
258
 
255
259
  return this.currentConfiguration;
256
260
  } else {
257
- this.logger?.warn(
261
+ logger?.warn(
258
262
  "Live Config: No previous valid configuration available, using empty config",
259
263
  );
260
264
  this.currentConfiguration = {};
@@ -264,25 +268,25 @@ export class LiveConfigManager {
264
268
 
265
269
  // Log success with detailed information
266
270
  if (newConfig) {
267
- this.logger?.debug(
271
+ logger?.debug(
268
272
  `Live Config: Configuration loaded successfully from ${loadResult.sourcePath || "merged sources"}`,
269
273
  );
270
274
 
271
275
  // Log detailed configuration info
272
276
  const hookCount = Object.keys(newConfig.hooks || {}).length;
273
277
  const envCount = Object.keys(newConfig.env || {}).length;
274
- this.logger?.debug(
278
+ logger?.debug(
275
279
  `Live Config: Loaded ${hookCount} hook events and ${envCount} environment variables`,
276
280
  );
277
281
  } else {
278
- this.logger?.debug(
282
+ logger?.debug(
279
283
  "Live Config: No configuration found (using empty configuration)",
280
284
  );
281
285
  }
282
286
 
283
287
  // Log warnings from successful loading
284
288
  if (loadResult.warnings && loadResult.warnings.length > 0) {
285
- this.logger?.warn(
289
+ logger?.warn(
286
290
  `Live Config: Configuration warnings: ${loadResult.warnings.join("; ")}`,
287
291
  );
288
292
  }
@@ -292,11 +296,11 @@ export class LiveConfigManager {
292
296
  const validation = this.validateConfiguration(newConfig);
293
297
  if (!validation.valid) {
294
298
  const errorMessage = `Configuration validation failed: ${validation.errors.join(", ")}`;
295
- this.logger?.error(`Live Config: ${errorMessage}`);
299
+ logger?.error(`Live Config: ${errorMessage}`);
296
300
 
297
301
  // Use previous valid configuration for error recovery
298
302
  if (this.lastValidConfiguration) {
299
- this.logger?.debug(
303
+ logger?.debug(
300
304
  "Live Config: Using previous valid configuration due to validation errors",
301
305
  );
302
306
  this.currentConfiguration = this.lastValidConfiguration;
@@ -317,7 +321,7 @@ export class LiveConfigManager {
317
321
 
318
322
  return this.currentConfiguration;
319
323
  } else {
320
- this.logger?.warn(
324
+ logger?.warn(
321
325
  "Live Config: No previous valid configuration available, using empty config",
322
326
  );
323
327
  this.currentConfiguration = {};
@@ -335,7 +339,7 @@ export class LiveConfigManager {
335
339
  // Save as last valid configuration if it's valid and not empty
336
340
  if (newConfig && (newConfig.hooks || newConfig.env)) {
337
341
  this.lastValidConfiguration = { ...newConfig };
338
- this.logger?.debug(
342
+ logger?.debug(
339
343
  "Live Config: Saved current configuration as last valid backup",
340
344
  );
341
345
  }
@@ -374,18 +378,18 @@ export class LiveConfigManager {
374
378
  }
375
379
  }
376
380
 
377
- this.logger?.debug(
381
+ logger?.debug(
378
382
  `Live Config: Configuration reload completed successfully with ${Object.keys(newConfig?.hooks || {}).length} event types and ${Object.keys(newConfig?.env || {}).length} environment variables`,
379
383
  );
380
384
 
381
385
  return this.currentConfiguration;
382
386
  } catch (error) {
383
387
  const errorMessage = `Configuration reload failed with exception: ${(error as Error).message}`;
384
- this.logger?.error(`Live Config: ${errorMessage}`);
388
+ logger?.error(`Live Config: ${errorMessage}`);
385
389
 
386
390
  // Use previous valid configuration for error recovery
387
391
  if (this.lastValidConfiguration) {
388
- this.logger?.debug(
392
+ logger?.debug(
389
393
  "Live Config: Using previous valid configuration due to reload exception",
390
394
  );
391
395
  this.currentConfiguration = this.lastValidConfiguration;
@@ -404,7 +408,7 @@ export class LiveConfigManager {
404
408
  );
405
409
  }
406
410
  } else {
407
- this.logger?.warn(
411
+ logger?.warn(
408
412
  "Live Config: No previous valid configuration available, using empty config",
409
413
  );
410
414
  this.currentConfiguration = {};
@@ -420,7 +424,7 @@ export class LiveConfigManager {
420
424
  * Reload configuration from files (public method)
421
425
  */
422
426
  async reload(): Promise<WaveConfiguration> {
423
- this.logger?.debug("Manually reloading configuration...");
427
+ logger?.debug("Manually reloading configuration...");
424
428
  return await this.reloadConfiguration();
425
429
  }
426
430
 
@@ -452,7 +456,7 @@ export class LiveConfigManager {
452
456
 
453
457
  private setupFileWatcherEvents(): void {
454
458
  this.fileWatcher.on("watcherError", (error: Error) => {
455
- this.logger?.error(`Live Config: File watcher error: ${error.message}`);
459
+ logger?.error(`Live Config: File watcher error: ${error.message}`);
456
460
  });
457
461
  }
458
462
 
@@ -460,14 +464,14 @@ export class LiveConfigManager {
460
464
  event: FileWatchEvent,
461
465
  source: Scope,
462
466
  ): Promise<void> {
463
- this.logger?.debug(
467
+ logger?.debug(
464
468
  `Live Config: File ${event.type} detected for ${source} config: ${event.path}`,
465
469
  );
466
470
 
467
471
  try {
468
472
  // Handle file deletion
469
473
  if (event.type === "delete") {
470
- this.logger?.debug(
474
+ logger?.debug(
471
475
  `Live Config: ${source} config file deleted: ${event.path}`,
472
476
  );
473
477
  // Reload configuration without the deleted file
@@ -477,7 +481,7 @@ export class LiveConfigManager {
477
481
 
478
482
  // Handle file creation or modification
479
483
  if (event.type === "change" || event.type === "create") {
480
- this.logger?.debug(
484
+ logger?.debug(
481
485
  `Live Config: ${source} config file ${event.type}: ${event.path}`,
482
486
  );
483
487
 
@@ -496,7 +500,7 @@ export class LiveConfigManager {
496
500
  await this.reloadConfiguration();
497
501
  }
498
502
  } catch (error) {
499
- this.logger?.error(
503
+ logger?.error(
500
504
  `Live Config: Error handling file change for ${source} config: ${(error as Error).message}`,
501
505
  );
502
506
  }
@@ -1,6 +1,5 @@
1
1
  import { ChildProcess, spawn } from "child_process";
2
2
  import {
3
- Logger,
4
3
  LspConfig,
5
4
  LspServerConfig,
6
5
  ILspManager,
@@ -8,6 +7,7 @@ import {
8
7
  } from "../types/index.js";
9
8
  import { join, isAbsolute, extname } from "path";
10
9
  import { promises as fs } from "fs";
10
+ import { Container } from "../utils/container.js";
11
11
 
12
12
  interface LspProcess {
13
13
  process: ChildProcess;
@@ -22,15 +22,14 @@ interface LspProcess {
22
22
  openedFiles: Set<string>;
23
23
  }
24
24
 
25
+ import { logger } from "../utils/globalLogger.js";
26
+
25
27
  export class LspManager implements ILspManager {
26
28
  private processes: Map<string, LspProcess> = new Map();
27
29
  private workdir: string = "";
28
- private logger?: Logger;
29
30
  private config: LspConfig = {};
30
31
 
31
- constructor(options: { logger?: Logger } = {}) {
32
- this.logger = options.logger;
33
- }
32
+ constructor(private container: Container) {}
34
33
 
35
34
  async initialize(workdir: string): Promise<void> {
36
35
  this.workdir = workdir;
@@ -39,7 +38,7 @@ export class LspManager implements ILspManager {
39
38
 
40
39
  registerServer(language: string, config: LspServerConfig): void {
41
40
  this.config[language] = config;
42
- this.logger?.debug(`Registered LSP server for ${language}`);
41
+ logger?.debug(`Registered LSP server for ${language}`);
43
42
  }
44
43
 
45
44
  private async loadConfig(): Promise<void> {
@@ -48,10 +47,10 @@ export class LspManager implements ILspManager {
48
47
  const content = await fs.readFile(lspJsonPath, "utf-8");
49
48
  const newConfig = JSON.parse(content);
50
49
  this.config = { ...this.config, ...newConfig };
51
- this.logger?.debug(`Loaded LSP config from ${lspJsonPath}`);
50
+ logger?.debug(`Loaded LSP config from ${lspJsonPath}`);
52
51
  } catch (error) {
53
52
  if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
54
- this.logger?.error(`Failed to load .lsp.json: ${error}`);
53
+ logger?.error(`Failed to load .lsp.json: ${error}`);
55
54
  }
56
55
  }
57
56
  }
@@ -86,7 +85,7 @@ export class LspManager implements ILspManager {
86
85
  language: string,
87
86
  config: LspServerConfig,
88
87
  ): Promise<LspProcess | null> {
89
- this.logger?.info(
88
+ logger?.info(
90
89
  `Starting LSP server for ${language}: ${config.command} ${config.args?.join(" ") || ""}`,
91
90
  );
92
91
 
@@ -139,7 +138,7 @@ export class LspManager implements ILspManager {
139
138
  const message = JSON.parse(content);
140
139
  this.handleMessage(lspProc, message);
141
140
  } catch (e) {
142
- this.logger?.error(`Failed to parse LSP message: ${e}`);
141
+ logger?.error(`Failed to parse LSP message: ${e}`);
143
142
  }
144
143
  } else {
145
144
  break;
@@ -148,13 +147,11 @@ export class LspManager implements ILspManager {
148
147
  });
149
148
 
150
149
  proc.stderr!.on("data", (data) => {
151
- this.logger?.debug(`LSP [${language}] stderr: ${data}`);
150
+ logger?.debug(`LSP [${language}] stderr: ${data}`);
152
151
  });
153
152
 
154
153
  proc.on("close", (code) => {
155
- this.logger?.info(
156
- `LSP server for ${language} exited with code ${code}`,
157
- );
154
+ logger?.info(`LSP server for ${language} exited with code ${code}`);
158
155
  this.processes.delete(language);
159
156
  });
160
157
 
@@ -175,9 +172,7 @@ export class LspManager implements ILspManager {
175
172
 
176
173
  return lspProc;
177
174
  } catch (error) {
178
- this.logger?.error(
179
- `Failed to start LSP server for ${language}: ${error}`,
180
- );
175
+ logger?.error(`Failed to start LSP server for ${language}: ${error}`);
181
176
  return null;
182
177
  }
183
178
  }
@@ -292,7 +287,7 @@ export class LspManager implements ILspManager {
292
287
  });
293
288
  lspProc.openedFiles.add(absolutePath);
294
289
  } catch (error) {
295
- this.logger?.error(`Failed to read file for LSP didOpen: ${error}`);
290
+ logger?.error(`Failed to read file for LSP didOpen: ${error}`);
296
291
  }
297
292
  }
298
293
 
@@ -422,7 +417,7 @@ export class LspManager implements ILspManager {
422
417
  await new Promise((resolve) => setTimeout(resolve, 100));
423
418
  }
424
419
  } catch (error) {
425
- this.logger?.debug(
420
+ logger?.debug(
426
421
  `Failed to gracefully shutdown LSP for ${language}: ${error}`,
427
422
  );
428
423
  } finally {
@@ -5,6 +5,7 @@ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"
5
5
  import { ChatCompletionFunctionTool } from "openai/resources.js";
6
6
  import { createMcpToolPlugin, findToolServer } from "../utils/mcpUtils.js";
7
7
  import type { ToolPlugin, ToolResult, ToolContext } from "../tools/types.js";
8
+ import { Container } from "../utils/container.js";
8
9
  import type {
9
10
  Logger,
10
11
  McpServerConfig,
@@ -23,6 +24,8 @@ export interface McpManagerCallbacks {
23
24
  onServersChange?: (servers: McpServerStatus[]) => void;
24
25
  }
25
26
 
27
+ import { logger } from "../utils/globalLogger.js";
28
+
26
29
  export interface McpManagerOptions {
27
30
  callbacks?: McpManagerCallbacks;
28
31
  logger?: Logger;
@@ -35,11 +38,12 @@ export class McpManager {
35
38
  private configPath: string = "";
36
39
  private workdir: string = "";
37
40
  private callbacks: McpManagerCallbacks;
38
- private logger?: Logger;
39
41
 
40
- constructor(options: McpManagerOptions = {}) {
42
+ constructor(
43
+ private container: Container,
44
+ options: McpManagerOptions = {},
45
+ ) {
41
46
  this.callbacks = options.callbacks || {};
42
- this.logger = options.logger;
43
47
  }
44
48
 
45
49
  /**
@@ -53,7 +57,7 @@ export class McpManager {
53
57
  this.workdir = workdir;
54
58
 
55
59
  if (autoConnect) {
56
- this.logger?.debug("Initializing MCP servers...");
60
+ logger?.debug("Initializing MCP servers...");
57
61
 
58
62
  // Ensure MCP configuration is loaded
59
63
  const config = await this.ensureConfigLoaded();
@@ -63,21 +67,17 @@ export class McpManager {
63
67
  const connectionPromises = Object.keys(config.mcpServers).map(
64
68
  async (serverName) => {
65
69
  try {
66
- this.logger?.debug(`Connecting to MCP server: ${serverName}`);
70
+ logger?.debug(`Connecting to MCP server: ${serverName}`);
67
71
  const success = await this.connectServer(serverName);
68
72
  if (success) {
69
- this.logger?.debug(
73
+ logger?.debug(
70
74
  `Successfully connected to MCP server: ${serverName}`,
71
75
  );
72
76
  } else {
73
- this.logger?.warn(
74
- `Failed to connect to MCP server: ${serverName}`,
75
- );
77
+ logger?.warn(`Failed to connect to MCP server: ${serverName}`);
76
78
  }
77
79
  } catch {
78
- this.logger?.error(
79
- `Error connecting to MCP server ${serverName}`,
80
- );
80
+ logger?.error(`Error connecting to MCP server ${serverName}`);
81
81
  }
82
82
  },
83
83
  );
@@ -86,7 +86,7 @@ export class McpManager {
86
86
  await Promise.all(connectionPromises);
87
87
  }
88
88
 
89
- this.logger?.debug("MCP servers initialization completed");
89
+ logger?.debug("MCP servers initialization completed");
90
90
  // Trigger state change callback after initialization
91
91
  this.callbacks.onServersChange?.(this.getAllServers());
92
92
  }
@@ -101,7 +101,7 @@ export class McpManager {
101
101
 
102
102
  async loadConfig(): Promise<McpConfig | null> {
103
103
  if (!this.configPath) {
104
- this.logger?.warn("MCP config path not set. Call initialize() first.");
104
+ logger?.warn("MCP config path not set. Call initialize() first.");
105
105
  return null;
106
106
  }
107
107
 
@@ -135,7 +135,7 @@ export class McpManager {
135
135
  } catch (error) {
136
136
  // Only log error if it's not a "file not found" error
137
137
  if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
138
- this.logger?.error("Failed to load .mcp.json:", error);
138
+ logger?.error("Failed to load .mcp.json:", error);
139
139
  }
140
140
  return null;
141
141
  }
@@ -147,7 +147,7 @@ export class McpManager {
147
147
  this.config = config;
148
148
  return true;
149
149
  } catch (error) {
150
- this.logger?.error("Failed to save .mcp.json:", error);
150
+ logger?.error("Failed to save .mcp.json:", error);
151
151
  return false;
152
152
  }
153
153
  }
@@ -247,7 +247,7 @@ export class McpManager {
247
247
 
248
248
  // Handle transport errors
249
249
  transport.onerror = (error: Error) => {
250
- this.logger?.error(`MCP Server ${name} transport error:`, error);
250
+ logger?.error(`MCP Server ${name} transport error:`, error);
251
251
  this.updateServerStatus(name, {
252
252
  status: "error",
253
253
  error: error.message,
@@ -255,7 +255,7 @@ export class McpManager {
255
255
  };
256
256
 
257
257
  transport.onclose = () => {
258
- this.logger?.debug(`MCP Server ${name} transport closed`);
258
+ logger?.debug(`MCP Server ${name} transport closed`);
259
259
  this.connections.delete(name);
260
260
  this.updateServerStatus(name, {
261
261
  status: "disconnected",
@@ -296,7 +296,7 @@ export class McpManager {
296
296
 
297
297
  return true;
298
298
  } catch (error) {
299
- this.logger?.error(`Failed to connect to MCP server ${name}:`, error);
299
+ logger?.error(`Failed to connect to MCP server ${name}:`, error);
300
300
  // updateServerStatus will trigger the callback
301
301
  this.updateServerStatus(name, {
302
302
  status: "error",
@@ -327,7 +327,7 @@ export class McpManager {
327
327
 
328
328
  return true;
329
329
  } catch (error) {
330
- this.logger?.error(`Error disconnecting from MCP server ${name}:`, error);
330
+ logger?.error(`Error disconnecting from MCP server ${name}:`, error);
331
331
  return false;
332
332
  }
333
333
  }