wave-code 0.14.4 → 0.15.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/acp/agent.d.ts.map +1 -1
- package/dist/acp/agent.js +10 -0
- package/dist/components/BackgroundTaskManager.d.ts.map +1 -1
- package/dist/components/BackgroundTaskManager.js +17 -53
- package/dist/components/CommandSelector.d.ts.map +1 -1
- package/dist/components/CommandSelector.js +38 -28
- package/dist/components/ConfirmationSelector.d.ts.map +1 -1
- package/dist/components/ConfirmationSelector.js +18 -196
- package/dist/components/DiscoverView.d.ts.map +1 -1
- package/dist/components/DiscoverView.js +19 -11
- package/dist/components/FileSelector.d.ts.map +1 -1
- package/dist/components/FileSelector.js +29 -25
- package/dist/components/HelpView.d.ts.map +1 -1
- package/dist/components/HelpView.js +24 -28
- package/dist/components/HistorySearch.d.ts.map +1 -1
- package/dist/components/HistorySearch.js +26 -28
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +14 -6
- package/dist/components/InstalledView.d.ts.map +1 -1
- package/dist/components/InstalledView.js +19 -11
- package/dist/components/MarketplaceDetail.d.ts.map +1 -1
- package/dist/components/MarketplaceDetail.js +35 -16
- package/dist/components/MarketplaceView.d.ts.map +1 -1
- package/dist/components/MarketplaceView.js +21 -12
- package/dist/components/McpManager.d.ts.map +1 -1
- package/dist/components/McpManager.js +27 -46
- package/dist/components/ModelSelector.d.ts.map +1 -1
- package/dist/components/ModelSelector.js +27 -17
- package/dist/components/PluginDetail.d.ts.map +1 -1
- package/dist/components/PluginDetail.js +39 -26
- package/dist/components/RewindCommand.d.ts.map +1 -1
- package/dist/components/RewindCommand.js +27 -21
- package/dist/components/SessionSelector.d.ts.map +1 -1
- package/dist/components/SessionSelector.js +21 -16
- package/dist/components/StatusLine.d.ts.map +1 -1
- package/dist/components/StatusLine.js +5 -1
- package/dist/components/WorktreeExitPrompt.d.ts.map +1 -1
- package/dist/components/WorktreeExitPrompt.js +21 -12
- package/dist/contexts/useChat.d.ts +0 -1
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +13 -20
- package/dist/hooks/useInputManager.d.ts +5 -19
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +222 -79
- package/dist/managers/inputHandlers.d.ts +1 -1
- package/dist/managers/inputHandlers.d.ts.map +1 -1
- package/dist/managers/inputHandlers.js +3 -6
- package/dist/managers/inputReducer.d.ts +46 -4
- package/dist/managers/inputReducer.d.ts.map +1 -1
- package/dist/managers/inputReducer.js +519 -4
- package/dist/print-cli.d.ts.map +1 -1
- package/dist/print-cli.js +21 -9
- package/dist/reducers/backgroundTaskManagerReducer.d.ts +20 -0
- package/dist/reducers/backgroundTaskManagerReducer.d.ts.map +1 -1
- package/dist/reducers/backgroundTaskManagerReducer.js +83 -0
- package/dist/reducers/confirmationReducer.d.ts +11 -0
- package/dist/reducers/confirmationReducer.d.ts.map +1 -1
- package/dist/reducers/confirmationReducer.js +146 -0
- package/dist/reducers/helpSelectorReducer.d.ts +26 -0
- package/dist/reducers/helpSelectorReducer.d.ts.map +1 -0
- package/dist/reducers/helpSelectorReducer.js +52 -0
- package/dist/reducers/mcpManagerReducer.d.ts +22 -0
- package/dist/reducers/mcpManagerReducer.d.ts.map +1 -1
- package/dist/reducers/mcpManagerReducer.js +57 -0
- package/dist/reducers/pluginDetailReducer.d.ts +8 -0
- package/dist/reducers/pluginDetailReducer.d.ts.map +1 -1
- package/dist/reducers/pluginDetailReducer.js +32 -0
- package/dist/reducers/questionReducer.d.ts +21 -0
- package/dist/reducers/questionReducer.d.ts.map +1 -1
- package/dist/reducers/questionReducer.js +177 -0
- package/dist/reducers/rewindSelectorReducer.d.ts +22 -0
- package/dist/reducers/rewindSelectorReducer.d.ts.map +1 -0
- package/dist/reducers/rewindSelectorReducer.js +37 -0
- package/dist/reducers/selectorReducer.d.ts +22 -0
- package/dist/reducers/selectorReducer.d.ts.map +1 -0
- package/dist/reducers/selectorReducer.js +40 -0
- package/dist/utils/inputUtils.d.ts +18 -0
- package/dist/utils/inputUtils.d.ts.map +1 -0
- package/dist/utils/inputUtils.js +67 -0
- package/dist/utils/worktree.d.ts.map +1 -1
- package/dist/utils/worktree.js +1 -2
- package/package.json +2 -2
- package/src/acp/agent.ts +10 -0
- package/src/components/BackgroundTaskManager.tsx +19 -58
- package/src/components/CommandSelector.tsx +53 -44
- package/src/components/ConfirmationSelector.tsx +18 -202
- package/src/components/DiscoverView.tsx +21 -11
- package/src/components/FileSelector.tsx +40 -35
- package/src/components/HelpView.tsx +37 -43
- package/src/components/HistorySearch.tsx +29 -36
- package/src/components/InputBox.tsx +14 -7
- package/src/components/InstalledView.tsx +21 -11
- package/src/components/MarketplaceDetail.tsx +48 -24
- package/src/components/MarketplaceView.tsx +25 -10
- package/src/components/McpManager.tsx +29 -54
- package/src/components/ModelSelector.tsx +30 -23
- package/src/components/PluginDetail.tsx +50 -27
- package/src/components/RewindCommand.tsx +38 -32
- package/src/components/SessionSelector.tsx +23 -20
- package/src/components/StatusLine.tsx +10 -1
- package/src/components/WorktreeExitPrompt.tsx +23 -13
- package/src/contexts/useChat.tsx +13 -31
- package/src/hooks/useInputManager.ts +273 -141
- package/src/managers/inputHandlers.ts +1 -6
- package/src/managers/inputReducer.ts +675 -7
- package/src/print-cli.ts +20 -11
- package/src/reducers/backgroundTaskManagerReducer.ts +110 -1
- package/src/reducers/confirmationReducer.ts +173 -1
- package/src/reducers/helpSelectorReducer.ts +77 -0
- package/src/reducers/mcpManagerReducer.ts +82 -1
- package/src/reducers/pluginDetailReducer.ts +42 -1
- package/src/reducers/questionReducer.ts +204 -0
- package/src/reducers/rewindSelectorReducer.ts +54 -0
- package/src/reducers/selectorReducer.ts +57 -0
- package/src/utils/inputUtils.ts +94 -0
- package/src/utils/worktree.ts +1 -7
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useReducer, useCallback
|
|
1
|
+
import { useEffect, useReducer, useCallback } from "react";
|
|
2
2
|
import { Key } from "ink";
|
|
3
3
|
import {
|
|
4
4
|
inputReducer,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
searchFiles as searchFilesUtil,
|
|
10
10
|
PermissionMode,
|
|
11
11
|
PromptEntry,
|
|
12
|
+
PromptHistoryManager,
|
|
12
13
|
} from "wave-agent-sdk";
|
|
13
14
|
import * as handlers from "../managers/inputHandlers.js";
|
|
14
15
|
|
|
@@ -16,17 +17,32 @@ export const useInputManager = (
|
|
|
16
17
|
callbacks: Partial<InputManagerCallbacks> = {},
|
|
17
18
|
) => {
|
|
18
19
|
const [state, dispatch] = useReducer(inputReducer, initialState);
|
|
19
|
-
const callbacksRef = useRef(callbacks);
|
|
20
|
-
const stateRef = useRef(state);
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
const {
|
|
22
|
+
onInputTextChange,
|
|
23
|
+
onCursorPositionChange,
|
|
24
|
+
onFileSelectorStateChange,
|
|
25
|
+
onCommandSelectorStateChange,
|
|
26
|
+
onHistorySearchStateChange,
|
|
27
|
+
onBackgroundTaskManagerStateChange,
|
|
28
|
+
onMcpManagerStateChange,
|
|
29
|
+
onRewindManagerStateChange,
|
|
30
|
+
onHelpStateChange,
|
|
31
|
+
onStatusCommandStateChange,
|
|
32
|
+
onPluginManagerStateChange,
|
|
33
|
+
onModelSelectorStateChange,
|
|
34
|
+
onImagesStateChange,
|
|
35
|
+
onSendMessage,
|
|
36
|
+
onHasSlashCommand,
|
|
37
|
+
onAbortMessage,
|
|
38
|
+
onBackgroundCurrentTask,
|
|
39
|
+
onPermissionModeChange,
|
|
40
|
+
onAskBtw,
|
|
41
|
+
sessionId,
|
|
42
|
+
workdir,
|
|
43
|
+
getFullMessageThread,
|
|
44
|
+
logger,
|
|
45
|
+
} = callbacks;
|
|
30
46
|
|
|
31
47
|
// Handle selectorJustUsed reset
|
|
32
48
|
useEffect(() => {
|
|
@@ -66,10 +82,7 @@ export const useInputManager = (
|
|
|
66
82
|
10,
|
|
67
83
|
);
|
|
68
84
|
const timer = setTimeout(() => {
|
|
69
|
-
const processedInput =
|
|
70
|
-
/\r/g,
|
|
71
|
-
"\n",
|
|
72
|
-
);
|
|
85
|
+
const processedInput = state.pasteBuffer.replace(/\r/g, "\n");
|
|
73
86
|
dispatch({
|
|
74
87
|
type: "INSERT_TEXT_WITH_PLACEHOLDER",
|
|
75
88
|
payload: processedInput,
|
|
@@ -83,15 +96,154 @@ export const useInputManager = (
|
|
|
83
96
|
|
|
84
97
|
// Sync state changes with callbacks
|
|
85
98
|
useEffect(() => {
|
|
86
|
-
|
|
87
|
-
}, [state.inputText]);
|
|
99
|
+
onInputTextChange?.(state.inputText);
|
|
100
|
+
}, [state.inputText, onInputTextChange]);
|
|
88
101
|
|
|
89
102
|
useEffect(() => {
|
|
90
|
-
|
|
91
|
-
}, [state.cursorPosition]);
|
|
103
|
+
onCursorPositionChange?.(state.cursorPosition);
|
|
104
|
+
}, [state.cursorPosition, onCursorPositionChange]);
|
|
92
105
|
|
|
106
|
+
// Handle pending effects
|
|
93
107
|
useEffect(() => {
|
|
94
|
-
|
|
108
|
+
if (!state.pendingEffect) return;
|
|
109
|
+
|
|
110
|
+
const effect = state.pendingEffect;
|
|
111
|
+
dispatch({ type: "CLEAR_PENDING_EFFECT" });
|
|
112
|
+
|
|
113
|
+
const runEffect = async () => {
|
|
114
|
+
try {
|
|
115
|
+
switch (effect.type) {
|
|
116
|
+
case "SEND_MESSAGE":
|
|
117
|
+
await onSendMessage?.(
|
|
118
|
+
effect.content,
|
|
119
|
+
effect.images,
|
|
120
|
+
effect.longTextMap,
|
|
121
|
+
);
|
|
122
|
+
PromptHistoryManager.addEntry(
|
|
123
|
+
effect.content,
|
|
124
|
+
sessionId,
|
|
125
|
+
effect.longTextMap,
|
|
126
|
+
workdir,
|
|
127
|
+
).catch((err: unknown) => {
|
|
128
|
+
logger?.error("Failed to save prompt history", err);
|
|
129
|
+
});
|
|
130
|
+
break;
|
|
131
|
+
case "ABORT_MESSAGE":
|
|
132
|
+
onAbortMessage?.();
|
|
133
|
+
break;
|
|
134
|
+
case "BACKGROUND_CURRENT_TASK":
|
|
135
|
+
onBackgroundCurrentTask?.();
|
|
136
|
+
break;
|
|
137
|
+
case "ASK_BTW":
|
|
138
|
+
try {
|
|
139
|
+
const answer = await onAskBtw?.(effect.question);
|
|
140
|
+
dispatch({
|
|
141
|
+
type: "SET_BTW_STATE",
|
|
142
|
+
payload: { answer, isLoading: false },
|
|
143
|
+
});
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.error("Failed to ask side question:", error);
|
|
146
|
+
dispatch({
|
|
147
|
+
type: "SET_BTW_STATE",
|
|
148
|
+
payload: {
|
|
149
|
+
answer:
|
|
150
|
+
"Error: Failed to get an answer for your side question.",
|
|
151
|
+
isLoading: false,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
break;
|
|
156
|
+
case "PERMISSION_MODE_CHANGE":
|
|
157
|
+
onPermissionModeChange?.(effect.mode);
|
|
158
|
+
break;
|
|
159
|
+
case "FETCH_HISTORY": {
|
|
160
|
+
let sessionIds: string[] | undefined = sessionId
|
|
161
|
+
? [sessionId]
|
|
162
|
+
: undefined;
|
|
163
|
+
|
|
164
|
+
if (getFullMessageThread) {
|
|
165
|
+
try {
|
|
166
|
+
const thread = await getFullMessageThread();
|
|
167
|
+
sessionIds = thread.sessionIds;
|
|
168
|
+
} catch (error) {
|
|
169
|
+
logger?.error("Failed to fetch ancestor session IDs", error);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const history = await PromptHistoryManager.getHistory({
|
|
174
|
+
sessionId: sessionIds,
|
|
175
|
+
workdir: workdir,
|
|
176
|
+
});
|
|
177
|
+
dispatch({ type: "SET_HISTORY_ENTRIES", payload: history });
|
|
178
|
+
dispatch({ type: "NAVIGATE_HISTORY", payload: "up" });
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
case "PASTE_IMAGE":
|
|
182
|
+
try {
|
|
183
|
+
await handlers.handlePasteImage(dispatch);
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.warn("Failed to handle paste image:", error);
|
|
186
|
+
}
|
|
187
|
+
break;
|
|
188
|
+
case "EXECUTE_COMMAND":
|
|
189
|
+
if (onSendMessage && onHasSlashCommand?.(effect.command)) {
|
|
190
|
+
const fullCommand = `/${effect.command}`;
|
|
191
|
+
try {
|
|
192
|
+
await onSendMessage(fullCommand, undefined, {});
|
|
193
|
+
} catch (error) {
|
|
194
|
+
console.error("Failed to execute slash command:", error);
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
// Internal command handling
|
|
198
|
+
const command = effect.command;
|
|
199
|
+
if (command === "tasks") {
|
|
200
|
+
dispatch({
|
|
201
|
+
type: "SET_SHOW_BACKGROUND_TASK_MANAGER",
|
|
202
|
+
payload: true,
|
|
203
|
+
});
|
|
204
|
+
} else if (command === "mcp") {
|
|
205
|
+
dispatch({ type: "SET_SHOW_MCP_MANAGER", payload: true });
|
|
206
|
+
} else if (command === "rewind") {
|
|
207
|
+
dispatch({ type: "SET_SHOW_REWIND_MANAGER", payload: true });
|
|
208
|
+
} else if (command === "help") {
|
|
209
|
+
dispatch({ type: "SET_SHOW_HELP", payload: true });
|
|
210
|
+
} else if (command === "status") {
|
|
211
|
+
dispatch({ type: "SET_SHOW_STATUS_COMMAND", payload: true });
|
|
212
|
+
} else if (command === "plugin") {
|
|
213
|
+
dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: true });
|
|
214
|
+
} else if (command === "model") {
|
|
215
|
+
dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: true });
|
|
216
|
+
} else if (command === "btw") {
|
|
217
|
+
dispatch({
|
|
218
|
+
type: "SET_BTW_STATE",
|
|
219
|
+
payload: { isActive: true, question: "", isLoading: false },
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
} catch (error) {
|
|
226
|
+
console.error("Effect execution error:", error);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
runEffect();
|
|
231
|
+
}, [
|
|
232
|
+
state.pendingEffect,
|
|
233
|
+
onSendMessage,
|
|
234
|
+
onAbortMessage,
|
|
235
|
+
onBackgroundCurrentTask,
|
|
236
|
+
onAskBtw,
|
|
237
|
+
onPermissionModeChange,
|
|
238
|
+
sessionId,
|
|
239
|
+
workdir,
|
|
240
|
+
getFullMessageThread,
|
|
241
|
+
logger,
|
|
242
|
+
onHasSlashCommand,
|
|
243
|
+
]);
|
|
244
|
+
|
|
245
|
+
useEffect(() => {
|
|
246
|
+
onFileSelectorStateChange?.(
|
|
95
247
|
state.showFileSelector,
|
|
96
248
|
state.filteredFiles,
|
|
97
249
|
state.fileSearchQuery,
|
|
@@ -102,10 +254,11 @@ export const useInputManager = (
|
|
|
102
254
|
state.filteredFiles,
|
|
103
255
|
state.fileSearchQuery,
|
|
104
256
|
state.atPosition,
|
|
257
|
+
onFileSelectorStateChange,
|
|
105
258
|
]);
|
|
106
259
|
|
|
107
260
|
useEffect(() => {
|
|
108
|
-
|
|
261
|
+
onCommandSelectorStateChange?.(
|
|
109
262
|
state.showCommandSelector,
|
|
110
263
|
state.commandSearchQuery,
|
|
111
264
|
state.slashPosition,
|
|
@@ -114,48 +267,51 @@ export const useInputManager = (
|
|
|
114
267
|
state.showCommandSelector,
|
|
115
268
|
state.commandSearchQuery,
|
|
116
269
|
state.slashPosition,
|
|
270
|
+
onCommandSelectorStateChange,
|
|
117
271
|
]);
|
|
118
272
|
|
|
119
273
|
useEffect(() => {
|
|
120
|
-
|
|
274
|
+
onHistorySearchStateChange?.(
|
|
121
275
|
state.showHistorySearch,
|
|
122
276
|
state.historySearchQuery,
|
|
123
277
|
);
|
|
124
|
-
}, [
|
|
278
|
+
}, [
|
|
279
|
+
state.showHistorySearch,
|
|
280
|
+
state.historySearchQuery,
|
|
281
|
+
onHistorySearchStateChange,
|
|
282
|
+
]);
|
|
125
283
|
|
|
126
284
|
useEffect(() => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
);
|
|
130
|
-
}, [state.showBackgroundTaskManager]);
|
|
285
|
+
onBackgroundTaskManagerStateChange?.(state.showBackgroundTaskManager);
|
|
286
|
+
}, [state.showBackgroundTaskManager, onBackgroundTaskManagerStateChange]);
|
|
131
287
|
|
|
132
288
|
useEffect(() => {
|
|
133
|
-
|
|
134
|
-
}, [state.showMcpManager]);
|
|
289
|
+
onMcpManagerStateChange?.(state.showMcpManager);
|
|
290
|
+
}, [state.showMcpManager, onMcpManagerStateChange]);
|
|
135
291
|
|
|
136
292
|
useEffect(() => {
|
|
137
|
-
|
|
138
|
-
}, [state.showRewindManager]);
|
|
293
|
+
onRewindManagerStateChange?.(state.showRewindManager);
|
|
294
|
+
}, [state.showRewindManager, onRewindManagerStateChange]);
|
|
139
295
|
|
|
140
296
|
useEffect(() => {
|
|
141
|
-
|
|
142
|
-
}, [state.showHelp]);
|
|
297
|
+
onHelpStateChange?.(state.showHelp);
|
|
298
|
+
}, [state.showHelp, onHelpStateChange]);
|
|
143
299
|
|
|
144
300
|
useEffect(() => {
|
|
145
|
-
|
|
146
|
-
}, [state.showStatusCommand]);
|
|
301
|
+
onStatusCommandStateChange?.(state.showStatusCommand);
|
|
302
|
+
}, [state.showStatusCommand, onStatusCommandStateChange]);
|
|
147
303
|
|
|
148
304
|
useEffect(() => {
|
|
149
|
-
|
|
150
|
-
}, [state.showPluginManager]);
|
|
305
|
+
onPluginManagerStateChange?.(state.showPluginManager);
|
|
306
|
+
}, [state.showPluginManager, onPluginManagerStateChange]);
|
|
151
307
|
|
|
152
308
|
useEffect(() => {
|
|
153
|
-
|
|
154
|
-
}, [state.showModelSelector]);
|
|
309
|
+
onModelSelectorStateChange?.(state.showModelSelector);
|
|
310
|
+
}, [state.showModelSelector, onModelSelectorStateChange]);
|
|
155
311
|
|
|
156
312
|
useEffect(() => {
|
|
157
|
-
|
|
158
|
-
}, [state.attachedImages]);
|
|
313
|
+
onImagesStateChange?.(state.attachedImages);
|
|
314
|
+
}, [state.attachedImages, onImagesStateChange]);
|
|
159
315
|
|
|
160
316
|
// Handle /btw side question
|
|
161
317
|
useEffect(() => {
|
|
@@ -166,9 +322,7 @@ export const useInputManager = (
|
|
|
166
322
|
) {
|
|
167
323
|
const askBtw = async () => {
|
|
168
324
|
try {
|
|
169
|
-
const answer = await
|
|
170
|
-
state.btwState.question,
|
|
171
|
-
);
|
|
325
|
+
const answer = await onAskBtw?.(state.btwState.question);
|
|
172
326
|
dispatch({
|
|
173
327
|
type: "SET_BTW_STATE",
|
|
174
328
|
payload: { answer, isLoading: false },
|
|
@@ -190,6 +344,7 @@ export const useInputManager = (
|
|
|
190
344
|
state.btwState.isActive,
|
|
191
345
|
state.btwState.isLoading,
|
|
192
346
|
state.btwState.question,
|
|
347
|
+
onAskBtw,
|
|
193
348
|
]);
|
|
194
349
|
|
|
195
350
|
// Methods
|
|
@@ -218,12 +373,7 @@ export const useInputManager = (
|
|
|
218
373
|
}, []);
|
|
219
374
|
|
|
220
375
|
const handleFileSelect = useCallback((filePath: string) => {
|
|
221
|
-
|
|
222
|
-
stateRef.current,
|
|
223
|
-
dispatch,
|
|
224
|
-
callbacksRef.current,
|
|
225
|
-
filePath,
|
|
226
|
-
);
|
|
376
|
+
dispatch({ type: "SELECT_FILE", payload: filePath });
|
|
227
377
|
}, []);
|
|
228
378
|
|
|
229
379
|
const handleCancelFileSelect = useCallback(() => {
|
|
@@ -234,51 +384,25 @@ export const useInputManager = (
|
|
|
234
384
|
dispatch({ type: "SET_FILE_SEARCH_QUERY", payload: query });
|
|
235
385
|
}, []);
|
|
236
386
|
|
|
237
|
-
const checkForAtDeletion = useCallback(
|
|
238
|
-
|
|
239
|
-
|
|
387
|
+
const checkForAtDeletion = useCallback(
|
|
388
|
+
(cursorPos: number) => {
|
|
389
|
+
// This is now largely handled inside HANDLE_KEY,
|
|
390
|
+
// but kept for external calls if any.
|
|
391
|
+
return handlers.checkForAtDeletion(state, dispatch, cursorPos);
|
|
392
|
+
},
|
|
393
|
+
[state],
|
|
394
|
+
);
|
|
240
395
|
|
|
241
396
|
const activateCommandSelector = useCallback((position: number) => {
|
|
242
397
|
dispatch({ type: "ACTIVATE_COMMAND_SELECTOR", payload: position });
|
|
243
398
|
}, []);
|
|
244
399
|
|
|
245
400
|
const handleCommandSelect = useCallback((command: string) => {
|
|
246
|
-
|
|
247
|
-
stateRef.current,
|
|
248
|
-
dispatch,
|
|
249
|
-
callbacksRef.current,
|
|
250
|
-
command,
|
|
251
|
-
);
|
|
401
|
+
dispatch({ type: "SELECT_COMMAND", payload: command });
|
|
252
402
|
}, []);
|
|
253
403
|
|
|
254
404
|
const handleCommandInsert = useCallback((command: string) => {
|
|
255
|
-
|
|
256
|
-
if (currentState.slashPosition >= 0) {
|
|
257
|
-
const wordEnd = handlers.getWordEnd(
|
|
258
|
-
currentState.inputText,
|
|
259
|
-
currentState.slashPosition,
|
|
260
|
-
);
|
|
261
|
-
const beforeSlash = currentState.inputText.substring(
|
|
262
|
-
0,
|
|
263
|
-
currentState.slashPosition,
|
|
264
|
-
);
|
|
265
|
-
const afterWord = currentState.inputText.substring(wordEnd);
|
|
266
|
-
const newInput = beforeSlash + `/${command} ` + afterWord;
|
|
267
|
-
const newCursorPosition = beforeSlash.length + command.length + 2;
|
|
268
|
-
|
|
269
|
-
dispatch({ type: "SET_INPUT_TEXT", payload: newInput });
|
|
270
|
-
dispatch({ type: "SET_CURSOR_POSITION", payload: newCursorPosition });
|
|
271
|
-
dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
|
|
272
|
-
|
|
273
|
-
callbacksRef.current.onInputTextChange?.(newInput);
|
|
274
|
-
callbacksRef.current.onCursorPositionChange?.(newCursorPosition);
|
|
275
|
-
|
|
276
|
-
return { newInput, newCursorPosition };
|
|
277
|
-
}
|
|
278
|
-
return {
|
|
279
|
-
newInput: currentState.inputText,
|
|
280
|
-
newCursorPosition: currentState.cursorPosition,
|
|
281
|
-
};
|
|
405
|
+
dispatch({ type: "INSERT_COMMAND", payload: command });
|
|
282
406
|
}, []);
|
|
283
407
|
|
|
284
408
|
const handleCancelCommandSelect = useCallback(() => {
|
|
@@ -289,13 +413,12 @@ export const useInputManager = (
|
|
|
289
413
|
dispatch({ type: "SET_COMMAND_SEARCH_QUERY", payload: query });
|
|
290
414
|
}, []);
|
|
291
415
|
|
|
292
|
-
const checkForSlashDeletion = useCallback(
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}, []);
|
|
416
|
+
const checkForSlashDeletion = useCallback(
|
|
417
|
+
(cursorPos: number) => {
|
|
418
|
+
return handlers.checkForSlashDeletion(state, dispatch, cursorPos);
|
|
419
|
+
},
|
|
420
|
+
[state],
|
|
421
|
+
);
|
|
299
422
|
|
|
300
423
|
const handleHistorySearchSelect = useCallback((entry: PromptEntry) => {
|
|
301
424
|
dispatch({ type: "SELECT_HISTORY_ENTRY", payload: entry });
|
|
@@ -305,9 +428,12 @@ export const useInputManager = (
|
|
|
305
428
|
dispatch({ type: "CANCEL_HISTORY_SEARCH" });
|
|
306
429
|
}, []);
|
|
307
430
|
|
|
308
|
-
const processSelectorInput = useCallback(
|
|
309
|
-
|
|
310
|
-
|
|
431
|
+
const processSelectorInput = useCallback(
|
|
432
|
+
(char: string) => {
|
|
433
|
+
handlers.processSelectorInput(state, dispatch, char);
|
|
434
|
+
},
|
|
435
|
+
[state],
|
|
436
|
+
);
|
|
311
437
|
|
|
312
438
|
const setInputText = useCallback((text: string) => {
|
|
313
439
|
dispatch({ type: "SET_INPUT_TEXT", payload: text });
|
|
@@ -345,14 +471,13 @@ export const useInputManager = (
|
|
|
345
471
|
dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: show });
|
|
346
472
|
}, []);
|
|
347
473
|
|
|
348
|
-
const setPermissionMode = useCallback(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}, []);
|
|
474
|
+
const setPermissionMode = useCallback(
|
|
475
|
+
(mode: PermissionMode) => {
|
|
476
|
+
dispatch({ type: "SET_PERMISSION_MODE", payload: mode });
|
|
477
|
+
onPermissionModeChange?.(mode);
|
|
478
|
+
},
|
|
479
|
+
[onPermissionModeChange],
|
|
480
|
+
);
|
|
356
481
|
|
|
357
482
|
const setBtwState = useCallback(
|
|
358
483
|
(payload: Partial<import("../managers/inputReducer.js").BtwState>) => {
|
|
@@ -377,35 +502,37 @@ export const useInputManager = (
|
|
|
377
502
|
return await handlers.handlePasteImage(dispatch);
|
|
378
503
|
}, []);
|
|
379
504
|
|
|
380
|
-
const handlePasteInput = useCallback(
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
async (
|
|
391
|
-
attachedImages: Array<{ id: number; path: string; mimeType: string }>,
|
|
392
|
-
) => {
|
|
393
|
-
await handlers.handleSubmit(
|
|
394
|
-
stateRef.current,
|
|
395
|
-
dispatch,
|
|
396
|
-
callbacksRef.current,
|
|
397
|
-
attachedImages,
|
|
398
|
-
);
|
|
505
|
+
const handlePasteInput = useCallback(
|
|
506
|
+
(input: string) => {
|
|
507
|
+
dispatch({
|
|
508
|
+
type: "HANDLE_KEY",
|
|
509
|
+
payload: {
|
|
510
|
+
input,
|
|
511
|
+
key: {} as Key,
|
|
512
|
+
hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
|
|
513
|
+
},
|
|
514
|
+
});
|
|
399
515
|
},
|
|
400
|
-
[],
|
|
516
|
+
[onHasSlashCommand],
|
|
401
517
|
);
|
|
402
518
|
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
519
|
+
const handleSubmit = useCallback(async () => {
|
|
520
|
+
dispatch({
|
|
521
|
+
type: "HANDLE_KEY",
|
|
522
|
+
payload: {
|
|
523
|
+
input: "",
|
|
524
|
+
key: { return: true } as Key,
|
|
525
|
+
hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
|
|
526
|
+
},
|
|
527
|
+
});
|
|
528
|
+
}, [onHasSlashCommand]);
|
|
529
|
+
|
|
530
|
+
const expandLongTextPlaceholders = useCallback(
|
|
531
|
+
(text: string) => {
|
|
532
|
+
return handlers.expandLongTextPlaceholders(text, state.longTextMap);
|
|
533
|
+
},
|
|
534
|
+
[state.longTextMap],
|
|
535
|
+
);
|
|
409
536
|
|
|
410
537
|
const clearLongTextMap = useCallback(() => {
|
|
411
538
|
dispatch({ type: "CLEAR_LONG_TEXT_MAP" });
|
|
@@ -415,19 +542,25 @@ export const useInputManager = (
|
|
|
415
542
|
async (
|
|
416
543
|
input: string,
|
|
417
544
|
key: Key,
|
|
418
|
-
|
|
545
|
+
_attachedImages: Array<{ id: number; path: string; mimeType: string }>,
|
|
419
546
|
clearImages?: () => void,
|
|
420
547
|
) => {
|
|
421
|
-
return
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
548
|
+
// Clear images side effect if return is pressed
|
|
549
|
+
if (key.return) {
|
|
550
|
+
clearImages?.();
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
dispatch({
|
|
554
|
+
type: "HANDLE_KEY",
|
|
555
|
+
payload: {
|
|
556
|
+
input,
|
|
557
|
+
key,
|
|
558
|
+
hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
|
|
559
|
+
},
|
|
560
|
+
});
|
|
561
|
+
return true;
|
|
429
562
|
},
|
|
430
|
-
[],
|
|
563
|
+
[onHasSlashCommand],
|
|
431
564
|
);
|
|
432
565
|
|
|
433
566
|
return {
|
|
@@ -494,7 +627,6 @@ export const useInputManager = (
|
|
|
494
627
|
setShowPluginManager,
|
|
495
628
|
setShowModelSelector,
|
|
496
629
|
setPermissionMode,
|
|
497
|
-
setAllowBypassInCycle,
|
|
498
630
|
setBtwState,
|
|
499
631
|
|
|
500
632
|
// Image management
|
|
@@ -124,12 +124,8 @@ export const cyclePermissionMode = (
|
|
|
124
124
|
currentMode: PermissionMode,
|
|
125
125
|
dispatch: React.Dispatch<InputAction>,
|
|
126
126
|
callbacks: Partial<InputManagerCallbacks>,
|
|
127
|
-
allowBypassInCycle: boolean = false,
|
|
128
127
|
) => {
|
|
129
|
-
const modes: PermissionMode[] = ["default", "acceptEdits", "plan"];
|
|
130
|
-
if (allowBypassInCycle) {
|
|
131
|
-
modes.push("bypassPermissions");
|
|
132
|
-
}
|
|
128
|
+
const modes: PermissionMode[] = ["default", "acceptEdits", "plan", "bypassPermissions"];
|
|
133
129
|
const currentIndex = modes.indexOf(currentMode);
|
|
134
130
|
const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % modes.length;
|
|
135
131
|
const nextMode = modes[nextIndex];
|
|
@@ -768,7 +764,6 @@ export const handleInput = async (
|
|
|
768
764
|
state.permissionMode,
|
|
769
765
|
dispatch,
|
|
770
766
|
callbacks,
|
|
771
|
-
state.allowBypassInCycle,
|
|
772
767
|
);
|
|
773
768
|
return true;
|
|
774
769
|
}
|