wave-code 0.8.4 → 0.9.1

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 (54) hide show
  1. package/dist/components/ChatInterface.d.ts.map +1 -1
  2. package/dist/components/ChatInterface.js +26 -7
  3. package/dist/components/FileSelector.d.ts +1 -0
  4. package/dist/components/FileSelector.d.ts.map +1 -1
  5. package/dist/components/FileSelector.js +3 -3
  6. package/dist/components/HelpView.d.ts.map +1 -1
  7. package/dist/components/HelpView.js +1 -0
  8. package/dist/components/HistorySearch.d.ts +2 -1
  9. package/dist/components/HistorySearch.d.ts.map +1 -1
  10. package/dist/components/HistorySearch.js +1 -1
  11. package/dist/components/InputBox.d.ts.map +1 -1
  12. package/dist/components/InputBox.js +8 -6
  13. package/dist/components/MessageBlockItem.d.ts.map +1 -1
  14. package/dist/components/MessageBlockItem.js +1 -1
  15. package/dist/components/MessageList.d.ts +2 -1
  16. package/dist/components/MessageList.d.ts.map +1 -1
  17. package/dist/components/MessageList.js +14 -4
  18. package/dist/components/QueuedMessageList.d.ts +3 -0
  19. package/dist/components/QueuedMessageList.d.ts.map +1 -0
  20. package/dist/components/QueuedMessageList.js +17 -0
  21. package/dist/components/ReasoningDisplay.d.ts +1 -0
  22. package/dist/components/ReasoningDisplay.d.ts.map +1 -1
  23. package/dist/components/ReasoningDisplay.js +3 -3
  24. package/dist/components/ToolDisplay.js +1 -1
  25. package/dist/contexts/useChat.d.ts +7 -0
  26. package/dist/contexts/useChat.d.ts.map +1 -1
  27. package/dist/contexts/useChat.js +17 -1
  28. package/dist/hooks/useInputManager.d.ts +6 -5
  29. package/dist/hooks/useInputManager.d.ts.map +1 -1
  30. package/dist/hooks/useInputManager.js +18 -16
  31. package/dist/managers/inputHandlers.d.ts +7 -4
  32. package/dist/managers/inputHandlers.d.ts.map +1 -1
  33. package/dist/managers/inputHandlers.js +184 -46
  34. package/dist/managers/inputReducer.d.ts +18 -2
  35. package/dist/managers/inputReducer.d.ts.map +1 -1
  36. package/dist/managers/inputReducer.js +92 -3
  37. package/dist/utils/logger.d.ts.map +1 -1
  38. package/dist/utils/logger.js +13 -1
  39. package/package.json +2 -2
  40. package/src/components/ChatInterface.tsx +42 -15
  41. package/src/components/FileSelector.tsx +13 -3
  42. package/src/components/HelpView.tsx +1 -0
  43. package/src/components/HistorySearch.tsx +2 -2
  44. package/src/components/InputBox.tsx +21 -17
  45. package/src/components/MessageBlockItem.tsx +8 -3
  46. package/src/components/MessageList.tsx +16 -3
  47. package/src/components/QueuedMessageList.tsx +31 -0
  48. package/src/components/ReasoningDisplay.tsx +8 -2
  49. package/src/components/ToolDisplay.tsx +2 -2
  50. package/src/contexts/useChat.tsx +29 -1
  51. package/src/hooks/useInputManager.ts +22 -31
  52. package/src/managers/inputHandlers.ts +223 -60
  53. package/src/managers/inputReducer.ts +104 -6
  54. package/src/utils/logger.ts +15 -1
@@ -2,16 +2,19 @@ import { Key } from "ink";
2
2
  import { PermissionMode } from "wave-agent-sdk";
3
3
  import { InputState, InputAction, InputManagerCallbacks } from "./inputReducer.js";
4
4
  export declare const expandLongTextPlaceholders: (text: string, longTextMap: Record<string, string>) => string;
5
- export declare const handleSubmit: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, isLoading?: boolean, isCommandRunning?: boolean, attachedImagesOverride?: Array<{
5
+ export declare const handleSubmit: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, attachedImagesOverride?: Array<{
6
6
  id: number;
7
7
  path: string;
8
8
  mimeType: string;
9
9
  }>) => Promise<void>;
10
10
  export declare const handlePasteImage: (dispatch: React.Dispatch<InputAction>) => Promise<boolean>;
11
11
  export declare const cyclePermissionMode: (currentMode: PermissionMode, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>) => void;
