wave-code 1.0.10 → 1.1.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 (242) hide show
  1. package/bin/wave-code.js +8 -2
  2. package/dist/bundle/wave.mjs +3207 -0
  3. package/package.json +24 -25
  4. package/src/commands/update.ts +2 -7
  5. package/src/components/App.tsx +3 -7
  6. package/src/components/BtwDisplay.tsx +10 -1
  7. package/src/components/ChatInterface.tsx +21 -52
  8. package/src/components/ConfirmationDetails.tsx +144 -37
  9. package/src/components/DiffDisplay.tsx +335 -301
  10. package/src/components/InputBox.tsx +3 -1
  11. package/src/components/LoadingIndicator.tsx +16 -2
  12. package/src/components/MessageBlockItem.tsx +2 -4
  13. package/src/components/MessageList.tsx +75 -14
  14. package/src/components/ReasoningDisplay.tsx +2 -4
  15. package/src/components/SessionSelector.tsx +82 -11
  16. package/src/components/StatusCommand.tsx +2 -9
  17. package/src/components/ToolDisplay.tsx +2 -4
  18. package/src/contexts/useChat.tsx +156 -335
  19. package/src/daemon/commands.ts +57 -27
  20. package/src/daemon/jsonRpcClient.ts +1 -1
  21. package/src/daemon/socketClient.ts +2 -2
  22. package/src/hooks/useInputManager.ts +1 -1
  23. package/src/index.ts +57 -10
  24. package/src/managers/inputReducer.ts +186 -104
  25. package/src/print-cli.ts +21 -17
  26. package/src/reducers/selectorReducer.ts +10 -0
  27. package/src/session-selector-cli.tsx +269 -28
  28. package/src/stdio/agentBridge.ts +22 -21
  29. package/src/stdio/daemonServer.ts +3 -1
  30. package/src/utils/clipboard.ts +21 -0
  31. package/src/utils/highlightUtils.ts +46 -1
  32. package/src/utils/readPackageJson.ts +29 -0
  33. package/src/utils/streamingText.ts +11 -0
  34. package/src/utils/worktree.ts +191 -43
  35. package/dist/cli.d.ts +0 -6
  36. package/dist/cli.js +0 -53
  37. package/dist/commands/plugin/disable.d.ts +0 -5
  38. package/dist/commands/plugin/disable.js +0 -15
  39. package/dist/commands/plugin/enable.d.ts +0 -5
  40. package/dist/commands/plugin/enable.js +0 -15
  41. package/dist/commands/plugin/install.d.ts +0 -5
  42. package/dist/commands/plugin/install.js +0 -21
  43. package/dist/commands/plugin/list.d.ts +0 -1
  44. package/dist/commands/plugin/list.js +0 -31
  45. package/dist/commands/plugin/marketplace.d.ts +0 -10
  46. package/dist/commands/plugin/marketplace.js +0 -90
  47. package/dist/commands/plugin/uninstall.d.ts +0 -3
  48. package/dist/commands/plugin/uninstall.js +0 -16
  49. package/dist/commands/plugin/update.d.ts +0 -3
  50. package/dist/commands/plugin/update.js +0 -15
  51. package/dist/commands/update.d.ts +0 -1
  52. package/dist/commands/update.js +0 -97
  53. package/dist/components/AgentsManager.d.ts +0 -7
  54. package/dist/components/AgentsManager.js +0 -109
  55. package/dist/components/App.d.ts +0 -9
  56. package/dist/components/App.js +0 -76
  57. package/dist/components/BackgroundTaskManager.d.ts +0 -5
  58. package/dist/components/BackgroundTaskManager.js +0 -99
  59. package/dist/components/BangDisplay.d.ts +0 -8
  60. package/dist/components/BangDisplay.js +0 -17
  61. package/dist/components/BtwDisplay.d.ts +0 -7
  62. package/dist/components/BtwDisplay.js +0 -19
  63. package/dist/components/ChatInterface.d.ts +0 -2
  64. package/dist/components/ChatInterface.js +0 -61
  65. package/dist/components/CommandSelector.d.ts +0 -10
  66. package/dist/components/CommandSelector.js +0 -66
  67. package/dist/components/CompactDisplay.d.ts +0 -8
  68. package/dist/components/CompactDisplay.js +0 -13
  69. package/dist/components/ConfirmationDetails.d.ts +0 -9
  70. package/dist/components/ConfirmationDetails.js +0 -45
  71. package/dist/components/ConfirmationSelector.d.ts +0 -13
  72. package/dist/components/ConfirmationSelector.js +0 -127
  73. package/dist/components/DiffDisplay.d.ts +0 -8
  74. package/dist/components/DiffDisplay.js +0 -201
  75. package/dist/components/DiscoverView.d.ts +0 -2
  76. package/dist/components/DiscoverView.js +0 -37
  77. package/dist/components/FileSelector.d.ts +0 -11
  78. package/dist/components/FileSelector.js +0 -50
  79. package/dist/components/HelpView.d.ts +0 -7
  80. package/dist/components/HelpView.js +0 -74
  81. package/dist/components/HistorySearch.d.ts +0 -8
  82. package/dist/components/HistorySearch.js +0 -66
  83. package/dist/components/InputBox.d.ts +0 -24
  84. package/dist/components/InputBox.js +0 -149
  85. package/dist/components/InstalledView.d.ts +0 -2
  86. package/dist/components/InstalledView.js +0 -45
  87. package/dist/components/LoadingIndicator.d.ts +0 -10
  88. package/dist/components/LoadingIndicator.js +0 -6
  89. package/dist/components/LoginCommand.d.ts +0 -5
  90. package/dist/components/LoginCommand.js +0 -153
  91. package/dist/components/Markdown.d.ts +0 -5
  92. package/dist/components/Markdown.js +0 -127
  93. package/dist/components/MarketplaceAddForm.d.ts +0 -2
  94. package/dist/components/MarketplaceAddForm.js +0 -55
  95. package/dist/components/MarketplaceDetail.d.ts +0 -2
  96. package/dist/components/MarketplaceDetail.js +0 -74
  97. package/dist/components/MarketplaceList.d.ts +0 -8
  98. package/dist/components/MarketplaceList.js +0 -17
  99. package/dist/components/MarketplaceView.d.ts +0 -2
  100. package/dist/components/MarketplaceView.js +0 -41
  101. package/dist/components/McpManager.d.ts +0 -9
  102. package/dist/components/McpManager.js +0 -88
  103. package/dist/components/MessageBlockItem.d.ts +0 -8
  104. package/dist/components/MessageBlockItem.js +0 -15
  105. package/dist/components/MessageList.d.ts +0 -10
  106. package/dist/components/MessageList.js +0 -80
  107. package/dist/components/ModelSelector.d.ts +0 -8
  108. package/dist/components/ModelSelector.js +0 -45
  109. package/dist/components/Notifications.d.ts +0 -7
  110. package/dist/components/Notifications.js +0 -9
  111. package/dist/components/PlanDisplay.d.ts +0 -7
  112. package/dist/components/PlanDisplay.js +0 -6
  113. package/dist/components/PluginDetail.d.ts +0 -2
  114. package/dist/components/PluginDetail.js +0 -87
  115. package/dist/components/PluginList.d.ts +0 -13
  116. package/dist/components/PluginList.js +0 -15
  117. package/dist/components/PluginManagerShell.d.ts +0 -6
  118. package/dist/components/PluginManagerShell.js +0 -92
  119. package/dist/components/PluginManagerTypes.d.ts +0 -35
  120. package/dist/components/PluginManagerTypes.js +0 -1
  121. package/dist/components/QueuedMessageList.d.ts +0 -2
  122. package/dist/components/QueuedMessageList.js +0 -18
  123. package/dist/components/ReasoningDisplay.d.ts +0 -8
  124. package/dist/components/ReasoningDisplay.js +0 -13
  125. package/dist/components/RewindCommand.d.ts +0 -12
  126. package/dist/components/RewindCommand.js +0 -78
  127. package/dist/components/SessionSelector.d.ts +0 -12
  128. package/dist/components/SessionSelector.js +0 -47
  129. package/dist/components/StatusCommand.d.ts +0 -5
  130. package/dist/components/StatusCommand.js +0 -28
  131. package/dist/components/StatusLine.d.ts +0 -6
  132. package/dist/components/StatusLine.js +0 -9
  133. package/dist/components/TaskList.d.ts +0 -5
  134. package/dist/components/TaskList.js +0 -197
  135. package/dist/components/TaskNotificationMessage.d.ts +0 -5
  136. package/dist/components/TaskNotificationMessage.js +0 -12
  137. package/dist/components/ToolDisplay.d.ts +0 -9
  138. package/dist/components/ToolDisplay.js +0 -55
  139. package/dist/components/WorkflowManager.d.ts +0 -5
  140. package/dist/components/WorkflowManager.js +0 -102
  141. package/dist/components/WorktreeExitPrompt.d.ts +0 -12
  142. package/dist/components/WorktreeExitPrompt.js +0 -35
  143. package/dist/constants/commands.d.ts +0 -2
  144. package/dist/constants/commands.js +0 -92
  145. package/dist/contexts/PluginManagerContext.d.ts +0 -3
  146. package/dist/contexts/PluginManagerContext.js +0 -9
  147. package/dist/contexts/useAppConfig.d.ts +0 -10
  148. package/dist/contexts/useAppConfig.js +0 -13
  149. package/dist/contexts/useChat.d.ts +0 -101
  150. package/dist/contexts/useChat.js +0 -993
  151. package/dist/contracts/status.d.ts +0 -7
  152. package/dist/contracts/status.js +0 -1
  153. package/dist/daemon/commands.d.ts +0 -49
  154. package/dist/daemon/commands.js +0 -341
  155. package/dist/daemon/jsonRpcClient.d.ts +0 -38
  156. package/dist/daemon/jsonRpcClient.js +0 -129
  157. package/dist/daemon/socketClient.d.ts +0 -13
  158. package/dist/daemon/socketClient.js +0 -26
  159. package/dist/daemon-cli.d.ts +0 -10
  160. package/dist/daemon-cli.js +0 -15
  161. package/dist/hooks/useInputManager.d.ts +0 -75
  162. package/dist/hooks/useInputManager.js +0 -583
  163. package/dist/hooks/usePluginManager.d.ts +0 -4
  164. package/dist/hooks/usePluginManager.js +0 -265
  165. package/dist/hooks/useTasks.d.ts +0 -1
  166. package/dist/hooks/useTasks.js +0 -5
  167. package/dist/index.d.ts +0 -4
  168. package/dist/index.js +0 -447
  169. package/dist/managers/inputHandlers.d.ts +0 -30
  170. package/dist/managers/inputHandlers.js +0 -625
  171. package/dist/managers/inputReducer.d.ts +0 -271
  172. package/dist/managers/inputReducer.js +0 -1121
  173. package/dist/plugin-manager-cli.d.ts +0 -5
  174. package/dist/plugin-manager-cli.js +0 -12
  175. package/dist/print-cli.d.ts +0 -10
  176. package/dist/print-cli.js +0 -209
  177. package/dist/reducers/agentsManagerReducer.d.ts +0 -26
  178. package/dist/reducers/agentsManagerReducer.js +0 -54
  179. package/dist/reducers/backgroundTaskManagerReducer.d.ts +0 -62
  180. package/dist/reducers/backgroundTaskManagerReducer.js +0 -106
  181. package/dist/reducers/confirmationReducer.d.ts +0 -37
  182. package/dist/reducers/confirmationReducer.js +0 -193
  183. package/dist/reducers/helpSelectorReducer.d.ts +0 -25
  184. package/dist/reducers/helpSelectorReducer.js +0 -52
  185. package/dist/reducers/marketplaceAddFormReducer.d.ts +0 -24
  186. package/dist/reducers/marketplaceAddFormReducer.js +0 -58
  187. package/dist/reducers/mcpManagerReducer.d.ts +0 -37
  188. package/dist/reducers/mcpManagerReducer.js +0 -74
  189. package/dist/reducers/pluginDetailReducer.d.ts +0 -32
  190. package/dist/reducers/pluginDetailReducer.js +0 -70
  191. package/dist/reducers/questionReducer.d.ts +0 -82
  192. package/dist/reducers/questionReducer.js +0 -375
  193. package/dist/reducers/rewindSelectorReducer.d.ts +0 -21
  194. package/dist/reducers/rewindSelectorReducer.js +0 -37
  195. package/dist/reducers/selectorReducer.d.ts +0 -23
  196. package/dist/reducers/selectorReducer.js +0 -42
  197. package/dist/reducers/workflowManagerReducer.d.ts +0 -40
  198. package/dist/reducers/workflowManagerReducer.js +0 -100
  199. package/dist/session-selector-cli.d.ts +0 -3
  200. package/dist/session-selector-cli.js +0 -25
  201. package/dist/stdio/agentBridge.d.ts +0 -139
  202. package/dist/stdio/agentBridge.js +0 -999
  203. package/dist/stdio/daemonServer.d.ts +0 -67
  204. package/dist/stdio/daemonServer.js +0 -191
  205. package/dist/stdio/index.d.ts +0 -5
  206. package/dist/stdio/index.js +0 -5
  207. package/dist/stdio/jsonRpcConnection.d.ts +0 -39
  208. package/dist/stdio/jsonRpcConnection.js +0 -135
  209. package/dist/stdio/protocol.d.ts +0 -41
  210. package/dist/stdio/protocol.js +0 -26
  211. package/dist/stdio/stdioServer.d.ts +0 -36
  212. package/dist/stdio/stdioServer.js +0 -51
  213. package/dist/stdio-cli.d.ts +0 -8
  214. package/dist/stdio-cli.js +0 -15
  215. package/dist/types.d.ts +0 -20
  216. package/dist/types.js +0 -1
  217. package/dist/utils/bracketedPaste.d.ts +0 -39
  218. package/dist/utils/bracketedPaste.js +0 -122
  219. package/dist/utils/clipboard.d.ts +0 -21
  220. package/dist/utils/clipboard.js +0 -347
  221. package/dist/utils/constants.d.ts +0 -16
  222. package/dist/utils/constants.js +0 -18
  223. package/dist/utils/highlightUtils.d.ts +0 -1
  224. package/dist/utils/highlightUtils.js +0 -93
  225. package/dist/utils/inputUtils.d.ts +0 -17
  226. package/dist/utils/inputUtils.js +0 -67
  227. package/dist/utils/logger.d.ts +0 -71
  228. package/dist/utils/logger.js +0 -259
  229. package/dist/utils/markdownTable.d.ts +0 -34
  230. package/dist/utils/markdownTable.js +0 -302
  231. package/dist/utils/rewindCheckpoints.d.ts +0 -8
  232. package/dist/utils/rewindCheckpoints.js +0 -17
  233. package/dist/utils/throttle.d.ts +0 -14
  234. package/dist/utils/throttle.js +0 -55
  235. package/dist/utils/toolParameterTransforms.d.ts +0 -18
  236. package/dist/utils/toolParameterTransforms.js +0 -73
  237. package/dist/utils/usageSummary.d.ts +0 -28
  238. package/dist/utils/usageSummary.js +0 -121
  239. package/dist/utils/version.d.ts +0 -1
  240. package/dist/utils/version.js +0 -4
  241. package/dist/utils/worktree.d.ts +0 -35
  242. package/dist/utils/worktree.js +0 -219
