wave-code 0.5.1 → 0.6.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/components/BackgroundTaskManager.d.ts +6 -0
- package/dist/components/BackgroundTaskManager.d.ts.map +1 -0
- package/dist/components/{TaskManager.js → BackgroundTaskManager.js} +1 -1
- package/dist/components/ChatInterface.d.ts.map +1 -1
- package/dist/components/ChatInterface.js +55 -5
- package/dist/components/CommandSelector.d.ts.map +1 -1
- package/dist/components/CommandSelector.js +10 -2
- package/dist/components/CompressDisplay.d.ts.map +1 -1
- package/dist/components/CompressDisplay.js +6 -10
- package/dist/components/ConfirmationDetails.d.ts +9 -0
- package/dist/components/ConfirmationDetails.d.ts.map +1 -0
- package/dist/components/ConfirmationDetails.js +53 -0
- package/dist/components/{Confirmation.d.ts → ConfirmationSelector.d.ts} +3 -3
- package/dist/components/ConfirmationSelector.d.ts.map +1 -0
- package/dist/components/{Confirmation.js → ConfirmationSelector.js} +34 -96
- package/dist/components/DiffDisplay.d.ts.map +1 -1
- package/dist/components/DiffDisplay.js +44 -1
- package/dist/components/FileSelector.d.ts.map +1 -1
- package/dist/components/FileSelector.js +2 -2
- package/dist/components/HistorySearch.d.ts.map +1 -1
- package/dist/components/HistorySearch.js +12 -4
- package/dist/components/InputBox.d.ts +1 -2
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +5 -9
- package/dist/components/LoadingIndicator.d.ts +11 -0
- package/dist/components/LoadingIndicator.d.ts.map +1 -0
- package/dist/components/LoadingIndicator.js +6 -0
- package/dist/components/Markdown.d.ts.map +1 -1
- package/dist/components/Markdown.js +114 -121
- package/dist/components/MessageItem.d.ts.map +1 -1
- package/dist/components/MessageItem.js +1 -2
- package/dist/components/MessageList.d.ts +2 -3
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +7 -7
- package/dist/components/PlanDisplay.d.ts.map +1 -1
- package/dist/components/PlanDisplay.js +4 -12
- package/dist/components/SubagentBlock.d.ts.map +1 -1
- package/dist/components/SubagentBlock.js +9 -6
- package/dist/components/TaskList.d.ts +3 -0
- package/dist/components/TaskList.d.ts.map +1 -0
- package/dist/components/TaskList.js +49 -0
- package/dist/components/ToolResultDisplay.js +1 -1
- package/dist/contexts/useChat.d.ts +5 -2
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +25 -25
- package/dist/hooks/useInputManager.d.ts +2 -7
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +8 -40
- package/dist/hooks/useTasks.d.ts +2 -0
- package/dist/hooks/useTasks.d.ts.map +1 -0
- package/dist/hooks/useTasks.js +5 -0
- package/dist/managers/InputManager.d.ts +4 -19
- package/dist/managers/InputManager.d.ts.map +1 -1
- package/dist/managers/InputManager.js +22 -65
- package/package.json +5 -6
- package/src/components/{TaskManager.tsx → BackgroundTaskManager.tsx} +4 -2
- package/src/components/ChatInterface.tsx +100 -20
- package/src/components/CommandSelector.tsx +35 -17
- package/src/components/CompressDisplay.tsx +5 -22
- package/src/components/ConfirmationDetails.tsx +108 -0
- package/src/components/{Confirmation.tsx → ConfirmationSelector.tsx} +69 -184
- package/src/components/DiffDisplay.tsx +62 -1
- package/src/components/FileSelector.tsx +0 -2
- package/src/components/HistorySearch.tsx +45 -21
- package/src/components/InputBox.tsx +9 -24
- package/src/components/LoadingIndicator.tsx +56 -0
- package/src/components/Markdown.tsx +126 -324
- package/src/components/MessageItem.tsx +1 -3
- package/src/components/MessageList.tsx +10 -67
- package/src/components/PlanDisplay.tsx +4 -27
- package/src/components/SubagentBlock.tsx +25 -16
- package/src/components/TaskList.tsx +70 -0
- package/src/components/ToolResultDisplay.tsx +2 -2
- package/src/contexts/useChat.tsx +38 -33
- package/src/hooks/useInputManager.ts +9 -47
- package/src/hooks/useTasks.ts +6 -0
- package/src/managers/InputManager.ts +25 -83
- package/dist/components/Confirmation.d.ts.map +0 -1
- package/dist/components/MemoryDisplay.d.ts +0 -8
- package/dist/components/MemoryDisplay.d.ts.map +0 -1
- package/dist/components/MemoryDisplay.js +0 -25
- package/dist/components/MemoryTypeSelector.d.ts +0 -8
- package/dist/components/MemoryTypeSelector.d.ts.map +0 -1
- package/dist/components/MemoryTypeSelector.js +0 -38
- package/dist/components/TaskManager.d.ts +0 -6
- package/dist/components/TaskManager.d.ts.map +0 -1
- package/src/components/MemoryDisplay.tsx +0 -62
- package/src/components/MemoryTypeSelector.tsx +0 -98
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BackgroundTaskManager.d.ts","sourceRoot":"","sources":["../../src/components/BackgroundTaskManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAcnD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CA6StE,CAAC"}
|
|
@@ -2,7 +2,7 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState, useEffect } from "react";
|
|
3
3
|
import { Box, Text, useInput } from "ink";
|
|
4
4
|
import { useChat } from "../contexts/useChat.js";
|
|
5
|
-
export const
|
|
5
|
+
export const BackgroundTaskManager = ({ onCancel, }) => {
|
|
6
6
|
const { backgroundTasks, getBackgroundTaskOutput, stopBackgroundTask } = useChat();
|
|
7
7
|
const [tasks, setTasks] = useState([]);
|
|
8
8
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAYhE,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAgJjC,CAAC"}
|
|
@@ -1,12 +1,62 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useCallback, useEffect } from "react";
|
|
3
|
+
import { Box, useStdout } from "ink";
|
|
3
4
|
import { MessageList } from "./MessageList.js";
|
|
4
5
|
import { InputBox } from "./InputBox.js";
|
|
5
|
-
import {
|
|
6
|
+
import { LoadingIndicator } from "./LoadingIndicator.js";
|
|
7
|
+
import { TaskList } from "./TaskList.js";
|
|
8
|
+
import { ConfirmationDetails } from "./ConfirmationDetails.js";
|
|
9
|
+
import { ConfirmationSelector } from "./ConfirmationSelector.js";
|
|
6
10
|
import { useChat } from "../contexts/useChat.js";
|
|
7
11
|
export const ChatInterface = () => {
|
|
8
|
-
const {
|
|
12
|
+
const { stdout } = useStdout();
|
|
13
|
+
const [isDetailsTooTall, setIsDetailsTooTall] = useState(false);
|
|
14
|
+
const [wasLastDetailsTooTall, setWasLastDetailsTooTall] = useState(0);
|
|
15
|
+
const { messages, isLoading, isCommandRunning, userInputHistory, isCompressing, sendMessage, abortMessage, mcpServers, connectMcpServer, disconnectMcpServer, isExpanded, sessionId, latestTotalTokens, slashCommands, hasSlashCommand, isConfirmationVisible, confirmingTool, handleConfirmationDecision, handleConfirmationCancel: originalHandleConfirmationCancel, rewindId, } = useChat();
|
|
16
|
+
const [remountKey, setRemountKey] = useState(String(isExpanded) + sessionId + rewindId + wasLastDetailsTooTall);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
const newKey = String(isExpanded) + sessionId + rewindId + wasLastDetailsTooTall;
|
|
19
|
+
if (newKey !== remountKey) {
|
|
20
|
+
stdout?.write("\u001b[2J\u001b[0;0H", (err) => {
|
|
21
|
+
if (err) {
|
|
22
|
+
console.error("Failed to clear terminal:", err);
|
|
23
|
+
}
|
|
24
|
+
setRemountKey(newKey);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}, [
|
|
28
|
+
isExpanded,
|
|
29
|
+
sessionId,
|
|
30
|
+
rewindId,
|
|
31
|
+
wasLastDetailsTooTall,
|
|
32
|
+
remountKey,
|
|
33
|
+
stdout,
|
|
34
|
+
]);
|
|
35
|
+
const handleHeightMeasured = useCallback((height) => {
|
|
36
|
+
const terminalHeight = stdout?.rows || 24;
|
|
37
|
+
if (height > terminalHeight - 10) {
|
|
38
|
+
setIsDetailsTooTall(true);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
setIsDetailsTooTall(false);
|
|
42
|
+
}
|
|
43
|
+
}, [stdout?.rows]);
|
|
44
|
+
const handleConfirmationCancel = useCallback(() => {
|
|
45
|
+
if (isDetailsTooTall) {
|
|
46
|
+
setWasLastDetailsTooTall((prev) => prev + 1);
|
|
47
|
+
setIsDetailsTooTall(false);
|
|
48
|
+
}
|
|
49
|
+
originalHandleConfirmationCancel();
|
|
50
|
+
}, [isDetailsTooTall, originalHandleConfirmationCancel]);
|
|
51
|
+
const wrappedHandleConfirmationDecision = useCallback((decision) => {
|
|
52
|
+
if (isDetailsTooTall) {
|
|
53
|
+
setWasLastDetailsTooTall((prev) => prev + 1);
|
|
54
|
+
setIsDetailsTooTall(false);
|
|
55
|
+
}
|
|
56
|
+
handleConfirmationDecision(decision);
|
|
57
|
+
}, [isDetailsTooTall, handleConfirmationDecision]);
|
|
9
58
|
if (!sessionId)
|
|
10
59
|
return null;
|
|
11
|
-
return (_jsxs(Box, { flexDirection: "column",
|
|
60
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(MessageList, { messages: messages, isLoading: isLoading, isCommandRunning: isCommandRunning, isExpanded: isExpanded, forceStaticLastMessage: isDetailsTooTall }, remountKey), (isLoading || isCommandRunning || isCompressing) &&
|
|
61
|
+
!isConfirmationVisible && (_jsx(LoadingIndicator, { isLoading: isLoading, isCommandRunning: isCommandRunning, isCompressing: isCompressing, latestTotalTokens: latestTotalTokens })), !isConfirmationVisible && _jsx(TaskList, {}), isConfirmationVisible && (_jsxs(_Fragment, { children: [_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, isExpanded: isExpanded, onHeightMeasured: handleHeightMeasured }), _jsx(ConfirmationSelector, { toolName: confirmingTool.name, toolInput: confirmingTool.input, suggestedPrefix: confirmingTool.suggestedPrefix, hidePersistentOption: confirmingTool.hidePersistentOption, isExpanded: isExpanded, onDecision: wrappedHandleConfirmationDecision, onCancel: handleConfirmationCancel, onAbort: abortMessage })] })), !isConfirmationVisible && !isExpanded && (_jsx(InputBox, { isLoading: isLoading, isCommandRunning: isCommandRunning, userInputHistory: userInputHistory, sendMessage: sendMessage, abortMessage: abortMessage, mcpServers: mcpServers, connectMcpServer: connectMcpServer, disconnectMcpServer: disconnectMcpServer, slashCommands: slashCommands, hasSlashCommand: hasSlashCommand }))] }));
|
|
12
62
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandSelector.d.ts","sourceRoot":"","sources":["../../src/components/CommandSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAwBnD,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;CAC3B;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"CommandSelector.d.ts","sourceRoot":"","sources":["../../src/components/CommandSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAwBnD,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;CAC3B;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA0I1D,CAAC"}
|
|
@@ -23,12 +23,16 @@ const AVAILABLE_COMMANDS = [
|
|
|
23
23
|
];
|
|
24
24
|
export const CommandSelector = ({ searchQuery, onSelect, onInsert, onCancel, commands = [], // Default to empty array
|
|
25
25
|
}) => {
|
|
26
|
+
const MAX_VISIBLE_ITEMS = 3;
|
|
26
27
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
27
28
|
// Merge agent commands and local commands
|
|
28
29
|
const allCommands = [...commands, ...AVAILABLE_COMMANDS];
|
|
29
30
|
// Filter command list
|
|
30
31
|
const filteredCommands = allCommands.filter((command) => !searchQuery ||
|
|
31
32
|
command.id.toLowerCase().includes(searchQuery.toLowerCase()));
|
|
33
|
+
// Calculate visible window
|
|
34
|
+
const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, filteredCommands.length - MAX_VISIBLE_ITEMS)));
|
|
35
|
+
const visibleCommands = filteredCommands.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
|
|
32
36
|
useInput((input, key) => {
|
|
33
37
|
if (key.return) {
|
|
34
38
|
if (filteredCommands.length > 0 &&
|
|
@@ -60,7 +64,11 @@ export const CommandSelector = ({ searchQuery, onSelect, onInsert, onCancel, com
|
|
|
60
64
|
}
|
|
61
65
|
});
|
|
62
66
|
if (filteredCommands.length === 0) {
|
|
63
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false,
|
|
67
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "yellow", children: ["No commands found for \"", searchQuery, "\""] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
|
|
64
68
|
}
|
|
65
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "magenta", borderBottom: false, borderLeft: false, borderRight: false,
|
|
69
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "magenta", borderBottom: false, borderLeft: false, borderRight: false, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "magenta", bold: true, children: ["Command Selector ", searchQuery && `(filtering: "${searchQuery}")`] }) }), _jsx(Box, { flexDirection: "column", children: visibleCommands.map((command, index) => {
|
|
70
|
+
const actualIndex = startIndex + index;
|
|
71
|
+
const isSelected = actualIndex === selectedIndex;
|
|
72
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "magenta" : undefined, children: [isSelected ? "▶ " : " ", "/", command.id] }), isSelected && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { color: "gray", dimColor: true, children: command.description }) }))] }, command.id));
|
|
73
|
+
}) }), _jsx(Box, { children: _jsxs(Text, { dimColor: true, children: ["\u2191\u2193 navigate \u2022 Enter execute \u2022 ", onInsert ? "Tab insert • " : "", "Esc cancel"] }) })] }));
|
|
66
74
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompressDisplay.d.ts","sourceRoot":"","sources":["../../src/components/CompressDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,UAAU,oBAAoB;IAC5B,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"CompressDisplay.d.ts","sourceRoot":"","sources":["../../src/components/CompressDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,UAAU,oBAAoB;IAC5B,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA+B1D,CAAC"}
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { Box, Text } from "ink";
|
|
4
|
-
export const CompressDisplay = ({ block
|
|
4
|
+
export const CompressDisplay = ({ block }) => {
|
|
5
5
|
const { content } = block;
|
|
6
|
-
const
|
|
7
|
-
const { displayContent, isOverflowing } = useMemo(() => {
|
|
6
|
+
const { displayContent } = useMemo(() => {
|
|
8
7
|
if (!content) {
|
|
9
|
-
return { displayContent: ""
|
|
8
|
+
return { displayContent: "" };
|
|
10
9
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return { displayContent: display, isOverflowing: overflow };
|
|
15
|
-
}, [content, isExpanded]);
|
|
16
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsx(Text, { children: "\uD83D\uDCE6 Compressed Messages" }) }), content && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: _jsx(Text, { color: "white", children: displayContent }) }), isOverflowing && (_jsx(Box, { paddingLeft: 2, marginTop: 1, children: _jsxs(Text, { color: "yellow", dimColor: true, children: ["Content truncated (", content.split("\n").length, " lines total, showing first ", MAX_LINES, " lines. Press Ctrl+O to expand."] }) }))] }))] }));
|
|
10
|
+
return { displayContent: content };
|
|
11
|
+
}, [content]);
|
|
12
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsx(Text, { children: "\uD83D\uDCE6 Compressed Messages" }) }), content && (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: _jsx(Text, { color: "white", children: displayContent }) }) }))] }));
|
|
17
13
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface ConfirmationDetailsProps {
|
|
3
|
+
toolName: string;
|
|
4
|
+
toolInput?: Record<string, unknown>;
|
|
5
|
+
isExpanded?: boolean;
|
|
6
|
+
onHeightMeasured?: (height: number) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare const ConfirmationDetails: React.FC<ConfirmationDetailsProps>;
|
|
9
|
+
//# sourceMappingURL=ConfirmationDetails.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfirmationDetails.d.ts","sourceRoot":"","sources":["../../src/components/ConfirmationDetails.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4C,MAAM,OAAO,CAAC;AA2CjE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAED,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAuDlE,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useLayoutEffect, useRef, useState } from "react";
|
|
3
|
+
import { Box, Text, useStdout, measureElement, Static } from "ink";
|
|
4
|
+
import { BASH_TOOL_NAME, EDIT_TOOL_NAME, MULTI_EDIT_TOOL_NAME, DELETE_FILE_TOOL_NAME, WRITE_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, ASK_USER_QUESTION_TOOL_NAME, } from "wave-agent-sdk";
|
|
5
|
+
import { DiffDisplay } from "./DiffDisplay.js";
|
|
6
|
+
import { PlanDisplay } from "./PlanDisplay.js";
|
|
7
|
+
// Helper function to generate descriptive action text
|
|
8
|
+
const getActionDescription = (toolName, toolInput) => {
|
|
9
|
+
if (!toolInput) {
|
|
10
|
+
return "Execute operation";
|
|
11
|
+
}
|
|
12
|
+
switch (toolName) {
|
|
13
|
+
case BASH_TOOL_NAME:
|
|
14
|
+
return `Execute command: ${toolInput.command || "unknown command"}`;
|
|
15
|
+
case EDIT_TOOL_NAME:
|
|
16
|
+
return `Edit file: ${toolInput.file_path || "unknown file"}`;
|
|
17
|
+
case MULTI_EDIT_TOOL_NAME:
|
|
18
|
+
return `Edit multiple sections in: ${toolInput.file_path || "unknown file"}`;
|
|
19
|
+
case DELETE_FILE_TOOL_NAME:
|
|
20
|
+
return `Delete file: ${toolInput.target_file || "unknown file"}`;
|
|
21
|
+
case WRITE_TOOL_NAME:
|
|
22
|
+
return `Write to file: ${toolInput.file_path || "unknown file"}`;
|
|
23
|
+
case EXIT_PLAN_MODE_TOOL_NAME:
|
|
24
|
+
return "Review and approve the plan";
|
|
25
|
+
case ASK_USER_QUESTION_TOOL_NAME:
|
|
26
|
+
return "Answer questions to clarify intent";
|
|
27
|
+
default:
|
|
28
|
+
return "Execute operation";
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
export const ConfirmationDetails = ({ toolName, toolInput, isExpanded = false, onHeightMeasured, }) => {
|
|
32
|
+
const { stdout } = useStdout();
|
|
33
|
+
const [isStatic, setIsStatic] = useState(false);
|
|
34
|
+
const boxRef = useRef(null);
|
|
35
|
+
useLayoutEffect(() => {
|
|
36
|
+
if (boxRef.current) {
|
|
37
|
+
const { height } = measureElement(boxRef.current);
|
|
38
|
+
const terminalHeight = stdout?.rows || 24;
|
|
39
|
+
if (height > terminalHeight - 10) {
|
|
40
|
+
setIsStatic(true);
|
|
41
|
+
}
|
|
42
|
+
onHeightMeasured?.(height);
|
|
43
|
+
}
|
|
44
|
+
}, [stdout?.rows, onHeightMeasured]);
|
|
45
|
+
const content = (_jsxs(Box, { ref: boxRef, flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Tool: ", toolName] }), _jsx(Text, { color: "yellow", children: getActionDescription(toolName, toolInput) }), _jsx(DiffDisplay, { toolName: toolName, parameters: JSON.stringify(toolInput) }), toolName !== ASK_USER_QUESTION_TOOL_NAME &&
|
|
46
|
+
toolName === EXIT_PLAN_MODE_TOOL_NAME &&
|
|
47
|
+
!!toolInput?.plan_content && (_jsx(PlanDisplay, { plan: toolInput.plan_content, isExpanded: isExpanded }))] }));
|
|
48
|
+
if (isStatic) {
|
|
49
|
+
return _jsx(Static, { items: [1], children: () => content });
|
|
50
|
+
}
|
|
51
|
+
return content;
|
|
52
|
+
};
|
|
53
|
+
ConfirmationDetails.displayName = "ConfirmationDetails";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { PermissionDecision } from "wave-agent-sdk";
|
|
3
|
-
export interface
|
|
3
|
+
export interface ConfirmationSelectorProps {
|
|
4
4
|
toolName: string;
|
|
5
5
|
toolInput?: Record<string, unknown>;
|
|
6
6
|
suggestedPrefix?: string;
|
|
@@ -10,5 +10,5 @@ export interface ConfirmationProps {
|
|
|
10
10
|
onCancel: () => void;
|
|
11
11
|
onAbort: () => void;
|
|
12
12
|
}
|
|
13
|
-
export declare const
|
|
14
|
-
//# sourceMappingURL=
|
|
13
|
+
export declare const ConfirmationSelector: React.FC<ConfirmationSelectorProps>;
|
|
14
|
+
//# sourceMappingURL=ConfirmationSelector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfirmationSelector.d.ts","sourceRoot":"","sources":["../../src/components/ConfirmationSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,kBAAkB,EAAwB,MAAM,gBAAgB,CAAC;AAgB/E,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AASD,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CA4apE,CAAC"}
|
|
@@ -1,33 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { Box, Text, useInput } from "ink";
|
|
4
|
-
import { BASH_TOOL_NAME,
|
|
5
|
-
import { DiffDisplay } from "./DiffDisplay.js";
|
|
6
|
-
import { PlanDisplay } from "./PlanDisplay.js";
|
|
7
|
-
// Helper function to generate descriptive action text
|
|
8
|
-
const getActionDescription = (toolName, toolInput) => {
|
|
9
|
-
if (!toolInput) {
|
|
10
|
-
return "Execute operation";
|
|
11
|
-
}
|
|
12
|
-
switch (toolName) {
|
|
13
|
-
case BASH_TOOL_NAME:
|
|
14
|
-
return `Execute command: ${toolInput.command || "unknown command"}`;
|
|
15
|
-
case EDIT_TOOL_NAME:
|
|
16
|
-
return `Edit file: ${toolInput.file_path || "unknown file"}`;
|
|
17
|
-
case MULTI_EDIT_TOOL_NAME:
|
|
18
|
-
return `Edit multiple sections in: ${toolInput.file_path || "unknown file"}`;
|
|
19
|
-
case DELETE_FILE_TOOL_NAME:
|
|
20
|
-
return `Delete file: ${toolInput.target_file || "unknown file"}`;
|
|
21
|
-
case WRITE_TOOL_NAME:
|
|
22
|
-
return `Write to file: ${toolInput.file_path || "unknown file"}`;
|
|
23
|
-
case EXIT_PLAN_MODE_TOOL_NAME:
|
|
24
|
-
return "Review and approve the plan";
|
|
25
|
-
case ASK_USER_QUESTION_TOOL_NAME:
|
|
26
|
-
return "Answer questions to clarify intent";
|
|
27
|
-
default:
|
|
28
|
-
return "Execute operation";
|
|
29
|
-
}
|
|
30
|
-
};
|
|
4
|
+
import { BASH_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, ASK_USER_QUESTION_TOOL_NAME, } from "wave-agent-sdk";
|
|
31
5
|
const getHeaderColor = (header) => {
|
|
32
6
|
const colors = ["red", "green", "blue", "magenta", "cyan"];
|
|
33
7
|
let hash = 0;
|
|
@@ -36,14 +10,13 @@ const getHeaderColor = (header) => {
|
|
|
36
10
|
}
|
|
37
11
|
return colors[Math.abs(hash) % colors.length];
|
|
38
12
|
};
|
|
39
|
-
export const
|
|
13
|
+
export const ConfirmationSelector = ({ toolName, toolInput, suggestedPrefix, hidePersistentOption, isExpanded = false, onDecision, onCancel, onAbort, }) => {
|
|
40
14
|
const [state, setState] = useState({
|
|
41
15
|
selectedOption: "allow",
|
|
42
16
|
alternativeText: "",
|
|
43
17
|
alternativeCursorPosition: 0,
|
|
44
18
|
hasUserInput: false,
|
|
45
19
|
});
|
|
46
|
-
// Specialized state for AskUserQuestion
|
|
47
20
|
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
|
|
48
21
|
const [selectedOptionIndex, setSelectedOptionIndex] = useState(0);
|
|
49
22
|
const [selectedOptionIndices, setSelectedOptionIndices] = useState(new Set());
|
|
@@ -65,7 +38,6 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
65
38
|
return "Yes, and auto-accept edits";
|
|
66
39
|
};
|
|
67
40
|
useInput((input, key) => {
|
|
68
|
-
// Handle ESC to cancel and abort
|
|
69
41
|
if (key.escape) {
|
|
70
42
|
onCancel();
|
|
71
43
|
onAbort();
|
|
@@ -75,7 +47,7 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
75
47
|
if (!currentQuestion)
|
|
76
48
|
return;
|
|
77
49
|
const options = [...currentQuestion.options, { label: "Other" }];
|
|
78
|
-
const isMultiSelect =
|
|
50
|
+
const isMultiSelect = currentQuestion.multiSelect;
|
|
79
51
|
const isOtherFocused = selectedOptionIndex === options.length - 1;
|
|
80
52
|
if (key.return) {
|
|
81
53
|
let answer = "";
|
|
@@ -112,7 +84,6 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
112
84
|
setOtherCursorPosition(0);
|
|
113
85
|
}
|
|
114
86
|
else {
|
|
115
|
-
// All questions answered
|
|
116
87
|
onDecision({
|
|
117
88
|
behavior: "allow",
|
|
118
89
|
message: JSON.stringify(newAnswers),
|
|
@@ -125,31 +96,25 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
125
96
|
(!isOtherFocused || !selectedOptionIndices.has(selectedOptionIndex))) {
|
|
126
97
|
setSelectedOptionIndices((prev) => {
|
|
127
98
|
const next = new Set(prev);
|
|
128
|
-
if (next.has(selectedOptionIndex))
|
|
99
|
+
if (next.has(selectedOptionIndex))
|
|
129
100
|
next.delete(selectedOptionIndex);
|
|
130
|
-
|
|
131
|
-
else {
|
|
101
|
+
else
|
|
132
102
|
next.add(selectedOptionIndex);
|
|
133
|
-
}
|
|
134
103
|
return next;
|
|
135
104
|
});
|
|
136
105
|
return;
|
|
137
106
|
}
|
|
138
|
-
if (!isOtherFocused)
|
|
107
|
+
if (!isOtherFocused)
|
|
139
108
|
return;
|
|
140
|
-
}
|
|
141
|
-
// If isOtherFocused is true, fall through to handle space as text input
|
|
142
109
|
}
|
|
143
110
|
if (key.upArrow) {
|
|
144
|
-
if (selectedOptionIndex > 0)
|
|
111
|
+
if (selectedOptionIndex > 0)
|
|
145
112
|
setSelectedOptionIndex(selectedOptionIndex - 1);
|
|
146
|
-
}
|
|
147
113
|
return;
|
|
148
114
|
}
|
|
149
115
|
if (key.downArrow) {
|
|
150
|
-
if (selectedOptionIndex < options.length - 1)
|
|
116
|
+
if (selectedOptionIndex < options.length - 1)
|
|
151
117
|
setSelectedOptionIndex(selectedOptionIndex + 1);
|
|
152
|
-
}
|
|
153
118
|
return;
|
|
154
119
|
}
|
|
155
120
|
if (isOtherFocused) {
|
|
@@ -163,30 +128,22 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
163
128
|
}
|
|
164
129
|
if (key.backspace || key.delete) {
|
|
165
130
|
if (otherCursorPosition > 0) {
|
|
166
|
-
setOtherText((prev) =>
|
|
167
|
-
|
|
168
|
-
prev.slice(otherCursorPosition);
|
|
169
|
-
return next;
|
|
170
|
-
});
|
|
131
|
+
setOtherText((prev) => prev.slice(0, otherCursorPosition - 1) +
|
|
132
|
+
prev.slice(otherCursorPosition));
|
|
171
133
|
setOtherCursorPosition((prev) => prev - 1);
|
|
172
134
|
}
|
|
173
135
|
return;
|
|
174
136
|
}
|
|
175
137
|
if (input && !key.ctrl && !key.meta) {
|
|
176
|
-
setOtherText((prev) =>
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
prev.slice(otherCursorPosition);
|
|
180
|
-
return next;
|
|
181
|
-
});
|
|
138
|
+
setOtherText((prev) => prev.slice(0, otherCursorPosition) +
|
|
139
|
+
input +
|
|
140
|
+
prev.slice(otherCursorPosition));
|
|
182
141
|
setOtherCursorPosition((prev) => prev + input.length);
|
|
183
142
|
return;
|
|
184
143
|
}
|
|
185
|
-
return;
|
|
186
144
|
}
|
|
187
145
|
return;
|
|
188
146
|
}
|
|
189
|
-
// Handle Enter to confirm selection
|
|
190
147
|
if (key.return) {
|
|
191
148
|
if (state.selectedOption === "allow") {
|
|
192
149
|
if (toolName === EXIT_PLAN_MODE_TOOL_NAME) {
|
|
@@ -201,26 +158,14 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
201
158
|
const rule = suggestedPrefix
|
|
202
159
|
? `Bash(${suggestedPrefix}*)`
|
|
203
160
|
: `Bash(${toolInput?.command})`;
|
|
204
|
-
onDecision({
|
|
205
|
-
behavior: "allow",
|
|
206
|
-
newPermissionRule: rule,
|
|
207
|
-
});
|
|
161
|
+
onDecision({ behavior: "allow", newPermissionRule: rule });
|
|
208
162
|
}
|
|
209
163
|
else {
|
|
210
|
-
onDecision({
|
|
211
|
-
behavior: "allow",
|
|
212
|
-
newPermissionMode: "acceptEdits",
|
|
213
|
-
});
|
|
164
|
+
onDecision({ behavior: "allow", newPermissionMode: "acceptEdits" });
|
|
214
165
|
}
|
|
215
166
|
}
|
|
216
|
-
else {
|
|
217
|
-
|
|
218
|
-
if (state.alternativeText.trim()) {
|
|
219
|
-
onDecision({
|
|
220
|
-
behavior: "deny",
|
|
221
|
-
message: state.alternativeText.trim(),
|
|
222
|
-
});
|
|
223
|
-
}
|
|
167
|
+
else if (state.alternativeText.trim()) {
|
|
168
|
+
onDecision({ behavior: "deny", message: state.alternativeText.trim() });
|
|
224
169
|
}
|
|
225
170
|
return;
|
|
226
171
|
}
|
|
@@ -240,15 +185,13 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
240
185
|
return;
|
|
241
186
|
}
|
|
242
187
|
}
|
|
243
|
-
// Handle arrow keys for navigation
|
|
244
188
|
if (key.upArrow) {
|
|
245
189
|
setState((prev) => {
|
|
246
|
-
if (prev.selectedOption === "alternative")
|
|
190
|
+
if (prev.selectedOption === "alternative")
|
|
247
191
|
return {
|
|
248
192
|
...prev,
|
|
249
193
|
selectedOption: hidePersistentOption ? "allow" : "auto",
|
|
250
194
|
};
|
|
251
|
-
}
|
|
252
195
|
if (prev.selectedOption === "auto")
|
|
253
196
|
return { ...prev, selectedOption: "allow" };
|
|
254
197
|
return prev;
|
|
@@ -257,21 +200,18 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
257
200
|
}
|
|
258
201
|
if (key.downArrow) {
|
|
259
202
|
setState((prev) => {
|
|
260
|
-
if (prev.selectedOption === "allow")
|
|
203
|
+
if (prev.selectedOption === "allow")
|
|
261
204
|
return {
|
|
262
205
|
...prev,
|
|
263
206
|
selectedOption: hidePersistentOption ? "alternative" : "auto",
|
|
264
207
|
};
|
|
265
|
-
}
|
|
266
208
|
if (prev.selectedOption === "auto")
|
|
267
209
|
return { ...prev, selectedOption: "alternative" };
|
|
268
210
|
return prev;
|
|
269
211
|
});
|
|
270
212
|
return;
|
|
271
213
|
}
|
|
272
|
-
// Handle text input for alternative option
|
|
273
214
|
if (input && !key.ctrl && !key.meta && !("alt" in key && key.alt)) {
|
|
274
|
-
// Focus on alternative option when user starts typing
|
|
275
215
|
setState((prev) => {
|
|
276
216
|
const nextText = prev.alternativeText.slice(0, prev.alternativeCursorPosition) +
|
|
277
217
|
input +
|
|
@@ -286,7 +226,6 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
286
226
|
});
|
|
287
227
|
return;
|
|
288
228
|
}
|
|
289
|
-
// Handle backspace and delete
|
|
290
229
|
if (key.backspace || key.delete) {
|
|
291
230
|
setState((prev) => {
|
|
292
231
|
if (prev.alternativeCursorPosition > 0) {
|
|
@@ -307,22 +246,21 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
307
246
|
});
|
|
308
247
|
const placeholderText = "Type here to tell Wave what to do differently";
|
|
309
248
|
const showPlaceholder = state.selectedOption === "alternative" && !state.hasUserInput;
|
|
310
|
-
return (_jsxs(Box, { flexDirection: "column",
|
|
249
|
+
return (_jsxs(Box, { flexDirection: "column", children: [toolName === ASK_USER_QUESTION_TOOL_NAME &&
|
|
311
250
|
currentQuestion &&
|
|
312
|
-
!isExpanded && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Box, { backgroundColor: getHeaderColor(currentQuestion.header), paddingX: 1, marginRight: 1, children: _jsx(Text, { color: "black", bold: true, children: currentQuestion.header.slice(0, 12).toUpperCase() }) }), _jsx(Text, { bold: true, children: currentQuestion.question })] }), _jsx(Box, { flexDirection: "column", children: (() => {
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
})
|
|
324
|
-
toolName === EXIT_PLAN_MODE_TOOL_NAME &&
|
|
325
|
-
!!toolInput?.plan_content && (_jsx(PlanDisplay, { plan: toolInput.plan_content, isExpanded: isExpanded })), toolName !== ASK_USER_QUESTION_TOOL_NAME && !isExpanded && (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Do you want to proceed?" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "allow" ? "black" : "white", backgroundColor: state.selectedOption === "allow" ? "yellow" : undefined, bold: state.selectedOption === "allow", children: [state.selectedOption === "allow" ? "> " : " ", toolName === EXIT_PLAN_MODE_TOOL_NAME
|
|
251
|
+
!isExpanded && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Box, { backgroundColor: getHeaderColor(currentQuestion.header), paddingX: 1, marginRight: 1, children: _jsx(Text, { color: "black", bold: true, children: currentQuestion.header.slice(0, 12).toUpperCase() }) }), _jsx(Text, { bold: true, children: currentQuestion.question })] }), _jsx(Box, { flexDirection: "column", children: [...currentQuestion.options, { label: "Other" }].map((option, index) => {
|
|
252
|
+
const isSelected = selectedOptionIndex === index;
|
|
253
|
+
const isChecked = currentQuestion.multiSelect
|
|
254
|
+
? selectedOptionIndices.has(index)
|
|
255
|
+
: isSelected;
|
|
256
|
+
const isOther = index === currentQuestion.options.length;
|
|
257
|
+
return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "yellow" : undefined, children: [isSelected ? "> " : " ", currentQuestion.multiSelect
|
|
258
|
+
? isChecked
|
|
259
|
+
? "[x] "
|
|
260
|
+
: "[ ] "
|
|
261
|
+
: "", option.label, option.description ? ` - ${option.description}` : "", isOther && isSelected && (_jsxs(Text, { children: [":", " ", otherText ? (_jsxs(_Fragment, { children: [otherText.slice(0, otherCursorPosition), _jsx(Text, { backgroundColor: "white", color: "black", children: otherText[otherCursorPosition] || " " }), otherText.slice(otherCursorPosition + 1)] })) : (_jsx(Text, { color: "gray", dimColor: true, children: "[Type your answer...]" }))] }))] }) }, index));
|
|
262
|
+
}) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Question ", currentQuestionIndex + 1, " of ", questions.length, " \u2022", currentQuestion.multiSelect ? " Space to toggle •" : "", " Use \u2191\u2193 to navigate \u2022 Enter to confirm"] }) })] })), toolName !== ASK_USER_QUESTION_TOOL_NAME && !isExpanded && (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Do you want to proceed?" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "allow" ? "black" : "white", backgroundColor: state.selectedOption === "allow" ? "yellow" : undefined, bold: state.selectedOption === "allow", children: [state.selectedOption === "allow" ? "> " : " ", toolName === EXIT_PLAN_MODE_TOOL_NAME
|
|
326
263
|
? "Yes, proceed with default mode"
|
|
327
264
|
: "Yes"] }) }, "allow-option"), !hidePersistentOption && (_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "auto" ? "black" : "white", backgroundColor: state.selectedOption === "auto" ? "yellow" : undefined, bold: state.selectedOption === "auto", children: [state.selectedOption === "auto" ? "> " : " ", getAutoOptionText()] }) }, "auto-option")), _jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "alternative" ? "black" : "white", backgroundColor: state.selectedOption === "alternative" ? "yellow" : undefined, bold: state.selectedOption === "alternative", children: [state.selectedOption === "alternative" ? "> " : " ", showPlaceholder ? (_jsx(Text, { color: "gray", dimColor: true, children: placeholderText })) : (_jsx(Text, { children: state.alternativeText ? (_jsxs(_Fragment, { children: [state.alternativeText.slice(0, state.alternativeCursorPosition), _jsx(Text, { backgroundColor: "white", color: "black", children: state.alternativeText[state.alternativeCursorPosition] || " " }), state.alternativeText.slice(state.alternativeCursorPosition + 1)] })) : ("Type here to tell Wave what to do differently") }))] }) }, "alternative-option")] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate \u2022 ESC to cancel" }) })] }))] }));
|
|
328
265
|
};
|
|
266
|
+
ConfirmationSelector.displayName = "ConfirmationSelector";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DiffDisplay.d.ts","sourceRoot":"","sources":["../../src/components/DiffDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAUvC,UAAU,gBAAgB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,
|
|
1
|
+
{"version":3,"file":"DiffDisplay.d.ts","sourceRoot":"","sources":["../../src/components/DiffDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAUvC,UAAU,gBAAgB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAySlD,CAAC"}
|
|
@@ -88,9 +88,52 @@ export const DiffDisplay = ({ toolName, parameters, }) => {
|
|
|
88
88
|
const lines = part.value
|
|
89
89
|
.split("\n")
|
|
90
90
|
.filter((line) => line !== "");
|
|
91
|
-
|
|
91
|
+
const isFirstBlock = partIndex === 0;
|
|
92
|
+
const isLastBlock = partIndex === lineDiffs.length - 1;
|
|
93
|
+
let linesToDisplay = lines;
|
|
94
|
+
let showEllipsisTop = false;
|
|
95
|
+
let showEllipsisBottom = false;
|
|
96
|
+
if (isFirstBlock && !isLastBlock) {
|
|
97
|
+
// First block: keep last 3
|
|
98
|
+
if (lines.length > 3) {
|
|
99
|
+
linesToDisplay = lines.slice(-3);
|
|
100
|
+
showEllipsisTop = true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else if (isLastBlock && !isFirstBlock) {
|
|
104
|
+
// Last block: keep first 3
|
|
105
|
+
if (lines.length > 3) {
|
|
106
|
+
linesToDisplay = lines.slice(0, 3);
|
|
107
|
+
showEllipsisBottom = true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else if (!isFirstBlock && !isLastBlock) {
|
|
111
|
+
// Middle block: keep first 3 and last 3
|
|
112
|
+
if (lines.length > 6) {
|
|
113
|
+
linesToDisplay = [...lines.slice(0, 3), ...lines.slice(-3)];
|
|
114
|
+
showEllipsisTop = false; // We'll put ellipsis in the middle
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else if (isFirstBlock && isLastBlock) {
|
|
118
|
+
// Only one block (no changes?) - keep all or apply a general limit
|
|
119
|
+
// For now, let's keep all if it's the only block
|
|
120
|
+
}
|
|
121
|
+
if (showEllipsisTop) {
|
|
122
|
+
diffElements.push(_jsx(Box, { children: _jsx(Text, { color: "gray", children: " ..." }) }, `ellipsis-top-${changeIndex}-${partIndex}`));
|
|
123
|
+
}
|
|
124
|
+
linesToDisplay.forEach((line, lineIndex) => {
|
|
125
|
+
// If it's a middle block and we are at the split point
|
|
126
|
+
if (!isFirstBlock &&
|
|
127
|
+
!isLastBlock &&
|
|
128
|
+
lines.length > 6 &&
|
|
129
|
+
lineIndex === 3) {
|
|
130
|
+
diffElements.push(_jsx(Box, { children: _jsx(Text, { color: "gray", children: " ..." }) }, `ellipsis-mid-${changeIndex}-${partIndex}`));
|
|
131
|
+
}
|
|
92
132
|
diffElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "white", children: " " }), _jsx(Text, { color: "white", children: line })] }, `context-${changeIndex}-${partIndex}-${lineIndex}`));
|
|
93
133
|
});
|
|
134
|
+
if (showEllipsisBottom) {
|
|
135
|
+
diffElements.push(_jsx(Box, { children: _jsx(Text, { color: "gray", children: " ..." }) }, `ellipsis-bottom-${changeIndex}-${partIndex}`));
|
|
136
|
+
}
|
|
94
137
|
}
|
|
95
138
|
});
|
|
96
139
|
// If it's a single line change (one removed, one added), use word-level diff
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSelector.d.ts","sourceRoot":"","sources":["../../src/components/FileSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"FileSelector.d.ts","sourceRoot":"","sources":["../../src/components/FileSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA2HpD,CAAC"}
|
|
@@ -24,7 +24,7 @@ export const FileSelector = ({ files, searchQuery, onSelect, onCancel, }) => {
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
if (files.length === 0) {
|
|
27
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false,
|
|
27
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "yellow", children: ["\uD83D\uDCC1 No files found for \"", searchQuery, "\""] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
|
|
28
28
|
}
|
|
29
29
|
const maxDisplay = 10;
|
|
30
30
|
// Calculate display window start and end positions
|
|
@@ -39,7 +39,7 @@ export const FileSelector = ({ files, searchQuery, onSelect, onCancel, }) => {
|
|
|
39
39
|
};
|
|
40
40
|
};
|
|
41
41
|
const { startIndex, endIndex, displayFiles } = getDisplayWindow();
|
|
42
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false,
|
|
42
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "cyan", bold: true, children: ["\uD83D\uDCC1 Select File/Directory", " ", searchQuery && `(filtering: "${searchQuery}")`] }), startIndex > 0 && (_jsxs(Text, { dimColor: true, children: ["... ", startIndex, " more files above"] })), displayFiles.map((fileItem, displayIndex) => {
|
|
43
43
|
const actualIndex = startIndex + displayIndex;
|
|
44
44
|
const isSelected = actualIndex === selectedIndex;
|
|
45
45
|
const icon = fileItem.type === "directory" ? "📁" : "📄";
|