wave-code 0.5.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 (95) hide show
  1. package/dist/components/App.d.ts.map +1 -1
  2. package/dist/components/App.js +38 -2
  3. package/dist/components/BackgroundTaskManager.d.ts +6 -0
  4. package/dist/components/BackgroundTaskManager.d.ts.map +1 -0
  5. package/dist/components/{TaskManager.js → BackgroundTaskManager.js} +1 -1
  6. package/dist/components/ChatInterface.d.ts.map +1 -1
  7. package/dist/components/ChatInterface.js +39 -5
  8. package/dist/components/CommandSelector.d.ts.map +1 -1
  9. package/dist/components/CommandSelector.js +10 -2
  10. package/dist/components/CompressDisplay.d.ts.map +1 -1
  11. package/dist/components/CompressDisplay.js +6 -10
  12. package/dist/components/ConfirmationDetails.d.ts +9 -0
  13. package/dist/components/ConfirmationDetails.d.ts.map +1 -0
  14. package/dist/components/ConfirmationDetails.js +53 -0
  15. package/dist/components/{Confirmation.d.ts → ConfirmationSelector.d.ts} +3 -3
  16. package/dist/components/ConfirmationSelector.d.ts.map +1 -0
  17. package/dist/components/{Confirmation.js → ConfirmationSelector.js} +34 -96
  18. package/dist/components/DiffDisplay.d.ts.map +1 -1
  19. package/dist/components/DiffDisplay.js +44 -1
  20. package/dist/components/FileSelector.d.ts.map +1 -1
  21. package/dist/components/FileSelector.js +2 -2
  22. package/dist/components/HistorySearch.d.ts.map +1 -1
  23. package/dist/components/HistorySearch.js +12 -4
  24. package/dist/components/InputBox.d.ts +1 -3
  25. package/dist/components/InputBox.d.ts.map +1 -1
  26. package/dist/components/InputBox.js +7 -17
  27. package/dist/components/LoadingIndicator.d.ts +11 -0
  28. package/dist/components/LoadingIndicator.d.ts.map +1 -0
  29. package/dist/components/LoadingIndicator.js +6 -0
  30. package/dist/components/Markdown.d.ts.map +1 -1
  31. package/dist/components/Markdown.js +114 -121
  32. package/dist/components/MessageItem.d.ts.map +1 -1
  33. package/dist/components/MessageItem.js +1 -2
  34. package/dist/components/MessageList.d.ts +2 -3
  35. package/dist/components/MessageList.d.ts.map +1 -1
  36. package/dist/components/MessageList.js +7 -7
  37. package/dist/components/PlanDisplay.d.ts.map +1 -1
  38. package/dist/components/PlanDisplay.js +4 -12
  39. package/dist/components/RewindCommand.d.ts +4 -0
  40. package/dist/components/RewindCommand.d.ts.map +1 -1
  41. package/dist/components/RewindCommand.js +19 -2
  42. package/dist/components/SubagentBlock.d.ts.map +1 -1
  43. package/dist/components/SubagentBlock.js +9 -6
  44. package/dist/components/TaskList.d.ts +3 -0
  45. package/dist/components/TaskList.d.ts.map +1 -0
  46. package/dist/components/TaskList.js +49 -0
  47. package/dist/components/ToolResultDisplay.js +1 -1
  48. package/dist/contexts/useChat.d.ts +11 -3
  49. package/dist/contexts/useChat.d.ts.map +1 -1
  50. package/dist/contexts/useChat.js +36 -31
  51. package/dist/hooks/useInputManager.d.ts +2 -13
  52. package/dist/hooks/useInputManager.d.ts.map +1 -1
  53. package/dist/hooks/useInputManager.js +8 -57
  54. package/dist/hooks/useTasks.d.ts +2 -0
  55. package/dist/hooks/useTasks.d.ts.map +1 -0
  56. package/dist/hooks/useTasks.js +5 -0
  57. package/dist/managers/InputManager.d.ts +4 -28
  58. package/dist/managers/InputManager.d.ts.map +1 -1
  59. package/dist/managers/InputManager.js +22 -128
  60. package/package.json +5 -6
  61. package/src/components/App.tsx +50 -3
  62. package/src/components/{TaskManager.tsx → BackgroundTaskManager.tsx} +4 -2
  63. package/src/components/ChatInterface.tsx +79 -23
  64. package/src/components/CommandSelector.tsx +35 -17
  65. package/src/components/CompressDisplay.tsx +5 -22
  66. package/src/components/ConfirmationDetails.tsx +108 -0
  67. package/src/components/{Confirmation.tsx → ConfirmationSelector.tsx} +69 -184
  68. package/src/components/DiffDisplay.tsx +62 -1
  69. package/src/components/FileSelector.tsx +0 -2
  70. package/src/components/HistorySearch.tsx +45 -21
  71. package/src/components/InputBox.tsx +11 -33
  72. package/src/components/LoadingIndicator.tsx +56 -0
  73. package/src/components/Markdown.tsx +126 -323
  74. package/src/components/MessageItem.tsx +1 -3
  75. package/src/components/MessageList.tsx +10 -67
  76. package/src/components/PlanDisplay.tsx +4 -27
  77. package/src/components/RewindCommand.tsx +38 -1
  78. package/src/components/SubagentBlock.tsx +25 -16
  79. package/src/components/TaskList.tsx +70 -0
  80. package/src/components/ToolResultDisplay.tsx +2 -2
  81. package/src/contexts/useChat.tsx +57 -40
  82. package/src/hooks/useInputManager.ts +9 -73
  83. package/src/hooks/useTasks.ts +6 -0
  84. package/src/managers/InputManager.ts +25 -159
  85. package/dist/components/Confirmation.d.ts.map +0 -1
  86. package/dist/components/MemoryDisplay.d.ts +0 -8
  87. package/dist/components/MemoryDisplay.d.ts.map +0 -1
  88. package/dist/components/MemoryDisplay.js +0 -25
  89. package/dist/components/MemoryTypeSelector.d.ts +0 -8
  90. package/dist/components/MemoryTypeSelector.d.ts.map +0 -1
  91. package/dist/components/MemoryTypeSelector.js +0 -38
  92. package/dist/components/TaskManager.d.ts +0 -6
  93. package/dist/components/TaskManager.d.ts.map +0 -1
  94. package/src/components/MemoryDisplay.tsx +0 -62
  95. package/src/components/MemoryTypeSelector.tsx +0 -98
