wave-code 0.5.0 → 0.6.2

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 (112) hide show
  1. package/dist/components/App.d.ts.map +1 -1
  2. package/dist/components/App.js +40 -2
  3. package/dist/components/BackgroundTaskManager.d.ts +6 -0
  4. package/dist/components/BackgroundTaskManager.d.ts.map +1 -0
  5. package/dist/components/{TaskManager.js → BackgroundTaskManager.js} +1 -1
  6. package/dist/components/ChatInterface.d.ts.map +1 -1
  7. package/dist/components/ChatInterface.js +40 -5
  8. package/dist/components/CommandOutputDisplay.d.ts.map +1 -1
  9. package/dist/components/CommandOutputDisplay.js +6 -17
  10. package/dist/components/CommandSelector.d.ts.map +1 -1
  11. package/dist/components/CommandSelector.js +16 -2
  12. package/dist/components/CompressDisplay.d.ts.map +1 -1
  13. package/dist/components/CompressDisplay.js +6 -10
  14. package/dist/components/ConfirmationDetails.d.ts +9 -0
  15. package/dist/components/ConfirmationDetails.d.ts.map +1 -0
  16. package/dist/components/ConfirmationDetails.js +53 -0
  17. package/dist/components/{Confirmation.d.ts → ConfirmationSelector.d.ts} +3 -3
  18. package/dist/components/ConfirmationSelector.d.ts.map +1 -0
  19. package/dist/components/{Confirmation.js → ConfirmationSelector.js} +34 -96
  20. package/dist/components/DiffDisplay.d.ts.map +1 -1
  21. package/dist/components/DiffDisplay.js +48 -1
  22. package/dist/components/FileSelector.d.ts.map +1 -1
  23. package/dist/components/FileSelector.js +2 -2
  24. package/dist/components/HelpView.d.ts +6 -0
  25. package/dist/components/HelpView.d.ts.map +1 -0
  26. package/dist/components/HelpView.js +24 -0
  27. package/dist/components/HistorySearch.d.ts.map +1 -1
  28. package/dist/components/HistorySearch.js +12 -4
  29. package/dist/components/InputBox.d.ts +1 -3
  30. package/dist/components/InputBox.d.ts.map +1 -1
  31. package/dist/components/InputBox.js +14 -17
  32. package/dist/components/LoadingIndicator.d.ts +11 -0
  33. package/dist/components/LoadingIndicator.d.ts.map +1 -0
  34. package/dist/components/LoadingIndicator.js +6 -0
  35. package/dist/components/Markdown.d.ts.map +1 -1
  36. package/dist/components/Markdown.js +114 -121
  37. package/dist/components/MessageItem.d.ts +1 -1
  38. package/dist/components/MessageItem.d.ts.map +1 -1
  39. package/dist/components/MessageItem.js +3 -5
  40. package/dist/components/MessageList.d.ts +2 -3
  41. package/dist/components/MessageList.d.ts.map +1 -1
  42. package/dist/components/MessageList.js +29 -12
  43. package/dist/components/PlanDisplay.d.ts.map +1 -1
  44. package/dist/components/PlanDisplay.js +4 -12
  45. package/dist/components/RewindCommand.d.ts +4 -0
  46. package/dist/components/RewindCommand.d.ts.map +1 -1
  47. package/dist/components/RewindCommand.js +20 -3
  48. package/dist/components/TaskList.d.ts +3 -0
  49. package/dist/components/TaskList.d.ts.map +1 -0
  50. package/dist/components/TaskList.js +40 -0
  51. package/dist/components/ToolDisplay.d.ts +9 -0
  52. package/dist/components/ToolDisplay.d.ts.map +1 -0
  53. package/dist/components/ToolDisplay.js +44 -0
  54. package/dist/contexts/useChat.d.ts +11 -3
  55. package/dist/contexts/useChat.d.ts.map +1 -1
  56. package/dist/contexts/useChat.js +51 -32
  57. package/dist/hooks/useInputManager.d.ts +4 -15
  58. package/dist/hooks/useInputManager.d.ts.map +1 -1
  59. package/dist/hooks/useInputManager.js +20 -65
  60. package/dist/hooks/useTasks.d.ts +2 -0
  61. package/dist/hooks/useTasks.d.ts.map +1 -0
  62. package/dist/hooks/useTasks.js +5 -0
  63. package/dist/managers/InputManager.d.ts +8 -30
  64. package/dist/managers/InputManager.d.ts.map +1 -1
  65. package/dist/managers/InputManager.js +38 -144
  66. package/dist/print-cli.d.ts.map +1 -1
  67. package/dist/print-cli.js +11 -30
  68. package/package.json +5 -6
  69. package/src/components/App.tsx +51 -3
  70. package/src/components/{TaskManager.tsx → BackgroundTaskManager.tsx} +4 -2
  71. package/src/components/ChatInterface.tsx +80 -23
  72. package/src/components/CommandOutputDisplay.tsx +16 -38
  73. package/src/components/CommandSelector.tsx +41 -17
  74. package/src/components/CompressDisplay.tsx +5 -22
  75. package/src/components/ConfirmationDetails.tsx +108 -0
  76. package/src/components/{Confirmation.tsx → ConfirmationSelector.tsx} +74 -193
  77. package/src/components/DiffDisplay.tsx +71 -1
  78. package/src/components/FileSelector.tsx +0 -2
  79. package/src/components/HelpView.tsx +59 -0
  80. package/src/components/HistorySearch.tsx +45 -21
  81. package/src/components/InputBox.tsx +51 -63
  82. package/src/components/LoadingIndicator.tsx +56 -0
  83. package/src/components/Markdown.tsx +126 -323
  84. package/src/components/MessageItem.tsx +13 -24
  85. package/src/components/MessageList.tsx +48 -82
  86. package/src/components/PlanDisplay.tsx +4 -27
  87. package/src/components/RewindCommand.tsx +39 -2
  88. package/src/components/TaskList.tsx +58 -0
  89. package/src/components/{ToolResultDisplay.tsx → ToolDisplay.tsx} +8 -18
  90. package/src/contexts/useChat.tsx +73 -41
  91. package/src/hooks/useInputManager.ts +21 -83
  92. package/src/hooks/useTasks.ts +6 -0
  93. package/src/managers/InputManager.ts +43 -179
  94. package/src/print-cli.ts +17 -35
  95. package/dist/components/Confirmation.d.ts.map +0 -1
  96. package/dist/components/MemoryDisplay.d.ts +0 -8
  97. package/dist/components/MemoryDisplay.d.ts.map +0 -1
  98. package/dist/components/MemoryDisplay.js +0 -25
  99. package/dist/components/MemoryTypeSelector.d.ts +0 -8
  100. package/dist/components/MemoryTypeSelector.d.ts.map +0 -1
  101. package/dist/components/MemoryTypeSelector.js +0 -38
  102. package/dist/components/SubagentBlock.d.ts +0 -8
  103. package/dist/components/SubagentBlock.d.ts.map +0 -1
  104. package/dist/components/SubagentBlock.js +0 -70
  105. package/dist/components/TaskManager.d.ts +0 -6
  106. package/dist/components/TaskManager.d.ts.map +0 -1
  107. package/dist/components/ToolResultDisplay.d.ts +0 -9
  108. package/dist/components/ToolResultDisplay.d.ts.map +0 -1
  109. package/dist/components/ToolResultDisplay.js +0 -54
  110. package/src/components/MemoryDisplay.tsx +0 -62
  111. package/src/components/MemoryTypeSelector.tsx +0 -98
  112. package/src/components/SubagentBlock.tsx +0 -143
