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,66 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { useReducer, useEffect } from "react";
3
- import { Box, Text, useInput } from "ink";
4
- import { PromptHistoryManager } from "wave-agent-sdk";
5
- import { selectorReducer, } from "../reducers/selectorReducer.js";
6
- export const HistorySearch = ({ searchQuery, onSelect, onCancel, }) => {
7
- const MAX_VISIBLE_ITEMS = 5;
8
- const [state, dispatch] = useReducer((selectorReducer), {
9
- selectedIndex: 0,
10
- pendingDecision: null,
11
- items: [],
12
- });
13
- const { selectedIndex, pendingDecision, items: entries } = state;
14
- useEffect(() => {
15
- const fetchHistory = async () => {
16
- const results = await PromptHistoryManager.searchHistory(searchQuery);
17
- dispatch({ type: "SET_ITEMS", items: results.slice(0, 20) });
18
- };
19
- fetchHistory();
20
- }, [searchQuery]);
21
- // Handle decisions from reducer
22
- useEffect(() => {
23
- if (!pendingDecision)
24
- return;
25
- if (pendingDecision === "select") {
26
- if (entries.length > 0 && selectedIndex < entries.length) {
27
- onSelect(entries[selectedIndex]);
28
- }
29
- }
30
- else if (pendingDecision === "cancel") {
31
- onCancel();
32
- }
33
- dispatch({ type: "CLEAR_DECISION" });
34
- }, [pendingDecision, selectedIndex, entries, onSelect, onCancel]);
35
- useInput((input, key) => {
36
- dispatch({ type: "HANDLE_KEY", key, hasInsert: false });
37
- });
38
- if (entries.length === 0) {
39
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "yellow", children: ["No history found ", searchQuery && `for "${searchQuery}"`] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
40
- }
41
- const formatTimestamp = (timestamp) => {
42
- const date = new Date(timestamp);
43
- const now = new Date();
44
- const diffMs = now.getTime() - date.getTime();
45
- const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
46
- const diffDays = Math.floor(diffHours / 24);
47
- if (diffDays > 0) {
48
- return `${diffDays}d ago`;
49
- }
50
- else if (diffHours > 0) {
51
- return `${diffHours}h ago`;
52
- }
53
- else {
54
- const diffMinutes = Math.floor(diffMs / (1000 * 60));
55
- return diffMinutes > 0 ? `${diffMinutes}m ago` : "just now";
56
- }
57
- };
58
- // Calculate visible window
59
- const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, entries.length - MAX_VISIBLE_ITEMS)));
60
- const visibleEntries = entries.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
61
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "blue", borderBottom: false, borderLeft: false, borderRight: false, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "blue", bold: true, children: ["Prompt History ", searchQuery && `(filtering: "${searchQuery}")`] }) }), _jsx(Box, { flexDirection: "column", children: visibleEntries.map((entry, index) => {
62
- const actualIndex = startIndex + index;
63
- const isSelected = actualIndex === selectedIndex;
64
- return (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", children: [_jsx(Box, { flexShrink: 1, children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "blue" : undefined, wrap: "truncate-end", children: [isSelected ? "> " : " ", entry.prompt.replace(/\n/g, " ")] }) }), isSelected && (_jsx(Box, { marginLeft: 2, flexShrink: 0, children: _jsx(Text, { color: "gray", dimColor: true, children: formatTimestamp(entry.timestamp) }) }))] }, actualIndex));
65
- }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate, Enter to select, Escape to cancel" }) })] }));
66
- };
@@ -1,24 +0,0 @@
1
- import React from "react";
2
- import type { McpServerStatus, SlashCommand } from "wave-agent-sdk";
3
- export declare const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
4
- export declare const INPUT_PLACEHOLDER_TEXT_PREFIX: string;
5
- export interface InputBoxProps {
6
- isLoading?: boolean;
7
- isCommandRunning?: boolean;
8
- isCompacting?: boolean;
9
- workdir?: string;
10
- sendMessage?: (message: string, images?: Array<{
11
- path: string;
12
- mimeType: string;
13
- }>, longTextMap?: Record<string, string>) => void;
14
- abortMessage?: () => void;
15
- mcpServers?: McpServerStatus[];
16
- connectMcpServer?: (serverName: string) => Promise<boolean>;
17
- disconnectMcpServer?: (serverName: string) => Promise<boolean>;
18
- slashCommands?: SlashCommand[];
19
- hasSlashCommand?: (commandId: string) => boolean;
20
- latestTotalTokens?: number;
21
- maxInputTokens?: number;
22
- showLoginHint?: boolean;
23
- }
24
- export declare const InputBox: React.FC<InputBoxProps>;
@@ -1,149 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useCallback } from "react";
3
- import { Box, Text } from "ink";
4
- import { useInput } from "ink";
5
- import { FileSelector } from "./FileSelector.js";
6
- import { CommandSelector } from "./CommandSelector.js";
7
- import { HistorySearch } from "./HistorySearch.js";
8
- import { BackgroundTaskManager } from "./BackgroundTaskManager.js";
9
- import { McpManager } from "./McpManager.js";
10
- import { AgentsManager } from "./AgentsManager.js";
11
- import { RewindCommand } from "./RewindCommand.js";
12
- import { HelpView } from "./HelpView.js";
13
- import { StatusCommand } from "./StatusCommand.js";
14
- import { LoginCommand } from "./LoginCommand.js";
15
- import { PluginManagerShell } from "./PluginManagerShell.js";
16
- import { ModelSelector } from "./ModelSelector.js";
17
- import { WorkflowManager } from "./WorkflowManager.js";
18
- import { StatusLine } from "./StatusLine.js";
19
- import { Notifications } from "./Notifications.js";
20
- import { BtwDisplay } from "./BtwDisplay.js";
21
- import { useInputManager } from "../hooks/useInputManager.js";
22
- import { useChat } from "../contexts/useChat.js";
23
- export const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
24
- export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
25
- export const InputBox = ({ isLoading, isCommandRunning, isCompacting, sendMessage = () => { }, abortMessage = () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, latestTotalTokens = 0, maxInputTokens = 200000, showLoginHint = false, }) => {
26
- const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, sessionId, workingDirectory, askBtw, clearMessages, compact, addDir, currentModel, configuredModels, setModel, recreateAgent, recallQueuedMessage, queuedMessages, setIsBtwActive, agentDefinitions, } = useChat();
27
- // Ref to hold setInputText so queue callbacks can access it before useInputManager returns
28
- const setInputTextRef = useRef(() => { });
29
- const hasQueuedMessages = (queuedMessages?.length ?? 0) > 0;
30
- // Idle means no AI work in flight. Esc double-press clear only applies when
31
- // idle; while busy, Esc keeps its abort semantics.
32
- const isIdle = !(isLoading || isCommandRunning || isCompacting);
33
- const onRecallQueuedMessage = useCallback(() => {
34
- const msg = recallQueuedMessage();
35
- if (msg) {
36
- const prefix = msg.type === "bang" ? "!" : "";
37
- setInputTextRef.current(prefix + msg.content);
38
- }
39
- }, [recallQueuedMessage]);
40
- // Input manager with all input state and functionality (including images)
41
- const { inputText, cursorPosition,
42
- // File selector
43
- showFileSelector, filteredFiles, fileSearchQuery: searchQuery, isFileSearching, handleFileSelect, handleCancelFileSelect,
44
- // Command selector
45
- showCommandSelector, commandSearchQuery, handleCommandSelect, handleCommandInsert, handleCancelCommandSelect, handleHistorySearchSelect, handleCancelHistorySearch,
46
- // History search
47
- showHistorySearch, historySearchQuery,
48
- // Task/MCP Manager
49
- showBackgroundTaskManager, showMcpManager, showAgentsManager, showRewindManager, showHelp, showStatusCommand, showLoginCommand, showPluginManager, showModelSelector, showWorkflowManager, setShowBackgroundTaskManager, setShowMcpManager, setShowAgentsManager, setShowRewindManager, setShowHelp, setShowStatusCommand, setShowLoginCommand, setShowPluginManager, setShowModelSelector, setShowWorkflowManager,
50
- // Permission mode
51
- permissionMode, setPermissionMode,
52
- // BTW state
53
- btwState,
54
- // Esc double-press clear pending
55
- escClearPending,
56
- // Main handler
57
- handleInput,
58
- // Manager ready state
59
- isManagerReady,
60
- // Direct state setters
61
- setInputText, } = useInputManager({
62
- onSendMessage: sendMessage,
63
- onAskBtw: askBtw,
64
- onClearMessages: clearMessages,
65
- onCompact: compact,
66
- onAddDir: addDir,
67
- onHasSlashCommand: hasSlashCommand,
68
- onAbortMessage: abortMessage,
69
- onBackgroundCurrentTask: backgroundCurrentTask,
70
- onPermissionModeChange: setChatPermissionMode,
71
- sessionId,
72
- workdir: workingDirectory,
73
- getFullMessageThread,
74
- hasQueuedMessages,
75
- isIdle,
76
- onRecallQueuedMessage,
77
- });
78
- // Keep setInputText ref updated for queue callbacks
79
- useEffect(() => {
80
- setInputTextRef.current = setInputText;
81
- }, [setInputText]);
82
- // Sync the btw overlay's visibility to ChatContext so siblings (TaskList)
83
- // can hide while the side-question is on display (aligned with Claude Code,
84
- // which suppresses the expanded task list while a local-jsx command shows).
85
- useEffect(() => {
86
- setIsBtwActive(btwState.question !== "" || btwState.answer !== undefined);
87
- }, [btwState.question, btwState.answer, setIsBtwActive]);
88
- // Sync permission mode from useChat to InputManager
89
- useEffect(() => {
90
- setPermissionMode(chatPermissionMode);
91
- }, [chatPermissionMode, setPermissionMode]);
92
- // Use the InputManager's unified input handler
93
- useInput(async (input, key) => {
94
- // These views have their own useInput handlers that handle escape and navigation.
95
- // If they are active, we should skip InputBox's global input handling to avoid
96
- // duplicate dispatches or state update conflicts.
97
- if (showRewindManager ||
98
- showHelp ||
99
- showStatusCommand ||
100
- showLoginCommand ||
101
- showPluginManager ||
102
- showModelSelector ||
103
- showBackgroundTaskManager ||
104
- showMcpManager ||
105
- showAgentsManager ||
106
- showWorkflowManager) {
107
- return;
108
- }
109
- await handleInput(input, key);
110
- });
111
- const handleRewindCancel = () => {
112
- if (setShowRewindManager) {
113
- setShowRewindManager(false);
114
- }
115
- };
116
- const isPlaceholder = !inputText;
117
- const placeholderText = INPUT_PLACEHOLDER_TEXT;
118
- const isShellCommand = inputText?.startsWith("!") && !inputText.includes("\n");
119
- // handleCommandSelectorInsert is already memoized in useInputManager, no need to wrap again
120
- // Split text into three parts: before cursor, cursor position, after cursor
121
- const displayText = isPlaceholder ? placeholderText : inputText;
122
- const beforeCursor = displayText.substring(0, cursorPosition);
123
- const atCursor = cursorPosition < displayText.length ? displayText[cursorPosition] : " ";
124
- const afterCursor = displayText.substring(cursorPosition + 1);
125
- // Always show cursor, allow user to continue input during memory mode
126
- const shouldShowCursor = true;
127
- // Only show the Box after InputManager is created on first mount
128
- if (!isManagerReady) {
129
- return null;
130
- }
131
- const handleRewindSelectWithClose = async (index) => {
132
- if (setShowRewindManager) {
133
- setShowRewindManager(false);
134
- }
135
- await handleRewindSelect(index);
136
- };
137
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(BtwDisplay, { btwState: btwState }), showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, isLoading: isFileSearching, onSelect: handleFileSelect, onCancel: handleCancelFileSelect })), showCommandSelector && (_jsx(CommandSelector, { searchQuery: commandSearchQuery, onSelect: handleCommandSelect, onInsert: handleCommandInsert, onCancel: handleCancelCommandSelect, commands: slashCommands })), showHistorySearch && (_jsx(HistorySearch, { searchQuery: historySearchQuery, onSelect: handleHistorySearchSelect, onCancel: handleCancelHistorySearch })), showBackgroundTaskManager && (_jsx(BackgroundTaskManager, { onCancel: () => setShowBackgroundTaskManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showAgentsManager && (_jsx(AgentsManager, { onCancel: () => setShowAgentsManager(false), agentDefinitions: agentDefinitions })), showWorkflowManager && (_jsx(WorkflowManager, { onCancel: () => setShowWorkflowManager(false) })), showRewindManager && (_jsx(RewindCommand, { messages: messages, onSelect: handleRewindSelectWithClose, onCancel: handleRewindCancel, getFullMessageThread: getFullMessageThread })), showHelp && (_jsx(HelpView, { onCancel: () => setShowHelp(false), commands: slashCommands })), showStatusCommand && (_jsx(StatusCommand, { onCancel: () => setShowStatusCommand(false) })), showLoginCommand && (_jsx(LoginCommand, { onCancel: () => setShowLoginCommand(false) })), showPluginManager && (_jsx(PluginManagerShell, { onCancel: () => setShowPluginManager(false), onPluginInstalled: recreateAgent })), showModelSelector && (_jsx(ModelSelector, { onCancel: () => setShowModelSelector(false), currentModel: currentModel, configuredModels: configuredModels, onSelectModel: setModel })), btwState.question || btwState.answer
138
- ? null
139
- : showBackgroundTaskManager ||
140
- showMcpManager ||
141
- showAgentsManager ||
142
- showRewindManager ||
143
- showHelp ||
144
- showStatusCommand ||
145
- showLoginCommand ||
146
- showPluginManager ||
147
- showModelSelector ||
148
- showWorkflowManager || (_jsxs(Box, { flexDirection: "column", children: [escClearPending && _jsx(Text, { color: "gray", children: "\u518D\u6B21\u6309 Esc \u6E05\u7A7A\u8F93\u5165" }), _jsx(Box, { borderStyle: "single", borderColor: "gray", borderLeft: false, borderRight: false, children: _jsx(Text, { color: isPlaceholder ? "gray" : "white", children: shouldShowCursor ? (_jsxs(_Fragment, { children: [beforeCursor, _jsx(Text, { backgroundColor: "white", color: "black", children: atCursor }), afterCursor] })) : (displayText) }) }), _jsxs(Box, { justifyContent: "space-between", children: [_jsx(StatusLine, { permissionMode: permissionMode, isShellCommand: isShellCommand }), _jsx(Notifications, { latestTotalTokens: latestTotalTokens, maxInputTokens: maxInputTokens, showLoginHint: showLoginHint })] })] }))] }));
149
- };
@@ -1,2 +0,0 @@
1
- import React from "react";
2
- export declare const InstalledView: React.FC;
@@ -1,45 +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 { usePluginManagerContext } from "../contexts/PluginManagerContext.js";
5
- import { selectorReducer, } from "../reducers/selectorReducer.js";
6
- export const InstalledView = () => {
7
- const { installedPlugins, actions } = usePluginManagerContext();
8
- const [state, dispatch] = useReducer((selectorReducer), {
9
- selectedIndex: 0,
10
- pendingDecision: null,
11
- items: [],
12
- });
13
- const { selectedIndex, pendingDecision, items } = state;
14
- // Sync plugins into reducer state
15
- useEffect(() => {
16
- dispatch({ type: "SET_ITEMS", items: installedPlugins });
17
- }, [installedPlugins]);
18
- useInput((_input, key) => {
19
- dispatch({
20
- type: "HANDLE_KEY",
21
- key,
22
- hasInsert: false,
23
- });
24
- });
25
- useEffect(() => {
26
- if (pendingDecision === "select") {
27
- const plugin = items[selectedIndex];
28
- if (plugin) {
29
- actions.setSelectedId(`${plugin.name}@${plugin.marketplace}`);
30
- actions.setView("PLUGIN_DETAIL");
31
- }
32
- dispatch({ type: "CLEAR_DECISION" });
33
- }
34
- }, [pendingDecision, selectedIndex, items, actions]);
35
- if (installedPlugins.length === 0) {
36
- return (_jsx(Box, { padding: 1, children: _jsx(Text, { dimColor: true, children: "No plugins installed." }) }));
37
- }
38
- const MAX_VISIBLE_ITEMS = 3;
39
- const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, installedPlugins.length - MAX_VISIBLE_ITEMS)));
40
- const visiblePlugins = installedPlugins.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
41
- return (_jsx(Box, { flexDirection: "column", children: visiblePlugins.map((plugin, index) => {
42
- const isSelected = index + startIndex === selectedIndex;
43
- return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "cyan" : undefined, children: [isSelected ? "> " : " ", _jsx(Text, { bold: true, children: plugin.name }), _jsxs(Text, { dimColor: true, children: [" @", plugin.marketplace] }), plugin.scope && _jsxs(Text, { color: "gray", children: [" (", plugin.scope, ")"] })] }) }), isSelected && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { dimColor: true, children: "Press Enter for actions" }) }))] }, `${plugin.name}@${plugin.marketplace}`));
44
- }) }));
45
- };
@@ -1,10 +0,0 @@
1
- export interface LoadingIndicatorProps {
2
- isLoading?: boolean;
3
- isCommandRunning?: boolean;
4
- isCompacting?: boolean;
5
- latestTotalTokens?: number;
6
- }
7
- export declare const LoadingIndicator: {
8
- ({ isLoading, isCommandRunning, isCompacting, latestTotalTokens, }: LoadingIndicatorProps): import("react/jsx-runtime").JSX.Element;
9
- displayName: string;
10
- };
@@ -1,6 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Box, Text } from "ink";
3
- export const LoadingIndicator = ({ isLoading = false, isCommandRunning = false, isCompacting = false, latestTotalTokens = 0, }) => {
4
- return (_jsxs(Box, { flexDirection: "column", children: [isLoading && !isCompacting && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "\u273B AI is thinking... " }), latestTotalTokens > 0 && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: "gray", dimColor: true, children: ["|", " "] }), _jsx(Text, { color: "blue", bold: true, children: latestTotalTokens.toLocaleString() }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "tokens", " "] })] })), _jsxs(Text, { color: "gray", dimColor: true, children: ["|", " "] }), _jsx(Text, { color: "red", bold: true, children: "Esc" }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "to abort"] })] })), isCommandRunning && _jsx(Text, { color: "blue", children: "\u273B Command is running..." }), isCompacting && (_jsx(Text, { color: "magenta", children: "\u273B Compacting message history..." }))] }));
5
- };
6
- LoadingIndicator.displayName = "LoadingIndicator";
@@ -1,5 +0,0 @@
1
- import React from "react";
2
- export interface LoginCommandProps {
3
- onCancel: () => void;
4
- }
5
- export declare const LoginCommand: React.FC<LoginCommandProps>;
@@ -1,153 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useRef, useState } from "react";
3
- import { Box, Text, useInput } from "ink";
4
- import { execFile } from "child_process";
5
- import { promisify } from "util";
6
- import { authService } from "wave-agent-sdk";
7
- import { createBracketedPasteDetector } from "../utils/bracketedPaste.js";
8
- const execFileAsync = promisify(execFile);
9
- function openBrowser(url) {
10
- const platform = process.platform;
11
- if (platform === "darwin") {
12
- execFileAsync("open", [url]).catch(() => { });
13
- }
14
- else if (platform === "win32") {
15
- execFileAsync("cmd", ["/c", "start", "", url]).catch(() => { });
16
- }
17
- else {
18
- execFileAsync("xdg-open", [url]).catch(() => { });
19
- }
20
- // Failures are ignored — URL is still displayed in the UI for manual copy
21
- }
22
- export const LoginCommand = ({ onCancel }) => {
23
- const [isLoading, setIsLoading] = useState(false);
24
- const [message, setMessage] = useState("");
25
- const [error, setError] = useState("");
26
- const [authUrl, setAuthUrl] = useState("");
27
- const [tokenInput, setTokenInput] = useState("");
28
- const isLoadingRef = useRef(isLoading);
29
- isLoadingRef.current = isLoading;
30
- // Detects and strips bracketed paste markers (\x1b[200~ ... \x1b[201~)
31
- // that terminals wrap pasted text in. Unlike the main InputBox pipeline,
32
- // this overlay's token input goes through raw ink useInput, which only
33
- // strips ONE leading ESC, leaving the markers (e.g. "[200~") in the input.
34
- const pasteDetectorRef = useRef(createBracketedPasteDetector());
35
- // Resolve/reject refs for the token promise
36
- const tokenResolveRef = useRef(null);
37
- const tokenRejectRef = useRef(null);
38
- // Single useInput handler — branches on isLoading to avoid the
39
- // isActive transition race that drops stdin between hook swaps.
40
- useInput((input, key) => {
41
- if (!isLoadingRef.current) {
42
- // Pre-loading mode: Enter starts login, Esc cancels
43
- if (key.escape) {
44
- onCancel();
45
- }
46
- if (key.return) {
47
- handleEnter();
48
- }
49
- return;
50
- }
51
- // Token input mode: capture keystrokes while loading
52
- if (key.escape) {
53
- tokenRejectRef.current?.(new Error("cancelled"));
54
- onCancel();
55
- }
56
- if (key.return) {
57
- // Submit token
58
- const trimmed = tokenInput.trim();
59
- if (trimmed) {
60
- tokenResolveRef.current?.(trimmed);
61
- }
62
- else {
63
- // Empty: just clear, keep waiting
64
- setTokenInput("");
65
- }
66
- return;
67
- }
68
- // Backspace
69
- if (key.backspace && tokenInput.length > 0) {
70
- setTokenInput((prev) => prev.slice(0, -1));
71
- return;
72
- }
73
- // Regular character input (single or pasted multi-char). Run through the
74
- // bracketed paste detector: a pasted token arrives wrapped in
75
- // \x1b[200~ ... \x1b[201~ markers (possibly split across chunks), which
76
- // must be stripped instead of being appended to the token.
77
- if (input && !key.ctrl && !key.meta && !key.return && input.length > 0) {
78
- const result = pasteDetectorRef.current.process(input);
79
- if (result.kind === "consume") {
80
- // In-flight bracketed paste content: hold it; the final chunk
81
- // delivers the complete text.
82
- return;
83
- }
84
- if (result.kind === "paste") {
85
- // Tokens never contain carriage returns — drop \r (CRLF terminals
86
- // send \r, not \n, in pasted text).
87
- const leading = result.leadingInput?.replace(/\r/g, "");
88
- if (leading) {
89
- setTokenInput((prev) => prev + leading);
90
- }
91
- const text = result.text.replace(/\r/g, "");
92
- if (text) {
93
- setTokenInput((prev) => prev + text);
94
- }
95
- return;
96
- }
97
- setTokenInput((prev) => prev + result.input);
98
- }
99
- });
100
- const handleEnter = async () => {
101
- if (isLoadingRef.current)
102
- return;
103
- // A stale-but-present SSO token still counts as logged in; it refreshes
104
- // lazily on the next API call. Enter toggles logout only when a token exists.
105
- const isAuthenticated = Boolean(authService.getSSOToken());
106
- if (isAuthenticated) {
107
- await authService.clearAuth();
108
- setMessage("Logged out successfully");
109
- return;
110
- }
111
- setIsLoading(true);
112
- setError("");
113
- setAuthUrl("");
114
- setTokenInput("");
115
- pasteDetectorRef.current.reset();
116
- setMessage("Starting authentication...");
117
- // Promise that resolves when user presses Enter with token input
118
- const readToken = () => new Promise((resolve, reject) => {
119
- tokenResolveRef.current = resolve;
120
- tokenRejectRef.current = reject;
121
- });
122
- try {
123
- await authService.login({
124
- onAuthUrl: (url) => {
125
- setAuthUrl(url);
126
- openBrowser(url);
127
- setMessage("Paste the authorization code from your browser URL bar:");
128
- },
129
- readToken,
130
- });
131
- setMessage("Login successful");
132
- }
133
- catch (err) {
134
- const errMessage = err.message;
135
- if (errMessage !== "cancelled") {
136
- setError(errMessage);
137
- }
138
- }
139
- finally {
140
- tokenResolveRef.current = null;
141
- tokenRejectRef.current = null;
142
- setTokenInput("");
143
- setIsLoading(false);
144
- }
145
- };
146
- const isAuthenticated = Boolean(authService.getSSOToken());
147
- const token = authService.getSSOToken();
148
- const serverUrl = authService.getServerUrl();
149
- const truncatedToken = token && token.length > 14
150
- ? `${token.substring(0, 10)}...${token.substring(token.length - 4)}`
151
- : (token ?? "");
152
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", borderLeft: false, borderRight: false, paddingX: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "cyan", bold: true, underline: true, children: "SSO Authentication" }) }), error && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "red", children: error }) })), message && !error && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: isLoading ? "yellow" : "green", children: [isLoading ? "⌛ " : "", message] }) })), authUrl && isLoading && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: "cyan", children: "Open this URL in your browser:" }), _jsx(Text, { color: "white", children: authUrl })] })), isLoading && (_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "cyan", children: "Code: " }), _jsx(Text, { color: "white", children: tokenInput || "..." })] })), !isAuthenticated && !isLoading && (_jsxs(_Fragment, { children: [_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "Status:" }), _jsx(Text, { color: "white", children: " Not logged in" })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Enter to login" }) })] })), isAuthenticated && !isLoading && !message && (_jsxs(_Fragment, { children: [_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "Status:" }), _jsx(Text, { color: "green", children: " Authenticated" })] }), _jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "Token:" }), _jsxs(Text, { color: "white", children: [" ", truncatedToken] })] }), serverUrl && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "Server URL:" }), _jsxs(Text, { color: "white", children: [" ", serverUrl] })] })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Enter to logout" }) })] })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Esc to cancel" }) })] }));
153
- };
@@ -1,5 +0,0 @@
1
- import React from "react";
2
- export interface MarkdownProps {
3
- children: string;
4
- }
5
- export declare const Markdown: React.MemoExoticComponent<({ children }: MarkdownProps) => import("react/jsx-runtime").JSX.Element>;
@@ -1,127 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import React, { useMemo } from "react";
3
- import { Box, Text, useStdout } from "ink";
4
- import { Renderer, marked } from "marked";
5
- import chalk from "chalk";
6
- import { highlightToAnsi } from "../utils/highlightUtils.js";
7
- import { renderMarkdownTable } from "../utils/markdownTable.js";
8
- const unescapeHtml = (html) => {
9
- return html
10
- .replace(/&amp;/g, "&")
11
- .replace(/&lt;/g, "<")
12
- .replace(/&gt;/g, ">")
13
- .replace(/&quot;/g, '"')
14
- .replace(/&#39;/g, "'")
15
- .replace(/&apos;/g, "'");
16
- };
17
- class AnsiRenderer extends Renderer {
18
- constructor(columns) {
19
- super();
20
- this.columns = columns;
21
- }
22
- code({ text, lang }) {
23
- const prefix = lang ? `\`\`\`${lang}` : "```";
24
- const suffix = "```";
25
- const highlighted = highlightToAnsi(text, lang);
26
- return `\n${chalk.gray(prefix)}\n${highlighted}\n${chalk.gray(suffix)}\n`;
27
- }
28
- blockquote({ tokens }) {
29
- const body = this.parser.parse(tokens);
30
- return ("\n" +
31
- body
32
- .trim()
33
- .split("\n")
34
- .map((line) => chalk.gray("> ") + line)
35
- .join("\n") +
36
- "\n");
37
- }
38
- heading({ tokens, depth }) {
39
- const text = this.parser.parseInline(tokens);
40
- const hashes = "#".repeat(depth);
41
- return `\n${chalk.cyan(`${hashes} ${text}`)}\n`;
42
- }
43
- hr() {
44
- return `\n${chalk.gray("─".repeat(20))}\n`;
45
- }
46
- list(token) {
47
- const body = token.items
48
- .map((item, i) => {
49
- const text = this.listitem(item);
50
- const prefix = token.ordered
51
- ? chalk.gray(`${(token.start || 1) + i}. `)
52
- : chalk.gray("• ");
53
- const lines = text.split("\n");
54
- const firstLine = prefix + lines[0];
55
- const restLines = lines
56
- .slice(1)
57
- .filter((line) => line.length > 0)
58
- .map((line) => " " + line);
59
- return [firstLine, ...restLines].join("\n") + "\n";
60
- })
61
- .join("");
62
- return `\n${body}`;
63
- }
64
- listitem(item) {
65
- return `${this.parser.parse(item.tokens).trim()}\n`;
66
- }
67
- checkbox({ checked }) {
68
- return checked ? chalk.green("[x] ") : chalk.gray("[ ] ");
69
- }
70
- paragraph({ tokens }) {
71
- const text = this.parser.parseInline(tokens);
72
- return `\n${text}\n`;
73
- }
74
- table(token) {
75
- const table = renderMarkdownTable(token, this.columns, (tokens) => this.parser.parseInline(tokens));
76
- return `\n${table}\n`;
77
- }
78
- strong({ tokens }) {
79
- const text = this.parser.parseInline(tokens);
80
- return chalk.bold(text);
81
- }
82
- em({ tokens }) {
83
- const text = this.parser.parseInline(tokens);
84
- return chalk.italic(text);
85
- }
86
- codespan({ text }) {
87
- return chalk.yellow(text);
88
- }
89
- br() {
90
- return "\n";
91
- }
92
- del({ tokens }) {
93
- const text = this.parser.parseInline(tokens);
94
- return chalk.strikethrough(text);
95
- }
96
- link({ href, tokens }) {
97
- const text = this.parser.parseInline(tokens);
98
- const linkText = chalk.blue.underline(text);
99
- const hrefText = chalk.gray(`(${href})`);
100
- return `${linkText} ${hrefText}`;
101
- }
102
- image({ href, tokens, text }) {
103
- const alt = this.parser.parseInline(tokens) || text;
104
- return chalk.gray(`![${alt}](${href})`);
105
- }
106
- text(token) {
107
- return "tokens" in token && token.tokens
108
- ? this.parser.parseInline(token.tokens)
109
- : unescapeHtml(token.text);
110
- }
111
- }
112
- const createRenderer = (columns) => new AnsiRenderer(columns);
113
- // Markdown component using custom ANSI renderer
114
- export const Markdown = React.memo(({ children }) => {
115
- const { stdout } = useStdout();
116
- const columns = stdout?.columns ?? 80;
117
- const ansiContent = useMemo(() => {
118
- return marked.parse(children, {
119
- renderer: createRenderer(columns),
120
- gfm: true,
121
- breaks: true,
122
- });
123
- }, [children, columns]);
124
- return (_jsx(Box, { flexDirection: "column", children: _jsx(Text, { children: ansiContent.trim() }) }));
125
- });
126
- // Add display name for debugging
127
- Markdown.displayName = "Markdown";
@@ -1,2 +0,0 @@
1
- import React from "react";
2
- export declare const MarketplaceAddForm: React.FC;