wave-code 0.14.3 → 0.15.0
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 +224 -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 +50 -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 +17 -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 +275 -141
- package/src/managers/inputHandlers.ts +1 -6
- package/src/managers/inputReducer.ts +680 -7
- package/src/print-cli.ts +15 -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,156 @@ 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
|
+
break;
|
|
123
|
+
case "ABORT_MESSAGE":
|
|
124
|
+
onAbortMessage?.();
|
|
125
|
+
break;
|
|
126
|
+
case "BACKGROUND_CURRENT_TASK":
|
|
127
|
+
onBackgroundCurrentTask?.();
|
|
128
|
+
break;
|
|
129
|
+
case "ASK_BTW":
|
|
130
|
+
try {
|
|
131
|
+
const answer = await onAskBtw?.(effect.question);
|
|
132
|
+
dispatch({
|
|
133
|
+
type: "SET_BTW_STATE",
|
|
134
|
+
payload: { answer, isLoading: false },
|
|
135
|
+
});
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.error("Failed to ask side question:", error);
|
|
138
|
+
dispatch({
|
|
139
|
+
type: "SET_BTW_STATE",
|
|
140
|
+
payload: {
|
|
141
|
+
answer:
|
|
142
|
+
"Error: Failed to get an answer for your side question.",
|
|
143
|
+
isLoading: false,
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
case "PERMISSION_MODE_CHANGE":
|
|
149
|
+
onPermissionModeChange?.(effect.mode);
|
|
150
|
+
break;
|
|
151
|
+
case "SAVE_HISTORY":
|
|
152
|
+
PromptHistoryManager.addEntry(
|
|
153
|
+
effect.content,
|
|
154
|
+
sessionId,
|
|
155
|
+
effect.longTextMap,
|
|
156
|
+
workdir,
|
|
157
|
+
).catch((err: unknown) => {
|
|
158
|
+
logger?.error("Failed to save prompt history", err);
|
|
159
|
+
});
|
|
160
|
+
break;
|
|
161
|
+
case "FETCH_HISTORY": {
|
|
162
|
+
let sessionIds: string[] | undefined = sessionId
|
|
163
|
+
? [sessionId]
|
|
164
|
+
: undefined;
|
|
165
|
+
|
|
166
|
+
if (getFullMessageThread) {
|
|
167
|
+
try {
|
|
168
|
+
const thread = await getFullMessageThread();
|
|
169
|
+
sessionIds = thread.sessionIds;
|
|
170
|
+
} catch (error) {
|
|
171
|
+
logger?.error("Failed to fetch ancestor session IDs", error);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const history = await PromptHistoryManager.getHistory({
|
|
176
|
+
sessionId: sessionIds,
|
|
177
|
+
workdir: workdir,
|
|
178
|
+
});
|
|
179
|
+
dispatch({ type: "SET_HISTORY_ENTRIES", payload: history });
|
|
180
|
+
dispatch({ type: "NAVIGATE_HISTORY", payload: "up" });
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
case "PASTE_IMAGE":
|
|
184
|
+
try {
|
|
185
|
+
await handlers.handlePasteImage(dispatch);
|
|
186
|
+
} catch (error) {
|
|
187
|
+
console.warn("Failed to handle paste image:", error);
|
|
188
|
+
}
|
|
189
|
+
break;
|
|
190
|
+
case "EXECUTE_COMMAND":
|
|
191
|
+
if (onSendMessage && onHasSlashCommand?.(effect.command)) {
|
|
192
|
+
const fullCommand = `/${effect.command}`;
|
|
193
|
+
try {
|
|
194
|
+
await onSendMessage(fullCommand, undefined, {});
|
|
195
|
+
} catch (error) {
|
|
196
|
+
console.error("Failed to execute slash command:", error);
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
// Internal command handling
|
|
200
|
+
const command = effect.command;
|
|
201
|
+
if (command === "tasks") {
|
|
202
|
+
dispatch({
|
|
203
|
+
type: "SET_SHOW_BACKGROUND_TASK_MANAGER",
|
|
204
|
+
payload: true,
|
|
205
|
+
});
|
|
206
|
+
} else if (command === "mcp") {
|
|
207
|
+
dispatch({ type: "SET_SHOW_MCP_MANAGER", payload: true });
|
|
208
|
+
} else if (command === "rewind") {
|
|
209
|
+
dispatch({ type: "SET_SHOW_REWIND_MANAGER", payload: true });
|
|
210
|
+
} else if (command === "help") {
|
|
211
|
+
dispatch({ type: "SET_SHOW_HELP", payload: true });
|
|
212
|
+
} else if (command === "status") {
|
|
213
|
+
dispatch({ type: "SET_SHOW_STATUS_COMMAND", payload: true });
|
|
214
|
+
} else if (command === "plugin") {
|
|
215
|
+
dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: true });
|
|
216
|
+
} else if (command === "model") {
|
|
217
|
+
dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: true });
|
|
218
|
+
} else if (command === "btw") {
|
|
219
|
+
dispatch({
|
|
220
|
+
type: "SET_BTW_STATE",
|
|
221
|
+
payload: { isActive: true, question: "", isLoading: false },
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
} catch (error) {
|
|
228
|
+
console.error("Effect execution error:", error);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
runEffect();
|
|
233
|
+
}, [
|
|
234
|
+
state.pendingEffect,
|
|
235
|
+
onSendMessage,
|
|
236
|
+
onAbortMessage,
|
|
237
|
+
onBackgroundCurrentTask,
|
|
238
|
+
onAskBtw,
|
|
239
|
+
onPermissionModeChange,
|
|
240
|
+
sessionId,
|
|
241
|
+
workdir,
|
|
242
|
+
getFullMessageThread,
|
|
243
|
+
logger,
|
|
244
|
+
onHasSlashCommand,
|
|
245
|
+
]);
|
|
246
|
+
|
|
247
|
+
useEffect(() => {
|
|
248
|
+
onFileSelectorStateChange?.(
|
|
95
249
|
state.showFileSelector,
|
|
96
250
|
state.filteredFiles,
|
|
97
251
|
state.fileSearchQuery,
|
|
@@ -102,10 +256,11 @@ export const useInputManager = (
|
|
|
102
256
|
state.filteredFiles,
|
|
103
257
|
state.fileSearchQuery,
|
|
104
258
|
state.atPosition,
|
|
259
|
+
onFileSelectorStateChange,
|
|
105
260
|
]);
|
|
106
261
|
|
|
107
262
|
useEffect(() => {
|
|
108
|
-
|
|
263
|
+
onCommandSelectorStateChange?.(
|
|
109
264
|
state.showCommandSelector,
|
|
110
265
|
state.commandSearchQuery,
|
|
111
266
|
state.slashPosition,
|
|
@@ -114,48 +269,51 @@ export const useInputManager = (
|
|
|
114
269
|
state.showCommandSelector,
|
|
115
270
|
state.commandSearchQuery,
|
|
116
271
|
state.slashPosition,
|
|
272
|
+
onCommandSelectorStateChange,
|
|
117
273
|
]);
|
|
118
274
|
|
|
119
275
|
useEffect(() => {
|
|
120
|
-
|
|
276
|
+
onHistorySearchStateChange?.(
|
|
121
277
|
state.showHistorySearch,
|
|
122
278
|
state.historySearchQuery,
|
|
123
279
|
);
|
|
124
|
-
}, [
|
|
280
|
+
}, [
|
|
281
|
+
state.showHistorySearch,
|
|
282
|
+
state.historySearchQuery,
|
|
283
|
+
onHistorySearchStateChange,
|
|
284
|
+
]);
|
|
125
285
|
|
|
126
286
|
useEffect(() => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
);
|
|
130
|
-
}, [state.showBackgroundTaskManager]);
|
|
287
|
+
onBackgroundTaskManagerStateChange?.(state.showBackgroundTaskManager);
|
|
288
|
+
}, [state.showBackgroundTaskManager, onBackgroundTaskManagerStateChange]);
|
|
131
289
|
|
|
132
290
|
useEffect(() => {
|
|
133
|
-
|
|
134
|
-
}, [state.showMcpManager]);
|
|
291
|
+
onMcpManagerStateChange?.(state.showMcpManager);
|
|
292
|
+
}, [state.showMcpManager, onMcpManagerStateChange]);
|
|
135
293
|
|
|
136
294
|
useEffect(() => {
|
|
137
|
-
|
|
138
|
-
}, [state.showRewindManager]);
|
|
295
|
+
onRewindManagerStateChange?.(state.showRewindManager);
|
|
296
|
+
}, [state.showRewindManager, onRewindManagerStateChange]);
|
|
139
297
|
|
|
140
298
|
useEffect(() => {
|
|
141
|
-
|
|
142
|
-
}, [state.showHelp]);
|
|
299
|
+
onHelpStateChange?.(state.showHelp);
|
|
300
|
+
}, [state.showHelp, onHelpStateChange]);
|
|
143
301
|
|
|
144
302
|
useEffect(() => {
|
|
145
|
-
|
|
146
|
-
}, [state.showStatusCommand]);
|
|
303
|
+
onStatusCommandStateChange?.(state.showStatusCommand);
|
|
304
|
+
}, [state.showStatusCommand, onStatusCommandStateChange]);
|
|
147
305
|
|
|
148
306
|
useEffect(() => {
|
|
149
|
-
|
|
150
|
-
}, [state.showPluginManager]);
|
|
307
|
+
onPluginManagerStateChange?.(state.showPluginManager);
|
|
308
|
+
}, [state.showPluginManager, onPluginManagerStateChange]);
|
|
151
309
|
|
|
152
310
|
useEffect(() => {
|
|
153
|
-
|
|
154
|
-
}, [state.showModelSelector]);
|
|
311
|
+
onModelSelectorStateChange?.(state.showModelSelector);
|
|
312
|
+
}, [state.showModelSelector, onModelSelectorStateChange]);
|
|
155
313
|
|
|
156
314
|
useEffect(() => {
|
|
157
|
-
|
|
158
|
-
}, [state.attachedImages]);
|
|
315
|
+
onImagesStateChange?.(state.attachedImages);
|
|
316
|
+
}, [state.attachedImages, onImagesStateChange]);
|
|
159
317
|
|
|
160
318
|
// Handle /btw side question
|
|
161
319
|
useEffect(() => {
|
|
@@ -166,9 +324,7 @@ export const useInputManager = (
|
|
|
166
324
|
) {
|
|
167
325
|
const askBtw = async () => {
|
|
168
326
|
try {
|
|
169
|
-
const answer = await
|
|
170
|
-
state.btwState.question,
|
|
171
|
-
);
|
|
327
|
+
const answer = await onAskBtw?.(state.btwState.question);
|
|
172
328
|
dispatch({
|
|
173
329
|
type: "SET_BTW_STATE",
|
|
174
330
|
payload: { answer, isLoading: false },
|
|
@@ -190,6 +346,7 @@ export const useInputManager = (
|
|
|
190
346
|
state.btwState.isActive,
|
|
191
347
|
state.btwState.isLoading,
|
|
192
348
|
state.btwState.question,
|
|
349
|
+
onAskBtw,
|
|
193
350
|
]);
|
|
194
351
|
|
|
195
352
|
// Methods
|
|
@@ -218,12 +375,7 @@ export const useInputManager = (
|
|
|
218
375
|
}, []);
|
|
219
376
|
|
|
220
377
|
const handleFileSelect = useCallback((filePath: string) => {
|
|
221
|
-
|
|
222
|
-
stateRef.current,
|
|
223
|
-
dispatch,
|
|
224
|
-
callbacksRef.current,
|
|
225
|
-
filePath,
|
|
226
|
-
);
|
|
378
|
+
dispatch({ type: "SELECT_FILE", payload: filePath });
|
|
227
379
|
}, []);
|
|
228
380
|
|
|
229
381
|
const handleCancelFileSelect = useCallback(() => {
|
|
@@ -234,51 +386,25 @@ export const useInputManager = (
|
|
|
234
386
|
dispatch({ type: "SET_FILE_SEARCH_QUERY", payload: query });
|
|
235
387
|
}, []);
|
|
236
388
|
|
|
237
|
-
const checkForAtDeletion = useCallback(
|
|
238
|
-
|
|
239
|
-
|
|
389
|
+
const checkForAtDeletion = useCallback(
|
|
390
|
+
(cursorPos: number) => {
|
|
391
|
+
// This is now largely handled inside HANDLE_KEY,
|
|
392
|
+
// but kept for external calls if any.
|
|
393
|
+
return handlers.checkForAtDeletion(state, dispatch, cursorPos);
|
|
394
|
+
},
|
|
395
|
+
[state],
|
|
396
|
+
);
|
|
240
397
|
|
|
241
398
|
const activateCommandSelector = useCallback((position: number) => {
|
|
242
399
|
dispatch({ type: "ACTIVATE_COMMAND_SELECTOR", payload: position });
|
|
243
400
|
}, []);
|
|
244
401
|
|
|
245
402
|
const handleCommandSelect = useCallback((command: string) => {
|
|
246
|
-
|
|
247
|
-
stateRef.current,
|
|
248
|
-
dispatch,
|
|
249
|
-
callbacksRef.current,
|
|
250
|
-
command,
|
|
251
|
-
);
|
|
403
|
+
dispatch({ type: "SELECT_COMMAND", payload: command });
|
|
252
404
|
}, []);
|
|
253
405
|
|
|
254
406
|
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
|
-
};
|
|
407
|
+
dispatch({ type: "INSERT_COMMAND", payload: command });
|
|
282
408
|
}, []);
|
|
283
409
|
|
|
284
410
|
const handleCancelCommandSelect = useCallback(() => {
|
|
@@ -289,13 +415,12 @@ export const useInputManager = (
|
|
|
289
415
|
dispatch({ type: "SET_COMMAND_SEARCH_QUERY", payload: query });
|
|
290
416
|
}, []);
|
|
291
417
|
|
|
292
|
-
const checkForSlashDeletion = useCallback(
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}, []);
|
|
418
|
+
const checkForSlashDeletion = useCallback(
|
|
419
|
+
(cursorPos: number) => {
|
|
420
|
+
return handlers.checkForSlashDeletion(state, dispatch, cursorPos);
|
|
421
|
+
},
|
|
422
|
+
[state],
|
|
423
|
+
);
|
|
299
424
|
|
|
300
425
|
const handleHistorySearchSelect = useCallback((entry: PromptEntry) => {
|
|
301
426
|
dispatch({ type: "SELECT_HISTORY_ENTRY", payload: entry });
|
|
@@ -305,9 +430,12 @@ export const useInputManager = (
|
|
|
305
430
|
dispatch({ type: "CANCEL_HISTORY_SEARCH" });
|
|
306
431
|
}, []);
|
|
307
432
|
|
|
308
|
-
const processSelectorInput = useCallback(
|
|
309
|
-
|
|
310
|
-
|
|
433
|
+
const processSelectorInput = useCallback(
|
|
434
|
+
(char: string) => {
|
|
435
|
+
handlers.processSelectorInput(state, dispatch, char);
|
|
436
|
+
},
|
|
437
|
+
[state],
|
|
438
|
+
);
|
|
311
439
|
|
|
312
440
|
const setInputText = useCallback((text: string) => {
|
|
313
441
|
dispatch({ type: "SET_INPUT_TEXT", payload: text });
|
|
@@ -345,14 +473,13 @@ export const useInputManager = (
|
|
|
345
473
|
dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: show });
|
|
346
474
|
}, []);
|
|
347
475
|
|
|
348
|
-
const setPermissionMode = useCallback(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}, []);
|
|
476
|
+
const setPermissionMode = useCallback(
|
|
477
|
+
(mode: PermissionMode) => {
|
|
478
|
+
dispatch({ type: "SET_PERMISSION_MODE", payload: mode });
|
|
479
|
+
onPermissionModeChange?.(mode);
|
|
480
|
+
},
|
|
481
|
+
[onPermissionModeChange],
|
|
482
|
+
);
|
|
356
483
|
|
|
357
484
|
const setBtwState = useCallback(
|
|
358
485
|
(payload: Partial<import("../managers/inputReducer.js").BtwState>) => {
|
|
@@ -377,35 +504,37 @@ export const useInputManager = (
|
|
|
377
504
|
return await handlers.handlePasteImage(dispatch);
|
|
378
505
|
}, []);
|
|
379
506
|
|
|
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
|
-
);
|
|
507
|
+
const handlePasteInput = useCallback(
|
|
508
|
+
(input: string) => {
|
|
509
|
+
dispatch({
|
|
510
|
+
type: "HANDLE_KEY",
|
|
511
|
+
payload: {
|
|
512
|
+
input,
|
|
513
|
+
key: {} as Key,
|
|
514
|
+
hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
|
|
515
|
+
},
|
|
516
|
+
});
|
|
399
517
|
},
|
|
400
|
-
[],
|
|
518
|
+
[onHasSlashCommand],
|
|
401
519
|
);
|
|
402
520
|
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
521
|
+
const handleSubmit = useCallback(async () => {
|
|
522
|
+
dispatch({
|
|
523
|
+
type: "HANDLE_KEY",
|
|
524
|
+
payload: {
|
|
525
|
+
input: "",
|
|
526
|
+
key: { return: true } as Key,
|
|
527
|
+
hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
|
|
528
|
+
},
|
|
529
|
+
});
|
|
530
|
+
}, [onHasSlashCommand]);
|
|
531
|
+
|
|
532
|
+
const expandLongTextPlaceholders = useCallback(
|
|
533
|
+
(text: string) => {
|
|
534
|
+
return handlers.expandLongTextPlaceholders(text, state.longTextMap);
|
|
535
|
+
},
|
|
536
|
+
[state.longTextMap],
|
|
537
|
+
);
|
|
409
538
|
|
|
410
539
|
const clearLongTextMap = useCallback(() => {
|
|
411
540
|
dispatch({ type: "CLEAR_LONG_TEXT_MAP" });
|
|
@@ -415,19 +544,25 @@ export const useInputManager = (
|
|
|
415
544
|
async (
|
|
416
545
|
input: string,
|
|
417
546
|
key: Key,
|
|
418
|
-
|
|
547
|
+
_attachedImages: Array<{ id: number; path: string; mimeType: string }>,
|
|
419
548
|
clearImages?: () => void,
|
|
420
549
|
) => {
|
|
421
|
-
return
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
550
|
+
// Clear images side effect if return is pressed
|
|
551
|
+
if (key.return) {
|
|
552
|
+
clearImages?.();
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
dispatch({
|
|
556
|
+
type: "HANDLE_KEY",
|
|
557
|
+
payload: {
|
|
558
|
+
input,
|
|
559
|
+
key,
|
|
560
|
+
hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
|
|
561
|
+
},
|
|
562
|
+
});
|
|
563
|
+
return true;
|
|
429
564
|
},
|
|
430
|
-
[],
|
|
565
|
+
[onHasSlashCommand],
|
|
431
566
|
);
|
|
432
567
|
|
|
433
568
|
return {
|
|
@@ -494,7 +629,6 @@ export const useInputManager = (
|
|
|
494
629
|
setShowPluginManager,
|
|
495
630
|
setShowModelSelector,
|
|
496
631
|
setPermissionMode,
|
|
497
|
-
setAllowBypassInCycle,
|
|
498
632
|
setBtwState,
|
|
499
633
|
|
|
500
634
|
// 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
|
}
|