wave-code 0.0.3 → 0.0.5

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 (82) hide show
  1. package/dist/components/InputBox.d.ts.map +1 -1
  2. package/dist/components/InputBox.js +69 -95
  3. package/dist/components/MemoryDisplay.js +1 -1
  4. package/dist/components/MemoryTypeSelector.js +1 -1
  5. package/dist/components/MessageList.d.ts.map +1 -1
  6. package/dist/components/MessageList.js +2 -1
  7. package/dist/components/SubagentBlock.d.ts +1 -1
  8. package/dist/components/SubagentBlock.d.ts.map +1 -1
  9. package/dist/components/SubagentBlock.js +12 -2
  10. package/dist/components/ToolResultDisplay.js +1 -1
  11. package/dist/contexts/useChat.d.ts +2 -1
  12. package/dist/contexts/useChat.d.ts.map +1 -1
  13. package/dist/contexts/useChat.js +18 -0
  14. package/dist/hooks/useInputManager.d.ts +91 -0
  15. package/dist/hooks/useInputManager.d.ts.map +1 -0
  16. package/dist/hooks/useInputManager.js +319 -0
  17. package/dist/index.js +9 -9
  18. package/dist/managers/InputManager.d.ts +169 -0
  19. package/dist/managers/InputManager.d.ts.map +1 -0
  20. package/dist/managers/InputManager.js +806 -0
  21. package/dist/print-cli.d.ts +7 -0
  22. package/dist/print-cli.d.ts.map +1 -0
  23. package/dist/{plain-cli.js → print-cli.js} +21 -2
  24. package/dist/utils/constants.d.ts +1 -1
  25. package/dist/utils/constants.js +1 -1
  26. package/dist/utils/fileSearch.d.ts +20 -0
  27. package/dist/utils/fileSearch.d.ts.map +1 -0
  28. package/dist/utils/fileSearch.js +102 -0
  29. package/dist/utils/logger.js +3 -3
  30. package/dist/utils/usageSummary.d.ts +27 -0
  31. package/dist/utils/usageSummary.d.ts.map +1 -0
  32. package/dist/utils/usageSummary.js +82 -0
  33. package/package.json +2 -2
  34. package/src/components/InputBox.tsx +114 -153
  35. package/src/components/MemoryDisplay.tsx +1 -1
  36. package/src/components/MemoryTypeSelector.tsx +1 -1
  37. package/src/components/MessageList.tsx +14 -10
  38. package/src/components/SubagentBlock.tsx +14 -3
  39. package/src/components/ToolResultDisplay.tsx +1 -1
  40. package/src/contexts/useChat.tsx +23 -0
  41. package/src/hooks/useInputManager.ts +443 -0
  42. package/src/index.ts +9 -9
  43. package/src/managers/InputManager.ts +1102 -0
  44. package/src/{plain-cli.ts → print-cli.ts} +21 -3
  45. package/src/utils/constants.ts +1 -1
  46. package/src/utils/fileSearch.ts +133 -0
  47. package/src/utils/logger.ts +3 -3
  48. package/src/utils/usageSummary.ts +125 -0
  49. package/dist/hooks/useBashHistorySelector.d.ts +0 -15
  50. package/dist/hooks/useBashHistorySelector.d.ts.map +0 -1
  51. package/dist/hooks/useBashHistorySelector.js +0 -61
  52. package/dist/hooks/useCommandSelector.d.ts +0 -24
  53. package/dist/hooks/useCommandSelector.d.ts.map +0 -1
  54. package/dist/hooks/useCommandSelector.js +0 -98
  55. package/dist/hooks/useFileSelector.d.ts +0 -16
  56. package/dist/hooks/useFileSelector.d.ts.map +0 -1
  57. package/dist/hooks/useFileSelector.js +0 -174
  58. package/dist/hooks/useImageManager.d.ts +0 -13
  59. package/dist/hooks/useImageManager.d.ts.map +0 -1
  60. package/dist/hooks/useImageManager.js +0 -46
  61. package/dist/hooks/useInputHistory.d.ts +0 -11
  62. package/dist/hooks/useInputHistory.d.ts.map +0 -1
  63. package/dist/hooks/useInputHistory.js +0 -64
  64. package/dist/hooks/useInputKeyboardHandler.d.ts +0 -83
  65. package/dist/hooks/useInputKeyboardHandler.d.ts.map +0 -1
  66. package/dist/hooks/useInputKeyboardHandler.js +0 -507
  67. package/dist/hooks/useInputState.d.ts +0 -14
  68. package/dist/hooks/useInputState.d.ts.map +0 -1
  69. package/dist/hooks/useInputState.js +0 -57
  70. package/dist/hooks/useMemoryTypeSelector.d.ts +0 -9
  71. package/dist/hooks/useMemoryTypeSelector.d.ts.map +0 -1
  72. package/dist/hooks/useMemoryTypeSelector.js +0 -27
  73. package/dist/plain-cli.d.ts +0 -7
  74. package/dist/plain-cli.d.ts.map +0 -1
  75. package/src/hooks/useBashHistorySelector.ts +0 -77
  76. package/src/hooks/useCommandSelector.ts +0 -131
  77. package/src/hooks/useFileSelector.ts +0 -227
  78. package/src/hooks/useImageManager.ts +0 -64
  79. package/src/hooks/useInputHistory.ts +0 -74
  80. package/src/hooks/useInputKeyboardHandler.ts +0 -778
  81. package/src/hooks/useInputState.ts +0 -66
  82. package/src/hooks/useMemoryTypeSelector.ts +0 -40