@@ -12,6 +12,7 @@ import type {
12
12
  Message,
13
13
  McpServerStatus,
14
14
  BackgroundTask,
15
+ Task,
15
16
  SlashCommand,
16
17
  PermissionDecision,
17
18
  PermissionMode,
@@ -30,9 +31,10 @@ export interface ChatContextType {
30
31
  isLoading: boolean;
31
32
  isCommandRunning: boolean;
32
33
  isCompressing: boolean;
33
- userInputHistory: string[];
34
34
  // Message display state
35
35
  isExpanded: boolean;
36
+ isTaskListVisible: boolean;
37
+ setIsTaskListVisible: (visible: boolean) => void;
36
38
  // AI functionality
37
39
  sessionId: string;
38
40
  sendMessage: (
@@ -41,14 +43,14 @@ export interface ChatContextType {
41
43
  ) => Promise<void>;
42
44
  abortMessage: () => void;
43
45
  latestTotalTokens: number;
44
- // Memory functionality
45
- saveMemory: (message: string, type: "project" | "user") => Promise<void>;
46
46
  // MCP functionality
47
47
  mcpServers: McpServerStatus[];
48
48
  connectMcpServer: (serverName: string) => Promise<boolean>;
49
49
  disconnectMcpServer: (serverName: string) => Promise<boolean>;
50
50
  // Background tasks
51
51
  backgroundTasks: BackgroundTask[];
52
+ // Session tasks
53
+ sessionTasks: Task[];
52
54
  getBackgroundTaskOutput: (
53
55
  taskId: string,
54
56
  ) => { stdout: string; stderr: string; status: string } | null;
@@ -58,6 +60,7 @@ export interface ChatContextType {
58
60
  hasSlashCommand: (commandId: string) => boolean;
59
61
  // Subagent messages
60
62
  subagentMessages: Record<string, Message[]>;
63
+ subagentLatestTokens: Record<string, number>;
61
64
  // Permission functionality
62
65
  permissionMode: PermissionMode;
63
66
  setPermissionMode: (mode: PermissionMode) => void;
@@ -83,6 +86,12 @@ export interface ChatContextType {
83
86
  // Rewind functionality
84
87
  rewindId: number;
85
88
  handleRewindSelect: (index: number) => Promise<void>;
89
+ getFullMessageThread: () => Promise<{
90
+ messages: Message[];
91
+ sessionIds: string[];
92
+ }>;
93
+ wasLastDetailsTooTall: number;
94
+ setWasLastDetailsTooTall: React.Dispatch<React.SetStateAction<number>>;
86
95
  }
87
96
 
88
97
  const ChatContext = createContext<ChatContextType | null>(null);
@@ -110,6 +119,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
110
119
 
111
120
  // Message Display State
112
121
  const [isExpanded, setIsExpanded] = useState(false);
122
+ const [isTaskListVisible, setIsTaskListVisible] = useState(true);
113
123
 
114
124
  // AI State
115
125
  const [messages, setMessages] = useState<Message[]>([]);
@@ -118,13 +128,14 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
118
128
  const [sessionId, setSessionId] = useState("");
119
129
  const [isCommandRunning, setIsCommandRunning] = useState(false);
120
130
  const [isCompressing, setIsCompressing] = useState(false);
121
- const [userInputHistory, setUserInputHistory] = useState<string[]>([]);
122
131
 
123
132
  // MCP State
124
133
  const [mcpServers, setMcpServers] = useState<McpServerStatus[]>([]);
125
134
 
126
135
  // Background tasks state
127
136
  const [backgroundTasks, setBackgroundTasks] = useState<BackgroundTask[]>([]);
137
+ // Session tasks state
138
+ const [sessionTasks, setSessionTasks] = useState<Task[]>([]);
128
139
 
129
140
  // Command state
130
141
  const [slashCommands, setSlashCommands] = useState<SlashCommand[]>([]);
@@ -133,6 +144,9 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
133
144
  const [subagentMessages, setSubagentMessages] = useState<
134
145
  Record<string, Message[]>
135
146
  >({});
147
+ const [subagentLatestTokens, setSubagentLatestTokens] = useState<
148
+ Record<string, number>
149
+ >({});
136
150
 
137
151
  // Permission state
138
152
  const [permissionMode, setPermissionModeState] =
@@ -171,6 +185,9 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
171
185
  // Rewind state
172
186
  const [rewindId, setRewindId] = useState(0);
173
187
 
188
+ // Confirmation too tall state
189
+ const [wasLastDetailsTooTall, setWasLastDetailsTooTall] = useState(0);
190
+
174
191
  const agentRef = useRef<Agent | null>(null);
175
192
 
176
193
  // Permission confirmation methods with queue support
@@ -209,29 +226,36 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
209
226
  setMcpServers([...servers]);
210
227
  },
211
228
  onSessionIdChange: (sessionId) => {
212
- process.stdout.write("\x1Bc", () => {
213
- setSessionId(sessionId);
214
- });
229
+ setSessionId(sessionId);
215
230
  },
216
231
  onLatestTotalTokensChange: (tokens) => {
217
232
  setlatestTotalTokens(tokens);
218
233
  },
219
- onUserInputHistoryChange: (history) => {
220
- setUserInputHistory([...history]);
221
- },
222
234
  onCompressionStateChange: (isCompressingState) => {
223
235
  setIsCompressing(isCompressingState);
224
236
  },
225
237
  onTasksChange: (tasks) => {
226
238
  setBackgroundTasks([...tasks]);
227
239
  },
228
- onSubagentMessagesChange: (subagentId, messages) => {
240
+ onSessionTasksChange: (tasks) => {
241
+ setSessionTasks([...tasks]);
242
+ },
243
+ onSubagentMessagesChange: (subagentId: string, messages: Message[]) => {
229
244
  logger.debug("onSubagentMessagesChange", subagentId, messages.length);
230
245
  setSubagentMessages((prev) => ({
231
246
  ...prev,
232
247
  [subagentId]: [...messages],
233
248
  }));
234
249
  },
250
+ onSubagentLatestTotalTokensChange: (
251
+ subagentId: string,
252
+ tokens: number,
253
+ ) => {
254
+ setSubagentLatestTokens((prev) => ({
255
+ ...prev,
256
+ [subagentId]: tokens,
257
+ }));
258
+ },
235
259
  onPermissionModeChange: (mode) => {
236
260
  setPermissionModeState(mode);
237
261
  },
@@ -283,7 +307,6 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
283
307
  setlatestTotalTokens(agent.latestTotalTokens);
284
308
  setIsCommandRunning(agent.isCommandRunning);
285
309
  setIsCompressing(agent.isCompressing);
286
- setUserInputHistory(agent.userInputHistory);
287
310
  setPermissionModeState(agent.getPermissionMode());
288
311
 
289
312
  // Get initial MCP servers state
@@ -338,16 +361,6 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
338
361
  if (!hasTextContent && !hasImageAttachments) return;
339
362
 
340
363
  try {
341
- // Handle memory mode - check if it's a memory message (starts with # and only one line)
342
- if (content.startsWith("#") && !content.includes("\n")) {
343
- const memoryText = content.substring(1).trim();
344
- if (!memoryText) return;
345
-
346
- // In memory mode, don't add user message, only wait for user to choose memory type then add assistant message
347
- // Don't auto-save, wait for user to choose memory type
348
- return;
349
- }
350
-
351
364
  // Handle bash mode - check if it's a bash command (starts with ! and only one line)
352
365
  if (content.startsWith("!") && !content.includes("\n")) {
353
366
  const command = content.substring(1).trim();
@@ -394,14 +407,6 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
394
407
  agentRef.current?.abortMessage();
395
408
  }, []);
396
409
 
397
- // Memory save function - delegate to Agent
398
- const saveMemory = useCallback(
399
- async (message: string, type: "project" | "user") => {
400
- await agentRef.current?.saveMemory(message, type);
401
- },
402
- [],
403
- );
404
-
405
410
  // Permission management methods
406
411
  const setPermissionMode = useCallback((mode: PermissionMode) => {
407
412
  setPermissionModeState((prev) => {
@@ -492,27 +497,34 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
492
497
  await agentRef.current.truncateHistory(index);
493
498
 
494
499
  // Clear terminal screen after rewind
495
- process.stdout.write("\x1Bc", () => {
496
- setRewindId((prev) => prev + 1);
497
- });
500
+ setRewindId((prev) => prev + 1);
498
501
  } catch (error) {
499
502
  logger.error("Failed to rewind:", error);
500
503
  }
501
504
  }
502
505
  }, []);
503
506
 
507
+ const getFullMessageThread = useCallback(async () => {
508
+ if (agentRef.current) {
509
+ return await agentRef.current.getFullMessageThread();
510
+ }
511
+ return { messages: [], sessionIds: [] };
512
+ }, []);
513
+
504
514
  // Listen for Ctrl+O hotkey to toggle collapse/expand state and ESC to cancel confirmation
505
515
  useInput((input, key) => {
506
516
  if (key.ctrl && input === "o") {
507
517
  // Clear terminal screen when expanded state changes
508
- process.stdout.write("\x1Bc", () => {
509
- setIsExpanded((prev) => {
510
- const newExpanded = !prev;
511
- return newExpanded;
512
- });
518
+ setIsExpanded((prev) => {
519
+ const newExpanded = !prev;
520
+ return newExpanded;
513
521
  });
514
522
  }
515
523
 
524
+ if (key.ctrl && input === "t") {
525
+ setIsTaskListVisible((prev) => !prev);
526
+ }
527
+
516
528
  // Handle ESC key to cancel confirmation
517
529
  if (key.escape && isConfirmationVisible) {
518
530
  handleConfirmationCancel();
@@ -523,23 +535,25 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
523
535
  messages,
524
536
  isLoading,
525
537
  isCommandRunning,
526
- userInputHistory,
527
538
  isExpanded,
539
+ isTaskListVisible,
540
+ setIsTaskListVisible,
528
541
  sessionId,
529
542
  sendMessage,
530
543
  abortMessage,
531
544
  latestTotalTokens,
532
545
  isCompressing,
533
- saveMemory,
534
546
  mcpServers,
535
547
  connectMcpServer,
536
548
  disconnectMcpServer,
537
549
  backgroundTasks,
550
+ sessionTasks,
538
551
  getBackgroundTaskOutput,
539
552
  stopBackgroundTask,
540
553
  slashCommands,
541
554
  hasSlashCommand,
542
555
  subagentMessages,
556
+ subagentLatestTokens,
543
557
  permissionMode,
544
558
  setPermissionMode,
545
559
  isConfirmationVisible,
@@ -551,6 +565,9 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
551
565
  backgroundCurrentTask,
552
566
  rewindId,
553
567
  handleRewindSelect,
568
+ getFullMessageThread,
569
+ wasLastDetailsTooTall,
570
+ setWasLastDetailsTooTall,
554
571
  };
555
572
 
556
573
  return (
@@ -33,11 +33,8 @@ export const useInputManager = (
33
33
  show: false,
34
34
  query: "",
35
35
  });
36
- const [memoryTypeSelectorState, setMemoryTypeSelectorState] = useState({
37
- show: false,
38
- message: "",
39
- });
40
- const [showTaskManager, setShowTaskManager] = useState(false);
36
+ const [showBackgroundTaskManager, setShowBackgroundTaskManager] =
37
+ useState(false);
41
38
  const [showMcpManager, setShowMcpManager] = useState(false);
42
39
  const [showRewindManager, setShowRewindManager] = useState(false);
43
40
  const [permissionMode, setPermissionModeState] =
@@ -61,11 +58,8 @@ export const useInputManager = (
61
58
  onHistorySearchStateChange: (show, query) => {
62
59
  setHistorySearchState({ show, query });
63
60
  },
64
- onMemoryTypeSelectorStateChange: (show, message) => {
65
- setMemoryTypeSelectorState({ show, message });
66
- },
67
- onTaskManagerStateChange: (show) => {
68
- setShowTaskManager(show);
61
+ onBackgroundTaskManagerStateChange: (show) => {
62
+ setShowBackgroundTaskManager(show);
69
63
  },
70
64
  onMcpManagerStateChange: (show) => {
71
65
  setShowMcpManager(show);
@@ -78,9 +72,6 @@ export const useInputManager = (
78
72
  callbacks.onPermissionModeChange?.(mode);
79
73
  },
80
74
  onImagesStateChange: setAttachedImages,
81
- onShowTaskManager: () => setShowTaskManager(true),
82
- onShowMcpManager: () => setShowMcpManager(true),
83
- onShowRewindManager: () => setShowRewindManager(true),
84
75
  ...callbacks,
85
76
  });
86
77
 
@@ -101,11 +92,8 @@ export const useInputManager = (
101
92
  onHistorySearchStateChange: (show, query) => {
102
93
  setHistorySearchState({ show, query });
103
94
  },
104
- onMemoryTypeSelectorStateChange: (show, message) => {
105
- setMemoryTypeSelectorState({ show, message });
106
- },
107
- onTaskManagerStateChange: (show) => {
108
- setShowTaskManager(show);
95
+ onBackgroundTaskManagerStateChange: (show) => {
96
+ setShowBackgroundTaskManager(show);
109
97
  },
110
98
  onMcpManagerStateChange: (show) => {
111
99
  setShowMcpManager(show);
@@ -118,9 +106,6 @@ export const useInputManager = (
118
106
  callbacks.onPermissionModeChange?.(mode);
119
107
  },
120
108
  onImagesStateChange: setAttachedImages,
121
- onShowTaskManager: () => setShowTaskManager(true),
122
- onShowMcpManager: () => setShowMcpManager(true),
123
- onShowRewindManager: () => setShowRewindManager(true),
124
109
  ...callbacks,
125
110
  });
126
111
  }
@@ -252,43 +237,6 @@ export const useInputManager = (
252
237
  managerRef.current?.handleCancelHistorySearch();
253
238
  }, []);
254
239
 
255
- // Memory type selector methods
256
- const activateMemoryTypeSelector = useCallback((message: string) => {
257
- managerRef.current?.activateMemoryTypeSelector(message);
258
- }, []);
259
-
260
- const handleMemoryTypeSelect = useCallback(
261
- async (type: "project" | "user") => {
262
- await managerRef.current?.handleMemoryTypeSelect(type);
263
- },
264
- [],
265
- );
266
-
267
- const handleCancelMemoryTypeSelect = useCallback(() => {
268
- managerRef.current?.handleCancelMemoryTypeSelect();
269
- }, []);
270
-
271
- // Input history methods
272
- const setUserInputHistory = useCallback((history: string[]) => {
273
- managerRef.current?.setUserInputHistory(history);
274
- }, []);
275
-
276
- const navigateHistory = useCallback(
277
- (direction: "up" | "down", currentInput: string) => {
278
- return (
279
- managerRef.current?.navigateHistory(direction, currentInput) || {
280
- newInput: currentInput,
281
- newCursorPosition: currentInput.length,
282
- }
283
- );
284
- },
285
- [],
286
- );
287
-
288
- const resetHistoryNavigation = useCallback(() => {
289
- managerRef.current?.resetHistoryNavigation();
290
- }, []);
291
-
292
240
  // Special character handling
293
241
  const handleSpecialCharInput = useCallback((char: string) => {
294
242
  managerRef.current?.handleSpecialCharInput(char);
@@ -317,9 +265,7 @@ export const useInputManager = (
317
265
  slashPosition: commandSelectorState.position,
318
266
  showHistorySearch: historySearchState.show,
319
267
  historySearchQuery: historySearchState.query,
320
- showMemoryTypeSelector: memoryTypeSelectorState.show,
321
- memoryMessage: memoryTypeSelectorState.message,
322
- showTaskManager,
268
+ showBackgroundTaskManager,
323
269
  showMcpManager,
324
270
  showRewindManager,
325
271
  permissionMode,
@@ -354,22 +300,12 @@ export const useInputManager = (
354
300
  handleHistorySearchSelect,
355
301
  handleCancelHistorySearch,
356
302
 
357
- // Memory type selector
358
- activateMemoryTypeSelector,
359
- handleMemoryTypeSelect,
360
- handleCancelMemoryTypeSelect,
361
-
362
- // Input history
363
- setUserInputHistory,
364
- navigateHistory,
365
- resetHistoryNavigation,
366
-
367
303
  // Special handling
368
304
  handleSpecialCharInput,
369
305
 
370
306
  // Bash/MCP Manager
371
- setShowTaskManager: useCallback((show: boolean) => {
372
- managerRef.current?.setShowTaskManager(show);
307
+ setShowBackgroundTaskManager: useCallback((show: boolean) => {
308
+ managerRef.current?.setShowBackgroundTaskManager(show);
373
309
  }, []),
374
310
  setShowMcpManager: useCallback((show: boolean) => {
375
311
  managerRef.current?.setShowMcpManager(show);
@@ -0,0 +1,6 @@
1
+ import { useChat } from "../contexts/useChat.js";
2
+
3
+ export const useTasks = () => {
4
+ const { sessionTasks } = useChat();
5
+ return sessionTasks;
6
+ };
@@ -29,12 +29,8 @@ export interface InputManagerCallbacks {
29
29
  position: number,
30
30
  ) => void;
31
31
  onHistorySearchStateChange?: (show: boolean, query: string) => void;
32
- onMemoryTypeSelectorStateChange?: (show: boolean, message: string) => void;
33
- onShowTaskManager?: () => void;
34
- onTaskManagerStateChange?: (show: boolean) => void;
35
- onShowMcpManager?: () => void;
32
+ onBackgroundTaskManagerStateChange?: (show: boolean) => void;
36
33
  onMcpManagerStateChange?: (show: boolean) => void;
37
- onShowRewindManager?: () => void;
38
34
  onRewindManagerStateChange?: (show: boolean) => void;
39
35
  onImagesStateChange?: (images: AttachedImage[]) => void;
40
36
  onSendMessage?: (
@@ -42,7 +38,6 @@ export interface InputManagerCallbacks {
42
38
  images?: Array<{ path: string; mimeType: string }>,
43
39
  ) => void | Promise<void>;
44
40
  onHasSlashCommand?: (commandId: string) => boolean;
45
- onSaveMemory?: (message: string, type: "project" | "user") => Promise<void>;
46
41
  onAbortMessage?: () => void;
47
42
  onBackgroundCurrentTask?: () => void;
48
43
  onResetHistoryNavigation?: () => void;
@@ -71,15 +66,6 @@ export class InputManager {
71
66
  private showHistorySearch: boolean = false;
72
67
  private historySearchQuery: string = "";
73
68
 
74
- // Memory type selector state
75
- private showMemoryTypeSelector: boolean = false;
76
- private memoryMessage: string = "";
77
-
78
- // Input history state
79
- private userInputHistory: string[] = [];
80
- private historyIndex: number = -1;
81
- private historyBuffer: string = "";
82
-
83
69
  // Paste debounce state
84
70
  private pasteDebounceTimer: NodeJS.Timeout | null = null;
85
71
  private pasteBuffer: string = "";
@@ -95,7 +81,7 @@ export class InputManager {
95
81
  private imageIdCounter: number = 1;
96
82
 
97
83
  // Additional UI state
98
- private showTaskManager: boolean = false;
84
+ private showBackgroundTaskManager: boolean = false;
99
85
  private showMcpManager: boolean = false;
100
86
  private showRewindManager: boolean = false;
101
87
 
@@ -362,17 +348,14 @@ export class InputManager {
362
348
 
363
349
  // If not an agent command or execution failed, check local commands
364
350
  if (!commandExecuted) {
365
- if (command === "tasks" && this.callbacks.onShowTaskManager) {
366
- this.callbacks.onShowTaskManager();
351
+ if (command === "tasks") {
352
+ this.setShowBackgroundTaskManager(true);
367
353
  commandExecuted = true;
368
- } else if (command === "mcp" && this.callbacks.onShowMcpManager) {
369
- this.callbacks.onShowMcpManager();
354
+ } else if (command === "mcp") {
355
+ this.setShowMcpManager(true);
370
356
  commandExecuted = true;
371
- } else if (
372
- command === "rewind" &&
373
- this.callbacks.onShowRewindManager
374
- ) {
375
- this.callbacks.onShowRewindManager();
357
+ } else if (command === "rewind") {
358
+ this.setShowRewindManager(true);
376
359
  commandExecuted = true;
377
360
  }
378
361
  }
@@ -439,95 +422,6 @@ export class InputManager {
439
422
  return false;
440
423
  }
441
424
 
442
- // Memory type selector methods
443
- activateMemoryTypeSelector(message: string): void {
444
- this.showMemoryTypeSelector = true;
445
- this.memoryMessage = message;
446
-
447
- this.callbacks.onMemoryTypeSelectorStateChange?.(true, message);
448
- }
449
-
450
- async handleMemoryTypeSelect(type: "project" | "user"): Promise<void> {
451
- const currentMessage = this.inputText.trim();
452
- if (currentMessage.startsWith("#")) {
453
- await this.callbacks.onSaveMemory?.(currentMessage, type);
454
- }
455
- // Close the selector
456
- this.showMemoryTypeSelector = false;
457
- this.memoryMessage = "";
458
- this.callbacks.onMemoryTypeSelectorStateChange?.(false, "");
459
-
460
- // Clear input box
461
- this.clearInput();
462
- }
463
-
464
- handleCancelMemoryTypeSelect(): void {
465
- this.showMemoryTypeSelector = false;
466
- this.memoryMessage = "";
467
-
468
- this.callbacks.onMemoryTypeSelectorStateChange?.(false, "");
469
- }
470
-
471
- // Input history methods
472
- setUserInputHistory(history: string[]): void {
473
- this.userInputHistory = history;
474
- }
475
-
476
- navigateHistory(
477
- direction: "up" | "down",
478
- currentInput: string,
479
- ): { newInput: string; newCursorPosition: number } {
480
- if (this.historyIndex === -1) {
481
- this.historyBuffer = currentInput;
482
- }
483
-
484
- if (direction === "up") {
485
- if (this.historyIndex < this.userInputHistory.length - 1) {
486
- this.historyIndex++;
487
- }
488
- } else {
489
- // Down direction
490
- if (this.historyIndex > 0) {
491
- this.historyIndex--;
492
- } else if (this.historyIndex === 0) {
493
- // Go from first history item to draft
494
- this.historyIndex = -1;
495
- } else if (this.historyIndex === -1) {
496
- // Go from draft to empty (beyond history bottom)
497
- this.historyIndex = -2;
498
- }
499
- }
500
-
501
- let newInput: string;
502
- if (this.historyIndex === -1) {
503
- newInput = this.historyBuffer;
504
- } else if (this.historyIndex === -2) {
505
- // Beyond history bottom, clear input
506
- newInput = "";
507
- } else {
508
- const historyItem =
509
- this.userInputHistory[
510
- this.userInputHistory.length - 1 - this.historyIndex
511
- ];
512
- newInput = historyItem || "";
513
- }
514
-
515
- const newCursorPosition = newInput.length;
516
-
517
- this.inputText = newInput;
518
- this.cursorPosition = newCursorPosition;
519
-
520
- this.callbacks.onInputTextChange?.(newInput);
521
- this.callbacks.onCursorPositionChange?.(newCursorPosition);
522
-
523
- return { newInput, newCursorPosition };
524
- }
525
-
526
- resetHistoryNavigation(): void {
527
- this.historyIndex = -1;
528
- this.historyBuffer = "";
529
- }
530
-
531
425
  // Getter methods for state
532
426
  isFileSelectorActive(): boolean {
533
427
  return this.showFileSelector;
@@ -537,10 +431,6 @@ export class InputManager {
537
431
  return this.showCommandSelector;
538
432
  }
539
433
 
540
- isMemoryTypeSelectorActive(): boolean {
541
- return this.showMemoryTypeSelector;
542
- }
543
-
544
434
  getFileSelectorState() {
545
435
  return {
546
436
  show: this.showFileSelector,
@@ -558,13 +448,6 @@ export class InputManager {
558
448
  };
559
449
  }
560
450
 
561
- getMemoryTypeSelectorState() {
562
- return {
563
- show: this.showMemoryTypeSelector,
564
- message: this.memoryMessage,
565
- };
566
- }
567
-
568
451
  // Update search queries for active selectors
569
452
  private updateSearchQueriesForActiveSelectors(
570
453
  inputText: string,
@@ -595,8 +478,6 @@ export class InputManager {
595
478
  // Don't activate command selector when file selector is active
596
479
  // Only activate command selector if '/' is at the start of input
597
480
  this.activateCommandSelector(this.cursorPosition - 1);
598
- } else if (char === "#" && this.cursorPosition === 1) {
599
- // Memory message detection will be handled in submit
600
481
  } else {
601
482
  // Update search queries for active selectors
602
483
  this.updateSearchQueriesForActiveSelectors(
@@ -753,13 +634,13 @@ export class InputManager {
753
634
  }
754
635
 
755
636
  // Task manager state methods
756
- getShowTaskManager(): boolean {
757
- return this.showTaskManager;
637
+ getShowBackgroundTaskManager(): boolean {
638
+ return this.showBackgroundTaskManager;
758
639
  }
759
640
 
760
- setShowTaskManager(show: boolean): void {
761
- this.showTaskManager = show;
762
- this.callbacks.onTaskManagerStateChange?.(show);
641
+ setShowBackgroundTaskManager(show: boolean): void {
642
+ this.showBackgroundTaskManager = show;
643
+ this.callbacks.onBackgroundTaskManagerStateChange?.(show);
763
644
  }
764
645
 
765
646
  getShowMcpManager(): boolean {
@@ -815,15 +696,6 @@ export class InputManager {
815
696
  }
816
697
 
817
698
  if (this.inputText.trim()) {
818
- const trimmedInput = this.inputText.trim();
819
-
820
- // Check if it's a memory message (starts with # and only one line)
821
- if (trimmedInput.startsWith("#") && !trimmedInput.includes("\n")) {
822
- // Activate memory type selector
823
- this.activateMemoryTypeSelector(trimmedInput);
824
- return;
825
- }
826
-
827
699
  // Extract image information
828
700
  const imageRegex = /\[Image #(\d+)\]/g;
829
701
  const matches = [...this.inputText.matchAll(imageRegex)];
@@ -1012,17 +884,6 @@ export class InputManager {
1012
884
  return true;
1013
885
  }
1014
886
 
1015
- // Handle up/down keys for history navigation (only when no selector is active)
1016
- if (key.upArrow && !this.showFileSelector && !this.showCommandSelector) {
1017
- this.navigateHistory("up", this.inputText);
1018
- return true;
1019
- }
1020
-
1021
- if (key.downArrow && !this.showFileSelector && !this.showCommandSelector) {
1022
- this.navigateHistory("down", this.inputText);
1023
- return true;
1024
- }
1025
-
1026
887
  // Handle typing input
1027
888
  if (
1028
889
  input &&
@@ -1060,7 +921,13 @@ export class InputManager {
1060
921
  }
1061
922
 
1062
923
  // Handle interrupt request - use Esc key to interrupt AI request or command
1063
- if (key.escape && (isLoading || isCommandRunning)) {
924
+ if (
925
+ key.escape &&
926
+ (isLoading || isCommandRunning) &&
927
+ !this.showBackgroundTaskManager &&
928
+ !this.showMcpManager &&
929
+ !this.showRewindManager
930
+ ) {
1064
931
  // Unified interrupt for AI message generation and command execution
1065
932
  this.callbacks.onAbortMessage?.();
1066
933
  return true;
@@ -1078,19 +945,18 @@ export class InputManager {
1078
945
  this.showFileSelector ||
1079
946
  this.showCommandSelector ||
1080
947
  this.showHistorySearch ||
1081
- this.showMemoryTypeSelector ||
1082
- this.showTaskManager ||
948
+ this.showBackgroundTaskManager ||
1083
949
  this.showMcpManager ||
1084
950
  this.showRewindManager
1085
951
  ) {
1086
952
  if (
1087
- this.showMemoryTypeSelector ||
1088
- this.showTaskManager ||
953
+ this.showBackgroundTaskManager ||
1089
954
  this.showMcpManager ||
1090
955
  this.showRewindManager
1091
956
  ) {
1092
- // Memory type selector, task manager, MCP manager and Rewind don't need to handle input, handled by component itself
1093
- return false;
957
+ // Task manager, MCP manager and Rewind don't need to handle input, handled by component itself
958
+ // Return true to indicate we've "handled" it (by ignoring it) so it doesn't leak to normal input
959
+ return true;
1094
960
  }
1095
961
 
1096
962
  if (this.showHistorySearch) {