wave-code 0.0.6 → 0.0.8
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/README.md +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/components/App.d.ts +1 -0
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/App.js +4 -4
- package/dist/components/BashHistorySelector.d.ts.map +1 -1
- package/dist/components/BashHistorySelector.js +17 -3
- package/dist/components/ChatInterface.d.ts.map +1 -1
- package/dist/components/ChatInterface.js +4 -2
- package/dist/components/Confirmation.d.ts +11 -0
- package/dist/components/Confirmation.d.ts.map +1 -0
- package/dist/components/Confirmation.js +148 -0
- package/dist/components/DiffDisplay.d.ts +8 -0
- package/dist/components/DiffDisplay.d.ts.map +1 -0
- package/dist/components/DiffDisplay.js +168 -0
- package/dist/components/FileSelector.d.ts +2 -4
- package/dist/components/FileSelector.d.ts.map +1 -1
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +10 -1
- package/dist/components/MemoryDisplay.js +1 -1
- package/dist/components/MessageItem.d.ts +1 -2
- package/dist/components/MessageItem.d.ts.map +1 -1
- package/dist/components/MessageItem.js +3 -3
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +2 -2
- package/dist/components/ReasoningDisplay.d.ts +8 -0
- package/dist/components/ReasoningDisplay.d.ts.map +1 -0
- package/dist/components/ReasoningDisplay.js +10 -0
- package/dist/components/ToolResultDisplay.d.ts.map +1 -1
- package/dist/components/ToolResultDisplay.js +2 -1
- package/dist/contexts/useChat.d.ts +13 -1
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +117 -15
- package/dist/hooks/useInputManager.d.ts +3 -0
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -4
- package/dist/managers/InputManager.d.ts +8 -0
- package/dist/managers/InputManager.d.ts.map +1 -1
- package/dist/managers/InputManager.js +33 -2
- package/dist/print-cli.d.ts +1 -0
- package/dist/print-cli.d.ts.map +1 -1
- package/dist/print-cli.js +36 -3
- package/dist/utils/toolParameterTransforms.d.ts +23 -0
- package/dist/utils/toolParameterTransforms.d.ts.map +1 -0
- package/dist/utils/toolParameterTransforms.js +77 -0
- package/package.json +6 -5
- package/src/cli.tsx +3 -1
- package/src/components/App.tsx +7 -3
- package/src/components/BashHistorySelector.tsx +26 -3
- package/src/components/ChatInterface.tsx +29 -15
- package/src/components/Confirmation.tsx +253 -0
- package/src/components/DiffDisplay.tsx +300 -0
- package/src/components/FileSelector.tsx +2 -4
- package/src/components/InputBox.tsx +37 -14
- package/src/components/MemoryDisplay.tsx +1 -1
- package/src/components/MessageItem.tsx +4 -12
- package/src/components/MessageList.tsx +0 -2
- package/src/components/ReasoningDisplay.tsx +33 -0
- package/src/components/ToolResultDisplay.tsx +4 -0
- package/src/contexts/useChat.tsx +178 -14
- package/src/hooks/useInputManager.ts +19 -0
- package/src/index.ts +34 -4
- package/src/managers/InputManager.ts +46 -2
- package/src/print-cli.ts +42 -2
- package/src/utils/toolParameterTransforms.ts +104 -0
- package/dist/components/DiffViewer.d.ts +0 -9
- package/dist/components/DiffViewer.d.ts.map +0 -1
- package/dist/components/DiffViewer.js +0 -221
- package/dist/utils/fileSearch.d.ts +0 -20
- package/dist/utils/fileSearch.d.ts.map +0 -1
- package/dist/utils/fileSearch.js +0 -102
- package/src/components/DiffViewer.tsx +0 -323
- package/src/utils/fileSearch.ts +0 -133
package/README.md
CHANGED
package/dist/cli.d.ts
CHANGED
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAwEjE"}
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import { render } from "ink";
|
|
|
3
3
|
import { App } from "./components/App.js";
|
|
4
4
|
import { cleanupLogs } from "./utils/logger.js";
|
|
5
5
|
export async function startCli(options) {
|
|
6
|
-
const { restoreSessionId, continueLastSession } = options;
|
|
6
|
+
const { restoreSessionId, continueLastSession, bypassPermissions } = options;
|
|
7
7
|
// Continue with ink-based UI for normal mode
|
|
8
8
|
// Global cleanup tracker
|
|
9
9
|
let isCleaningUp = false;
|
|
@@ -45,7 +45,7 @@ export async function startCli(options) {
|
|
|
45
45
|
cleanup();
|
|
46
46
|
});
|
|
47
47
|
// Render the application
|
|
48
|
-
const { unmount } = render(_jsx(App, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession }));
|
|
48
|
+
const { unmount } = render(_jsx(App, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, bypassPermissions: bypassPermissions }));
|
|
49
49
|
// Store unmount function for cleanup when process exits normally
|
|
50
50
|
process.on("exit", () => {
|
|
51
51
|
if (!appUnmounted) {
|
package/dist/components/App.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,UAAU,QAAQ;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,UAAU,QAAQ;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAYD,eAAO,MAAM,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAalC,CAAC"}
|
package/dist/components/App.js
CHANGED
|
@@ -2,9 +2,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { ChatInterface } from "./ChatInterface.js";
|
|
3
3
|
import { ChatProvider } from "../contexts/useChat.js";
|
|
4
4
|
import { AppProvider } from "../contexts/useAppConfig.js";
|
|
5
|
-
const AppWithProviders = () => {
|
|
6
|
-
return (_jsx(ChatProvider, { children: _jsx(ChatInterface, {}) }));
|
|
5
|
+
const AppWithProviders = ({ bypassPermissions, }) => {
|
|
6
|
+
return (_jsx(ChatProvider, { bypassPermissions: bypassPermissions, children: _jsx(ChatInterface, {}) }));
|
|
7
7
|
};
|
|
8
|
-
export const App = ({ restoreSessionId, continueLastSession, }) => {
|
|
9
|
-
return (_jsx(AppProvider, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, children: _jsx(AppWithProviders, {}) }));
|
|
8
|
+
export const App = ({ restoreSessionId, continueLastSession, bypassPermissions, }) => {
|
|
9
|
+
return (_jsx(AppProvider, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, children: _jsx(AppWithProviders, { bypassPermissions: bypassPermissions }) }));
|
|
10
10
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BashHistorySelector.d.ts","sourceRoot":"","sources":["../../src/components/BashHistorySelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"BashHistorySelector.d.ts","sourceRoot":"","sources":["../../src/components/BashHistorySelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AASnD,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAwKlE,CAAC"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
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
|
-
import { searchBashHistory } from "wave-agent-sdk";
|
|
4
|
+
import { searchBashHistory, deleteBashCommandFromHistory, } from "wave-agent-sdk";
|
|
5
5
|
import { logger } from "../utils/logger.js";
|
|
6
6
|
export const BashHistorySelector = ({ searchQuery, workdir, onSelect, onExecute, onCancel, }) => {
|
|
7
7
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
8
8
|
const [commands, setCommands] = useState([]);
|
|
9
|
+
const [refreshCounter, setRefreshCounter] = useState(0);
|
|
9
10
|
// Search bash history
|
|
10
11
|
useEffect(() => {
|
|
11
12
|
const results = searchBashHistory(searchQuery, 10, workdir);
|
|
@@ -15,8 +16,9 @@ export const BashHistorySelector = ({ searchQuery, workdir, onSelect, onExecute,
|
|
|
15
16
|
searchQuery,
|
|
16
17
|
workdir,
|
|
17
18
|
resultCount: results.length,
|
|
19
|
+
refreshCounter,
|
|
18
20
|
});
|
|
19
|
-
}, [searchQuery, workdir]);
|
|
21
|
+
}, [searchQuery, workdir, refreshCounter]);
|
|
20
22
|
useInput((input, key) => {
|
|
21
23
|
logger.debug("BashHistorySelector useInput:", {
|
|
22
24
|
input,
|
|
@@ -58,6 +60,18 @@ export const BashHistorySelector = ({ searchQuery, workdir, onSelect, onExecute,
|
|
|
58
60
|
setSelectedIndex(Math.min(commands.length - 1, selectedIndex + 1));
|
|
59
61
|
return;
|
|
60
62
|
}
|
|
63
|
+
if (key.delete) {
|
|
64
|
+
if (commands.length > 0 && selectedIndex < commands.length) {
|
|
65
|
+
const selectedCommand = commands[selectedIndex];
|
|
66
|
+
deleteBashCommandFromHistory(selectedCommand.command, selectedCommand.workdir);
|
|
67
|
+
setRefreshCounter((prev) => prev + 1);
|
|
68
|
+
// Adjust selectedIndex if we deleted the last item
|
|
69
|
+
if (selectedIndex >= commands.length - 1 && selectedIndex > 0) {
|
|
70
|
+
setSelectedIndex(selectedIndex - 1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
61
75
|
});
|
|
62
76
|
if (commands.length === 0) {
|
|
63
77
|
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", padding: 1, marginBottom: 1, children: [_jsxs(Text, { color: "yellow", children: ["No bash history found ", searchQuery && `for "${searchQuery}"`] }), searchQuery.trim() && (_jsxs(Text, { color: "green", children: ["Press Enter to execute: ", searchQuery] })), searchQuery.trim() && (_jsxs(Text, { color: "blue", children: ["Press Tab to insert: ", searchQuery] })), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
|
|
@@ -79,5 +93,5 @@ export const BashHistorySelector = ({ searchQuery, workdir, onSelect, onExecute,
|
|
|
79
93
|
return diffMinutes > 0 ? `${diffMinutes}m ago` : "just now";
|
|
80
94
|
}
|
|
81
95
|
};
|
|
82
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "blue", padding: 1, gap: 1, marginBottom: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "blue", bold: true, children: ["Bash History ", searchQuery && `(filtering: "${searchQuery}")`] }) }), commands.map((cmd, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: index === selectedIndex ? "black" : "white", backgroundColor: index === selectedIndex ? "blue" : undefined, children: cmd.command }), index === selectedIndex && (_jsx(Box, { marginLeft: 4, flexDirection: "column", children: _jsxs(Text, { color: "gray", dimColor: true, children: [formatTimestamp(cmd.timestamp), cmd.workdir !== workdir && ` • in ${cmd.workdir}`] }) }))] }, index))), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate, Enter to execute, Tab to insert, Escape to cancel" }) })] }));
|
|
96
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "blue", padding: 1, gap: 1, marginBottom: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "blue", bold: true, children: ["Bash History ", searchQuery && `(filtering: "${searchQuery}")`] }) }), commands.map((cmd, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: index === selectedIndex ? "black" : "white", backgroundColor: index === selectedIndex ? "blue" : undefined, children: cmd.command }), index === selectedIndex && (_jsx(Box, { marginLeft: 4, flexDirection: "column", children: _jsxs(Text, { color: "gray", dimColor: true, children: [formatTimestamp(cmd.timestamp), cmd.workdir !== workdir && ` • in ${cmd.workdir}`] }) }))] }, index))), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate, Enter to execute, Tab to insert, Delete to remove, Escape to cancel" }) })] }));
|
|
83
97
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAgEjC,CAAC"}
|
|
@@ -2,10 +2,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Box } from "ink";
|
|
3
3
|
import { MessageList } from "./MessageList.js";
|
|
4
4
|
import { InputBox } from "./InputBox.js";
|
|
5
|
+
import { Confirmation } from "./Confirmation.js";
|
|
5
6
|
import { useChat } from "../contexts/useChat.js";
|
|
6
7
|
export const ChatInterface = () => {
|
|
7
|
-
const { messages, isLoading, isCommandRunning, userInputHistory, isCompressing, sendMessage, abortMessage, saveMemory, mcpServers, connectMcpServer, disconnectMcpServer, isExpanded, sessionId, latestTotalTokens, slashCommands, hasSlashCommand, } = useChat();
|
|
8
|
+
const { messages, isLoading, isCommandRunning, userInputHistory, isCompressing, sendMessage, abortMessage, saveMemory, mcpServers, connectMcpServer, disconnectMcpServer, isExpanded, sessionId, latestTotalTokens, slashCommands, hasSlashCommand, isConfirmationVisible, confirmingTool, handleConfirmationDecision, handleConfirmationCancel, } = useChat();
|
|
8
9
|
if (!sessionId)
|
|
9
10
|
return null;
|
|
10
|
-
return (_jsxs(Box, { flexDirection: "column", height: "100%", paddingY: 1, children: [_jsx(MessageList, { messages: messages, isLoading: isLoading, isCommandRunning: isCommandRunning, isCompressing: isCompressing, latestTotalTokens: latestTotalTokens, isExpanded: isExpanded }, String(isExpanded) + sessionId), !isExpanded &&
|
|
11
|
+
return (_jsxs(Box, { flexDirection: "column", height: "100%", paddingY: 1, children: [_jsx(MessageList, { messages: messages, isLoading: isLoading, isCommandRunning: isCommandRunning, isCompressing: isCompressing, latestTotalTokens: latestTotalTokens, isExpanded: isExpanded }, String(isExpanded) + sessionId), !isExpanded &&
|
|
12
|
+
(isConfirmationVisible ? (_jsx(Confirmation, { toolName: confirmingTool.name, toolInput: confirmingTool.input, onDecision: handleConfirmationDecision, onCancel: handleConfirmationCancel, onAbort: abortMessage })) : (_jsx(InputBox, { isLoading: isLoading, isCommandRunning: isCommandRunning, userInputHistory: userInputHistory, sendMessage: sendMessage, abortMessage: abortMessage, saveMemory: saveMemory, mcpServers: mcpServers, connectMcpServer: connectMcpServer, disconnectMcpServer: disconnectMcpServer, slashCommands: slashCommands, hasSlashCommand: hasSlashCommand })))] }));
|
|
11
13
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { PermissionDecision } from "wave-agent-sdk";
|
|
3
|
+
export interface ConfirmationProps {
|
|
4
|
+
toolName: string;
|
|
5
|
+
toolInput?: Record<string, unknown>;
|
|
6
|
+
onDecision: (decision: PermissionDecision) => void;
|
|
7
|
+
onCancel: () => void;
|
|
8
|
+
onAbort: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const Confirmation: React.FC<ConfirmationProps>;
|
|
11
|
+
//# sourceMappingURL=Confirmation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Confirmation.d.ts","sourceRoot":"","sources":["../../src/components/Confirmation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AA2BzD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,UAAU,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAQD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAiNpD,CAAC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Box, Text, useInput } from "ink";
|
|
4
|
+
// Helper function to generate descriptive action text
|
|
5
|
+
const getActionDescription = (toolName, toolInput) => {
|
|
6
|
+
if (!toolInput) {
|
|
7
|
+
return "Execute operation";
|
|
8
|
+
}
|
|
9
|
+
switch (toolName) {
|
|
10
|
+
case "Bash":
|
|
11
|
+
return `Execute command: ${toolInput.command || "unknown command"}`;
|
|
12
|
+
case "Edit":
|
|
13
|
+
return `Edit file: ${toolInput.file_path || "unknown file"}`;
|
|
14
|
+
case "MultiEdit":
|
|
15
|
+
return `Edit multiple sections in: ${toolInput.file_path || "unknown file"}`;
|
|
16
|
+
case "Delete":
|
|
17
|
+
return `Delete file: ${toolInput.target_file || "unknown file"}`;
|
|
18
|
+
case "Write":
|
|
19
|
+
return `Write to file: ${toolInput.file_path || "unknown file"}`;
|
|
20
|
+
default:
|
|
21
|
+
return "Execute operation";
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
export const Confirmation = ({ toolName, toolInput, onDecision, onCancel, onAbort, }) => {
|
|
25
|
+
const [state, setState] = useState({
|
|
26
|
+
selectedOption: "allow",
|
|
27
|
+
alternativeText: "",
|
|
28
|
+
hasUserInput: false,
|
|
29
|
+
});
|
|
30
|
+
const getAutoOptionText = () => {
|
|
31
|
+
if (toolName === "Bash") {
|
|
32
|
+
return `Yes, and don't ask again for ${toolInput?.command || "this"} commands in this workdir`;
|
|
33
|
+
}
|
|
34
|
+
return "Yes, and auto-accept edits";
|
|
35
|
+
};
|
|
36
|
+
useInput((input, key) => {
|
|
37
|
+
// Handle ESC to cancel and abort
|
|
38
|
+
if (key.escape) {
|
|
39
|
+
onCancel();
|
|
40
|
+
onAbort();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Handle Enter to confirm selection
|
|
44
|
+
if (key.return) {
|
|
45
|
+
if (state.selectedOption === "allow") {
|
|
46
|
+
onDecision({ behavior: "allow" });
|
|
47
|
+
}
|
|
48
|
+
else if (state.selectedOption === "auto") {
|
|
49
|
+
if (toolName === "Bash") {
|
|
50
|
+
onDecision({
|
|
51
|
+
behavior: "allow",
|
|
52
|
+
newPermissionRule: `Bash(${toolInput?.command})`,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
onDecision({
|
|
57
|
+
behavior: "allow",
|
|
58
|
+
newPermissionMode: "acceptEdits",
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// For alternative option, require text input
|
|
64
|
+
if (state.alternativeText.trim()) {
|
|
65
|
+
onDecision({
|
|
66
|
+
behavior: "deny",
|
|
67
|
+
message: state.alternativeText.trim(),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Handle numeric keys for quick selection (only if not typing in alternative)
|
|
74
|
+
if (state.selectedOption !== "alternative" || !state.hasUserInput) {
|
|
75
|
+
if (input === "1") {
|
|
76
|
+
onDecision({ behavior: "allow" });
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (input === "2") {
|
|
80
|
+
if (toolName === "Bash") {
|
|
81
|
+
onDecision({
|
|
82
|
+
behavior: "allow",
|
|
83
|
+
newPermissionRule: `Bash(${toolInput?.command})`,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
onDecision({
|
|
88
|
+
behavior: "allow",
|
|
89
|
+
newPermissionMode: "acceptEdits",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (input === "3") {
|
|
95
|
+
setState((prev) => ({ ...prev, selectedOption: "alternative" }));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Handle arrow keys for navigation
|
|
100
|
+
if (key.upArrow) {
|
|
101
|
+
setState((prev) => {
|
|
102
|
+
if (prev.selectedOption === "alternative")
|
|
103
|
+
return { ...prev, selectedOption: "auto" };
|
|
104
|
+
if (prev.selectedOption === "auto")
|
|
105
|
+
return { ...prev, selectedOption: "allow" };
|
|
106
|
+
return prev;
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (key.downArrow) {
|
|
111
|
+
setState((prev) => {
|
|
112
|
+
if (prev.selectedOption === "allow")
|
|
113
|
+
return { ...prev, selectedOption: "auto" };
|
|
114
|
+
if (prev.selectedOption === "auto")
|
|
115
|
+
return { ...prev, selectedOption: "alternative" };
|
|
116
|
+
return prev;
|
|
117
|
+
});
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// Handle text input for alternative option
|
|
121
|
+
if (input && !key.ctrl && !key.meta && !("alt" in key && key.alt)) {
|
|
122
|
+
// Focus on alternative option when user starts typing
|
|
123
|
+
setState((prev) => ({
|
|
124
|
+
selectedOption: "alternative",
|
|
125
|
+
alternativeText: prev.alternativeText + input,
|
|
126
|
+
hasUserInput: true,
|
|
127
|
+
}));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// Handle backspace and delete (same behavior - delete one character)
|
|
131
|
+
if (key.backspace || key.delete) {
|
|
132
|
+
setState((prev) => {
|
|
133
|
+
const newText = prev.alternativeText.slice(0, -1);
|
|
134
|
+
return {
|
|
135
|
+
...prev,
|
|
136
|
+
selectedOption: "alternative",
|
|
137
|
+
alternativeText: newText,
|
|
138
|
+
hasUserInput: newText.length > 0,
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
const placeholderText = "Type here to tell Wave what to do differently";
|
|
145
|
+
const showPlaceholder = state.selectedOption === "alternative" && !state.hasUserInput;
|
|
146
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", padding: 1, marginBottom: 1, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Tool: ", toolName] }), _jsx(Text, { color: "yellow", children: getActionDescription(toolName, toolInput) }), _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" ? "> " : " ", "1. Yes"] }) }, "allow-option"), _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" ? "> " : " ", "2.", " ", 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" ? "> " : " ", "3.", " ", showPlaceholder ? (_jsx(Text, { color: "gray", dimColor: true, children: placeholderText })) : (_jsx(Text, { children: state.alternativeText ||
|
|
147
|
+
"Type here to tell Wave what to do differently" }))] }) }, "alternative-option")] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 or 1-3 to navigate \u2022 ESC to cancel" }) })] }));
|
|
148
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiffDisplay.d.ts","sourceRoot":"","sources":["../../src/components/DiffDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAIvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,UAAU,gBAAgB;IACxB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAiSlD,CAAC"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useMemo } from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
import { transformToolBlockToChanges } from "../utils/toolParameterTransforms.js";
|
|
5
|
+
import { diffLines, diffWords } from "diff";
|
|
6
|
+
export const DiffDisplay = ({ toolBlock }) => {
|
|
7
|
+
const showDiff = ["running", "end"].includes(toolBlock.stage) &&
|
|
8
|
+
toolBlock.name &&
|
|
9
|
+
["Write", "Edit", "MultiEdit"].includes(toolBlock.name);
|
|
10
|
+
// Diff detection and transformation using typed parameters
|
|
11
|
+
const changes = useMemo(() => {
|
|
12
|
+
if (!showDiff || !toolBlock.name || !toolBlock.parameters)
|
|
13
|
+
return [];
|
|
14
|
+
try {
|
|
15
|
+
// Use local transformation with JSON parsing and type guards
|
|
16
|
+
return transformToolBlockToChanges(toolBlock.name, toolBlock.parameters);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
console.warn("Error transforming tool block to changes:", error);
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
}, [toolBlock.name, toolBlock.parameters, showDiff]);
|
|
23
|
+
// Render word-level diff between two lines of text
|
|
24
|
+
const renderWordLevelDiff = (oldLine, newLine, keyPrefix) => {
|
|
25
|
+
try {
|
|
26
|
+
const changes = diffWords(oldLine, newLine);
|
|
27
|
+
const removedParts = [];
|
|
28
|
+
const addedParts = [];
|
|
29
|
+
changes.forEach((part, index) => {
|
|
30
|
+
if (part.removed) {
|
|
31
|
+
removedParts.push(_jsx(Text, { color: "black", backgroundColor: "red", children: part.value }, `removed-${keyPrefix}-${index}`));
|
|
32
|
+
}
|
|
33
|
+
else if (part.added) {
|
|
34
|
+
addedParts.push(_jsx(Text, { color: "black", backgroundColor: "green", children: part.value }, `added-${keyPrefix}-${index}`));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Unchanged parts
|
|
38
|
+
removedParts.push(_jsx(Text, { color: "red", children: part.value }, `removed-unchanged-${keyPrefix}-${index}`));
|
|
39
|
+
addedParts.push(_jsx(Text, { color: "green", children: part.value }, `added-unchanged-${keyPrefix}-${index}`));
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
return { removedParts, addedParts };
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.warn("Error rendering word-level diff:", error);
|
|
46
|
+
// Fallback to simple line display
|
|
47
|
+
return {
|
|
48
|
+
removedParts: [
|
|
49
|
+
_jsx(Text, { color: "red", children: oldLine }, `fallback-removed-${keyPrefix}`),
|
|
50
|
+
],
|
|
51
|
+
addedParts: [
|
|
52
|
+
_jsx(Text, { color: "green", children: newLine }, `fallback-added-${keyPrefix}`),
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
// Render expanded diff display using word-level diff for all changes
|
|
58
|
+
const renderExpandedDiff = () => {
|
|
59
|
+
try {
|
|
60
|
+
if (changes.length === 0)
|
|
61
|
+
return null;
|
|
62
|
+
return (_jsx(Box, { flexDirection: "column", children: changes.map((change, changeIndex) => {
|
|
63
|
+
try {
|
|
64
|
+
// Get line-level diff to understand the structure
|
|
65
|
+
const lineDiffs = diffLines(change.oldContent || "", change.newContent || "");
|
|
66
|
+
const diffElements = [];
|
|
67
|
+
// Process line diffs and apply word-level diff to changed lines
|
|
68
|
+
lineDiffs.forEach((part, partIndex) => {
|
|
69
|
+
if (part.added) {
|
|
70
|
+
const lines = part.value
|
|
71
|
+
.split("\n")
|
|
72
|
+
.filter((line) => line !== "");
|
|
73
|
+
lines.forEach((line, lineIndex) => {
|
|
74
|
+
diffElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "green", children: "+" }), _jsx(Text, { color: "green", children: line })] }, `add-${changeIndex}-${partIndex}-${lineIndex}`));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else if (part.removed) {
|
|
78
|
+
const lines = part.value
|
|
79
|
+
.split("\n")
|
|
80
|
+
.filter((line) => line !== "");
|
|
81
|
+
lines.forEach((line, lineIndex) => {
|
|
82
|
+
diffElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "red", children: "-" }), _jsx(Text, { color: "red", children: line })] }, `remove-${changeIndex}-${partIndex}-${lineIndex}`));
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Context lines - show unchanged content
|
|
87
|
+
const lines = part.value
|
|
88
|
+
.split("\n")
|
|
89
|
+
.filter((line) => line !== "");
|
|
90
|
+
lines.forEach((line, lineIndex) => {
|
|
91
|
+
diffElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "white", children: " " }), _jsx(Text, { color: "white", children: line })] }, `context-${changeIndex}-${partIndex}-${lineIndex}`));
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
// Now look for pairs of removed/added lines that can be word-diffed
|
|
96
|
+
const processedElements = [];
|
|
97
|
+
let i = 0;
|
|
98
|
+
while (i < diffElements.length) {
|
|
99
|
+
const current = diffElements[i];
|
|
100
|
+
const next = i + 1 < diffElements.length ? diffElements[i + 1] : null;
|
|
101
|
+
// Check if we have a removed line followed by an added line
|
|
102
|
+
const currentKey = React.isValidElement(current)
|
|
103
|
+
? current.key
|
|
104
|
+
: "";
|
|
105
|
+
const nextKey = React.isValidElement(next) ? next.key : "";
|
|
106
|
+
const isCurrentRemoved = typeof currentKey === "string" &&
|
|
107
|
+
currentKey.includes("remove-");
|
|
108
|
+
const isNextAdded = typeof nextKey === "string" && nextKey.includes("add-");
|
|
109
|
+
if (isCurrentRemoved &&
|
|
110
|
+
isNextAdded &&
|
|
111
|
+
React.isValidElement(current) &&
|
|
112
|
+
React.isValidElement(next)) {
|
|
113
|
+
// Extract the text content from the removed and added lines
|
|
114
|
+
const removedText = extractTextFromElement(current);
|
|
115
|
+
const addedText = extractTextFromElement(next);
|
|
116
|
+
if (removedText && addedText) {
|
|
117
|
+
// Apply word-level diff
|
|
118
|
+
const { removedParts, addedParts } = renderWordLevelDiff(removedText, addedText, `word-${changeIndex}-${i}`);
|
|
119
|
+
processedElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "red", children: "-" }), removedParts] }, `word-diff-removed-${changeIndex}-${i}`));
|
|
120
|
+
processedElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "green", children: "+" }), addedParts] }, `word-diff-added-${changeIndex}-${i}`));
|
|
121
|
+
i += 2; // Skip the next element since we processed it
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// Fallback to original elements
|
|
125
|
+
processedElements.push(current);
|
|
126
|
+
i += 1;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
processedElements.push(current);
|
|
131
|
+
i += 1;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return (_jsx(Box, { flexDirection: "column", children: processedElements }, changeIndex));
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.warn(`Error rendering diff for change ${changeIndex}:`, error);
|
|
138
|
+
// Fallback to simple display
|
|
139
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "red", children: ["-", change.oldContent || ""] }), _jsxs(Text, { color: "green", children: ["+", change.newContent || ""] })] }, changeIndex));
|
|
140
|
+
}
|
|
141
|
+
}) }));
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
console.warn("Error rendering expanded diff:", error);
|
|
145
|
+
return (_jsx(Box, { children: _jsx(Text, { color: "gray", children: "Error rendering diff display" }) }));
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
// Helper function to extract text content from a React element
|
|
149
|
+
const extractTextFromElement = (element) => {
|
|
150
|
+
if (!React.isValidElement(element))
|
|
151
|
+
return null;
|
|
152
|
+
// Navigate through Box -> Text structure
|
|
153
|
+
const children = element.props.children;
|
|
154
|
+
if (Array.isArray(children) && children.length >= 2) {
|
|
155
|
+
const textElement = children[1]; // Second child should be the Text with content
|
|
156
|
+
if (React.isValidElement(textElement) &&
|
|
157
|
+
textElement.props.children) {
|
|
158
|
+
return textElement.props.children;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
};
|
|
163
|
+
// Don't render anything if no diff should be shown
|
|
164
|
+
if (!showDiff) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
return (_jsx(Box, { flexDirection: "column", children: _jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Diff:" }), renderExpandedDiff()] }) }));
|
|
168
|
+
};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
type: "file" | "directory";
|
|
5
|
-
}
|
|
2
|
+
import type { FileItem } from "wave-agent-sdk";
|
|
3
|
+
export { type FileItem } from "wave-agent-sdk";
|
|
6
4
|
export interface FileSelectorProps {
|
|
7
5
|
files: FileItem[];
|
|
8
6
|
searchQuery: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSelector.d.ts","sourceRoot":"","sources":["../../src/components/FileSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;
|
|
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,CAyHpD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6B,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6B,MAAM,OAAO,CAAC;AAYlD,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,yGACqE,CAAC;AAEzG,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,KAC/C,IAAI,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1E,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAClD;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAuM5C,CAAC"}
|
|
@@ -9,11 +9,13 @@ import { MemoryTypeSelector } from "./MemoryTypeSelector.js";
|
|
|
9
9
|
import { BashShellManager } from "./BashShellManager.js";
|
|
10
10
|
import { McpManager } from "./McpManager.js";
|
|
11
11
|
import { useInputManager } from "../hooks/useInputManager.js";
|
|
12
|
+
import { useChat } from "../contexts/useChat.js";
|
|
12
13
|
export const INPUT_PLACEHOLDER_TEXT = "Type your message (use @ to reference files, / for commands, ! for bash history, # to add memory)...";
|
|
13
14
|
export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
|
|
14
15
|
export const InputBox = ({ isLoading = false, isCommandRunning = false, workdir, userInputHistory = [], sendMessage = () => { }, abortMessage = () => { }, saveMemory = async () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
|
|
15
16
|
// Get current working directory - memoized to avoid repeated process.cwd() calls
|
|
16
17
|
const currentWorkdir = useMemo(() => workdir || process.cwd(), [workdir]);
|
|
18
|
+
const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, } = useChat();
|
|
17
19
|
// Input manager with all input state and functionality (including images)
|
|
18
20
|
const { inputText, cursorPosition,
|
|
19
21
|
// Image management
|
|
@@ -28,6 +30,8 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, workdir,
|
|
|
28
30
|
showMemoryTypeSelector, memoryMessage, handleMemoryTypeSelect, handleCancelMemoryTypeSelect,
|
|
29
31
|
// Bash/MCP Manager
|
|
30
32
|
showBashManager, showMcpManager, setShowBashManager, setShowMcpManager,
|
|
33
|
+
// Permission mode
|
|
34
|
+
permissionMode, setPermissionMode,
|
|
31
35
|
// Input history
|
|
32
36
|
setUserInputHistory,
|
|
33
37
|
// Complex handlers combining multiple operations
|
|
@@ -40,7 +44,12 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, workdir,
|
|
|
40
44
|
onHasSlashCommand: hasSlashCommand,
|
|
41
45
|
onSaveMemory: saveMemory,
|
|
42
46
|
onAbortMessage: abortMessage,
|
|
47
|
+
onPermissionModeChange: setChatPermissionMode,
|
|
43
48
|
});
|
|
49
|
+
// Sync permission mode from useChat to InputManager
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
setPermissionMode(chatPermissionMode);
|
|
52
|
+
}, [chatPermissionMode, setPermissionMode]);
|
|
44
53
|
// Set user input history when it changes
|
|
45
54
|
useEffect(() => {
|
|
46
55
|
setUserInputHistory(userInputHistory);
|
|
@@ -65,5 +74,5 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, workdir,
|
|
|
65
74
|
if (!isManagerReady) {
|
|
66
75
|
return null;
|
|
67
76
|
}
|
|
68
|
-
return (_jsxs(Box, { flexDirection: "column", children: [showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, onSelect: handleFileSelect, onCancel: handleCancelFileSelect })), showCommandSelector && (_jsx(CommandSelector, { searchQuery: commandSearchQuery, onSelect: handleCommandSelect, onInsert: handleCommandInsert, onCancel: handleCancelCommandSelect, commands: slashCommands })), showBashHistorySelector && (_jsx(BashHistorySelector, { searchQuery: bashHistorySearchQuery, workdir: currentWorkdir, onSelect: handleBashHistorySelect, onExecute: handleBashHistoryExecuteAndSend, onCancel: handleCancelBashHistorySelect })), showMemoryTypeSelector && (_jsx(MemoryTypeSelector, { message: memoryMessage, onSelect: handleMemoryTypeSelect, onCancel: handleCancelMemoryTypeSelect })), showBashManager && (_jsx(BashShellManager, { onCancel: () => setShowBashManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showBashManager || showMcpManager || (_jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, children: _jsx(Text, { color: isPlaceholder ? "gray" : "white", children: shouldShowCursor ? (_jsxs(_Fragment, { children: [beforeCursor, _jsx(Text, { backgroundColor: "white", color: "black", children: atCursor }), afterCursor] })) : (displayText) }) }))] }));
|
|
77
|
+
return (_jsxs(Box, { flexDirection: "column", children: [showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, onSelect: handleFileSelect, onCancel: handleCancelFileSelect })), showCommandSelector && (_jsx(CommandSelector, { searchQuery: commandSearchQuery, onSelect: handleCommandSelect, onInsert: handleCommandInsert, onCancel: handleCancelCommandSelect, commands: slashCommands })), showBashHistorySelector && (_jsx(BashHistorySelector, { searchQuery: bashHistorySearchQuery, workdir: currentWorkdir, onSelect: handleBashHistorySelect, onExecute: handleBashHistoryExecuteAndSend, onCancel: handleCancelBashHistorySelect })), showMemoryTypeSelector && (_jsx(MemoryTypeSelector, { message: memoryMessage, onSelect: handleMemoryTypeSelect, onCancel: handleCancelMemoryTypeSelect })), showBashManager && (_jsx(BashShellManager, { onCancel: () => setShowBashManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showBashManager || showMcpManager || (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, children: _jsx(Text, { color: isPlaceholder ? "gray" : "white", children: shouldShowCursor ? (_jsxs(_Fragment, { children: [beforeCursor, _jsx(Text, { backgroundColor: "white", color: "black", children: atCursor }), afterCursor] })) : (displayText) }) }), _jsx(Box, { paddingX: 1, children: _jsxs(Text, { color: "gray", children: ["Mode: ", _jsx(Text, { color: "cyan", children: permissionMode }), " (Shift+Tab to cycle)"] }) })] }))] }));
|
|
69
78
|
};
|
|
@@ -15,7 +15,7 @@ export const MemoryDisplay = ({ block }) => {
|
|
|
15
15
|
if (!isSuccess)
|
|
16
16
|
return null;
|
|
17
17
|
if (memoryType === "user") {
|
|
18
|
-
return `Memory saved to ${storagePath || "
|
|
18
|
+
return `Memory saved to ${storagePath || "AGENTS.md"}`;
|
|
19
19
|
}
|
|
20
20
|
else {
|
|
21
21
|
return `Memory saved to ${storagePath || "AGENTS.md"}`;
|
|
@@ -3,7 +3,6 @@ export interface MessageItemProps {
|
|
|
3
3
|
message: Message;
|
|
4
4
|
isExpanded: boolean;
|
|
5
5
|
shouldShowHeader: boolean;
|
|
6
|
-
isStatic?: boolean;
|
|
7
6
|
}
|
|
8
|
-
export declare const MessageItem: ({ message, isExpanded, shouldShowHeader,
|
|
7
|
+
export declare const MessageItem: ({ message, isExpanded, shouldShowHeader, }: MessageItemProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
9
8
|
//# sourceMappingURL=MessageItem.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageItem.d.ts","sourceRoot":"","sources":["../../src/components/MessageItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAU9C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MessageItem.d.ts","sourceRoot":"","sources":["../../src/components/MessageItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAU9C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,WAAW,GAAI,4CAIzB,gBAAgB,mDAyElB,CAAC"}
|