@@ -0,0 +1,443 @@
1
+ import { useEffect, useRef, useState, useCallback } from "react";
2
+ import { Key } from "ink";
3
+ import {
4
+ InputManager,
5
+ InputManagerCallbacks,
6
+ AttachedImage,
7
+ } from "../managers/InputManager.js";
8
+ import { FileItem } from "../components/FileSelector.js";
9
+
10
+ export const useInputManager = (
11
+ callbacks: Partial<InputManagerCallbacks> = {},
12
+ ) => {
13
+ const managerRef = useRef<InputManager | null>(null);
14
+
15
+ // React state that mirrors InputManager state
16
+ const [inputText, setInputText] = useState("");
17
+ const [cursorPosition, setCursorPosition] = useState(0);
18
+ const [fileSelectorState, setFileSelectorState] = useState({
19
+ show: false,
20
+ files: [] as FileItem[],
21
+ query: "",
22
+ position: -1,
23
+ });
24
+ const [commandSelectorState, setCommandSelectorState] = useState({
25
+ show: false,
26
+ query: "",
27
+ position: -1,
28
+ });
29
+ const [bashHistorySelectorState, setBashHistorySelectorState] = useState({
30
+ show: false,
31
+ query: "",
32
+ position: -1,
33
+ });
34
+ const [memoryTypeSelectorState, setMemoryTypeSelectorState] = useState({
35
+ show: false,
36
+ message: "",
37
+ });
38
+ const [showBashManager, setShowBashManager] = useState(false);
39
+ const [showMcpManager, setShowMcpManager] = useState(false);
40
+ const [attachedImages, setAttachedImages] = useState<AttachedImage[]>([]);
41
+
42
+ // Create InputManager on mount and update callbacks when they change
43
+ useEffect(() => {
44
+ if (!managerRef.current) {
45
+ // Create InputManager on first mount
46
+ const manager = new InputManager({
47
+ onInputTextChange: setInputText,
48
+ onCursorPositionChange: setCursorPosition,
49
+ onFileSelectorStateChange: (show, files, query, position) => {
50
+ setFileSelectorState({ show, files, query, position });
51
+ },
52
+ onCommandSelectorStateChange: (show, query, position) => {
53
+ setCommandSelectorState({ show, query, position });
54
+ },
55
+ onBashHistorySelectorStateChange: (show, query, position) => {
56
+ setBashHistorySelectorState({ show, query, position });
57
+ },
58
+ onMemoryTypeSelectorStateChange: (show, message) => {
59
+ setMemoryTypeSelectorState({ show, message });
60
+ },
61
+ onBashManagerStateChange: (show) => {
62
+ setShowBashManager(show);
63
+ },
64
+ onMcpManagerStateChange: (show) => {
65
+ setShowMcpManager(show);
66
+ },
67
+ onImagesStateChange: setAttachedImages,
68
+ ...callbacks,
69
+ });
70
+
71
+ managerRef.current = manager;
72
+ } else {
73
+ // Update callbacks on existing manager
74
+ managerRef.current.updateCallbacks({
75
+ onInputTextChange: setInputText,
76
+ onCursorPositionChange: setCursorPosition,
77
+ onFileSelectorStateChange: (show, files, query, position) => {
78
+ setFileSelectorState({ show, files, query, position });
79
+ },
80
+ onCommandSelectorStateChange: (show, query, position) => {
81
+ setCommandSelectorState({ show, query, position });
82
+ },
83
+ onBashHistorySelectorStateChange: (show, query, position) => {
84
+ setBashHistorySelectorState({ show, query, position });
85
+ },
86
+ onMemoryTypeSelectorStateChange: (show, message) => {
87
+ setMemoryTypeSelectorState({ show, message });
88
+ },
89
+ onBashManagerStateChange: (show) => {
90
+ setShowBashManager(show);
91
+ },
92
+ onMcpManagerStateChange: (show) => {
93
+ setShowMcpManager(show);
94
+ },
95
+ onImagesStateChange: setAttachedImages,
96
+ ...callbacks,
97
+ });
98
+ }
99
+ }, [callbacks]);
100
+
101
+ // Cleanup on unmount
102
+ useEffect(() => {
103
+ return () => {
104
+ if (managerRef.current) {
105
+ managerRef.current.destroy();
106
+ }
107
+ };
108
+ }, []);
109
+
110
+ // Expose manager methods
111
+ const insertTextAtCursor = useCallback(
112
+ (
113
+ text: string,
114
+ callback?: (newText: string, newCursorPosition: number) => void,
115
+ ) => {
116
+ managerRef.current?.insertTextAtCursor(text, callback);
117
+ },
118
+ [],
119
+ );
120
+
121
+ const deleteCharAtCursor = useCallback(
122
+ (callback?: (newText: string, newCursorPosition: number) => void) => {
123
+ managerRef.current?.deleteCharAtCursor(callback);
124
+ },
125
+ [],
126
+ );
127
+
128
+ const clearInput = useCallback(() => {
129
+ managerRef.current?.clearInput();
130
+ }, []);
131
+
132
+ const moveCursorLeft = useCallback(() => {
133
+ managerRef.current?.moveCursorLeft();
134
+ }, []);
135
+
136
+ const moveCursorRight = useCallback(() => {
137
+ managerRef.current?.moveCursorRight();
138
+ }, []);
139
+
140
+ const moveCursorToStart = useCallback(() => {
141
+ managerRef.current?.moveCursorToStart();
142
+ }, []);
143
+
144
+ const moveCursorToEnd = useCallback(() => {
145
+ managerRef.current?.moveCursorToEnd();
146
+ }, []);
147
+
148
+ // File selector methods
149
+ const activateFileSelector = useCallback((position: number) => {
150
+ managerRef.current?.activateFileSelector(position);
151
+ }, []);
152
+
153
+ const handleFileSelect = useCallback(
154
+ (filePath: string) => {
155
+ return (
156
+ managerRef.current?.handleFileSelect(filePath) || {
157
+ newInput: inputText,
158
+ newCursorPosition: cursorPosition,
159
+ }
160
+ );
161
+ },
162
+ [inputText, cursorPosition],
163
+ );
164
+
165
+ const handleCancelFileSelect = useCallback(() => {
166
+ managerRef.current?.handleCancelFileSelect();
167
+ }, []);
168
+
169
+ const updateFileSearchQuery = useCallback((query: string) => {
170
+ managerRef.current?.updateFileSearchQuery(query);
171
+ }, []);
172
+
173
+ const checkForAtDeletion = useCallback((cursorPos: number) => {
174
+ return managerRef.current?.checkForAtDeletion(cursorPos) || false;
175
+ }, []);
176
+
177
+ // Command selector methods
178
+ const activateCommandSelector = useCallback((position: number) => {
179
+ managerRef.current?.activateCommandSelector(position);
180
+ }, []);
181
+
182
+ const handleCommandSelect = useCallback(
183
+ (command: string) => {
184
+ return (
185
+ managerRef.current?.handleCommandSelect(command) || {
186
+ newInput: inputText,
187
+ newCursorPosition: cursorPosition,
188
+ }
189
+ );
190
+ },
191
+ [inputText, cursorPosition],
192
+ );
193
+
194
+ const handleCommandInsert = useCallback(
195
+ (command: string) => {
196
+ return (
197
+ managerRef.current?.handleCommandInsert(command) || {
198
+ newInput: inputText,
199
+ newCursorPosition: cursorPosition,
200
+ }
201
+ );
202
+ },
203
+ [inputText, cursorPosition],
204
+ );
205
+
206
+ const handleCancelCommandSelect = useCallback(() => {
207
+ managerRef.current?.handleCancelCommandSelect();
208
+ }, []);
209
+
210
+ const updateCommandSearchQuery = useCallback((query: string) => {
211
+ managerRef.current?.updateCommandSearchQuery(query);
212
+ }, []);
213
+
214
+ const checkForSlashDeletion = useCallback((cursorPos: number) => {
215
+ return managerRef.current?.checkForSlashDeletion(cursorPos) || false;
216
+ }, []);
217
+
218
+ // Bash history selector methods
219
+ const activateBashHistorySelector = useCallback((position: number) => {
220
+ managerRef.current?.activateBashHistorySelector(position);
221
+ }, []);
222
+
223
+ const handleBashHistorySelect = useCallback(
224
+ (command: string) => {
225
+ return (
226
+ managerRef.current?.handleBashHistorySelect(command) || {
227
+ newInput: inputText,
228
+ newCursorPosition: cursorPosition,
229
+ }
230
+ );
231
+ },
232
+ [inputText, cursorPosition],
233
+ );
234
+
235
+ const handleCancelBashHistorySelect = useCallback(() => {
236
+ managerRef.current?.handleCancelBashHistorySelect();
237
+ }, []);
238
+
239
+ const updateBashHistorySearchQuery = useCallback((query: string) => {
240
+ managerRef.current?.updateBashHistorySearchQuery(query);
241
+ }, []);
242
+
243
+ const handleBashHistoryExecute = useCallback((command: string) => {
244
+ return managerRef.current?.handleBashHistoryExecute(command) || command;
245
+ }, []);
246
+
247
+ const checkForExclamationDeletion = useCallback((cursorPos: number) => {
248
+ return managerRef.current?.checkForExclamationDeletion(cursorPos) || false;
249
+ }, []);
250
+
251
+ // Memory type selector methods
252
+ const activateMemoryTypeSelector = useCallback((message: string) => {
253
+ managerRef.current?.activateMemoryTypeSelector(message);
254
+ }, []);
255
+
256
+ const handleMemoryTypeSelect = useCallback((type: "project" | "user") => {
257
+ managerRef.current?.handleMemoryTypeSelect(type);
258
+ }, []);
259
+
260
+ const handleCancelMemoryTypeSelect = useCallback(() => {
261
+ managerRef.current?.handleCancelMemoryTypeSelect();
262
+ }, []);
263
+
264
+ // Input history methods
265
+ const setUserInputHistory = useCallback((history: string[]) => {
266
+ managerRef.current?.setUserInputHistory(history);
267
+ }, []);
268
+
269
+ const navigateHistory = useCallback(
270
+ (direction: "up" | "down", currentInput: string) => {
271
+ return (
272
+ managerRef.current?.navigateHistory(direction, currentInput) || {
273
+ newInput: currentInput,
274
+ newCursorPosition: currentInput.length,
275
+ }
276
+ );
277
+ },
278
+ [],
279
+ );
280
+
281
+ const resetHistoryNavigation = useCallback(() => {
282
+ managerRef.current?.resetHistoryNavigation();
283
+ }, []);
284
+
285
+ // Special character handling
286
+ const handleSpecialCharInput = useCallback((char: string) => {
287
+ managerRef.current?.handleSpecialCharInput(char);
288
+ }, []);
289
+
290
+ // Direct state access methods (for compatibility with existing code)
291
+ const setInputTextDirect = useCallback((text: string) => {
292
+ managerRef.current?.setInputText(text);
293
+ }, []);
294
+
295
+ const setCursorPositionDirect = useCallback((position: number) => {
296
+ managerRef.current?.setCursorPosition(position);
297
+ }, []);
298
+
299
+ return {
300
+ // State
301
+ inputText,
302
+ cursorPosition,
303
+ showFileSelector: fileSelectorState.show,
304
+ filteredFiles: fileSelectorState.files,
305
+ fileSearchQuery: fileSelectorState.query,
306
+ atPosition: fileSelectorState.position,
307
+ showCommandSelector: commandSelectorState.show,
308
+ commandSearchQuery: commandSelectorState.query,
309
+ slashPosition: commandSelectorState.position,
310
+ showBashHistorySelector: bashHistorySelectorState.show,
311
+ bashHistorySearchQuery: bashHistorySelectorState.query,
312
+ exclamationPosition: bashHistorySelectorState.position,
313
+ showMemoryTypeSelector: memoryTypeSelectorState.show,
314
+ memoryMessage: memoryTypeSelectorState.message,
315
+ showBashManager,
316
+ showMcpManager,
317
+ attachedImages,
318
+
319
+ // Methods
320
+ insertTextAtCursor,
321
+ deleteCharAtCursor,
322
+ clearInput,
323
+ moveCursorLeft,
324
+ moveCursorRight,
325
+ moveCursorToStart,
326
+ moveCursorToEnd,
327
+
328
+ // File selector
329
+ activateFileSelector,
330
+ handleFileSelect,
331
+ handleCancelFileSelect,
332
+ updateFileSearchQuery,
333
+ checkForAtDeletion,
334
+
335
+ // Command selector
336
+ activateCommandSelector,
337
+ handleCommandSelect,
338
+ handleCommandInsert,
339
+ handleCancelCommandSelect,
340
+ updateCommandSearchQuery,
341
+ checkForSlashDeletion,
342
+
343
+ // Bash history selector
344
+ activateBashHistorySelector,
345
+ handleBashHistorySelect,
346
+ handleCancelBashHistorySelect,
347
+ updateBashHistorySearchQuery,
348
+
349
+ handleBashHistoryExecute,
350
+ checkForExclamationDeletion,
351
+
352
+ // Memory type selector
353
+ activateMemoryTypeSelector,
354
+ handleMemoryTypeSelect,
355
+ handleCancelMemoryTypeSelect,
356
+
357
+ // Input history
358
+ setUserInputHistory,
359
+ navigateHistory,
360
+ resetHistoryNavigation,
361
+
362
+ // Special handling
363
+ handleSpecialCharInput,
364
+
365
+ // Bash/MCP Manager
366
+ setShowBashManager: useCallback((show: boolean) => {
367
+ managerRef.current?.setShowBashManager(show);
368
+ }, []),
369
+ setShowMcpManager: useCallback((show: boolean) => {
370
+ managerRef.current?.setShowMcpManager(show);
371
+ }, []),
372
+
373
+ // Image management
374
+ addImage: useCallback((imagePath: string, mimeType: string) => {
375
+ return managerRef.current?.addImage(imagePath, mimeType);
376
+ }, []),
377
+ removeImage: useCallback((imageId: number) => {
378
+ managerRef.current?.removeImage(imageId);
379
+ }, []),
380
+ clearImages: useCallback(() => {
381
+ managerRef.current?.clearImages();
382
+ }, []),
383
+ handlePasteImage: useCallback(async () => {
384
+ return (await managerRef.current?.handlePasteImage()) || false;
385
+ }, []),
386
+
387
+ // Paste and text handling
388
+ handlePasteInput: useCallback((input: string) => {
389
+ managerRef.current?.handlePasteInput(input);
390
+ }, []),
391
+ handleSubmit: useCallback(
392
+ async (
393
+ attachedImages: Array<{ id: number; path: string; mimeType: string }>,
394
+ isLoading: boolean = false,
395
+ isCommandRunning: boolean = false,
396
+ ) => {
397
+ await managerRef.current?.handleSubmit(
398
+ attachedImages,
399
+ isLoading,
400
+ isCommandRunning,
401
+ );
402
+ },
403
+ [],
404
+ ),
405
+ expandLongTextPlaceholders: useCallback((text: string) => {
406
+ return managerRef.current?.expandLongTextPlaceholders(text) || text;
407
+ }, []),
408
+ clearLongTextMap: useCallback(() => {
409
+ managerRef.current?.clearLongTextMap();
410
+ }, []),
411
+
412
+ // Main input handler
413
+ handleInput: useCallback(
414
+ async (
415
+ input: string,
416
+ key: Key,
417
+ attachedImages: Array<{ id: number; path: string; mimeType: string }>,
418
+ isLoading: boolean = false,
419
+ isCommandRunning: boolean = false,
420
+ clearImages?: () => void,
421
+ ) => {
422
+ return (
423
+ (await managerRef.current?.handleInput(
424
+ input,
425
+ key,
426
+ attachedImages,
427
+ isLoading,
428
+ isCommandRunning,
429
+ clearImages,
430
+ )) || false
431
+ );
432
+ },
433
+ [],
434
+ ),
435
+
436
+ // Direct state setters (for React compatibility)
437
+ setInputText: setInputTextDirect,
438
+ setCursorPosition: setCursorPositionDirect,
439
+
440
+ // Manager reference for advanced usage
441
+ manager: managerRef.current,
442
+ };
443
+ };
package/src/index.ts CHANGED
@@ -16,9 +16,9 @@ export async function main() {
16
16
  description: "Continue from last session",
17
17
  type: "boolean",
18
18
  })
