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.
Files changed (90) hide show
  1. package/dist/cli.d.ts +1 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +2 -2
  4. package/dist/commands/plugin/disable.d.ts +5 -0
  5. package/dist/commands/plugin/disable.d.ts.map +1 -0
  6. package/dist/commands/plugin/disable.js +21 -0
  7. package/dist/commands/plugin/enable.d.ts +5 -0
  8. package/dist/commands/plugin/enable.d.ts.map +1 -0
  9. package/dist/commands/plugin/enable.js +21 -0
  10. package/dist/commands/plugin/install.d.ts +5 -0
  11. package/dist/commands/plugin/install.d.ts.map +1 -0
  12. package/dist/commands/plugin/install.js +28 -0
  13. package/dist/commands/plugin/list.d.ts +2 -0
  14. package/dist/commands/plugin/list.d.ts.map +1 -0
  15. package/dist/commands/plugin/list.js +53 -0
  16. package/dist/commands/plugin/marketplace.d.ts +8 -0
  17. package/dist/commands/plugin/marketplace.d.ts.map +1 -0
  18. package/dist/commands/plugin/marketplace.js +73 -0
  19. package/dist/components/App.d.ts +1 -0
  20. package/dist/components/App.d.ts.map +1 -1
  21. package/dist/components/App.js +4 -4
  22. package/dist/components/BashHistorySelector.d.ts +1 -0
  23. package/dist/components/BashHistorySelector.d.ts.map +1 -1
  24. package/dist/components/BashHistorySelector.js +15 -5
  25. package/dist/components/BashShellManager.d.ts.map +1 -1
  26. package/dist/components/BashShellManager.js +4 -4
  27. package/dist/components/ChatInterface.d.ts.map +1 -1
  28. package/dist/components/ChatInterface.js +1 -2
  29. package/dist/components/CommandSelector.d.ts.map +1 -1
  30. package/dist/components/CommandSelector.js +2 -2
  31. package/dist/components/Confirmation.d.ts +1 -0
  32. package/dist/components/Confirmation.d.ts.map +1 -1
  33. package/dist/components/Confirmation.js +151 -48
  34. package/dist/components/DiffDisplay.d.ts +3 -2
  35. package/dist/components/DiffDisplay.d.ts.map +1 -1
  36. package/dist/components/DiffDisplay.js +87 -82
  37. package/dist/components/FileSelector.d.ts.map +1 -1
  38. package/dist/components/FileSelector.js +2 -2
  39. package/dist/components/InputBox.d.ts.map +1 -1
  40. package/dist/components/InputBox.js +2 -2
  41. package/dist/components/McpManager.d.ts.map +1 -1
  42. package/dist/components/McpManager.js +3 -3
  43. package/dist/components/MemoryTypeSelector.d.ts.map +1 -1
  44. package/dist/components/MemoryTypeSelector.js +1 -1
  45. package/dist/components/MessageList.js +1 -1
  46. package/dist/components/PlanDisplay.d.ts +8 -0
  47. package/dist/components/PlanDisplay.d.ts.map +1 -0
  48. package/dist/components/PlanDisplay.js +14 -0
  49. package/dist/components/ToolResultDisplay.d.ts.map +1 -1
  50. package/dist/components/ToolResultDisplay.js +1 -1
  51. package/dist/contexts/useChat.d.ts +1 -0
  52. package/dist/contexts/useChat.d.ts.map +1 -1
  53. package/dist/contexts/useChat.js +3 -1
  54. package/dist/hooks/useInputManager.d.ts +1 -0
  55. package/dist/hooks/useInputManager.d.ts.map +1 -1
  56. package/dist/hooks/useInputManager.js +4 -0
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +103 -0
  59. package/dist/managers/InputManager.d.ts +1 -0
  60. package/dist/managers/InputManager.d.ts.map +1 -1
  61. package/dist/managers/InputManager.js +7 -2
  62. package/dist/print-cli.d.ts +1 -0
  63. package/dist/print-cli.d.ts.map +1 -1
  64. package/dist/print-cli.js +2 -1
  65. package/package.json +2 -2
  66. package/src/cli.tsx +8 -1
  67. package/src/commands/plugin/disable.ts +31 -0
  68. package/src/commands/plugin/enable.ts +31 -0
  69. package/src/commands/plugin/install.ts +42 -0
  70. package/src/commands/plugin/list.ts +64 -0
  71. package/src/commands/plugin/marketplace.ts +72 -0
  72. package/src/components/App.tsx +11 -5
  73. package/src/components/BashHistorySelector.tsx +25 -7
  74. package/src/components/BashShellManager.tsx +16 -8
  75. package/src/components/ChatInterface.tsx +29 -27
  76. package/src/components/CommandSelector.tsx +8 -4
  77. package/src/components/Confirmation.tsx +312 -106
  78. package/src/components/DiffDisplay.tsx +167 -149
  79. package/src/components/FileSelector.tsx +8 -4
  80. package/src/components/InputBox.tsx +14 -4
  81. package/src/components/McpManager.tsx +12 -6
  82. package/src/components/MemoryTypeSelector.tsx +4 -2
  83. package/src/components/MessageList.tsx +1 -1
  84. package/src/components/PlanDisplay.tsx +46 -0
  85. package/src/components/ToolResultDisplay.tsx +4 -2
  86. package/src/contexts/useChat.tsx +4 -0
  87. package/src/hooks/useInputManager.ts +8 -0
  88. package/src/index.ts +178 -0
  89. package/src/managers/InputManager.ts +12 -1
  90. 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 "Bash":
