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
@@ -1,17 +1,9 @@
1
- import {
2
- callAgent,
3
- compressMessages,
4
- type CallAgentOptions,
5
- } from "../services/aiService.js";
1
+ import { type CallAgentOptions } from "../services/aiService.js";
2
+ import * as aiService from "../services/aiService.js";
6
3
  import { convertMessagesForAPI } from "../utils/convertMessagesForAPI.js";
7
4
  import { calculateComprehensiveTotalTokens } from "../utils/tokenCalculation.js";
8
5
  import * as fs from "node:fs/promises";
9
- import type {
10
- Logger,
11
- GatewayConfig,
12
- ModelConfig,
13
- Usage,
14
- } from "../types/index.js";
6
+ import type { GatewayConfig, ModelConfig, Usage } from "../types/index.js";
15
7
  import type { ToolManager } from "./toolManager.js";
16
8
  import type { ToolContext, ToolResult } from "../tools/types.js";
17
9
  import type { MessageManager } from "./messageManager.js";
@@ -20,7 +12,12 @@ import { ChatCompletionMessageFunctionToolCall } from "openai/resources.js";
20
12
  import type { HookManager } from "./hookManager.js";
21
13
  import type { ExtendedHookExecutionContext } from "../types/hooks.js";
22
14
  import type { PermissionManager } from "./permissionManager.js";
15
+ import type { SubagentManager } from "./subagentManager.js";
16
+ import type { SkillManager } from "./skillManager.js";
23
17
  import { buildSystemPrompt } from "../prompts/index.js";
18
+ import { Container } from "../utils/container.js";
19
+
20
+ import { logger } from "../utils/globalLogger.js";
24
21
 
