wave-code 1.0.10 → 1.1.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 (248) hide show
  1. package/bin/wave-code.js +8 -2
  2. package/dist/bundle/wave.mjs +3231 -0
  3. package/package.json +24 -25
  4. package/src/cli.tsx +6 -1
  5. package/src/commands/update.ts +2 -7
  6. package/src/components/App.tsx +3 -7
  7. package/src/components/BtwDisplay.tsx +10 -1
  8. package/src/components/ChatInterface.tsx +21 -52
  9. package/src/components/ConfirmationDetails.tsx +144 -37
  10. package/src/components/DiffDisplay.tsx +335 -301
  11. package/src/components/InputBox.tsx +17 -2
  12. package/src/components/LoadingIndicator.tsx +16 -2
  13. package/src/components/MessageBlockItem.tsx +2 -4
  14. package/src/components/MessageList.tsx +75 -14
  15. package/src/components/ReasoningDisplay.tsx +2 -4
  16. package/src/components/SessionSelector.tsx +82 -11
  17. package/src/components/SkillsManager.tsx +312 -0
  18. package/src/components/StatusCommand.tsx +2 -9
  19. package/src/components/ToolDisplay.tsx +2 -4
  20. package/src/constants/commands.ts +6 -0
  21. package/src/contexts/useChat.tsx +245 -301
  22. package/src/daemon/commands.ts +57 -27
  23. package/src/daemon/jsonRpcClient.ts +1 -1
  24. package/src/daemon/socketClient.ts +2 -2
  25. package/src/hooks/useInputManager.ts +7 -1
  26. package/src/index.ts +57 -10
  27. package/src/managers/inputHandlers.ts +2 -0
  28. package/src/managers/inputReducer.ts +195 -104
  29. package/src/print-cli.ts +25 -17
  30. package/src/reducers/selectorReducer.ts +10 -0
  31. package/src/reducers/skillsManagerReducer.ts +91 -0
  32. package/src/session-selector-cli.tsx +269 -28
  33. package/src/stdio/agentBridge.ts +30 -21
  34. package/src/stdio/daemonServer.ts +3 -1
  35. package/src/stdio/protocol.ts +2 -0
  36. package/src/utils/clipboard.ts +21 -0
  37. package/src/utils/highlightUtils.ts +46 -1
  38. package/src/utils/readPackageJson.ts +29 -0
  39. package/src/utils/streamingText.ts +11 -0
  40. package/src/utils/worktree.ts +191 -43
  41. package/dist/cli.d.ts +0 -6
  42. package/dist/cli.js +0 -53
  43. package/dist/commands/plugin/disable.d.ts +0 -5
  44. package/dist/commands/plugin/disable.js +0 -15
  45. package/dist/commands/plugin/enable.d.ts +0 -5
  46. package/dist/commands/plugin/enable.js +0 -15
  47. package/dist/commands/plugin/install.d.ts +0 -5
  48. package/dist/commands/plugin/install.js +0 -21
  49. package/dist/commands/plugin/list.d.ts +0 -1
  50. package/dist/commands/plugin/list.js +0 -31
  51. package/dist/commands/plugin/marketplace.d.ts +0 -10
  52. package/dist/commands/plugin/marketplace.js +0 -90
  53. package/dist/commands/plugin/uninstall.d.ts +0 -3
  54. package/dist/commands/plugin/uninstall.js +0 -16
  55. package/dist/commands/plugin/update.d.ts +0 -3
  56. package/dist/commands/plugin/update.js +0 -15
  57. package/dist/commands/update.d.ts +0 -1
  58. package/dist/commands/update.js +0 -97
  59. package/dist/components/AgentsManager.d.ts +0 -7
  60. package/dist/components/AgentsManager.js +0 -109
  61. package/dist/components/App.d.ts +0 -9
  62. package/dist/components/App.js +0 -76
  63. package/dist/components/BackgroundTaskManager.d.ts +0 -5
  64. package/dist/components/BackgroundTaskManager.js +0 -99
  65. package/dist/components/BangDisplay.d.ts +0 -8
  66. package/dist/components/BangDisplay.js +0 -17
  67. package/dist/components/BtwDisplay.d.ts +0 -7
  68. package/dist/components/BtwDisplay.js +0 -19
  69. package/dist/components/ChatInterface.d.ts +0 -2
  70. package/dist/components/ChatInterface.js +0 -61
  71. package/dist/components/CommandSelector.d.ts +0 -10
  72. package/dist/components/CommandSelector.js +0 -66
  73. package/dist/components/CompactDisplay.d.ts +0 -8
  74. package/dist/components/CompactDisplay.js +0 -13
  75. package/dist/components/ConfirmationDetails.d.ts +0 -9
  76. package/dist/components/ConfirmationDetails.js +0 -45
  77. package/dist/components/ConfirmationSelector.d.ts +0 -13
  78. package/dist/components/ConfirmationSelector.js +0 -127
  79. package/dist/components/DiffDisplay.d.ts +0 -8
  80. package/dist/components/DiffDisplay.js +0 -201
  81. package/dist/components/DiscoverView.d.ts +0 -2
  82. package/dist/components/DiscoverView.js +0 -37
  83. package/dist/components/FileSelector.d.ts +0 -11
  84. package/dist/components/FileSelector.js +0 -50
  85. package/dist/components/HelpView.d.ts +0 -7
  86. package/dist/components/HelpView.js +0 -74
  87. package/dist/components/HistorySearch.d.ts +0 -8
  88. package/dist/components/HistorySearch.js +0 -66
  89. package/dist/components/InputBox.d.ts +0 -24
  90. package/dist/components/InputBox.js +0 -149
  91. package/dist/components/InstalledView.d.ts +0 -2
  92. package/dist/components/InstalledView.js +0 -45
  93. package/dist/components/LoadingIndicator.d.ts +0 -10
  94. package/dist/components/LoadingIndicator.js +0 -6
  95. package/dist/components/LoginCommand.d.ts +0 -5
  96. package/dist/components/LoginCommand.js +0 -153
  97. package/dist/components/Markdown.d.ts +0 -5
  98. package/dist/components/Markdown.js +0 -127
  99. package/dist/components/MarketplaceAddForm.d.ts +0 -2
  100. package/dist/components/MarketplaceAddForm.js +0 -55
  101. package/dist/components/MarketplaceDetail.d.ts +0 -2
  102. package/dist/components/MarketplaceDetail.js +0 -74
  103. package/dist/components/MarketplaceList.d.ts +0 -8
  104. package/dist/components/MarketplaceList.js +0 -17
  105. package/dist/components/MarketplaceView.d.ts +0 -2
  106. package/dist/components/MarketplaceView.js +0 -41
  107. package/dist/components/McpManager.d.ts +0 -9
  108. package/dist/components/McpManager.js +0 -88
  109. package/dist/components/MessageBlockItem.d.ts +0 -8
  110. package/dist/components/MessageBlockItem.js +0 -15
  111. package/dist/components/MessageList.d.ts +0 -10
  112. package/dist/components/MessageList.js +0 -80
  113. package/dist/components/ModelSelector.d.ts +0 -8
  114. package/dist/components/ModelSelector.js +0 -45
  115. package/dist/components/Notifications.d.ts +0 -7
  116. package/dist/components/Notifications.js +0 -9
  117. package/dist/components/PlanDisplay.d.ts +0 -7
  118. package/dist/components/PlanDisplay.js +0 -6
  119. package/dist/components/PluginDetail.d.ts +0 -2
  120. package/dist/components/PluginDetail.js +0 -87
  121. package/dist/components/PluginList.d.ts +0 -13
  122. package/dist/components/PluginList.js +0 -15
  123. package/dist/components/PluginManagerShell.d.ts +0 -6
  124. package/dist/components/PluginManagerShell.js +0 -92
  125. package/dist/components/PluginManagerTypes.d.ts +0 -35
  126. package/dist/components/PluginManagerTypes.js +0 -1
  127. package/dist/components/QueuedMessageList.d.ts +0 -2
  128. package/dist/components/QueuedMessageList.js +0 -18
  129. package/dist/components/ReasoningDisplay.d.ts +0 -8
  130. package/dist/components/ReasoningDisplay.js +0 -13
  131. package/dist/components/RewindCommand.d.ts +0 -12
  132. package/dist/components/RewindCommand.js +0 -78
  133. package/dist/components/SessionSelector.d.ts +0 -12
  134. package/dist/components/SessionSelector.js +0 -47
  135. package/dist/components/StatusCommand.d.ts +0 -5
  136. package/dist/components/StatusCommand.js +0 -28
  137. package/dist/components/StatusLine.d.ts +0 -6
  138. package/dist/components/StatusLine.js +0 -9
  139. package/dist/components/TaskList.d.ts +0 -5
  140. package/dist/components/TaskList.js +0 -197
  141. package/dist/components/TaskNotificationMessage.d.ts +0 -5
  142. package/dist/components/TaskNotificationMessage.js +0 -12
  143. package/dist/components/ToolDisplay.d.ts +0 -9
  144. package/dist/components/ToolDisplay.js +0 -55
  145. package/dist/components/WorkflowManager.d.ts +0 -5
  146. package/dist/components/WorkflowManager.js +0 -102
  147. package/dist/components/WorktreeExitPrompt.d.ts +0 -12
  148. package/dist/components/WorktreeExitPrompt.js +0 -35
  149. package/dist/constants/commands.d.ts +0 -2
  150. package/dist/constants/commands.js +0 -92
  151. package/dist/contexts/PluginManagerContext.d.ts +0 -3
  152. package/dist/contexts/PluginManagerContext.js +0 -9
  153. package/dist/contexts/useAppConfig.d.ts +0 -10
  154. package/dist/contexts/useAppConfig.js +0 -13
  155. package/dist/contexts/useChat.d.ts +0 -101
  156. package/dist/contexts/useChat.js +0 -993
  157. package/dist/contracts/status.d.ts +0 -7
  158. package/dist/contracts/status.js +0 -1
  159. package/dist/daemon/commands.d.ts +0 -49
  160. package/dist/daemon/commands.js +0 -341
  161. package/dist/daemon/jsonRpcClient.d.ts +0 -38
  162. package/dist/daemon/jsonRpcClient.js +0 -129
  163. package/dist/daemon/socketClient.d.ts +0 -13
  164. package/dist/daemon/socketClient.js +0 -26
  165. package/dist/daemon-cli.d.ts +0 -10
  166. package/dist/daemon-cli.js +0 -15
  167. package/dist/hooks/useInputManager.d.ts +0 -75
  168. package/dist/hooks/useInputManager.js +0 -583
  169. package/dist/hooks/usePluginManager.d.ts +0 -4
  170. package/dist/hooks/usePluginManager.js +0 -265
  171. package/dist/hooks/useTasks.d.ts +0 -1
  172. package/dist/hooks/useTasks.js +0 -5
  173. package/dist/index.d.ts +0 -4
  174. package/dist/index.js +0 -447
  175. package/dist/managers/inputHandlers.d.ts +0 -30
  176. package/dist/managers/inputHandlers.js +0 -625
  177. package/dist/managers/inputReducer.d.ts +0 -271
  178. package/dist/managers/inputReducer.js +0 -1121
  179. package/dist/plugin-manager-cli.d.ts +0 -5
  180. package/dist/plugin-manager-cli.js +0 -12
  181. package/dist/print-cli.d.ts +0 -10
  182. package/dist/print-cli.js +0 -209
  183. package/dist/reducers/agentsManagerReducer.d.ts +0 -26
  184. package/dist/reducers/agentsManagerReducer.js +0 -54
  185. package/dist/reducers/backgroundTaskManagerReducer.d.ts +0 -62
  186. package/dist/reducers/backgroundTaskManagerReducer.js +0 -106
  187. package/dist/reducers/confirmationReducer.d.ts +0 -37
  188. package/dist/reducers/confirmationReducer.js +0 -193
  189. package/dist/reducers/helpSelectorReducer.d.ts +0 -25
  190. package/dist/reducers/helpSelectorReducer.js +0 -52
  191. package/dist/reducers/marketplaceAddFormReducer.d.ts +0 -24
  192. package/dist/reducers/marketplaceAddFormReducer.js +0 -58
  193. package/dist/reducers/mcpManagerReducer.d.ts +0 -37
  194. package/dist/reducers/mcpManagerReducer.js +0 -74
  195. package/dist/reducers/pluginDetailReducer.d.ts +0 -32
  196. package/dist/reducers/pluginDetailReducer.js +0 -70
  197. package/dist/reducers/questionReducer.d.ts +0 -82
  198. package/dist/reducers/questionReducer.js +0 -375
  199. package/dist/reducers/rewindSelectorReducer.d.ts +0 -21
  200. package/dist/reducers/rewindSelectorReducer.js +0 -37
  201. package/dist/reducers/selectorReducer.d.ts +0 -23
  202. package/dist/reducers/selectorReducer.js +0 -42
  203. package/dist/reducers/workflowManagerReducer.d.ts +0 -40
  204. package/dist/reducers/workflowManagerReducer.js +0 -100
  205. package/dist/session-selector-cli.d.ts +0 -3
  206. package/dist/session-selector-cli.js +0 -25
  207. package/dist/stdio/agentBridge.d.ts +0 -139
  208. package/dist/stdio/agentBridge.js +0 -999
  209. package/dist/stdio/daemonServer.d.ts +0 -67
  210. package/dist/stdio/daemonServer.js +0 -191
  211. package/dist/stdio/index.d.ts +0 -5
  212. package/dist/stdio/index.js +0 -5
  213. package/dist/stdio/jsonRpcConnection.d.ts +0 -39
  214. package/dist/stdio/jsonRpcConnection.js +0 -135
  215. package/dist/stdio/protocol.d.ts +0 -41
  216. package/dist/stdio/protocol.js +0 -26
  217. package/dist/stdio/stdioServer.d.ts +0 -36
  218. package/dist/stdio/stdioServer.js +0 -51
  219. package/dist/stdio-cli.d.ts +0 -8
  220. package/dist/stdio-cli.js +0 -15
  221. package/dist/types.d.ts +0 -20
  222. package/dist/types.js +0 -1
  223. package/dist/utils/bracketedPaste.d.ts +0 -39
  224. package/dist/utils/bracketedPaste.js +0 -122
  225. package/dist/utils/clipboard.d.ts +0 -21
  226. package/dist/utils/clipboard.js +0 -347
  227. package/dist/utils/constants.d.ts +0 -16
  228. package/dist/utils/constants.js +0 -18
  229. package/dist/utils/highlightUtils.d.ts +0 -1
  230. package/dist/utils/highlightUtils.js +0 -93
  231. package/dist/utils/inputUtils.d.ts +0 -17
  232. package/dist/utils/inputUtils.js +0 -67
  233. package/dist/utils/logger.d.ts +0 -71
  234. package/dist/utils/logger.js +0 -259
  235. package/dist/utils/markdownTable.d.ts +0 -34
  236. package/dist/utils/markdownTable.js +0 -302
  237. package/dist/utils/rewindCheckpoints.d.ts +0 -8
  238. package/dist/utils/rewindCheckpoints.js +0 -17
  239. package/dist/utils/throttle.d.ts +0 -14
  240. package/dist/utils/throttle.js +0 -55
  241. package/dist/utils/toolParameterTransforms.d.ts +0 -18
  242. package/dist/utils/toolParameterTransforms.js +0 -73
  243. package/dist/utils/usageSummary.d.ts +0 -28
  244. package/dist/utils/usageSummary.js +0 -121
  245. package/dist/utils/version.d.ts +0 -1
  246. package/dist/utils/version.js +0 -4
  247. package/dist/utils/worktree.d.ts +0 -35
  248. package/dist/utils/worktree.js +0 -219
