wave-agent-sdk 0.0.7 → 0.0.8

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 (172) hide show
  1. package/dist/agent.d.ts +32 -20
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +202 -20
  4. package/dist/constants/events.d.ts +28 -0
  5. package/dist/constants/events.d.ts.map +1 -0
  6. package/dist/constants/events.js +27 -0
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +2 -0
  10. package/dist/managers/aiManager.d.ts +34 -1
  11. package/dist/managers/aiManager.d.ts.map +1 -1
  12. package/dist/managers/aiManager.js +243 -128
  13. package/dist/managers/backgroundBashManager.d.ts.map +1 -1
  14. package/dist/managers/backgroundBashManager.js +7 -6
  15. package/dist/managers/hookManager.d.ts +9 -4
  16. package/dist/managers/hookManager.d.ts.map +1 -1
  17. package/dist/managers/hookManager.js +62 -30
  18. package/dist/managers/liveConfigManager.d.ts +58 -0
  19. package/dist/managers/liveConfigManager.d.ts.map +1 -0
  20. package/dist/managers/liveConfigManager.js +160 -0
  21. package/dist/managers/messageManager.d.ts +38 -13
  22. package/dist/managers/messageManager.d.ts.map +1 -1
  23. package/dist/managers/messageManager.js +163 -30
  24. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  25. package/dist/managers/slashCommandManager.js +4 -1
  26. package/dist/managers/subagentManager.d.ts +51 -0
  27. package/dist/managers/subagentManager.d.ts.map +1 -1
  28. package/dist/managers/subagentManager.js +189 -18
  29. package/dist/services/aiService.d.ts +13 -5
  30. package/dist/services/aiService.d.ts.map +1 -1
  31. package/dist/services/aiService.js +350 -74
  32. package/dist/services/configurationWatcher.d.ts +120 -0
  33. package/dist/services/configurationWatcher.d.ts.map +1 -0
  34. package/dist/services/configurationWatcher.js +439 -0
  35. package/dist/services/fileWatcher.d.ts +69 -0
  36. package/dist/services/fileWatcher.d.ts.map +1 -0
  37. package/dist/services/fileWatcher.js +213 -0
  38. package/dist/services/hook.d.ts +91 -9
  39. package/dist/services/hook.d.ts.map +1 -1
  40. package/dist/services/hook.js +393 -43
  41. package/dist/services/jsonlHandler.d.ts +62 -0
  42. package/dist/services/jsonlHandler.d.ts.map +1 -0
  43. package/dist/services/jsonlHandler.js +257 -0
  44. package/dist/services/memory.d.ts +9 -0
  45. package/dist/services/memory.d.ts.map +1 -1
  46. package/dist/services/memory.js +81 -12
  47. package/dist/services/memoryStore.d.ts +81 -0
  48. package/dist/services/memoryStore.d.ts.map +1 -0
  49. package/dist/services/memoryStore.js +200 -0
  50. package/dist/services/session.d.ts +64 -49
  51. package/dist/services/session.d.ts.map +1 -1
  52. package/dist/services/session.js +310 -132
  53. package/dist/tools/bashTool.d.ts.map +1 -1
  54. package/dist/tools/bashTool.js +5 -4
  55. package/dist/tools/deleteFileTool.d.ts.map +1 -1
  56. package/dist/tools/deleteFileTool.js +2 -1
  57. package/dist/tools/editTool.d.ts.map +1 -1
  58. package/dist/tools/editTool.js +3 -2
  59. package/dist/tools/multiEditTool.d.ts.map +1 -1
  60. package/dist/tools/multiEditTool.js +4 -3
  61. package/dist/tools/readTool.d.ts.map +1 -1
  62. package/dist/tools/readTool.js +2 -1
  63. package/dist/tools/writeTool.d.ts.map +1 -1
  64. package/dist/tools/writeTool.js +5 -6
  65. package/dist/types/commands.d.ts +4 -0
  66. package/dist/types/commands.d.ts.map +1 -1
  67. package/dist/types/core.d.ts +35 -0
  68. package/dist/types/core.d.ts.map +1 -1
  69. package/dist/types/environment.d.ts +42 -0
  70. package/dist/types/environment.d.ts.map +1 -0
  71. package/dist/types/environment.js +21 -0
  72. package/dist/types/hooks.d.ts +8 -2
  73. package/dist/types/hooks.d.ts.map +1 -1
  74. package/dist/types/hooks.js +8 -2
  75. package/dist/types/index.d.ts +2 -0
  76. package/dist/types/index.d.ts.map +1 -1
  77. package/dist/types/index.js +2 -0
  78. package/dist/types/memoryStore.d.ts +82 -0
  79. package/dist/types/memoryStore.d.ts.map +1 -0
  80. package/dist/types/memoryStore.js +7 -0
  81. package/dist/types/messaging.d.ts +14 -2
  82. package/dist/types/messaging.d.ts.map +1 -1
  83. package/dist/types/session.d.ts +20 -0
  84. package/dist/types/session.d.ts.map +1 -0
  85. package/dist/types/session.js +7 -0
  86. package/dist/utils/bashHistory.d.ts.map +1 -1
  87. package/dist/utils/bashHistory.js +27 -26
  88. package/dist/utils/cacheControlUtils.d.ts +121 -0
  89. package/dist/utils/cacheControlUtils.d.ts.map +1 -0
  90. package/dist/utils/cacheControlUtils.js +367 -0
  91. package/dist/utils/commandPathResolver.d.ts +52 -0
  92. package/dist/utils/commandPathResolver.d.ts.map +1 -0
  93. package/dist/utils/commandPathResolver.js +145 -0
  94. package/dist/utils/configPaths.d.ts +85 -0
  95. package/dist/utils/configPaths.d.ts.map +1 -0
  96. package/dist/utils/configPaths.js +121 -0
  97. package/dist/utils/configResolver.d.ts +37 -10
  98. package/dist/utils/configResolver.d.ts.map +1 -1
  99. package/dist/utils/configResolver.js +127 -23
  100. package/dist/utils/constants.d.ts +1 -1
  101. package/dist/utils/constants.js +1 -1
  102. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  103. package/dist/utils/convertMessagesForAPI.js +7 -5
  104. package/dist/utils/customCommands.d.ts.map +1 -1
  105. package/dist/utils/customCommands.js +66 -21
  106. package/dist/utils/fileUtils.d.ts +15 -0
  107. package/dist/utils/fileUtils.d.ts.map +1 -0
  108. package/dist/utils/fileUtils.js +61 -0
  109. package/dist/utils/globalLogger.d.ts +102 -0
  110. package/dist/utils/globalLogger.d.ts.map +1 -0
  111. package/dist/utils/globalLogger.js +136 -0
  112. package/dist/utils/mcpUtils.d.ts.map +1 -1
  113. package/dist/utils/mcpUtils.js +25 -3
  114. package/dist/utils/messageOperations.d.ts +20 -8
  115. package/dist/utils/messageOperations.d.ts.map +1 -1
  116. package/dist/utils/messageOperations.js +25 -16
  117. package/dist/utils/pathEncoder.d.ts +104 -0
  118. package/dist/utils/pathEncoder.d.ts.map +1 -0
  119. package/dist/utils/pathEncoder.js +272 -0
  120. package/dist/utils/subagentParser.d.ts.map +1 -1
  121. package/dist/utils/subagentParser.js +2 -1
  122. package/dist/utils/tokenCalculation.d.ts +26 -0
  123. package/dist/utils/tokenCalculation.d.ts.map +1 -0
  124. package/dist/utils/tokenCalculation.js +36 -0
  125. package/package.json +6 -3
  126. package/src/agent.ts +298 -34
  127. package/src/constants/events.ts +38 -0
  128. package/src/index.ts +2 -0
  129. package/src/managers/aiManager.ts +323 -170
  130. package/src/managers/backgroundBashManager.ts +7 -6
  131. package/src/managers/hookManager.ts +83 -40
  132. package/src/managers/liveConfigManager.ts +248 -0
  133. package/src/managers/messageManager.ts +230 -63
  134. package/src/managers/slashCommandManager.ts +4 -1
  135. package/src/managers/subagentManager.ts +283 -21
  136. package/src/services/aiService.ts +474 -83
  137. package/src/services/configurationWatcher.ts +622 -0
  138. package/src/services/fileWatcher.ts +301 -0
  139. package/src/services/hook.ts +538 -47
  140. package/src/services/jsonlHandler.ts +319 -0
  141. package/src/services/memory.ts +92 -12
  142. package/src/services/memoryStore.ts +279 -0
  143. package/src/services/session.ts +381 -157
  144. package/src/tools/bashTool.ts +5 -4
  145. package/src/tools/deleteFileTool.ts +2 -1
  146. package/src/tools/editTool.ts +3 -2
  147. package/src/tools/multiEditTool.ts +4 -3
  148. package/src/tools/readTool.ts +2 -1
  149. package/src/tools/writeTool.ts +7 -6
  150. package/src/types/commands.ts +6 -0
  151. package/src/types/core.ts +44 -0
  152. package/src/types/environment.ts +60 -0
  153. package/src/types/hooks.ts +21 -8
  154. package/src/types/index.ts +2 -0
  155. package/src/types/memoryStore.ts +94 -0
  156. package/src/types/messaging.ts +14 -2
  157. package/src/types/session.ts +25 -0
  158. package/src/utils/bashHistory.ts +27 -27
  159. package/src/utils/cacheControlUtils.ts +540 -0
  160. package/src/utils/commandPathResolver.ts +189 -0
  161. package/src/utils/configPaths.ts +163 -0
  162. package/src/utils/configResolver.ts +182 -22
  163. package/src/utils/constants.ts +1 -1
  164. package/src/utils/convertMessagesForAPI.ts +7 -5
  165. package/src/utils/customCommands.ts +90 -22
  166. package/src/utils/fileUtils.ts +65 -0
  167. package/src/utils/globalLogger.ts +145 -0
  168. package/src/utils/mcpUtils.ts +34 -3
  169. package/src/utils/messageOperations.ts +42 -20
  170. package/src/utils/pathEncoder.ts +379 -0
  171. package/src/utils/subagentParser.ts +2 -1
  172. package/src/utils/tokenCalculation.ts +43 -0
