wave-code 0.2.0 → 0.4.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 (140) hide show
  1. package/dist/commands/plugin/disable.d.ts +2 -1
  2. package/dist/commands/plugin/disable.d.ts.map +1 -1
  3. package/dist/commands/plugin/disable.js +3 -2
  4. package/dist/commands/plugin/enable.d.ts +2 -1
  5. package/dist/commands/plugin/enable.d.ts.map +1 -1
  6. package/dist/commands/plugin/enable.js +3 -2
  7. package/dist/commands/plugin/install.d.ts +2 -1
  8. package/dist/commands/plugin/install.d.ts.map +1 -1
  9. package/dist/commands/plugin/list.d.ts.map +1 -1
  10. package/dist/commands/plugin/list.js +15 -3
  11. package/dist/commands/plugin/marketplace.d.ts +3 -0
  12. package/dist/commands/plugin/marketplace.d.ts.map +1 -1
  13. package/dist/commands/plugin/marketplace.js +15 -1
  14. package/dist/commands/plugin/uninstall.d.ts +4 -0
  15. package/dist/commands/plugin/uninstall.d.ts.map +1 -0
  16. package/dist/commands/plugin/uninstall.js +29 -0
  17. package/dist/commands/plugin/update.d.ts +4 -0
  18. package/dist/commands/plugin/update.d.ts.map +1 -0
  19. package/dist/commands/plugin/update.js +15 -0
  20. package/dist/components/ChatInterface.d.ts.map +1 -1
  21. package/dist/components/ChatInterface.js +2 -2
  22. package/dist/components/CommandSelector.d.ts.map +1 -1
  23. package/dist/components/CommandSelector.js +6 -0
  24. package/dist/components/Confirmation.js +1 -1
  25. package/dist/components/DiscoverView.d.ts +3 -0
  26. package/dist/components/DiscoverView.d.ts.map +1 -0
  27. package/dist/components/DiscoverView.js +25 -0
  28. package/dist/components/FileSelector.js +1 -1
  29. package/dist/components/HistorySearch.d.ts +8 -0
  30. package/dist/components/HistorySearch.d.ts.map +1 -0
  31. package/dist/components/HistorySearch.js +67 -0
  32. package/dist/components/InputBox.d.ts +1 -1
  33. package/dist/components/InputBox.d.ts.map +1 -1
  34. package/dist/components/InputBox.js +26 -17
  35. package/dist/components/InstalledView.d.ts +3 -0
  36. package/dist/components/InstalledView.d.ts.map +1 -0
  37. package/dist/components/InstalledView.js +30 -0
  38. package/dist/components/Markdown.d.ts.map +1 -1
  39. package/dist/components/Markdown.js +22 -9
  40. package/dist/components/MarketplaceAddForm.d.ts +3 -0
  41. package/dist/components/MarketplaceAddForm.d.ts.map +1 -0
  42. package/dist/components/MarketplaceAddForm.js +26 -0
  43. package/dist/components/MarketplaceDetail.d.ts +3 -0
  44. package/dist/components/MarketplaceDetail.d.ts.map +1 -0
  45. package/dist/components/MarketplaceDetail.js +38 -0
  46. package/dist/components/MarketplaceList.d.ts +9 -0
  47. package/dist/components/MarketplaceList.d.ts.map +1 -0
  48. package/dist/components/MarketplaceList.js +16 -0
  49. package/dist/components/MarketplaceView.d.ts +3 -0
  50. package/dist/components/MarketplaceView.d.ts.map +1 -0
  51. package/dist/components/MarketplaceView.js +28 -0
  52. package/dist/components/PluginDetail.d.ts +3 -0
  53. package/dist/components/PluginDetail.d.ts.map +1 -0
  54. package/dist/components/PluginDetail.js +63 -0
  55. package/dist/components/PluginList.d.ts +14 -0
  56. package/dist/components/PluginList.d.ts.map +1 -0
  57. package/dist/components/PluginList.js +12 -0
  58. package/dist/components/PluginManagerShell.d.ts +5 -0
  59. package/dist/components/PluginManagerShell.d.ts.map +1 -0
  60. package/dist/components/PluginManagerShell.js +89 -0
  61. package/dist/components/PluginManagerTypes.d.ts +33 -0
  62. package/dist/components/PluginManagerTypes.d.ts.map +1 -0
  63. package/dist/components/PluginManagerTypes.js +1 -0
  64. package/dist/components/RewindCommand.d.ts +9 -0
  65. package/dist/components/RewindCommand.d.ts.map +1 -0
  66. package/dist/components/RewindCommand.js +42 -0
  67. package/dist/components/SessionSelector.d.ts +11 -0
  68. package/dist/components/SessionSelector.d.ts.map +1 -0
  69. package/dist/components/SessionSelector.js +38 -0
  70. package/dist/components/SubagentBlock.d.ts.map +1 -1
  71. package/dist/components/SubagentBlock.js +20 -1
  72. package/dist/components/ToolResultDisplay.js +1 -1
  73. package/dist/contexts/PluginManagerContext.d.ts +4 -0
  74. package/dist/contexts/PluginManagerContext.d.ts.map +1 -0
  75. package/dist/contexts/PluginManagerContext.js +9 -0
  76. package/dist/contexts/useChat.d.ts +2 -0
  77. package/dist/contexts/useChat.d.ts.map +1 -1
  78. package/dist/contexts/useChat.js +21 -0
  79. package/dist/hooks/useInputManager.d.ts +6 -14
  80. package/dist/hooks/useInputManager.d.ts.map +1 -1
  81. package/dist/hooks/useInputManager.js +29 -45
  82. package/dist/hooks/usePluginManager.d.ts +3 -0
  83. package/dist/hooks/usePluginManager.d.ts.map +1 -0
  84. package/dist/hooks/usePluginManager.js +223 -0
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +150 -177
  87. package/dist/managers/InputManager.d.ts +12 -21
  88. package/dist/managers/InputManager.d.ts.map +1 -1
  89. package/dist/managers/InputManager.js +77 -108
  90. package/dist/plugin-manager-cli.d.ts +6 -0
  91. package/dist/plugin-manager-cli.d.ts.map +1 -0
  92. package/dist/plugin-manager-cli.js +12 -0
  93. package/dist/session-selector-cli.d.ts +2 -0
  94. package/dist/session-selector-cli.d.ts.map +1 -0
  95. package/dist/session-selector-cli.js +25 -0
  96. package/package.json +7 -3
  97. package/src/commands/plugin/disable.ts +7 -3
  98. package/src/commands/plugin/enable.ts +7 -3
  99. package/src/commands/plugin/install.ts +2 -1
  100. package/src/commands/plugin/list.ts +21 -3
  101. package/src/commands/plugin/marketplace.ts +17 -1
  102. package/src/commands/plugin/uninstall.ts +39 -0
  103. package/src/commands/plugin/update.ts +19 -0
  104. package/src/components/ChatInterface.tsx +2 -1
  105. package/src/components/CommandSelector.tsx +7 -0
  106. package/src/components/Confirmation.tsx +1 -1
  107. package/src/components/DiscoverView.tsx +31 -0
  108. package/src/components/FileSelector.tsx +1 -1
  109. package/src/components/HistorySearch.tsx +148 -0
  110. package/src/components/InputBox.tsx +43 -28
  111. package/src/components/InstalledView.tsx +61 -0
  112. package/src/components/Markdown.tsx +37 -26
  113. package/src/components/MarketplaceAddForm.tsx +39 -0
  114. package/src/components/MarketplaceDetail.tsx +79 -0
  115. package/src/components/MarketplaceList.tsx +52 -0
  116. package/src/components/MarketplaceView.tsx +43 -0
  117. package/src/components/PluginDetail.tsx +147 -0
  118. package/src/components/PluginList.tsx +51 -0
  119. package/src/components/PluginManagerShell.tsx +189 -0
  120. package/src/components/PluginManagerTypes.ts +47 -0
  121. package/src/components/RewindCommand.tsx +114 -0
  122. package/src/components/SessionSelector.tsx +127 -0
  123. package/src/components/SubagentBlock.tsx +29 -1
  124. package/src/components/ToolResultDisplay.tsx +2 -2
  125. package/src/contexts/PluginManagerContext.ts +15 -0
  126. package/src/contexts/useChat.tsx +26 -0
  127. package/src/hooks/useInputManager.ts +29 -61
  128. package/src/hooks/usePluginManager.ts +296 -0
  129. package/src/index.ts +241 -280
  130. package/src/managers/InputManager.ts +93 -149
  131. package/src/plugin-manager-cli.tsx +13 -0
  132. package/src/session-selector-cli.tsx +37 -0
  133. package/dist/components/BashHistorySelector.d.ts +0 -11
  134. package/dist/components/BashHistorySelector.d.ts.map +0 -1
  135. package/dist/components/BashHistorySelector.js +0 -93
  136. package/dist/hooks/usePagination.d.ts +0 -20
  137. package/dist/hooks/usePagination.d.ts.map +0 -1
  138. package/dist/hooks/usePagination.js +0 -168
  139. package/src/components/BashHistorySelector.tsx +0 -181
  140. package/src/hooks/usePagination.ts +0 -203
