wave-code 0.19.8 → 1.0.0

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 (37) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/components/ChatInterface.js +1 -1
  3. package/dist/components/HelpView.js +6 -0
  4. package/dist/components/InputBox.d.ts +2 -0
  5. package/dist/components/InputBox.js +11 -2
  6. package/dist/components/RewindCommand.js +4 -2
  7. package/dist/components/TaskList.js +28 -12
  8. package/dist/hooks/useInputManager.d.ts +1 -0
  9. package/dist/hooks/useInputManager.js +23 -20
  10. package/dist/index.js +1 -1
  11. package/dist/managers/inputHandlers.js +5 -8
  12. package/dist/managers/inputReducer.d.ts +10 -20
  13. package/dist/managers/inputReducer.js +309 -173
  14. package/dist/print-cli.js +36 -10
  15. package/dist/stdio/agentBridge.d.ts +6 -0
  16. package/dist/stdio/agentBridge.js +141 -1
  17. package/dist/stdio/protocol.d.ts +1 -1
  18. package/dist/utils/rewindCheckpoints.d.ts +8 -0
  19. package/dist/utils/rewindCheckpoints.js +15 -0
  20. package/dist/utils/worktree.d.ts +12 -2
  21. package/dist/utils/worktree.js +61 -25
  22. package/package.json +2 -2
  23. package/src/cli.tsx +1 -1
  24. package/src/components/ChatInterface.tsx +2 -0
  25. package/src/components/HelpView.tsx +6 -0
  26. package/src/components/InputBox.tsx +19 -0
  27. package/src/components/RewindCommand.tsx +4 -2
  28. package/src/components/TaskList.tsx +30 -12
  29. package/src/hooks/useInputManager.ts +27 -21
  30. package/src/index.ts +1 -1
  31. package/src/managers/inputHandlers.ts +6 -10
  32. package/src/managers/inputReducer.ts +381 -208
  33. package/src/print-cli.ts +48 -11
  34. package/src/stdio/agentBridge.ts +210 -0
  35. package/src/stdio/protocol.ts +6 -1
  36. package/src/utils/rewindCheckpoints.ts +15 -0
  37. package/src/utils/worktree.ts +99 -34
@@ -4,6 +4,7 @@ import {
4
4
  inputReducer,
5
5
  initialState,
6
6
  InputManagerCallbacks,
7
+ ESC_DOUBLE_PRESS_TIMEOUT_MS,
7
8
  } from "../managers/inputReducer.js";
8
9
  import {
9
10
  searchFiles as searchFilesUtil,
@@ -48,6 +49,7 @@ export const useInputManager = (
48
49
  onClearMessages,
49
50
  onCompact,
50
51
  onGoalCommand,
52
+ isIdle: isIdleProp,
51
53
  } = callbacks;
52
54
 
53
55
  // Handle debounced file search
@@ -70,25 +72,15 @@ export const useInputManager = (
70
72
  }
71
73
  }, [state.showFileSelector, state.fileSearchQuery]);
72
74
 
73
- // Handle paste debouncing
75
+ // Auto-expire the double-Esc clear pending flag after the timeout window
76
+ // (aligned with Claude Code's useDoublePress timeout-based expiry).
74
77
  useEffect(() => {
75
- if (state.isPasting) {
76
- const pasteDebounceDelay = parseInt(
77
- process.env.PASTE_DEBOUNCE_MS || "30",
78
- 10,
79
- );
80
- const timer = setTimeout(() => {
81
- const processedInput = state.pasteBuffer.replace(/\r/g, "\n");
82
- dispatch({
83
- type: "INSERT_TEXT_WITH_PLACEHOLDER",
84
- payload: processedInput,
85
- });
86
- dispatch({ type: "END_PASTE" });
87
- dispatch({ type: "RESET_HISTORY_NAVIGATION" });
88
- }, pasteDebounceDelay);
89
- return () => clearTimeout(timer);
90
- }
91
- }, [state.isPasting, state.pasteBuffer]);
78
+ if (!state.escClearPending) return;
79
+ const timer = setTimeout(() => {
80
+ dispatch({ type: "RESET_ESC_CLEAR_PENDING" });
81
+ }, ESC_DOUBLE_PRESS_TIMEOUT_MS);
82
+ return () => clearTimeout(timer);
83
+ }, [state.escClearPending]);
92
84
 
93
85
  // Sync state changes with callbacks
