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
package/src/agent.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { ForegroundTaskManager } from "./managers/foregroundTaskManager.js";
1
2
  import {
2
3
  MessageManager,
3
4
  type MessageManagerCallbacks,
@@ -8,14 +9,13 @@ import {
8
9
  SubagentManager,
9
10
  type SubagentManagerCallbacks,
10
11
  } from "./managers/subagentManager.js";
11
- import * as memory from "./services/memory.js";
12
12
  import { McpManager, type McpManagerCallbacks } from "./managers/mcpManager.js";
13
13
  import { LspManager } from "./managers/lspManager.js";
14
14
  import { BashManager } from "./managers/bashManager.js";
15
15
  import {
16
- BackgroundBashManager,
17
- type BackgroundBashManagerCallbacks,
18
- } from "./managers/backgroundBashManager.js";
16
+ BackgroundTaskManager,
17
+ type BackgroundTaskManagerCallbacks,
18
+ } from "./managers/backgroundTaskManager.js";
19
19
  import { SlashCommandManager } from "./managers/slashCommandManager.js";
20
20
  import { PluginManager } from "./managers/pluginManager.js";
21
21
  import { HookManager } from "./managers/hookManager.js";
@@ -38,11 +38,14 @@ import type {
38
38
  Usage,
39
39
  PermissionMode,
40
40
  PermissionCallback,
41
+ BackgroundTask,
42
+ ForegroundTask,
41
43
  } from "./types/index.js";
42
44
  import { MemoryRuleManager } from "./managers/MemoryRuleManager.js";
43
45
  import { LiveConfigManager } from "./managers/liveConfigManager.js";
44
46
  import { configValidator } from "./utils/configValidator.js";
45
47
  import { SkillManager } from "./managers/skillManager.js";