@@ -1,6 +1,7 @@
1
1
  import { callAgent, compressMessages } from "../services/aiService.js";
2
2
  import { getMessagesToCompress } from "../utils/messageOperations.js";
3
3
  import { convertMessagesForAPI } from "../utils/convertMessagesForAPI.js";
4
+ import { calculateComprehensiveTotalTokens } from "../utils/tokenCalculation.js";
4
5
  import * as memory from "../services/memory.js";
5
6
  export class AIManager {
6
7
  constructor(options) {
@@ -15,12 +16,60 @@ export class AIManager {
15
16
  this.logger = options.logger;
16
17
  this.workdir = options.workdir;
17
18
  this.systemPrompt = options.systemPrompt;
19
+ this.subagentType = options.subagentType; // Store subagent type
18
20
  this.callbacks = options.callbacks ?? {};
19
21
  // Store resolved configuration
20
22
  this.gatewayConfig = options.gatewayConfig;
21
23
  this.modelConfig = options.modelConfig;
22
24
  this.tokenLimit = options.tokenLimit;
23
25
  }
26
+ /**
27
+ * Update gateway configuration at runtime for live config reload
28
+ * @param newConfig - New gateway configuration
29
+ */
30
+ updateGatewayConfig(newConfig) {
31
+ this.logger?.info(`Live Config: Updating AIManager gateway config - baseURL: ${newConfig.baseURL}`);
32
+ this.gatewayConfig = newConfig;
33
+ }
34
+ /**
35
+ * Update model configuration at runtime for live config reload
36
+ * @param newConfig - New model configuration
37
+ */
38
+ updateModelConfig(newConfig) {
39
+ this.logger?.info(`Live Config: Updating AIManager model config - agent: ${newConfig.agentModel}, fast: ${newConfig.fastModel}`);
40
+ this.modelConfig = newConfig;
41
+ }
42
+ /**
43
+ * Update token limit at runtime for live config reload
44
+ * @param newLimit - New token limit
45
+ */
46
+ updateTokenLimit(newLimit) {
47
+ this.logger?.info(`Live Config: Updating AIManager token limit: ${newLimit}`);
48
+ this.tokenLimit = newLimit;
49
+ }
50
+ /**
51
+ * Update all configurations at once for live config reload
52
+ * @param newGatewayConfig - New gateway configuration
53
+ * @param newModelConfig - New model configuration
54
+ * @param newTokenLimit - New token limit
55
+ */
56
+ updateConfiguration(newGatewayConfig, newModelConfig, newTokenLimit) {
57
+ this.logger?.info("Live Config: Updating all AIManager configuration");
58
+ this.gatewayConfig = newGatewayConfig;
59
+ this.modelConfig = newModelConfig;
60
+ this.tokenLimit = newTokenLimit;
61
+ this.logger?.info(`Live Config: Configuration updated - model: ${newModelConfig.agentModel}, tokenLimit: ${newTokenLimit}`);
62
+ }
63
+ /**
64
+ * Get current configuration for debugging
65
+ */
66
+ getCurrentConfiguration() {
67
+ return {
68
+ gatewayConfig: { ...this.gatewayConfig },
69
+ modelConfig: { ...this.modelConfig },
70
+ tokenLimit: this.tokenLimit,
71
+ };
72
+ }
24
73
  /**
25
74
  * Get filtered tool configuration
26
75
  */
@@ -73,22 +122,28 @@ export class AIManager {
73
122
  catch (error) {
74
123
  this.logger?.warn("Failed to generate compactParams", error);
75
124
  }
76
- return undefined;
125
+ return "";
77
126
  }
78
127
  // Private method to handle token statistics and message compression
79
128
  async handleTokenUsageAndCompression(usage, abortController) {
80
129
  if (!usage)
81
130
  return;
82
- // Update token statistics - display latest token usage
83
- this.messageManager.setlatestTotalTokens(usage.total_tokens);
131
+ // Update token statistics - display comprehensive token usage including cache tokens
132
+ const comprehensiveTotalTokens = calculateComprehensiveTotalTokens(usage);
133
+ this.messageManager.setlatestTotalTokens(comprehensiveTotalTokens);
84
134
  // Check if token limit exceeded - use injected configuration
85
- if (usage.total_tokens > this.tokenLimit) {
135
+ if (usage.total_tokens +
136
+ (usage.cache_read_input_tokens || 0) +
137
+ (usage.cache_creation_input_tokens || 0) >
138
+ this.tokenLimit) {
86
139
  this.logger?.debug(`Token usage exceeded ${this.tokenLimit}, compressing messages...`);
87
140
  // Check if messages need compression
88
141
  const { messagesToCompress, insertIndex } = getMessagesToCompress(this.messageManager.getMessages(), 7);
89
142
  // If there are messages to compress, perform compression
90
143
  if (messagesToCompress.length > 0) {
91
144
  const recentChatMessages = convertMessagesForAPI(messagesToCompress);
145
+ // Save session before compression to preserve original messages
146
+ await this.messageManager.saveSession();
92
147
  this.setIsCompressing(true);
93
148
  try {
94
149
  const compressionResult = await compressMessages({
@@ -97,21 +152,22 @@ export class AIManager {
97
152
  messages: recentChatMessages,
98
153
  abortSignal: abortController.signal,
99
154
  });
100
- // Execute message reconstruction and sessionId update after compression
101
- this.messageManager.compressMessagesAndUpdateSession(insertIndex, compressionResult.content);
102
155
  // Handle usage tracking for compression operations
156
+ let compressionUsage;
103
157
  if (compressionResult.usage) {
104
- const usage = {
158
+ compressionUsage = {
105
159
  prompt_tokens: compressionResult.usage.prompt_tokens,
106
160
  completion_tokens: compressionResult.usage.completion_tokens,
107
161
  total_tokens: compressionResult.usage.total_tokens,
108
162
  model: this.modelConfig.fastModel,
109
163
  operation_type: "compress",
110
164
  };
111
- // Notify Agent to add to usage tracking
112
- if (this.callbacks?.onUsageAdded) {
113
- this.callbacks.onUsageAdded(usage);
114
- }
165
+ }
166
+ // Execute message reconstruction and sessionId update after compression
167
+ this.messageManager.compressMessagesAndUpdateSession(insertIndex, compressionResult.content, compressionUsage);
168
+ // Notify Agent to add to usage tracking
169
+ if (compressionUsage && this.callbacks?.onUsageAdded) {
170
+ this.callbacks.onUsageAdded(compressionUsage);
115
171
  }
116
172
  this.logger?.debug(`Successfully compressed ${messagesToCompress.length} messages and updated session`);
117
173
  }
@@ -139,6 +195,8 @@ export class AIManager {
139
195
  if (recursionDepth === 0 && this.isLoading) {
140
196
  return;
141
197
  }
198
+ // Save session in each recursion to ensure message persistence
199
+ await this.messageManager.saveSession();
142
200
  // Only create new AbortControllers for the initial call (recursionDepth === 0)
143
201
  // For recursive calls, reuse existing controllers to maintain abort signal
144
202
  let abortController;
@@ -164,7 +222,9 @@ export class AIManager {
164
222
  try {
165
223
  // Get combined memory content
166
224
  const combinedMemory = await memory.getCombinedMemoryContent(this.workdir);
167
- // Call AI service (non-streaming)
225
+ // Add assistant message first (for streaming updates)
226
+ this.messageManager.addAssistantMessage();
227
+ // Call AI service with streaming callbacks
168
228
  const result = await callAgent({
169
229
  gatewayConfig: this.gatewayConfig,
170
230
  modelConfig: this.modelConfig,
@@ -176,17 +236,39 @@ export class AIManager {
176
236
  tools: this.getFilteredToolsConfig(allowedTools), // Pass filtered tool configuration
177
237
  model: model, // Use passed model
178
238
  systemPrompt: this.systemPrompt, // Pass custom system prompt
239
+ // Streaming callbacks
240
+ onContentUpdate: (content) => {
241
+ this.messageManager.updateCurrentMessageContent(content);
242
+ },
243
+ onToolUpdate: (toolCall) => {
244
+ // Use parametersChunk as compact param for better performance
245
+ // No need to extract params or generate compact params during streaming
246
+ this.logger?.debug("Tool streaming update:", toolCall);
247
+ // Update tool block with streaming parameters using parametersChunk as compact param
248
+ this.messageManager.updateToolBlock({
249
+ id: toolCall.id,
250
+ name: toolCall.name,
251
+ parameters: toolCall.parameters,
252
+ parametersChunk: toolCall.parametersChunk,
253
+ compactParams: toolCall.parameters?.split("\n").pop()?.slice(-30),
254
+ stage: toolCall.stage || "streaming", // Default to streaming if stage not provided
255
+ });
256
+ },
179
257
  });
180
- // Collect content and tool calls
181
- const content = result.content || "";
182
- const toolCalls = [];
183
- if (result.tool_calls) {
184
- for (const toolCall of result.tool_calls) {
185
- this.logger?.debug("ToolCall", toolCall);
186
- if (toolCall.type === "function") {
187
- toolCalls.push(toolCall);
188
- }
189
- }
258
+ // Log finish reason and response headers if available
259
+ if (result.finish_reason) {
260
+ this.logger?.debug(`AI response finished with reason: ${result.finish_reason}`);
261
+ }
262
+ if (result.response_headers &&
263
+ Object.keys(result.response_headers).length > 0) {
264
+ this.logger?.debug("AI response headers:", result.response_headers);
265
+ }
266
+ if (result.metadata && Object.keys(result.metadata).length > 0) {
267
+ this.messageManager.mergeAssistantMetadata(result.metadata);
268
+ }
269
+ // Handle result content from non-streaming mode
270
+ if (result.content) {
271
+ this.messageManager.updateCurrentMessageContent(result.content);
190
272
  }
191
273
  // Handle usage tracking for agent operations
192
274
  let usage;
@@ -197,113 +279,140 @@ export class AIManager {
197
279
  total_tokens: result.usage.total_tokens,
198
280
  model: model || this.modelConfig.agentModel,
199
281
  operation_type: "agent",
282
+ // Preserve cache fields if present
283
+ ...(result.usage.cache_read_input_tokens !== undefined && {
284
+ cache_read_input_tokens: result.usage.cache_read_input_tokens,
285
+ }),
286
+ ...(result.usage.cache_creation_input_tokens !== undefined && {
287
+ cache_creation_input_tokens: result.usage.cache_creation_input_tokens,
288
+ }),
289
+ ...(result.usage.cache_creation && {
290
+ cache_creation: result.usage.cache_creation,
291
+ }),
200
292
  };
201
293
  }
202
- // Add assistant message at once (including content, tool calls, and usage)
203
- this.messageManager.addAssistantMessage(content, toolCalls, usage);
204
- // Notify Agent to add to usage tracking
294
+ // Set usage on the assistant message if available
205
295
  if (usage) {
296
+ const messages = this.messageManager.getMessages();
297
+ const lastMessage = messages[messages.length - 1];
298
+ if (lastMessage && lastMessage.role === "assistant") {
299
+ lastMessage.usage = usage;
300
+ this.messageManager.setMessages(messages);
301
+ }
302
+ // Notify Agent to add to usage tracking
206
303
  if (this.callbacks?.onUsageAdded) {
207
304
  this.callbacks.onUsageAdded(usage);
208
305
  }
209
306
  }
307
+ // Collect tool calls for processing
308
+ const toolCalls = [];
309
+ if (result.tool_calls) {
310
+ for (const toolCall of result.tool_calls) {
311
+ if (toolCall.type === "function") {
312
+ toolCalls.push(toolCall);
313
+ }
314
+ }
315
+ }
210
316
  if (toolCalls.length > 0) {
211
317
  // Execute all tools in parallel using Promise.all
212
318
  const toolExecutionPromises = toolCalls.map(async (functionToolCall) => {
213
319
  const toolId = functionToolCall.id || "";
214
- try {
215
- // Check if already interrupted, skip tool execution if so
216
- if (abortController.signal.aborted ||
217
- toolAbortController.signal.aborted) {
320
+ // Check if already interrupted, skip tool execution if so
321
+ if (abortController.signal.aborted ||
322
+ toolAbortController.signal.aborted) {
323
+ return;
324
+ }
325
+ const toolName = functionToolCall.function?.name || "";
326
+ // Safely parse tool parameters, handle tools without parameters
327
+ let toolArgs = {};
328
+ const argsString = functionToolCall.function?.arguments?.trim();
329
+ if (!argsString || argsString === "") {
330
+ // Tool without parameters, use empty object
331
+ toolArgs = {};
332
+ }
333
+ else {
334
+ try {
335
+ toolArgs = JSON.parse(argsString);
336
+ }
337
+ catch (parseError) {
338
+ // For non-empty but malformed JSON, still throw exception
339
+ const errorMessage = `Failed to parse tool arguments, finish_reason: ${result.finish_reason}`;
340
+ const fullErrorMessage = `${errorMessage}\nAI response headers:, ${JSON.stringify(result.response_headers)}`;
341
+ this.logger?.error(fullErrorMessage, parseError);
342
+ this.messageManager.updateToolBlock({
343
+ id: toolId,
344
+ parameters: argsString,
345
+ result: errorMessage,
346
+ success: false,
347
+ error: fullErrorMessage,
348
+ stage: "end",
349
+ name: toolName,
350
+ compactParams: "",
351
+ });
218
352
  return;
219
353
  }
220
- // Safely parse tool parameters, handle tools without parameters
221
- let toolArgs = {};
222
- const argsString = functionToolCall.function?.arguments?.trim();
223
- if (!argsString || argsString === "") {
224
- // Tool without parameters, use empty object
225
- toolArgs = {};
354
+ }
355
+ const compactParams = this.generateCompactParams(toolName, toolArgs);
356
+ // Emit running stage for non-streaming tool calls (tool execution about to start)
357
+ this.messageManager.updateToolBlock({
358
+ id: toolId,
359
+ stage: "running",
360
+ name: toolName,
361
+ compactParams,
362
+ parameters: argsString,
363
+ parametersChunk: "",
364
+ });
365
+ try {
366
+ // Execute PreToolUse hooks before tool execution
367
+ const shouldExecuteTool = await this.executePreToolUseHooks(toolName, toolArgs, toolId);
368
+ // If PreToolUse hooks blocked execution, skip tool execution
369
+ if (!shouldExecuteTool) {
370
+ this.logger?.info(`Tool ${toolName} execution blocked by PreToolUse hooks`);
371
+ return; // Skip this tool and return from this map function
226
372
  }
227
- else {
228
- try {
229
- toolArgs = JSON.parse(argsString);
230
- }
231
- catch (parseError) {
232
- // For non-empty but malformed JSON, still throw exception
233
- const errorMessage = `Failed to parse tool arguments: ${argsString}`;
234
- this.logger?.error(errorMessage, parseError);
235
- throw new Error(errorMessage);
236
- }
373
+ // Create tool execution context
374
+ const context = {
375
+ abortSignal: toolAbortController.signal,
376
+ backgroundBashManager: this.backgroundBashManager,
377
+ workdir: this.workdir,
378
+ };
379
+ // Execute tool
380
+ const toolResult = await this.toolManager.execute(functionToolCall.function?.name || "", toolArgs, context);
381
+ // Update message state - tool execution completed
382
+ this.messageManager.updateToolBlock({
383
+ id: toolId,
384
+ parameters: argsString,
385
+ result: toolResult.content ||
386
+ (toolResult.error ? `Error: ${toolResult.error}` : ""),
387
+ success: toolResult.success,
388
+ error: toolResult.error,
389
+ stage: "end",
390
+ name: toolName,
391
+ shortResult: toolResult.shortResult,
392
+ });
393
+ // If tool returns diff information, add diff block
394
+ if (toolResult.success &&
395
+ toolResult.diffResult &&
396
+ toolResult.filePath) {
397
+ this.messageManager.addDiffBlock(toolResult.filePath, toolResult.diffResult);
237
398
  }
238
- // Set tool start execution state
239
- const toolName = functionToolCall.function?.name || "";
240
- const compactParams = this.generateCompactParams(toolName, toolArgs);
399
+ // Execute PostToolUse hooks after successful tool completion
400
+ await this.executePostToolUseHooks(toolId, toolName, toolArgs, toolResult);
401
+ }
402
+ catch (toolError) {
403
+ const errorMessage = toolError instanceof Error
404
+ ? toolError.message
405
+ : String(toolError);
241
406
  this.messageManager.updateToolBlock({
242
407
  id: toolId,
243
408
  parameters: JSON.stringify(toolArgs, null, 2),
244
- isRunning: true, // isRunning: true
409
+ result: `Tool execution failed: ${errorMessage}`,
410
+ success: false,
411
+ error: errorMessage,
412
+ stage: "end",
245
413
  name: toolName,
246
414
  compactParams,
247
415
  });
248
- try {
249
- // Execute PreToolUse hooks before tool execution
250
- const shouldExecuteTool = await this.executePreToolUseHooks(toolName, toolArgs, toolId);
251
- // If PreToolUse hooks blocked execution, skip tool execution
252
- if (!shouldExecuteTool) {
253
- this.logger?.info(`Tool ${toolName} execution blocked by PreToolUse hooks`);
254
- return; // Skip this tool and return from this map function
255
- }
256
- // Create tool execution context
257
- const context = {
258
- abortSignal: toolAbortController.signal,
259
- backgroundBashManager: this.backgroundBashManager,
260
- workdir: this.workdir,
261
- };
262
- // Execute tool
263
- const toolResult = await this.toolManager.execute(functionToolCall.function?.name || "", toolArgs, context);
264
- // Update message state - tool execution completed
265
- this.messageManager.updateToolBlock({
266
- id: toolId,
267
- parameters: JSON.stringify(toolArgs, null, 2),
268
- result: toolResult.content ||
269
- (toolResult.error ? `Error: ${toolResult.error}` : ""),
270
- success: toolResult.success,
271
- error: toolResult.error,
272
- isRunning: false, // isRunning: false
273
- name: toolName,
274
- shortResult: toolResult.shortResult,
275
- compactParams,
276
- });
277
- // If tool returns diff information, add diff block
278
- if (toolResult.success &&
279
- toolResult.diffResult &&
280
- toolResult.filePath) {
281
- this.messageManager.addDiffBlock(toolResult.filePath, toolResult.diffResult);
282
- }
283
- // Execute PostToolUse hooks after successful tool completion
284
- await this.executePostToolUseHooks(toolId, toolName, toolArgs, toolResult);
285
- }
286
- catch (toolError) {
287
- const errorMessage = toolError instanceof Error
288
- ? toolError.message
289
- : String(toolError);
290
- this.messageManager.updateToolBlock({
291
- id: toolId,
292
- parameters: JSON.stringify(toolArgs, null, 2),
293
- result: `Tool execution failed: ${errorMessage}`,
294
- success: false,
295
- error: errorMessage,
296
- isRunning: false,
297
- name: toolName,
298
- compactParams,
299
- });
300
- }
301
- }
302
- catch (parseError) {
303
- const errorMessage = parseError instanceof Error
304
- ? parseError.message
305
- : String(parseError);
306
- this.messageManager.addErrorBlock(`Failed to parse tool arguments for ${functionToolCall.function?.name}: ${errorMessage}`);
307
416
  }
308
417
  });
309
418
  // Wait for all tools to complete execution in parallel
@@ -329,66 +438,70 @@ export class AIManager {
329
438
  this.messageManager.addErrorBlock(error instanceof Error ? error.message : "Unknown error occurred");
330
439
  }
331
440
  finally {
332
- // Only execute Stop hooks for the initial call
441
+ // Only execute cleanup and hooks for the initial call
333
442
  if (recursionDepth === 0) {
334
- // Execute Stop hooks only if the operation was not aborted
443
+ // Save session in each recursion to ensure message persistence
444
+ await this.messageManager.saveSession();
445
+ // Set loading to false first
446
+ this.setIsLoading(false);
447
+ // Clear abort controllers
448
+ this.abortController = null;
449
+ this.toolAbortController = null;
450
+ // Execute Stop/SubagentStop hooks only if the operation was not aborted
335
451
  const isCurrentlyAborted = abortController.signal.aborted || toolAbortController.signal.aborted;
336
452
  if (!isCurrentlyAborted) {
337
453
  const shouldContinue = await this.executeStopHooks();
338
- // If Stop hooks indicate we should continue (due to blocking errors),
454
+ // If Stop/SubagentStop hooks indicate we should continue (due to blocking errors),
339
455
  // restart the AI conversation cycle
340
456
  if (shouldContinue) {
341
- this.logger?.info("Stop hooks indicate issues need fixing, continuing conversation...");
457
+ this.logger?.info(`${this.subagentType ? "SubagentStop" : "Stop"} hooks indicate issues need fixing, continuing conversation...`);
342
458
  // Restart the conversation to let AI fix the issues
343
- // Use recursionDepth = 1 to prevent Stop hooks from running again in continuation
459
+ // Use recursionDepth = 0 to set loading false again for continuation
344
460
  await this.sendAIMessage({
345
- recursionDepth: 1,
461
+ recursionDepth: 0,
346
462
  model,
347
463
  allowedTools,
348
464
  });
349
465
  }
350
466
  }
351
- // Save session after all operations (including continuation) are complete
352
- await this.messageManager.saveSession();
353
- // Clear abort controllers and loading state after all operations are complete
354
- this.abortController = null;
355
- this.toolAbortController = null;
356
- // Set loading to false at the very end, after all operations including continuation
357
- this.setIsLoading(false);
358
467
  }
359
468
  }
360
469
  }
361
470
  /**
362
- * Execute Stop hooks when AI response cycle completes
471
+ * Execute Stop or SubagentStop hooks when AI response cycle completes
472
+ * Uses "SubagentStop" hook name when triggered by a subagent, otherwise uses "Stop"
363
473
  * @returns Promise<boolean> - true if should continue conversation, false if should stop
364
474
  */
365
475
  async executeStopHooks() {
366
476
  if (!this.hookManager)
367
477
  return false;
368
478
  try {
479
+ // Use "SubagentStop" hook name when triggered by a subagent, otherwise use "Stop"
480
+ const hookName = this.subagentType ? "SubagentStop" : "Stop";
369
481
  const context = {
370
- event: "Stop",
482
+ event: hookName,
371
483
  projectDir: this.workdir,
372
484
  timestamp: new Date(),
373
485
  sessionId: this.messageManager.getSessionId(),
374
486
  transcriptPath: this.messageManager.getTranscriptPath(),
375
487
  cwd: this.workdir,
488
+ subagentType: this.subagentType, // Include subagent type in hook context
376
489
  // Stop hooks don't need toolName, toolInput, toolResponse, or userPrompt
377
490
  };
378
- const results = await this.hookManager.executeHooks("Stop", context);
491
+ const results = await this.hookManager.executeHooks(hookName, context);
379
492
  // Process hook results to handle exit codes and appropriate responses
380
493
  let shouldContinue = false;
381
494
  if (results.length > 0) {
382
- const processResult = this.hookManager.processHookResults("Stop", results, this.messageManager);
495
+ const processResult = this.hookManager.processHookResults(hookName, results, this.messageManager);
383
496
  // If hook processing indicates we should block (exit code 2), continue conversation
384
497
  if (processResult.shouldBlock) {
385
- this.logger?.info("Stop hook blocked stopping with error:", processResult.errorMessage);
498
+ this.logger?.info(`${hookName} hook blocked stopping with error:`, processResult.errorMessage);
386
499
  shouldContinue = true;
387
500
  }
388
501
  }
389
502
  // Log hook execution results for debugging
390
503
  if (results.length > 0) {
391
- this.logger?.debug(`Executed ${results.length} Stop hook(s):`, results.map((r) => ({
504
+ this.logger?.debug(`Executed ${results.length} ${hookName} hook(s):`, results.map((r) => ({
392
505
  success: r.success,
393
506
  duration: r.duration,
394
507
  exitCode: r.exitCode,
@@ -400,7 +513,7 @@ export class AIManager {
400
513
  }
401
514
  catch (error) {
402
515
  // Hook execution errors should not interrupt the main workflow
403
- this.logger?.error("Stop hook execution failed:", error);
516
+ this.logger?.error(`${this.subagentType ? "SubagentStop" : "Stop"} hook execution failed:`, error);
404
517
  return false;
405
518
  }
406
519
  }
@@ -421,6 +534,7 @@ export class AIManager {
421
534
  transcriptPath: this.messageManager.getTranscriptPath(),
422
535
  cwd: this.workdir,
423
536
  toolInput,
537
+ subagentType: this.subagentType, // Include subagent type in hook context
424
538
  };
425
539
  const results = await this.hookManager.executeHooks("PreToolUse", context);
426
540
  // Process hook results to handle exit codes and determine if tool should be blocked
@@ -465,6 +579,7 @@ export class AIManager {
465
579
  cwd: this.workdir,
466
580
  toolInput,
467
581
  toolResponse,
582
+ subagentType: this.subagentType, // Include subagent type in hook context
468
583
  };
469
584
  const results = await this.hookManager.executeHooks("PostToolUse", context);
470
585
  // Process hook results to handle exit codes and update tool results
@@ -1 +1 @@
1
- {"version":3,"file":"backgroundBashManager.d.ts","sourceRoot":"","sources":["../../src/managers/backgroundBashManager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,WAAW,8BAA8B;IAC7C,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,8BAA8B,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,4BAA4B;IAKjD,OAAO,CAAC,kBAAkB;IAInB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IAsErD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIjD,YAAY,IAAI,eAAe,EAAE;IAIjC,SAAS,CACd,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,MAAM,GACd;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAiCrD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAmD9B,OAAO,IAAI,IAAI;CAUvB"}
1
+ {"version":3,"file":"backgroundBashManager.d.ts","sourceRoot":"","sources":["../../src/managers/backgroundBashManager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,WAAW,8BAA8B;IAC7C,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,8BAA8B,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,4BAA4B;IAKjD,OAAO,CAAC,kBAAkB;IAInB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IAsErD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIjD,YAAY,IAAI,eAAe,EAAE;IAIjC,SAAS,CACd,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,MAAM,GACd;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAiCrD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAmD9B,OAAO,IAAI,IAAI;CAUvB"}
@@ -1,4 +1,5 @@
1
1
  import { spawn } from "child_process";
2
+ import { logger } from "../utils/globalLogger.js";
2
3
  export class BackgroundBashManager {
3
4
  constructor(options) {
4
5
  this.shells = new Map();
@@ -95,8 +96,8 @@ export class BackgroundBashManager {
95
96
  .filter((line) => regex.test(line))
96
97
  .join("\n");
97
98
  }
98
- catch {
99
- // logger.warn(`Invalid filter regex: ${filter}`, error);
99
+ catch (error) {
100
+ logger.warn(`Invalid filter regex: ${filter}`, error);
100
101
  }
101
102
  }
102
103
  return {
@@ -122,8 +123,8 @@ export class BackgroundBashManager {
122
123
  try {
123
124
  process.kill(-shell.process.pid, "SIGKILL");
124
125
  }
125
- catch {
126
- // logger.error("Failed to force kill process:", error);
126
+ catch (error) {
127
+ logger.error("Failed to force kill process:", error);
127
128
  }
128
129
  }
129
130
  }, 1000);
@@ -147,8 +148,8 @@ export class BackgroundBashManager {
147
148
  this.notifyShellsChange();
148
149
  return true;
149
150
  }
150
- catch {
151
- // logger.error("Failed to kill child process:", directKillError);
151
+ catch (directKillError) {
152
+ logger.error("Failed to kill child process:", directKillError);
152
153
  return false;
153
154
  }
154
155
  }
@@ -4,12 +4,13 @@
4
4
  * Central orchestrator for the hooks system. Handles configuration loading,
5
5
  * validation, and hook execution across all supported events.
6
6
  */
7
- import { type HookEvent, type HookConfiguration, type PartialHookConfiguration, type HookExecutionContext, type ExtendedHookExecutionContext, type HookExecutionResult, type ValidationResult } from "../types/hooks.js";
7
+ import { type HookEvent, type WaveConfiguration, type PartialHookConfiguration, type HookExecutionContext, type ExtendedHookExecutionContext, type HookExecutionResult, type ValidationResult } from "../types/hooks.js";
8
8
  import { HookMatcher } from "../utils/hookMatcher.js";
9
9
  import type { Logger } from "../types/index.js";
10
10
  import type { MessageManager } from "./messageManager.js";
11
11
  export declare class HookManager {
12
12
  private configuration;
13
+ private environmentVars;
13
14
  private readonly matcher;
14
15
  private readonly logger?;
15
16
  private readonly workdir;
@@ -21,7 +22,7 @@ export declare class HookManager {
21
22
  loadConfiguration(userHooks?: PartialHookConfiguration, projectHooks?: PartialHookConfiguration): void;
22
23
  /**
23
24
  * Load configuration from filesystem settings
24
- * Automatically loads and merges user and project hooks configuration
25
+ * Automatically loads and merges user and project Wave configuration (hooks + environment)
25
26
  */
26
27
  loadConfigurationFromSettings(): void;
27
28
  /**
@@ -53,9 +54,9 @@ export declare class HookManager {
53
54
  */
54
55
  hasHooks(event: HookEvent, toolName?: string): boolean;
55
56
  /**
56
- * Validate hook configuration structure and content
57
+ * Validate Wave configuration structure and content
57
58
  */
58
- validateConfiguration(config: HookConfiguration): ValidationResult;
59
+ validateConfiguration(config: WaveConfiguration): ValidationResult;
59
60
  /**
60
61
  * Validate partial hook configuration structure and content
61
62
  */
@@ -64,6 +65,10 @@ export declare class HookManager {
64
65
  * Get current configuration
65
66
  */
66
67
  getConfiguration(): PartialHookConfiguration | undefined;
68
+ /**
69
+ * Get current environment variables
70
+ */
71
+ getEnvironmentVars(): Record<string, string> | undefined;
67
72
  /**
68
73
  * Clear current configuration
69
74
  */
@@ -1 +1 @@
1
- {"version":3,"file":"hookManager.d.ts","sourceRoot":"","sources":["../../src/managers/hookManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAItB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,qBAAa,WAAW;IACtB,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAA+B,EACxC,MAAM,CAAC,EAAE,MAAM;IAOjB;;;OAGG;IACH,iBAAiB,CACf,SAAS,CAAC,EAAE,wBAAwB,EACpC,YAAY,CAAC,EAAE,wBAAwB,GACtC,IAAI;IAyBP;;;OAGG;IACH,6BAA6B,IAAI,IAAI;IAqCrC;;OAEG;IACG,YAAY,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,GAC3D,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAqHjC;;;OAGG;IACH,kBAAkB,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,mBAAmB,EAAE,EAC9B,cAAc,CAAC,EAAE,cAAc,EAC/B,MAAM,CAAC,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,GACtB;QACD,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IAuCD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAwD3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAWtD;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,GAAG,gBAAgB;IA8ClE;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAyCpC;;OAEG;IACH,gBAAgB,IAAI,wBAAwB,GAAG,SAAS;IAOxD;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAmDhC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAa/B;;OAEG;IACH,OAAO,CAAC,aAAa;IA4BrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAqC3B;;OAEG;IACH,qBAAqB,IAAI;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KAC3C;CA2CF"}
1
+ {"version":3,"file":"hookManager.d.ts","sourceRoot":"","sources":["../../src/managers/hookManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAItB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,qBAAa,WAAW;IACtB,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAA+B,EACxC,MAAM,CAAC,EAAE,MAAM;IAOjB;;;OAGG;IACH,iBAAiB,CACf,SAAS,CAAC,EAAE,wBAAwB,EACpC,YAAY,CAAC,EAAE,wBAAwB,GACtC,IAAI;IAyBP;;;OAGG;IACH,6BAA6B,IAAI,IAAI;IA6CrC;;OAEG;IACG,YAAY,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,GAC3D,OAAO,CAAC,mBAAmB,EAAE,CAAC;IA0HjC;;;OAGG;IACH,kBAAkB,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,mBAAmB,EAAE,EAC9B,cAAc,CAAC,EAAE,cAAc,EAC/B,MAAM,CAAC,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,GACtB;QACD,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IAuCD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAyD3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAWtD;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,GAAG,gBAAgB;IA8DlE;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAyCpC;;OAEG;IACH,gBAAgB,IAAI,wBAAwB,GAAG,SAAS;IAOxD;;OAEG;IACH,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAOxD;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAmDhC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAa/B;;OAEG;IACH,OAAO,CAAC,aAAa;IA4BrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAqC3B;;OAEG;IACH,qBAAqB,IAAI;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KAC3C;CA6CF"}