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
@@ -0,0 +1,312 @@
1
+ import React, { useEffect, useMemo, useReducer } from "react";
2
+ import { Box, Text, useInput, useStdout } from "ink";
3
+ import type { SkillMetadata } from "wave-agent-sdk";
4
+ import {
5
+ skillsManagerReducer,
6
+ type SkillsManagerState,
7
+ } from "../reducers/skillsManagerReducer.js";
8
+
9
+ export interface SkillsManagerProps {
10
+ onCancel: () => void;
11
+ skills: SkillMetadata[];
12
+ }
13
+
14
+ interface DisplayEntry {
15
+ kind: "header" | "skill" | "empty";
16
+ label: string;
17
+ sub?: string;
18
+ scope?: SkillScope;
19
+ selectableIndex: number; // -1 for non-selectable rows
20
+ skill?: SkillMetadata;
21
+ }
22
+
23
+ type SkillScope = "builtin" | "user" | "project" | "plugin";
24
+
25
+ const SCOPE_LABELS: Record<SkillScope, string> = {
26
+ builtin: "Built-in skills",
27
+ user: "User skills",
28
+ project: "Project skills",
29
+ plugin: "Plugin skills",
30
+ };
31
+
32
+ const SCOPE_ORDER: SkillScope[] = ["builtin", "user", "project", "plugin"];
33
+
34
+ const initialState: SkillsManagerState = {
35
+ selectedIndex: 0,
36
+ viewMode: "list",
37
+ pendingEffect: null,
38
+ };
39
+
40
+ /** Group scope for a skill: plugin skills (pluginName set) get their own
41
+ * group, everything else groups by its discovery type ("personal" skills
42
+ * are shown under the user scope). */
43
+ function getSkillScope(skill: SkillMetadata): SkillScope {
44
+ if (skill.pluginName) {
45
+ return "plugin";
46
+ }
47
+ if (skill.type === "personal") {
48
+ return "user";
49
+ }
50
+ return skill.type;
51
+ }
52
+
53
+ export const SkillsManager: React.FC<SkillsManagerProps> = ({
54
+ onCancel,
55
+ skills,
56
+ }) => {
57
+ const [state, dispatch] = useReducer(skillsManagerReducer, initialState);
58
+ const { stdout } = useStdout();
59
+
60
+ // Handle pending effects
61
+ useEffect(() => {
62
+ if (!state.pendingEffect) return;
63
+ const effect = state.pendingEffect;
64
+ dispatch({ type: "CLEAR_PENDING_EFFECT" });
65
+ if (effect.type === "CANCEL") {
66
+ onCancel();
67
+ }
68
+ }, [state.pendingEffect, onCancel]);
69
+
70
+ // Flatten skills (grouped by scope) into one navigable list. Headers and
71
+ // the empty-state line are non-selectable.
72
+ const entries = useMemo<DisplayEntry[]>(() => {
73
+ const result: DisplayEntry[] = [];
74
+ let selectableCount = 0;
75
+
76
+ result.push({ kind: "header", label: "SKILLS", selectableIndex: -1 });
77
+ let skillCount = 0;
78
+ for (const scope of SCOPE_ORDER) {
79
+ const scopedSkills = skills
80
+ .filter((s) => getSkillScope(s) === scope)
81
+ .sort((a, b) => a.name.localeCompare(b.name));
82
+ if (scopedSkills.length === 0) continue;
83
+ result.push({
84
+ kind: "header",
85
+ label: SCOPE_LABELS[scope],
86
+ scope,
87
+ selectableIndex: -1,
88
+ });
89
+ for (const skill of scopedSkills) {
90
+ result.push({
91
+ kind: "skill",
92
+ label: skill.name,
93
+ sub: skill.description,
94
+ scope,
95
+ selectableIndex: selectableCount++,
96
+ skill,
97
+ });
98
+ skillCount++;
99
+ }
100
+ }
101
+ if (skillCount === 0) {
102
+ result.push({
103
+ kind: "empty",
104
+ label: "No skills available",
105
+ selectableIndex: -1,
106
+ });
107
+ }
108
+
109
+ return result;
110
+ }, [skills]);
111
+
112
+ const itemCount = entries.filter((e) => e.selectableIndex >= 0).length;
113
+
114
+ // Window slice: center the selected item within the visible area, clamping
115
+ // to the terminal's available rows (reusable pattern from
116
+ // AgentsManager/BackgroundTaskManager).
117
+ const availableRows = stdout?.rows ?? 24;
118
+ const maxVisible = Math.max(3, Math.min(15, availableRows - 12));
119
+ const selectedFlatIndex = entries.findIndex(
120
+ (e) => e.selectableIndex === state.selectedIndex,
121
+ );
122
+ const startIndex = Math.max(
123
+ 0,
124
+ Math.min(
125
+ selectedFlatIndex - Math.floor(maxVisible / 2),
126
+ Math.max(0, entries.length - maxVisible),
127
+ ),
128
+ );
129
+ const visibleEntries = entries.slice(startIndex, startIndex + maxVisible);
130
+
131
+ useInput((input, key) => {
132
+ dispatch({ type: "HANDLE_KEY", input, key, itemCount });
133
+ });
134
+
135
+ const selectedEntry = entries.find(
136
+ (e) => e.selectableIndex === state.selectedIndex,
137
+ );
138
+
139
+ // Detail view — body renders fully expanded with no height limit, no
140
+ // clipping and no scrolling (aligned with AgentsManager's detail view).
141
+ if (state.viewMode === "detail" && selectedEntry) {
142
+ const skill = selectedEntry.skill;
143
+ return (
144
+ <Box
145
+ flexDirection="column"
146
+ borderStyle="single"
147
+ borderColor="cyan"
148
+ borderBottom={false}
149
+ borderLeft={false}
150
+ borderRight={false}
151
+ paddingTop={1}
152
+ gap={1}
153
+ >
154
+ <Box>
155
+ <Text color="cyan" bold>
156
+ Skill: {selectedEntry.label}
157
+ </Text>
158
+ </Box>
159
+
160
+ <Box flexDirection="column" gap={1}>
161
+ {skill?.description && (
162
+ <Box>
163
+ <Text>
164
+ <Text color="blue">Description:</Text> {skill.description}
165
+ </Text>
166
+ </Box>
167
+ )}
168
+ <Box>
169
+ <Text>
170
+ <Text color="blue">Scope:</Text>{" "}
171
+ {skill ? SCOPE_LABELS[getSkillScope(skill)] : ""}
172
+ {skill?.pluginName ? ` (${skill.pluginName})` : ""}
173
+ </Text>
174
+ </Box>
175
+ {skill?.skillPath && (
176
+ <Box>
177
+ <Text wrap="wrap">
178
+ <Text color="blue">Path:</Text> {skill.skillPath}
179
+ </Text>
180
+ </Box>
181
+ )}
182
+ {skill?.model && (
183
+ <Box>
184
+ <Text>
185
+ <Text color="blue">Model:</Text> {skill.model}
186
+ </Text>
187
+ </Box>
188
+ )}
189
+ {skill?.agent && (
190
+ <Box>
191
+ <Text>
192
+ <Text color="blue">Agent:</Text> {skill.agent}
193
+ </Text>
194
+ </Box>
195
+ )}
196
+ {skill?.allowedTools && skill.allowedTools.length > 0 && (
197
+ <Box>
198
+ <Text wrap="wrap">
199
+ <Text color="blue">Allowed tools:</Text>{" "}
200
+ {skill.allowedTools.join(", ")}
201
+ </Text>
202
+ </Box>
203
+ )}
204
+ {skill && (
205
+ <Box>
206
+ <Text wrap="wrap">
207
+ <Text color="blue">Invocation:</Text>{" "}
208
+ {[
209
+ skill.userInvocable === false ? "not user-invocable" : null,
210
+ skill.disableModelInvocation
211
+ ? "model invocation disabled"
212
+ : null,
213
+ ]
214
+ .filter(Boolean)
215
+ .join(", ") || "user-invocable, model-invocable"}
216
+ </Text>
217
+ </Box>
218
+ )}
219
+ </Box>
220
+
221
+ <Box marginTop={1}>
222
+ <Text dimColor>Esc or Enter to go back</Text>
223
+ </Box>
224
+ </Box>
225
+ );
226
+ }
227
+
228
+ if (itemCount === 0) {
229
+ return (
230
+ <Box
231
+ flexDirection="column"
232
+ borderStyle="single"
233
+ borderColor="cyan"
234
+ borderBottom={false}
235
+ borderLeft={false}
236
+ borderRight={false}
237
+ paddingTop={1}
238
+ >
239
+ <Text color="cyan" bold>
240
+ Skills
241
+ </Text>
242
+ <Text>No skills available</Text>
243
+ <Text dimColor>Create skills in .wave/skills/ or ~/.wave/skills/</Text>
244
+ <Text dimColor>Press Escape to close</Text>
245
+ </Box>
246
+ );
247
+ }
248
+
249
+ return (
250
+ <Box
251
+ flexDirection="column"
252
+ borderStyle="single"
253
+ borderColor="cyan"
254
+ borderBottom={false}
255
+ borderLeft={false}
256
+ borderRight={false}
257
+ paddingTop={1}
258
+ gap={1}
259
+ >
260
+ <Box>
261
+ <Text color="cyan" bold>
262
+ Skills
263
+ </Text>
264
+ </Box>
265
+ <Text dimColor>Select a skill to view details</Text>
266
+
267
+ <Box flexDirection="column">
268
+ {visibleEntries.map((entry, index) => {
269
+ const isSelected = entry.selectableIndex === state.selectedIndex;
270
+ if (entry.kind === "header") {
271
+ return (
272
+ <Text key={`${entry.kind}-${entry.label}-${index}`} dimColor bold>
273
+ {entry.label}
274
+ </Text>
275
+ );
276
+ }
277
+ if (entry.kind === "empty") {
278
+ return (
279
+ <Text key={`empty-${index}`} dimColor>
280
+ {entry.label}
281
+ </Text>
282
+ );
283
+ }
284
+ return (
285
+ <Text
286
+ key={`${entry.kind}-${entry.selectableIndex}`}
287
+ color={isSelected ? "black" : "white"}
288
+ backgroundColor={isSelected ? "cyan" : undefined}
289
+ wrap="truncate-end"
290
+ >
291
+ {isSelected ? "▶ " : " "}
292
+ {entry.selectableIndex + 1}. {entry.label}
293
+ {entry.scope === "plugin" && entry.skill?.pluginName ? (
294
+ <Text color={isSelected ? "black" : "gray"}>
295
+ {" "}
296
+ · {entry.skill.pluginName}
297
+ </Text>
298
+ ) : null}
299
+ {entry.sub ? ` · ${entry.sub}` : ""}
300
+ </Text>
301
+ );
302
+ })}
303
+ </Box>
304
+
305
+ <Box marginTop={1}>
306
+ <Text dimColor>
307
+ ↑/↓ to select · Enter to view details · Esc to close
308
+ </Text>
309
+ </Box>
310
+ </Box>
311
+ );
312
+ };
@@ -1,12 +1,7 @@
1
1
  import React from "react";