@@ -0,0 +1,127 @@
1
+ import React, { useState } from "react";
2
+ import { Box, Text, useInput } from "ink";
3
+ import type { SessionMetadata } from "wave-agent-sdk";
4
+
5
+ export interface SessionSelectorProps {
6
+ sessions: (SessionMetadata & { firstMessage?: string })[];
7
+ onSelect: (sessionId: string) => void;
8
+ onCancel: () => void;
9
+ }
10
+
11
+ export const SessionSelector: React.FC<SessionSelectorProps> = ({
12
+ sessions,
13
+ onSelect,
14
+ onCancel,
15
+ }) => {
16
+ const [selectedIndex, setSelectedIndex] = useState(0);
17
+
18
+ useInput((input, key) => {
19
+ if (key.return) {
20
+ if (sessions.length > 0 && selectedIndex < sessions.length) {
21
+ onSelect(sessions[selectedIndex].id);
22
+ }
23
+ return;
24
+ }
25
+
26
+ if (key.escape) {
27
+ onCancel();
28
+ return;
29
+ }
30
+
31
+ if (key.upArrow) {
32
+ setSelectedIndex(Math.max(0, selectedIndex - 1));
33
+ return;
34
+ }
35
+
36
+ if (key.downArrow) {
37
+ setSelectedIndex(Math.min(sessions.length - 1, selectedIndex + 1));
38
+ return;
39
+ }
40
+ });
41
+
42
+ if (sessions.length === 0) {
43
+ return (
44
+ <Box
45
+ flexDirection="column"
46
+ borderStyle="single"
47
+ borderColor="yellow"
48
+ borderLeft={false}
49
+ borderRight={false}
50
+ paddingX={1}
51
+ width="100%"
52
+ >
53
+ <Text color="yellow">No sessions found.</Text>
54
+ <Text dimColor>Press Escape to cancel</Text>
55
+ </Box>
56
+ );
57
+ }
58
+
59
+ const maxDisplay = 10;
60
+ const startIndex = Math.max(
61
+ 0,
62
+ Math.min(
63
+ selectedIndex - Math.floor(maxDisplay / 2),
64
+ sessions.length - maxDisplay,
65
+ ),
66
+ );
67
+ const displaySessions = sessions.slice(startIndex, startIndex + maxDisplay);
68
+
69
+ return (
70
+ <Box
71
+ flexDirection="column"
72
+ paddingX={1}
73
+ gap={1}
74
+ borderStyle="single"
75
+ borderColor="cyan"
76
+ borderLeft={false}
77
+ borderRight={false}
78
+ width="100%"
79
+ >
80
+ <Box>
81
+ <Text color="cyan" bold>
82
+ Select a session to resume
83
+ </Text>
84
+ </Box>
85
+
86
+ <Box flexDirection="column">
87
+ {displaySessions.map((session, index) => {
88
+ const actualIndex = startIndex + index;
89
+ const isSelected = actualIndex === selectedIndex;
90
+ const lastActiveAt = new Date(session.lastActiveAt).toLocaleString();
91
+
92
+ return (
93
+ <Box key={session.id} flexDirection="column" width="100%">
94
+ <Box width="100%">
95
+ <Text
96
+ color={isSelected ? "black" : "white"}
97
+ backgroundColor={isSelected ? "cyan" : undefined}
98
+ >
99
+ {isSelected ? "▶ " : " "}
100
+ {session.id} | {lastActiveAt} | {session.latestTotalTokens}{" "}
101
+ tokens
102
+ </Text>
103
+ </Box>
104
+ <Box marginLeft={4} width="100%">
105
+ <Text dimColor italic>
106
+ {session.firstMessage}
107
+ </Text>
108
+ </Box>
109
+ </Box>
110
+ );
111
+ })}
112
+ </Box>
113
+
114
+ {sessions.length > maxDisplay && (
115
+ <Box>
116
+ <Text dimColor>
117
+ ... showing {displaySessions.length} of {sessions.length} sessions
118
+ </Text>
119
+ </Box>
120
+ )}
121
+
122
+ <Box>
123
+ <Text dimColor>↑↓ navigate • Enter to select • Esc to cancel</Text>
124
+ </Box>
125
+ </Box>
126
+ );
127
+ };
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import { Box, Text } from "ink";
3
3
  import type { SubagentBlock as SubagentBlockType } from "wave-agent-sdk";