12
+ export declare const getAtSelectorPosition: (text: string, cursorPosition: number) => number;
13
+ export declare const getSlashSelectorPosition: (text: string, cursorPosition: number) => number;
12
14
  export declare const updateSearchQueriesForActiveSelectors: (state: InputState, dispatch: React.Dispatch<InputAction>, inputText: string, cursorPosition: number) => void;
13
- export declare const handleSpecialCharInput: (state: InputState, dispatch: React.Dispatch<InputAction>, char: string, cursorPosition: number, inputText: string) => void;
15
+ export declare const processSelectorInput: (state: InputState, dispatch: React.Dispatch<InputAction>, char: string) => void;
14
16
  export declare const handlePasteInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string) => void;
17
+ export declare const getWordEnd: (text: string, startPos: number) => number;
15
18
  export declare const handleCommandSelect: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, command: string) => {
16
19
  newInput: string;
17
20
  newCursorPosition: number;
@@ -23,6 +26,6 @@ export declare const handleFileSelect: (state: InputState, dispatch: React.Dispa
23
26
  export declare const checkForAtDeletion: (state: InputState, dispatch: React.Dispatch<InputAction>, cursorPosition: number) => boolean;
24
27
  export declare const checkForSlashDeletion: (state: InputState, dispatch: React.Dispatch<InputAction>, cursorPosition: number) => boolean;
25
28
  export declare const handleSelectorInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string, key: Key) => boolean;
26
- export declare const handleNormalInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string, key: Key, isLoading?: boolean, isCommandRunning?: boolean, clearImages?: () => void) => Promise<boolean>;
27
- export declare const handleInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string, key: Key, isLoading?: boolean, isCommandRunning?: boolean, clearImages?: () => void) => Promise<boolean>;
29
+ export declare const handleNormalInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string, key: Key, clearImages?: () => void) => Promise<boolean>;
30
+ export declare const handleInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string, key: Key, clearImages?: () => void) => Promise<boolean>;
28
31
  //# sourceMappingURL=inputHandlers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"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"}
@@ -13,10 +13,7 @@ export const expandLongTextPlaceholders = (text, longTextMap) => {
13
13
  }
14
14
  return expandedText;
15
15
  };