13
+ case BASH_TOOL_NAME:
11
14
  return `Execute command: ${toolInput.command || "unknown command"}`;
12
- case "Edit":
15
+ case EDIT_TOOL_NAME:
13
16
  return `Edit file: ${toolInput.file_path || "unknown file"}`;
14
- case "MultiEdit":
17
+ case MULTI_EDIT_TOOL_NAME:
15
18
  return `Edit multiple sections in: ${toolInput.file_path || "unknown file"}`;
16
- case "Delete":
19
+ case DELETE_FILE_TOOL_NAME:
17
20
  return `Delete file: ${toolInput.target_file || "unknown file"}`;
18
- case "Write":
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
- export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersistentOption, onDecision, onCancel, onAbort, }) => {
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 === "Bash") {
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
- onDecision({ behavior: "allow" });
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 === "Bash") {
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", 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"), !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" ? "> " : " ", "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" ? "> " : " ", hidePersistentOption ? "2. " : "3. ", showPlaceholder ? (_jsx(Text, { color: "gray", dimColor: true, children: placeholderText })) : (_jsx(Text, { children: state.alternativeText ||
171
- "Type here to tell Wave what to do differently" }))] }) }, "alternative-option")] }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Use \u2191\u2193 or 1-", hidePersistentOption ? "2" : "3", " to navigate \u2022 ESC to cancel"] }) })] }));
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
- toolBlock: ToolBlock;
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;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"}
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 = ({ toolBlock }) => {
7
- const showDiff = ["running", "end"].includes(toolBlock.stage) &&
8
- toolBlock.name &&
9
- ["Write", "Edit", "MultiEdit"].includes(toolBlock.name);
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 || !toolBlock.name || !toolBlock.parameters)
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(toolBlock.name, toolBlock.parameters);
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
- }, [toolBlock.name, toolBlock.parameters, showDiff]);
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
- 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
- }
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
- processedElements.push(current);
125
+ // Fallback to original elements
126
+ allElements.push(current);
131
127
  i += 1;
132
128
  }
133
129
  }
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));
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,CAyHpD,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,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", padding: 1, marginBottom: 1, children: [_jsxs(Text, { color: "yellow", children: ["\uD83D\uDCC1 No files found for \"", searchQuery, "\""] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
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", padding: 1, marginBottom: 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) => {
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,CAuM5C,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,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", 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)"] }) })] }))] }));
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,CA4ThD,CAAC"}
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", padding: 1, gap: 1, marginBottom: 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 &&
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", padding: 1, marginBottom: 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" })] }));
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", padding: 1, gap: 1, marginBottom: 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" ||
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,CAsFhE,CAAC"}
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", padding: 1, gap: 1, marginBottom: 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" }) })] }));
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", paddingX: 1, 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) => {
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));