4
4
  import { useChat } from "../contexts/useChat.js";
5
+ import { Markdown } from "./Markdown.js";
5
6
 
6
7
  interface SubagentBlockProps {
7
8
  block: SubagentBlockType;
@@ -59,6 +60,26 @@ export const SubagentBlock: React.FC<SubagentBlockProps> = ({ block }) => {
59
60
 
60
61
  const { tools: lastTwoTools, totalToolCount } = getLastTwoTools();
61
62
 
63
+ // Get the last text message content if completed
64
+ const getLastTextMessage = () => {
65
+ if (block.status !== "completed") return null;
66
+
67
+ for (let i = messages.length - 1; i >= 0; i--) {
68
+ const message = messages[i];
69
+ if (message.role === "assistant") {
70
+ for (let j = message.blocks.length - 1; j >= 0; j--) {
71
+ const messageBlock = message.blocks[j];
72
+ if (messageBlock.type === "text" && messageBlock.content) {
73
+ return messageBlock.content;
74
+ }
75
+ }
76
+ }
77
+ }
78
+ return null;
79
+ };
80
+
81
+ const lastTextMessage = getLastTextMessage();
82
+
62
83
  return (
63
84
  <Box
64
85
  borderRight={false}
@@ -86,8 +107,15 @@ export const SubagentBlock: React.FC<SubagentBlockProps> = ({ block }) => {
86
107
  </Box>
87
108
  </Box>
88
109
 
110
+ {/* Last Text Message Section */}
111
+ {lastTextMessage && (
112
+ <Box marginTop={1}>
113
+ <Markdown>{lastTextMessage}</Markdown>
114
+ </Box>
115
+ )}
116
+
89
117
  {/* Tool Names Section - Vertical List */}
90
- {lastTwoTools.length > 0 && (
118
+ {block.status !== "completed" && lastTwoTools.length > 0 && (
91
119
  <Box flexDirection="column" marginTop={1} gap={1}>
92
120
  {totalToolCount > 2 && (
93
121
  <Text color="gray" dimColor>
@@ -135,8 +135,8 @@ export const ToolResultDisplay: React.FC<ToolResultDisplayProps> = ({
135
135
  </Box>
136
136
  )}
137
137
 
138
- {/* Diff display - only show after tool execution completes */}
139
- {stage === "end" && (
138
+ {/* Diff display - only show after tool execution completes and was successful */}
139
+ {stage === "end" && success && (
140
140
  <DiffDisplay toolName={name} parameters={parameters} />
141
141
  )}
142
142
  </Box>
@@ -0,0 +1,15 @@
1
+ import { createContext, useContext } from "react";
2
+ import { PluginManagerContextType } from "../components/PluginManagerTypes.js";
3
+
4
+ export const PluginManagerContext =
5
+ createContext<PluginManagerContextType | null>(null);
6
+
7
+ export const usePluginManagerContext = () => {
8
+ const context = useContext(PluginManagerContext);
9
+ if (!context) {
10
+ throw new Error(
11
+ "usePluginManagerContext must be used within a PluginManagerProvider",
12
+ );
13
+ }
14
+ return context;
15
+ };
@@ -78,6 +78,9 @@ export interface ChatContextType {
78
78
  hideConfirmation: () => void;
79
79
  handleConfirmationDecision: (decision: PermissionDecision) => void;
80
80
  handleConfirmationCancel: () => void;
81
+ // Rewind functionality
82
+ rewindId: number;
83
+ handleRewindSelect: (index: number) => Promise<void>;
81
84
  }
82
85
 
83
86
  const ChatContext = createContext<ChatContextType | null>(null);
@@ -165,6 +168,9 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
165
168
  reject: () => void;
166
169
  } | null>(null);
167
170
 
171
+ // Rewind state
172
+ const [rewindId, setRewindId] = useState(0);
173
+
168
174
  const agentRef = useRef<Agent | null>(null);
169
175
 
170
176
  // Permission confirmation methods with queue support
@@ -229,6 +235,9 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
229
235
  onPermissionModeChange: (mode) => {
230
236
  setPermissionModeState(mode);
231
237
  },
238
+ onSlashCommandsChange: (commands) => {
239
+ setSlashCommands([...commands]);
240
+ },
232
241
  };
233
242
 
234
243
  try {
@@ -473,6 +482,21 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
473
482
  hideConfirmation();
474
483
  }, [currentConfirmation, hideConfirmation]);
475
484
 
485
+ const handleRewindSelect = useCallback(async (index: number) => {
486
+ if (agentRef.current) {
487
+ try {
488
+ await agentRef.current.truncateHistory(index);
489
+
490
+ // Clear terminal screen after rewind
491
+ process.stdout.write("\x1Bc", () => {
492
+ setRewindId((prev) => prev + 1);
493
+ });
494
+ } catch (error) {
495
+ logger.error("Failed to rewind:", error);
496
+ }
497
+ }
498
+ }, []);
499
+
476
500
  // Listen for Ctrl+O hotkey to toggle collapse/expand state and ESC to cancel confirmation
477
501
  useInput((input, key) => {
478
502
  if (key.ctrl && input === "o") {
@@ -520,6 +544,8 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
520
544
  hideConfirmation,
521
545
  handleConfirmationDecision,
522
546
  handleConfirmationCancel,
547
+ rewindId,
548
+ handleRewindSelect,
523
549
  };
524
550
 
525
551
  return (
@@ -29,10 +29,9 @@ export const useInputManager = (
29
29
  query: "",
30
30
  position: -1,
31
31
  });
32
- const [bashHistorySelectorState, setBashHistorySelectorState] = useState({
32
+ const [historySearchState, setHistorySearchState] = useState({
33
33
  show: false,
34
34
  query: "",
35
- position: -1,
36
35
  });
37
36
  const [memoryTypeSelectorState, setMemoryTypeSelectorState] = useState({
38
37
  show: false,
@@ -40,6 +39,7 @@ export const useInputManager = (
40
39
  });
41
40
  const [showBashManager, setShowBashManager] = useState(false);
42
41
  const [showMcpManager, setShowMcpManager] = useState(false);
42
+ const [showRewindManager, setShowRewindManager] = useState(false);
43
43
  const [permissionMode, setPermissionModeState] =
44
44
  useState<PermissionMode>("default");
45
45
  const [attachedImages, setAttachedImages] = useState<AttachedImage[]>([]);
@@ -58,8 +58,8 @@ export const useInputManager = (
58
58
  onCommandSelectorStateChange: (show, query, position) => {
59
59
  setCommandSelectorState({ show, query, position });
60
60
  },
61
- onBashHistorySelectorStateChange: (show, query, position) => {
62
- setBashHistorySelectorState({ show, query, position });
61
+ onHistorySearchStateChange: (show, query) => {
62
+ setHistorySearchState({ show, query });
63
63
  },
64
64
  onMemoryTypeSelectorStateChange: (show, message) => {
65
65
  setMemoryTypeSelectorState({ show, message });
@@ -70,6 +70,9 @@ export const useInputManager = (
70
70
  onMcpManagerStateChange: (show) => {
71
71
  setShowMcpManager(show);
72
72
  },
73
+ onRewindManagerStateChange: (show) => {
74
+ setShowRewindManager(show);
75
+ },
73
76
  onPermissionModeChange: (mode) => {
74
77
  setPermissionModeState(mode);
75
78
  callbacks.onPermissionModeChange?.(mode);
@@ -77,6 +80,7 @@ export const useInputManager = (
77
80
  onImagesStateChange: setAttachedImages,
78
81
  onShowBashManager: () => setShowBashManager(true),
79
82
  onShowMcpManager: () => setShowMcpManager(true),
83
+ onShowRewindManager: () => setShowRewindManager(true),
80
84
  ...callbacks,
81
85
  });
82
86
 
@@ -94,8 +98,8 @@ export const useInputManager = (
94
98
  onCommandSelectorStateChange: (show, query, position) => {
95
99
  setCommandSelectorState({ show, query, position });
96
100
  },
97
- onBashHistorySelectorStateChange: (show, query, position) => {
98
- setBashHistorySelectorState({ show, query, position });
101
+ onHistorySearchStateChange: (show, query) => {
102
+ setHistorySearchState({ show, query });
99
103
  },
100
104
  onMemoryTypeSelectorStateChange: (show, message) => {
101
105
  setMemoryTypeSelectorState({ show, message });
@@ -106,6 +110,9 @@ export const useInputManager = (
106
110
  onMcpManagerStateChange: (show) => {
107
111
  setShowMcpManager(show);
108
112
  },
113
+ onRewindManagerStateChange: (show) => {
114
+ setShowRewindManager(show);
115
+ },
109
116
  onPermissionModeChange: (mode) => {
110
117
  setPermissionModeState(mode);
111
118
  callbacks.onPermissionModeChange?.(mode);
@@ -113,6 +120,7 @@ export const useInputManager = (
113
120
  onImagesStateChange: setAttachedImages,
114
121
  onShowBashManager: () => setShowBashManager(true),
115
122
  onShowMcpManager: () => setShowMcpManager(true),
123
+ onShowRewindManager: () => setShowRewindManager(true),
116
124
  ...callbacks,
117
125
  });
118
126
  }
@@ -235,37 +243,13 @@ export const useInputManager = (
235
243
  return managerRef.current?.checkForSlashDeletion(cursorPos) || false;
236
244
  }, []);
237
245
 
238
- // Bash history selector methods
239
- const activateBashHistorySelector = useCallback((position: number) => {
240
- managerRef.current?.activateBashHistorySelector(position);
241
- }, []);
242
-
243
- const handleBashHistorySelect = useCallback(
244
- (command: string) => {
245
- return (
246
- managerRef.current?.handleBashHistorySelect(command) || {
247
- newInput: inputText,
248
- newCursorPosition: cursorPosition,
249
- }
250
- );
251
- },
252
- [inputText, cursorPosition],
253
- );
254
-
255
- const handleCancelBashHistorySelect = useCallback(() => {
256
- managerRef.current?.handleCancelBashHistorySelect();
257
- }, []);
258
-
259
- const updateBashHistorySearchQuery = useCallback((query: string) => {
260
- managerRef.current?.updateBashHistorySearchQuery(query);
246
+ // History search methods
247
+ const handleHistorySearchSelect = useCallback((prompt: string) => {
248
+ managerRef.current?.handleHistorySearchSelect(prompt);
261
249
  }, []);
262
250
 
263
- const handleBashHistoryExecute = useCallback((command: string) => {
264
- return managerRef.current?.handleBashHistoryExecute(command) || command;
265
- }, []);
266
-
267
- const checkForExclamationDeletion = useCallback((cursorPos: number) => {
268
- return managerRef.current?.checkForExclamationDeletion(cursorPos) || false;
251
+ const handleCancelHistorySearch = useCallback(() => {
252
+ managerRef.current?.handleCancelHistorySearch();
269
253
  }, []);
270
254
 
271
255
  // Memory type selector methods
@@ -320,17 +304,6 @@ export const useInputManager = (
320
304
  }, []);
321
305
 
322
306
  // Complex handlers that combine multiple operations
323
- const handleBashHistoryExecuteAndSend = useCallback((command: string) => {
324
- managerRef.current?.handleBashHistoryExecuteAndSend(command);
325
- }, []);
326
-
327
- const handleBashHistoryDelete = useCallback(
328
- (command: string, workdir?: string) => {
329
- managerRef.current?.handleBashHistoryDelete(command, workdir);
330
- },
331
- [],
332
- );
333
-
334
307
  return {
335
308
  // State
336
309
  inputText,
@@ -342,13 +315,13 @@ export const useInputManager = (
342
315
  showCommandSelector: commandSelectorState.show,
343
316
  commandSearchQuery: commandSelectorState.query,
344
317
  slashPosition: commandSelectorState.position,
345
- showBashHistorySelector: bashHistorySelectorState.show,
346
- bashHistorySearchQuery: bashHistorySelectorState.query,
347
- exclamationPosition: bashHistorySelectorState.position,
318
+ showHistorySearch: historySearchState.show,
319
+ historySearchQuery: historySearchState.query,
348
320
  showMemoryTypeSelector: memoryTypeSelectorState.show,
349
321
  memoryMessage: memoryTypeSelectorState.message,
350
322
  showBashManager,
351
323
  showMcpManager,
324
+ showRewindManager,
352
325
  permissionMode,
353
326
  attachedImages,
354
327
  isManagerReady,
@@ -377,14 +350,9 @@ export const useInputManager = (
377
350
  updateCommandSearchQuery,
378
351
  checkForSlashDeletion,
379
352
 
380
- // Bash history selector
381
- activateBashHistorySelector,
382
- handleBashHistorySelect,
383
- handleCancelBashHistorySelect,
384
- updateBashHistorySearchQuery,
385
-
386
- handleBashHistoryExecute,
387
- checkForExclamationDeletion,
353
+ // History search
354
+ handleHistorySearchSelect,
355
+ handleCancelHistorySearch,
388
356
 
389
357
  // Memory type selector
390
358
  activateMemoryTypeSelector,
@@ -406,6 +374,10 @@ export const useInputManager = (
406
374
  setShowMcpManager: useCallback((show: boolean) => {
407
375
  managerRef.current?.setShowMcpManager(show);
408
376
  }, []),
377
+ setShowRewindManager: useCallback((show: boolean) => {
378
+ managerRef.current?.setShowRewindManager(show);
379
+ setShowRewindManager(show);
380
+ }, []),
409
381
  setPermissionMode: useCallback((mode: PermissionMode) => {
410
382
  setPermissionModeState(mode);
411
383
  managerRef.current?.setPermissionMode(mode);
@@ -450,10 +422,6 @@ export const useInputManager = (
450
422
  managerRef.current?.clearLongTextMap();
451
423
  }, []),
452
424
 
453
- // Complex handlers combining multiple operations
454
- handleBashHistoryExecuteAndSend,
455
- handleBashHistoryDelete,
456
-
457
425
  // Main input handler
458
426
  handleInput: useCallback(
459
427
  async (