2
2
  import { Box, Text, useInput } from "ink";
3
3
  import { useChat } from "../contexts/useChat.js";
4
- import fs from "fs";
5
- import path from "path";
6
- import { fileURLToPath } from "url";
7
-
8
- const __filename = fileURLToPath(import.meta.url);
9
- const __dirname = path.dirname(__filename);
4
+ import { readNearestPackageJson } from "../utils/readPackageJson.js";
10
5
 
11
6
  export interface StatusCommandProps {
12
7
  onCancel: () => void;
@@ -27,9 +22,7 @@ export const StatusCommand: React.FC<StatusCommandProps> = ({ onCancel }) => {
27
22
 
28
23
  let version = "unknown";
29
24
  try {
30
- const pkgPath = path.resolve(__dirname, "../../package.json");
31
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
32
- version = pkg.version;
25
+ version = readNearestPackageJson().version;
33
26
  } catch {
34
27
  // Fallback if package.json cannot be read
35
28
  }
@@ -3,6 +3,7 @@ import { Box, Text } from "ink";
3
3
  import type { ToolBlock } from "wave-agent-sdk";
4
4
  import { getLastLines } from "wave-agent-sdk";
5
5
  import { DiffDisplay } from "./DiffDisplay.js";
6
+ import { streamingTail } from "../utils/streamingText.js";
6
7
 
7
8
  interface ToolDisplayProps {
8
9
  block: ToolBlock;
@@ -81,10 +82,7 @@ export const ToolDisplay: React.FC<ToolDisplayProps> = ({
81
82
  parameters &&
82
83
  !compactParams && (
83
84
  <Text color="gray" wrap="truncate-end">
84
- {` ${(() => {
85
- const flat = parameters.replace(/\n/g, "\\n");
86
- return flat.length > 30 ? `…${flat.slice(-30)}` : flat;
87
- })()}`}
85
+ {` ${streamingTail(parameters)}`}
88
86
  </Text>
89
87
  )}
90
88
  {/* Display image indicator */}
@@ -19,6 +19,12 @@ export const AVAILABLE_COMMANDS: SlashCommand[] = [
19
19
  description: "List available agents and active subagents",
20
20
  handler: () => {}, // Handler here won't be used, actual processing is in the hook
21
21
  },
22
+ {
23
+ id: "skills",
24
+ name: "skills",
25
+ description: "List available skills",
26
+ handler: () => {}, // Handler here won't be used, actual processing is in the hook
27
+ },
22
28
  {
23
29
  id: "rewind",
24
30
  name: "rewind",