25
22
  export interface AIManagerCallbacks {
26
23
  onCompressionStateChange?: (isCompressing: boolean) => void;
@@ -28,18 +25,10 @@ export interface AIManagerCallbacks {
28
25
  }
29
26
 
30
27
  export interface AIManagerOptions {
31
- messageManager: MessageManager;
32
- toolManager: ToolManager;
33
- taskManager: import("../services/taskManager.js").TaskManager;
34
- logger?: Logger;
35
- backgroundTaskManager?: BackgroundTaskManager;
36
- hookManager?: HookManager;
37
- permissionManager?: PermissionManager;
38
28
  callbacks?: AIManagerCallbacks;
39
29
  workdir: string;
40
30
  systemPrompt?: string;
41
31
  subagentType?: string; // Optional subagent type for hook context
42
- reversionManager?: import("./reversionManager.js").ReversionManager;
43
32
  /**Whether to use streaming mode for AI responses - defaults to true */
44
33
  stream?: boolean;
45
34
  // Dynamic configuration getters
@@ -54,14 +43,6 @@ export class AIManager {
54
43
  public isLoading: boolean = false;
55
44
  private abortController: AbortController | null = null;
56
45
  private toolAbortController: AbortController | null = null;
57
- private logger?: Logger;
58
- private toolManager: ToolManager;
59
- private messageManager: MessageManager;
60
- private taskManager: import("../services/taskManager.js").TaskManager;
61
- private backgroundTaskManager?: BackgroundTaskManager;
62
- private hookManager?: HookManager;
63
- private reversionManager?: import("./reversionManager.js").ReversionManager;
64
- private permissionManager?: PermissionManager;
65
46
  private workdir: string;
66
47
  private systemPrompt?: string;
67
48
  private subagentType?: string; // Store subagent type for hook context
@@ -74,15 +55,11 @@ export class AIManager {
74
55
  private getLanguageFn: () => string | undefined;
75
56
  private getEnvironmentVarsFn?: () => Record<string, string>;
76
57
 
77
- constructor(options: AIManagerOptions) {
78
- this.messageManager = options.messageManager;
79
- this.toolManager = options.toolManager;
80
- this.taskManager = options.taskManager;
81
- this.backgroundTaskManager = options.backgroundTaskManager;
82
- this.hookManager = options.hookManager;
83
- this.reversionManager = options.reversionManager;
84
- this.permissionManager = options.permissionManager;
85
- this.logger = options.logger;
58
+ // Service overrides
59
+ constructor(
60
+ private container: Container,
61
+ options: AIManagerOptions,
62
+ ) {
86
63
  this.workdir = options.workdir;
87
64
  this.systemPrompt = options.systemPrompt;
88
65
  this.subagentType = options.subagentType; // Store subagent type
@@ -97,6 +74,40 @@ export class AIManager {
97
74
  this.getEnvironmentVarsFn = options.getEnvironmentVars;
98
75
  }
99
76
 
77
+ private get toolManager(): ToolManager {
78
+ return this.container.get<ToolManager>("ToolManager")!;
79
+ }
80
+
81
+ private get messageManager(): MessageManager {
82
+ return this.container.get<MessageManager>("MessageManager")!;
83
+ }
84
+
85
+ private get taskManager(): import("../services/taskManager.js").TaskManager {
86
+ return this.container.get<import("../services/taskManager.js").TaskManager>(
87
+ "TaskManager",
88
+ )!;
89
+ }
90
+
91
+ private get backgroundTaskManager(): BackgroundTaskManager | undefined {
92
+ return this.container.get<BackgroundTaskManager>("BackgroundTaskManager");
93
+ }
94
+
95
+ private get hookManager(): HookManager | undefined {
96
+ return this.container.get<HookManager>("HookManager");
97
+ }
98
+
99
+ private get reversionManager():
100
+ | import("./reversionManager.js").ReversionManager
101
+ | undefined {
102
+ return this.container.get<import("./reversionManager.js").ReversionManager>(
103
+ "ReversionManager",
104
+ );
105
+ }
106
+
107
+ private get permissionManager(): PermissionManager | undefined {
108
+ return this.container.get<PermissionManager>("PermissionManager");
109
+ }
110
+
100
111
  // Getter methods for accessing dynamic configuration
101
112
  public getGatewayConfig(): GatewayConfig {
102
113
  return this.getGatewayConfigFn();
@@ -142,7 +153,7 @@ export class AIManager {
142
153
  try {
143
154
  this.abortController.abort();
144
155
  } catch (error) {
145
- this.logger?.error("Failed to abort AI service:", error);
156
+ logger?.error("Failed to abort AI service:", error);
146
157
  }
147
158
  }
148
159
 
@@ -151,7 +162,7 @@ export class AIManager {
151
162
  try {
152
163
  this.toolAbortController.abort();
153
164
  } catch (error) {
154
- this.logger?.error("Failed to abort tool execution:", error);
165
+ logger?.error("Failed to abort tool execution:", error);
155
166
  }
156
167
  }
157
168
 
@@ -175,7 +186,7 @@ export class AIManager {
175
186
  return toolPlugin.formatCompactParams(toolArgs, context);
176
187
  }
177
188
  } catch (error) {
178
- this.logger?.warn("Failed to generate compactParams", error);
189
+ logger?.warn("Failed to generate compactParams", error);
179
190
  }
180
191
  return "";
181
192
  }
@@ -199,7 +210,7 @@ export class AIManager {
199
210
  (usage.cache_creation_input_tokens || 0) >
200
211
  this.getMaxInputTokens()
201
212
  ) {
202
- this.logger?.debug(
213
+ logger?.debug(
203
214
  `Token usage exceeded ${this.getMaxInputTokens()}, compressing messages...`,
204
215
  );
205
216
 
@@ -215,7 +226,7 @@ export class AIManager {
215
226
 
216
227
  this.setIsCompressing(true);
217
228
  try {
218
- const compressionResult = await compressMessages({
229
+ const compressionResult = await aiService.compressMessages({
219
230
  gatewayConfig: this.getGatewayConfig(),
220
231
  modelConfig: this.getModelConfig(),
221
232
  messages: recentChatMessages,
@@ -246,11 +257,11 @@ export class AIManager {
246
257
  this.callbacks.onUsageAdded(compressionUsage);
247
258
  }
248
259
 
249
- this.logger?.debug(
260
+ logger?.debug(
250
261
  `Successfully compressed ${messagesToCompress.length} messages and updated session`,
251
262
  );
252
263
  } catch (compressError) {
253
- this.logger?.error("Failed to compress messages:", compressError);
264
+ logger?.error("Failed to compress messages:", compressError);
254
265
  } finally {
255
266
  this.setIsCompressing(false);
256
267
  }
@@ -269,6 +280,14 @@ export class AIManager {
269
280
  }
270
281
  }
271
282
 
283
+ private get subagentManager(): SubagentManager | undefined {
284
+ return this.container.get<SubagentManager>("SubagentManager");
285
+ }
286
+
287
+ private get skillManager(): SkillManager | undefined {
288
+ return this.container.get<SkillManager>("SkillManager");
289
+ }
290
+
272
291
  public async sendAIMessage(
273
292
  options: {
274
293
  recursionDepth?: number;
@@ -334,7 +353,7 @@ export class AIManager {
334
353
  // Track if assistant message has been created
335
354
  let assistantMessageCreated = false;
336
355
 
337
- this.logger?.debug("modelConfig in sendAIMessage", this.getModelConfig());
356
+ logger?.debug("modelConfig in sendAIMessage", this.getModelConfig());
338
357
 
339
358
  // Get current permission mode and plan file path
340
359
  const currentMode = this.permissionManager?.getCurrentEffectiveMode(
@@ -364,6 +383,10 @@ export class AIManager {
364
383
  }
365
384
  }
366
385
 
386
+ // Get available subagents and skills for dynamic prompts
387
+ const availableSubagents = this.subagentManager?.getConfigurations();
388
+ const availableSkills = this.skillManager?.getAvailableSkills();
389
+
367
390
  // Call AI service with streaming callbacks if enabled
368
391
  const callAgentOptions: CallAgentOptions = {
369
392
  gatewayConfig: this.getGatewayConfig(),
@@ -383,6 +406,8 @@ export class AIManager {
383
406
  language: this.getLanguage(),
384
407
  isSubagent: !!this.subagentType,
385
408
  planMode: planModeOptions,
409
+ availableSubagents,
410
+ availableSkills,
386
411
  },
387
412
  ), // Pass custom system prompt
388
413
  maxTokens: maxTokens, // Pass max tokens override
@@ -428,7 +453,7 @@ export class AIManager {
428
453
  };
429
454
  }
430
455
 
431
- const result = await callAgent(callAgentOptions);
456
+ const result = await aiService.callAgent(callAgentOptions);
432
457
  const createdByStreaming = assistantMessageCreated;
433
458
 
434
459
  // For non-streaming mode, create assistant message after callAgent returns
@@ -446,7 +471,7 @@ export class AIManager {
446
471
  if (result.finish_reason) {
447
472
  // Log warning headers when finish reason is length
448
473
  if (result.finish_reason === "length") {
449
- this.logger?.warn(
474
+ logger?.warn(
450
475
  "AI response truncated due to length limit. Response headers:",
451
476
  result.response_headers,
452
477
  );
@@ -456,7 +481,7 @@ export class AIManager {
456
481
  result.response_headers &&
457
482
  Object.keys(result.response_headers).length > 0
458
483
  ) {
459
- this.logger?.debug("AI response headers:", result.response_headers);
484
+ logger?.debug("AI response headers:", result.response_headers);
460
485
  }
461
486
 
462
487
  if (
@@ -566,7 +591,7 @@ export class AIManager {
566
591
  errorMessage +=
567
592
  " (output truncated, please reduce your output)";
568
593
  }
569
- this.logger?.error(errorMessage, parseError);
594
+ logger?.error(errorMessage, parseError);
570
595
  this.messageManager.updateToolBlock({
571
596
  id: toolId,
572
597
  parameters: argsString,
@@ -606,7 +631,7 @@ export class AIManager {
606
631
 
607
632
  // If PreToolUse hooks blocked execution, skip tool execution
608
633
  if (!shouldExecuteTool) {
609
- this.logger?.info(
634
+ logger?.info(
610
635
  `Tool ${toolName} execution blocked by PreToolUse hooks`,
611
636
  );
612
637
  return; // Skip this tool and return from this map function
@@ -720,7 +745,7 @@ export class AIManager {
720
745
  toolBlocks.some((block) => block.isManuallyBackgrounded);
721
746
 
722
747
  if (hasBackgrounded) {
723
- this.logger?.info(
748
+ logger?.info(
724
749
  "Some tools were manually backgrounded, stopping recursion.",
725
750
  );
726
751
  } else if (!isCurrentlyAborted) {
@@ -772,7 +797,7 @@ export class AIManager {
772
797
  // If Stop/SubagentStop hooks indicate we should continue (due to blocking errors),
773
798
  // restart the AI conversation cycle
774
799
  if (shouldContinue) {
775
- this.logger?.info(
800
+ logger?.info(
776
801
  `${this.subagentType ? "SubagentStop" : "Stop"} hooks indicate issues need fixing, continuing conversation...`,
777
802
  );
778
803
 
@@ -828,7 +853,7 @@ export class AIManager {
828
853
 
829
854
  // If hook processing indicates we should block (exit code 2), continue conversation
830
855
  if (processResult.shouldBlock) {
831
- this.logger?.info(
856
+ logger?.info(
832
857
  `${hookName} hook blocked stopping with error:`,
833
858
  processResult.errorMessage,
834
859
  );
@@ -838,7 +863,7 @@ export class AIManager {
838
863
 
839
864
  // Log hook execution results for debugging
840
865
  if (results.length > 0) {
841
- this.logger?.debug(
866
+ logger?.debug(
842
867
  `Executed ${results.length} ${hookName} hook(s):`,
843
868
  results.map((r) => ({
844
869
  success: r.success,
@@ -853,7 +878,7 @@ export class AIManager {
853
878
  return shouldContinue;
854
879
  } catch (error) {
855
880
  // Hook execution errors should not interrupt the main workflow
856
- this.logger?.error(
881
+ logger?.error(
857
882
  `${this.subagentType ? "SubagentStop" : "Stop"} hook execution failed:`,
858
883
  error,
859
884
  );
@@ -906,7 +931,7 @@ export class AIManager {
906
931
 
907
932
  // Log hook execution results for debugging
908
933
  if (results.length > 0) {
909
- this.logger?.debug(
934
+ logger?.debug(
910
935
  `Executed ${results.length} PreToolUse hook(s) for ${toolName}:`,
911
936
  results.map((r) => ({
912
937
  success: r.success,
@@ -921,7 +946,7 @@ export class AIManager {
921
946
  return shouldContinue;
922
947
  } catch (error) {
923
948
  // Hook execution errors should not interrupt the main workflow
924
- this.logger?.error("PreToolUse hook execution failed:", error);
949
+ logger?.error("PreToolUse hook execution failed:", error);
925
950
  return true; // Allow tool execution on hook errors
926
951
  }
927
952
  }
@@ -969,7 +994,7 @@ export class AIManager {
969
994
 
970
995
  // Log hook execution results for debugging
971
996
  if (results.length > 0) {
972
- this.logger?.debug(
997
+ logger?.debug(
973
998
  `Executed ${results.length} PostToolUse hook(s) for ${toolName}:`,
974
999
  results.map((r) => ({
975
1000
  success: r.success,
@@ -982,7 +1007,7 @@ export class AIManager {
982
1007
  }
983
1008
  } catch (error) {
984
1009
  // Hook execution errors should not interrupt the main workflow
985
- this.logger?.error("PostToolUse hook execution failed:", error);
1010
+ logger?.error("PostToolUse hook execution failed:", error);
986
1011
  }
987
1012
  }
988
1013
  }
@@ -2,6 +2,7 @@ import { spawn, type ChildProcess } from "child_process";
2
2
  import { BackgroundTask, BackgroundShell } from "../types/processes.js";
3
3
  import { stripAnsiColors } from "../utils/stringUtils.js";
4
4
  import { logger } from "../utils/globalLogger.js";
5
+ import { Container } from "../utils/container.js";
5
6
 
6
7
  export interface BackgroundTaskManagerCallbacks {
7
8
  onTasksChange?: (tasks: BackgroundTask[]) => void;
@@ -18,7 +19,10 @@ export class BackgroundTaskManager {
18
19
  private callbacks: BackgroundTaskManagerCallbacks;
19
20
  private workdir: string;
20
21
 
21
- constructor(options: BackgroundTaskManagerOptions) {
22
+ constructor(
23
+ private container: Container,
24
+ options: BackgroundTaskManagerOptions,
25
+ ) {
22
26
  this.callbacks = options.callbacks || {};
23
27
  this.workdir = options.workdir;
24
28
  }
@@ -1,8 +1,8 @@
1
1
  import { spawn, type ChildProcess } from "child_process";
2
2
  import type { MessageManager } from "./messageManager.js";
3
+ import { Container } from "../utils/container.js";
3
4
 
4
5
  export interface BashManagerOptions {
5
- messageManager: MessageManager;
6
6
  workdir: string;
7
7
  }
8
8
 
@@ -13,13 +13,18 @@ export interface CommandExecutionResult {
13
13
 
14
14
  export class BashManager {
15
15
  private workdir: string;
16
- private messageManager: MessageManager;
17
16
  public isCommandRunning = false;
18
17
  private currentProcess: ChildProcess | null = null;
19
18
 
20
- constructor(options: BashManagerOptions) {
19
+ constructor(
20
+ private container: Container,
21
+ options: BashManagerOptions,
22
+ ) {
21
23
  this.workdir = options.workdir;
22
- this.messageManager = options.messageManager;
24
+ }
25
+
26
+ private get messageManager(): MessageManager {
27
+ return this.container.get<MessageManager>("MessageManager")!;
23
28
  }
24
29
 
25
30
  private setCommandRunning(isRunning: boolean): void {
@@ -1,8 +1,11 @@
1
1
  import { ForegroundTask, IForegroundTaskManager } from "../types/processes.js";
2
+ import { Container } from "../utils/container.js";
2
3
 
3
4
  export class ForegroundTaskManager implements IForegroundTaskManager {
4
5
  private activeForegroundTasks: ForegroundTask[] = [];
5
6
 
7
+ constructor(private container: Container) {}
8
+
6
9
  public registerForegroundTask(task: ForegroundTask): void {
7
10
  this.activeForegroundTasks.push(task);
8
11
  }
@@ -22,24 +22,24 @@ import type {
22
22
  } from "../types/configuration.js";
23
23
  import { HookMatcher } from "../utils/hookMatcher.js";
24
24
  import { executeCommand, isCommandSafe } from "../services/hook.js";
25
- import type { Logger } from "../types/index.js";
26
25
  import { MessageSource } from "../types/index.js";
27
26
  import type { MessageManager } from "./messageManager.js";
27
+ import { Container } from "../utils/container.js";
28
+
29
+ import { logger } from "../utils/globalLogger.js";
28
30
 
29
31
  export class HookManager {
30
32
  private configuration: PartialHookConfiguration | undefined;
31
33
  private readonly matcher: HookMatcher;
32
- private readonly logger?: Logger;
33
34
  private readonly workdir: string;
34
35
 
35
36
  constructor(
37
+ private container: Container,
36
38
  workdir: string,
37
39
  matcher: HookMatcher = new HookMatcher(),
38
- logger?: Logger,
39
40
  ) {
40
41
  this.workdir = workdir;
41
42
  this.matcher = matcher;
42
- this.logger = logger;
43
43
  }
44
44
 
45
45
  /**
@@ -80,7 +80,7 @@ export class HookManager {
80
80
  */
81
81
  loadConfigurationFromWaveConfig(waveConfig: WaveConfiguration | null): void {
82
82
  try {
83
- this.logger?.debug(
83
+ logger?.debug(
84
84
  `[HookManager] Loading hooks configuration from pre-loaded config...`,
85
85
  );
86
86
 
@@ -97,7 +97,7 @@ export class HookManager {
97
97
  }
98
98
  }
99
99
 
100
- this.logger?.debug(
100
+ logger?.debug(
101
101
  `[HookManager] Hooks configuration loaded successfully with ${Object.keys(waveConfig?.hooks || {}).length} event types`,
102
102
  );
103
103
  } catch (error) {
@@ -108,7 +108,7 @@ export class HookManager {
108
108
  if (error instanceof HookConfigurationError) {
109
109
  throw error;
110
110
  } else {
111
- this.logger?.warn(
111
+ logger?.warn(
112
112
  `[HookManager] Failed to load configuration, continuing with no hooks: ${(error as Error).message}`,
113
113
  );
114
114
  }
@@ -125,7 +125,7 @@ export class HookManager {
125
125
  // Validate execution context
126
126
  const contextValidation = this.validateExecutionContext(event, context);
127
127
  if (!contextValidation.valid) {
128
- this.logger?.error(
128
+ logger?.error(
129
129
  `[HookManager] Invalid execution context for ${event}: ${contextValidation.errors.join(", ")}`,
130
130
  );
131
131
  return [
@@ -139,7 +139,7 @@ export class HookManager {
139
139
  }
140
140
 
141
141
  if (!this.configuration) {
142
- this.logger?.debug(
142
+ logger?.debug(
143
143
  `[HookManager] No configuration loaded, skipping ${event} hooks`,
144
144
  );
145
145
  return [];
@@ -147,13 +147,11 @@ export class HookManager {
147
147
 
148
148
  const eventConfigs = this.configuration[event];
149
149
  if (!eventConfigs || eventConfigs.length === 0) {
150
- this.logger?.debug(
151
- `[HookManager] No hooks configured for ${event} event`,
152
- );
150
+ logger?.debug(`[HookManager] No hooks configured for ${event} event`);
153
151
  return [];
154
152
  }
155
153
 
156
- this.logger?.debug(
154
+ logger?.debug(
157
155
  `[HookManager] Starting ${event} hook execution with ${eventConfigs.length} configurations`,
158
156
  );
159
157
 
@@ -169,13 +167,13 @@ export class HookManager {
169
167
 
170
168
  // Check if this config applies to the current context
171
169
  if (!this.configApplies(config, event, context.toolName)) {
172
- this.logger?.debug(
170
+ logger?.debug(
173
171
  `[HookManager] Skipping configuration ${configIndex + 1}: matcher '${config.matcher}' does not match tool '${context.toolName}'`,
174
172
  );
175
173
  continue;
176
174
  }
177
175
 
178
- this.logger?.debug(
176
+ logger?.debug(
179
177
  `[HookManager] Executing configuration ${configIndex + 1} with ${config.hooks.length} commands (matcher: ${config.matcher || "any"})`,
180
178
  );
181
179
 
@@ -188,7 +186,7 @@ export class HookManager {
188
186
  const hookCommand = config.hooks[commandIndex];
189
187
 
190
188
  try {
191
- this.logger?.debug(
189
+ logger?.debug(
192
190
  `[HookManager] Executing command ${commandIndex + 1}/${config.hooks.length} in configuration ${configIndex + 1}`,
193
191
  );
194
192
 
@@ -201,11 +199,11 @@ export class HookManager {
201
199
 
202
200
  // Report individual command result
203
201
  if (result.success) {
204
- this.logger?.debug(
202
+ logger?.debug(
205
203
  `[HookManager] Command ${commandIndex + 1} completed successfully in ${result.duration}ms`,
206
204
  );
207
205
  } else {
208
- this.logger?.debug(
206
+ logger?.debug(
209
207
  `[HookManager] Command ${commandIndex + 1} failed in ${result.duration}ms (exit code: ${result.exitCode}, timed out: ${result.timedOut})`,
210
208
  );
211
209
  }
@@ -216,7 +214,7 @@ export class HookManager {
216
214
  // This should be rare as executor handles most errors
217
215
  const errorMessage =
218
216
  error instanceof Error ? error.message : "Unknown execution error";
219
- this.logger?.error(
217
+ logger?.error(
220
218
  `[HookManager] Unexpected error in command ${commandIndex + 1}: ${errorMessage}`,
221
219
  );
222
220
 
@@ -237,7 +235,7 @@ export class HookManager {
237
235
  results,
238
236
  totalDuration,
239
237
  );
240
- this.logger?.debug(`[HookManager] ${event} execution summary: ${summary}`);
238
+ logger?.debug(`[HookManager] ${event} execution summary: ${summary}`);
241
239
 
242
240
  return results;
243
241
  }
@@ -552,7 +550,7 @@ export class HookManager {
552
550
 
553
551
  // Warn about event mismatch but don't fail validation
554
552
  if (context.event !== event) {
555
- this.logger?.warn(
553
+ logger?.warn(
556
554
  `[HookManager] Context event '${context.event}' does not match requested event '${event}'`,
557
555
  );
558
556
  }
@@ -582,7 +580,7 @@ export class HookManager {
582
580
  event === "SubagentStop") &&
583
581
  context.toolName !== undefined
584
582
  ) {
585
- this.logger?.warn(
583
+ logger?.warn(
586
584
  `[HookManager] ${event} event has unexpected toolName in context: ${context.toolName}`,
587
585
  );
588
586
  }
@@ -790,7 +788,7 @@ export class HookManager {
790
788
 
791
789
  this.mergeHooksConfiguration(this.configuration, hooks);
792
790
 
793
- this.logger?.debug(
791
+ logger?.debug(
794
792
  `Registered plugin hooks. Total event types: ${Object.keys(this.configuration).length}`,
795
793
  );
796
794
  }