@@ -1,33 +1,7 @@
1
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
- import { BASH_TOOL_NAME, EDIT_TOOL_NAME, MULTI_EDIT_TOOL_NAME, DELETE_FILE_TOOL_NAME, WRITE_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, ASK_USER_QUESTION_TOOL_NAME, } from "wave-agent-sdk";
5
- import { DiffDisplay } from "./DiffDisplay.js";
6
- import { PlanDisplay } from "./PlanDisplay.js";
7
- // Helper function to generate descriptive action text
8
- const getActionDescription = (toolName, toolInput) => {
9
- if (!toolInput) {
10
- return "Execute operation";
11
- }
12
- switch (toolName) {
13
- case BASH_TOOL_NAME:
14
- return `Execute command: ${toolInput.command || "unknown command"}`;
15
- case EDIT_TOOL_NAME:
16
- return `Edit file: ${toolInput.file_path || "unknown file"}`;
17
- case MULTI_EDIT_TOOL_NAME:
18
- return `Edit multiple sections in: ${toolInput.file_path || "unknown file"}`;
19
- case DELETE_FILE_TOOL_NAME:
20
- return `Delete file: ${toolInput.target_file || "unknown file"}`;
21
- case WRITE_TOOL_NAME:
22
- return `Write to file: ${toolInput.file_path || "unknown file"}`;
23
- case EXIT_PLAN_MODE_TOOL_NAME:
24
- return "Review and approve the plan";
25
- case ASK_USER_QUESTION_TOOL_NAME:
26
- return "Answer questions to clarify intent";
27
- default:
28
- return "Execute operation";
29
- }
30
- };
4
+ import { BASH_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, ASK_USER_QUESTION_TOOL_NAME, } from "wave-agent-sdk";
31
5
  const getHeaderColor = (header) => {
32
6
  const colors = ["red", "green", "blue", "magenta", "cyan"];
33
7
  let hash = 0;
@@ -36,14 +10,13 @@ const getHeaderColor = (header) => {
36
10
  }
37
11
  return colors[Math.abs(hash) % colors.length];
38
12
  };