16
- export const handleSubmit = async (state, dispatch, callbacks, isLoading = false, isCommandRunning = false, attachedImagesOverride) => {
17
- if (isLoading || isCommandRunning) {
18
- return;
19
- }
16
+ export const handleSubmit = async (state, dispatch, callbacks, attachedImagesOverride) => {
20
17
  if (state.inputText.trim()) {
21
18
  const imageRegex = /\[Image #(\d+)\]/g;
22
19
  const matches = [...state.inputText.matchAll(imageRegex)];
@@ -30,12 +27,12 @@ export const handleSubmit = async (state, dispatch, callbacks, isLoading = false
30
27
  .map((img) => ({ path: img.path, mimeType: img.mimeType }));
31
28
  let cleanContent = state.inputText.replace(imageRegex, "").trim();
32
29
  cleanContent = expandLongTextPlaceholders(cleanContent, state.longTextMap);
33
- PromptHistoryManager.addEntry(cleanContent).catch((err) => {
30
+ PromptHistoryManager.addEntry(cleanContent, callbacks.sessionId, state.longTextMap).catch((err) => {
34
31
  callbacks.logger?.error("Failed to save prompt history", err);
35
32
  });
36
33
  callbacks.onSendMessage?.(cleanContent, referencedImages.length > 0 ? referencedImages : undefined);
37
34
  dispatch({ type: "CLEAR_INPUT" });
38
- callbacks.onResetHistoryNavigation?.();
35
+ dispatch({ type: "RESET_HISTORY_NAVIGATION" });
39
36
  dispatch({ type: "CLEAR_LONG_TEXT_MAP" });
40
37
  }
41
38
  };
@@ -68,6 +65,55 @@ export const cyclePermissionMode = (currentMode, dispatch, callbacks) => {
68
65
  dispatch({ type: "SET_PERMISSION_MODE", payload: nextMode });
69
66
  callbacks.onPermissionModeChange?.(nextMode);
70
67
  };
68
+ const SELECTOR_TRIGGERS = [
69
+ {
70
+ char: "@",
71
+ type: "ACTIVATE_FILE_SELECTOR",
72
+ shouldActivate: (char, pos, text) => char === "@" && (pos === 1 || /\s/.test(text[pos - 2])),
73
+ },
74
+ {
75
+ char: "/",
76
+ type: "ACTIVATE_COMMAND_SELECTOR",
77
+ shouldActivate: (char, pos, text, state) => char === "/" &&
78
+ !state.showFileSelector &&
79
+ (pos === 1 || /\s/.test(text[pos - 2])),
80
+ },
81
+ ];
82
+ const getProjectedState = (state, char) => {
83
+ const beforeCursor = state.inputText.substring(0, state.cursorPosition);
84
+ const afterCursor = state.inputText.substring(state.cursorPosition);
85
+ const newInputText = beforeCursor + char + afterCursor;
86
+ const newCursorPosition = state.cursorPosition + char.length;
87
+ return { newInputText, newCursorPosition };
88
+ };
89
+ export const getAtSelectorPosition = (text, cursorPosition) => {
90
+ let i = cursorPosition - 1;
91
+ while (i >= 0 && !/\s/.test(text[i])) {
92
+ if (text[i] === "@") {
93
+ // Check if this @ is at the start or preceded by whitespace
94
+ if (i === 0 || /\s/.test(text[i - 1])) {
95
+ return i;
96
+ }
97
+ break;
98
+ }
99
+ i--;
100
+ }
101
+ return -1;
102
+ };
103
+ export const getSlashSelectorPosition = (text, cursorPosition) => {
104
+ let i = cursorPosition - 1;
105
+ while (i >= 0 && !/\s/.test(text[i])) {
106
+ if (text[i] === "/") {
107
+ // Check if this / is at the start or preceded by whitespace
108
+ if (i === 0 || /\s/.test(text[i - 1])) {
109
+ return i;
110
+ }
111
+ break;
112
+ }
113
+ i--;
114
+ }
115
+ return -1;
116
+ };
71
117
  export const updateSearchQueriesForActiveSelectors = (state, dispatch, inputText, cursorPosition) => {
72
118
  if (state.showFileSelector && state.atPosition >= 0) {
73
119
  const queryStart = state.atPosition + 1;
@@ -82,18 +128,45 @@ export const updateSearchQueriesForActiveSelectors = (state, dispatch, inputText
82
128
  dispatch({ type: "SET_COMMAND_SEARCH_QUERY", payload: newQuery });
83
129
  }
84
130
  };
85
- export const handleSpecialCharInput = (state, dispatch, char, cursorPosition, inputText) => {
86
- if (char === "@") {
87
- dispatch({ type: "ACTIVATE_FILE_SELECTOR", payload: cursorPosition - 1 });
88
- }
89
- else if (char === "/" && !state.showFileSelector && cursorPosition === 1) {
131
+ export const processSelectorInput = (state, dispatch, char) => {
132
+ const { newInputText, newCursorPosition } = getProjectedState(state, char);
133
+ const trigger = SELECTOR_TRIGGERS.find((t) => t.shouldActivate(char, newCursorPosition, newInputText, state));
134
+ if (trigger) {
90
135
  dispatch({
91
- type: "ACTIVATE_COMMAND_SELECTOR",
92
- payload: cursorPosition - 1,
136
+ type: trigger.type,
137
+ payload: newCursorPosition - 1,
93
138
  });
94
139
  }
95
140
  else {
96
- updateSearchQueriesForActiveSelectors(state, dispatch, inputText, cursorPosition);
141
+ const atPos = getAtSelectorPosition(newInputText, newCursorPosition);
142
+ let showFileSelector = state.showFileSelector;
143
+ let atPosition = state.atPosition;
144
+ if (atPos !== -1 && !state.showFileSelector) {
145
+ dispatch({
146
+ type: "ACTIVATE_FILE_SELECTOR",
147
+ payload: atPos,
148
+ });
149
+ showFileSelector = true;
150
+ atPosition = atPos;
151
+ }
152
+ const slashPos = getSlashSelectorPosition(newInputText, newCursorPosition);
153
+ let showCommandSelector = state.showCommandSelector;
154
+ let slashPosition = state.slashPosition;
155
+ if (slashPos !== -1 && !state.showCommandSelector) {
156
+ dispatch({
157
+ type: "ACTIVATE_COMMAND_SELECTOR",
158
+ payload: slashPos,
159
+ });
160
+ showCommandSelector = true;
161
+ slashPosition = slashPos;
162
+ }
163
+ updateSearchQueriesForActiveSelectors({
164
+ ...state,
165
+ showFileSelector,
166
+ atPosition,
167
+ showCommandSelector,
168
+ slashPosition,
169
+ }, dispatch, newInputText, newCursorPosition);
97
170
  }
98
171
  };
99
172
  export const handlePasteInput = (state, dispatch, callbacks, input) => {
@@ -117,21 +190,24 @@ export const handlePasteInput = (state, dispatch, callbacks, input) => {
117
190
  if (char === "!" && state.cursorPosition === 0) {
118
191
  char = "!";
119
192
  }
120
- callbacks.onResetHistoryNavigation?.();
193
+ dispatch({ type: "RESET_HISTORY_NAVIGATION" });
121
194
  dispatch({ type: "INSERT_TEXT", payload: char });
122
- // Calculate new state for special char handling
123
- const newCursorPosition = state.cursorPosition + char.length;
124
- const beforeCursor = state.inputText.substring(0, state.cursorPosition);
125
- const afterCursor = state.inputText.substring(state.cursorPosition);
126
- const newInputText = beforeCursor + char + afterCursor;
127
- handleSpecialCharInput(state, dispatch, char, newCursorPosition, newInputText);
195
+ processSelectorInput(state, dispatch, char);
196
+ }
197
+ };
198
+ export const getWordEnd = (text, startPos) => {
199
+ let i = startPos;
200
+ while (i < text.length && !/\s/.test(text[i])) {
201
+ i++;
128
202
  }
203
+ return i;
129
204
  };
130
205
  export const handleCommandSelect = (state, dispatch, callbacks, command) => {
131
206
  if (state.slashPosition >= 0) {
207
+ const wordEnd = getWordEnd(state.inputText, state.slashPosition);
132
208
  const beforeSlash = state.inputText.substring(0, state.slashPosition);
133
- const afterQuery = state.inputText.substring(state.cursorPosition);
134
- const newInput = beforeSlash + afterQuery;
209
+ const afterWord = state.inputText.substring(wordEnd);
210
+ const newInput = beforeSlash + afterWord;
135
211
  const newCursorPosition = beforeSlash.length;
136
212
  dispatch({ type: "SET_INPUT_TEXT", payload: newInput });
137
213
  dispatch({ type: "SET_CURSOR_POSITION", payload: newCursorPosition });
@@ -178,10 +254,11 @@ export const handleCommandSelect = (state, dispatch, callbacks, command) => {
178
254
  };
179
255
  export const handleFileSelect = (state, dispatch, callbacks, filePath) => {
180
256
  if (state.atPosition >= 0) {
257
+ const wordEnd = getWordEnd(state.inputText, state.atPosition);
181
258
  const beforeAt = state.inputText.substring(0, state.atPosition);
182
- const afterQuery = state.inputText.substring(state.cursorPosition);
183
- const newInput = beforeAt + `${filePath} ` + afterQuery;
184
- const newCursorPosition = beforeAt.length + filePath.length + 1;
259
+ const afterWord = state.inputText.substring(wordEnd);
260
+ const newInput = beforeAt + `@${filePath} ` + afterWord;
261
+ const newCursorPosition = beforeAt.length + filePath.length + 2;
185
262
  dispatch({ type: "SET_INPUT_TEXT", payload: newInput });
186
263
  dispatch({ type: "SET_CURSOR_POSITION", payload: newCursorPosition });
187
264
  dispatch({ type: "CANCEL_FILE_SELECTOR" });
@@ -224,6 +301,23 @@ export const handleSelectorInput = (state, dispatch, callbacks, input, key) => {
224
301
  if (key.upArrow || key.downArrow || key.return || key.tab) {
225
302
  return true;
226
303
  }
304
+ if (key.leftArrow) {
305
+ const newCursorPosition = state.cursorPosition - 1;
306
+ dispatch({ type: "MOVE_CURSOR", payload: -1 });
307
+ checkForAtDeletion(state, dispatch, newCursorPosition);
308
+ checkForSlashDeletion(state, dispatch, newCursorPosition);
309
+ return true;
310
+ }
311
+ if (key.rightArrow) {
312
+ const newCursorPosition = state.cursorPosition + 1;
313
+ dispatch({ type: "MOVE_CURSOR", payload: 1 });
314
+ checkForAtDeletion(state, dispatch, newCursorPosition);
315
+ checkForSlashDeletion(state, dispatch, newCursorPosition);
316
+ return true;
317
+ }
318
+ if (input === " " && state.showFileSelector) {
319
+ dispatch({ type: "CANCEL_FILE_SELECTOR" });
320
+ }
227
321
  if (input &&
228
322
  !key.ctrl &&
229
323
  !("alt" in key && key.alt) &&
@@ -236,19 +330,14 @@ export const handleSelectorInput = (state, dispatch, callbacks, input, key) => {
236
330
  !("home" in key && key.home) &&
237
331
  !("end" in key && key.end)) {
238
332
  dispatch({ type: "INSERT_TEXT", payload: input });
239
- // Calculate new state for special char handling
240
- const newCursorPosition = state.cursorPosition + input.length;
241
- const beforeCursor = state.inputText.substring(0, state.cursorPosition);
242
- const afterCursor = state.inputText.substring(state.cursorPosition);
243
- const newInputText = beforeCursor + input + afterCursor;
244
- handleSpecialCharInput(state, dispatch, input, newCursorPosition, newInputText);
333
+ processSelectorInput(state, dispatch, input);
245
334
  return true;
246
335
  }
247
336
  return false;
248
337
  };
249
- export const handleNormalInput = async (state, dispatch, callbacks, input, key, isLoading = false, isCommandRunning = false, clearImages) => {
338
+ export const handleNormalInput = async (state, dispatch, callbacks, input, key, clearImages) => {
250
339
  if (key.return) {
251
- await handleSubmit(state, dispatch, callbacks, isLoading, isCommandRunning);
340
+ await handleSubmit(state, dispatch, callbacks);
252
341
  clearImages?.();
253
342
  return true;
254
343
  }
@@ -259,15 +348,65 @@ export const handleNormalInput = async (state, dispatch, callbacks, input, key,
259
348
  else if (state.showCommandSelector) {
260
349
  dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
261
350
  }
351
+ else if (state.historyIndex !== -1) {
352
+ dispatch({ type: "RESET_HISTORY_NAVIGATION" });
353
+ }
354
+ return true;
355
+ }
356
+ if (key.upArrow) {
357
+ if (state.history.length === 0) {
358
+ const history = await PromptHistoryManager.getHistory(callbacks.sessionId);
359
+ dispatch({ type: "SET_HISTORY_ENTRIES", payload: history });
360
+ }
361
+ dispatch({ type: "NAVIGATE_HISTORY", payload: "up" });
362
+ return true;
363
+ }
364
+ if (key.downArrow) {
365
+ dispatch({ type: "NAVIGATE_HISTORY", payload: "down" });
262
366
  return true;
263
367
  }
264
368
  if (key.backspace || key.delete) {
265
369
  if (state.cursorPosition > 0) {
266
370
  const newCursorPosition = state.cursorPosition - 1;
371
+ const beforeCursor = state.inputText.substring(0, state.cursorPosition - 1);
372
+ const afterCursor = state.inputText.substring(state.cursorPosition);
373
+ const newInputText = beforeCursor + afterCursor;
267
374
  dispatch({ type: "DELETE_CHAR" });
268
- callbacks.onResetHistoryNavigation?.();
375
+ dispatch({ type: "RESET_HISTORY_NAVIGATION" });
269
376
  checkForAtDeletion(state, dispatch, newCursorPosition);
270
377
  checkForSlashDeletion(state, dispatch, newCursorPosition);
378
+ // Reactivate file selector if cursor is now within an @word
379
+ const atPos = getAtSelectorPosition(newInputText, newCursorPosition);
380
+ let showFileSelector = state.showFileSelector;
381
+ let atPosition = state.atPosition;
382
+ if (atPos !== -1 && !state.showFileSelector) {
383
+ dispatch({
384
+ type: "ACTIVATE_FILE_SELECTOR",
385
+ payload: atPos,
386
+ });
387
+ showFileSelector = true;
388
+ atPosition = atPos;
389
+ }
390
+ const slashPos = getSlashSelectorPosition(newInputText, newCursorPosition);
391
+ let showCommandSelector = state.showCommandSelector;
392
+ let slashPosition = state.slashPosition;
393
+ if (slashPos !== -1 && !state.showCommandSelector) {
394
+ dispatch({
395
+ type: "ACTIVATE_COMMAND_SELECTOR",
396
+ payload: slashPos,
397
+ });
398
+ showCommandSelector = true;
399
+ slashPosition = slashPos;
400
+ }
401
+ updateSearchQueriesForActiveSelectors({
402
+ ...state,
403
+ inputText: newInputText,
404
+ cursorPosition: newCursorPosition,
405
+ showFileSelector,
406
+ atPosition,
407
+ showCommandSelector,
408
+ slashPosition,
409
+ }, dispatch, newInputText, newCursorPosition);
271
410
  }
272
411
  return true;
273
412
  }
@@ -310,20 +449,19 @@ export const handleNormalInput = async (state, dispatch, callbacks, input, key,
310
449
  }
311
450
  return false;
312
451
  };
313
- export const handleInput = async (state, dispatch, callbacks, input, key, isLoading = false, isCommandRunning = false, clearImages) => {
452
+ export const handleInput = async (state, dispatch, callbacks, input, key, clearImages) => {
314
453
  if (state.selectorJustUsed) {
315
454
  return true;
316
455
  }
317
456
  if (key.escape) {
318
- if ((isLoading || isCommandRunning) &&
319
- !(state.showFileSelector ||
320
- state.showCommandSelector ||
321
- state.showHistorySearch ||
322
- state.showBackgroundTaskManager ||
323
- state.showMcpManager ||
324
- state.showRewindManager ||
325
- state.showHelp ||
326
- state.showStatusCommand)) {
457
+ if (!(state.showFileSelector ||
458
+ state.showCommandSelector ||
459
+ state.showHistorySearch ||
460
+ state.showBackgroundTaskManager ||
461
+ state.showMcpManager ||
462
+ state.showRewindManager ||
463
+ state.showHelp ||
464
+ state.showStatusCommand)) {
327
465
  callbacks.onAbortMessage?.();
328
466
  return true;
329
467
  }
@@ -373,6 +511,6 @@ export const handleInput = async (state, dispatch, callbacks, input, key, isLoad
373
511
  return handleSelectorInput(state, dispatch, callbacks, input, key);
374
512
  }
375
513
  else {
376
- return await handleNormalInput(state, dispatch, callbacks, input, key, isLoading, isCommandRunning, clearImages);
514
+ return await handleNormalInput(state, dispatch, callbacks, input, key, clearImages);
377
515
  }
378
516
  };
@@ -1,4 +1,4 @@
1
- import { FileItem, PermissionMode, Logger } from "wave-agent-sdk";
1
+ import { FileItem, PermissionMode, Logger, PromptEntry } from "wave-agent-sdk";
2
2
  export interface AttachedImage {
3
3
  id: number;
4
4
  path: string;
@@ -24,8 +24,8 @@ export interface InputManagerCallbacks {
24
24
  onAbortMessage?: () => void;
25
25
  onClearMessages?: () => void;
26
26
  onBackgroundCurrentTask?: () => void;
27
- onResetHistoryNavigation?: () => void;
28
27
  onPermissionModeChange?: (mode: PermissionMode) => void;
28
+ sessionId?: string;
29
29
  logger?: Logger;
30
30
  }
31
31
  export interface InputState {
@@ -54,6 +54,11 @@ export interface InputState {
54
54
  isPasting: boolean;
55
55
  pasteBuffer: string;
56
56
  initialPasteCursorPosition: number;
57
+ history: PromptEntry[];
58
+ historyIndex: number;
59
+ originalInputText: string;
60
+ originalLongTextMap: Record<string, string>;
61
+ isFileSearching: boolean;
57
62
  }
58
63
  export declare const initialState: InputState;
59
64
  export type InputAction = {
@@ -152,6 +157,17 @@ export type InputAction = {
152
157
  path: string;
153
158
  mimeType: string;
154
159
  };
160
+ } | {
161
+ type: "SET_HISTORY_ENTRIES";
162
+ payload: PromptEntry[];
163
+ } | {
164
+ type: "NAVIGATE_HISTORY";
165
+ payload: "up" | "down";
166
+ } | {
167
+ type: "RESET_HISTORY_NAVIGATION";
168
+ } | {
169
+ type: "SELECT_HISTORY_ENTRY";
170
+ payload: PromptEntry;
155
171
  };
156
172
  export declare function inputReducer(state: InputState, action: InputAction): InputState;
157
173
  //# sourceMappingURL=inputReducer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inputReducer.d.ts","sourceRoot":"","sources":["../../src/managers/inputReducer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inputReducer.d.ts","sourceRoot":"","sources":["../../src/managers/inputReducer.ts"],"names":[],"mappings":"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"}
@@ -24,11 +24,20 @@ export const initialState = {
24
24
  isPasting: false,
25
25
  pasteBuffer: "",
26
26
  initialPasteCursorPosition: 0,
27
+ history: [],
28
+ historyIndex: -1,
29
+ originalInputText: "",
30
+ originalLongTextMap: {},
31
+ isFileSearching: false,
27
32
  };
28
33
  export function inputReducer(state, action) {
29
34
  switch (action.type) {
30
35
  case "SET_INPUT_TEXT":
31
- return { ...state, inputText: action.payload };
36
+ return {
37
+ ...state,
38
+ inputText: action.payload,
39
+ historyIndex: -1,
40
+ };
32
41
  case "SET_CURSOR_POSITION":
33
42
  return {
34
43
  ...state,
@@ -43,6 +52,7 @@ export function inputReducer(state, action) {
43
52
  ...state,
44
53
  inputText: newText,
45
54
  cursorPosition: newCursorPosition,
55
+ historyIndex: -1,
46
56
  };
47
57
  }
48
58
  case "DELETE_CHAR": {
@@ -55,6 +65,7 @@ export function inputReducer(state, action) {
55
65
  ...state,
56
66
  inputText: newText,
57
67
  cursorPosition: newCursorPosition,
68
+ historyIndex: -1,
58
69
  };
59
70
  }
60
71
  return state;
@@ -70,11 +81,20 @@ export function inputReducer(state, action) {
70
81
  atPosition: action.payload,
71
82
  fileSearchQuery: "",
72
83
  filteredFiles: [],
84
+ isFileSearching: true,
73
85
  };
74
86
  case "SET_FILE_SEARCH_QUERY":
75
- return { ...state, fileSearchQuery: action.payload };
87
+ return {
88
+ ...state,
89
+ fileSearchQuery: action.payload,
90
+ isFileSearching: true,
91
+ };
76
92
  case "SET_FILTERED_FILES":
77
- return { ...state, filteredFiles: action.payload };
93
+ return {
94
+ ...state,
95
+ filteredFiles: action.payload,
96
+ isFileSearching: false,
97
+ };
78
98
  case "CANCEL_FILE_SELECTOR":
79
99
  return {
80
100
  ...state,
@@ -83,6 +103,7 @@ export function inputReducer(state, action) {
83
103
  fileSearchQuery: "",
84
104
  filteredFiles: [],
85
105
  selectorJustUsed: true,
106
+ isFileSearching: false,
86
107
  };
87
108
  case "ACTIVATE_COMMAND_SELECTOR":
88
109
  return {
@@ -189,6 +210,7 @@ export function inputReducer(state, action) {
189
210
  cursorPosition: newCursorPosition,
190
211
  longTextCounter: newLongTextCounter,
191
212
  longTextMap: newLongTextMap,
213
+ historyIndex: -1,
192
214
  };
193
215
  }
194
216
  case "CLEAR_LONG_TEXT_MAP":
@@ -198,6 +220,7 @@ export function inputReducer(state, action) {
198
220
  ...state,
199
221
  inputText: "",
200
222
  cursorPosition: 0,
223
+ historyIndex: -1,
201
224
  };
202
225
  case "START_PASTE":
203
226
  return {
@@ -234,8 +257,74 @@ export function inputReducer(state, action) {
234
257
  imageIdCounter: state.imageIdCounter + 1,
235
258
  inputText: newText,
236
259
  cursorPosition: newCursorPosition,
260
+ historyIndex: -1,
261
+ };
262
+ }
263
+ case "SET_HISTORY_ENTRIES":
264
+ return { ...state, history: action.payload };
265
+ case "NAVIGATE_HISTORY": {
266
+ const direction = action.payload;
267
+ let newIndex = state.historyIndex;
268
+ let newOriginalInputText = state.originalInputText;
269
+ let newOriginalLongTextMap = state.originalLongTextMap;
270
+ if (direction === "up") {
271
+ if (newIndex === -1) {
272
+ newOriginalInputText = state.inputText;
273
+ newOriginalLongTextMap = state.longTextMap;
274
+ }
275
+ newIndex = Math.min(state.history.length - 1, newIndex + 1);
276
+ }
277
+ else {
278
+ newIndex = Math.max(-1, newIndex - 1);
279
+ }
280
+ if (newIndex === -1) {
281
+ return {
282
+ ...state,
283
+ historyIndex: newIndex,
284
+ inputText: newOriginalInputText,
285
+ longTextMap: newOriginalLongTextMap,
286
+ cursorPosition: newOriginalInputText.length,
287
+ originalInputText: newOriginalInputText,
288
+ originalLongTextMap: newOriginalLongTextMap,
289
+ };
290
+ }
291
+ else {
292
+ const entry = state.history[newIndex];
293
+ return {
294
+ ...state,
295
+ historyIndex: newIndex,
296
+ inputText: entry.prompt,
297
+ longTextMap: entry.longTextMap || {},
298
+ cursorPosition: entry.prompt.length,
299
+ originalInputText: newOriginalInputText,
300
+ originalLongTextMap: newOriginalLongTextMap,
301
+ };
302
+ }
303
+ }
304
+ case "SELECT_HISTORY_ENTRY": {
305
+ const entry = action.payload;
306
+ return {
307
+ ...state,
308
+ inputText: entry.prompt,
309
+ longTextMap: entry.longTextMap || {},
310
+ cursorPosition: entry.prompt.length,
311
+ historyIndex: -1,
312
+ history: [],
313
+ originalInputText: "",
314
+ originalLongTextMap: {},
315
+ showHistorySearch: false,
316
+ historySearchQuery: "",
317
+ selectorJustUsed: true,
237
318
  };
238
319
  }
320
+ case "RESET_HISTORY_NAVIGATION":
321
+ return {
322
+ ...state,
323
+ historyIndex: -1,
324
+ history: [],
325
+ originalInputText: "",
326
+ originalLongTextMap: {},
327
+ };
239
328
  default:
240
329
  return state;
241
330
  }
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH;;GAEG;AACH,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAYD;;GAEG;AACH,UAAU,SAAS;IACjB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;CAC7B;AA8HD;;GAEG;AACH,eAAO,MAAM,MAAM;IACjB;;OAEG;qBACc,OAAO,EAAE,KAAG,IAAI;IAIjC;;OAEG;oBACa,OAAO,EAAE,KAAG,IAAI;IAIhC;;OAEG;oBACa,OAAO,EAAE,KAAG,IAAI;IAIhC;;OAEG;qBACc,OAAO,EAAE,KAAG,IAAI;CAGlC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,QAAO,SAE/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,QAAO,MAE7B,CAAC;AAEF;;GAEG;AACH,UAAU,gBAAgB;IACxB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;CACnB;AAqDD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GACtB,eAAe,OAAO,CAAC,gBAAgB,CAAC,KACvC,OAAO,CAAC,IAAI,CAiBd,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH;;GAEG;AACH,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAsBD;;GAEG;AACH,UAAU,SAAS;IACjB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;CAC7B;AA+HD;;GAEG;AACH,eAAO,MAAM,MAAM;IACjB;;OAEG;qBACc,OAAO,EAAE,KAAG,IAAI;IAIjC;;OAEG;oBACa,OAAO,EAAE,KAAG,IAAI;IAIhC;;OAEG;oBACa,OAAO,EAAE,KAAG,IAAI;IAIhC;;OAEG;qBACc,OAAO,EAAE,KAAG,IAAI;CAGlC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,QAAO,SAE/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,QAAO,MAE7B,CAAC;AAEF;;GAEG;AACH,UAAU,gBAAgB;IACxB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;CACnB;AAqDD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GACtB,eAAe,OAAO,CAAC,gBAAgB,CAAC,KACvC,OAAO,CAAC,IAAI,CAiBd,CAAC"}
@@ -8,7 +8,9 @@
8
8
  * - This can significantly improve test execution performance by avoiding unnecessary disk writes
9
9
  */
10
10
  import * as fs from "fs";
11
+ import { Chalk } from "chalk";
11
12
  import { LOG_FILE, DATA_DIRECTORY } from "./constants.js";
13
+ const chalk = new Chalk({ level: 3 });
12
14
  const logFile = process.env.LOG_FILE || LOG_FILE;
13
15
  /**
14
16
  * Log level enumeration
@@ -29,6 +31,15 @@ const LOG_LEVEL_NAMES = {
29
31
  [LogLevel.WARN]: "WARN",
30
32
  [LogLevel.ERROR]: "ERROR",
31
33
  };
34
+ /**
35
+ * Log level color mapping
36
+ */
37
+ const LEVEL_COLORS = {
38
+ [LogLevel.DEBUG]: chalk.gray,
39
+ [LogLevel.INFO]: chalk.blue,
40
+ [LogLevel.WARN]: chalk.yellow,
41
+ [LogLevel.ERROR]: chalk.red,
42
+ };
32
43
  /**
33
44
  * Parse log level from environment variable
34
45
  */
@@ -125,7 +136,8 @@ const logMessage = (level, ...args) => {
125
136
  }
126
137
  const levelName = LOG_LEVEL_NAMES[level];
127
138
  const timestamp = new Date().toISOString();
128
- const formattedMessage = `[${timestamp}] [${levelName}] ${messageText}\n`;
139
+ const color = LEVEL_COLORS[level] || ((s) => s);
140
+ const formattedMessage = `[${chalk.gray(timestamp)}] [${color(levelName)}] ${messageText}\n`;
129
141
  try {
130
142
  // Ensure directory exists
131
143
  if (!fs.existsSync(DATA_DIRECTORY)) {