94
86
  useEffect(() => {
@@ -127,6 +119,16 @@ export const useInputManager = (
127
119
  case "ABORT_MESSAGE":
128
120
  onAbortMessage?.();
129
121
  break;
122
+ case "SAVE_PROMPT_HISTORY":
123
+ PromptHistoryManager.addEntry(
124
+ effect.content,
125
+ sessionId,
126
+ effect.longTextMap,
127
+ workdir,
128
+ ).catch((err: unknown) => {
129
+ logger?.error("Failed to save prompt history", err);
130
+ });
131
+ break;
130
132
  case "BACKGROUND_CURRENT_TASK":
131
133
  onBackgroundCurrentTask?.();
132
134
  break;
@@ -501,10 +503,11 @@ export const useInputManager = (
501
503
  key: {} as Key,
502
504
  hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
503
505
  hasQueuedMessages: hasQueuedMessagesProp ?? false,
506
+ isIdle: isIdleProp ?? false,
504
507
  },
505
508
  });
506
509
  },
507
- [onHasSlashCommand, hasQueuedMessagesProp],
510
+ [onHasSlashCommand, hasQueuedMessagesProp, isIdleProp],
508
511
  );
509
512
 
510
513
  const handleSubmit = useCallback(async () => {
@@ -515,9 +518,10 @@ export const useInputManager = (
515
518
  key: { return: true } as Key,
516
519
  hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
517
520
  hasQueuedMessages: hasQueuedMessagesProp ?? false,
521
+ isIdle: isIdleProp ?? false,
518
522
  },
519
523
  });
520
- }, [onHasSlashCommand, hasQueuedMessagesProp]);
524
+ }, [onHasSlashCommand, hasQueuedMessagesProp, isIdleProp]);
521
525
 
522
526
  const expandLongTextPlaceholders = useCallback(
523
527
  (text: string) => {
@@ -539,11 +543,12 @@ export const useInputManager = (
539
543
  key,
540
544
  hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
541
545
  hasQueuedMessages: hasQueuedMessagesProp ?? false,
546
+ isIdle: isIdleProp ?? false,
542
547
  },
543
548
  });
544
549
  return true;
545
550
  },
546
- [onHasSlashCommand, hasQueuedMessagesProp],
551
+ [onHasSlashCommand, hasQueuedMessagesProp, isIdleProp],
547
552
  );
548
553
 
549
554
  return {
@@ -572,6 +577,7 @@ export const useInputManager = (
572
577
  permissionMode: state.permissionMode,
573
578
  attachedImages: state.attachedImages,
574
579
  btwState: state.btwState,
580
+ escClearPending: state.escClearPending,
575
581
  isManagerReady: true,
576
582
 
577
583
  // Methods
package/src/index.ts CHANGED
@@ -326,7 +326,7 @@ export async function main() {
326
326
  name = generateRandomName();
327
327
  }
328
328
  const baseRef = loadMergedWaveConfig(originalCwd)?.worktree?.baseRef;
329
- worktreeSession = createWorktree(name, originalCwd, { baseRef });
329
+ worktreeSession = await createWorktree(name, originalCwd, { baseRef });
330
330
 
331
331
  // Note: the full worktree session (originalCwd etc.) is injected into the
332
332
  // agent's DI container after the agent is created in useChat.tsx. This keeps
@@ -292,17 +292,13 @@ export const handlePasteInput = (
292
292
  input: string,
293
293
  ): void => {
294
294
  const inputString = input;
295
- const isPasteOperation =
296
- inputString.length > 1 ||
297
- inputString.includes("\n") ||
298
- inputString.includes("\r");
299
-
300
- if (isPasteOperation) {
301
- // Dispatch a single action type; the reducer determines start vs append
302
- // by checking pasteBuffer, avoiding stale state issues
295
+
296
+ if (inputString.length > 1) {
297
+ // Multi-char chunk: insert immediately (\r → \n normalizes CRLF
298
+ // terminals), matching the reducer's HANDLE_KEY path.
303
299
  dispatch({
304
- type: "APPEND_PASTE_CHUNK",
305
- payload: { chunk: inputString, cursorPosition: state.cursorPosition },
300
+ type: "INSERT_TEXT_WITH_PLACEHOLDER",
301
+ payload: inputString.replace(/\r/g, "\n"),
306
302
  });
307
303
  } else {
308
304
  let char = inputString;