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.
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/App.js +38 -2
- package/dist/components/BackgroundTaskManager.d.ts +6 -0
- package/dist/components/BackgroundTaskManager.d.ts.map +1 -0
- package/dist/components/{TaskManager.js → BackgroundTaskManager.js} +1 -1
- package/dist/components/ChatInterface.d.ts.map +1 -1
- package/dist/components/ChatInterface.js +39 -5
- package/dist/components/CommandSelector.d.ts.map +1 -1
- package/dist/components/CommandSelector.js +10 -2
- package/dist/components/CompressDisplay.d.ts.map +1 -1
- package/dist/components/CompressDisplay.js +6 -10
- package/dist/components/ConfirmationDetails.d.ts +9 -0
- package/dist/components/ConfirmationDetails.d.ts.map +1 -0
- package/dist/components/ConfirmationDetails.js +53 -0
- package/dist/components/{Confirmation.d.ts → ConfirmationSelector.d.ts} +3 -3
- package/dist/components/ConfirmationSelector.d.ts.map +1 -0
- package/dist/components/{Confirmation.js → ConfirmationSelector.js} +34 -96
- package/dist/components/DiffDisplay.d.ts.map +1 -1
- package/dist/components/DiffDisplay.js +44 -1
- package/dist/components/FileSelector.d.ts.map +1 -1
- package/dist/components/FileSelector.js +2 -2
- package/dist/components/HistorySearch.d.ts.map +1 -1
- package/dist/components/HistorySearch.js +12 -4
- package/dist/components/InputBox.d.ts +1 -3
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +7 -17
- package/dist/components/LoadingIndicator.d.ts +11 -0
- package/dist/components/LoadingIndicator.d.ts.map +1 -0
- package/dist/components/LoadingIndicator.js +6 -0
- package/dist/components/Markdown.d.ts.map +1 -1
- package/dist/components/Markdown.js +114 -121
- package/dist/components/MessageItem.d.ts.map +1 -1
- package/dist/components/MessageItem.js +1 -2
- package/dist/components/MessageList.d.ts +2 -3
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +7 -7
- package/dist/components/PlanDisplay.d.ts.map +1 -1
- package/dist/components/PlanDisplay.js +4 -12
- package/dist/components/RewindCommand.d.ts +4 -0
- package/dist/components/RewindCommand.d.ts.map +1 -1
- package/dist/components/RewindCommand.js +19 -2
- package/dist/components/SubagentBlock.d.ts.map +1 -1
- package/dist/components/SubagentBlock.js +9 -6
- package/dist/components/TaskList.d.ts +3 -0
- package/dist/components/TaskList.d.ts.map +1 -0
- package/dist/components/TaskList.js +49 -0
- package/dist/components/ToolResultDisplay.js +1 -1
- package/dist/contexts/useChat.d.ts +11 -3
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +36 -31
- package/dist/hooks/useInputManager.d.ts +2 -13
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +8 -57
- package/dist/hooks/useTasks.d.ts +2 -0
- package/dist/hooks/useTasks.d.ts.map +1 -0
- package/dist/hooks/useTasks.js +5 -0
- package/dist/managers/InputManager.d.ts +4 -28
- package/dist/managers/InputManager.d.ts.map +1 -1
- package/dist/managers/InputManager.js +22 -128
- package/package.json +5 -6
- package/src/components/App.tsx +50 -3
- package/src/components/{TaskManager.tsx → BackgroundTaskManager.tsx} +4 -2
- package/src/components/ChatInterface.tsx +79 -23
- package/src/components/CommandSelector.tsx +35 -17
- package/src/components/CompressDisplay.tsx +5 -22
- package/src/components/ConfirmationDetails.tsx +108 -0
- package/src/components/{Confirmation.tsx → ConfirmationSelector.tsx} +69 -184
- package/src/components/DiffDisplay.tsx +62 -1
- package/src/components/FileSelector.tsx +0 -2
- package/src/components/HistorySearch.tsx +45 -21
- package/src/components/InputBox.tsx +11 -33
- package/src/components/LoadingIndicator.tsx +56 -0
- package/src/components/Markdown.tsx +126 -323
- package/src/components/MessageItem.tsx +1 -3
- package/src/components/MessageList.tsx +10 -67
- package/src/components/PlanDisplay.tsx +4 -27
- package/src/components/RewindCommand.tsx +38 -1
- package/src/components/SubagentBlock.tsx +25 -16
- package/src/components/TaskList.tsx +70 -0
- package/src/components/ToolResultDisplay.tsx +2 -2
- package/src/contexts/useChat.tsx +57 -40
- package/src/hooks/useInputManager.ts +9 -73
- package/src/hooks/useTasks.ts +6 -0
- package/src/managers/InputManager.ts +25 -159
- package/dist/components/Confirmation.d.ts.map +0 -1
- package/dist/components/MemoryDisplay.d.ts +0 -8
- package/dist/components/MemoryDisplay.d.ts.map +0 -1
- package/dist/components/MemoryDisplay.js +0 -25
- package/dist/components/MemoryTypeSelector.d.ts +0 -8
- package/dist/components/MemoryTypeSelector.d.ts.map +0 -1
- package/dist/components/MemoryTypeSelector.js +0 -38
- package/dist/components/TaskManager.d.ts +0 -6
- package/dist/components/TaskManager.d.ts.map +0 -1
- package/src/components/MemoryDisplay.tsx +0 -62
- package/src/components/MemoryTypeSelector.tsx +0 -98
package/src/contexts/useChat.tsx
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
509
|
-
|
|
510
|
-
|
|
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 [
|
|
37
|
-
|
|
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
|
-
|
|
65
|
-
|
|
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
|
-
|
|
105
|
-
|
|
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
|
-
|
|
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
|
-
|
|
372
|
-
managerRef.current?.
|
|
307
|
+
setShowBackgroundTaskManager: useCallback((show: boolean) => {
|
|
308
|
+
managerRef.current?.setShowBackgroundTaskManager(show);
|
|
373
309
|
}, []),
|
|
374
310
|
setShowMcpManager: useCallback((show: boolean) => {
|
|
375
311
|
managerRef.current?.setShowMcpManager(show);
|
|
@@ -29,12 +29,8 @@ export interface InputManagerCallbacks {
|
|
|
29
29
|
position: number,
|
|
30
30
|
) => void;
|
|
31
31
|
onHistorySearchStateChange?: (show: boolean, query: string) => void;
|
|
32
|
-
|
|
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
|
|
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"
|
|
366
|
-
this.
|
|
351
|
+
if (command === "tasks") {
|
|
352
|
+
this.setShowBackgroundTaskManager(true);
|
|
367
353
|
commandExecuted = true;
|
|
368
|
-
} else if (command === "mcp"
|
|
369
|
-
this.
|
|
354
|
+
} else if (command === "mcp") {
|
|
355
|
+
this.setShowMcpManager(true);
|
|
370
356
|
commandExecuted = true;
|
|
371
|
-
} else if (
|
|
372
|
-
|
|
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
|
-
|
|
757
|
-
return this.
|
|
637
|
+
getShowBackgroundTaskManager(): boolean {
|
|
638
|
+
return this.showBackgroundTaskManager;
|
|
758
639
|
}
|
|
759
640
|
|
|
760
|
-
|
|
761
|
-
this.
|
|
762
|
-
this.callbacks.
|
|
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 (
|
|
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.
|
|
1082
|
-
this.showTaskManager ||
|
|
948
|
+
this.showBackgroundTaskManager ||
|
|
1083
949
|
this.showMcpManager ||
|
|
1084
950
|
this.showRewindManager
|
|
1085
951
|
) {
|
|
1086
952
|
if (
|
|
1087
|
-
this.
|
|
1088
|
-
this.showTaskManager ||
|
|
953
|
+
this.showBackgroundTaskManager ||
|
|
1089
954
|
this.showMcpManager ||
|
|
1090
955
|
this.showRewindManager
|
|
1091
956
|
) {
|
|
1092
|
-
//
|
|
1093
|
-
|
|
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) {
|