wave-code 0.11.6 → 0.12.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 +9 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +97 -0
- package/dist/components/App.js +1 -1
- package/dist/components/BtwDisplay.d.ts +8 -0
- package/dist/components/BtwDisplay.d.ts.map +1 -0
- package/dist/components/BtwDisplay.js +9 -0
- package/dist/components/ChatInterface.d.ts.map +1 -1
- package/dist/components/ChatInterface.js +3 -5
- package/dist/components/ConfirmationDetails.d.ts.map +1 -1
- package/dist/components/ConfirmationDetails.js +7 -1
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +18 -4
- package/dist/components/MessageBlockItem.d.ts.map +1 -1
- package/dist/components/MessageBlockItem.js +2 -1
- package/dist/components/MessageList.d.ts +1 -2
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +9 -6
- package/dist/components/ModelSelector.d.ts +9 -0
- package/dist/components/ModelSelector.d.ts.map +1 -0
- package/dist/components/ModelSelector.js +34 -0
- package/dist/components/RewindCommand.js +2 -2
- package/dist/components/SlashDisplay.d.ts +9 -0
- package/dist/components/SlashDisplay.d.ts.map +1 -0
- package/dist/components/SlashDisplay.js +20 -0
- package/dist/components/StatusLine.d.ts +8 -0
- package/dist/components/StatusLine.d.ts.map +1 -0
- package/dist/components/StatusLine.js +5 -0
- package/dist/constants/commands.d.ts.map +1 -1
- package/dist/constants/commands.js +12 -0
- package/dist/contexts/useChat.d.ts +8 -0
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +61 -1
- package/dist/hooks/useInputManager.d.ts +5 -0
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +58 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/managers/inputHandlers.d.ts +1 -1
- package/dist/managers/inputHandlers.d.ts.map +1 -1
- package/dist/managers/inputHandlers.js +74 -5
- package/dist/managers/inputReducer.d.ts +22 -0
- package/dist/managers/inputReducer.d.ts.map +1 -1
- package/dist/managers/inputReducer.js +23 -0
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +4 -0
- package/package.json +4 -2
- package/src/acp/agent.ts +10 -0
- package/src/commands/update.ts +116 -0
- package/src/components/App.tsx +1 -1
- package/src/components/BtwDisplay.tsx +33 -0
- package/src/components/ChatInterface.tsx +25 -29
- package/src/components/ConfirmationDetails.tsx +14 -0
- package/src/components/InputBox.tsx +47 -17
- package/src/components/MessageBlockItem.tsx +5 -5
- package/src/components/MessageList.tsx +9 -10
- package/src/components/ModelSelector.tsx +109 -0
- package/src/components/RewindCommand.tsx +2 -2
- package/src/components/SlashDisplay.tsx +70 -0
- package/src/components/StatusLine.tsx +36 -0
- package/src/constants/commands.ts +12 -0
- package/src/contexts/useChat.tsx +82 -1
- package/src/hooks/useInputManager.ts +69 -0
- package/src/index.ts +9 -0
- package/src/managers/inputHandlers.ts +92 -4
- package/src/managers/inputReducer.ts +41 -1
- package/src/utils/version.ts +8 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import type { SlashBlock } from "wave-agent-sdk";
|
|
4
|
+
|
|
5
|
+
interface SlashDisplayProps {
|
|
6
|
+
block: SlashBlock;
|
|
7
|
+
isExpanded?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const SlashDisplay: React.FC<SlashDisplayProps> = ({
|
|
11
|
+
block,
|
|
12
|
+
isExpanded = false,
|
|
13
|
+
}) => {
|
|
14
|
+
const { command, args, stage, shortResult, error, result } = block;
|
|
15
|
+
|
|
16
|
+
const getStatusColor = () => {
|
|
17
|
+
switch (stage) {
|
|
18
|
+
case "running":
|
|
19
|
+
return "yellow";
|
|
20
|
+
case "success":
|
|
21
|
+
return "green";
|
|
22
|
+
case "error":
|
|
23
|
+
return "red";
|
|
24
|
+
case "aborted":
|
|
25
|
+
return "gray";
|
|
26
|
+
default:
|
|
27
|
+
return "white";
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<Box flexDirection="column">
|
|
33
|
+
<Box>
|
|
34
|
+
<Text color={getStatusColor()}>/ </Text>
|
|
35
|
+
<Text color="white">{command}</Text>
|
|
36
|
+
{args && <Text color="gray"> {args}</Text>}
|
|
37
|
+
</Box>
|
|
38
|
+
|
|
39
|
+
{/* Display shortResult in collapsed state */}
|
|
40
|
+
{!isExpanded && shortResult && !error && (
|
|
41
|
+
<Box paddingLeft={2} flexDirection="column">
|
|
42
|
+
{shortResult.split("\n").map((line, index) => (
|
|
43
|
+
<Text key={index} color="gray">
|
|
44
|
+
{line}
|
|
45
|
+
</Text>
|
|
46
|
+
))}
|
|
47
|
+
</Box>
|
|
48
|
+
)}
|
|
49
|
+
|
|
50
|
+
{/* Display complete result in expanded state */}
|
|
51
|
+
{isExpanded && result && (
|
|
52
|
+
<Box paddingLeft={2} flexDirection="column">
|
|
53
|
+
<Text color="cyan" bold>
|
|
54
|
+
Result:
|
|
55
|
+
</Text>
|
|
56
|
+
<Text color="white">{result}</Text>
|
|
57
|
+
</Box>
|
|
58
|
+
)}
|
|
59
|
+
|
|
60
|
+
{/* Error information always displayed */}
|
|
61
|
+
{error && (
|
|
62
|
+
<Box paddingLeft={2}>
|
|
63
|
+
<Text color="red">
|
|
64
|
+
Error: {typeof error === "string" ? error : String(error)}
|
|
65
|
+
</Text>
|
|
66
|
+
</Box>
|
|
67
|
+
)}
|
|
68
|
+
</Box>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
|
|
4
|
+
export interface StatusLineProps {
|
|
5
|
+
permissionMode: string;
|
|
6
|
+
isShellCommand: boolean;
|
|
7
|
+
isBtwActive: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const StatusLine: React.FC<StatusLineProps> = ({
|
|
11
|
+
permissionMode,
|
|
12
|
+
isShellCommand,
|
|
13
|
+
isBtwActive,
|
|
14
|
+
}) => {
|
|
15
|
+
return (
|
|
16
|
+
<Box paddingRight={1} justifyContent="space-between" width="100%">
|
|
17
|
+
{isBtwActive ? (
|
|
18
|
+
<Text color="gray">
|
|
19
|
+
Mode: <Text color="cyan">BTW</Text> (ESC to dismiss)
|
|
20
|
+
</Text>
|
|
21
|
+
) : isShellCommand ? (
|
|
22
|
+
<Text color="gray">
|
|
23
|
+
Shell: <Text color="yellow">Run shell command</Text>
|
|
24
|
+
</Text>
|
|
25
|
+
) : (
|
|
26
|
+
<Text color="gray">
|
|
27
|
+
Mode:{" "}
|
|
28
|
+
<Text color={permissionMode === "plan" ? "yellow" : "cyan"}>
|
|
29
|
+
{permissionMode}
|
|
30
|
+
</Text>{" "}
|
|
31
|
+
(Shift+Tab to cycle)
|
|
32
|
+
</Text>
|
|
33
|
+
)}
|
|
34
|
+
</Box>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
@@ -38,4 +38,16 @@ export const AVAILABLE_COMMANDS: SlashCommand[] = [
|
|
|
38
38
|
description: "View and manage plugins",
|
|
39
39
|
handler: () => {}, // Handler here won't be used, actual processing is in the hook
|
|
40
40
|
},
|
|
41
|
+
{
|
|
42
|
+
id: "btw",
|
|
43
|
+
name: "btw",
|
|
44
|
+
description: "Ask a side question without tool use",
|
|
45
|
+
handler: () => {}, // Handler here won't be used, actual processing is in the hook
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: "model",
|
|
49
|
+
name: "model",
|
|
50
|
+
description: "Switch between configured AI models",
|
|
51
|
+
handler: () => {}, // Handler here won't be used, actual processing is in the hook
|
|
52
|
+
},
|
|
41
53
|
];
|
package/src/contexts/useChat.tsx
CHANGED
|
@@ -51,8 +51,14 @@ export interface ChatContextType {
|
|
|
51
51
|
images?: Array<{ path: string; mimeType: string }>,
|
|
52
52
|
longTextMap?: Record<string, string>,
|
|
53
53
|
) => Promise<void>;
|
|
54
|
+
askBtw: (question: string) => Promise<string>;
|
|
54
55
|
abortMessage: () => void;
|
|
55
56
|
latestTotalTokens: number;
|
|
57
|
+
// Model functionality
|
|
58
|
+
currentModel: string;
|
|
59
|
+
configuredModels: string[];
|
|
60
|
+
getConfiguredModels: () => string[];
|
|
61
|
+
setModel: (model: string) => void;
|
|
56
62
|
// MCP functionality
|
|
57
63
|
mcpServers: McpServerStatus[];
|
|
58
64
|
connectMcpServer: (serverName: string) => Promise<boolean>;
|
|
@@ -77,6 +83,7 @@ export interface ChatContextType {
|
|
|
77
83
|
// Permission functionality
|
|
78
84
|
permissionMode: PermissionMode;
|
|
79
85
|
setPermissionMode: (mode: PermissionMode) => void;
|
|
86
|
+
allowBypassInCycle: boolean;
|
|
80
87
|
// Permission confirmation state
|
|
81
88
|
isConfirmationVisible: boolean;
|
|
82
89
|
confirmingTool?: {
|
|
@@ -113,6 +120,10 @@ export interface ChatContextType {
|
|
|
113
120
|
workingDirectory: string;
|
|
114
121
|
version?: string;
|
|
115
122
|
workdir?: string;
|
|
123
|
+
btwState: import("../managers/inputReducer.js").BtwState;
|
|
124
|
+
setBtwState: (
|
|
125
|
+
payload: Partial<import("../managers/inputReducer.js").BtwState>,
|
|
126
|
+
) => void;
|
|
116
127
|
}
|
|
117
128
|
|
|
118
129
|
const ChatContext = createContext<ChatContextType | null>(null);
|
|
@@ -170,6 +181,8 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
170
181
|
const [sessionId, setSessionId] = useState("");
|
|
171
182
|
const [isCommandRunning, setIsCommandRunning] = useState(false);
|
|
172
183
|
const [isCompressing, setIsCompressing] = useState(false);
|
|
184
|
+
const [currentModel, setCurrentModelState] = useState("");
|
|
185
|
+
const [configuredModels, setConfiguredModels] = useState<string[]>([]);
|
|
173
186
|
|
|
174
187
|
// MCP State
|
|
175
188
|
const [mcpServers, setMcpServers] = useState<McpServerStatus[]>([]);
|
|
@@ -235,8 +248,32 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
235
248
|
// Status metadata state
|
|
236
249
|
const [workingDirectory, setWorkingDirectory] = useState("");
|
|
237
250
|
|
|
251
|
+
// /btw state
|
|
252
|
+
const [btwState, setBtwStateInternal] = useState<
|
|
253
|
+
import("../managers/inputReducer.js").BtwState
|
|
254
|
+
>({
|
|
255
|
+
isActive: false,
|
|
256
|
+
question: "",
|
|
257
|
+
isLoading: false,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
const setBtwState = useCallback(
|
|
261
|
+
(payload: Partial<import("../managers/inputReducer.js").BtwState>) => {
|
|
262
|
+
setBtwStateInternal((prev) => {
|
|
263
|
+
const newState = { ...prev, ...payload };
|
|
264
|
+
if (process.env.NODE_ENV === "test") {
|
|
265
|
+
// console.log("setBtwState", newState);
|
|
266
|
+
}
|
|
267
|
+
return newState;
|
|
268
|
+
});
|
|
269
|
+
},
|
|
270
|
+
[],
|
|
271
|
+
);
|
|
272
|
+
|
|
238
273
|
// Confirmation too tall state
|
|
239
274
|
const [wasLastDetailsTooTall, setWasLastDetailsTooTall] = useState(0);
|
|
275
|
+
const allowBypassInCycle =
|
|
276
|
+
!!bypassPermissions || initialPermissionMode === "bypassPermissions";
|
|
240
277
|
|
|
241
278
|
const agentRef = useRef<Agent | null>(null);
|
|
242
279
|
const taskUpdateTimerRef = useRef<NodeJS.Timeout | null>(null);
|
|
@@ -327,6 +364,12 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
327
364
|
onPermissionModeChange: (mode) => {
|
|
328
365
|
setPermissionModeState(mode);
|
|
329
366
|
},
|
|
367
|
+
onModelChange: (model) => {
|
|
368
|
+
setCurrentModelState(model);
|
|
369
|
+
},
|
|
370
|
+
onConfiguredModelsChange: (models) => {
|
|
371
|
+
setConfiguredModels(models);
|
|
372
|
+
},
|
|
330
373
|
};
|
|
331
374
|
|
|
332
375
|
try {
|
|
@@ -384,6 +427,8 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
384
427
|
setIsCompressing(agent.isCompressing);
|
|
385
428
|
setPermissionModeState(agent.getPermissionMode());
|
|
386
429
|
setWorkingDirectory(agent.workingDirectory);
|
|
430
|
+
setCurrentModelState(agent.getModelConfig().model);
|
|
431
|
+
setConfiguredModels(agent.getConfiguredModels());
|
|
387
432
|
|
|
388
433
|
// Get initial MCP servers state
|
|
389
434
|
const mcpServers = agent.getMcpServers?.() || [];
|
|
@@ -497,6 +542,13 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
497
542
|
[isLoading, isCommandRunning],
|
|
498
543
|
);
|
|
499
544
|
|
|
545
|
+
const askBtw = useCallback(async (question: string) => {
|
|
546
|
+
if (!agentRef.current) {
|
|
547
|
+
throw new Error("Agent not initialized");
|
|
548
|
+
}
|
|
549
|
+
return await agentRef.current.askBtw(question);
|
|
550
|
+
}, []);
|
|
551
|
+
|
|
500
552
|
// Process queued messages when idle
|
|
501
553
|
useEffect(() => {
|
|
502
554
|
if (!isLoading && !isCommandRunning && queuedMessages.length > 0) {
|
|
@@ -635,6 +687,20 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
635
687
|
return agentRef.current.getModelConfig();
|
|
636
688
|
}, []);
|
|
637
689
|
|
|
690
|
+
const getConfiguredModels = useCallback(() => {
|
|
691
|
+
if (!agentRef.current) {
|
|
692
|
+
return [];
|
|
693
|
+
}
|
|
694
|
+
return agentRef.current.getConfiguredModels();
|
|
695
|
+
}, []);
|
|
696
|
+
|
|
697
|
+
const setModel = useCallback((model: string) => {
|
|
698
|
+
if (agentRef.current) {
|
|
699
|
+
agentRef.current.setModel(model);
|
|
700
|
+
setCurrentModelState(model);
|
|
701
|
+
}
|
|
702
|
+
}, []);
|
|
703
|
+
|
|
638
704
|
// Listen for Ctrl+O hotkey to toggle collapse/expand state and ESC to cancel confirmation
|
|
639
705
|
useInput((input, key) => {
|
|
640
706
|
if (key.ctrl && input === "o") {
|
|
@@ -664,10 +730,17 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
664
730
|
setIsTaskListVisible((prev) => !prev);
|
|
665
731
|
}
|
|
666
732
|
|
|
667
|
-
// Handle ESC key to cancel confirmation
|
|
733
|
+
// Handle ESC key to cancel confirmation or dismiss BTW
|
|
668
734
|
if (key.escape) {
|
|
669
735
|
if (isConfirmationVisible) {
|
|
670
736
|
handleConfirmationCancel();
|
|
737
|
+
} else if (btwState.isActive) {
|
|
738
|
+
setBtwState({
|
|
739
|
+
isActive: false,
|
|
740
|
+
question: "",
|
|
741
|
+
answer: undefined,
|
|
742
|
+
isLoading: false,
|
|
743
|
+
});
|
|
671
744
|
}
|
|
672
745
|
}
|
|
673
746
|
});
|
|
@@ -682,8 +755,13 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
682
755
|
queuedMessages,
|
|
683
756
|
sessionId,
|
|
684
757
|
sendMessage,
|
|
758
|
+
askBtw,
|
|
685
759
|
abortMessage,
|
|
686
760
|
latestTotalTokens,
|
|
761
|
+
currentModel,
|
|
762
|
+
configuredModels,
|
|
763
|
+
getConfiguredModels,
|
|
764
|
+
setModel,
|
|
687
765
|
isCompressing,
|
|
688
766
|
mcpServers,
|
|
689
767
|
connectMcpServer,
|
|
@@ -698,6 +776,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
698
776
|
subagentLatestTokens,
|
|
699
777
|
permissionMode,
|
|
700
778
|
setPermissionMode,
|
|
779
|
+
allowBypassInCycle,
|
|
701
780
|
isConfirmationVisible,
|
|
702
781
|
confirmingTool,
|
|
703
782
|
showConfirmation,
|
|
@@ -715,6 +794,8 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
715
794
|
workingDirectory,
|
|
716
795
|
version,
|
|
717
796
|
workdir,
|
|
797
|
+
btwState,
|
|
798
|
+
setBtwState,
|
|
718
799
|
};
|
|
719
800
|
|
|
720
801
|
return (
|
|
@@ -149,10 +149,55 @@ export const useInputManager = (
|
|
|
149
149
|
callbacksRef.current.onPluginManagerStateChange?.(state.showPluginManager);
|
|
150
150
|
}, [state.showPluginManager]);
|
|
151
151
|
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
callbacksRef.current.onModelSelectorStateChange?.(state.showModelSelector);
|
|
154
|
+
}, [state.showModelSelector]);
|
|
155
|
+
|
|
152
156
|
useEffect(() => {
|
|
153
157
|
callbacksRef.current.onImagesStateChange?.(state.attachedImages);
|
|
154
158
|
}, [state.attachedImages]);
|
|
155
159
|
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
if (callbacksRef.current.onBtwStateChange) {
|
|
162
|
+
callbacksRef.current.onBtwStateChange(state.btwState);
|
|
163
|
+
}
|
|
164
|
+
}, [state.btwState]);
|
|
165
|
+
|
|
166
|
+
// Handle /btw side question
|
|
167
|
+
useEffect(() => {
|
|
168
|
+
if (
|
|
169
|
+
state.btwState.isActive &&
|
|
170
|
+
state.btwState.isLoading &&
|
|
171
|
+
state.btwState.question
|
|
172
|
+
) {
|
|
173
|
+
const askBtw = async () => {
|
|
174
|
+
try {
|
|
175
|
+
const answer = await callbacksRef.current.onAskBtw?.(
|
|
176
|
+
state.btwState.question,
|
|
177
|
+
);
|
|
178
|
+
dispatch({
|
|
179
|
+
type: "SET_BTW_STATE",
|
|
180
|
+
payload: { answer, isLoading: false },
|
|
181
|
+
});
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error("Failed to ask side question:", error);
|
|
184
|
+
dispatch({
|
|
185
|
+
type: "SET_BTW_STATE",
|
|
186
|
+
payload: {
|
|
187
|
+
answer: "Error: Failed to get an answer for your side question.",
|
|
188
|
+
isLoading: false,
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
askBtw();
|
|
194
|
+
}
|
|
195
|
+
}, [
|
|
196
|
+
state.btwState.isActive,
|
|
197
|
+
state.btwState.isLoading,
|
|
198
|
+
state.btwState.question,
|
|
199
|
+
]);
|
|
200
|
+
|
|
156
201
|
// Methods
|
|
157
202
|
const insertTextAtCursor = useCallback((text: string) => {
|
|
158
203
|
dispatch({ type: "INSERT_TEXT", payload: text });
|
|
@@ -302,11 +347,30 @@ export const useInputManager = (
|
|
|
302
347
|
dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: show });
|
|
303
348
|
}, []);
|
|
304
349
|
|
|
350
|
+
const setShowModelSelector = useCallback((show: boolean) => {
|
|
351
|
+
dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: show });
|
|
352
|
+
}, []);
|
|
353
|
+
|
|
305
354
|
const setPermissionMode = useCallback((mode: PermissionMode) => {
|
|
306
355
|
dispatch({ type: "SET_PERMISSION_MODE", payload: mode });
|
|
307
356
|
callbacksRef.current.onPermissionModeChange?.(mode);
|
|
308
357
|
}, []);
|
|
309
358
|
|
|
359
|
+
const setAllowBypassInCycle = useCallback((allow: boolean) => {
|
|
360
|
+
dispatch({ type: "SET_ALLOW_BYPASS_IN_CYCLE", payload: allow });
|
|
361
|
+
}, []);
|
|
362
|
+
|
|
363
|
+
const setBtwState = useCallback(
|
|
364
|
+
(payload: Partial<import("../managers/inputReducer.js").BtwState>) => {
|
|
365
|
+
if (callbacksRef.current.onBtwStateChange) {
|
|
366
|
+
callbacksRef.current.onBtwStateChange(payload);
|
|
367
|
+
} else {
|
|
368
|
+
dispatch({ type: "SET_BTW_STATE", payload });
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
[],
|
|
372
|
+
);
|
|
373
|
+
|
|
310
374
|
const addImage = useCallback((imagePath: string, mimeType: string) => {
|
|
311
375
|
dispatch({ type: "ADD_IMAGE", payload: { path: imagePath, mimeType } });
|
|
312
376
|
}, []);
|
|
@@ -396,8 +460,10 @@ export const useInputManager = (
|
|
|
396
460
|
showHelp: state.showHelp,
|
|
397
461
|
showStatusCommand: state.showStatusCommand,
|
|
398
462
|
showPluginManager: state.showPluginManager,
|
|
463
|
+
showModelSelector: state.showModelSelector,
|
|
399
464
|
permissionMode: state.permissionMode,
|
|
400
465
|
attachedImages: state.attachedImages,
|
|
466
|
+
btwState: state.btwState,
|
|
401
467
|
isManagerReady: true,
|
|
402
468
|
|
|
403
469
|
// Methods
|
|
@@ -436,7 +502,10 @@ export const useInputManager = (
|
|
|
436
502
|
setShowHelp,
|
|
437
503
|
setShowStatusCommand,
|
|
438
504
|
setShowPluginManager,
|
|
505
|
+
setShowModelSelector,
|
|
439
506
|
setPermissionMode,
|
|
507
|
+
setAllowBypassInCycle,
|
|
508
|
+
setBtwState,
|
|
440
509
|
|
|
441
510
|
// Image management
|
|
442
511
|
addImage,
|
package/src/index.ts
CHANGED
|
@@ -228,6 +228,15 @@ export async function main() {
|
|
|
228
228
|
},
|
|
229
229
|
);
|
|
230
230
|
})
|
|
231
|
+
.command(
|
|
232
|
+
"update",
|
|
233
|
+
"Update WAVE Code to the latest version",
|
|
234
|
+
{},
|
|
235
|
+
async () => {
|
|
236
|
+
const { updateCommand } = await import("./commands/update.js");
|
|
237
|
+
await updateCommand();
|
|
238
|
+
},
|
|
239
|
+
)
|
|
231
240
|
.version()
|
|
232
241
|
.alias("v", "version")
|
|
233
242
|
.example("$0", "Start CLI with default settings")
|
|
@@ -55,6 +55,30 @@ export const handleSubmit = async (
|
|
|
55
55
|
.replace(imageRegex, "")
|
|
56
56
|
.trim();
|
|
57
57
|
|
|
58
|
+
if (
|
|
59
|
+
contentWithPlaceholders === "/btw" ||
|
|
60
|
+
contentWithPlaceholders.startsWith("/btw ")
|
|
61
|
+
) {
|
|
62
|
+
const question = contentWithPlaceholders.startsWith("/btw ")
|
|
63
|
+
? contentWithPlaceholders.substring(5).trim()
|
|
64
|
+
: "";
|
|
65
|
+
|
|
66
|
+
const payload = {
|
|
67
|
+
isActive: true,
|
|
68
|
+
question,
|
|
69
|
+
isLoading: question !== "",
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
dispatch({
|
|
73
|
+
type: "SET_BTW_STATE",
|
|
74
|
+
payload,
|
|
75
|
+
});
|
|
76
|
+
dispatch({ type: "CLEAR_INPUT" });
|
|
77
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
78
|
+
dispatch({ type: "CLEAR_LONG_TEXT_MAP" });
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
58
82
|
PromptHistoryManager.addEntry(
|
|
59
83
|
contentWithPlaceholders,
|
|
60
84
|
callbacks.sessionId,
|
|
@@ -100,8 +124,12 @@ export const cyclePermissionMode = (
|
|
|
100
124
|
currentMode: PermissionMode,
|
|
101
125
|
dispatch: React.Dispatch<InputAction>,
|
|
102
126
|
callbacks: Partial<InputManagerCallbacks>,
|
|
127
|
+
allowBypassInCycle: boolean = false,
|
|
103
128
|
) => {
|
|
104
129
|
const modes: PermissionMode[] = ["default", "acceptEdits", "plan"];
|
|
130
|
+
if (allowBypassInCycle) {
|
|
131
|
+
modes.push("bypassPermissions");
|
|
132
|
+
}
|
|
105
133
|
const currentIndex = modes.indexOf(currentMode);
|
|
106
134
|
const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % modes.length;
|
|
107
135
|
const nextMode = modes[nextIndex];
|
|
@@ -342,6 +370,13 @@ export const handleCommandSelect = (
|
|
|
342
370
|
dispatch({ type: "SET_SHOW_STATUS_COMMAND", payload: true });
|
|
343
371
|
} else if (command === "plugin") {
|
|
344
372
|
dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: true });
|
|
373
|
+
} else if (command === "model") {
|
|
374
|
+
dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: true });
|
|
375
|
+
} else if (command === "btw") {
|
|
376
|
+
dispatch({
|
|
377
|
+
type: "SET_BTW_STATE",
|
|
378
|
+
payload: { isActive: true, question: "", isLoading: false },
|
|
379
|
+
});
|
|
345
380
|
}
|
|
346
381
|
}
|
|
347
382
|
})();
|
|
@@ -461,8 +496,10 @@ export const handleSelectorInput = (
|
|
|
461
496
|
if (input === " ") {
|
|
462
497
|
if (state.showFileSelector) {
|
|
463
498
|
dispatch({ type: "CANCEL_FILE_SELECTOR" });
|
|
499
|
+
return false;
|
|
464
500
|
} else if (state.showCommandSelector) {
|
|
465
501
|
dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
|
|
502
|
+
return false;
|
|
466
503
|
}
|
|
467
504
|
}
|
|
468
505
|
|
|
@@ -667,6 +704,46 @@ export const handleInput = async (
|
|
|
667
704
|
return true;
|
|
668
705
|
}
|
|
669
706
|
|
|
707
|
+
if (state.btwState.isActive) {
|
|
708
|
+
if (key.escape) {
|
|
709
|
+
dispatch({
|
|
710
|
+
type: "SET_BTW_STATE",
|
|
711
|
+
payload: {
|
|
712
|
+
isActive: false,
|
|
713
|
+
question: "",
|
|
714
|
+
answer: undefined,
|
|
715
|
+
isLoading: false,
|
|
716
|
+
},
|
|
717
|
+
});
|
|
718
|
+
return true;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
if (key.return) {
|
|
722
|
+
if (state.inputText.trim() && !state.btwState.isLoading) {
|
|
723
|
+
dispatch({
|
|
724
|
+
type: "SET_BTW_STATE",
|
|
725
|
+
payload: {
|
|
726
|
+
question: state.inputText.trim(),
|
|
727
|
+
isLoading: true,
|
|
728
|
+
answer: undefined,
|
|
729
|
+
},
|
|
730
|
+
});
|
|
731
|
+
dispatch({ type: "CLEAR_INPUT" });
|
|
732
|
+
}
|
|
733
|
+
return true;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// Handle normal input for the question
|
|
737
|
+
return await handleNormalInput(
|
|
738
|
+
state,
|
|
739
|
+
dispatch,
|
|
740
|
+
callbacks,
|
|
741
|
+
input,
|
|
742
|
+
key,
|
|
743
|
+
clearImages,
|
|
744
|
+
);
|
|
745
|
+
}
|
|
746
|
+
|
|
670
747
|
if (key.escape) {
|
|
671
748
|
if (
|
|
672
749
|
!(
|
|
@@ -678,7 +755,9 @@ export const handleInput = async (
|
|
|
678
755
|
state.showRewindManager ||
|
|
679
756
|
state.showHelp ||
|
|
680
757
|
state.showStatusCommand ||
|
|
681
|
-
state.showPluginManager
|
|
758
|
+
state.showPluginManager ||
|
|
759
|
+
state.showModelSelector ||
|
|
760
|
+
state.btwState.isActive
|
|
682
761
|
)
|
|
683
762
|
) {
|
|
684
763
|
callbacks.onAbortMessage?.();
|
|
@@ -687,7 +766,12 @@ export const handleInput = async (
|
|
|
687
766
|
}
|
|
688
767
|
|
|
689
768
|
if (key.tab && key.shift) {
|
|
690
|
-
cyclePermissionMode(
|
|
769
|
+
cyclePermissionMode(
|
|
770
|
+
state.permissionMode,
|
|
771
|
+
dispatch,
|
|
772
|
+
callbacks,
|
|
773
|
+
state.allowBypassInCycle,
|
|
774
|
+
);
|
|
691
775
|
return true;
|
|
692
776
|
}
|
|
693
777
|
|
|
@@ -700,7 +784,9 @@ export const handleInput = async (
|
|
|
700
784
|
state.showRewindManager ||
|
|
701
785
|
state.showHelp ||
|
|
702
786
|
state.showStatusCommand ||
|
|
703
|
-
state.showPluginManager
|
|
787
|
+
state.showPluginManager ||
|
|
788
|
+
state.showModelSelector ||
|
|
789
|
+
state.btwState.isActive
|
|
704
790
|
) {
|
|
705
791
|
if (
|
|
706
792
|
state.showBackgroundTaskManager ||
|
|
@@ -708,7 +794,9 @@ export const handleInput = async (
|
|
|
708
794
|
state.showRewindManager ||
|
|
709
795
|
state.showHelp ||
|
|
710
796
|
state.showStatusCommand ||
|
|
711
|
-
state.showPluginManager
|
|
797
|
+
state.showPluginManager ||
|
|
798
|
+
state.showModelSelector ||
|
|
799
|
+
state.btwState.isActive
|
|
712
800
|
) {
|
|
713
801
|
return true;
|
|
714
802
|
}
|