39
- export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersistentOption, isExpanded = false, onDecision, onCancel, onAbort, }) => {
13
+ export const ConfirmationSelector = ({ toolName, toolInput, suggestedPrefix, hidePersistentOption, isExpanded = false, onDecision, onCancel, onAbort, }) => {
40
14
  const [state, setState] = useState({
41
15
  selectedOption: "allow",
42
16
  alternativeText: "",
43
17
  alternativeCursorPosition: 0,
44
18
  hasUserInput: false,
45
19
  });
46
- // Specialized state for AskUserQuestion
47
20
  const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
48
21
  const [selectedOptionIndex, setSelectedOptionIndex] = useState(0);
49
22
  const [selectedOptionIndices, setSelectedOptionIndices] = useState(new Set());
@@ -65,7 +38,6 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
65
38
  return "Yes, and auto-accept edits";
66
39
  };
67
40
  useInput((input, key) => {
68
- // Handle ESC to cancel and abort
69
41
  if (key.escape) {
70
42
  onCancel();
71
43
  onAbort();
@@ -75,7 +47,7 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
75
47
  if (!currentQuestion)
76
48
  return;
77
49
  const options = [...currentQuestion.options, { label: "Other" }];
78
- const isMultiSelect = !!currentQuestion.multiSelect;
50
+ const isMultiSelect = currentQuestion.multiSelect;
79
51
  const isOtherFocused = selectedOptionIndex === options.length - 1;
80
52
  if (key.return) {
81
53
  let answer = "";
@@ -112,7 +84,6 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
112
84
  setOtherCursorPosition(0);
113
85
  }
114
86
  else {
115
- // All questions answered
116
87
  onDecision({
117
88
  behavior: "allow",
118
89
  message: JSON.stringify(newAnswers),
@@ -125,31 +96,25 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
125
96
  (!isOtherFocused || !selectedOptionIndices.has(selectedOptionIndex))) {
126
97
  setSelectedOptionIndices((prev) => {
127
98
  const next = new Set(prev);
128
- if (next.has(selectedOptionIndex)) {
99
+ if (next.has(selectedOptionIndex))
129
100
  next.delete(selectedOptionIndex);
130
- }
131
- else {
101
+ else
132
102
  next.add(selectedOptionIndex);
133
- }
134
103
  return next;
135
104
  });
136
105
  return;
137
106
  }
138
- if (!isOtherFocused) {
107
+ if (!isOtherFocused)
139
108
  return;
140
- }
141
- // If isOtherFocused is true, fall through to handle space as text input
142
109
  }
143
110
  if (key.upArrow) {
144
- if (selectedOptionIndex > 0) {
111
+ if (selectedOptionIndex > 0)
145
112
  setSelectedOptionIndex(selectedOptionIndex - 1);
146
- }
147
113
  return;
148
114
  }
149
115
  if (key.downArrow) {
150
- if (selectedOptionIndex < options.length - 1) {
116
+ if (selectedOptionIndex < options.length - 1)
151
117
  setSelectedOptionIndex(selectedOptionIndex + 1);
152
- }
153
118
  return;
154
119
  }
155
120
  if (isOtherFocused) {
@@ -163,30 +128,22 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
163
128
  }
164
129
  if (key.backspace || key.delete) {
165
130
  if (otherCursorPosition > 0) {
166
- setOtherText((prev) => {
167
- const next = prev.slice(0, otherCursorPosition - 1) +
168
- prev.slice(otherCursorPosition);
169
- return next;
170
- });
131
+ setOtherText((prev) => prev.slice(0, otherCursorPosition - 1) +
132
+ prev.slice(otherCursorPosition));
171
133
  setOtherCursorPosition((prev) => prev - 1);
172
134
  }
173
135
  return;
174
136
  }
175
137
  if (input && !key.ctrl && !key.meta) {
176
- setOtherText((prev) => {
177
- const next = prev.slice(0, otherCursorPosition) +
178
- input +
179
- prev.slice(otherCursorPosition);
180
- return next;
181
- });
138
+ setOtherText((prev) => prev.slice(0, otherCursorPosition) +
139
+ input +
140
+ prev.slice(otherCursorPosition));
182
141
  setOtherCursorPosition((prev) => prev + input.length);
183
142
  return;
184
143
  }
185
- return;
186
144
  }
187
145
  return;
188
146
  }
189
- // Handle Enter to confirm selection
190
147
  if (key.return) {
191
148
  if (state.selectedOption === "allow") {
192
149
  if (toolName === EXIT_PLAN_MODE_TOOL_NAME) {
@@ -201,26 +158,14 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
201
158
  const rule = suggestedPrefix
202
159
  ? `Bash(${suggestedPrefix}*)`
203
160
  : `Bash(${toolInput?.command})`;
204
- onDecision({
205
- behavior: "allow",
206
- newPermissionRule: rule,
207
- });
161
+ onDecision({ behavior: "allow", newPermissionRule: rule });
208
162
  }
209
163
  else {
210
- onDecision({
211
- behavior: "allow",
212
- newPermissionMode: "acceptEdits",
213
- });
164
+ onDecision({ behavior: "allow", newPermissionMode: "acceptEdits" });
214
165
  }
215
166
  }
216
- else {
217
- // For alternative option, require text input
218
- if (state.alternativeText.trim()) {
219
- onDecision({
220
- behavior: "deny",
221
- message: state.alternativeText.trim(),
222
- });
223
- }
167
+ else if (state.alternativeText.trim()) {
168
+ onDecision({ behavior: "deny", message: state.alternativeText.trim() });
224
169
  }
225
170
  return;
226
171
  }
@@ -240,15 +185,13 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
240
185
  return;
241
186
  }
242
187
  }
243
- // Handle arrow keys for navigation
244
188
  if (key.upArrow) {
245
189
  setState((prev) => {
246
- if (prev.selectedOption === "alternative") {
190
+ if (prev.selectedOption === "alternative")
247
191
  return {
248
192
  ...prev,
249
193
  selectedOption: hidePersistentOption ? "allow" : "auto",
250
194
  };
251
- }
252
195
  if (prev.selectedOption === "auto")
253
196
  return { ...prev, selectedOption: "allow" };
254
197
  return prev;
@@ -257,21 +200,18 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
257
200
  }
258
201
  if (key.downArrow) {
259
202
  setState((prev) => {
260
- if (prev.selectedOption === "allow") {
203
+ if (prev.selectedOption === "allow")
261
204
  return {
262
205
  ...prev,
263
206
  selectedOption: hidePersistentOption ? "alternative" : "auto",
264
207
  };
265
- }
266
208
  if (prev.selectedOption === "auto")
267
209
  return { ...prev, selectedOption: "alternative" };
268
210
  return prev;
269
211
  });
270
212
  return;
271
213
  }
272
- // Handle text input for alternative option
273
214
  if (input && !key.ctrl && !key.meta && !("alt" in key && key.alt)) {
274
- // Focus on alternative option when user starts typing
275
215
  setState((prev) => {
276
216
  const nextText = prev.alternativeText.slice(0, prev.alternativeCursorPosition) +
277
217
  input +
@@ -286,7 +226,6 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
286
226
  });
287
227
  return;
288
228
  }
289
- // Handle backspace and delete
290
229
  if (key.backspace || key.delete) {
291
230
  setState((prev) => {
292
231
  if (prev.alternativeCursorPosition > 0) {
@@ -307,22 +246,21 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
307
246
  });
308
247
  const placeholderText = "Type here to tell Wave what to do differently";
309
248
  const showPlaceholder = state.selectedOption === "alternative" && !state.hasUserInput;
310
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Tool: ", toolName] }), _jsx(Text, { color: "yellow", children: getActionDescription(toolName, toolInput) }), _jsx(DiffDisplay, { toolName: toolName, parameters: JSON.stringify(toolInput) }), toolName === ASK_USER_QUESTION_TOOL_NAME &&
249
+ return (_jsxs(Box, { flexDirection: "column", children: [toolName === ASK_USER_QUESTION_TOOL_NAME &&
311
250
  currentQuestion &&
312
- !isExpanded && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Box, { backgroundColor: getHeaderColor(currentQuestion.header), paddingX: 1, marginRight: 1, children: _jsx(Text, { color: "black", bold: true, children: currentQuestion.header.slice(0, 12).toUpperCase() }) }), _jsx(Text, { bold: true, children: currentQuestion.question })] }), _jsx(Box, { flexDirection: "column", children: (() => {
313
- const isMultiSelect = !!currentQuestion.multiSelect;
314
- return [...currentQuestion.options, { label: "Other" }].map((option, index) => {
315
- const isSelected = selectedOptionIndex === index;
316
- const isChecked = isMultiSelect
317
- ? selectedOptionIndices.has(index)
318
- : isSelected;
319
- const isOther = index === currentQuestion.options.length;
320
- const isRecommended = !isOther && option.isRecommended;
321
- 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 ? (_jsxs(_Fragment, { children: [otherText.slice(0, otherCursorPosition), _jsx(Text, { backgroundColor: "white", color: "black", children: otherText[otherCursorPosition] || " " }), otherText.slice(otherCursorPosition + 1)] })) : (_jsx(Text, { color: "gray", dimColor: true, children: "[Type your answer...]" }))] }))] }) }, index));
322
- });
323
- })() }), _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 &&
324
- toolName === EXIT_PLAN_MODE_TOOL_NAME &&
325
- !!toolInput?.plan_content && (_jsx(PlanDisplay, { plan: toolInput.plan_content, isExpanded: isExpanded })), toolName !== ASK_USER_QUESTION_TOOL_NAME && !isExpanded && (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Do you want to proceed?" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "allow" ? "black" : "white", backgroundColor: state.selectedOption === "allow" ? "yellow" : undefined, bold: state.selectedOption === "allow", children: [state.selectedOption === "allow" ? "> " : " ", toolName === EXIT_PLAN_MODE_TOOL_NAME
251
+ !isExpanded && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: getHeaderColor(currentQuestion.header), bold: true, children: currentQuestion.header.slice(0, 12).toUpperCase() }), _jsx(Box, { marginLeft: 1, children: _jsx(Text, { bold: true, children: currentQuestion.question }) })] }), _jsx(Box, { flexDirection: "column", children: [...currentQuestion.options, { label: "Other" }].map((option, index) => {
252
+ const isSelected = selectedOptionIndex === index;
253
+ const isChecked = currentQuestion.multiSelect
254
+ ? selectedOptionIndices.has(index)
255
+ : isSelected;
256
+ const isOther = index === currentQuestion.options.length;
257
+ return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "yellow" : undefined, children: [isSelected ? "> " : " ", currentQuestion.multiSelect
258
+ ? isChecked
259
+ ? "[x] "
260
+ : "[ ] "
261
+ : "", option.label, option.description ? ` - ${option.description}` : "", isOther && isSelected && (_jsxs(Text, { children: [":", " ", otherText ? (_jsxs(_Fragment, { children: [otherText.slice(0, otherCursorPosition), _jsx(Text, { backgroundColor: "white", color: "black", children: otherText[otherCursorPosition] || " " }), otherText.slice(otherCursorPosition + 1)] })) : (_jsx(Text, { color: "gray", dimColor: true, children: "[Type your answer...]" }))] }))] }) }, index));
262
+ }) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Question ", currentQuestionIndex + 1, " of ", questions.length, " \u2022", currentQuestion.multiSelect ? " Space to toggle •" : "", " Use \u2191\u2193 to navigate \u2022 Enter to confirm"] }) })] })), toolName !== ASK_USER_QUESTION_TOOL_NAME && !isExpanded && (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Do you want to proceed?" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "allow" ? "black" : "white", backgroundColor: state.selectedOption === "allow" ? "yellow" : undefined, bold: state.selectedOption === "allow", children: [state.selectedOption === "allow" ? "> " : " ", toolName === EXIT_PLAN_MODE_TOOL_NAME
326
263
  ? "Yes, proceed with default mode"
327
264
  : "Yes"] }) }, "allow-option"), !hidePersistentOption && (_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "auto" ? "black" : "white", backgroundColor: state.selectedOption === "auto" ? "yellow" : undefined, bold: state.selectedOption === "auto", children: [state.selectedOption === "auto" ? "> " : " ", getAutoOptionText()] }) }, "auto-option")), _jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "alternative" ? "black" : "white", backgroundColor: state.selectedOption === "alternative" ? "yellow" : undefined, bold: state.selectedOption === "alternative", children: [state.selectedOption === "alternative" ? "> " : " ", showPlaceholder ? (_jsx(Text, { color: "gray", dimColor: true, children: placeholderText })) : (_jsx(Text, { children: state.alternativeText ? (_jsxs(_Fragment, { children: [state.alternativeText.slice(0, state.alternativeCursorPosition), _jsx(Text, { backgroundColor: "white", color: "black", children: state.alternativeText[state.alternativeCursorPosition] || " " }), state.alternativeText.slice(state.alternativeCursorPosition + 1)] })) : ("Type here to tell Wave what to do differently") }))] }) }, "alternative-option")] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate \u2022 ESC to cancel" }) })] }))] }));