@@ -1,13 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useMemo } from "react";
3
- import { Box, Text } from "ink";
4
- export const CompactDisplay = ({ block }) => {
5
- const { content } = block;
6
- const { displayContent } = useMemo(() => {
7
- if (!content) {
8
- return { displayContent: "" };
9
- }
10
- return { displayContent: content };
11
- }, [content]);
12
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsx(Text, { children: "Compacted Messages" }) }), content && (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: _jsx(Text, { color: "white", children: displayContent }) }) }))] }));
13
- };
@@ -1,9 +0,0 @@
1
- import React from "react";
2
- export interface ConfirmationDetailsProps {
3
- toolName: string;
4
- toolInput?: Record<string, unknown>;
5
- planContent?: string;
6
- warning?: string;
7
- isExpanded?: boolean;
8
- }
9
- export declare const ConfirmationDetails: React.FC<ConfirmationDetailsProps>;
@@ -1,45 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { Box, Text } from "ink";
3
- import { BASH_TOOL_NAME, EDIT_TOOL_NAME, WRITE_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, ENTER_PLAN_MODE_TOOL_NAME, ASK_USER_QUESTION_TOOL_NAME, ARTIFACT_TOOL_NAME, } from "wave-agent-sdk";
4
- import { DiffDisplay } from "./DiffDisplay.js";
5
- import { PlanDisplay } from "./PlanDisplay.js";
6
- import { highlightToAnsi } from "../utils/highlightUtils.js";
7
- // Helper function to generate descriptive action text
8
- const getActionDescription = (toolName, toolInput) => {
9
- if (!toolInput) {
10
- return "Execute operation";
11
- }
12
- switch (toolName) {
13
- case BASH_TOOL_NAME:
14
- return `Execute command: ${toolInput.command || "unknown command"}`;
15
- case EDIT_TOOL_NAME:
16
- return `Edit file: ${toolInput.file_path || "unknown file"}`;
17
- case WRITE_TOOL_NAME:
18
- return `Write to file: ${toolInput.file_path || "unknown file"}`;
19
- case EXIT_PLAN_MODE_TOOL_NAME:
20
- return "Review and approve the plan";
21
- case ENTER_PLAN_MODE_TOOL_NAME:
22
- return "Enter plan mode for complex task planning";
23
- case ASK_USER_QUESTION_TOOL_NAME:
24
- return "Answer questions to clarify intent";
25
- case ARTIFACT_TOOL_NAME:
26
- return `Publish file: ${toolInput.file_path || "unknown file"}`;
27
- default:
28
- return "Execute operation";
29
- }
30
- };
31
- export const ConfirmationDetails = ({ toolName, toolInput, planContent, warning, isExpanded = false, }) => {
32
- const startLineNumber = toolInput?.startLineNumber ??
33
- (toolName === WRITE_TOOL_NAME ? 1 : undefined);
34
- const content = (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Tool: ", toolName] }), _jsx(Text, { color: "yellow", children: getActionDescription(toolName, toolInput) }), warning && _jsxs(Text, { color: "red", children: ["\u26A0 ", warning] }), _jsx(DiffDisplay, { toolName: toolName, parameters: JSON.stringify(toolInput), startLineNumber: startLineNumber }), toolName !== WRITE_TOOL_NAME &&
35
- toolName !== EDIT_TOOL_NAME &&
36
- toolName !== EXIT_PLAN_MODE_TOOL_NAME &&
37
- toolName !== ENTER_PLAN_MODE_TOOL_NAME &&
38
- toolName !== ASK_USER_QUESTION_TOOL_NAME &&
39
- toolName !== BASH_TOOL_NAME &&
40
- !!toolInput && (_jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", children: _jsx(Text, { children: highlightToAnsi(JSON.stringify(toolInput, null, 2), "json") }) })), toolName !== ASK_USER_QUESTION_TOOL_NAME &&
41
- toolName === EXIT_PLAN_MODE_TOOL_NAME &&
42
- !!planContent && (_jsx(PlanDisplay, { plan: planContent, isExpanded: isExpanded }))] }));
43
- return content;
44
- };
45
- ConfirmationDetails.displayName = "ConfirmationDetails";
@@ -1,13 +0,0 @@
1
- import React from "react";
2
- import type { PermissionDecision, PermissionMode } from "wave-agent-sdk";
3
- export interface ConfirmationSelectorProps {
4
- toolName: string;
5
- toolInput?: Record<string, unknown>;
6
- suggestedPrefix?: string;
7
- hidePersistentOption?: boolean;
8
- permissionMode?: PermissionMode;
9
- isExpanded?: boolean;
10
- onDecision: (decision: PermissionDecision) => void;
11
- onCancel: () => void;
12
- }
13
- export declare const ConfirmationSelector: React.FC<ConfirmationSelectorProps>;
@@ -1,127 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useEffect, useReducer, useRef } from "react";
3
- import { Box, Text, useInput } from "ink";
4
- import { BASH_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, ENTER_PLAN_MODE_TOOL_NAME, ASK_USER_QUESTION_TOOL_NAME, } from "wave-agent-sdk";
5
- import { confirmationReducer } from "../reducers/confirmationReducer.js";
6
- import { questionReducer } from "../reducers/questionReducer.js";
7
- import { createBracketedPasteDetector } from "../utils/bracketedPaste.js";
8
- const getHeaderColor = (header) => {
9
- const colors = ["red", "green", "blue", "magenta", "cyan"];
10
- let hash = 0;
11
- for (let i = 0; i < header.length; i++) {
12
- hash = header.charCodeAt(i) + ((hash << 5) - hash);
13
- }
14
- return colors[Math.abs(hash) % colors.length];
15
- };
16
- export const ConfirmationSelector = ({ toolName, toolInput, suggestedPrefix, hidePersistentOption, permissionMode, isExpanded = false, onDecision, onCancel, }) => {
17
- const [state, dispatch] = useReducer(confirmationReducer, {
18
- selectedOption: "allow",
19
- alternativeText: "",
20
- alternativeCursorPosition: 0,
21
- hasUserInput: false,
22
- decision: null,
23
- });
24
- const questions = toolInput?.questions || [];
25
- const [questionState, questionDispatch] = useReducer(questionReducer, {
26
- currentQuestionIndex: 0,
27
- selectedOptionIndex: 0,
28
- selectedOptionIndices: new Set(),
29
- userAnswers: {},
30
- otherText: "",
31
- otherCursorPosition: 0,
32
- savedStates: {},
33
- decision: null,
34
- });
35
- // Handle decisions from reducers
36
- useEffect(() => {
37
- if (state.decision) {
38
- onDecision(state.decision);
39
- dispatch({ type: "CLEAR_DECISION" });
40
- }
41
- }, [state.decision, onDecision]);
42
- useEffect(() => {
43
- if (questionState.decision) {
44
- onDecision(questionState.decision);
45
- questionDispatch({ type: "CLEAR_DECISION" });
46
- }
47
- }, [questionState.decision, onDecision]);
48
- const currentQuestion = questions[questionState.currentQuestionIndex];
49
- const getAutoOptionText = () => {
50
- if (toolName === EXIT_PLAN_MODE_TOOL_NAME) {
51
- return "Yes, auto-accept edits";
52
- }
53
- if (toolName === BASH_TOOL_NAME) {
54
- const command = toolInput?.command || "";
55
- if (command.trim().startsWith("mkdir")) {
56
- return "Yes, and auto-accept edits";
57
- }
58
- if (suggestedPrefix) {
59
- return `Yes, and don't ask again for: ${suggestedPrefix}`;
60
- }
61
- return "Yes, and don't ask again for this command in this workdir";
62
- }
63
- if (toolName.startsWith("mcp__")) {
64
- return `Yes, and don't ask again for: ${toolName}`;
65
- }
66
- return "Yes, and auto-accept edits";
67
- };
68
- const pasteDetectorRef = useRef(createBracketedPasteDetector());
69
- useInput((input, key) => {
70
- if (key.escape) {
71
- onCancel();
72
- return;
73
- }
74
- const result = pasteDetectorRef.current.process(input);
75
- if (result.kind === "consume") {
76
- // Content of an in-flight bracketed paste: hold it, never submit.
77
- return;
78
- }
79
- let cleanInput;
80
- if (result.kind === "paste") {
81
- cleanInput = (result.leadingInput ?? "") + result.text;
82
- }
83
- else {
84
- cleanInput = result.input;
85
- }
86
- if (toolName === ASK_USER_QUESTION_TOOL_NAME) {
87
- questionDispatch({
88
- type: "HANDLE_KEY",
89
- input: cleanInput,
90
- key,
91
- questions,
92
- });
93
- }
94
- else {
95
- dispatch({
96
- type: "HANDLE_KEY",
97
- input: cleanInput,
98
- key,
99
- toolName,
100
- toolInput,
101
- suggestedPrefix,
102
- hidePersistentOption,
103
- permissionMode,
104
- });
105
- }
106
- });
107
- const placeholderText = "Type here to tell Wave what to change";
108
- const showPlaceholder = state.selectedOption === "alternative" && !state.hasUserInput;
109
- return (_jsxs(Box, { flexDirection: "column", children: [toolName === ASK_USER_QUESTION_TOOL_NAME &&
110
- currentQuestion &&
111
- !isExpanded && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: getHeaderColor(currentQuestion.header), bold: true, children: currentQuestion.header.slice(0, 12).toUpperCase() }), _jsx(Box, { marginLeft: 1, children: _jsx(Text, { bold: true, children: currentQuestion.question }) })] }), _jsx(Box, { flexDirection: "column", children: [...currentQuestion.options, { label: "Other" }].map((option, index) => {
112
- const isSelected = questionState.selectedOptionIndex === index;
113
- const isChecked = currentQuestion.multiSelect
114
- ? questionState.selectedOptionIndices.has(index)
115
- : isSelected;
116
- const isOther = index === currentQuestion.options.length;
117
- return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "yellow" : undefined, children: [isSelected ? "> " : " ", currentQuestion.multiSelect
118
- ? isChecked
119
- ? "[x] "
120
- : "[ ] "
121
- : "", option.label, option.description ? ` - ${option.description}` : "", isOther && isSelected && (_jsxs(Text, { children: [":", " ", questionState.otherText ? (_jsxs(_Fragment, { children: [questionState.otherText.slice(0, questionState.otherCursorPosition), _jsx(Text, { backgroundColor: "white", color: "black", children: questionState.otherText[questionState.otherCursorPosition] || " " }), questionState.otherText.slice(questionState.otherCursorPosition + 1)] })) : (_jsx(Text, { color: "gray", dimColor: true, children: "[Type your answer...]" }))] }))] }) }, index));
122
- }) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Question ", questionState.currentQuestionIndex + 1, " of", " ", questions.length, " \u2022", currentQuestion.multiSelect ? " Space to toggle •" : "", " Use \u2191\u2193 or Tab to navigate \u2022 Enter to confirm"] }) })] })), toolName !== ASK_USER_QUESTION_TOOL_NAME && !isExpanded && (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Do you want to proceed?" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "allow" ? "black" : "white", backgroundColor: state.selectedOption === "allow" ? "yellow" : undefined, bold: state.selectedOption === "allow", children: [state.selectedOption === "allow" ? "> " : " ", toolName === EXIT_PLAN_MODE_TOOL_NAME
123
- ? "Yes, manually approve edits"
124
- : "Yes, proceed"] }) }, "allow-option"), !hidePersistentOption && (_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "auto" ? "black" : "white", backgroundColor: state.selectedOption === "auto" ? "yellow" : undefined, bold: state.selectedOption === "auto", children: [state.selectedOption === "auto" ? "> " : " ", getAutoOptionText()] }) }, "auto-option")), (toolName === EXIT_PLAN_MODE_TOOL_NAME ||
125
- (toolName === BASH_TOOL_NAME && permissionMode !== "plan")) && (_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "bypass" ? "black" : "white", backgroundColor: state.selectedOption === "bypass" ? "yellow" : undefined, bold: state.selectedOption === "bypass", children: [state.selectedOption === "bypass" ? "> " : " ", "Yes, and bypass permissions"] }) }, "bypass-option")), _jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "alternative" ? "black" : "white", backgroundColor: state.selectedOption === "alternative" ? "yellow" : undefined, bold: state.selectedOption === "alternative", children: [state.selectedOption === "alternative" ? "> " : " ", toolName === ENTER_PLAN_MODE_TOOL_NAME && showPlaceholder ? (_jsx(Text, { color: "gray", dimColor: true, children: "No, start implementing now" })) : showPlaceholder ? (_jsx(Text, { color: "gray", dimColor: true, children: placeholderText })) : (_jsx(Text, { children: state.alternativeText ? (_jsxs(_Fragment, { children: [state.alternativeText.slice(0, state.alternativeCursorPosition), _jsx(Text, { backgroundColor: "white", color: "black", children: state.alternativeText[state.alternativeCursorPosition] || " " }), state.alternativeText.slice(state.alternativeCursorPosition + 1)] })) : ("Type here to tell Wave what to change") }))] }) }, "alternative-option")] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 or Tab to navigate \u2022 ESC to cancel" }) })] }))] }));
126
- };
127
- ConfirmationSelector.displayName = "ConfirmationSelector";
@@ -1,8 +0,0 @@
1
- import React from "react";
2
- interface DiffDisplayProps {
3
- toolName?: string;
4
- parameters?: string;
5
- startLineNumber?: number;
6
- }
7
- export declare const DiffDisplay: React.FC<DiffDisplayProps>;
8
- export {};
@@ -1,201 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useMemo } from "react";
3
- import { Box, Text } from "ink";
4
- import { WRITE_TOOL_NAME, EDIT_TOOL_NAME } from "wave-agent-sdk";
5
- import { transformToolBlockToChanges } from "../utils/toolParameterTransforms.js";
6
- import { diffLines, diffWords } from "diff";
7
- export const DiffDisplay = ({ toolName, parameters, startLineNumber, }) => {
8
- const showDiff = toolName && [WRITE_TOOL_NAME, EDIT_TOOL_NAME].includes(toolName);
9
- // Diff detection and transformation using typed parameters
10
- const changes = useMemo(() => {
11
- if (!showDiff || !toolName || !parameters)
12
- return [];
13
- try {
14
- // Use local transformation with JSON parsing and type guards
15
- return transformToolBlockToChanges(toolName, parameters, startLineNumber);
16
- }
17
- catch (error) {
18
- console.warn("Error transforming tool block to changes:", error);
19
- return [];
20
- }
21
- }, [toolName, parameters, showDiff, startLineNumber]);
22
- // Render word-level diff between two lines of text
23
- const renderWordLevelDiff = (oldLine, newLine, keyPrefix) => {
24
- try {
25
- const changes = diffWords(oldLine, newLine);
26
- const removedParts = [];
27
- const addedParts = [];
28
- changes.forEach((part, index) => {
29
- if (part.removed) {
30
- removedParts.push(_jsx(Text, { color: "black", backgroundColor: "red", children: part.value }, `removed-${keyPrefix}-${index}`));
31
- }
32
- else if (part.added) {
33
- addedParts.push(_jsx(Text, { color: "black", backgroundColor: "green", children: part.value }, `added-${keyPrefix}-${index}`));
34
- }
35
- else {
36
- // Unchanged parts
37
- removedParts.push(_jsx(Text, { color: "red", children: part.value }, `removed-unchanged-${keyPrefix}-${index}`));
38
- addedParts.push(_jsx(Text, { color: "green", children: part.value }, `added-unchanged-${keyPrefix}-${index}`));
39
- }
40
- });
41
- return { removedParts, addedParts };
42
- }
43
- catch (error) {
44
- console.warn("Error rendering word-level diff:", error);
45
- // Fallback to simple line display
46
- return {
47
- removedParts: [
48
- _jsx(Text, { color: "red", children: oldLine }, `fallback-removed-${keyPrefix}`),
49
- ],
50
- addedParts: [
51
- _jsx(Text, { color: "green", children: newLine }, `fallback-added-${keyPrefix}`),
52
- ],
53
- };
54
- }
55
- };
56
- // Render expanded diff display
57
- const renderExpandedDiff = () => {
58
- try {
59
- if (changes.length === 0)
60
- return null;
61
- const maxLineNum = changes.reduce((max, change) => {
62
- const oldLines = (change.oldContent || "").split("\n").length;
63
- const newLines = (change.newContent || "").split("\n").length;
64
- const start = change.startLineNumber || 1;
65
- // For Edit tool, the diff might show context lines before/after the change.
66
- // The startLineNumber is the line where old_string starts.
67
- // diffLines will include context lines if they are part of the change object.
68
- // However, our transformEditParameters currently only puts old_string/new_string.
69
- // If we ever support context lines in the Change object, we need to be careful.
70
- return Math.max(max, start + oldLines, start + newLines);
71
- }, 0);
72
- const maxDigits = Math.max(2, maxLineNum.toString().length);
73
- const renderLine = (oldLineNum, newLineNum, prefix, content, color, key) => {
74
- const formatNum = (num) => num === null
75
- ? " ".repeat(maxDigits)
76
- : num.toString().padStart(maxDigits);
77
- return (_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: "gray", children: [formatNum(oldLineNum), " "] }), _jsxs(Text, { color: "gray", children: [formatNum(newLineNum), " "] }), _jsx(Text, { color: "gray", children: "| " }), _jsx(Text, { color: color, children: prefix }), _jsx(Text, { color: color, children: content })] }, key));
78
- };
79
- const allElements = [];
80
- changes.forEach((change, changeIndex) => {
81
- try {
82
- // Get line-level diff to understand the structure
83
- const lineDiffs = diffLines(change.oldContent || "", change.newContent || "");
84
- let oldLineNum = change.startLineNumber || 1;
85
- let newLineNum = change.startLineNumber || 1;
86
- // Process line diffs
87
- const diffElements = [];
88
- for (let i = 0; i < lineDiffs.length; i++) {
89
- const part = lineDiffs[i];
90
- const lines = part.value.split("\n");
91
- // diffLines might return a trailing empty string if the content ends with a newline
92
- if (lines[lines.length - 1] === "") {
93
- lines.pop();
94
- }
95
- if (part.removed) {
96
- // Look ahead for an added block
97
- if (i + 1 < lineDiffs.length && lineDiffs[i + 1].added) {
98
- const nextPart = lineDiffs[i + 1];
99
- const addedLines = nextPart.value.split("\n");
100
- if (addedLines[addedLines.length - 1] === "") {
101
- addedLines.pop();
102
- }
103
- if (lines.length === addedLines.length) {
104
- // Word-level diffing
105
- lines.forEach((line, lineIndex) => {
106
- const { removedParts, addedParts } = renderWordLevelDiff(line, addedLines[lineIndex], `word-${changeIndex}-${i}-${lineIndex}`);
107
- diffElements.push(renderLine(oldLineNum++, null, "-", removedParts, "red", `remove-${changeIndex}-${i}-${lineIndex}`));
108
- diffElements.push(renderLine(null, newLineNum++, "+", addedParts, "green", `add-${changeIndex}-${i}-${lineIndex}`));
109
- });
110
- i++; // Skip the added block
111
- continue;
112
- }
113
- }
114
- // Fallback to standard removed rendering
115
- lines.forEach((line, lineIndex) => {
116
- diffElements.push(renderLine(oldLineNum++, null, "-", line, "red", `remove-${changeIndex}-${i}-${lineIndex}`));
117
- });
118
- }
119
- else if (part.added) {
120
- lines.forEach((line, lineIndex) => {
121
- diffElements.push(renderLine(null, newLineNum++, "+", line, "green", `add-${changeIndex}-${i}-${lineIndex}`));
122
- });
123
- }
124
- else {
125
- // Context lines - show unchanged content
126
- const isFirstBlock = i === 0;
127
- const isLastBlock = i === lineDiffs.length - 1;
128
- let linesToDisplay = lines;
129
- let showEllipsisTop = false;
130
- let showEllipsisBottom = false;
131
- if (isFirstBlock && !isLastBlock) {
132
- // First block: keep last 3
133
- if (lines.length > 3) {
134
- const skipCount = lines.length - 3;
135
- oldLineNum += skipCount;
136
- newLineNum += skipCount;
137
- linesToDisplay = lines.slice(-3);
138
- showEllipsisTop = true;
139
- }
140
- }
141
- else if (isLastBlock && !isFirstBlock) {
142
- // Last block: keep first 3
143
- if (lines.length > 3) {
144
- linesToDisplay = lines.slice(0, 3);
145
- showEllipsisBottom = true;
146
- }
147
- }
148
- else if (!isFirstBlock && !isLastBlock) {
149
- // Middle block: keep first 3 and last 3
150
- if (lines.length > 6) {
151
- linesToDisplay = [...lines.slice(0, 3), ...lines.slice(-3)];
152
- showEllipsisTop = false; // We'll put ellipsis in the middle
153
- }
154
- }
155
- if (showEllipsisTop) {
156
- diffElements.push(_jsx(Box, { children: _jsxs(Text, { color: "gray", children: [" ".repeat(maxDigits * 2 + 2), "..."] }) }, `ellipsis-top-${changeIndex}-${i}`));
157
- }
158
- linesToDisplay.forEach((line, lineIndex) => {
159
- // If it's a middle block and we are at the split point
160
- if (!isFirstBlock &&
161
- !isLastBlock &&
162
- lines.length > 6 &&
163
- lineIndex === 3) {
164
- const skipCount = lines.length - 6;
165
- oldLineNum += skipCount;
166
- newLineNum += skipCount;
167
- diffElements.push(_jsx(Box, { children: _jsxs(Text, { color: "gray", children: [" ".repeat(maxDigits * 2 + 2), "..."] }) }, `ellipsis-mid-${changeIndex}-${i}`));
168
- }
169
- diffElements.push(renderLine(oldLineNum++, newLineNum++, " ", line, "white", `context-${changeIndex}-${i}-${lineIndex}`));
170
- });
171
- if (showEllipsisBottom) {
172
- const skipCount = lines.length - linesToDisplay.length;
173
- // We don't increment oldLineNum/newLineNum here because they are already incremented in the loop
174
- // But we need to account for the lines we skipped at the end of this block
175
- oldLineNum += skipCount;
176
- newLineNum += skipCount;
177
- diffElements.push(_jsx(Box, { children: _jsxs(Text, { color: "gray", children: [" ".repeat(maxDigits * 2 + 2), "..."] }) }, `ellipsis-bottom-${changeIndex}-${i}`));
178
- }
179
- }
180
- }
181
- allElements.push(...diffElements);
182
- }
183
- catch (error) {
184
- console.warn(`Error rendering diff for change ${changeIndex}:`, error);
185
- // Fallback to simple display
186
- allElements.push(_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "red", children: ["-", change.oldContent || ""] }), _jsxs(Text, { color: "green", children: ["+", change.newContent || ""] })] }, `fallback-${changeIndex}`));
187
- }
188
- });
189
- return _jsx(Box, { flexDirection: "column", children: allElements });
190
- }
191
- catch (error) {
192
- console.warn("Error rendering expanded diff:", error);
193
- return (_jsx(Box, { children: _jsx(Text, { color: "gray", children: "Error rendering diff display" }) }));
194
- }
195
- };
196
- // Don't render anything if no diff should be shown
197
- if (!showDiff) {
198
- return null;
199
- }
200
- return (_jsx(Box, { flexDirection: "column", children: _jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", flexDirection: "column", children: renderExpandedDiff() }) }));
201
- };
@@ -1,2 +0,0 @@
1
- import React from "react";
2
- export declare const DiscoverView: React.FC;
@@ -1,37 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useReducer, useEffect } from "react";
3
- import { Box, useInput } from "ink";
4
- import { usePluginManagerContext } from "../contexts/PluginManagerContext.js";
5
- import { PluginList } from "./PluginList.js";
6
- import { selectorReducer, } from "../reducers/selectorReducer.js";
7
- export const DiscoverView = () => {
8
- const { discoverablePlugins, actions } = usePluginManagerContext();
9
- const [state, dispatch] = useReducer((selectorReducer), {
10
- selectedIndex: 0,
11
- pendingDecision: null,
12
- items: [],
13
- });
14
- const { selectedIndex, pendingDecision, items } = state;
15
- // Sync plugins into reducer state
16
- useEffect(() => {
17
- dispatch({ type: "SET_ITEMS", items: discoverablePlugins });
18
- }, [discoverablePlugins]);
19
- useInput((_input, key) => {
20
- dispatch({
21
- type: "HANDLE_KEY",
22
- key,
23
- hasInsert: false,
24
- });
25
- });
26
- useEffect(() => {
27
- if (pendingDecision === "select") {
28
- const plugin = items[selectedIndex];
29
- if (plugin) {
30
- actions.setSelectedId(`${plugin.name}@${plugin.marketplace}`);
31
- actions.setView("PLUGIN_DETAIL");
32
- }
33
- dispatch({ type: "CLEAR_DECISION" });
34
- }
35
- }, [pendingDecision, selectedIndex, items, actions]);
36
- return (_jsx(Box, { flexDirection: "column", children: _jsx(PluginList, { plugins: discoverablePlugins, selectedIndex: selectedIndex }) }));
37
- };
@@ -1,11 +0,0 @@
1
- import React from "react";
2
- import type { FileItem } from "wave-agent-sdk";
3
- export { type FileItem } from "wave-agent-sdk";
4
- export interface FileSelectorProps {
5
- files: FileItem[];
6
- searchQuery: string;
7
- isLoading?: boolean;
8
- onSelect: (filePath: string) => void;
9
- onCancel: () => void;
10
- }
11
- export declare const FileSelector: React.FC<FileSelectorProps>;
@@ -1,50 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useReducer, useEffect } from "react";
3
- import { Box, Text, useInput } from "ink";
4
- import { selectorReducer, } from "../reducers/selectorReducer.js";
5
- export const FileSelector = ({ files, searchQuery, isLoading = false, onSelect, onCancel, }) => {
6
- const [state, dispatch] = useReducer((selectorReducer), {
7
- selectedIndex: 0,
8
- pendingDecision: null,
9
- items: [],
10
- });
11
- const { selectedIndex, pendingDecision, items: filesInState } = state;
12
- // Sync files from props into reducer state (SET_ITEMS also resets index)
13
- useEffect(() => {
14
- dispatch({ type: "SET_ITEMS", items: files });
15
- }, [files]);
16
- // Handle decisions from reducer
17
- useEffect(() => {
18
- if (!pendingDecision)
19
- return;
20
- if (pendingDecision === "select" || pendingDecision === "insert") {
21
- if (filesInState.length > 0 && selectedIndex < filesInState.length) {
22
- onSelect(filesInState[selectedIndex].path);
23
- }
24
- }
25
- else if (pendingDecision === "cancel") {
26
- onCancel();
27
- }
28
- dispatch({ type: "CLEAR_DECISION" });
29
- }, [pendingDecision, selectedIndex, filesInState, onSelect, onCancel]);
30
- useInput((input, key) => {
31
- dispatch({
32
- type: "HANDLE_KEY",
33
- key,
34
- hasInsert: true, // For FileSelector, Tab is also select
35
- });
36
- });
37
- if (files.length === 0) {
38
- return (_jsx(Box, { flexDirection: "column", borderStyle: "single", borderColor: isLoading ? "cyan" : "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: isLoading ? (_jsx(Text, { color: "cyan", bold: true, children: "Select File/Directory..." })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { color: "yellow", children: ["No files found for \"", searchQuery, "\""] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] })) }));
39
- }
40
- const maxDisplay = 5;
41
- // Calculate display window start and end positions
42
- const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(maxDisplay / 2), Math.max(0, files.length - maxDisplay)));
43
- const endIndex = Math.min(files.length, startIndex + maxDisplay);
44
- const displayFiles = files.slice(startIndex, endIndex);
45
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "cyan", bold: true, children: ["Select File/Directory ", searchQuery && `(filtering: "${searchQuery}")`] }) }), _jsx(Box, { flexDirection: "column", children: displayFiles.map((fileItem, displayIndex) => {
46
- const actualIndex = startIndex + displayIndex;
47
- const isSelected = actualIndex === selectedIndex;
48
- return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, children: [isSelected ? "▶ " : " ", fileItem.path] }) }, fileItem.path));
49
- }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "\u2191\u2193 navigate \u2022 Enter/Tab select \u2022 Esc cancel" }) })] }));
50
- };
@@ -1,7 +0,0 @@
1
- import React from "react";
2
- import type { SlashCommand } from "wave-agent-sdk";
3
- export interface HelpViewProps {
4
- onCancel: () => void;
5
- commands?: SlashCommand[];
6
- }
7
- export declare const HelpView: React.FC<HelpViewProps>;
@@ -1,74 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useReducer, useEffect } from "react";
3
- import { Box, Text, useInput } from "ink";
4
- import { AVAILABLE_COMMANDS } from "../constants/commands.js";
5
- import { helpSelectorReducer } from "../reducers/helpSelectorReducer.js";
6
- export const HelpView = ({ onCancel, commands = [], }) => {
7
- const MAX_VISIBLE_ITEMS = 10;
8
- const tabs = [
9
- "general",
10
- "commands",
11
- ];
12
- if (commands.length > 0) {
13
- tabs.push("custom-commands");
14
- }
15
- const [state, dispatch] = useReducer(helpSelectorReducer, {
16
- selectedIndex: 0,
17
- activeTab: "general",
18
- pendingDecision: null,
19
- });
20
- const { selectedIndex, activeTab, pendingDecision } = state;
21
- // Handle decisions from reducer
22
- useEffect(() => {
23
- if (pendingDecision === "cancel") {
24
- onCancel();
25
- dispatch({ type: "CLEAR_DECISION" });
26
- }
27
- }, [pendingDecision, onCancel]);
28
- const currentCommands = activeTab === "commands" ? AVAILABLE_COMMANDS : commands;
29
- // Calculate visible window for commands
30
- const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, currentCommands.length - MAX_VISIBLE_ITEMS)));
31
- const visibleCommands = currentCommands.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
32
- useInput((_, key) => {
33
- dispatch({
34
- type: "HANDLE_KEY",
35
- key,
36
- maxIndex: activeTab === "general" ? 0 : currentCommands.length - 1,
37
- tabs,
38
- });
39
- });
40
- const helpItems = [
41
- { key: "@", description: "Reference files" },
42
- { key: "/", description: "Commands" },
43
- { key: "!", description: "Shell commands (e.g. !ls)" },
44
- { key: "Ctrl+R", description: "Search history" },
45
- { key: "Ctrl+O", description: "Expand/collapse messages" },
46
- { key: "Ctrl+T", description: "Toggle task list" },
47
- { key: "Ctrl+B", description: "Background current task" },
48
- { key: "Ctrl+V", description: "Paste image" },
49
- { key: "Ctrl+J", description: "Newline" },
50
- { key: "Ctrl+A", description: "Cursor to line start" },
51
- { key: "Ctrl+E", description: "Cursor to line end" },
52
- { key: "Ctrl+U", description: "Delete to line start" },
53
- { key: "Ctrl+K", description: "Delete to line end" },
54
- { key: "Ctrl+W", description: "Delete word before cursor" },
55
- { key: "Shift+Tab", description: "Cycle permission mode" },
56
- {
57
- key: "Esc",
58
- description: "Interrupt AI or command / Cancel selector / Close help",
59
- },
60
- { key: "Esc ×2", description: "Clear input (idle)" },
61
- ];
62
- const footerText = [
63
- "Tab switch",
64
- activeTab !== "general" && "↑↓ navigate",
65
- "Esc close",
66
- ]
67
- .filter(Boolean)
68
- .join(" • ");
69
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderLeft: false, borderRight: false, paddingX: 1, width: "100%", children: [_jsxs(Box, { marginBottom: 1, gap: 2, children: [_jsx(Text, { color: activeTab === "general" ? "cyan" : "gray", bold: true, underline: activeTab === "general", children: "General" }), _jsx(Text, { color: activeTab === "commands" ? "cyan" : "gray", bold: true, underline: activeTab === "commands", children: "Commands" }), commands.length > 0 && (_jsx(Text, { color: activeTab === "custom-commands" ? "cyan" : "gray", bold: true, underline: activeTab === "custom-commands", children: "Custom Commands" }))] }), activeTab === "general" ? (_jsx(Box, { flexDirection: "column", children: helpItems.map((item, index) => (_jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: item.key }) }), _jsx(Text, { color: "white", children: item.description })] }, index))) })) : (_jsx(Box, { flexDirection: "column", children: visibleCommands.map((command, index) => {
70
- const actualIndex = startIndex + index;
71
- const isSelected = actualIndex === selectedIndex;
72
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, children: [isSelected ? "▶ " : " ", "/", command.id] }), isSelected && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { color: "gray", dimColor: true, children: command.description }) }))] }, command.id));
73
- }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: footerText }) })] }));
74
- };
@@ -1,8 +0,0 @@
1
- import React from "react";
2
- import { type PromptEntry } from "wave-agent-sdk";
3
- export interface HistorySearchProps {
4
- searchQuery: string;
5
- onSelect: (entry: PromptEntry) => void;
6
- onCancel: () => void;
7
- }
8
- export declare const HistorySearch: React.FC<HistorySearchProps>;