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,97 +0,0 @@
1
- import { spawnSync } from "child_process";
2
- import { readFileSync } from "fs";
3
- import path from "path";
4
- import { fileURLToPath } from "url";
5
- import https from "https";
6
- import chalk from "chalk";
7
- import { isUpdateAvailable } from "../utils/version.js";
8
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
- const packageJsonPath = path.resolve(__dirname, "../../package.json");
10
- const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
11
- const currentVersion = packageJson.version;
12
- async function getLatestVersion() {
13
- return new Promise((resolve, reject) => {
14
- https
15
- .get("https://registry.npmjs.org/wave-code/latest", (res) => {
16
- let data = "";
17
- res.on("data", (chunk) => {
18
- data += chunk;
19
- });
20
- res.on("end", () => {
21
- try {
22
- const json = JSON.parse(data);
23
- resolve(json.version);
24
- }
25
- catch {
26
- reject(new Error("Failed to parse npm registry response"));
27
- }
28
- });
29
- })
30
- .on("error", (err) => {
31
- reject(err);
32
- });
33
- });
34
- }
35
- function detectPackageManager() {
36
- // Check if wave-code is installed globally with pnpm
37
- const pnpmList = spawnSync("pnpm", ["list", "-g", "wave-code"], {
38
- encoding: "utf-8",
39
- });
40
- if (pnpmList.status === 0 && pnpmList.stdout?.includes("wave-code")) {
41
- return "pnpm";
42
- }
43
- // Check if wave-code is installed globally with yarn
44
- const yarnList = spawnSync("yarn", ["global", "list"], { encoding: "utf-8" });
45
- if (yarnList.status === 0 && yarnList.stdout?.includes("wave-code")) {
46
- return "yarn";
47
- }
48
- // Default to npm
49
- return "npm";
50
- }
51
- export async function updateCommand() {
52
- console.log(chalk.blue(`Checking for updates...`));
53
- console.log(chalk.dim(`Current version: ${currentVersion}`));
54
- try {
55
- const latestVersion = await getLatestVersion();
56
- console.log(chalk.dim(`Latest version: ${latestVersion}`));
57
- if (!isUpdateAvailable(currentVersion, latestVersion)) {
58
- console.log(chalk.green("WAVE Code is already up to date!"));
59
- process.exit(0);
60
- }
61
- console.log(chalk.yellow(`A new version of WAVE Code is available: ${latestVersion}`));
62
- const packageManager = detectPackageManager();
63
- let updateCmd;
64
- let args;
65
- if (packageManager === "pnpm") {
66
- updateCmd = "pnpm";
67
- args = ["add", "-g", "wave-code@latest"];
68
- }
69
- else if (packageManager === "yarn") {
70
- updateCmd = "yarn";
71
- args = ["global", "add", "wave-code@latest"];
72
- }
73
- else {
74
- updateCmd = "npm";
75
- args = ["install", "-g", "wave-code@latest"];
76
- }
77
- console.log(chalk.blue(`Updating WAVE Code using ${packageManager}...`));
78
- console.log(chalk.dim(`Running: ${updateCmd} ${args.join(" ")}`));
79
- const result = spawnSync(updateCmd, args, { stdio: "inherit" });
80
- if (result.status === 0) {
81
- console.log(chalk.green("WAVE Code updated successfully!"));
82
- process.exit(0);
83
- }
84
- else {
85
- console.log(chalk.red("Failed to update WAVE Code."));
86
- console.log(chalk.yellow(`Please try running the update command manually: ${updateCmd} ${args.join(" ")}`));
87
- if (process.platform !== "win32") {
88
- console.log(chalk.yellow("You might need to run it with sudo if you encounter permission issues."));
89
- }
90
- process.exit(1);
91
- }
92
- }
93
- catch (error) {
94
- console.error(chalk.red("Error checking for updates:"), error);
95
- process.exit(1);
96
- }
97
- }
@@ -1,7 +0,0 @@
1
- import React from "react";
2
- import type { SubagentConfiguration } from "wave-agent-sdk";
3
- export interface AgentsManagerProps {
4
- onCancel: () => void;
5
- agentDefinitions: SubagentConfiguration[];
6
- }
7
- export declare const AgentsManager: React.FC<AgentsManagerProps>;
@@ -1,109 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { useEffect, useMemo, useReducer } from "react";
3
- import { Box, Text, useInput, useStdout } from "ink";
4
- import { Markdown } from "./Markdown.js";
5
- import { agentsManagerReducer, } from "../reducers/agentsManagerReducer.js";
6
- const SCOPE_LABELS = {
7
- builtin: "Built-in agents",
8
- user: "User agents",
9
- project: "Project agents",
10
- plugin: "Plugin agents",
11
- };
12
- const SCOPE_ORDER = [
13
- "builtin",
14
- "user",
15
- "project",
16
- "plugin",
17
- ];
18
- const initialState = {
19
- selectedIndex: 0,
20
- viewMode: "list",
21
- pendingEffect: null,
22
- };
23
- export const AgentsManager = ({ onCancel, agentDefinitions, }) => {
24
- const [state, dispatch] = useReducer(agentsManagerReducer, initialState);
25
- const { stdout } = useStdout();
26
- // Handle pending effects
27
- useEffect(() => {
28
- if (!state.pendingEffect)
29
- return;
30
- const effect = state.pendingEffect;
31
- dispatch({ type: "CLEAR_PENDING_EFFECT" });
32
- if (effect.type === "CANCEL") {
33
- onCancel();
34
- }
35
- }, [state.pendingEffect, onCancel]);
36
- // Flatten definitions (grouped by scope) into one navigable list. Headers
37
- // and the empty-state line are non-selectable.
38
- const entries = useMemo(() => {
39
- const result = [];
40
- let selectableCount = 0;
41
- result.push({ kind: "header", label: "AGENTS", selectableIndex: -1 });
42
- let definitionCount = 0;
43
- for (const scope of SCOPE_ORDER) {
44
- const defs = agentDefinitions
45
- .filter((d) => d.scope === scope)
46
- .sort((a, b) => a.name.localeCompare(b.name));
47
- if (defs.length === 0)
48
- continue;
49
- result.push({
50
- kind: "header",
51
- label: SCOPE_LABELS[scope],
52
- scope,
53
- selectableIndex: -1,
54
- });
55
- for (const def of defs) {
56
- result.push({
57
- kind: "definition",
58
- label: def.name,
59
- model: def.model,
60
- sub: def.description,
61
- scope: def.scope,
62
- selectableIndex: selectableCount++,
63
- definition: def,
64
- });
65
- definitionCount++;
66
- }
67
- }
68
- if (definitionCount === 0) {
69
- result.push({
70
- kind: "empty",
71
- label: "No agents available",
72
- selectableIndex: -1,
73
- });
74
- }
75
- return result;
76
- }, [agentDefinitions]);
77
- const itemCount = entries.filter((e) => e.selectableIndex >= 0).length;
78
- // Window slice: center the selected item within the visible area, clamping
79
- // to the terminal's available rows (reusable pattern from
80
- // BackgroundTaskManager).
81
- const availableRows = stdout?.rows ?? 24;
82
- const maxVisible = Math.max(3, Math.min(15, availableRows - 12));
83
- const selectedFlatIndex = entries.findIndex((e) => e.selectableIndex === state.selectedIndex);
84
- const startIndex = Math.max(0, Math.min(selectedFlatIndex - Math.floor(maxVisible / 2), Math.max(0, entries.length - maxVisible)));
85
- const visibleEntries = entries.slice(startIndex, startIndex + maxVisible);
86
- useInput((input, key) => {
87
- dispatch({ type: "HANDLE_KEY", input, key, itemCount });
88
- });
89
- const selectedEntry = entries.find((e) => e.selectableIndex === state.selectedIndex);
90
- // Detail view — body renders fully expanded with no height limit, no
91
- // clipping and no scrolling (aligned with Claude Code's AgentDetail).
92
- if (state.viewMode === "detail" && selectedEntry) {
93
- const def = selectedEntry.definition;
94
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "cyan", bold: true, children: ["Agent: ", selectedEntry.label] }) }), _jsxs(Box, { flexDirection: "column", gap: 1, children: [def?.description && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Description:" }), " ", def.description] }) })), _jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Model:" }), " ", def?.model || "default (not explicitly configured)"] }) }), _jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Scope:" }), " ", def ? SCOPE_LABELS[def.scope] : ""] }) }), def?.tools && def.tools.length > 0 && (_jsx(Box, { children: _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { color: "blue", children: "Tools:" }), " ", def.tools.join(", ")] }) })), def?.filePath && (_jsx(Box, { children: _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { color: "blue", children: "File:" }), " ", def.filePath] }) }))] }), def && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "blue", bold: true, children: "System Prompt:" }), _jsx(Box, { marginLeft: 2, marginRight: 2, children: _jsx(Markdown, { children: def.systemPrompt }) })] })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Esc or Enter to go back" }) })] }));
95
- }
96
- if (itemCount === 0) {
97
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "Agents" }), _jsx(Text, { children: "No agents available" }), _jsx(Text, { dimColor: true, children: "Press Escape to close" })] }));
98
- }
99
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsx(Text, { color: "cyan", bold: true, children: "Agents" }) }), _jsx(Text, { dimColor: true, children: "Select an agent to view details" }), _jsx(Box, { flexDirection: "column", children: visibleEntries.map((entry, index) => {
100
- const isSelected = entry.selectableIndex === state.selectedIndex;
101
- if (entry.kind === "header") {
102
- return (_jsx(Text, { dimColor: true, bold: true, children: entry.label }, `${entry.kind}-${entry.label}-${index}`));
103
- }
104
- if (entry.kind === "empty") {
105
- return (_jsx(Text, { dimColor: true, children: entry.label }, `empty-${index}`));
106
- }
107
- return (_jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, wrap: "truncate-end", children: [isSelected ? "▶ " : " ", entry.selectableIndex + 1, ". ", entry.label, entry.model ? (_jsxs(Text, { color: isSelected ? "black" : "gray", children: [" ", "\u00B7 ", entry.model] })) : null, entry.sub ? ` · ${entry.sub}` : ""] }, `${entry.kind}-${entry.selectableIndex}`));
108
- }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191/\u2193 to select \u00B7 Enter to view details \u00B7 Esc to close" }) })] }));
109
- };
@@ -1,9 +0,0 @@
1
- import React from "react";
2
- import { BaseAppProps } from "../types.js";
3
- interface AppProps extends BaseAppProps {
4
- restoreSessionId?: string;
5
- continueLastSession?: boolean;
6
- onExit: (shouldRemove: boolean) => void;
7
- }
8
- export declare const App: React.FC<AppProps>;
9
- export {};
@@ -1,76 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useState, useEffect, useCallback } from "react";
3
- import { useInput } from "ink";
4
- import { ChatInterface } from "./ChatInterface.js";
5
- import { ChatProvider, useChat } from "../contexts/useChat.js";
6
- import { AppProvider } from "../contexts/useAppConfig.js";
7
- import { WorktreeExitPrompt } from "./WorktreeExitPrompt.js";
8
- import { hasUncommittedChanges, hasNewCommits, getDefaultRemoteBranch, } from "wave-agent-sdk";
9
- import { btwOverlayActiveRef } from "../managers/inputReducer.js";
10
- /** Wraps ChatInterface with worktree exit handling, using useChat() for hook access. */
11
- const ChatWithExitPrompt = ({ worktreeSession, onExit }) => {
12
- const { triggerWorktreeRemoveHook } = useChat();
13
- const [isExiting, setIsExiting] = useState(false);
14
- const [worktreeStatus, setWorktreeStatus] = useState(null);
15
- const handleSignal = useCallback(async () => {
16
- const cwd = worktreeSession.path;
17
- const baseBranch = getDefaultRemoteBranch(cwd);
18
- const hasChanges = hasUncommittedChanges(cwd);
19
- const hasCommits = hasNewCommits(cwd, baseBranch);
20
- if (hasChanges || hasCommits) {
21
- setWorktreeStatus({
22
- hasUncommittedChanges: hasChanges,
23
- hasNewCommits: hasCommits,
24
- });
25
- setIsExiting(true);
26
- }
27
- else {
28
- onExit(true);
29
- }
30
- }, [worktreeSession, onExit]);
31
- useInput((input, key) => {
32
- // While the /btw overlay is up it owns the keys; Ctrl+C must not quit
33
- if (btwOverlayActiveRef.current)
34
- return;
35
- if (input === "c" && key.ctrl) {
36
- handleSignal();
37
- }
38
- });
39
- useEffect(() => {
40
- const onSigInt = () => handleSignal();
41
- const onSigTerm = () => handleSignal();
42
- process.on("SIGINT", onSigInt);
43
- process.on("SIGTERM", onSigTerm);
44
- return () => {
45
- process.off("SIGINT", onSigInt);
46
- process.off("SIGTERM", onSigTerm);
47
- };
48
- }, [handleSignal]);
49
- if (isExiting && worktreeStatus) {
50
- return (_jsx(WorktreeExitPrompt, { name: worktreeSession.name, path: worktreeSession.path, hasUncommittedChanges: worktreeStatus.hasUncommittedChanges, hasNewCommits: worktreeStatus.hasNewCommits, onKeep: () => onExit(false), onRemove: async () => {
51
- await triggerWorktreeRemoveHook(worktreeSession.path);
52
- onExit(true);
53
- }, onCancel: () => setIsExiting(false) }));
54
- }
55
- return _jsx(ChatInterface, {});
56
- };
57
- const AppWithProviders = ({ bypassPermissions, permissionMode, pluginDirs, additionalDirectories, tools, allowedTools, disallowedTools, worktreeSession, workdir, originalCwd, version, model, mcpServers, onExit, }) => {
58
- // Handle Ctrl-C for non-worktree sessions (immediate exit)
59
- // Ink runs terminal in raw mode, so Ctrl+C arrives as useInput event, not SIGINT
60
- useInput((input, key) => {
61
- // While the /btw overlay is up it owns the keys; Ctrl+C must not quit
62
- if (btwOverlayActiveRef.current)
63
- return;
64
- if (!worktreeSession && input === "c" && key.ctrl) {
65
- onExit(false);
66
- return true;
67
- }
68
- });
69
- if (worktreeSession) {
70
- return (_jsx(ChatProvider, { bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, additionalDirectories: additionalDirectories, tools: tools, allowedTools: allowedTools, disallowedTools: disallowedTools, workdir: workdir, worktreeSession: worktreeSession, originalCwd: originalCwd, version: version, model: model, mcpServers: mcpServers, children: _jsx(ChatWithExitPrompt, { worktreeSession: worktreeSession, onExit: onExit }) }));
71
- }
72
- return (_jsx(ChatProvider, { bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, additionalDirectories: additionalDirectories, tools: tools, allowedTools: allowedTools, disallowedTools: disallowedTools, workdir: workdir, worktreeSession: worktreeSession, originalCwd: originalCwd, version: version, model: model, mcpServers: mcpServers, children: _jsx(ChatInterface, {}) }));
73
- };
74
- export const App = ({ restoreSessionId, continueLastSession, bypassPermissions, permissionMode, pluginDirs, additionalDirectories, tools, allowedTools, disallowedTools, worktreeSession, workdir, originalCwd, version, model, mcpServers, onExit, }) => {
75
- return (_jsx(AppProvider, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, children: _jsx(AppWithProviders, { bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, additionalDirectories: additionalDirectories, tools: tools, allowedTools: allowedTools, disallowedTools: disallowedTools, worktreeSession: worktreeSession, workdir: workdir, originalCwd: originalCwd, version: version, model: model, mcpServers: mcpServers, onExit: onExit }) }));
76
- };
@@ -1,5 +0,0 @@
1
- import React from "react";
2
- export interface BackgroundTaskManagerProps {
3
- onCancel: () => void;
4
- }
5
- export declare const BackgroundTaskManager: React.FC<BackgroundTaskManagerProps>;
@@ -1,99 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { useEffect, useReducer } from "react";
3
- import { Box, Text, useInput } from "ink";
4
- import { useChat } from "../contexts/useChat.js";
5
- import { getLastLines } from "wave-agent-sdk";
6
- import { backgroundTaskManagerReducer, } from "../reducers/backgroundTaskManagerReducer.js";
7
- export const BackgroundTaskManager = ({ onCancel, }) => {
8
- const { backgroundTasks, getBackgroundTaskOutput, stopBackgroundTask } = useChat();
9
- const MAX_VISIBLE_ITEMS = 3;
10
- const [state, dispatch] = useReducer(backgroundTaskManagerReducer, {
11
- tasks: [],
12
- selectedIndex: 0,
13
- viewMode: "list",
14
- detailTaskId: null,
15
- detailOutput: null,
16
- pendingEffect: null,
17
- });
18
- // Handle pending effects
19
- useEffect(() => {
20
- if (!state.pendingEffect)
21
- return;
22
- const effect = state.pendingEffect;
23
- dispatch({ type: "CLEAR_PENDING_EFFECT" });
24
- switch (effect.type) {
25
- case "CANCEL":
26
- onCancel();
27
- break;
28
- case "STOP_TASK":
29
- stopBackgroundTask(effect.taskId);
30
- break;
31
- }
32
- }, [state.pendingEffect, onCancel, stopBackgroundTask]);
33
- const { tasks, selectedIndex, viewMode, detailTaskId, detailOutput } = state;
34
- // Convert backgroundTasks to local Task format
35
- useEffect(() => {
36
- dispatch({
37
- type: "SET_TASKS",
38
- tasks: backgroundTasks.map((task) => ({
39
- id: task.id,
40
- type: task.type,
41
- description: task.description,
42
- status: task.status,
43
- startTime: task.startTime,
44
- exitCode: task.exitCode,
45
- runtime: task.runtime,
46
- outputPath: task.outputPath,
47
- })),
48
- });
49
- }, [backgroundTasks]);
50
- // Load detail output for selected task
51
- useEffect(() => {
52
- if (viewMode === "detail" && detailTaskId) {
53
- const output = getBackgroundTaskOutput(detailTaskId);
54
- dispatch({ type: "SET_DETAIL_OUTPUT", output });
55
- }
56
- }, [viewMode, detailTaskId, getBackgroundTaskOutput]);
57
- const formatDuration = (ms) => {
58
- if (ms < 1000)
59
- return `${ms}ms`;
60
- if (ms < 60000)
61
- return `${Math.round(ms / 1000)}s`;
62
- const minutes = Math.floor(ms / 60000);
63
- const seconds = Math.round((ms % 60000) / 1000);
64
- return `${minutes}m ${seconds}s`;
65
- };
66
- const formatTime = (timestamp) => {
67
- return new Date(timestamp).toLocaleTimeString();
68
- };
69
- // Calculate visible window
70
- const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, tasks.length - MAX_VISIBLE_ITEMS)));
71
- const visibleTasks = tasks.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
72
- useInput((input, key) => {
73
- dispatch({ type: "HANDLE_KEY", input, key });
74
- });
75
- if (viewMode === "detail" && detailTaskId && detailOutput) {
76
- const task = tasks.find((t) => t.id === detailTaskId);
77
- if (!task) {
78
- dispatch({ type: "RESET_DETAIL" });
79
- return null;
80
- }
81
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "cyan", bold: true, children: ["Background Task Details: ", task.id] }) }), _jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Type:" }), " ", task.type] }) }), task.description && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Description:" }), " ", task.description] }) })), _jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Status:" }), " ", task.status, task.exitCode !== undefined && ` (exit code: ${task.exitCode})`] }) }), _jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Started:" }), " ", formatTime(task.startTime), task.runtime !== undefined && (_jsxs(Text, { children: [" ", "| ", _jsx(Text, { color: "blue", children: "Runtime:" }), " ", formatDuration(task.runtime)] }))] }) }), task.outputPath && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Log File:" }), " ", task.outputPath] }) }))] }), detailOutput.stdout && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "green", bold: true, children: "OUTPUT (last 10 lines):" }), _jsx(Box, { borderStyle: "single", borderColor: "green", padding: 1, children: _jsx(Text, { children: getLastLines(detailOutput.stdout, 10) }) })] })), detailOutput.stderr && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "red", bold: true, children: "ERRORS:" }), _jsx(Box, { borderStyle: "single", borderColor: "red", padding: 1, children: _jsx(Text, { color: "red", children: getLastLines(detailOutput.stderr, 10) }) })] })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: [task.status === "running" ? "k to stop · " : "", "Esc to go back"] }) })] }));
82
- }
83
- if (!backgroundTasks) {
84
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "Background Tasks" }), _jsx(Text, { children: "Background tasks not available" }), _jsx(Text, { dimColor: true, children: "Press Escape to close" })] }));
85
- }
86
- if (tasks.length === 0) {
87
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "Background Tasks" }), _jsx(Text, { children: "No background tasks found" }), _jsx(Text, { dimColor: true, children: "Press Escape to close" })] }));
88
- }
89
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsx(Text, { color: "cyan", bold: true, children: "Background Tasks" }) }), _jsx(Text, { dimColor: true, children: "Select a task to view details" }), _jsx(Box, { flexDirection: "column", children: visibleTasks.map((task, index) => {
90
- const actualIndex = startIndex + index;
91
- const isSelected = actualIndex === selectedIndex;
92
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, children: [isSelected ? "▶ " : " ", actualIndex + 1, ". [", task.id, "] ", task.type, task.description ? `: ${task.description}` : "", _jsxs(Text, { color: task.status === "running"
93
- ? "green"
94
- : task.status === "completed"
95
- ? "blue"
96
- : "red", children: [" ", "(", task.status, ")"] })] }), isSelected && (_jsx(Box, { marginLeft: 4, flexDirection: "column", children: _jsxs(Text, { color: "gray", dimColor: true, children: [task.outputPath ? (_jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Log File:" }), " ", task.outputPath] })) : (`Started: ${formatTime(task.startTime)}`), task.runtime !== undefined &&
97
- ` | Runtime: ${formatDuration(task.runtime)}`, task.exitCode !== undefined && ` | Exit: ${task.exitCode}`] }) }))] }, task.id));
98
- }) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["\u2191/\u2193 to select \u00B7 Enter to view \u00B7", " ", tasks[selectedIndex]?.status === "running" ? "k to stop · " : "", "Esc to close"] }) })] }));
99
- };
@@ -1,8 +0,0 @@
1
- import React from "react";
2
- import type { BangBlock } from "wave-agent-sdk";
3
- interface BangDisplayProps {
4
- block: BangBlock;
5
- isExpanded?: boolean;
6
- }
7
- export declare const BangDisplay: React.FC<BangDisplayProps>;
8
- export {};
@@ -1,17 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from "ink";
3
- import { getLastLines } from "wave-agent-sdk";
4
- export const BangDisplay = ({ block, isExpanded = false, }) => {
5
- const { command, output, stage, exitCode } = block;
6
- const MAX_LINES = 3; // Set maximum display lines
7
- const getStatusColor = () => {
8
- if (stage === "running")
9
- return "yellow";
10
- if (exitCode === 0)
11
- return "green";
12
- if (exitCode !== null && exitCode !== 0)
13
- return "red";
14
- return "gray"; // Unknown state
15
- };
16
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: getStatusColor(), children: "! " }), _jsx(Text, { color: "white", children: command })] }), output && (_jsx(Box, { paddingLeft: 2, overflow: "hidden", children: _jsx(Text, { color: "gray", children: isExpanded ? output : getLastLines(output, MAX_LINES) }) }))] }));
17
- };
@@ -1,7 +0,0 @@
1
- import React from "react";
2
- import { BtwState } from "../managers/inputReducer.js";
3
- interface BtwDisplayProps {
4
- btwState: BtwState;
5
- }
6
- export declare const BtwDisplay: React.FC<BtwDisplayProps>;
7
- export {};
@@ -1,19 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { Box, Text } from "ink";
3
- import { Markdown } from "./Markdown.js";
4
- export const BtwDisplay = ({ btwState }) => {
5
- // Rendered for a real question (loading or answered) and for the bare
6
- // `/btw` usage message (question === "", answer set).
7
- if (!btwState.question && !btwState.answer) {
8
- return null;
9
- }
10
- const answer = btwState.answer ?? "";
11
- // The SDK surfaces failure as the answer string; classify by prefix so it
12
- // renders in error color (aligned with Claude Code's error display).
13
- const isError = !btwState.isLoading &&
14
- (answer.startsWith("(API error") ||
15
- answer.startsWith("(The model tried to call") ||
16
- answer === "No response received");
17
- return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [btwState.question && (_jsxs(Box, { children: [_jsxs(Text, { color: "warning", bold: true, children: ["/btw", " "] }), _jsx(Text, { dimColor: true, children: btwState.question })] })), _jsx(Box, { marginTop: 1, flexDirection: "column", children: btwState.isLoading ? (_jsx(Text, { color: "gray", children: "\u273B Answering..." })) : isError ? (_jsx(Text, { color: "error", children: answer })) : (_jsx(Markdown, { children: answer })) }), btwState.question && btwState.answer && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Escape to dismiss" }) })), !btwState.question && btwState.answer && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Escape to dismiss" }) }))] }));
18
- };
19
- BtwDisplay.displayName = "BtwDisplay";
@@ -1,2 +0,0 @@
1
- import React from "react";
2
- export declare const ChatInterface: React.FC;
@@ -1,61 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useRef, useEffect, useCallback } from "react";
3
- import { Box, useStdout, measureElement, Static } from "ink";
4
- import { authService } from "wave-agent-sdk";
5
- import { MessageList } from "./MessageList.js";
6
- import { InputBox } from "./InputBox.js";
7
- import { LoadingIndicator } from "./LoadingIndicator.js";
8
- import { TaskList } from "./TaskList.js";
9
- import { QueuedMessageList } from "./QueuedMessageList.js";
10
- import { ConfirmationDetails } from "./ConfirmationDetails.js";
11
- import { ConfirmationSelector } from "./ConfirmationSelector.js";
12
- import { useChat } from "../contexts/useChat.js";
13
- export const ChatInterface = () => {
14
- const { messages, isLoading, isCommandRunning, isCompacting, sendMessage, abortMessage, mcpServers, connectMcpServer, disconnectMcpServer, isExpanded, sessionId, latestTotalTokens, maxInputTokens, slashCommands, hasSlashCommand, isConfirmationVisible, hasPendingConfirmations, confirmingTool, handleConfirmationDecision, handleConfirmationCancel, version, workdir, remountKey, forceRemount, getGatewayConfig, } = useChat();
15
- const displayMessages = messages;
16
- const [forceStatic, setForceStatic] = useState(false);
17
- const { stdout } = useStdout();
18
- const terminalHeight = stdout?.rows ?? 24;
19
- const chatInterfaceRef = useRef(null);
20
- // Compute whether the user has any usable auth/direct-API config,
21
- // so the welcome page can prompt /login when neither is present.
22
- // An SSO token counts as authenticated even if the access token is stale —
23
- // it refreshes lazily on the next API call (matching the claude-code CLI).
24
- const computeAuthState = useCallback(() => {
25
- if (authService.getSSOToken())
26
- return true;
27
- const gateway = getGatewayConfig();
28
- return Boolean(gateway.apiKey || gateway.baseURL);
29
- }, [getGatewayConfig]);
30
- const [hasAuth, setHasAuth] = useState(computeAuthState);
31
- // Keep the /login hint in sync with auth state changes (login/logout).
32
- useEffect(() => {
33
- const unsubscribe = authService.onAuthChange(() => {
34
- setHasAuth(computeAuthState());
35
- });
36
- return unsubscribe;
37
- }, [computeAuthState]);
38
- const showLoginHint = !hasAuth;
39
- // Handle forceStatic mode for overflow and request remount when exiting
40
- useEffect(() => {
41
- if (isConfirmationVisible && chatInterfaceRef.current) {
42
- const { height } = measureElement(chatInterfaceRef.current);
43
- if (height > terminalHeight) {
44
- setForceStatic(true);
45
- }
46
- }
47
- else if (forceStatic && !hasPendingConfirmations) {
48
- setForceStatic(false);
49
- forceRemount();
50
- }
51
- }, [
52
- isConfirmationVisible,
53
- terminalHeight,
54
- forceStatic,
55
- hasPendingConfirmations,
56
- forceRemount,
57
- ]);
58
- if (!sessionId)
59
- return null;
60
- return (_jsxs(Box, { ref: chatInterfaceRef, flexDirection: "column", children: [_jsx(MessageList, { messages: displayMessages, isExpanded: isExpanded, version: version, workdir: workdir, forceStatic: forceStatic }, remountKey), !isConfirmationVisible && !isExpanded && (_jsxs(_Fragment, { children: [(isLoading || isCommandRunning || isCompacting) && (_jsx(LoadingIndicator, { isLoading: isLoading, isCommandRunning: isCommandRunning, isCompacting: isCompacting, latestTotalTokens: latestTotalTokens })), _jsx(TaskList, {}), _jsx(QueuedMessageList, {}), _jsx(InputBox, { isLoading: isLoading, isCommandRunning: isCommandRunning, isCompacting: isCompacting, sendMessage: sendMessage, abortMessage: abortMessage, mcpServers: mcpServers, connectMcpServer: connectMcpServer, disconnectMcpServer: disconnectMcpServer, slashCommands: slashCommands, hasSlashCommand: hasSlashCommand, latestTotalTokens: latestTotalTokens, maxInputTokens: maxInputTokens, showLoginHint: showLoginHint })] })), isConfirmationVisible && (_jsxs(_Fragment, { children: [forceStatic ? (_jsx(Static, { items: [{ key: "confirmation-details" }], children: () => (_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, planContent: confirmingTool.planContent, warning: confirmingTool.warning, isExpanded: isExpanded }, "confirmation-details")) })) : (_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, planContent: confirmingTool.planContent, warning: confirmingTool.warning, isExpanded: isExpanded })), _jsx(ConfirmationSelector, { toolName: confirmingTool.name, toolInput: confirmingTool.input, suggestedPrefix: confirmingTool.suggestedPrefix, hidePersistentOption: confirmingTool.hidePersistentOption, permissionMode: confirmingTool.permissionMode, isExpanded: isExpanded, onDecision: handleConfirmationDecision, onCancel: handleConfirmationCancel })] }))] }));
61
- };
@@ -1,10 +0,0 @@
1
- import React from "react";
2
- import type { SlashCommand } from "wave-agent-sdk";
3
- export interface CommandSelectorProps {
4
- searchQuery: string;
5
- onSelect: (command: string) => void;
6
- onInsert?: (command: string) => void;
7
- onCancel: () => void;
8
- commands?: SlashCommand[];
9
- }
10
- export declare const CommandSelector: React.FC<CommandSelectorProps>;
@@ -1,66 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { useReducer, useEffect, useMemo } from "react";
3
- import { Box, Text, useInput } from "ink";
4
- import { AVAILABLE_COMMANDS } from "../constants/commands.js";
5
- import { selectorReducer, } from "../reducers/selectorReducer.js";
6
- export const CommandSelector = ({ searchQuery, onSelect, onInsert, onCancel, commands = [], }) => {
7
- const MAX_VISIBLE_ITEMS = 3;
8
- const [state, dispatch] = useReducer((selectorReducer), {
9
- selectedIndex: 0,
10
- pendingDecision: null,
11
- items: [],
12
- });
13
- const { selectedIndex, pendingDecision, items: filteredCommands } = state;
14
- // Merge agent commands and local commands, memoized to stabilize useEffect dependencies
15
- const computedCommands = useMemo(() => {
16
- const allCommands = [...AVAILABLE_COMMANDS, ...commands];
17
- return allCommands.filter((command) => !searchQuery ||
18
- command.id.toLowerCase().includes(searchQuery.toLowerCase()));
19
- }, [searchQuery, commands]);
20
- // Sync computed commands into reducer state (SET_ITEMS also resets index)
21
- useEffect(() => {
22
- dispatch({ type: "SET_ITEMS", items: computedCommands });
23
- }, [computedCommands]);
24
- // Handle decisions from reducer
25
- useEffect(() => {
26
- if (!pendingDecision)
27
- return;
28
- if (pendingDecision === "select") {
29
- if (filteredCommands.length > 0 &&
30
- selectedIndex < filteredCommands.length) {
31
- onSelect(filteredCommands[selectedIndex].id);
32
- }
33
- }
34
- else if (pendingDecision === "insert" && onInsert) {
35
- if (filteredCommands.length > 0 &&
36
- selectedIndex < filteredCommands.length) {
37
- onInsert(filteredCommands[selectedIndex].id);
38
- }
39
- }
40
- else if (pendingDecision === "cancel") {
41
- onCancel();
42
- }
43
- dispatch({ type: "CLEAR_DECISION" });
44
- }, [
45
- pendingDecision,
46
- selectedIndex,
47
- filteredCommands,
48
- onSelect,
49
- onInsert,
50
- onCancel,
51
- ]);
52
- // Calculate visible window
53
- const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, filteredCommands.length - MAX_VISIBLE_ITEMS)));
54
- const visibleCommands = filteredCommands.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
55
- useInput((input, key) => {
56
- dispatch({ type: "HANDLE_KEY", key, hasInsert: !!onInsert });
57
- });
58
- if (filteredCommands.length === 0) {
59
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "yellow", children: ["No commands found for \"", searchQuery, "\""] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
60
- }
61
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "magenta", borderBottom: false, borderLeft: false, borderRight: false, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "magenta", bold: true, children: ["Command Selector ", searchQuery && `(filtering: "${searchQuery}")`] }) }), _jsx(Box, { flexDirection: "column", children: visibleCommands.map((command, index) => {
62
- const actualIndex = startIndex + index;
63
- const isSelected = actualIndex === selectedIndex;
64
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "magenta" : undefined, children: [isSelected ? "▶ " : " ", "/", command.id] }), isSelected && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { color: "gray", dimColor: true, children: command.description }) }))] }, command.id));
65
- }) }), _jsx(Box, { children: _jsxs(Text, { dimColor: true, children: ["\u2191\u2193 navigate \u2022 Enter execute \u2022 ", onInsert ? "Tab insert • " : "", "Esc cancel"] }) })] }));
66
- };
@@ -1,8 +0,0 @@
1
- import React from "react";
2
- import type { CompactBlock } from "wave-agent-sdk";
3
- interface CompactDisplayProps {
4
- block: CompactBlock;
5
- isExpanded?: boolean;
6
- }
7
- export declare const CompactDisplay: React.FC<CompactDisplayProps>;
8
- export {};