328
265
  };
266
+ ConfirmationSelector.displayName = "ConfirmationSelector";
@@ -1 +1 @@
1
- {"version":3,"file":"DiffDisplay.d.ts","sourceRoot":"","sources":["../../src/components/DiffDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAUvC,UAAU,gBAAgB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA4OlD,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;CACrB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAkTlD,CAAC"}
@@ -62,6 +62,10 @@ export const DiffDisplay = ({ toolName, parameters, }) => {
62
62
  const allElements = [];
63
63
  changes.forEach((change, changeIndex) => {
64
64
  try {
65
+ // Add ellipsis between non-contiguous edits in MultiEdit
66
+ if (toolName === MULTI_EDIT_TOOL_NAME && changeIndex > 0) {
67
+ allElements.push(_jsx(Box, { children: _jsx(Text, { color: "gray", children: "..." }) }, `multi-edit-separator-${changeIndex}`));
68
+ }
65
69
  // Get line-level diff to understand the structure
66
70
  const lineDiffs = diffLines(change.oldContent || "", change.newContent || "");
67
71
  // Process line diffs
@@ -88,9 +92,52 @@ export const DiffDisplay = ({ toolName, parameters, }) => {
88
92
  const lines = part.value
89
93
  .split("\n")
90
94
  .filter((line) => line !== "");
91
- lines.forEach((line, lineIndex) => {
95
+ const isFirstBlock = partIndex === 0;
96
+ const isLastBlock = partIndex === lineDiffs.length - 1;
97
+ let linesToDisplay = lines;
98
+ let showEllipsisTop = false;
99
+ let showEllipsisBottom = false;
100
+ if (isFirstBlock && !isLastBlock) {
101
+ // First block: keep last 3
102
+ if (lines.length > 3) {
103
+ linesToDisplay = lines.slice(-3);
104
+ showEllipsisTop = true;
105
+ }
106
+ }
107
+ else if (isLastBlock && !isFirstBlock) {
108
+ // Last block: keep first 3
109
+ if (lines.length > 3) {
110
+ linesToDisplay = lines.slice(0, 3);
111
+ showEllipsisBottom = true;
112
+ }
113
+ }
114
+ else if (!isFirstBlock && !isLastBlock) {
115
+ // Middle block: keep first 3 and last 3
116
+ if (lines.length > 6) {
117
+ linesToDisplay = [...lines.slice(0, 3), ...lines.slice(-3)];
118
+ showEllipsisTop = false; // We'll put ellipsis in the middle
119
+ }
120
+ }
121
+ else if (isFirstBlock && isLastBlock) {
122
+ // Only one block (no changes?) - keep all or apply a general limit
123
+ // For now, let's keep all if it's the only block
124
+ }
125
+ if (showEllipsisTop) {
126
+ diffElements.push(_jsx(Box, { children: _jsx(Text, { color: "gray", children: " ..." }) }, `ellipsis-top-${changeIndex}-${partIndex}`));
127
+ }
128
+ linesToDisplay.forEach((line, lineIndex) => {
129
+ // If it's a middle block and we are at the split point
130
+ if (!isFirstBlock &&
131
+ !isLastBlock &&
132
+ lines.length > 6 &&
133
+ lineIndex === 3) {
134
+ diffElements.push(_jsx(Box, { children: _jsx(Text, { color: "gray", children: " ..." }) }, `ellipsis-mid-${changeIndex}-${partIndex}`));
135
+ }
92
136
  diffElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "white", children: " " }), _jsx(Text, { color: "white", children: line })] }, `context-${changeIndex}-${partIndex}-${lineIndex}`));
93
137
  });
138
+ if (showEllipsisBottom) {
139
+ diffElements.push(_jsx(Box, { children: _jsx(Text, { color: "gray", children: " ..." }) }, `ellipsis-bottom-${changeIndex}-${partIndex}`));
140
+ }
94
141
  }
95
142
  });
