wave-code 0.0.16 → 0.0.17
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/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/commands/plugin/disable.d.ts +5 -0
- package/dist/commands/plugin/disable.d.ts.map +1 -0
- package/dist/commands/plugin/disable.js +21 -0
- package/dist/commands/plugin/enable.d.ts +5 -0
- package/dist/commands/plugin/enable.d.ts.map +1 -0
- package/dist/commands/plugin/enable.js +21 -0
- package/dist/commands/plugin/install.d.ts +5 -0
- package/dist/commands/plugin/install.d.ts.map +1 -0
- package/dist/commands/plugin/install.js +28 -0
- package/dist/commands/plugin/list.d.ts +2 -0
- package/dist/commands/plugin/list.d.ts.map +1 -0
- package/dist/commands/plugin/list.js +53 -0
- package/dist/commands/plugin/marketplace.d.ts +8 -0
- package/dist/commands/plugin/marketplace.d.ts.map +1 -0
- package/dist/commands/plugin/marketplace.js +73 -0
- 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 +1 -0
- package/dist/components/BashHistorySelector.d.ts.map +1 -1
- package/dist/components/BashHistorySelector.js +15 -5
- package/dist/components/BashShellManager.d.ts.map +1 -1
- package/dist/components/BashShellManager.js +4 -4
- package/dist/components/ChatInterface.d.ts.map +1 -1
- package/dist/components/ChatInterface.js +1 -2
- package/dist/components/CommandSelector.d.ts.map +1 -1
- package/dist/components/CommandSelector.js +2 -2
- package/dist/components/Confirmation.d.ts +1 -0
- package/dist/components/Confirmation.d.ts.map +1 -1
- package/dist/components/Confirmation.js +151 -48
- package/dist/components/DiffDisplay.d.ts +3 -2
- package/dist/components/DiffDisplay.d.ts.map +1 -1
- package/dist/components/DiffDisplay.js +87 -82
- package/dist/components/FileSelector.d.ts.map +1 -1
- package/dist/components/FileSelector.js +2 -2
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +2 -2
- package/dist/components/McpManager.d.ts.map +1 -1
- package/dist/components/McpManager.js +3 -3
- package/dist/components/MemoryTypeSelector.d.ts.map +1 -1
- package/dist/components/MemoryTypeSelector.js +1 -1
- package/dist/components/MessageList.js +1 -1
- package/dist/components/PlanDisplay.d.ts +8 -0
- package/dist/components/PlanDisplay.d.ts.map +1 -0
- package/dist/components/PlanDisplay.js +14 -0
- package/dist/components/ToolResultDisplay.d.ts.map +1 -1
- package/dist/components/ToolResultDisplay.js +1 -1
- package/dist/contexts/useChat.d.ts +1 -0
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +3 -1
- package/dist/hooks/useInputManager.d.ts +1 -0
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +103 -0
- package/dist/managers/InputManager.d.ts +1 -0
- package/dist/managers/InputManager.d.ts.map +1 -1
- package/dist/managers/InputManager.js +7 -2
- package/dist/print-cli.d.ts +1 -0
- package/dist/print-cli.d.ts.map +1 -1
- package/dist/print-cli.js +2 -1
- package/package.json +2 -2
- package/src/cli.tsx +8 -1
- package/src/commands/plugin/disable.ts +31 -0
- package/src/commands/plugin/enable.ts +31 -0
- package/src/commands/plugin/install.ts +42 -0
- package/src/commands/plugin/list.ts +64 -0
- package/src/commands/plugin/marketplace.ts +72 -0
- package/src/components/App.tsx +11 -5
- package/src/components/BashHistorySelector.tsx +25 -7
- package/src/components/BashShellManager.tsx +16 -8
- package/src/components/ChatInterface.tsx +29 -27
- package/src/components/CommandSelector.tsx +8 -4
- package/src/components/Confirmation.tsx +312 -106
- package/src/components/DiffDisplay.tsx +167 -149
- package/src/components/FileSelector.tsx +8 -4
- package/src/components/InputBox.tsx +14 -4
- package/src/components/McpManager.tsx +12 -6
- package/src/components/MemoryTypeSelector.tsx +4 -2
- package/src/components/MessageList.tsx +1 -1
- package/src/components/PlanDisplay.tsx +46 -0
- package/src/components/ToolResultDisplay.tsx +4 -2
- package/src/contexts/useChat.tsx +4 -0
- package/src/hooks/useInputManager.ts +8 -0
- package/src/index.ts +178 -0
- package/src/managers/InputManager.ts +12 -1
- package/src/print-cli.ts +3 -0
|
@@ -1,34 +1,60 @@
|
|
|
1
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, 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, 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";
|
|
4
7
|
// Helper function to generate descriptive action text
|
|
5
8
|
const getActionDescription = (toolName, toolInput) => {
|
|
6
9
|
if (!toolInput) {
|
|
7
10
|
return "Execute operation";
|
|
8
11
|
}
|
|
9
12
|
switch (toolName) {
|
|
10
|
-
case
|
|
13
|
+
case BASH_TOOL_NAME:
|
|
11
14
|
return `Execute command: ${toolInput.command || "unknown command"}`;
|
|
12
|
-
case
|
|
15
|
+
case EDIT_TOOL_NAME:
|
|
13
16
|
return `Edit file: ${toolInput.file_path || "unknown file"}`;
|
|
14
|
-
case
|
|
17
|
+
case MULTI_EDIT_TOOL_NAME:
|
|
15
18
|
return `Edit multiple sections in: ${toolInput.file_path || "unknown file"}`;
|
|
16
|
-
case
|
|
19
|
+
case DELETE_FILE_TOOL_NAME:
|
|
17
20
|
return `Delete file: ${toolInput.target_file || "unknown file"}`;
|
|
18
|
-
case
|
|
21
|
+
case WRITE_TOOL_NAME:
|
|
19
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";
|
|
20
27
|
default:
|
|
21
28
|
return "Execute operation";
|
|
22
29
|
}
|
|
23
30
|
};
|
|
24
|
-
|
|
31
|
+
const getHeaderColor = (header) => {
|
|
32
|
+
const colors = ["red", "green", "blue", "magenta", "cyan"];
|
|
33
|
+
let hash = 0;
|
|
34
|
+
for (let i = 0; i < header.length; i++) {
|
|
35
|
+
hash = header.charCodeAt(i) + ((hash << 5) - hash);
|
|
36
|
+
}
|
|
37
|
+
return colors[Math.abs(hash) % colors.length];
|
|
38
|
+
};
|
|
39
|
+
export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersistentOption, isExpanded = false, onDecision, onCancel, onAbort, }) => {
|
|
25
40
|
const [state, setState] = useState({
|
|
26
41
|
selectedOption: "allow",
|
|
27
42
|
alternativeText: "",
|
|
28
43
|
hasUserInput: false,
|
|
29
44
|
});
|
|
45
|
+
// Specialized state for AskUserQuestion
|
|
46
|
+
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
|
|
47
|
+
const [selectedOptionIndex, setSelectedOptionIndex] = useState(0);
|
|
48
|
+
const [selectedOptionIndices, setSelectedOptionIndices] = useState(new Set());
|
|
49
|
+
const [userAnswers, setUserAnswers] = useState({});
|
|
50
|
+
const [otherText, setOtherText] = useState("");
|
|
51
|
+
const questions = toolInput?.questions || [];
|
|
52
|
+
const currentQuestion = questions[currentQuestionIndex];
|
|
30
53
|
const getAutoOptionText = () => {
|
|
31
|
-
if (toolName ===
|
|
54
|
+
if (toolName === EXIT_PLAN_MODE_TOOL_NAME) {
|
|
55
|
+
return "Yes, and auto-accept edits";
|
|
56
|
+
}
|
|
57
|
+
if (toolName === BASH_TOOL_NAME) {
|
|
32
58
|
if (suggestedPrefix) {
|
|
33
59
|
return `Yes, and don't ask again for: ${suggestedPrefix}`;
|
|
34
60
|
}
|
|
@@ -43,13 +69,109 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
43
69
|
onAbort();
|
|
44
70
|
return;
|
|
45
71
|
}
|
|
72
|
+
if (toolName === ASK_USER_QUESTION_TOOL_NAME) {
|
|
73
|
+
if (!currentQuestion)
|
|
74
|
+
return;
|
|
75
|
+
const options = [...currentQuestion.options, { label: "Other" }];
|
|
76
|
+
const isMultiSelect = !!currentQuestion.multiSelect;
|
|
77
|
+
const isOtherFocused = selectedOptionIndex === options.length - 1;
|
|
78
|
+
if (key.return) {
|
|
79
|
+
let answer = "";
|
|
80
|
+
if (isMultiSelect) {
|
|
81
|
+
const selectedLabels = Array.from(selectedOptionIndices)
|
|
82
|
+
.filter((i) => i < currentQuestion.options.length)
|
|
83
|
+
.map((i) => currentQuestion.options[i].label);
|
|
84
|
+
const isOtherChecked = selectedOptionIndices.has(options.length - 1);
|
|
85
|
+
if (isOtherChecked && otherText.trim()) {
|
|
86
|
+
selectedLabels.push(otherText.trim());
|
|
87
|
+
}
|
|
88
|
+
answer = selectedLabels.join(", ");
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
if (isOtherFocused) {
|
|
92
|
+
answer = otherText.trim();
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
answer = options[selectedOptionIndex].label;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (!answer)
|
|
99
|
+
return;
|
|
100
|
+
const newAnswers = {
|
|
101
|
+
...userAnswers,
|
|
102
|
+
[currentQuestion.question]: answer,
|
|
103
|
+
};
|
|
104
|
+
setUserAnswers(newAnswers);
|
|
105
|
+
if (currentQuestionIndex < questions.length - 1) {
|
|
106
|
+
setCurrentQuestionIndex(currentQuestionIndex + 1);
|
|
107
|
+
setSelectedOptionIndex(0);
|
|
108
|
+
setSelectedOptionIndices(new Set());
|
|
109
|
+
setOtherText("");
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// All questions answered
|
|
113
|
+
onDecision({
|
|
114
|
+
behavior: "allow",
|
|
115
|
+
message: JSON.stringify(newAnswers),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (input === " ") {
|
|
121
|
+
if (isMultiSelect &&
|
|
122
|
+
(!isOtherFocused || !selectedOptionIndices.has(selectedOptionIndex))) {
|
|
123
|
+
setSelectedOptionIndices((prev) => {
|
|
124
|
+
const next = new Set(prev);
|
|
125
|
+
if (next.has(selectedOptionIndex)) {
|
|
126
|
+
next.delete(selectedOptionIndex);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
next.add(selectedOptionIndex);
|
|
130
|
+
}
|
|
131
|
+
return next;
|
|
132
|
+
});
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (!isOtherFocused) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
// If isOtherFocused is true, fall through to handle space as text input
|
|
139
|
+
}
|
|
140
|
+
if (key.upArrow) {
|
|
141
|
+
if (selectedOptionIndex > 0) {
|
|
142
|
+
setSelectedOptionIndex(selectedOptionIndex - 1);
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (key.downArrow) {
|
|
147
|
+
if (selectedOptionIndex < options.length - 1) {
|
|
148
|
+
setSelectedOptionIndex(selectedOptionIndex + 1);
|
|
149
|
+
}
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (isOtherFocused) {
|
|
153
|
+
if (key.backspace || key.delete) {
|
|
154
|
+
setOtherText((prev) => prev.slice(0, -1));
|
|
155
|
+
}
|
|
156
|
+
else if (input && !key.ctrl && !key.meta) {
|
|
157
|
+
setOtherText((prev) => prev + input);
|
|
158
|
+
}
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
46
163
|
// Handle Enter to confirm selection
|
|
47
164
|
if (key.return) {
|
|
48
165
|
if (state.selectedOption === "allow") {
|
|
49
|
-
|
|
166
|
+
if (toolName === EXIT_PLAN_MODE_TOOL_NAME) {
|
|
167
|
+
onDecision({ behavior: "allow", newPermissionMode: "default" });
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
onDecision({ behavior: "allow" });
|
|
171
|
+
}
|
|
50
172
|
}
|
|
51
173
|
else if (state.selectedOption === "auto") {
|
|
52
|
-
if (toolName ===
|
|
174
|
+
if (toolName === BASH_TOOL_NAME) {
|
|
53
175
|
const rule = suggestedPrefix
|
|
54
176
|
? `Bash(${suggestedPrefix}:*)`
|
|
55
177
|
: `Bash(${toolInput?.command})`;
|
|
@@ -76,42 +198,6 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
76
198
|
}
|
|
77
199
|
return;
|
|
78
200
|
}
|
|
79
|
-
// Handle numeric keys for quick selection (only if not typing in alternative)
|
|
80
|
-
if (state.selectedOption !== "alternative" || !state.hasUserInput) {
|
|
81
|
-
if (input === "1") {
|
|
82
|
-
onDecision({ behavior: "allow" });
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (input === "2") {
|
|
86
|
-
if (!hidePersistentOption) {
|
|
87
|
-
if (toolName === "Bash") {
|
|
88
|
-
const rule = suggestedPrefix
|
|
89
|
-
? `Bash(${suggestedPrefix}:*)`
|
|
90
|
-
: `Bash(${toolInput?.command})`;
|
|
91
|
-
onDecision({
|
|
92
|
-
behavior: "allow",
|
|
93
|
-
newPermissionRule: rule,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
onDecision({
|
|
98
|
-
behavior: "allow",
|
|
99
|
-
newPermissionMode: "acceptEdits",
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
// If auto option is hidden, '2' selects alternative
|
|
106
|
-
setState((prev) => ({ ...prev, selectedOption: "alternative" }));
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if (input === "3" && !hidePersistentOption) {
|
|
111
|
-
setState((prev) => ({ ...prev, selectedOption: "alternative" }));
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
201
|
// Handle arrow keys for navigation
|
|
116
202
|
if (key.upArrow) {
|
|
117
203
|
setState((prev) => {
|
|
@@ -167,6 +253,23 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
|
|
|
167
253
|
});
|
|
168
254
|
const placeholderText = "Type here to tell Wave what to do differently";
|
|
169
255
|
const showPlaceholder = state.selectedOption === "alternative" && !state.hasUserInput;
|
|
170
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow",
|
|
171
|
-
|
|
256
|
+
return (_jsxs(Box, { 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), isExpanded: isExpanded }), toolName === ASK_USER_QUESTION_TOOL_NAME &&
|
|
257
|
+
currentQuestion &&
|
|
258
|
+
!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: (() => {
|
|
259
|
+
const isMultiSelect = !!currentQuestion.multiSelect;
|
|
260
|
+
return [...currentQuestion.options, { label: "Other" }].map((option, index) => {
|
|
261
|
+
const isSelected = selectedOptionIndex === index;
|
|
262
|
+
const isChecked = isMultiSelect
|
|
263
|
+
? selectedOptionIndices.has(index)
|
|
264
|
+
: isSelected;
|
|
265
|
+
const isOther = index === currentQuestion.options.length;
|
|
266
|
+
const isRecommended = !isOther && option.isRecommended;
|
|
267
|
+
return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "yellow" : undefined, children: [isSelected ? "> " : " ", isMultiSelect ? (isChecked ? "[x] " : "[ ] ") : "", option.label, isRecommended && (_jsxs(Text, { color: "green", bold: true, children: [" ", "(Recommended)"] })), option.description ? ` - ${option.description}` : "", isOther && isSelected && (_jsxs(Text, { children: [":", " ", otherText || (_jsx(Text, { color: "gray", dimColor: true, children: "[Type your answer...]" }))] }))] }) }, index));
|
|
268
|
+
});
|
|
269
|
+
})() }), _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 &&
|
|
270
|
+
toolName === EXIT_PLAN_MODE_TOOL_NAME &&
|
|
271
|
+
!!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
|
|
272
|
+
? "Yes, proceed with default mode"
|
|
273
|
+
: "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 ||
|
|
274
|
+
"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" }) })] }))] }));
|
|
172
275
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { ToolBlock } from "wave-agent-sdk";
|
|
3
2
|
interface DiffDisplayProps {
|
|
4
|
-
|
|
3
|
+
toolName?: string;
|
|
4
|
+
parameters?: string;
|
|
5
|
+
isExpanded?: boolean;
|
|
5
6
|
}
|
|
6
7
|
export declare const DiffDisplay: React.FC<DiffDisplayProps>;
|
|
7
8
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DiffDisplay.d.ts","sourceRoot":"","sources":["../../src/components/DiffDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;
|
|
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;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA6SlD,CAAC"}
|
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useMemo } from "react";
|
|
3
|
-
import { Box, Text } from "ink";
|
|
3
|
+
import { Box, Text, useStdout } from "ink";
|
|
4
|
+
import { WRITE_TOOL_NAME, EDIT_TOOL_NAME, MULTI_EDIT_TOOL_NAME, } from "wave-agent-sdk";
|
|
4
5
|
import { transformToolBlockToChanges } from "../utils/toolParameterTransforms.js";
|
|
5
6
|
import { diffLines, diffWords } from "diff";
|
|
6
|
-
export const DiffDisplay = ({
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export const DiffDisplay = ({ toolName, parameters, isExpanded = false, }) => {
|
|
8
|
+
const { stdout } = useStdout();
|
|
9
|
+
const maxHeight = useMemo(() => {
|
|
10
|
+
return Math.max(5, (stdout?.rows || 24) - 20);
|
|
11
|
+
}, [stdout?.rows]);
|
|
12
|
+
const showDiff = toolName &&
|
|
13
|
+
[WRITE_TOOL_NAME, EDIT_TOOL_NAME, MULTI_EDIT_TOOL_NAME].includes(toolName);
|
|
10
14
|
// Diff detection and transformation using typed parameters
|
|
11
15
|
const changes = useMemo(() => {
|
|
12
|
-
if (!showDiff || !
|
|
16
|
+
if (!showDiff || !toolName || !parameters)
|
|
13
17
|
return [];
|
|
14
18
|
try {
|
|
15
19
|
// Use local transformation with JSON parsing and type guards
|
|
16
|
-
return transformToolBlockToChanges(
|
|
20
|
+
return transformToolBlockToChanges(toolName, parameters);
|
|
17
21
|
}
|
|
18
22
|
catch (error) {
|
|
19
23
|
console.warn("Error transforming tool block to changes:", error);
|
|
20
24
|
return [];
|
|
21
25
|
}
|
|
22
|
-
}, [
|
|
26
|
+
}, [toolName, parameters, showDiff]);
|
|
23
27
|
// Render word-level diff between two lines of text
|
|
24
28
|
const renderWordLevelDiff = (oldLine, newLine, keyPrefix) => {
|
|
25
29
|
try {
|
|
@@ -59,86 +63,87 @@ export const DiffDisplay = ({ toolBlock }) => {
|
|
|
59
63
|
try {
|
|
60
64
|
if (changes.length === 0)
|
|
61
65
|
return null;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
}
|
|
66
|
+
const allElements = [];
|
|
67
|
+
changes.forEach((change, changeIndex) => {
|
|
68
|
+
try {
|
|
69
|
+
// Get line-level diff to understand the structure
|
|
70
|
+
const lineDiffs = diffLines(change.oldContent || "", change.newContent || "");
|
|
71
|
+
const diffElements = [];
|
|
72
|
+
// Process line diffs and apply word-level diff to changed lines
|
|
73
|
+
lineDiffs.forEach((part, partIndex) => {
|
|
74
|
+
if (part.added) {
|
|
75
|
+
const lines = part.value
|
|
76
|
+
.split("\n")
|
|
77
|
+
.filter((line) => line !== "");
|
|
78
|
+
lines.forEach((line, lineIndex) => {
|
|
79
|
+
diffElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "green", children: "+" }), _jsx(Text, { color: "green", children: line })] }, `add-${changeIndex}-${partIndex}-${lineIndex}`));
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
else if (part.removed) {
|
|
83
|
+
const lines = part.value
|
|
84
|
+
.split("\n")
|
|
85
|
+
.filter((line) => line !== "");
|
|
86
|
+
lines.forEach((line, lineIndex) => {
|
|
87
|
+
diffElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "red", children: "-" }), _jsx(Text, { color: "red", children: line })] }, `remove-${changeIndex}-${partIndex}-${lineIndex}`));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Context lines - show unchanged content
|
|
92
|
+
const lines = part.value
|
|
93
|
+
.split("\n")
|
|
94
|
+
.filter((line) => line !== "");
|
|
95
|
+
lines.forEach((line, lineIndex) => {
|
|
96
|
+
diffElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "white", children: " " }), _jsx(Text, { color: "white", children: line })] }, `context-${changeIndex}-${partIndex}-${lineIndex}`));
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
// Now look for pairs of removed/added lines that can be word-diffed
|
|
101
|
+
let i = 0;
|
|
102
|
+
while (i < diffElements.length) {
|
|
103
|
+
const current = diffElements[i];
|
|
104
|
+
const next = i + 1 < diffElements.length ? diffElements[i + 1] : null;
|
|
105
|
+
// Check if we have a removed line followed by an added line
|
|
106
|
+
const currentKey = React.isValidElement(current) ? current.key : "";
|
|
107
|
+
const nextKey = React.isValidElement(next) ? next.key : "";
|
|
108
|
+
const isCurrentRemoved = typeof currentKey === "string" && currentKey.includes("remove-");
|
|
109
|
+
const isNextAdded = typeof nextKey === "string" && nextKey.includes("add-");
|
|
110
|
+
if (isCurrentRemoved &&
|
|
111
|
+
isNextAdded &&
|
|
112
|
+
React.isValidElement(current) &&
|
|
113
|
+
React.isValidElement(next)) {
|
|
114
|
+
// Extract the text content from the removed and added lines
|
|
115
|
+
const removedText = extractTextFromElement(current);
|
|
116
|
+
const addedText = extractTextFromElement(next);
|
|
117
|
+
if (removedText && addedText) {
|
|
118
|
+
// Apply word-level diff
|
|
119
|
+
const { removedParts, addedParts } = renderWordLevelDiff(removedText, addedText, `word-${changeIndex}-${i}`);
|
|
120
|
+
allElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "red", children: "-" }), removedParts] }, `word-diff-removed-${changeIndex}-${i}`));
|
|
121
|
+
allElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "green", children: "+" }), addedParts] }, `word-diff-added-${changeIndex}-${i}`));
|
|
122
|
+
i += 2; // Skip the next element since we processed it
|
|
128
123
|
}
|
|
129
124
|
else {
|
|
130
|
-
|
|
125
|
+
// Fallback to original elements
|
|
126
|
+
allElements.push(current);
|
|
131
127
|
i += 1;
|
|
132
128
|
}
|
|
133
129
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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));
|
|
130
|
+
else {
|
|
131
|
+
allElements.push(current);
|
|
132
|
+
i += 1;
|
|
133
|
+
}
|
|
140
134
|
}
|
|
141
|
-
}
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.warn(`Error rendering diff for change ${changeIndex}:`, error);
|
|
138
|
+
// Fallback to simple display
|
|
139
|
+
allElements.push(_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "red", children: ["-", change.oldContent || ""] }), _jsxs(Text, { color: "green", children: ["+", change.newContent || ""] })] }, `fallback-${changeIndex}`));
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
const isTruncated = !isExpanded && allElements.length > maxHeight;
|
|
143
|
+
const displayElements = isTruncated
|
|
144
|
+
? allElements.slice(0, maxHeight - 1)
|
|
145
|
+
: allElements;
|
|
146
|
+
return (_jsxs(Box, { flexDirection: "column", children: [displayElements, isTruncated && (_jsxs(Text, { color: "yellow", dimColor: true, children: ["... (truncated ", allElements.length - (maxHeight - 1), " more lines)"] }))] }));
|
|
142
147
|
}
|
|
143
148
|
catch (error) {
|
|
144
149
|
console.warn("Error rendering expanded diff:", error);
|
|
@@ -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,CA6HpD,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",
|
|
27
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, 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",
|
|
42
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, 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" ? "📁" : "📄";
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,CAiN5C,CAAC"}
|
|
@@ -35,7 +35,7 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, workdir,
|
|
|
35
35
|
// Input history
|
|
36
36
|
setUserInputHistory,
|
|
37
37
|
// Complex handlers combining multiple operations
|
|
38
|
-
handleBashHistoryExecuteAndSend,
|
|
38
|
+
handleBashHistoryExecuteAndSend, handleBashHistoryDelete,
|
|
39
39
|
// Main handler
|
|
40
40
|
handleInput,
|
|
41
41
|
// Manager ready state
|
|
@@ -74,5 +74,5 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, workdir,
|
|
|
74
74
|
if (!isManagerReady) {
|
|
75
75
|
return null;
|
|
76
76
|
}
|
|
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",
|
|
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, onDelete: handleBashHistoryDelete, 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", borderLeft: false, borderRight: false, 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, { paddingRight: 1, children: _jsxs(Text, { color: "gray", children: ["Mode:", " ", _jsx(Text, { color: permissionMode === "plan" ? "yellow" : "cyan", children: permissionMode }), " ", "(Shift+Tab to cycle)"] }) })] }))] }));
|
|
78
78
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpManager.d.ts","sourceRoot":"","sources":["../../src/components/McpManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,kBAAkB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"McpManager.d.ts","sourceRoot":"","sources":["../../src/components/McpManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,kBAAkB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAkUhD,CAAC"}
|
|
@@ -105,16 +105,16 @@ export const McpManager = ({ onCancel, servers, onConnectServer, onDisconnectSer
|
|
|
105
105
|
}
|
|
106
106
|
});
|
|
107
107
|
if (viewMode === "detail" && selectedServer) {
|
|
108
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan",
|
|
108
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "cyan", bold: true, children: ["MCP Server Details: ", selectedServer.name] }) }), _jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Status:" }), " ", _jsxs(Text, { color: getStatusColor(selectedServer.status), children: [getStatusIcon(selectedServer.status), " ", selectedServer.status] })] }) }), _jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Command:" }), " ", selectedServer.config.command] }) }), selectedServer.config.args && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Args:" }), " ", selectedServer.config.args.join(" ")] }) })), selectedServer.toolCount !== undefined && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Tools:" }), " ", selectedServer.toolCount, " ", "tools"] }) })), selectedServer.capabilities && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Capabilities:" }), " ", selectedServer.capabilities.join(", ")] }) })), selectedServer.lastConnected && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Last Connected:" }), " ", formatTime(selectedServer.lastConnected)] }) })), selectedServer.error && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "red", children: "Error:" }), " ", selectedServer.error] }) }))] }), selectedServer.config.env &&
|
|
109
109
|
Object.keys(selectedServer.config.env).length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "blue", bold: true, children: "Environment Variables:" }), _jsx(Box, { borderStyle: "single", borderColor: "blue", padding: 1, children: Object.entries(selectedServer.config.env).map(([key, value]) => (_jsxs(Text, { children: [key, "=", value] }, key))) })] })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: [selectedServer.status === "disconnected" ||
|
|
110
110
|
selectedServer.status === "error"
|
|
111
111
|
? "c to connect · "
|
|
112
112
|
: "", selectedServer.status === "connected" ? "d to disconnect · " : "", "Esc to go back"] }) })] }));
|
|
113
113
|
}
|
|
114
114
|
if (servers.length === 0) {
|
|
115
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan",
|
|
115
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "Manage MCP servers" }), _jsx(Text, { children: "No MCP servers configured" }), _jsx(Text, { dimColor: true, children: "Create a .mcp.json file in your project root to add servers" }), _jsx(Text, { dimColor: true, children: "Press Escape to close" })] }));
|
|
116
116
|
}
|
|
117
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan",
|
|
117
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsx(Text, { color: "cyan", bold: true, children: "Manage MCP servers" }) }), _jsx(Text, { dimColor: true, children: "Select a server to view details" }), servers.map((server, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: index === selectedIndex ? "black" : "white", backgroundColor: index === selectedIndex ? "cyan" : undefined, children: [index === selectedIndex ? "▶ " : " ", index + 1, ".", " ", _jsx(Text, { color: getStatusColor(server.status), children: getStatusIcon(server.status) }), " ", server.name, server.status === "connected" && server.toolCount && (_jsxs(Text, { color: "green", children: [" \u00B7 ", server.toolCount, " tools"] }))] }), index === selectedIndex && (_jsxs(Box, { marginLeft: 4, flexDirection: "column", children: [_jsxs(Text, { color: "gray", dimColor: true, children: [server.config.command, server.config.args ? ` ${server.config.args.join(" ")}` : ""] }), server.lastConnected && (_jsxs(Text, { color: "gray", dimColor: true, children: ["Last connected: ", formatTime(server.lastConnected)] }))] }))] }, server.name))), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["\u2191/\u2193 to select \u00B7 Enter to view \u00B7", " ", servers[selectedIndex]?.status === "disconnected" ||
|
|
118
118
|
servers[selectedIndex]?.status === "error"
|
|
119
119
|
? "c to connect · "
|
|
120
120
|
: "", servers[selectedIndex]?.status === "connected"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoryTypeSelector.d.ts","sourceRoot":"","sources":["../../src/components/MemoryTypeSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,KAAK,IAAI,CAAC;IAC7C,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,
|
|
1
|
+
{"version":3,"file":"MemoryTypeSelector.d.ts","sourceRoot":"","sources":["../../src/components/MemoryTypeSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,KAAK,IAAI,CAAC;IAC7C,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAwFhE,CAAC"}
|
|
@@ -34,5 +34,5 @@ export const MemoryTypeSelector = ({ message, onSelect, onCancel, }) => {
|
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "green",
|
|
37
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "green", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "green", bold: true, children: ["Save Memory: \"", message.substring(1).trim(), "\""] }) }), _jsx(Text, { color: "gray", children: "Choose where to save this memory:" }), options.map((option, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: index === selectedIndex ? "black" : "white", backgroundColor: index === selectedIndex ? "green" : undefined, bold: index === selectedIndex, children: option.label }), index === selectedIndex && (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: "gray", dimColor: true, children: option.description }) }))] }, option.type))), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate, Enter to select, Escape to cancel" }) })] }));
|
|
38
38
|
};
|
|
@@ -24,7 +24,7 @@ export const MessageList = React.memo(({ messages, isLoading = false, isCommandR
|
|
|
24
24
|
const dynamicMessages = shouldRenderLastDynamic && displayMessages.length > 0
|
|
25
25
|
? [displayMessages[displayMessages.length - 1]]
|
|
26
26
|
: [];
|
|
27
|
-
return (_jsxs(Box, { flexDirection: "column",
|
|
27
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [omittedCount > 0 && (_jsx(Box, { children: _jsxs(Text, { color: "gray", dimColor: true, children: ["... ", omittedCount, " earlier message", omittedCount !== 1 ? "s" : "", " ", "omitted (showing latest ", maxExpandedMessages, ")"] }) })), _jsx(Static, { items: staticMessages, children: (message, key) => {
|
|
28
28
|
// Get previous message
|
|
29
29
|
const previousMessage = key > 0 ? staticMessages[key - 1] : undefined;
|
|
30
30
|
return (_jsx(MessageItem, { message: message, shouldShowHeader: previousMessage?.role !== message.role, isExpanded: isExpanded }, key));
|