@@ -1,75 +0,0 @@
1
- import { Key } from "ink";
2
- import { InputManagerCallbacks } from "../managers/inputReducer.js";
3
- import { PermissionMode, PromptEntry } from "wave-agent-sdk";
4
- export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks>) => {
5
- inputText: string;
6
- cursorPosition: number;
7
- showFileSelector: boolean;
8
- filteredFiles: import("wave-agent-sdk").FileItem[];
9
- fileSearchQuery: string;
10
- isFileSearching: boolean;
11
- atPosition: number;
12
- showCommandSelector: boolean;
13
- commandSearchQuery: string;
14
- slashPosition: number;
15
- showHistorySearch: boolean;
16
- historySearchQuery: string;
17
- showBackgroundTaskManager: boolean;
18
- showMcpManager: boolean;
19
- showAgentsManager: boolean;
20
- showRewindManager: boolean;
21
- showHelp: boolean;
22
- showStatusCommand: boolean;
23
- showLoginCommand: boolean;
24
- showPluginManager: boolean;
25
- showModelSelector: boolean;
26
- showWorkflowManager: boolean;
27
- permissionMode: PermissionMode;
28
- attachedImages: import("../managers/inputReducer.js").AttachedImage[];
29
- btwState: import("../managers/inputReducer.js").BtwState;
30
- escClearPending: boolean;
31
- isManagerReady: boolean;
32
- insertTextAtCursor: (text: string) => void;
33
- deleteCharAtCursor: () => void;
34
- clearInput: () => void;
35
- moveCursorLeft: () => void;
36
- moveCursorRight: () => void;
37
- activateFileSelector: (position: number) => void;
38
- handleFileSelect: (filePath: string) => void;
39
- handleCancelFileSelect: () => void;
40
- updateFileSearchQuery: (query: string) => void;
41
- checkForAtDeletion: (cursorPos: number) => boolean;
42
- activateCommandSelector: (position: number) => void;
43
- handleCommandSelect: (command: string) => void;
44
- handleCommandInsert: (command: string) => void;
45
- handleCancelCommandSelect: () => void;
46
- updateCommandSearchQuery: (query: string) => void;
47
- checkForSlashDeletion: (cursorPos: number) => boolean;
48
- handleHistorySearchSelect: (entry: PromptEntry) => void;
49
- handleCancelHistorySearch: () => void;
50
- processSelectorInput: (char: string) => void;
51
- setShowBackgroundTaskManager: (show: boolean) => void;
52
- setShowMcpManager: (show: boolean) => void;
53
- setShowAgentsManager: (show: boolean) => void;
54
- setShowRewindManager: (show: boolean) => void;
55
- setShowHelp: (show: boolean) => void;
56
- setShowStatusCommand: (show: boolean) => void;
57
- setShowLoginCommand: (show: boolean) => void;
58
- setShowPluginManager: (show: boolean) => void;
59
- setShowModelSelector: (show: boolean) => void;
60
- setShowWorkflowManager: (show: boolean) => void;
61
- setPermissionMode: (mode: PermissionMode) => void;
62
- setBtwState: (payload: Partial<import("../managers/inputReducer.js").BtwState>) => void;
63
- addImage: (imagePath: string, mimeType: string) => void;
64
- removeImage: (imageId: number) => void;
65
- clearImages: () => void;
66
- handlePasteImage: () => Promise<boolean>;
67
- handlePasteInput: (input: string) => void;
68
- handleSubmit: () => Promise<void>;
69
- expandLongTextPlaceholders: (text: string) => string;
70
- clearLongTextMap: () => void;
71
- handleInput: (input: string, key: Key) => Promise<boolean>;
72
- setInputText: (text: string) => void;
73
- setCursorPosition: (position: number) => void;
74
- manager: null;
75
- };
@@ -1,583 +0,0 @@
1
- import { useEffect, useReducer, useCallback, useRef } from "react";
2
- import { inputReducer, initialState, ESC_DOUBLE_PRESS_TIMEOUT_MS, btwOverlayActiveRef, } from "../managers/inputReducer.js";
3
- import { createBracketedPasteDetector } from "../utils/bracketedPaste.js";
4
- import { searchFiles as searchFilesUtil, PromptHistoryManager, } from "wave-agent-sdk";
5
- import * as handlers from "../managers/inputHandlers.js";
6
- export const useInputManager = (callbacks = {}) => {
7
- const [state, dispatch] = useReducer(inputReducer, initialState);
8
- // Detects bracketed paste (DECSET 2004) markers so pasted text is inserted
9
- // without triggering submit — a pasted trailing \r must not be treated as
10
- // Enter (see utils/bracketedPaste.ts).
11
- const pasteDetectorRef = useRef(createBracketedPasteDetector());
12
- // Abort plumbing for the /btw side question: ABORT_BTW (set when the overlay
13
- // is dismissed while loading) aborts the in-flight onAskBtw call; the
14
- // dismissed ref suppresses the late SET_BTW_STATE dispatch / error logging.
15
- const btwAbortRef = useRef(null);
16
- const btwDismissedRef = useRef(false);
17
- const { onInputTextChange, onCursorPositionChange, onFileSelectorStateChange, onCommandSelectorStateChange, onHistorySearchStateChange, onBackgroundTaskManagerStateChange, onMcpManagerStateChange, onRewindManagerStateChange, onHelpStateChange, onStatusCommandStateChange, onPluginManagerStateChange, onModelSelectorStateChange, onWorkflowManagerStateChange, onImagesStateChange, onSendMessage, onHasSlashCommand, onAbortMessage, onBackgroundCurrentTask, onPermissionModeChange, onAskBtw, sessionId, workdir, getFullMessageThread, logger, hasQueuedMessages: hasQueuedMessagesProp, onRecallQueuedMessage, onClearMessages, onCompact, onAddDir, isIdle: isIdleProp, } = callbacks;
18
- // Handle debounced file search
19
- useEffect(() => {
20
- if (state.showFileSelector) {
21
- const debounceDelay = state.fileSearchQuery === ""
22
- ? 0
23
- : parseInt(process.env.FILE_SELECTOR_DEBOUNCE_MS || "300", 10);
24
- const timer = setTimeout(async () => {
25
- try {
26
- const fileItems = await searchFilesUtil(state.fileSearchQuery);
27
- dispatch({ type: "SET_FILTERED_FILES", payload: fileItems });
28
- }
29
- catch (error) {
30
- console.error("File search error:", error);
31
- dispatch({ type: "SET_FILTERED_FILES", payload: [] });
32
- }
33
- }, debounceDelay);
34
- return () => clearTimeout(timer);
35
- }
36
- }, [state.showFileSelector, state.fileSearchQuery]);
37
- // Auto-expire the double-Esc clear pending flag after the timeout window
38
- // (aligned with Claude Code's useDoublePress timeout-based expiry).
39
- useEffect(() => {
40
- if (!state.escClearPending)
41
- return;
42
- const timer = setTimeout(() => {
43
- dispatch({ type: "RESET_ESC_CLEAR_PENDING" });
44
- }, ESC_DOUBLE_PRESS_TIMEOUT_MS);
45
- return () => clearTimeout(timer);
46
- }, [state.escClearPending]);
47
- // Sync state changes with callbacks
48
- useEffect(() => {
49
- onInputTextChange?.(state.inputText);
50
- }, [state.inputText, onInputTextChange]);
51
- useEffect(() => {
52
- onCursorPositionChange?.(state.cursorPosition);
53
- }, [state.cursorPosition, onCursorPositionChange]);
54
- // Handle pending effects
55
- useEffect(() => {
56
- if (!state.pendingEffect)
57
- return;
58
- const effect = state.pendingEffect;
59
- dispatch({ type: "CLEAR_PENDING_EFFECT" });
60
- const runEffect = async () => {
61
- try {
62
- switch (effect.type) {
63
- case "SEND_MESSAGE":
64
- await onSendMessage?.(effect.content, effect.images, effect.longTextMap);
65
- PromptHistoryManager.addEntry(effect.content, sessionId, effect.longTextMap, workdir).catch((err) => {
66
- logger?.error("Failed to save prompt history", err);
67
- });
68
- break;
69
- case "ABORT_MESSAGE":
70
- onAbortMessage?.();
71
- break;
72
- case "SAVE_PROMPT_HISTORY":
73
- PromptHistoryManager.addEntry(effect.content, sessionId, effect.longTextMap, workdir).catch((err) => {
74
- logger?.error("Failed to save prompt history", err);
75
- });
76
- break;
77
- case "BACKGROUND_CURRENT_TASK":
78
- onBackgroundCurrentTask?.();
79
- break;
80
- case "ASK_BTW": {
81
- const controller = new AbortController();
82
- btwAbortRef.current = controller;
83
- btwDismissedRef.current = false;
84
- try {
85
- const answer = await onAskBtw?.(effect.question, controller.signal, (content) => {
86
- // Stream partial answers into the overlay so the user sees
87
- // the response grow in real time (same visual language as
88
- // assistant text / thinking blocks) instead of a static
89
- // "Answering..." indicator.
90
- if (!btwDismissedRef.current) {
91
- dispatch({
92
- type: "SET_BTW_STATE",
93
- payload: { answer: content, isLoading: true },
94
- });
95
- }
96
- });
97
- if (!btwDismissedRef.current) {
98
- dispatch({
99
- type: "SET_BTW_STATE",
100
- payload: { answer, isLoading: false },
101
- });
102
- }
103
- }
104
- catch (error) {
105
- if (!btwDismissedRef.current) {
106
- console.error("Failed to ask side question:", error);
107
- dispatch({
108
- type: "SET_BTW_STATE",
109
- payload: {
110
- answer: "Error: Failed to get an answer for your side question.",
111
- isLoading: false,
112
- },
113
- });
114
- }
115
- }
116
- break;
117
- }
118
- case "ABORT_BTW":
119
- btwDismissedRef.current = true;
120
- btwAbortRef.current?.abort();
121
- btwAbortRef.current = null;
122
- break;
123
- case "PERMISSION_MODE_CHANGE":
124
- onPermissionModeChange?.(effect.mode);
125
- break;
126
- case "FETCH_HISTORY": {
127
- let sessionIds = sessionId
128
- ? [sessionId]
129
- : undefined;
130
- if (getFullMessageThread) {
131
- try {
132
- const thread = await getFullMessageThread();
133
- sessionIds = thread.sessionIds;
134
- }
135
- catch (error) {
136
- logger?.error("Failed to fetch ancestor session IDs", error);
137
- }
138
- }
139
- const history = await PromptHistoryManager.getHistory({
140
- sessionId: sessionIds,
141
- workdir: workdir,
142
- });
143
- dispatch({ type: "SET_HISTORY_ENTRIES", payload: history });
144
- dispatch({ type: "NAVIGATE_HISTORY", payload: "up" });
145
- break;
146
- }
147
- case "PASTE_IMAGE":
148
- try {
149
- await handlers.handlePasteImage(dispatch);
150
- }
151
- catch (error) {
152
- console.warn("Failed to handle paste image:", error);
153
- }
154
- break;
155
- case "EXECUTE_COMMAND":
156
- if (onSendMessage && onHasSlashCommand?.(effect.command)) {
157
- const fullCommand = `/${effect.command}`;
158
- try {
159
- await onSendMessage(fullCommand, undefined, {});
160
- }
161
- catch (error) {
162
- console.error("Failed to execute slash command:", error);
163
- }
164
- }
165
- else {
166
- // Internal command handling
167
- const command = effect.command;
168
- if (command === "tasks") {
169
- dispatch({
170
- type: "SET_SHOW_BACKGROUND_TASK_MANAGER",
171
- payload: true,
172
- });
173
- }
174
- else if (command === "mcp") {
175
- dispatch({ type: "SET_SHOW_MCP_MANAGER", payload: true });
176
- }
177
- else if (command === "agents") {
178
- dispatch({ type: "SET_SHOW_AGENTS_MANAGER", payload: true });
179
- }
180
- else if (command === "rewind") {
181
- dispatch({ type: "SET_SHOW_REWIND_MANAGER", payload: true });
182
- }
183
- else if (command === "help") {
184
- dispatch({ type: "SET_SHOW_HELP", payload: true });
185
- }
186
- else if (command === "status") {
187
- dispatch({ type: "SET_SHOW_STATUS_COMMAND", payload: true });
188
- }
189
- else if (command === "login") {
190
- dispatch({ type: "SET_SHOW_LOGIN_COMMAND", payload: true });
191
- }
192
- else if (command === "logout") {
193
- dispatch({ type: "SET_SHOW_LOGIN_COMMAND", payload: true });
194
- }
195
- else if (command === "btw") {
196
- // Bare /btw executed via the command selector — show usage
197
- // (aligned with Claude Code's empty-args message).
198
- dispatch({
199
- type: "SET_BTW_STATE",
200
- payload: {
201
- question: "",
202
- isLoading: false,
203
- answer: "Usage: /btw <your question>",
204
- },
205
- });
206
- }
207
- else if (command === "plugin") {
208
- dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: true });
209
- }
210
- else if (command === "model") {
211
- dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: true });
212
- }
213
- else if (command === "workflows") {
214
- dispatch({ type: "SET_SHOW_WORKFLOW_MANAGER", payload: true });
215
- }
216
- else if (command === "clear") {
217
- await onClearMessages?.();
218
- }
219
- else if (command === "compact") {
220
- await onCompact?.(effect.args);
221
- }
222
- else if (command === "add-dir") {
223
- await onAddDir?.(effect.args);
224
- }
225
- }
226
- break;
227
- case "RECALL_QUEUED_MESSAGE":
228
- onRecallQueuedMessage?.();
229
- break;
230
- }
231
- }
232
- catch (error) {
233
- console.error("Effect execution error:", error);
234
- }
235
- };
236
- runEffect();
237
- }, [
238
- state.pendingEffect,
239
- onSendMessage,
240
- onAbortMessage,
241
- onBackgroundCurrentTask,
242
- onAskBtw,
243
- onPermissionModeChange,
244
- sessionId,
245
- workdir,
246
- getFullMessageThread,
247
- logger,
248
- onHasSlashCommand,
249
- onRecallQueuedMessage,
250
- onClearMessages,
251
- onCompact,
252
- onAddDir,
253
- ]);
254
- useEffect(() => {
255
- onFileSelectorStateChange?.(state.showFileSelector, state.filteredFiles, state.fileSearchQuery, state.atPosition);
256
- }, [
257
- state.showFileSelector,
258
- state.filteredFiles,
259
- state.fileSearchQuery,
260
- state.atPosition,
261
- onFileSelectorStateChange,
262
- ]);
263
- useEffect(() => {
264
- onCommandSelectorStateChange?.(state.showCommandSelector, state.commandSearchQuery, state.slashPosition);
265
- }, [
266
- state.showCommandSelector,
267
- state.commandSearchQuery,
268
- state.slashPosition,
269
- onCommandSelectorStateChange,
270
- ]);
271
- useEffect(() => {
272
- onHistorySearchStateChange?.(state.showHistorySearch, state.historySearchQuery);
273
- }, [
274
- state.showHistorySearch,
275
- state.historySearchQuery,
276
- onHistorySearchStateChange,
277
- ]);
278
- useEffect(() => {
279
- onBackgroundTaskManagerStateChange?.(state.showBackgroundTaskManager);
280
- }, [state.showBackgroundTaskManager, onBackgroundTaskManagerStateChange]);
281
- useEffect(() => {
282
- onMcpManagerStateChange?.(state.showMcpManager);
283
- }, [state.showMcpManager, onMcpManagerStateChange]);
284
- useEffect(() => {
285
- onRewindManagerStateChange?.(state.showRewindManager);
286
- }, [state.showRewindManager, onRewindManagerStateChange]);
287
- useEffect(() => {
288
- onHelpStateChange?.(state.showHelp);
289
- }, [state.showHelp, onHelpStateChange]);
290
- useEffect(() => {
291
- onStatusCommandStateChange?.(state.showStatusCommand);
292
- }, [state.showStatusCommand, onStatusCommandStateChange]);
293
- useEffect(() => {
294
- onPluginManagerStateChange?.(state.showPluginManager);
295
- }, [state.showPluginManager, onPluginManagerStateChange]);
296
- useEffect(() => {
297
- onModelSelectorStateChange?.(state.showModelSelector);
298
- }, [state.showModelSelector, onModelSelectorStateChange]);
299
- useEffect(() => {
300
- onWorkflowManagerStateChange?.(state.showWorkflowManager);
301
- }, [state.showWorkflowManager, onWorkflowManagerStateChange]);
302
- useEffect(() => {
303
- onImagesStateChange?.(state.attachedImages);
304
- }, [state.attachedImages, onImagesStateChange]);
305
- // Keep the shared overlay-active flag in sync so App's Ctrl+C exit handler
306
- // can defer to the /btw overlay (ink runs ALL useInput handlers per keypress
307
- // with no propagation control).
308
- useEffect(() => {
309
- btwOverlayActiveRef.current =
310
- state.btwState.question !== "" || state.btwState.answer !== undefined;
311
- }, [state.btwState.question, state.btwState.answer]);
312
- // Methods
313
- const insertTextAtCursor = useCallback((text) => {
314
- dispatch({ type: "INSERT_TEXT", payload: text });
315
- }, []);
316
- const deleteCharAtCursor = useCallback(() => {
317
- dispatch({ type: "DELETE_CHAR" });
318
- }, []);
319
- const clearInput = useCallback(() => {
320
- dispatch({ type: "CLEAR_INPUT" });
321
- }, []);
322
- const moveCursorLeft = useCallback(() => {
323
- dispatch({ type: "MOVE_CURSOR", payload: -1 });
324
- }, []);
325
- const moveCursorRight = useCallback(() => {
326
- dispatch({ type: "MOVE_CURSOR", payload: 1 });
327
- }, []);
328
- const activateFileSelector = useCallback((position) => {
329
- dispatch({ type: "ACTIVATE_FILE_SELECTOR", payload: position });
330
- }, []);
331
- const handleFileSelect = useCallback((filePath) => {
332
- dispatch({ type: "SELECT_FILE", payload: filePath });
333
- }, []);
334
- const handleCancelFileSelect = useCallback(() => {
335
- dispatch({ type: "CANCEL_FILE_SELECTOR" });
336
- }, []);
337
- const updateFileSearchQuery = useCallback((query) => {
338
- dispatch({ type: "SET_FILE_SEARCH_QUERY", payload: query });
339
- }, []);
340
- const checkForAtDeletion = useCallback((cursorPos) => {
341
- // This is now largely handled inside HANDLE_KEY,
342
- // but kept for external calls if any.
343
- return handlers.checkForAtDeletion(state, dispatch, cursorPos);
344
- }, [state]);
345
- const activateCommandSelector = useCallback((position) => {
346
- dispatch({ type: "ACTIVATE_COMMAND_SELECTOR", payload: position });
347
- }, []);
348
- const handleCommandSelect = useCallback((command) => {
349
- dispatch({ type: "SELECT_COMMAND", payload: command });
350
- }, []);
351
- const handleCommandInsert = useCallback((command) => {
352
- dispatch({ type: "INSERT_COMMAND", payload: command });
353
- }, []);
354
- const handleCancelCommandSelect = useCallback(() => {
355
- dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
356
- }, []);
357
- const updateCommandSearchQuery = useCallback((query) => {
358
- dispatch({ type: "SET_COMMAND_SEARCH_QUERY", payload: query });
359
- }, []);
360
- const checkForSlashDeletion = useCallback((cursorPos) => {
361
- return handlers.checkForSlashDeletion(state, dispatch, cursorPos);
362
- }, [state]);
363
- const handleHistorySearchSelect = useCallback((entry) => {
364
- dispatch({ type: "SELECT_HISTORY_ENTRY", payload: entry });
365
- }, []);
366
- const handleCancelHistorySearch = useCallback(() => {
367
- dispatch({ type: "CANCEL_HISTORY_SEARCH" });
368
- }, []);
369
- const processSelectorInput = useCallback((char) => {
370
- handlers.processSelectorInput(state, dispatch, char);
371
- }, [state]);
372
- const setInputText = useCallback((text) => {
373
- dispatch({ type: "SET_INPUT_TEXT", payload: text });
374
- }, []);
375
- const setCursorPosition = useCallback((position) => {
376
- dispatch({ type: "SET_CURSOR_POSITION", payload: position });
377
- }, []);
378
- const setShowBackgroundTaskManager = useCallback((show) => {
379
- dispatch({ type: "SET_SHOW_BACKGROUND_TASK_MANAGER", payload: show });
380
- }, []);
381
- const setShowMcpManager = useCallback((show) => {
382
- dispatch({ type: "SET_SHOW_MCP_MANAGER", payload: show });
383
- }, []);
384
- const setShowAgentsManager = useCallback((show) => {
385
- dispatch({ type: "SET_SHOW_AGENTS_MANAGER", payload: show });
386
- }, []);
387
- const setShowRewindManager = useCallback((show) => {
388
- dispatch({ type: "SET_SHOW_REWIND_MANAGER", payload: show });
389
- }, []);
390
- const setShowHelp = useCallback((show) => {
391
- dispatch({ type: "SET_SHOW_HELP", payload: show });
392
- }, []);
393
- const setShowStatusCommand = useCallback((show) => {
394
- dispatch({ type: "SET_SHOW_STATUS_COMMAND", payload: show });
395
- }, []);
396
- const setShowLoginCommand = useCallback((show) => {
397
- dispatch({ type: "SET_SHOW_LOGIN_COMMAND", payload: show });
398
- }, []);
399
- const setShowPluginManager = useCallback((show) => {
400
- dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: show });
401
- }, []);
402
- const setShowModelSelector = useCallback((show) => {
403
- dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: show });
404
- }, []);
405
- const setShowWorkflowManager = useCallback((show) => {
406
- dispatch({ type: "SET_SHOW_WORKFLOW_MANAGER", payload: show });
407
- }, []);
408
- const setPermissionMode = useCallback((mode) => {
409
- dispatch({ type: "SET_PERMISSION_MODE", payload: mode });
410
- onPermissionModeChange?.(mode);
411
- }, [onPermissionModeChange]);
412
- const setBtwState = useCallback((payload) => {
413
- dispatch({ type: "SET_BTW_STATE", payload });
414
- }, []);
415
- const addImage = useCallback((imagePath, mimeType) => {
416
- dispatch({ type: "ADD_IMAGE", payload: { path: imagePath, mimeType } });
417
- }, []);
418
- const removeImage = useCallback((imageId) => {
419
- dispatch({ type: "REMOVE_IMAGE", payload: imageId });
420
- }, []);
421
- const clearImages = useCallback(() => {
422
- dispatch({ type: "CLEAR_IMAGES" });
423
- }, []);
424
- const handlePasteImage = useCallback(async () => {
425
- return await handlers.handlePasteImage(dispatch);
426
- }, []);
427
- const handlePasteInput = useCallback((input) => {
428
- dispatch({
429
- type: "HANDLE_KEY",
430
- payload: {
431
- input,
432
- key: {},
433
- hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
434
- hasQueuedMessages: hasQueuedMessagesProp ?? false,
435
- isIdle: isIdleProp ?? false,
436
- },
437
- });
438
- }, [onHasSlashCommand, hasQueuedMessagesProp, isIdleProp]);
439
- const handleSubmit = useCallback(async () => {
440
- dispatch({
441
- type: "HANDLE_KEY",
442
- payload: {
443
- input: "",
444
- key: { return: true },
445
- hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
446
- hasQueuedMessages: hasQueuedMessagesProp ?? false,
447
- isIdle: isIdleProp ?? false,
448
- },
449
- });
450
- }, [onHasSlashCommand, hasQueuedMessagesProp, isIdleProp]);
451
- const expandLongTextPlaceholders = useCallback((text) => {
452
- return handlers.expandLongTextPlaceholders(text, state.longTextMap);
453
- }, [state.longTextMap]);
454
- const clearLongTextMap = useCallback(() => {
455
- dispatch({ type: "CLEAR_LONG_TEXT_MAP" });
456
- }, []);
457
- const handleInput = useCallback(async (input, key) => {
458
- const result = pasteDetectorRef.current.process(input);
459
- if (result.kind === "consume") {
460
- // Content of an in-flight bracketed paste (or an empty paste):
461
- // hold it, never submit or insert prematurely.
462
- return true;
463
- }
464
- if (result.kind === "paste") {
465
- if (result.leadingInput) {
466
- dispatch({
467
- type: "HANDLE_KEY",
468
- payload: {
469
- input: result.leadingInput,
470
- key,
471
- hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
472
- hasQueuedMessages: hasQueuedMessagesProp ?? false,
473
- isIdle: isIdleProp ?? false,
474
- },
475
- });
476
- }
477
- if (result.text !== "") {
478
- // Insert-only: \r → \n normalizes CRLF terminals, matching the
479
- // canonical paste path (inputHandlers.handlePasteInput).
480
- dispatch({
481
- type: "INSERT_TEXT_WITH_PLACEHOLDER",
482
- payload: result.text.replace(/\r/g, "\n"),
483
- });
484
- }
485
- return true;
486
- }
487
- dispatch({
488
- type: "HANDLE_KEY",
489
- payload: {
490
- input: result.input,
491
- key,
492
- hasSlashCommand: (cmd) => !!onHasSlashCommand?.(cmd),
493
- hasQueuedMessages: hasQueuedMessagesProp ?? false,
494
- isIdle: isIdleProp ?? false,
495
- },
496
- });
497
- return true;
498
- }, [onHasSlashCommand, hasQueuedMessagesProp, isIdleProp]);
499
- return {
500
- // State
501
- inputText: state.inputText,
502
- cursorPosition: state.cursorPosition,
503
- showFileSelector: state.showFileSelector,
504
- filteredFiles: state.filteredFiles,
505
- fileSearchQuery: state.fileSearchQuery,
506
- isFileSearching: state.isFileSearching,
507
- atPosition: state.atPosition,
508
- showCommandSelector: state.showCommandSelector,
509
- commandSearchQuery: state.commandSearchQuery,
510
- slashPosition: state.slashPosition,
511
- showHistorySearch: state.showHistorySearch,
512
- historySearchQuery: state.historySearchQuery,
513
- showBackgroundTaskManager: state.showBackgroundTaskManager,
514
- showMcpManager: state.showMcpManager,
515
- showAgentsManager: state.showAgentsManager,
516
- showRewindManager: state.showRewindManager,
517
- showHelp: state.showHelp,
518
- showStatusCommand: state.showStatusCommand,
519
- showLoginCommand: state.showLoginCommand,
520
- showPluginManager: state.showPluginManager,
521
- showModelSelector: state.showModelSelector,
522
- showWorkflowManager: state.showWorkflowManager,
523
- permissionMode: state.permissionMode,
524
- attachedImages: state.attachedImages,
525
- btwState: state.btwState,
526
- escClearPending: state.escClearPending,
527
- isManagerReady: true,
528
- // Methods
529
- insertTextAtCursor,
530
- deleteCharAtCursor,
531
- clearInput,
532
- moveCursorLeft,
533
- moveCursorRight,
534
- // File selector
535
- activateFileSelector,
536
- handleFileSelect,
537
- handleCancelFileSelect,
538
- updateFileSearchQuery,
539
- checkForAtDeletion,
540
- // Command selector
541
- activateCommandSelector,
542
- handleCommandSelect,
543
- handleCommandInsert,
544
- handleCancelCommandSelect,
545
- updateCommandSearchQuery,
546
- checkForSlashDeletion,
547
- // History search
548
- handleHistorySearchSelect,
549
- handleCancelHistorySearch,
550
- // Special handling
551
- processSelectorInput,
552
- // Bash/MCP Manager
553
- setShowBackgroundTaskManager,
554
- setShowMcpManager,
555
- setShowAgentsManager,
556
- setShowRewindManager,
557
- setShowHelp,
558
- setShowStatusCommand,
559
- setShowLoginCommand,
560
- setShowPluginManager,
561
- setShowModelSelector,
562
- setShowWorkflowManager,
563
- setPermissionMode,
564
- setBtwState,
565
- // Image management
566
- addImage,
567
- removeImage,
568
- clearImages,
569
- handlePasteImage,
570
- // Paste and text handling
571
- handlePasteInput,
572
- handleSubmit,
573
- expandLongTextPlaceholders,
574
- clearLongTextMap,
575
- // Main input handler
576
- handleInput,
577
- // Direct state setters
578
- setInputText,
579
- setCursorPosition,
580
- // Manager reference (for compatibility, though it's null now)
581
- manager: null,
582
- };
583
- };
@@ -1,4 +0,0 @@
1
- import { PluginManagerContextType } from "../components/PluginManagerTypes.js";
2
- export declare function usePluginManager(options?: {
3
- onPluginInstalled?: () => void;
4
- }): PluginManagerContextType;