96
143
  // If it's a single line change (one removed, one added), use word-level diff
@@ -1 +1 @@
1
- {"version":3,"file":"FileSelector.d.ts","sourceRoot":"","sources":["../../src/components/FileSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA6HpD,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,CA2HpD,CAAC"}
@@ -24,7 +24,7 @@ export const FileSelector = ({ files, searchQuery, onSelect, onCancel, }) => {
24
24
  }
25
25
  });
26
26
  if (files.length === 0) {
27
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 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, children: [_jsxs(Text, { color: "yellow", children: ["\uD83D\uDCC1 No files found for \"", searchQuery, "\""] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
28
28
  }
29
29
  const maxDisplay = 10;
30
30
  // Calculate display window start and end positions
@@ -39,7 +39,7 @@ export const FileSelector = ({ files, searchQuery, onSelect, onCancel, }) => {
39
39
  };
40
40
  };
41
41
  const { startIndex, endIndex, displayFiles } = getDisplayWindow();
42
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, 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) => {
42
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "cyan", bold: true, children: ["\uD83D\uDCC1 Select File/Directory", " ", searchQuery && `(filtering: "${searchQuery}")`] }), startIndex > 0 && (_jsxs(Text, { dimColor: true, children: ["... ", startIndex, " more files above"] })), displayFiles.map((fileItem, displayIndex) => {
43
43
  const actualIndex = startIndex + displayIndex;
44
44
  const isSelected = actualIndex === selectedIndex;
45
45
  const icon = fileItem.type === "directory" ? "📁" : "📄";
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ export interface HelpViewProps {
3
+ onCancel: () => void;
4
+ }
5
+ export declare const HelpView: React.FC<HelpViewProps>;
6
+ //# sourceMappingURL=HelpView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HelpView.d.ts","sourceRoot":"","sources":["../../src/components/HelpView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAmD5C,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from "ink";
3
+ export const HelpView = ({ onCancel }) => {
4
+ useInput((_, key) => {
5
+ if (key.escape || key.return) {
6
+ onCancel();
7
+ }
8
+ });
9
+ const helpItems = [
10
+ { key: "@", description: "Reference files" },
11
+ { key: "/", description: "Commands" },
12
+ { key: "Ctrl+R", description: "Search history" },
13
+ { key: "Ctrl+O", description: "Expand/collapse messages" },
14
+ { key: "Ctrl+T", description: "Toggle task list" },
15
+ { key: "Ctrl+B", description: "Background current task" },
16
+ { key: "Ctrl+V", description: "Paste image" },
17
+ { key: "Shift+Tab", description: "Cycle permission mode" },
18
+ {
19
+ key: "Esc",
20
+ description: "Interrupt AI or command / Cancel selector / Close help",
21
+ },
22
+ ];
23
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderLeft: false, borderRight: false, paddingX: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "cyan", bold: true, underline: true, children: "Help & Key Bindings" }) }), helpItems.map((item, index) => (_jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: item.key }) }), _jsx(Text, { color: "white", children: item.description })] }, index))), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Esc or Enter to close" }) })] }));
24
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"HistorySearch.d.ts","sourceRoot":"","sources":["../../src/components/HistorySearch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAyItD,CAAC"}
1
+ {"version":3,"file":"HistorySearch.d.ts","sourceRoot":"","sources":["../../src/components/HistorySearch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAiKtD,CAAC"}
@@ -3,6 +3,7 @@ import React, { useState, useEffect } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
4
  import { PromptHistoryManager } from "wave-agent-sdk";
5
5
  export const HistorySearch = ({ searchQuery, onSelect, onCancel, }) => {
6
+ const MAX_VISIBLE_ITEMS = 5;
6
7
  const [selectedIndex, setSelectedIndex] = useState(0);
7
8
  const [entries, setEntries] = useState([]);
8
9
  const entriesRef = React.useRef([]);
@@ -16,8 +17,8 @@ export const HistorySearch = ({ searchQuery, onSelect, onCancel, }) => {
16
17
  useEffect(() => {
17
18
  const fetchHistory = async () => {
18
19
  const results = await PromptHistoryManager.searchHistory(searchQuery);
19
- const limitedResults = results.slice(0, 10);
20
- setEntries(limitedResults); // Limit to 10 results
20
+ const limitedResults = results.slice(0, 20);
21
+ setEntries(limitedResults); // Limit to 20 results
21
22
  setSelectedIndex(0);
22
23
  };
23
24
  fetchHistory();
@@ -44,7 +45,7 @@ export const HistorySearch = ({ searchQuery, onSelect, onCancel, }) => {
44
45
  }
45
46
  });
46
47
  if (entries.length === 0) {
47
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsxs(Text, { color: "yellow", children: ["No history found ", searchQuery && `for "${searchQuery}"`] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
48
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "yellow", children: ["No history found ", searchQuery && `for "${searchQuery}"`] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
48
49
  }
49
50
  const formatTimestamp = (timestamp) => {
50
51
  const date = new Date(timestamp);
@@ -63,5 +64,12 @@ export const HistorySearch = ({ searchQuery, onSelect, onCancel, }) => {
63
64
  return diffMinutes > 0 ? `${diffMinutes}m ago` : "just now";
64
65
  }
65
66
  };
66
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "blue", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "blue", bold: true, children: ["Prompt History ", searchQuery && `(filtering: "${searchQuery}")`] }) }), entries.map((entry, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: index === selectedIndex ? "black" : "white", backgroundColor: index === selectedIndex ? "blue" : undefined, wrap: "truncate-end", children: entry.prompt.replace(/\n/g, " ") }), index === selectedIndex && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { color: "gray", dimColor: true, children: formatTimestamp(entry.timestamp) }) }))] }, index))), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate, Enter to select, Escape to cancel" }) })] }));
67
+ // Calculate visible window
68
+ const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, entries.length - MAX_VISIBLE_ITEMS)));
69
+ const visibleEntries = entries.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
70
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "blue", borderBottom: false, borderLeft: false, borderRight: false, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "blue", bold: true, children: ["Prompt History ", searchQuery && `(filtering: "${searchQuery}")`] }) }), _jsx(Box, { flexDirection: "column", children: visibleEntries.map((entry, index) => {
71
+ const actualIndex = startIndex + index;
72
+ const isSelected = actualIndex === selectedIndex;
73
+ return (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", children: [_jsx(Box, { flexShrink: 1, children: _jsx(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "blue" : undefined, wrap: "truncate-end", children: entry.prompt.replace(/\n/g, " ") }) }), isSelected && (_jsx(Box, { marginLeft: 2, flexShrink: 0, children: _jsx(Text, { color: "gray", dimColor: true, children: formatTimestamp(entry.timestamp) }) }))] }, actualIndex));
74
+ }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate, Enter to select, Escape to cancel" }) })] }));
67
75
  };
@@ -1,18 +1,16 @@
1
1
  import React from "react";
2
2
  import type { McpServerStatus, SlashCommand } from "wave-agent-sdk";
3
- export declare const INPUT_PLACEHOLDER_TEXT = "Type your message (use @ to reference files, / for commands, # to add memory, Ctrl+R to search history)...";
3
+ export declare const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
4
4
  export declare const INPUT_PLACEHOLDER_TEXT_PREFIX: string;
5
5
  export interface InputBoxProps {
6
6
  isLoading?: boolean;
7
7
  isCommandRunning?: boolean;
8
8
  workdir?: string;
9
- userInputHistory?: string[];
10
9
  sendMessage?: (message: string, images?: Array<{
11
10
  path: string;
12
11
  mimeType: string;
13
12
  }>) => void;
14
13
  abortMessage?: () => void;
15
- saveMemory?: (message: string, type: "project" | "user") => Promise<void>;
16
14
  mcpServers?: McpServerStatus[];
17
15
  connectMcpServer?: (serverName: string) => Promise<boolean>;
18
16
  disconnectMcpServer?: (serverName: string) => Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAazC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,+GAC2E,CAAC;AAE/G,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,CAiO5C,CAAC"}
1
+ {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAazC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,mDACe,CAAC;AAEnD,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,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;IAE1B,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,CAuN5C,CAAC"}
@@ -5,16 +5,16 @@ import { useInput } from "ink";
5
5
  import { FileSelector } from "./FileSelector.js";
6
6
  import { CommandSelector } from "./CommandSelector.js";
7
7
  import { HistorySearch } from "./HistorySearch.js";
8
- import { MemoryTypeSelector } from "./MemoryTypeSelector.js";
9
- import { TaskManager } from "./TaskManager.js";
8
+ import { BackgroundTaskManager } from "./BackgroundTaskManager.js";
10
9
  import { McpManager } from "./McpManager.js";
11
10
  import { RewindCommand } from "./RewindCommand.js";
11
+ import { HelpView } from "./HelpView.js";
12
12
  import { useInputManager } from "../hooks/useInputManager.js";
13
13
  import { useChat } from "../contexts/useChat.js";
14
- export const INPUT_PLACEHOLDER_TEXT = "Type your message (use @ to reference files, / for commands, # to add memory, Ctrl+R to search history)...";
14
+ export const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
15
15
  export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
16
- export const InputBox = ({ isLoading = false, isCommandRunning = false, userInputHistory = [], sendMessage = () => { }, abortMessage = () => { }, saveMemory = async () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
17
- const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, } = useChat();
16
+ export const InputBox = ({ isLoading = false, isCommandRunning = false, sendMessage = () => { }, abortMessage = () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
17
+ const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, } = useChat();
18
18
  // Input manager with all input state and functionality (including images)
19
19
  const { inputText, cursorPosition,
20
20
  // Image management
@@ -23,23 +23,18 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, userInpu
23
23
  showFileSelector, filteredFiles, fileSearchQuery: searchQuery, handleFileSelect, handleCancelFileSelect,
24
24
  // Command selector
25
25
  showCommandSelector, commandSearchQuery, handleCommandSelect, handleCommandInsert, handleCancelCommandSelect, handleHistorySearchSelect, handleCancelHistorySearch,
26
- // Memory type selector
27
- showMemoryTypeSelector, memoryMessage, handleMemoryTypeSelect, handleCancelMemoryTypeSelect,
28
26
  // History search
29
27
  showHistorySearch, historySearchQuery,
30
28
  // Task/MCP Manager
31
- showTaskManager, showMcpManager, showRewindManager, setShowTaskManager, setShowMcpManager, setShowRewindManager,
29
+ showBackgroundTaskManager, showMcpManager, showRewindManager, showHelp, setShowBackgroundTaskManager, setShowMcpManager, setShowRewindManager, setShowHelp,
32
30
  // Permission mode
33
31
  permissionMode, setPermissionMode,
34
- // Input history
35
- setUserInputHistory,
36
32
  // Main handler
37
33
  handleInput,
38
34
  // Manager ready state
39
35
  isManagerReady, } = useInputManager({
40
36
  onSendMessage: sendMessage,
41
37
  onHasSlashCommand: hasSlashCommand,
42
- onSaveMemory: saveMemory,
43
38
  onAbortMessage: abortMessage,
44
39
  onBackgroundCurrentTask: backgroundCurrentTask,
45
40
  onPermissionModeChange: setChatPermissionMode,
@@ -48,10 +43,6 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, userInpu
48
43
  useEffect(() => {
49
44
  setPermissionMode(chatPermissionMode);
50
45
  }, [chatPermissionMode, setPermissionMode]);
51
- // Set user input history when it changes
52
- useEffect(() => {
53
- setUserInputHistory(userInputHistory);
54
- }, [userInputHistory, setUserInputHistory]);
55
46
  // Use the InputManager's unified input handler
56
47
  useInput(async (input, key) => {
57
48
  await handleInput(input, key, attachedImages, isLoading, isCommandRunning, clearImages);
@@ -82,7 +73,13 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, userInpu
82
73
  await handleRewindSelect(index);
83
74
  };
84
75
  if (showRewindManager) {
85
- return (_jsx(RewindCommand, { messages: messages, onSelect: handleRewindSelectWithClose, onCancel: handleRewindCancel }));
76
+ return (_jsx(RewindCommand, { messages: messages, onSelect: handleRewindSelectWithClose, onCancel: handleRewindCancel, getFullMessageThread: getFullMessageThread }));
77
+ }
78
+ if (showHelp) {
79
+ return _jsx(HelpView, { onCancel: () => setShowHelp(false) });
86
80
  }
87
- 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 })), showHistorySearch && (_jsx(HistorySearch, { searchQuery: historySearchQuery, onSelect: handleHistorySearchSelect, onCancel: handleCancelHistorySearch })), showMemoryTypeSelector && (_jsx(MemoryTypeSelector, { message: memoryMessage, onSelect: handleMemoryTypeSelect, onCancel: handleCancelMemoryTypeSelect })), showTaskManager && (_jsx(TaskManager, { onCancel: () => setShowTaskManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showTaskManager || showMcpManager || showRewindManager || (_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)"] }) })] }))] }));
81
+ 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 })), showHistorySearch && (_jsx(HistorySearch, { searchQuery: historySearchQuery, onSelect: handleHistorySearchSelect, onCancel: handleCancelHistorySearch })), showBackgroundTaskManager && (_jsx(BackgroundTaskManager, { onCancel: () => setShowBackgroundTaskManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showBackgroundTaskManager ||
82
+ showMcpManager ||
83
+ showRewindManager ||
84
+ showHelp || (_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, justifyContent: "space-between", width: "100%", children: _jsxs(Text, { color: "gray", children: ["Mode:", " ", _jsx(Text, { color: permissionMode === "plan" ? "yellow" : "cyan", children: permissionMode }), " ", "(Shift+Tab to cycle)"] }) })] }))] }));
88
85
  };