48
+ import { TaskManager } from "./services/taskManager.js";
46
49
  import {
47
50
  loadSessionFromJsonl,
48
51
  handleSessionRestoration,
@@ -100,10 +103,17 @@ export interface AgentOptions {
100
103
 
101
104
  export interface AgentCallbacks
102
105
  extends MessageManagerCallbacks,
103
- BackgroundBashManagerCallbacks,
106
+ BackgroundTaskManagerCallbacks,
104
107
  McpManagerCallbacks,
105
108
  SubagentManagerCallbacks {
109
+ onTasksChange?: (tasks: BackgroundTask[]) => void;
110
+ onSessionTasksChange?: (tasks: import("./types/tasks.js").Task[]) => void;
106
111
  onPermissionModeChange?: (mode: PermissionMode) => void;
112
+ onSubagentLatestTotalTokensChange?: (
113
+ subagentId: string,
114
+ tokens: number,
115
+ ) => void;
116
+ onBackgroundCurrentTask?: () => void;
107
117
  }
108
118
 
109
119
  export class Agent {
@@ -111,7 +121,7 @@ export class Agent {
111
121
  private aiManager: AIManager;
112
122
 
113
123
  private bashManager: BashManager | null = null;
114
- private backgroundBashManager: BackgroundBashManager;
124
+ private backgroundTaskManager: BackgroundTaskManager;
115
125
  private logger?: Logger; // Add optional logger property
116
126
  private toolManager: ToolManager; // Add tool registry instance
117
127
  private mcpManager: McpManager; // Add MCP manager instance
@@ -126,6 +136,8 @@ export class Agent {
126
136
  private reversionManager: ReversionManager;
127
137
  private memoryRuleManager: MemoryRuleManager; // Add memory rule manager instance
128
138
  private liveConfigManager: LiveConfigManager; // Add live configuration manager
139
+ private taskManager: TaskManager;
140
+ private foregroundTaskManager: ForegroundTaskManager;
129
141
  private configurationService: ConfigurationService; // Add configuration service
130
142
  private workdir: string; // Working directory
131
143
  private systemPrompt?: string; // Custom system prompt
@@ -200,8 +212,55 @@ export class Agent {
200
212
  // Store options for dynamic configuration resolution
201
213
  this.options = options;
202
214
 
203
- this.backgroundBashManager = new BackgroundBashManager({
204
- callbacks,
215
+ this.foregroundTaskManager = new ForegroundTaskManager();
216
+
217
+ // Initialize memory rule manager
218
+ this.memoryRuleManager = new MemoryRuleManager({
219
+ workdir: this.workdir,
220
+ });
221
+
222
+ // Initialize MessageManager
223
+ this.messageManager = new MessageManager({
224
+ callbacks: {
225
+ ...callbacks,
226
+ onSessionIdChange: (sessionId) => {
227
+ // When session ID changes (e.g. due to compression),
228
+ // we update the task manager to use the root session ID
229
+ // to ensure the task list remains consistent.
230
+ this.taskManager.setTaskListId(
231
+ this.messageManager.getRootSessionId(),
232
+ );
233
+ callbacks.onSessionIdChange?.(sessionId);
234
+ },
235
+ onSubagentTaskStopRequested: (subagentId) => {
236
+ this.backgroundTaskManager.stopTask(subagentId);
237
+ },
238
+ },
239
+ workdir: this.workdir,
240
+ logger: this.logger,
241
+ memoryRuleManager: this.memoryRuleManager,
242
+ });
243
+
244
+ // Resolve taskListId once during construction to ensure stability
245
+ const resolvedTaskListId =
246
+ this.configurationService.getEnvironmentVars().WAVE_TASK_LIST_ID ||
247
+ process.env.WAVE_TASK_LIST_ID ||
248
+ this.messageManager.getRootSessionId();
249
+
250
+ this.taskManager = new TaskManager(resolvedTaskListId);
251
+ this.taskManager.on("tasksChange", async () => {
252
+ const tasks = await this.taskManager.listTasks();
253
+ this.options.callbacks?.onSessionTasksChange?.(tasks);
254
+ });
255
+
256
+ // Initialize BackgroundTaskManager
257
+ this.backgroundTaskManager = new BackgroundTaskManager({
258
+ callbacks: {
259
+ ...callbacks,
260
+ onTasksChange: (tasks) => {
261
+ callbacks.onTasksChange?.(tasks);
262
+ },
263
+ },
205
264
  workdir: this.workdir,
206
265
  });
207
266
  this.mcpManager = new McpManager({ callbacks, logger: this.logger }); // Initialize MCP manager
@@ -230,23 +289,11 @@ export class Agent {
230
289
  workdir: this.workdir,
231
290
  });
232
291
 
233
- // Initialize MessageManager
234
- this.messageManager = new MessageManager({
235
- callbacks,
236
- workdir: this.workdir,
237
- logger: this.logger,
238
- });
239
-
240
- // Initialize ReversionManager
292
+ // ReversionManager depends on MessageManager
241
293
  this.reversionManager = new ReversionManager(
242
294
  new ReversionService(this.messageManager.getTranscriptPath()),
243
295
  );
244
296
 
245
- // Initialize memory rule manager
246
- this.memoryRuleManager = new MemoryRuleManager({
247
- workdir: this.workdir,
248
- });
249
-
250
297
  // Create a wrapper for canUseTool that triggers notification hooks
251
298
  const canUseToolWithNotification: PermissionCallback | undefined =
252
299
  options.canUseTool
@@ -298,6 +345,9 @@ export class Agent {
298
345
  reversionManager: this.reversionManager,
299
346
  permissionMode: options.permissionMode, // Let PermissionManager handle defaultMode resolution
300
347
  canUseToolCallback: canUseToolWithNotification,
348
+ taskManager: this.taskManager,
349
+ backgroundTaskManager: this.backgroundTaskManager,
350
+ foregroundTaskManager: this.foregroundTaskManager,
301
351
  }); // Initialize tool registry with permission support
302
352
  this.liveConfigManager = new LiveConfigManager({
303
353
  workdir: this.workdir,
@@ -323,6 +373,8 @@ export class Agent {
323
373
  callbacks.onSubagentAssistantReasoningUpdated,
324
374
  onSubagentToolBlockUpdated: callbacks.onSubagentToolBlockUpdated,
325
375
  onSubagentMessagesChange: callbacks.onSubagentMessagesChange,
376
+ onSubagentLatestTotalTokensChange:
377
+ callbacks.onSubagentLatestTotalTokensChange,
326
378
  }, // Pass subagent callbacks for forwarding
327
379
  logger: this.logger,
328
380
  getGatewayConfig: () => this.getGatewayConfig(),
@@ -331,14 +383,18 @@ export class Agent {
331
383
  getLanguage: () => this.getLanguage(),
332
384
  hookManager: this.hookManager,
333
385
  onUsageAdded: (usage) => this.addUsage(usage),
386
+ backgroundTaskManager: this.backgroundTaskManager,
387
+ taskManager: this.taskManager,
388
+ memoryRuleManager: this.memoryRuleManager,
334
389
  });
335
390
 
336
391
  // Initialize AI manager with resolved configuration
337
392
  this.aiManager = new AIManager({
338
393
  messageManager: this.messageManager,
339
394
  toolManager: this.toolManager,
395
+ taskManager: this.taskManager,
340
396
  logger: this.logger,
341
- backgroundBashManager: this.backgroundBashManager,
397
+ backgroundTaskManager: this.backgroundTaskManager,
342
398
  hookManager: this.hookManager,
343
399
  permissionManager: this.permissionManager,
344
400
  callbacks: {
@@ -362,6 +418,8 @@ export class Agent {
362
418
  this.slashCommandManager = new SlashCommandManager({
363
419
  messageManager: this.messageManager,
364
420
  aiManager: this.aiManager,
421
+ backgroundTaskManager: this.backgroundTaskManager,
422
+ taskManager: this.taskManager,
365
423
  workdir: this.workdir,
366
424
  logger: this.logger,
367
425
  });
@@ -436,10 +494,6 @@ export class Agent {
436
494
  return this.messageManager.getlatestTotalTokens();
437
495
  }
438
496
 
439
- public get userInputHistory(): string[] {
440
- return this.messageManager.getUserInputHistory();
441
- }
442
-
443
497
  /** Get working directory */
444
498
  public get workingDirectory(): string {
445
499
  return this.workdir;
@@ -456,34 +510,8 @@ export class Agent {
456
510
  }
457
511
 
458
512
  /** Get combined memory content (project + user + modular rules) */
459
- public get combinedMemory(): string {
460
- let combined = "";
461
- if (this._projectMemoryContent.trim()) {
462
- combined += this._projectMemoryContent;
463
- }
464
- if (this._userMemoryContent.trim()) {
465
- if (combined) {
466
- combined += "\n\n";
467
- }
468
- combined += this._userMemoryContent;
469
- }
470
-
471
- // Add modular memory rules
472
- const filesInContext = this.messageManager.getFilesInContext();
473
- const activeRules = this.memoryRuleManager.getActiveRules(filesInContext);
474
- if (activeRules.length > 0) {
475
- this.logger?.debug(
476
- `Active modular rules (${activeRules.length}): ${activeRules.map((r) => r.id).join(", ")}`,
477
- );
478
- if (combined) {
479
- combined += "\n\n";
480
- }
481
- combined += activeRules.map((r) => r.content).join("\n\n");
482
- } else {
483
- this.logger?.debug("No active modular rules for current context");
484
- }
485
-
486
- return combined;
513
+ public async getCombinedMemory(): Promise<string> {
514
+ return this.messageManager.getCombinedMemory();
487
515
  }
488
516
 
489
517
  /** Get AI loading status */
@@ -506,12 +534,25 @@ export class Agent {
506
534
  id: string,
507
535
  filter?: string,
508
536
  ): { stdout: string; stderr: string; status: string } | null {
509
- return this.backgroundBashManager.getOutput(id, filter);
537
+ return this.backgroundTaskManager.getOutput(id, filter);
510
538
  }
511
539
 
512
540
  /** Kill background bash shell */
513
541
  public killBackgroundShell(id: string): boolean {
514
- return this.backgroundBashManager.killShell(id);
542
+ return this.backgroundTaskManager.stopTask(id);
543
+ }
544
+
545
+ /** Get background task output */
546
+ public getBackgroundTaskOutput(
547
+ id: string,
548
+ filter?: string,
549
+ ): { stdout: string; stderr: string; status: string } | null {
550
+ return this.backgroundTaskManager.getOutput(id, filter);
551
+ }
552
+
553
+ /** Stop background task */
554
+ public stopBackgroundTask(id: string): boolean {
555
+ return this.backgroundTaskManager.stopTask(id);
515
556
  }
516
557
 
517
558
  /**
@@ -774,8 +815,18 @@ export class Agent {
774
815
  // After main session is restored, restore any associated subagent sessions
775
816
  await this.restoreSubagentSessions(sessionToRestore?.messages || []);
776
817
 
777
- if (sessionToRestore)
818
+ if (sessionToRestore) {
778
819
  this.messageManager.initializeFromSession(sessionToRestore);
820
+
821
+ // Update task manager with the root session ID to ensure continuity across compressions
822
+ this.taskManager.setTaskListId(
823
+ sessionToRestore.rootSessionId || sessionToRestore.id,
824
+ );
825
+
826
+ // After session is initialized, load tasks for the session
827
+ const tasks = await this.taskManager.listTasks();
828
+ this.options.callbacks?.onSessionTasksChange?.(tasks);
829
+ }
779
830
  }
780
831
  }
781
832
 
@@ -898,6 +949,13 @@ export class Agent {
898
949
 
899
950
  // 6. Initialize session state last
900
951
  this.messageManager.initializeFromSession(sessionData);
952
+
953
+ // Update task manager with the root session ID to ensure continuity across compressions
954
+ this.taskManager.setTaskListId(sessionData.rootSessionId || sessionData.id);
955
+
956
+ // 7. Load tasks for the restored session
957
+ const tasks = await this.taskManager.listTasks();
958
+ this.options.callbacks?.onSessionTasksChange?.(tasks);
901
959
  }
902
960
 
903
961
  public abortAIMessage(): void {
@@ -906,12 +964,9 @@ export class Agent {
906
964
 
907
965
  /** Execute bash command */
908
966
  public async executeBashCommand(command: string): Promise<void> {
909
- // Add user message to history (but not displayed in UI)
910
- this.addToInputHistory(`!${command}`);
911
967
  await this.bashManager?.executeCommand(command);
912
968
  }
913
969
 
914
- /** Clear messages and input history */
915
970
  public clearMessages(): void {
916
971
  this.messageManager.clearMessages();
917
972
  }
@@ -923,11 +978,6 @@ export class Agent {
923
978
  this.abortSlashCommand();
924
979
  }
925
980
 
926
- /** Add to input history */
927
- private addToInputHistory(input: string): void {
928
- this.messageManager.addToInputHistory(input);
929
- }
930
-
931
981
  /** Interrupt bash command execution */
932
982
  public abortBashCommand(): void {
933
983
  this.bashManager?.abortCommand();
@@ -938,14 +988,36 @@ export class Agent {
938
988
  this.slashCommandManager.abortCurrentCommand();
939
989
  }
940
990
 
991
+ /**
992
+ * Register a foreground task that can be backgrounded
993
+ */
994
+ public registerForegroundTask(task: ForegroundTask): void {
995
+ this.foregroundTaskManager.registerForegroundTask(task);
996
+ }
997
+
998
+ /**
999
+ * Unregister a foreground task
1000
+ */
1001
+ public unregisterForegroundTask(id: string): void {
1002
+ this.foregroundTaskManager.unregisterForegroundTask(id);
1003
+ }
1004
+
1005
+ /**
1006
+ * Background the current foreground task
1007
+ */
1008
+ public async backgroundCurrentTask(): Promise<void> {
1009
+ await this.foregroundTaskManager.backgroundCurrentTask();
1010
+ this.options.callbacks?.onBackgroundCurrentTask?.();
1011
+ }
1012
+
941
1013
  /** Destroy managers, clean up resources */
942
1014
  public async destroy(): Promise<void> {
943
1015
  await this.messageManager.saveSession();
944
1016
  this.abortAIMessage(); // This will abort tools including Task tool (subagents)
945
1017
  this.abortBashCommand();
946
1018
  this.abortSlashCommand();
947
- // Cleanup background bash manager
948
- this.backgroundBashManager.cleanup();
1019
+ // Cleanup background task manager
1020
+ this.backgroundTaskManager.cleanup();
949
1021
  // Cleanup MCP connections
950
1022
  await this.mcpManager.cleanup();
951
1023
  // Cleanup LSP connections
@@ -1027,8 +1099,6 @@ export class Agent {
1027
1099
  // Execute valid slash command
1028
1100
  await this.slashCommandManager.executeCommand(commandId, args);
1029
1101
 
1030
- // Add slash command to history
1031
- this.addToInputHistory(command);
1032
1102
  return;
1033
1103
  }
1034
1104
 
@@ -1037,9 +1107,6 @@ export class Agent {
1037
1107
  }
1038
1108
 
1039
1109
  // Handle normal AI message
1040
- // Add user message to history
1041
- this.addToInputHistory(content);
1042
-
1043
1110
  // Add user message first, will automatically sync to UI
1044
1111
  this.messageManager.addUserMessage({
1045
1112
  content,
@@ -1096,67 +1163,6 @@ export class Agent {
1096
1163
  }
1097
1164
  }
1098
1165
 
1099
- /** Save memory to project or user memory file */
1100
- public async saveMemory(
1101
- message: string,
1102
- type: "project" | "user",
1103
- ): Promise<void> {
1104
- try {
1105
- // Ensure the message starts with # for memory functions
1106
- const formattedMessage = message.startsWith("#")
1107
- ? message
1108
- : `#${message}`;
1109
-
1110
- if (type === "project") {
1111
- await memory.addMemory(formattedMessage, this.workdir);
1112
- // Update internal state after successful save
1113
- this._projectMemoryContent = await memory.readMemoryFile(this.workdir);
1114
- } else {
1115
- await memory.addUserMemory(formattedMessage);
1116
- // Update internal state after successful save
1117
- this._userMemoryContent = await memory.getUserMemoryContent();
1118
- }
1119
-
1120
- // Add successful MemoryBlock to the last assistant message
1121
- const memoryText = message.substring(1).trim();
1122
- const typeLabel = type === "project" ? "Project Memory" : "User Memory";
1123
- const storagePath = "AGENTS.md";
1124
-
1125
- const messages = this.messageManager.getMessages();
1126
- const lastMessage = messages[messages.length - 1];
1127
- if (lastMessage && lastMessage.role === "assistant") {
1128
- lastMessage.blocks.push({
1129
- type: "memory",
1130
- content: `${typeLabel}: ${memoryText}`,
1131
- isSuccess: true,
1132
- memoryType: type,
1133
- storagePath,
1134
- });
1135
- this.messageManager.setMessages(messages);
1136
- }
1137
- } catch (error) {
1138
- // Add failed MemoryBlock to the last assistant message
1139
- const memoryText = message.substring(1).trim();
1140
- const typeLabel = type === "project" ? "Project Memory" : "User Memory";
1141
- const storagePath = "AGENTS.md";
1142
- const errorMessage =
1143
- error instanceof Error ? error.message : String(error);
1144
-
1145
- const messages = this.messageManager.getMessages();
1146
- const lastMessage = messages[messages.length - 1];
1147
- if (lastMessage && lastMessage.role === "assistant") {
1148
- lastMessage.blocks.push({
1149
- type: "memory",
1150
- content: `${typeLabel}: ${memoryText} - Error: ${errorMessage}`,
1151
- isSuccess: false,
1152
- memoryType: type,
1153
- storagePath,
1154
- });
1155
- this.messageManager.setMessages(messages);
1156
- }
1157
- }
1158
- }
1159
-
1160
1166
  // ========== MCP Management Methods ==========
1161
1167
 
1162
1168
  /** Get all MCP server status */
@@ -1236,6 +1242,16 @@ export class Agent {
1236
1242
  await this.messageManager.truncateHistory(index, this.reversionManager);
1237
1243
  }
1238
1244
 
1245
+ /**
1246
+ * Get the full message thread including parent sessions
1247
+ */
1248
+ public async getFullMessageThread(): Promise<{
1249
+ messages: Message[];
1250
+ sessionIds: string[];
1251
+ }> {
1252
+ return this.messageManager.getFullMessageThread();
1253
+ }
1254
+
1239
1255
  /**
1240
1256
  * Get the current plan file path (for testing and UI)
1241
1257
  */
@@ -1304,7 +1320,7 @@ export class Agent {
1304
1320
  private handlePlanModeTransition(mode: PermissionMode): void {
1305
1321
  if (mode === "plan") {
1306
1322
  this.planManager
1307
- .getOrGeneratePlanFilePath()
1323
+ .getOrGeneratePlanFilePath(this.messageManager.getRootSessionId())
1308
1324
  .then(({ path }) => {
1309
1325
  this.logger?.debug("Plan file path generated", { path });
1310
1326
  this.permissionManager.setPlanFilePath(path);
@@ -1316,4 +1332,11 @@ export class Agent {
1316
1332
  this.permissionManager.setPlanFilePath(undefined);
1317
1333
  }
1318
1334
  }
1335
+
1336
+ /**
1337
+ * Get the current task list ID
1338
+ */
1339
+ public get taskListId(): string {
1340
+ return this.taskManager.getTaskListId();
1341
+ }
1319
1342
  }