19
- .option("plain", {
19
+ .option("print", {
20
20
  alias: "p",
21
- description: "Plain mode with message to send",
21
+ description: "Print response without interactive mode",
22
22
  type: "string",
23
23
  })
24
24
  .option("list-sessions", {
@@ -30,8 +30,8 @@ export async function main() {
30
30
  .example("$0", "Start CLI with default settings")
31
31
  .example("$0 --restore session_123", "Restore specific session")
32
32
  .example("$0 --continue", "Continue from last session")
33
- .example("$0 --plain 'Hello'", "Send message in plain mode")
34
- .example("$0 -p 'Hello'", "Send message in plain mode (short)")
33
+ .example("$0 --print 'Hello'", "Send message in print mode")
34
+ .example("$0 -p 'Hello'", "Send message in print mode (short)")
35
35
  .example("$0 --list-sessions", "List all available sessions")
36
36
  .help("h")
37
37
  .parseAsync();
@@ -69,13 +69,13 @@ export async function main() {
69
69
  }
70
70
  }
71
71
 
72
- // Handle plain mode directly
73
- if (argv.plain !== undefined) {
74
- const { startPlainCli } = await import("./plain-cli.js");
75
- return startPlainCli({
72
+ // Handle print mode directly
73
+ if (argv.print !== undefined) {
74
+ const { startPrintCli } = await import("./print-cli.js");
75
+ return startPrintCli({
76
76
  restoreSessionId: argv.restore,
77
77
  continueLastSession: argv.continue,
78
- message: argv.plain,
78
+ message: argv.print,
79
79
  });
80
80
  }
81
81