wave-code 0.8.1 → 0.8.2
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/ChatInterface.js +1 -1
- package/dist/components/MessageList.d.ts +2 -2
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +5 -6
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +2 -17
- package/dist/hooks/useInputManager.d.ts +7 -8
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +224 -232
- package/dist/managers/inputHandlers.d.ts +28 -0
- package/dist/managers/inputHandlers.d.ts.map +1 -0
- package/dist/managers/inputHandlers.js +378 -0
- package/dist/managers/inputReducer.d.ts +157 -0
- package/dist/managers/inputReducer.d.ts.map +1 -0
- package/dist/managers/inputReducer.js +242 -0
- package/package.json +2 -2
- package/src/components/ChatInterface.tsx +1 -1
- package/src/components/MessageList.tsx +5 -6
- package/src/contexts/useChat.tsx +2 -17
- package/src/hooks/useInputManager.ts +352 -299
- package/src/managers/inputHandlers.ts +560 -0
- package/src/managers/inputReducer.ts +367 -0
- package/dist/managers/InputManager.d.ts +0 -156
- package/dist/managers/InputManager.d.ts.map +0 -1
- package/dist/managers/InputManager.js +0 -749
- package/src/managers/InputManager.ts +0 -1024
|
@@ -1,284 +1,401 @@
|
|
|
1
|
-
import { useEffect,
|
|
1
|
+
import { useEffect, useReducer, useCallback, useRef } from "react";
|
|
2
2
|
import { Key } from "ink";
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
inputReducer,
|
|
5
|
+
initialState,
|
|
5
6
|
InputManagerCallbacks,
|
|
6
|
-
|
|
7
|
-
} from "
|
|
8
|
-
import
|
|
9
|
-
import { PermissionMode } from "wave-agent-sdk";
|
|
10
|
-
import { logger } from "../utils/logger.js";
|
|
7
|
+
} from "../managers/inputReducer.js";
|
|
8
|
+
import { searchFiles as searchFilesUtil, PermissionMode } from "wave-agent-sdk";
|
|
9
|
+
import * as handlers from "../managers/inputHandlers.js";
|
|
11
10
|
|
|
12
11
|
export const useInputManager = (
|
|
13
12
|
callbacks: Partial<InputManagerCallbacks> = {},
|
|
14
13
|
) => {
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const [cursorPosition, setCursorPosition] = useState(0);
|
|
21
|
-
const [fileSelectorState, setFileSelectorState] = useState({
|
|
22
|
-
show: false,
|
|
23
|
-
files: [] as FileItem[],
|
|
24
|
-
query: "",
|
|
25
|
-
position: -1,
|
|
26
|
-
});
|
|
27
|
-
const [commandSelectorState, setCommandSelectorState] = useState({
|
|
28
|
-
show: false,
|
|
29
|
-
query: "",
|
|
30
|
-
position: -1,
|
|
31
|
-
});
|
|
32
|
-
const [historySearchState, setHistorySearchState] = useState({
|
|
33
|
-
show: false,
|
|
34
|
-
query: "",
|
|
35
|
-
});
|
|
36
|
-
const [showBackgroundTaskManager, setShowBackgroundTaskManager] =
|
|
37
|
-
useState(false);
|
|
38
|
-
const [showMcpManager, setShowMcpManager] = useState(false);
|
|
39
|
-
const [showRewindManager, setShowRewindManager] = useState(false);
|
|
40
|
-
const [showHelp, setShowHelp] = useState(false);
|
|
41
|
-
const [showStatusCommand, setShowStatusCommand] = useState(false);
|
|
42
|
-
const [permissionMode, setPermissionModeState] =
|
|
43
|
-
useState<PermissionMode>("default");
|
|
44
|
-
const [attachedImages, setAttachedImages] = useState<AttachedImage[]>([]);
|
|
45
|
-
|
|
46
|
-
// Create InputManager on mount and update callbacks when they change
|
|
14
|
+
const [state, dispatch] = useReducer(inputReducer, initialState);
|
|
15
|
+
const callbacksRef = useRef(callbacks);
|
|
16
|
+
const stateRef = useRef(state);
|
|
17
|
+
|
|
18
|
+
// Update refs when they change
|
|
47
19
|
useEffect(() => {
|
|
48
|
-
|
|
49
|
-
// Create InputManager on first mount
|
|
50
|
-
const manager = new InputManager({
|
|
51
|
-
logger,
|
|
52
|
-
onInputTextChange: setInputText,
|
|
53
|
-
onCursorPositionChange: setCursorPosition,
|
|
54
|
-
onFileSelectorStateChange: (show, files, query, position) => {
|
|
55
|
-
setFileSelectorState({ show, files, query, position });
|
|
56
|
-
},
|
|
57
|
-
onCommandSelectorStateChange: (show, query, position) => {
|
|
58
|
-
setCommandSelectorState({ show, query, position });
|
|
59
|
-
},
|
|
60
|
-
onHistorySearchStateChange: (show, query) => {
|
|
61
|
-
setHistorySearchState({ show, query });
|
|
62
|
-
},
|
|
63
|
-
onBackgroundTaskManagerStateChange: (show) => {
|
|
64
|
-
setShowBackgroundTaskManager(show);
|
|
65
|
-
},
|
|
66
|
-
onMcpManagerStateChange: (show) => {
|
|
67
|
-
setShowMcpManager(show);
|
|
68
|
-
},
|
|
69
|
-
onRewindManagerStateChange: (show) => {
|
|
70
|
-
setShowRewindManager(show);
|
|
71
|
-
},
|
|
72
|
-
onHelpStateChange: (show) => {
|
|
73
|
-
setShowHelp(show);
|
|
74
|
-
},
|
|
75
|
-
onStatusCommandStateChange: (show) => {
|
|
76
|
-
setShowStatusCommand(show);
|
|
77
|
-
},
|
|
78
|
-
onPermissionModeChange: (mode) => {
|
|
79
|
-
setPermissionModeState(mode);
|
|
80
|
-
callbacks.onPermissionModeChange?.(mode);
|
|
81
|
-
},
|
|
82
|
-
onImagesStateChange: setAttachedImages,
|
|
83
|
-
...callbacks,
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
managerRef.current = manager;
|
|
87
|
-
setIsManagerReady(true);
|
|
88
|
-
} else {
|
|
89
|
-
// Update callbacks on existing manager
|
|
90
|
-
managerRef.current.updateCallbacks({
|
|
91
|
-
logger,
|
|
92
|
-
onInputTextChange: setInputText,
|
|
93
|
-
onCursorPositionChange: setCursorPosition,
|
|
94
|
-
onFileSelectorStateChange: (show, files, query, position) => {
|
|
95
|
-
setFileSelectorState({ show, files, query, position });
|
|
96
|
-
},
|
|
97
|
-
onCommandSelectorStateChange: (show, query, position) => {
|
|
98
|
-
setCommandSelectorState({ show, query, position });
|
|
99
|
-
},
|
|
100
|
-
onHistorySearchStateChange: (show, query) => {
|
|
101
|
-
setHistorySearchState({ show, query });
|
|
102
|
-
},
|
|
103
|
-
onBackgroundTaskManagerStateChange: (show) => {
|
|
104
|
-
setShowBackgroundTaskManager(show);
|
|
105
|
-
},
|
|
106
|
-
onMcpManagerStateChange: (show) => {
|
|
107
|
-
setShowMcpManager(show);
|
|
108
|
-
},
|
|
109
|
-
onRewindManagerStateChange: (show) => {
|
|
110
|
-
setShowRewindManager(show);
|
|
111
|
-
},
|
|
112
|
-
onHelpStateChange: (show) => {
|
|
113
|
-
setShowHelp(show);
|
|
114
|
-
},
|
|
115
|
-
onStatusCommandStateChange: (show) => {
|
|
116
|
-
setShowStatusCommand(show);
|
|
117
|
-
},
|
|
118
|
-
onPermissionModeChange: (mode) => {
|
|
119
|
-
setPermissionModeState(mode);
|
|
120
|
-
callbacks.onPermissionModeChange?.(mode);
|
|
121
|
-
},
|
|
122
|
-
onImagesStateChange: setAttachedImages,
|
|
123
|
-
...callbacks,
|
|
124
|
-
});
|
|
125
|
-
}
|
|
20
|
+
callbacksRef.current = callbacks;
|
|
126
21
|
}, [callbacks]);
|
|
127
22
|
|
|
128
|
-
// Cleanup on unmount
|
|
129
23
|
useEffect(() => {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
managerRef.current.destroy();
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
}, []);
|
|
24
|
+
stateRef.current = state;
|
|
25
|
+
}, [state]);
|
|
136
26
|
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
);
|
|
27
|
+
// Handle selectorJustUsed reset
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (state.selectorJustUsed) {
|
|
30
|
+
const timer = setTimeout(() => {
|
|
31
|
+
dispatch({ type: "SET_SELECTOR_JUST_USED", payload: false });
|
|
32
|
+
}, 0);
|
|
33
|
+
return () => clearTimeout(timer);
|
|
34
|
+
}
|
|
35
|
+
}, [state.selectorJustUsed]);
|
|
147
36
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
37
|
+
// Handle debounced file search
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (state.showFileSelector) {
|
|
40
|
+
const debounceDelay = parseInt(
|
|
41
|
+
process.env.FILE_SELECTOR_DEBOUNCE_MS || "300",
|
|
42
|
+
10,
|
|
43
|
+
);
|
|
44
|
+
const timer = setTimeout(async () => {
|
|
45
|
+
try {
|
|
46
|
+
const fileItems = await searchFilesUtil(state.fileSearchQuery);
|
|
47
|
+
dispatch({ type: "SET_FILTERED_FILES", payload: fileItems });
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error("File search error:", error);
|
|
50
|
+
dispatch({ type: "SET_FILTERED_FILES", payload: [] });
|
|
51
|
+
}
|
|
52
|
+
}, debounceDelay);
|
|
53
|
+
return () => clearTimeout(timer);
|
|
54
|
+
}
|
|
55
|
+
}, [state.showFileSelector, state.fileSearchQuery]);
|
|
56
|
+
|
|
57
|
+
// Handle paste debouncing
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (state.isPasting) {
|
|
60
|
+
const pasteDebounceDelay = parseInt(
|
|
61
|
+
process.env.PASTE_DEBOUNCE_MS || "30",
|
|
62
|
+
10,
|
|
63
|
+
);
|
|
64
|
+
const timer = setTimeout(() => {
|
|
65
|
+
const processedInput = stateRef.current.pasteBuffer.replace(
|
|
66
|
+
/\r/g,
|
|
67
|
+
"\n",
|
|
68
|
+
);
|
|
69
|
+
dispatch({ type: "COMPRESS_AND_INSERT_TEXT", payload: processedInput });
|
|
70
|
+
dispatch({ type: "END_PASTE" });
|
|
71
|
+
callbacksRef.current.onResetHistoryNavigation?.();
|
|
72
|
+
}, pasteDebounceDelay);
|
|
73
|
+
return () => clearTimeout(timer);
|
|
74
|
+
}
|
|
75
|
+
}, [state.isPasting, state.pasteBuffer]);
|
|
76
|
+
|
|
77
|
+
// Sync state changes with callbacks
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
callbacksRef.current.onInputTextChange?.(state.inputText);
|
|
80
|
+
}, [state.inputText]);
|
|
81
|
+
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
callbacksRef.current.onCursorPositionChange?.(state.cursorPosition);
|
|
84
|
+
}, [state.cursorPosition]);
|
|
85
|
+
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
callbacksRef.current.onFileSelectorStateChange?.(
|
|
88
|
+
state.showFileSelector,
|
|
89
|
+
state.filteredFiles,
|
|
90
|
+
state.fileSearchQuery,
|
|
91
|
+
state.atPosition,
|
|
92
|
+
);
|
|
93
|
+
}, [
|
|
94
|
+
state.showFileSelector,
|
|
95
|
+
state.filteredFiles,
|
|
96
|
+
state.fileSearchQuery,
|
|
97
|
+
state.atPosition,
|
|
98
|
+
]);
|
|
99
|
+
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
callbacksRef.current.onCommandSelectorStateChange?.(
|
|
102
|
+
state.showCommandSelector,
|
|
103
|
+
state.commandSearchQuery,
|
|
104
|
+
state.slashPosition,
|
|
105
|
+
);
|
|
106
|
+
}, [
|
|
107
|
+
state.showCommandSelector,
|
|
108
|
+
state.commandSearchQuery,
|
|
109
|
+
state.slashPosition,
|
|
110
|
+
]);
|
|
111
|
+
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
callbacksRef.current.onHistorySearchStateChange?.(
|
|
114
|
+
state.showHistorySearch,
|
|
115
|
+
state.historySearchQuery,
|
|
116
|
+
);
|
|
117
|
+
}, [state.showHistorySearch, state.historySearchQuery]);
|
|
118
|
+
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
callbacksRef.current.onBackgroundTaskManagerStateChange?.(
|
|
121
|
+
state.showBackgroundTaskManager,
|
|
122
|
+
);
|
|
123
|
+
}, [state.showBackgroundTaskManager]);
|
|
124
|
+
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
callbacksRef.current.onMcpManagerStateChange?.(state.showMcpManager);
|
|
127
|
+
}, [state.showMcpManager]);
|
|
128
|
+
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
callbacksRef.current.onRewindManagerStateChange?.(state.showRewindManager);
|
|
131
|
+
}, [state.showRewindManager]);
|
|
132
|
+
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
callbacksRef.current.onHelpStateChange?.(state.showHelp);
|
|
135
|
+
}, [state.showHelp]);
|
|
136
|
+
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
callbacksRef.current.onStatusCommandStateChange?.(state.showStatusCommand);
|
|
139
|
+
}, [state.showStatusCommand]);
|
|
140
|
+
|
|
141
|
+
useEffect(() => {
|
|
142
|
+
callbacksRef.current.onImagesStateChange?.(state.attachedImages);
|
|
143
|
+
}, [state.attachedImages]);
|
|
144
|
+
|
|
145
|
+
// Methods
|
|
146
|
+
const insertTextAtCursor = useCallback((text: string) => {
|
|
147
|
+
dispatch({ type: "INSERT_TEXT", payload: text });
|
|
148
|
+
}, []);
|
|
149
|
+
|
|
150
|
+
const deleteCharAtCursor = useCallback(() => {
|
|
151
|
+
dispatch({ type: "DELETE_CHAR" });
|
|
152
|
+
}, []);
|
|
154
153
|
|
|
155
154
|
const clearInput = useCallback(() => {
|
|
156
|
-
|
|
155
|
+
dispatch({ type: "CLEAR_INPUT" });
|
|
157
156
|
}, []);
|
|
158
157
|
|
|
159
158
|
const moveCursorLeft = useCallback(() => {
|
|
160
|
-
|
|
159
|
+
dispatch({ type: "MOVE_CURSOR", payload: -1 });
|
|
161
160
|
}, []);
|
|
162
161
|
|
|
163
162
|
const moveCursorRight = useCallback(() => {
|
|
164
|
-
|
|
163
|
+
dispatch({ type: "MOVE_CURSOR", payload: 1 });
|
|
165
164
|
}, []);
|
|
166
165
|
|
|
167
|
-
// File selector methods
|
|
168
166
|
const activateFileSelector = useCallback((position: number) => {
|
|
169
|
-
|
|
167
|
+
dispatch({ type: "ACTIVATE_FILE_SELECTOR", payload: position });
|
|
170
168
|
}, []);
|
|
171
169
|
|
|
172
|
-
const handleFileSelect = useCallback(
|
|
173
|
-
(
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
},
|
|
181
|
-
[inputText, cursorPosition],
|
|
182
|
-
);
|
|
170
|
+
const handleFileSelect = useCallback((filePath: string) => {
|
|
171
|
+
return handlers.handleFileSelect(
|
|
172
|
+
stateRef.current,
|
|
173
|
+
dispatch,
|
|
174
|
+
callbacksRef.current,
|
|
175
|
+
filePath,
|
|
176
|
+
);
|
|
177
|
+
}, []);
|
|
183
178
|
|
|
184
179
|
const handleCancelFileSelect = useCallback(() => {
|
|
185
|
-
|
|
180
|
+
dispatch({ type: "CANCEL_FILE_SELECTOR" });
|
|
186
181
|
}, []);
|
|
187
182
|
|
|
188
183
|
const updateFileSearchQuery = useCallback((query: string) => {
|
|
189
|
-
|
|
184
|
+
dispatch({ type: "SET_FILE_SEARCH_QUERY", payload: query });
|
|
190
185
|
}, []);
|
|
191
186
|
|
|
192
187
|
const checkForAtDeletion = useCallback((cursorPos: number) => {
|
|
193
|
-
return
|
|
188
|
+
return handlers.checkForAtDeletion(stateRef.current, dispatch, cursorPos);
|
|
194
189
|
}, []);
|
|
195
190
|
|
|
196
|
-
// Command selector methods
|
|
197
191
|
const activateCommandSelector = useCallback((position: number) => {
|
|
198
|
-
|
|
192
|
+
dispatch({ type: "ACTIVATE_COMMAND_SELECTOR", payload: position });
|
|
199
193
|
}, []);
|
|
200
194
|
|
|
201
|
-
const handleCommandSelect = useCallback(
|
|
202
|
-
(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
},
|
|
210
|
-
[inputText, cursorPosition],
|
|
211
|
-
);
|
|
195
|
+
const handleCommandSelect = useCallback((command: string) => {
|
|
196
|
+
return handlers.handleCommandSelect(
|
|
197
|
+
stateRef.current,
|
|
198
|
+
dispatch,
|
|
199
|
+
callbacksRef.current,
|
|
200
|
+
command,
|
|
201
|
+
);
|
|
202
|
+
}, []);
|
|
212
203
|
|
|
213
|
-
const handleCommandInsert = useCallback(
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
204
|
+
const handleCommandInsert = useCallback((command: string) => {
|
|
205
|
+
const currentState = stateRef.current;
|
|
206
|
+
if (currentState.slashPosition >= 0) {
|
|
207
|
+
const beforeSlash = currentState.inputText.substring(
|
|
208
|
+
0,
|
|
209
|
+
currentState.slashPosition,
|
|
220
210
|
);
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
211
|
+
const afterQuery = currentState.inputText.substring(
|
|
212
|
+
currentState.cursorPosition,
|
|
213
|
+
);
|
|
214
|
+
const newInput = beforeSlash + `/${command} ` + afterQuery;
|
|
215
|
+
const newCursorPosition = beforeSlash.length + command.length + 2;
|
|
216
|
+
|
|
217
|
+
dispatch({ type: "SET_INPUT_TEXT", payload: newInput });
|
|
218
|
+
dispatch({ type: "SET_CURSOR_POSITION", payload: newCursorPosition });
|
|
219
|
+
dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
|
|
220
|
+
|
|
221
|
+
callbacksRef.current.onInputTextChange?.(newInput);
|
|
222
|
+
callbacksRef.current.onCursorPositionChange?.(newCursorPosition);
|
|
223
|
+
|
|
224
|
+
return { newInput, newCursorPosition };
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
newInput: currentState.inputText,
|
|
228
|
+
newCursorPosition: currentState.cursorPosition,
|
|
229
|
+
};
|
|
230
|
+
}, []);
|
|
224
231
|
|
|
225
232
|
const handleCancelCommandSelect = useCallback(() => {
|
|
226
|
-
|
|
233
|
+
dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
|
|
227
234
|
}, []);
|
|
228
235
|
|
|
229
236
|
const updateCommandSearchQuery = useCallback((query: string) => {
|
|
230
|
-
|
|
237
|
+
dispatch({ type: "SET_COMMAND_SEARCH_QUERY", payload: query });
|
|
231
238
|
}, []);
|
|
232
239
|
|
|
233
240
|
const checkForSlashDeletion = useCallback((cursorPos: number) => {
|
|
234
|
-
return
|
|
241
|
+
return handlers.checkForSlashDeletion(
|
|
242
|
+
stateRef.current,
|
|
243
|
+
dispatch,
|
|
244
|
+
cursorPos,
|
|
245
|
+
);
|
|
235
246
|
}, []);
|
|
236
247
|
|
|
237
|
-
// History search methods
|
|
238
248
|
const handleHistorySearchSelect = useCallback((prompt: string) => {
|
|
239
|
-
|
|
249
|
+
dispatch({ type: "SET_INPUT_TEXT", payload: prompt });
|
|
250
|
+
dispatch({ type: "SET_CURSOR_POSITION", payload: prompt.length });
|
|
251
|
+
dispatch({ type: "CANCEL_HISTORY_SEARCH" });
|
|
240
252
|
}, []);
|
|
241
253
|
|
|
242
254
|
const handleCancelHistorySearch = useCallback(() => {
|
|
243
|
-
|
|
255
|
+
dispatch({ type: "CANCEL_HISTORY_SEARCH" });
|
|
244
256
|
}, []);
|
|
245
257
|
|
|
246
|
-
// Special character handling
|
|
247
258
|
const handleSpecialCharInput = useCallback((char: string) => {
|
|
248
|
-
|
|
259
|
+
handlers.handleSpecialCharInput(
|
|
260
|
+
stateRef.current,
|
|
261
|
+
dispatch,
|
|
262
|
+
char,
|
|
263
|
+
stateRef.current.cursorPosition,
|
|
264
|
+
stateRef.current.inputText,
|
|
265
|
+
);
|
|
266
|
+
}, []);
|
|
267
|
+
|
|
268
|
+
const setInputText = useCallback((text: string) => {
|
|
269
|
+
dispatch({ type: "SET_INPUT_TEXT", payload: text });
|
|
270
|
+
}, []);
|
|
271
|
+
|
|
272
|
+
const setCursorPosition = useCallback((position: number) => {
|
|
273
|
+
dispatch({ type: "SET_CURSOR_POSITION", payload: position });
|
|
274
|
+
}, []);
|
|
275
|
+
|
|
276
|
+
const setShowBackgroundTaskManager = useCallback((show: boolean) => {
|
|
277
|
+
dispatch({ type: "SET_SHOW_BACKGROUND_TASK_MANAGER", payload: show });
|
|
278
|
+
}, []);
|
|
279
|
+
|
|
280
|
+
const setShowMcpManager = useCallback((show: boolean) => {
|
|
281
|
+
dispatch({ type: "SET_SHOW_MCP_MANAGER", payload: show });
|
|
282
|
+
}, []);
|
|
283
|
+
|
|
284
|
+
const setShowRewindManager = useCallback((show: boolean) => {
|
|
285
|
+
dispatch({ type: "SET_SHOW_REWIND_MANAGER", payload: show });
|
|
286
|
+
}, []);
|
|
287
|
+
|
|
288
|
+
const setShowHelp = useCallback((show: boolean) => {
|
|
289
|
+
dispatch({ type: "SET_SHOW_HELP", payload: show });
|
|
290
|
+
}, []);
|
|
291
|
+
|
|
292
|
+
const setShowStatusCommand = useCallback((show: boolean) => {
|
|
293
|
+
dispatch({ type: "SET_SHOW_STATUS_COMMAND", payload: show });
|
|
294
|
+
}, []);
|
|
295
|
+
|
|
296
|
+
const setPermissionMode = useCallback((mode: PermissionMode) => {
|
|
297
|
+
dispatch({ type: "SET_PERMISSION_MODE", payload: mode });
|
|
298
|
+
callbacksRef.current.onPermissionModeChange?.(mode);
|
|
299
|
+
}, []);
|
|
300
|
+
|
|
301
|
+
const addImage = useCallback((imagePath: string, mimeType: string) => {
|
|
302
|
+
dispatch({ type: "ADD_IMAGE", payload: { path: imagePath, mimeType } });
|
|
303
|
+
}, []);
|
|
304
|
+
|
|
305
|
+
const removeImage = useCallback((imageId: number) => {
|
|
306
|
+
dispatch({ type: "REMOVE_IMAGE", payload: imageId });
|
|
249
307
|
}, []);
|
|
250
308
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
managerRef.current?.setInputText(text);
|
|
309
|
+
const clearImages = useCallback(() => {
|
|
310
|
+
dispatch({ type: "CLEAR_IMAGES" });
|
|
254
311
|
}, []);
|
|
255
312
|
|
|
256
|
-
const
|
|
257
|
-
|
|
313
|
+
const handlePasteImage = useCallback(async () => {
|
|
314
|
+
return await handlers.handlePasteImage(dispatch);
|
|
258
315
|
}, []);
|
|
259
316
|
|
|
260
|
-
|
|
317
|
+
const handlePasteInput = useCallback((input: string) => {
|
|
318
|
+
handlers.handlePasteInput(
|
|
319
|
+
stateRef.current,
|
|
320
|
+
dispatch,
|
|
321
|
+
callbacksRef.current,
|
|
322
|
+
input,
|
|
323
|
+
);
|
|
324
|
+
}, []);
|
|
325
|
+
|
|
326
|
+
const handleSubmit = useCallback(
|
|
327
|
+
async (
|
|
328
|
+
attachedImages: Array<{ id: number; path: string; mimeType: string }>,
|
|
329
|
+
isLoading: boolean = false,
|
|
330
|
+
isCommandRunning: boolean = false,
|
|
331
|
+
) => {
|
|
332
|
+
await handlers.handleSubmit(
|
|
333
|
+
stateRef.current,
|
|
334
|
+
dispatch,
|
|
335
|
+
callbacksRef.current,
|
|
336
|
+
isLoading,
|
|
337
|
+
isCommandRunning,
|
|
338
|
+
attachedImages,
|
|
339
|
+
);
|
|
340
|
+
},
|
|
341
|
+
[],
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
const expandLongTextPlaceholders = useCallback((text: string) => {
|
|
345
|
+
return handlers.expandLongTextPlaceholders(
|
|
346
|
+
text,
|
|
347
|
+
stateRef.current.longTextMap,
|
|
348
|
+
);
|
|
349
|
+
}, []);
|
|
350
|
+
|
|
351
|
+
const clearLongTextMap = useCallback(() => {
|
|
352
|
+
dispatch({ type: "CLEAR_LONG_TEXT_MAP" });
|
|
353
|
+
}, []);
|
|
354
|
+
|
|
355
|
+
const handleInput = useCallback(
|
|
356
|
+
async (
|
|
357
|
+
input: string,
|
|
358
|
+
key: Key,
|
|
359
|
+
attachedImages: Array<{ id: number; path: string; mimeType: string }>,
|
|
360
|
+
isLoading: boolean = false,
|
|
361
|
+
isCommandRunning: boolean = false,
|
|
362
|
+
clearImages?: () => void,
|
|
363
|
+
) => {
|
|
364
|
+
return await handlers.handleInput(
|
|
365
|
+
stateRef.current,
|
|
366
|
+
dispatch,
|
|
367
|
+
callbacksRef.current,
|
|
368
|
+
input,
|
|
369
|
+
key,
|
|
370
|
+
isLoading,
|
|
371
|
+
isCommandRunning,
|
|
372
|
+
clearImages,
|
|
373
|
+
);
|
|
374
|
+
},
|
|
375
|
+
[],
|
|
376
|
+
);
|
|
377
|
+
|
|
261
378
|
return {
|
|
262
379
|
// State
|
|
263
|
-
inputText,
|
|
264
|
-
cursorPosition,
|
|
265
|
-
showFileSelector:
|
|
266
|
-
filteredFiles:
|
|
267
|
-
fileSearchQuery:
|
|
268
|
-
atPosition:
|
|
269
|
-
showCommandSelector:
|
|
270
|
-
commandSearchQuery:
|
|
271
|
-
slashPosition:
|
|
272
|
-
showHistorySearch:
|
|
273
|
-
historySearchQuery:
|
|
274
|
-
showBackgroundTaskManager,
|
|
275
|
-
showMcpManager,
|
|
276
|
-
showRewindManager,
|
|
277
|
-
showHelp,
|
|
278
|
-
showStatusCommand,
|
|
279
|
-
permissionMode,
|
|
280
|
-
attachedImages,
|
|
281
|
-
isManagerReady,
|
|
380
|
+
inputText: state.inputText,
|
|
381
|
+
cursorPosition: state.cursorPosition,
|
|
382
|
+
showFileSelector: state.showFileSelector,
|
|
383
|
+
filteredFiles: state.filteredFiles,
|
|
384
|
+
fileSearchQuery: state.fileSearchQuery,
|
|
385
|
+
atPosition: state.atPosition,
|
|
386
|
+
showCommandSelector: state.showCommandSelector,
|
|
387
|
+
commandSearchQuery: state.commandSearchQuery,
|
|
388
|
+
slashPosition: state.slashPosition,
|
|
389
|
+
showHistorySearch: state.showHistorySearch,
|
|
390
|
+
historySearchQuery: state.historySearchQuery,
|
|
391
|
+
showBackgroundTaskManager: state.showBackgroundTaskManager,
|
|
392
|
+
showMcpManager: state.showMcpManager,
|
|
393
|
+
showRewindManager: state.showRewindManager,
|
|
394
|
+
showHelp: state.showHelp,
|
|
395
|
+
showStatusCommand: state.showStatusCommand,
|
|
396
|
+
permissionMode: state.permissionMode,
|
|
397
|
+
attachedImages: state.attachedImages,
|
|
398
|
+
isManagerReady: true,
|
|
282
399
|
|
|
283
400
|
// Methods
|
|
284
401
|
insertTextAtCursor,
|
|
@@ -310,97 +427,33 @@ export const useInputManager = (
|
|
|
310
427
|
handleSpecialCharInput,
|
|
311
428
|
|
|
312
429
|
// Bash/MCP Manager
|
|
313
|
-
setShowBackgroundTaskManager
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
setShowRewindManager: useCallback((show: boolean) => {
|
|
320
|
-
managerRef.current?.setShowRewindManager(show);
|
|
321
|
-
setShowRewindManager(show);
|
|
322
|
-
}, []),
|
|
323
|
-
setShowHelp: useCallback((show: boolean) => {
|
|
324
|
-
managerRef.current?.setShowHelp(show);
|
|
325
|
-
setShowHelp(show);
|
|
326
|
-
}, []),
|
|
327
|
-
setShowStatusCommand: useCallback((show: boolean) => {
|
|
328
|
-
managerRef.current?.setShowStatusCommand(show);
|
|
329
|
-
setShowStatusCommand(show);
|
|
330
|
-
}, []),
|
|
331
|
-
setPermissionMode: useCallback((mode: PermissionMode) => {
|
|
332
|
-
setPermissionModeState(mode);
|
|
333
|
-
managerRef.current?.setPermissionMode(mode);
|
|
334
|
-
}, []),
|
|
430
|
+
setShowBackgroundTaskManager,
|
|
431
|
+
setShowMcpManager,
|
|
432
|
+
setShowRewindManager,
|
|
433
|
+
setShowHelp,
|
|
434
|
+
setShowStatusCommand,
|
|
435
|
+
setPermissionMode,
|
|
335
436
|
|
|
336
437
|
// Image management
|
|
337
|
-
addImage
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
managerRef.current?.removeImage(imageId);
|
|
342
|
-
}, []),
|
|
343
|
-
clearImages: useCallback(() => {
|
|
344
|
-
managerRef.current?.clearImages();
|
|
345
|
-
}, []),
|
|
346
|
-
handlePasteImage: useCallback(async () => {
|
|
347
|
-
return (await managerRef.current?.handlePasteImage()) || false;
|
|
348
|
-
}, []),
|
|
438
|
+
addImage,
|
|
439
|
+
removeImage,
|
|
440
|
+
clearImages,
|
|
441
|
+
handlePasteImage,
|
|
349
442
|
|
|
350
443
|
// Paste and text handling
|
|
351
|
-
handlePasteInput
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
async (
|
|
356
|
-
attachedImages: Array<{ id: number; path: string; mimeType: string }>,
|
|
357
|
-
isLoading: boolean = false,
|
|
358
|
-
isCommandRunning: boolean = false,
|
|
359
|
-
) => {
|
|
360
|
-
await managerRef.current?.handleSubmit(
|
|
361
|
-
attachedImages,
|
|
362
|
-
isLoading,
|
|
363
|
-
isCommandRunning,
|
|
364
|
-
);
|
|
365
|
-
},
|
|
366
|
-
[],
|
|
367
|
-
),
|
|
368
|
-
expandLongTextPlaceholders: useCallback((text: string) => {
|
|
369
|
-
return managerRef.current?.expandLongTextPlaceholders(text) || text;
|
|
370
|
-
}, []),
|
|
371
|
-
clearLongTextMap: useCallback(() => {
|
|
372
|
-
managerRef.current?.clearLongTextMap();
|
|
373
|
-
}, []),
|
|
444
|
+
handlePasteInput,
|
|
445
|
+
handleSubmit,
|
|
446
|
+
expandLongTextPlaceholders,
|
|
447
|
+
clearLongTextMap,
|
|
374
448
|
|
|
375
449
|
// Main input handler
|
|
376
|
-
handleInput
|
|
377
|
-
async (
|
|
378
|
-
input: string,
|
|
379
|
-
key: Key,
|
|
380
|
-
attachedImages: Array<{ id: number; path: string; mimeType: string }>,
|
|
381
|
-
isLoading: boolean = false,
|
|
382
|
-
isCommandRunning: boolean = false,
|
|
383
|
-
clearImages?: () => void,
|
|
384
|
-
) => {
|
|
385
|
-
return (
|
|
386
|
-
(await managerRef.current?.handleInput(
|
|
387
|
-
input,
|
|
388
|
-
key,
|
|
389
|
-
attachedImages,
|
|
390
|
-
isLoading,
|
|
391
|
-
isCommandRunning,
|
|
392
|
-
clearImages,
|
|
393
|
-
)) || false
|
|
394
|
-
);
|
|
395
|
-
},
|
|
396
|
-
[],
|
|
397
|
-
),
|
|
450
|
+
handleInput,
|
|
398
451
|
|
|
399
|
-
// Direct state setters
|
|
400
|
-
setInputText
|
|
401
|
-
setCursorPosition
|
|
452
|
+
// Direct state setters
|
|
453
|
+
setInputText,
|
|
454
|
+
setCursorPosition,
|
|
402
455
|
|
|
403
|
-
// Manager reference for
|
|
404
|
-
manager:
|
|
456
|
+
// Manager reference (for compatibility, though it's null now)
|
|
457
|
+
manager: null,
|
|
405
458
|
};
|
|
406
459
|
};
|