wave-agent-sdk 0.4.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/dist/agent.d.ts +42 -11
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +114 -115
  4. package/dist/constants/prompts.d.ts +18 -14
  5. package/dist/constants/prompts.d.ts.map +1 -1
  6. package/dist/constants/prompts.js +130 -54
  7. package/dist/constants/tools.d.ts +6 -3
  8. package/dist/constants/tools.d.ts.map +1 -1
  9. package/dist/constants/tools.js +6 -3
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +1 -0
  13. package/dist/managers/MemoryRuleManager.js +1 -1
  14. package/dist/managers/aiManager.d.ts +5 -3
  15. package/dist/managers/aiManager.d.ts.map +1 -1
  16. package/dist/managers/aiManager.js +57 -20
  17. package/dist/managers/backgroundBashManager.d.ts.map +1 -1
  18. package/dist/managers/backgroundBashManager.js +1 -0
  19. package/dist/managers/backgroundTaskManager.d.ts +35 -0
  20. package/dist/managers/backgroundTaskManager.d.ts.map +1 -0
  21. package/dist/managers/backgroundTaskManager.js +255 -0
  22. package/dist/managers/foregroundTaskManager.d.ts +9 -0
  23. package/dist/managers/foregroundTaskManager.d.ts.map +1 -0
  24. package/dist/managers/foregroundTaskManager.js +21 -0
  25. package/dist/managers/liveConfigManager.d.ts +1 -1
  26. package/dist/managers/lspManager.d.ts.map +1 -1
  27. package/dist/managers/lspManager.js +3 -1
  28. package/dist/managers/mcpManager.d.ts.map +1 -1
  29. package/dist/managers/messageManager.d.ts +26 -12
  30. package/dist/managers/messageManager.d.ts.map +1 -1
  31. package/dist/managers/messageManager.js +138 -64
  32. package/dist/managers/permissionManager.d.ts.map +1 -1
  33. package/dist/managers/permissionManager.js +26 -22
  34. package/dist/managers/planManager.d.ts +1 -1
  35. package/dist/managers/planManager.d.ts.map +1 -1
  36. package/dist/managers/planManager.js +2 -2
  37. package/dist/managers/pluginManager.d.ts.map +1 -1
  38. package/dist/managers/pluginManager.js +3 -2
  39. package/dist/managers/slashCommandManager.d.ts +6 -0
  40. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  41. package/dist/managers/slashCommandManager.js +8 -2
  42. package/dist/managers/subagentManager.d.ts +15 -2
  43. package/dist/managers/subagentManager.d.ts.map +1 -1
  44. package/dist/managers/subagentManager.js +153 -39
  45. package/dist/managers/toolManager.d.ts +18 -1
  46. package/dist/managers/toolManager.d.ts.map +1 -1
  47. package/dist/managers/toolManager.js +29 -5
  48. package/dist/services/GitService.d.ts.map +1 -1
  49. package/dist/services/GitService.js +6 -2
  50. package/dist/services/MarketplaceService.d.ts +2 -2
  51. package/dist/services/MarketplaceService.d.ts.map +1 -1
  52. package/dist/services/MarketplaceService.js +18 -11
  53. package/dist/services/MemoryRuleService.d.ts +1 -1
  54. package/dist/services/MemoryRuleService.d.ts.map +1 -1
  55. package/dist/services/MemoryRuleService.js +13 -2
  56. package/dist/services/aiService.d.ts +0 -1
  57. package/dist/services/aiService.d.ts.map +1 -1
  58. package/dist/services/aiService.js +4 -140
  59. package/dist/services/memory.d.ts +0 -3
  60. package/dist/services/memory.d.ts.map +1 -1
  61. package/dist/services/memory.js +1 -60
  62. package/dist/services/session.d.ts +15 -1
  63. package/dist/services/session.d.ts.map +1 -1
  64. package/dist/services/session.js +57 -1
  65. package/dist/services/taskManager.d.ts +21 -0
  66. package/dist/services/taskManager.d.ts.map +1 -0
  67. package/dist/services/taskManager.js +158 -0
  68. package/dist/tools/askUserQuestion.d.ts.map +1 -1
  69. package/dist/tools/askUserQuestion.js +39 -25
  70. package/dist/tools/bashTool.d.ts +0 -8
  71. package/dist/tools/bashTool.d.ts.map +1 -1
  72. package/dist/tools/bashTool.js +48 -172
  73. package/dist/tools/editTool.d.ts.map +1 -1
  74. package/dist/tools/editTool.js +8 -6
  75. package/dist/tools/exitPlanMode.d.ts.map +1 -1
  76. package/dist/tools/exitPlanMode.js +25 -1
  77. package/dist/tools/globTool.d.ts.map +1 -1
  78. package/dist/tools/globTool.js +8 -2
  79. package/dist/tools/grepTool.d.ts.map +1 -1
  80. package/dist/tools/grepTool.js +17 -6
  81. package/dist/tools/lsTool.d.ts.map +1 -1
  82. package/dist/tools/lsTool.js +3 -1
  83. package/dist/tools/multiEditTool.d.ts.map +1 -1
  84. package/dist/tools/multiEditTool.js +7 -6
  85. package/dist/tools/readTool.d.ts.map +1 -1
  86. package/dist/tools/readTool.js +16 -1
  87. package/dist/tools/taskManagementTools.d.ts +6 -0
  88. package/dist/tools/taskManagementTools.d.ts.map +1 -0
  89. package/dist/tools/taskManagementTools.js +453 -0
  90. package/dist/tools/taskOutputTool.d.ts +3 -0
  91. package/dist/tools/taskOutputTool.d.ts.map +1 -0
  92. package/dist/tools/taskOutputTool.js +173 -0
  93. package/dist/tools/taskStopTool.d.ts +3 -0
  94. package/dist/tools/taskStopTool.d.ts.map +1 -0
  95. package/dist/tools/taskStopTool.js +71 -0
  96. package/dist/tools/taskTool.d.ts.map +1 -1
  97. package/dist/tools/taskTool.js +110 -63
  98. package/dist/tools/types.d.ts +12 -0
  99. package/dist/tools/types.d.ts.map +1 -1
  100. package/dist/tools/writeTool.d.ts.map +1 -1
  101. package/dist/tools/writeTool.js +9 -1
  102. package/dist/types/index.d.ts +1 -0
  103. package/dist/types/index.d.ts.map +1 -1
  104. package/dist/types/index.js +1 -0
  105. package/dist/types/marketplace.d.ts +1 -0
  106. package/dist/types/marketplace.d.ts.map +1 -1
  107. package/dist/types/messaging.d.ts +3 -8
  108. package/dist/types/messaging.d.ts.map +1 -1
  109. package/dist/types/processes.d.ts +29 -4
  110. package/dist/types/processes.d.ts.map +1 -1
  111. package/dist/types/tasks.d.ts +13 -0
  112. package/dist/types/tasks.d.ts.map +1 -0
  113. package/dist/types/tasks.js +1 -0
  114. package/dist/types/tools.d.ts +4 -1
  115. package/dist/types/tools.d.ts.map +1 -1
  116. package/dist/utils/builtinSubagents.d.ts.map +1 -1
  117. package/dist/utils/builtinSubagents.js +38 -1
  118. package/dist/utils/cacheControlUtils.d.ts.map +1 -1
  119. package/dist/utils/cacheControlUtils.js +18 -12
  120. package/dist/utils/constants.d.ts +0 -4
  121. package/dist/utils/constants.d.ts.map +1 -1
  122. package/dist/utils/constants.js +0 -4
  123. package/dist/utils/convertMessagesForAPI.js +2 -2
  124. package/dist/utils/editUtils.d.ts +2 -11
  125. package/dist/utils/editUtils.d.ts.map +1 -1
  126. package/dist/utils/editUtils.js +52 -79
  127. package/dist/utils/messageOperations.d.ts +5 -36
  128. package/dist/utils/messageOperations.d.ts.map +1 -1
  129. package/dist/utils/messageOperations.js +9 -98
  130. package/dist/utils/nameGenerator.d.ts +1 -1
  131. package/dist/utils/nameGenerator.d.ts.map +1 -1
  132. package/dist/utils/nameGenerator.js +19 -3
  133. package/package.json +5 -5
  134. package/src/agent.ts +157 -134
  135. package/src/constants/prompts.ts +156 -65
  136. package/src/constants/tools.ts +6 -3
  137. package/src/index.ts +1 -0
  138. package/src/managers/MemoryRuleManager.ts +1 -1
  139. package/src/managers/aiManager.ts +77 -35
  140. package/src/managers/backgroundBashManager.ts +1 -0
  141. package/src/managers/backgroundTaskManager.ts +305 -0
  142. package/src/managers/foregroundTaskManager.ts +27 -0
  143. package/src/managers/lspManager.ts +3 -1
  144. package/src/managers/mcpManager.ts +6 -3
  145. package/src/managers/messageManager.ts +185 -75
  146. package/src/managers/permissionManager.ts +33 -28
  147. package/src/managers/planManager.ts +2 -2
  148. package/src/managers/pluginManager.ts +4 -3
  149. package/src/managers/slashCommandManager.ts +15 -2
  150. package/src/managers/subagentManager.ts +194 -35
  151. package/src/managers/toolManager.ts +48 -6
  152. package/src/services/GitService.ts +6 -2
  153. package/src/services/MarketplaceService.ts +30 -12
  154. package/src/services/MemoryRuleService.ts +18 -6
  155. package/src/services/aiService.ts +3 -145
  156. package/src/services/memory.ts +1 -73
  157. package/src/services/session.ts +73 -0
  158. package/src/services/taskManager.ts +188 -0
  159. package/src/tools/askUserQuestion.ts +51 -29
  160. package/src/tools/bashTool.ts +63 -196
  161. package/src/tools/editTool.ts +9 -18
  162. package/src/tools/exitPlanMode.ts +26 -2
  163. package/src/tools/globTool.ts +10 -2
  164. package/src/tools/grepTool.ts +17 -6
  165. package/src/tools/lsTool.ts +3 -1
  166. package/src/tools/multiEditTool.ts +7 -18
  167. package/src/tools/readTool.ts +17 -1
  168. package/src/tools/taskManagementTools.ts +498 -0
  169. package/src/tools/taskOutputTool.ts +196 -0
  170. package/src/tools/taskStopTool.ts +78 -0
  171. package/src/tools/taskTool.ts +136 -74
  172. package/src/tools/types.ts +13 -0
  173. package/src/tools/writeTool.ts +9 -2
  174. package/src/types/index.ts +1 -0
  175. package/src/types/marketplace.ts +1 -0
  176. package/src/types/messaging.ts +2 -9
  177. package/src/types/processes.ts +39 -4
  178. package/src/types/tasks.ts +13 -0
  179. package/src/types/tools.ts +4 -1
  180. package/src/utils/builtinSubagents.ts +47 -1
  181. package/src/utils/cacheControlUtils.ts +26 -18
  182. package/src/utils/constants.ts +0 -5
  183. package/src/utils/convertMessagesForAPI.ts +2 -2
  184. package/src/utils/editUtils.ts +65 -103
  185. package/src/utils/messageOperations.ts +12 -136
  186. package/src/utils/nameGenerator.ts +20 -3
  187. package/dist/tools/todoWriteTool.d.ts +0 -6
  188. package/dist/tools/todoWriteTool.d.ts.map +0 -1
  189. package/dist/tools/todoWriteTool.js +0 -220
  190. package/src/tools/todoWriteTool.ts +0 -257