@@ -0,0 +1,11 @@
1
+ export interface LoadingIndicatorProps {
2
+ isLoading?: boolean;
3
+ isCommandRunning?: boolean;
4
+ isCompressing?: boolean;
5
+ latestTotalTokens?: number;
6
+ }
7
+ export declare const LoadingIndicator: {
8
+ ({ isLoading, isCommandRunning, isCompressing, latestTotalTokens, }: LoadingIndicatorProps): import("react/jsx-runtime").JSX.Element;
9
+ displayName: string;
10
+ };
11
+ //# sourceMappingURL=LoadingIndicator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadingIndicator.d.ts","sourceRoot":"","sources":["../../src/components/LoadingIndicator.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,gBAAgB;yEAK1B,qBAAqB;;CAsCvB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ export const LoadingIndicator = ({ isLoading = false, isCommandRunning = false, isCompressing = false, latestTotalTokens = 0, }) => {
4
+ return (_jsxs(Box, { flexDirection: "column", children: [isLoading && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "\u273B AI is thinking... " }), latestTotalTokens > 0 && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: "gray", dimColor: true, children: ["|", " "] }), _jsx(Text, { color: "blue", bold: true, children: latestTotalTokens.toLocaleString() }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "tokens", " "] })] })), _jsxs(Text, { color: "gray", dimColor: true, children: ["|", " "] }), _jsx(Text, { color: "red", bold: true, children: "Esc" }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "to abort"] })] })), isCommandRunning && _jsx(Text, { color: "blue", children: "\uD83D\uDE80 Command is running..." }), isCompressing && (_jsx(Text, { color: "magenta", children: "\uD83D\uDDDC\uFE0F Compressing message history..." }))] }));
5
+ };
6
+ LoadingIndicator.displayName = "LoadingIndicator";
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAKvC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAmVD,eAAO,MAAM,QAAQ,2CAA6B,aAAa,6CAQ7D,CAAC"}
1
+ {"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAKvC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwID,eAAO,MAAM,QAAQ,2CAA6B,aAAa,6CAc7D,CAAC"}