@@ -1,4 +1,4 @@
1
- import { addAssistantMessageToMessages, updateToolBlockInMessage, addErrorBlockToMessage, addUserMessageToMessages, extractUserInputHistory, addCommandOutputMessage, updateCommandOutputInMessage, completeCommandInMessage, addSubagentBlockToMessage, updateSubagentBlockInMessage, removeLastUserMessage, } from "../utils/messageOperations.js";
1
+ import { addAssistantMessageToMessages, updateToolBlockInMessage, addErrorBlockToMessage, addUserMessageToMessages, addCommandOutputMessage, updateCommandOutputInMessage, completeCommandInMessage, addSubagentBlockToMessage, updateSubagentBlockInMessage, removeLastUserMessage, } from "../utils/messageOperations.js";
2
2
  import { join } from "path";
3
3
  import { appendMessages, createSession, generateSessionId, SESSION_DIR, } from "../services/session.js";
4
4
  import { pathEncoder } from "../utils/pathEncoder.js";
@@ -6,9 +6,9 @@ export class MessageManager {
6
6
  constructor(options) {
7
7
  this.filesInContext = new Set(); // Track files mentioned in the conversation
8
8
  this.sessionId = generateSessionId();
9
+ this.rootSessionId = this.sessionId;
9
10
  this.messages = [];
10
11
  this.latestTotalTokens = 0;
11
- this.userInputHistory = [];
12
12
  this.workdir = options.workdir;
13
13
  this.encodedWorkdir = pathEncoder.encodeSync(this.workdir); // Cache encoded workdir
14
14
  this.callbacks = options.callbacks;
@@ -16,6 +16,7 @@ export class MessageManager {
16
16
  this.savedMessageCount = 0; // Initialize saved message count tracker
17
17
  this.sessionType = options.sessionType || "main";
18
18
  this.subagentType = options.subagentType;
19
+ this.memoryRuleManager = options.memoryRuleManager;
19
20
  // Compute and cache the transcript path
20
21
  this.transcriptPath = this.computeTranscriptPath();
21
22
  }
@@ -23,15 +24,18 @@ export class MessageManager {
23
24
  getSessionId() {
24
25
  return this.sessionId;
25
26
  }
27
+ getRootSessionId() {
28
+ return this.rootSessionId;
29
+ }
30
+ getParentSessionId() {
31
+ return this.parentSessionId;
32
+ }
26
33
  getMessages() {
27
34
  return [...this.messages];
28
35
  }
29
36
  getlatestTotalTokens() {
30
37
  return this.latestTotalTokens;
31
38
  }
32
- getUserInputHistory() {
33
- return [...this.userInputHistory];
34
- }
35
39
  getWorkdir() {
36
40
  return this.workdir;
37
41
  }
@@ -47,6 +51,25 @@ export class MessageManager {
47
51
  getTranscriptPath() {
48
52
  return this.transcriptPath;
49
53
  }
54
+ /**
55
+ * Get combined memory content (project memory + user memory + modular rules)
56
+ */
57
+ async getCombinedMemory() {
58
+ const memory = await import("../services/memory.js");
59
+ let combined = await memory.getCombinedMemoryContent(this.workdir);
60
+ if (this.memoryRuleManager) {
61
+ const filesInContext = this.getFilesInContext();
62
+ const activeRules = this.memoryRuleManager.getActiveRules(filesInContext);
63
+ if (activeRules.length > 0) {
64
+ this.logger?.debug(`Active modular rules (${activeRules.length}): ${activeRules.map((r) => r.id).join(", ")}`);
65
+ if (combined) {
66
+ combined += "\n\n";
67
+ }
68
+ combined += activeRules.map((r) => r.content).join("\n\n");
69
+ }
70
+ }
71
+ return combined;
72
+ }
50
73
  /**
51
74
  * Compute the transcript path using cached encoded workdir
52
75
  * Called during construction and when sessionId changes
@@ -102,7 +125,7 @@ export class MessageManager {
102
125
  }
103
126
  // Use JSONL format for new sessions
104
127
  await appendMessages(this.sessionId, unsavedMessages, // Only append new messages
105
- this.workdir, this.sessionType);
128
+ this.workdir, this.sessionType, this.rootSessionId, this.parentSessionId);
106
129
  // Update the saved message count
107
130
  this.savedMessageCount = this.messages.length;
108
131
  }
@@ -116,17 +139,13 @@ export class MessageManager {
116
139
  this.callbacks.onLatestTotalTokensChange?.(latestTotalTokens);
117
140
  }
118
141
  }
119
- setUserInputHistory(userInputHistory) {
120
- this.userInputHistory = [...userInputHistory];
121
- this.callbacks.onUserInputHistoryChange?.(this.userInputHistory);
122
- }
123
142
  /**
124
- * Clear messages and input history
143
+ * Clear messages
125
144
  */
126
145
  clearMessages() {
127
146
  this.setMessages([]);
128
- this.setUserInputHistory([]);
129
147
  this.setSessionId(generateSessionId());
148
+ this.rootSessionId = this.sessionId;
130
149
  this.setlatestTotalTokens(0);
131
150
  this.savedMessageCount = 0; // Reset saved message count
132
151
  }
@@ -145,29 +164,15 @@ export class MessageManager {
145
164
  // Initialize state from session data
146
165
  initializeFromSession(sessionData) {
147
166
  this.setSessionId(sessionData.id);
167
+ this.rootSessionId = sessionData.rootSessionId || sessionData.id;
168
+ this.parentSessionId = sessionData.parentSessionId;
148
169
  this.setMessages([...sessionData.messages]);
149
170
  this.updateFilesInContext(sessionData.messages);
150
171
  this.setlatestTotalTokens(sessionData.metadata.latestTotalTokens);
151
- // Extract user input history from session messages
152
- this.setUserInputHistory(extractUserInputHistory(sessionData.messages));
153
172
  // Set saved message count to the number of loaded messages since they're already saved
154
173
  // This must be done after setSessionId which resets it to 0
155
174
  this.savedMessageCount = sessionData.messages.length;
156
175
  }
157
- // Add to input history
158
- addToInputHistory(input) {
159
- // Avoid adding duplicate inputs
160
- if (this.userInputHistory.length > 0 &&
161
- this.userInputHistory[this.userInputHistory.length - 1] === input) {
162
- return;
163
- }
164
- // Limit history records, keep the latest 100
165
- this.setUserInputHistory([...this.userInputHistory, input].slice(-100));
166
- }
167
- // Clear input history
168
- clearInputHistory() {
169
- this.setUserInputHistory([]);
170
- }
171
176
  // Encapsulated message operation functions
172
177
  addUserMessage(params) {
173
178
  const newMessages = addUserMessageToMessages({
@@ -216,17 +221,7 @@ export class MessageManager {
216
221
  updateToolBlock(params) {
217
222
  const newMessages = updateToolBlockInMessage({
218
223
  messages: this.messages,
219
- id: params.id,
220
- parameters: params.parameters,
221
- result: params.result,
222
- success: params.success,
223
- error: params.error,
224
- stage: params.stage,
225
- name: params.name,
226
- shortResult: params.shortResult,
227
- images: params.images,
228
- compactParams: params.compactParams,
229
- parametersChunk: params.parametersChunk,
224
+ ...params,
230
225
  });
231
226
  this.setMessages(newMessages);
232
227
  this.callbacks.onToolBlockUpdated?.(params);
@@ -240,11 +235,23 @@ export class MessageManager {
240
235
  this.setMessages(newMessages);
241
236
  this.callbacks.onErrorBlockAdded?.(error);
242
237
  }
238
+ addInfoBlock(content) {
239
+ const lastMessage = this.messages[this.messages.length - 1];
240
+ if (lastMessage && lastMessage.role === "assistant") {
241
+ lastMessage.blocks.push({
242
+ type: "info",
243
+ content,
244
+ });
245
+ this.setMessages([...this.messages]);
246
+ this.callbacks.onInfoBlockAdded?.(content);
247
+ }
248
+ }
243
249
  /**
244
- * Compress messages and update session, delete compressed messages, only keep compressed messages and subsequent messages
250
+ * Compress messages and update session, delete compressed messages, only keep compressed messages and last 3 messages
245
251
  */
246
- compressMessagesAndUpdateSession(insertIndex, compressedContent, usage) {
247
- const currentMessages = this.messages;
252
+ compressMessagesAndUpdateSession(compressedContent, usage) {
253
+ // Get last 3 messages to preserve
254
+ const lastThreeMessages = this.messages.slice(-3);
248
255
  // Create compressed message
249
256
  const compressMessage = {
250
257
  role: "assistant",
@@ -257,19 +264,20 @@ export class MessageManager {
257
264
  ],
258
265
  ...(usage && { usage }),
259
266
  };
260
- // Convert negative index to positive index
261
- const actualIndex = insertIndex < 0 ? currentMessages.length + insertIndex : insertIndex;
262
- // Build new message array: keep compressed message and all messages from actualIndex onwards
263
- const newMessages = [
264
- compressMessage,
265
- ...currentMessages.slice(actualIndex),
266
- ];
267
- // Update sessionId
267
+ // Build new message array: keep the compressed message and last 3 messages
268
+ const newMessages = [compressMessage, ...lastThreeMessages];
269
+ // Update sessionId and parentSessionId
270
+ const oldSessionId = this.sessionId;
268
271
  this.setSessionId(generateSessionId());
272
+ this.parentSessionId = oldSessionId;
273
+ // Trigger task list update if this is the main session to ensure continuity
274
+ if (this.sessionType === "main") {
275
+ this.callbacks.onSessionIdChange?.(this.sessionId);
276
+ }
269
277
  // Set new message list
270
278
  this.setMessages(newMessages);
271
- // Trigger compression callback, insertIndex remains unchanged
272
- this.callbacks.onCompressBlockAdded?.(insertIndex, compressedContent);
279
+ // Trigger compression callback
280
+ this.callbacks.onCompressBlockAdded?.(compressedContent);
273
281
  }
274
282
  addFileHistoryBlock(snapshots) {
275
283
  if (snapshots.length === 0)
@@ -281,6 +289,7 @@ export class MessageManager {
281
289
  snapshots,
282
290
  });
283
291
  this.setMessages([...this.messages]);
292
+ this.callbacks.onFileHistoryBlockAdded?.(snapshots);
284
293
  }
285
294
  }
286
295
  // Bash command related message operations
@@ -311,7 +320,7 @@ export class MessageManager {
311
320
  this.callbacks.onCompleteCommandMessage?.(command, exitCode);
312
321
  }
313
322
  // Subagent block methods
314
- addSubagentBlock(subagentId, subagentName, sessionId, configuration, status = "active", parameters) {
323
+ addSubagentBlock(subagentId, subagentName, sessionId, configuration, status = "active", parameters, runInBackground) {
315
324
  const params = {
316
325
  messages: this.messages,
317
326
  subagentId,
@@ -319,6 +328,7 @@ export class MessageManager {
319
328
  sessionId,
320
329
  status,
321
330
  configuration,
331
+ runInBackground,
322
332
  };
323
333
  const updatedMessages = addSubagentBlockToMessage(params);
324
334
  this.setMessages(updatedMessages);
@@ -332,7 +342,9 @@ export class MessageManager {
332
342
  subagentId,
333
343
  status: updates.status || "active",
334
344
  };
335
- this.callbacks.onSubAgentBlockUpdated?.(params.subagentId, params.status);
345
+ if (updates.status) {
346
+ this.callbacks.onSubAgentBlockUpdated?.(params.subagentId, params.status);
347
+ }
336
348
  }
337
349
  /**
338
350
  * Trigger usage change callback with all usage data from assistant messages
@@ -426,31 +438,93 @@ export class MessageManager {
426
438
  const newMessages = removeLastUserMessage(this.messages);
427
439
  this.setMessages(newMessages);
428
440
  }
441
+ async getFullMessageThread() {
442
+ const { loadFullMessageThread } = await import("../services/session.js");
443
+ return loadFullMessageThread(this.sessionId, this.workdir);
444
+ }
429
445
  /**
430
446
  * Truncate history to a specific index and revert file changes.
431
447
  * @param index - The index of the user message to truncate to.
432
448
  * @param reversionManager - Optional ReversionManager to handle file rollbacks.
433
449
  */
434
450
  async truncateHistory(index, reversionManager) {
435
- if (index < 0 || index >= this.messages.length) {
451
+ const { messages, sessionIds } = await this.getFullMessageThread();
452
+ if (index < 0 || index >= messages.length) {
436
453
  throw new Error(`Invalid message index: ${index}`);
437
454
  }
438
- // Identify messages to be removed
439
- const messagesToRemove = this.messages.slice(index);
455
+ // Find which session the index belongs to
456
+ let targetSessionId = this.sessionId;
457
+ let targetIndexInSession = index;
458
+ // We need to be careful here because loadFullMessageThread might have removed "compress" blocks
459
+ // Let's re-calculate based on the actual messages returned.
460
+ // Actually, it's easier to just load sessions one by one again or keep track of counts.
461
+ // For simplicity, let's assume we want to truncate the WHOLE thread.
462
+ // If the index is in a previous session, we need to:
463
+ // 1. Load that session.
464
+ // 2. Truncate it.
465
+ // 3. Make it the current session.
466
+ // 4. Delete/Invalidate subsequent sessions.
467
+ // To correctly map 'index' to a session, we need to know the message count of each session
468
+ // as they appear in the concatenated 'messages' array.
469
+ let remainingIndex = index;
470
+ const { loadSessionFromJsonl } = await import("../services/session.js");
471
+ for (const sid of sessionIds) {
472
+ const sessionData = await loadSessionFromJsonl(sid, this.workdir);
473
+ if (!sessionData)
474
+ continue;
475
+ const sessionMessages = sessionData.messages;
476
+ // If this is not the first session in the thread, it might have a compress block at the start
477
+ // that was removed in getFullMessageThread.
478
+ const hasCompressBlock = sessionMessages[0]?.blocks.some((b) => b.type === "compress");
479
+ const effectiveMessages = hasCompressBlock && sid !== sessionIds[0]
480
+ ? sessionMessages.slice(1)
481
+ : sessionMessages;
482
+ if (remainingIndex < effectiveMessages.length) {
483
+ targetSessionId = sid;
484
+ targetIndexInSession = hasCompressBlock
485
+ ? remainingIndex + 1
486
+ : remainingIndex;
487
+ break;
488
+ }
489
+ remainingIndex -= effectiveMessages.length;
490
+ }
491
+ // Load the target session to perform truncation
492
+ const targetSessionData = await loadSessionFromJsonl(targetSessionId, this.workdir);
493
+ if (!targetSessionData)
494
+ throw new Error(`Target session ${targetSessionId} not found`);
495
+ // Identify messages to be removed (from the whole thread)
496
+ const messagesToRemove = messages.slice(index);
440
497
  const messageIdsToRemove = messagesToRemove
441
498
  .map((m) => m.id)
442
499
  .filter((id) => !!id);
443
500
  // Revert file changes if manager is provided
444
501
  if (reversionManager && messageIdsToRemove.length > 0) {
445
- await reversionManager.revertTo(messageIdsToRemove, this.messages);
502
+ await reversionManager.revertTo(messageIdsToRemove, messages);
446
503
  }
447
- // Truncate messages in memory
448
- const newMessages = this.messages.slice(0, index);
449
- this.setMessages(newMessages);
450
- // Update persistence: rewrite the session file
451
- await this.rewriteSessionFile(newMessages);
504
+ // Truncate messages in the target session
505
+ const newMessagesInSession = targetSessionData.messages.slice(0, targetIndexInSession);
506
+ // Identify subagent tasks to stop
507
+ for (const message of messagesToRemove) {
508
+ for (const block of message.blocks) {
509
+ if (block.type === "subagent" && block.subagentId) {
510
+ this.callbacks.onSubagentTaskStopRequested?.(block.subagentId);
511
+ }
512
+ }
513
+ }
514
+ // Update target session file
515
+ this.sessionId = targetSessionId;
516
+ this.rootSessionId = targetSessionData.rootSessionId || targetSessionId;
517
+ this.parentSessionId = targetSessionData.parentSessionId;
518
+ this.transcriptPath = this.computeTranscriptPath();
519
+ await this.rewriteSessionFile(newMessagesInSession);
520
+ // Update in-memory messages to the truncated session messages
521
+ // We do NOT include ancestor messages here to avoid exceeding context limits.
522
+ // The 'compress' block at the start of the session (if any) already summarizes them.
523
+ this.setMessages(newMessagesInSession);
452
524
  // Update saved message count
453
- this.savedMessageCount = newMessages.length;
525
+ this.savedMessageCount = newMessagesInSession.length;
526
+ // Notify session ID change if it changed
527
+ this.callbacks.onSessionIdChange?.(this.sessionId);
454
528
  }
455
529
  /**
456
530
  * Rewrite the session file with the current messages.
@@ -1 +1 @@
1
- {"version":3,"file":"permissionManager.d.ts","sourceRoot":"","sources":["../../src/managers/permissionManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"permissionManager.d.ts","sourceRoot":"","sources":["../../src/managers/permissionManager.ts"],"names":[],"mappings":"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"}
@@ -159,13 +159,7 @@ export class PermissionManager {
159
159
  * Get the current effective permission mode for tool execution context
160
160
  */
161
161
  getCurrentEffectiveMode(cliPermissionMode) {
162
- const mode = this.resolveEffectivePermissionMode(cliPermissionMode);
163
- this.logger?.debug("getCurrentEffectiveMode", {
164
- cliPermissionMode,
165
- configuredDefaultMode: this.configuredDefaultMode,
166
- resolvedMode: mode,
167
- });
168
- return mode;
162
+ return this.resolveEffectivePermissionMode(cliPermissionMode);
169
163
  }
170
164
  /**
171
165
  * Resolve the effective permission mode based on CLI override and configured default
@@ -236,31 +230,24 @@ export class PermissionManager {
236
230
  if (targetPath) {
237
231
  const { isInside, resolvedPath } = this.isInsideSafeZone(targetPath, workdir);
238
232
  if (!isInside) {
239
- this.logger?.warn("File operation outside the Safe Zone in acceptEdits mode", {
233
+ this.logger?.info("File operation outside the Safe Zone in acceptEdits mode, falling back to manual confirmation", {
240
234
  toolName: context.toolName,
241
235
  targetPath,
242
236
  resolvedPath,
243
237
  });
244
- return {
245
- behavior: "deny",
246
- message: `Tool '${context.toolName}' attempted to modify a file outside the Safe Zone: ${targetPath}. Operations outside the Safe Zone always require manual confirmation.`,
247
- };
238
+ // Fall through to normal permission check flow to trigger confirmation prompt
239
+ }
240
+ else {
241
+ this.logger?.debug("Permission automatically accepted for tool in acceptEdits mode", {
242
+ toolName: context.toolName,
243
+ });
244
+ return { behavior: "allow" };
248
245
  }
249
246
  }
250
- this.logger?.debug("Permission automatically accepted for tool in acceptEdits mode", {
251
- toolName: context.toolName,
252
- });
253
- return { behavior: "allow" };
254
247
  }
255
248
  }
256
249
  // 1.3 If plan mode, allow Read-only tools and Edit/Write for plan file
257
250
  if (context.permissionMode === "plan") {
258
- if (context.toolName === BASH_TOOL_NAME) {
259
- return {
260
- behavior: "deny",
261
- message: "Bash commands are not allowed in plan mode.",
262
- };
263
- }
264
251
  const writeTools = [
265
252
  EDIT_TOOL_NAME,
266
253
  MULTI_EDIT_TOOL_NAME,
@@ -374,6 +361,23 @@ export class PermissionManager {
374
361
  toolInput,
375
362
  suggestedPrefix,
376
363
  };
364
+ // Set hidePersistentOption for out-of-bounds file operations
365
+ const fileTools = [
366
+ EDIT_TOOL_NAME,
367
+ MULTI_EDIT_TOOL_NAME,
368
+ DELETE_FILE_TOOL_NAME,
369
+ WRITE_TOOL_NAME,
370
+ ];
371
+ if (fileTools.includes(toolName)) {
372
+ const targetPath = (toolInput?.file_path || toolInput?.target_file);
373
+ const workdir = toolInput?.workdir;
374
+ if (targetPath) {
375
+ const { isInside } = this.isInsideSafeZone(targetPath, workdir);
376
+ if (!isInside) {
377
+ context.hidePersistentOption = true;
378
+ }
379
+ }
380
+ }
377
381
  // Set hidePersistentOption for dangerous or out-of-bounds bash commands
378
382
  if (toolName === BASH_TOOL_NAME && toolInput?.command) {
379
383
  const command = String(toolInput.command);
@@ -9,7 +9,7 @@ export declare class PlanManager {
9
9
  /**
10
10
  * Ensures the plan directory exists and generates a new plan file path with a random name
11
11
  */
12
- getOrGeneratePlanFilePath(): Promise<{
12
+ getOrGeneratePlanFilePath(seed?: string): Promise<{
13
13
  path: string;
14
14
  name: string;
15
15
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"planManager.d.ts","sourceRoot":"","sources":["../../src/managers/planManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;GAEG;AACH,qBAAa,WAAW;IAGV,OAAO,CAAC,MAAM,CAAC;IAF3B,OAAO,CAAC,OAAO,CAAS;gBAEJ,MAAM,CAAC,EAAE,MAAM,YAAA;IAInC;;OAEG;IACU,yBAAyB,IAAI,OAAO,CAAC;QAChD,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IAgBF;;OAEG;IACI,UAAU,IAAI,MAAM;CAG5B"}
1
+ {"version":3,"file":"planManager.d.ts","sourceRoot":"","sources":["../../src/managers/planManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;GAEG;AACH,qBAAa,WAAW;IAGV,OAAO,CAAC,MAAM,CAAC;IAF3B,OAAO,CAAC,OAAO,CAAS;gBAEJ,MAAM,CAAC,EAAE,MAAM,YAAA;IAInC;;OAEG;IACU,yBAAyB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAC7D,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IAgBF;;OAEG;IACI,UAAU,IAAI,MAAM;CAG5B"}
@@ -13,7 +13,7 @@ export class PlanManager {
13
13
  /**
14
14
  * Ensures the plan directory exists and generates a new plan file path with a random name
15
15
  */
16
- async getOrGeneratePlanFilePath() {
16
+ async getOrGeneratePlanFilePath(seed) {
17
17
  try {
18
18
  await fs.mkdir(this.planDir, { recursive: true });
19
19
  }
@@ -21,7 +21,7 @@ export class PlanManager {
21
21
  this.logger?.error(`Failed to create plan directory: ${this.planDir}`, error);
22
22
  throw error;
23
23
  }
24
- const name = generateRandomName();
24
+ const name = generateRandomName(seed);
25
25
  const filePath = path.join(this.planDir, `${name}.md`);
26
26
  this.logger?.info(`Generated plan file path: ${filePath}`);
27
27
  return { path: filePath, name };
@@ -1 +1 @@
1
- {"version":3,"file":"pluginManager.d.ts","sourceRoot":"","sources":["../../src/managers/pluginManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,mBAAmB,CAAC,CAAsB;IAClD,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,oBAAoB,CAAC,CAAuB;gBAExC,OAAO,EAAE,oBAAoB;IAYzC;;OAEG;IACH,oBAAoB,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAInE;;OAEG;YACW,oBAAoB;IA2BlC;;OAEG;YACW,gBAAgB;IA2D9B;;;OAGG;IACG,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBzD;;OAEG;IACH,UAAU,IAAI,MAAM,EAAE;IAItB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAG5C"}
1
+ {"version":3,"file":"pluginManager.d.ts","sourceRoot":"","sources":["../../src/managers/pluginManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,mBAAmB,CAAC,CAAsB;IAClD,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,oBAAoB,CAAC,CAAuB;gBAExC,OAAO,EAAE,oBAAoB;IAYzC;;OAEG;IACH,oBAAoB,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAInE;;OAEG;YACW,oBAAoB;IA2BlC;;OAEG;YACW,gBAAgB;IA2D9B;;;OAGG;IACG,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBzD;;OAEG;IACH,UAAU,IAAI,MAAM,EAAE;IAItB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAG5C"}
@@ -96,8 +96,7 @@ export class PluginManager {
96
96
  * @param configs Array of plugin configurations
97
97
  */
98
98
  async loadPlugins(configs) {
99
- // Load installed plugins from marketplace first
100
- await this.loadInstalledPlugins();
99
+ // Load plugins from configuration (e.g. --plugin-dir) first to give them higher priority
101
100
  for (const config of configs) {
102
101
  if (config.type !== "local") {
103
102
  this.logger?.warn(`Unsupported plugin type: ${config.type}`);
@@ -108,6 +107,8 @@ export class PluginManager {
108
107
  : path.resolve(this.workdir, config.path);
109
108
  await this.loadSinglePlugin(absolutePath);
110
109
  }
110
+ // Load installed plugins from marketplace
111
+ await this.loadInstalledPlugins();
111
112
  }
112
113
  /**
113
114
  * Get all loaded plugins
@@ -1,9 +1,13 @@
1
1
  import type { MessageManager } from "./messageManager.js";
2
2
  import type { AIManager } from "./aiManager.js";
3
+ import type { BackgroundTaskManager } from "./backgroundTaskManager.js";
4
+ import type { TaskManager } from "../services/taskManager.js";
3
5
  import type { SlashCommand, CustomSlashCommand, Logger } from "../types/index.js";
4
6
  export interface SlashCommandManagerOptions {
5
7
  messageManager: MessageManager;
6
8
  aiManager: AIManager;
9
+ backgroundTaskManager: BackgroundTaskManager;
10
+ taskManager: TaskManager;
7
11
  workdir: string;
8
12
  logger?: Logger;
9
13
  }
@@ -12,6 +16,8 @@ export declare class SlashCommandManager {
12
16
  private customCommands;
13
17
  private messageManager;
14
18
  private aiManager;
19
+ private backgroundTaskManager;
20
+ private taskManager;
15
21
  private workdir;
16
22
  private logger?;
17
23
  constructor(options: SlashCommandManagerOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"slashCommandManager.d.ts","sourceRoot":"","sources":["../../src/managers/slashCommandManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,MAAM,EACP,MAAM,mBAAmB,CAAC;AAmB3B,MAAM,WAAW,0BAA0B;IACzC,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,OAAO,EAAE,0BAA0B;IAU/C,OAAO,CAAC,yBAAyB;IAiCjC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyD1B;;OAEG;IACI,sBAAsB,CAC3B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,kBAAkB,EAAE,GAC7B,IAAI;IAwDP;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAWnC;;OAEG;IACI,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAKnD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACI,WAAW,IAAI,YAAY,EAAE;IAIpC;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI9D;;OAEG;IACU,cAAc,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC;IAenB;;;OAGG;IACI,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG;QAClD,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;IAeD;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI7C;;OAEG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI1E;;OAEG;IACI,iBAAiB,IAAI,kBAAkB,EAAE;IAIhD;;OAEG;YACW,+BAA+B;IA0E7C;;OAEG;IACI,mBAAmB,IAAI,IAAI;CAInC"}
1
+ {"version":3,"file":"slashCommandManager.d.ts","sourceRoot":"","sources":["../../src/managers/slashCommandManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,MAAM,EACP,MAAM,mBAAmB,CAAC;AAmB3B,MAAM,WAAW,0BAA0B;IACzC,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,SAAS,CAAC;IACrB,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,qBAAqB,CAAwB;IACrD,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,OAAO,EAAE,0BAA0B;IAY/C,OAAO,CAAC,yBAAyB;IAsCjC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyD1B;;OAEG;IACI,sBAAsB,CAC3B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,kBAAkB,EAAE,GAC7B,IAAI;IAwDP;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAWnC;;OAEG;IACI,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAKnD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACI,WAAW,IAAI,YAAY,EAAE;IAIpC;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI9D;;OAEG;IACU,cAAc,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC;IAenB;;;OAGG;IACI,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG;QAClD,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;IAeD;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI7C;;OAEG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI1E;;OAEG;IACI,iBAAiB,IAAI,kBAAkB,EAAE;IAIhD;;OAEG;YACW,+BAA+B;IA0E7C;;OAEG;IACI,mBAAmB,IAAI,IAAI;CAInC"}
@@ -11,6 +11,8 @@ export class SlashCommandManager {
11
11
  this.customCommands = new Map();
12
12
  this.messageManager = options.messageManager;
13
13
  this.aiManager = options.aiManager;
14
+ this.backgroundTaskManager = options.backgroundTaskManager;
15
+ this.taskManager = options.taskManager;
14
16
  this.workdir = options.workdir;
15
17
  this.logger = options.logger;
16
18
  this.initializeBuiltinCommands();
@@ -25,8 +27,12 @@ export class SlashCommandManager {
25
27
  handler: () => {
26
28
  // Clear chat messages
27
29
  this.messageManager.clearMessages();
28
- // Clear terminal screen
29
- process.stdout.write("\x1Bc");
30
+ // Reset task list if WAVE_TASK_LIST_ID is not set
31
+ if (!process.env.WAVE_TASK_LIST_ID) {
32
+ const newTaskListId = this.messageManager.getRootSessionId();
33
+ this.taskManager.setTaskListId(newTaskListId);
34
+ this.taskManager.emit("tasksChange", newTaskListId);
35
+ }
30
36
  },
31
37
  });
32
38
  // Register built-in init command
@@ -1,3 +1,4 @@
1
+ import type { MemoryRuleManager } from "./MemoryRuleManager.js";
1
2
  import type { SubagentConfiguration } from "../utils/subagentParser.js";
2
3
  import type { Message, Logger, GatewayConfig, ModelConfig, Usage } from "../types/index.js";
3
4
  import type { SessionData } from "../services/session.js";
@@ -6,6 +7,7 @@ import { MessageManager } from "./messageManager.js";
6
7
  import { ToolManager } from "./toolManager.js";
7
8
  import { HookManager } from "./hookManager.js";
8
9
  import { UserMessageParams, type AgentToolBlockUpdateParams } from "../utils/messageOperations.js";
10
+ import { BackgroundTaskManager } from "./backgroundTaskManager.js";
9
11
  export interface SubagentManagerCallbacks {
10
12
  /** Triggered when subagent adds user message */
11
13
  onSubagentUserMessageAdded?: (subagentId: string, params: UserMessageParams) => void;
@@ -19,6 +21,8 @@ export interface SubagentManagerCallbacks {
19
21
  onSubagentToolBlockUpdated?: (subagentId: string, params: AgentToolBlockUpdateParams) => void;
20
22
  /** Triggered when subagent messages change */
21
23
  onSubagentMessagesChange?: (subagentId: string, messages: Message[]) => void;
24
+ /** Triggered when subagent latest total tokens change */
25
+ onSubagentLatestTotalTokensChange?: (subagentId: string, tokens: number) => void;
22
26
  }
23
27
  export interface SubagentInstance {
24
28
  subagentId: string;
@@ -29,11 +33,13 @@ export interface SubagentInstance {
29
33
  status: "initializing" | "active" | "completed" | "error" | "aborted";
30
34
  messages: Message[];
31
35
  subagentType: string;
36
+ backgroundTaskId?: string;
32
37
  }
33
38
  export interface SubagentManagerOptions {
34
39
  workdir: string;
35
40
  parentToolManager: ToolManager;
36
41
  parentMessageManager: MessageManager;
42
+ taskManager: import("../services/taskManager.js").TaskManager;
37
43
  callbacks?: SubagentManagerCallbacks;
38
44
  logger?: Logger;
39
45
  getGatewayConfig: () => GatewayConfig;
@@ -42,6 +48,8 @@ export interface SubagentManagerOptions {
42
48
  getLanguage: () => string | undefined;
43
49
  hookManager?: HookManager;
44
50
  onUsageAdded?: (usage: Usage) => void;
51
+ backgroundTaskManager?: BackgroundTaskManager;
52
+ memoryRuleManager?: MemoryRuleManager;
45
53
  }
46
54
  export declare class SubagentManager {
47
55
  private instances;
@@ -49,6 +57,7 @@ export declare class SubagentManager {
49
57
  private workdir;
50
58
  private parentToolManager;
51
59
  private parentMessageManager;
60
+ private taskManager;
52
61
  private callbacks?;
53
62
  private logger?;
54
63
  private getGatewayConfig;
@@ -57,6 +66,8 @@ export declare class SubagentManager {
57
66
  private getLanguage;
58
67
  private hookManager?;
59
68
  private onUsageAdded?;
69
+ private backgroundTaskManager?;
70
+ private memoryRuleManager?;
60
71
  constructor(options: SubagentManagerOptions);
61
72
  /**
62
73
  * Initialize the SubagentManager by loading and caching configurations
@@ -81,14 +92,16 @@ export declare class SubagentManager {
81
92
  description: string;
82
93
  prompt: string;
83
94
  subagent_type: string;
84
- }): Promise<SubagentInstance>;
95
+ }, runInBackground?: boolean): Promise<SubagentInstance>;
85
96
  /**
86
97
  * Execute task using subagent instance
87
98
  *
88
99
  * IMPORTANT: This method automatically filters out the Task tool from allowedTools
89
100
  * to prevent subagents from spawning other subagents (infinite recursion protection)
90
101
  */
91
- executeTask(instance: SubagentInstance, prompt: string, abortSignal?: AbortSignal): Promise<string>;
102
+ executeTask(instance: SubagentInstance, prompt: string, abortSignal?: AbortSignal, runInBackground?: boolean): Promise<string>;
103
+ backgroundInstance(subagentId: string): Promise<string>;
104
+ private internalExecute;
92
105
  /**
93
106
  * Get instance by subagent ID
94
107
  */