wave-code 1.0.9 → 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.
- package/bin/wave-code.js +8 -2
- package/dist/bundle/wave.mjs +3207 -0
- package/package.json +24 -25
- package/src/commands/update.ts +2 -7
- package/src/components/App.tsx +3 -7
- package/src/components/BtwDisplay.tsx +10 -1
- package/src/components/ChatInterface.tsx +21 -52
- package/src/components/ConfirmationDetails.tsx +144 -37
- package/src/components/DiffDisplay.tsx +335 -301
- package/src/components/InputBox.tsx +3 -1
- package/src/components/LoadingIndicator.tsx +16 -2
- package/src/components/MessageBlockItem.tsx +2 -4
- package/src/components/MessageList.tsx +75 -14
- package/src/components/ReasoningDisplay.tsx +2 -4
- package/src/components/SessionSelector.tsx +82 -11
- package/src/components/StatusCommand.tsx +2 -9
- package/src/components/ToolDisplay.tsx +2 -4
- package/src/contexts/useChat.tsx +172 -350
- package/src/daemon/commands.ts +57 -27
- package/src/daemon/jsonRpcClient.ts +1 -1
- package/src/daemon/socketClient.ts +2 -2
- package/src/hooks/useInputManager.ts +1 -1
- package/src/index.ts +57 -10
- package/src/managers/inputReducer.ts +186 -104
- package/src/print-cli.ts +21 -17
- package/src/reducers/selectorReducer.ts +10 -0
- package/src/session-selector-cli.tsx +269 -28
- package/src/stdio/agentBridge.ts +22 -21
- package/src/stdio/daemonServer.ts +3 -1
- package/src/stdio/jsonRpcConnection.ts +19 -1
- package/src/stdio/stdioServer.ts +17 -0
- package/src/utils/clipboard.ts +21 -0
- package/src/utils/highlightUtils.ts +46 -1
- package/src/utils/readPackageJson.ts +29 -0
- package/src/utils/streamingText.ts +11 -0
- package/src/utils/worktree.ts +191 -43
- package/dist/cli.d.ts +0 -6
- package/dist/cli.js +0 -53
- package/dist/commands/plugin/disable.d.ts +0 -5
- package/dist/commands/plugin/disable.js +0 -15
- package/dist/commands/plugin/enable.d.ts +0 -5
- package/dist/commands/plugin/enable.js +0 -15
- package/dist/commands/plugin/install.d.ts +0 -5
- package/dist/commands/plugin/install.js +0 -21
- package/dist/commands/plugin/list.d.ts +0 -1
- package/dist/commands/plugin/list.js +0 -31
- package/dist/commands/plugin/marketplace.d.ts +0 -10
- package/dist/commands/plugin/marketplace.js +0 -90
- package/dist/commands/plugin/uninstall.d.ts +0 -3
- package/dist/commands/plugin/uninstall.js +0 -16
- package/dist/commands/plugin/update.d.ts +0 -3
- package/dist/commands/plugin/update.js +0 -15
- package/dist/commands/update.d.ts +0 -1
- package/dist/commands/update.js +0 -97
- package/dist/components/AgentsManager.d.ts +0 -7
- package/dist/components/AgentsManager.js +0 -109
- package/dist/components/App.d.ts +0 -9
- package/dist/components/App.js +0 -76
- package/dist/components/BackgroundTaskManager.d.ts +0 -5
- package/dist/components/BackgroundTaskManager.js +0 -99
- package/dist/components/BangDisplay.d.ts +0 -8
- package/dist/components/BangDisplay.js +0 -17
- package/dist/components/BtwDisplay.d.ts +0 -7
- package/dist/components/BtwDisplay.js +0 -19
- package/dist/components/ChatInterface.d.ts +0 -2
- package/dist/components/ChatInterface.js +0 -61
- package/dist/components/CommandSelector.d.ts +0 -10
- package/dist/components/CommandSelector.js +0 -66
- package/dist/components/CompactDisplay.d.ts +0 -8
- package/dist/components/CompactDisplay.js +0 -13
- package/dist/components/ConfirmationDetails.d.ts +0 -9
- package/dist/components/ConfirmationDetails.js +0 -45
- package/dist/components/ConfirmationSelector.d.ts +0 -13
- package/dist/components/ConfirmationSelector.js +0 -127
- package/dist/components/DiffDisplay.d.ts +0 -8
- package/dist/components/DiffDisplay.js +0 -201
- package/dist/components/DiscoverView.d.ts +0 -2
- package/dist/components/DiscoverView.js +0 -37
- package/dist/components/FileSelector.d.ts +0 -11
- package/dist/components/FileSelector.js +0 -50
- package/dist/components/HelpView.d.ts +0 -7
- package/dist/components/HelpView.js +0 -74
- package/dist/components/HistorySearch.d.ts +0 -8
- package/dist/components/HistorySearch.js +0 -66
- package/dist/components/InputBox.d.ts +0 -24
- package/dist/components/InputBox.js +0 -149
- package/dist/components/InstalledView.d.ts +0 -2
- package/dist/components/InstalledView.js +0 -45
- package/dist/components/LoadingIndicator.d.ts +0 -10
- package/dist/components/LoadingIndicator.js +0 -6
- package/dist/components/LoginCommand.d.ts +0 -5
- package/dist/components/LoginCommand.js +0 -153
- package/dist/components/Markdown.d.ts +0 -5
- package/dist/components/Markdown.js +0 -127
- package/dist/components/MarketplaceAddForm.d.ts +0 -2
- package/dist/components/MarketplaceAddForm.js +0 -55
- package/dist/components/MarketplaceDetail.d.ts +0 -2
- package/dist/components/MarketplaceDetail.js +0 -74
- package/dist/components/MarketplaceList.d.ts +0 -8
- package/dist/components/MarketplaceList.js +0 -17
- package/dist/components/MarketplaceView.d.ts +0 -2
- package/dist/components/MarketplaceView.js +0 -41
- package/dist/components/McpManager.d.ts +0 -9
- package/dist/components/McpManager.js +0 -88
- package/dist/components/MessageBlockItem.d.ts +0 -8
- package/dist/components/MessageBlockItem.js +0 -15
- package/dist/components/MessageList.d.ts +0 -10
- package/dist/components/MessageList.js +0 -80
- package/dist/components/ModelSelector.d.ts +0 -8
- package/dist/components/ModelSelector.js +0 -45
- package/dist/components/Notifications.d.ts +0 -7
- package/dist/components/Notifications.js +0 -9
- package/dist/components/PlanDisplay.d.ts +0 -7
- package/dist/components/PlanDisplay.js +0 -6
- package/dist/components/PluginDetail.d.ts +0 -2
- package/dist/components/PluginDetail.js +0 -87
- package/dist/components/PluginList.d.ts +0 -13
- package/dist/components/PluginList.js +0 -15
- package/dist/components/PluginManagerShell.d.ts +0 -6
- package/dist/components/PluginManagerShell.js +0 -92
- package/dist/components/PluginManagerTypes.d.ts +0 -35
- package/dist/components/PluginManagerTypes.js +0 -1
- package/dist/components/QueuedMessageList.d.ts +0 -2
- package/dist/components/QueuedMessageList.js +0 -18
- package/dist/components/ReasoningDisplay.d.ts +0 -8
- package/dist/components/ReasoningDisplay.js +0 -13
- package/dist/components/RewindCommand.d.ts +0 -12
- package/dist/components/RewindCommand.js +0 -78
- package/dist/components/SessionSelector.d.ts +0 -12
- package/dist/components/SessionSelector.js +0 -47
- package/dist/components/StatusCommand.d.ts +0 -5
- package/dist/components/StatusCommand.js +0 -28
- package/dist/components/StatusLine.d.ts +0 -6
- package/dist/components/StatusLine.js +0 -9
- package/dist/components/TaskList.d.ts +0 -5
- package/dist/components/TaskList.js +0 -197
- package/dist/components/TaskNotificationMessage.d.ts +0 -5
- package/dist/components/TaskNotificationMessage.js +0 -12
- package/dist/components/ToolDisplay.d.ts +0 -9
- package/dist/components/ToolDisplay.js +0 -55
- package/dist/components/WorkflowManager.d.ts +0 -5
- package/dist/components/WorkflowManager.js +0 -102
- package/dist/components/WorktreeExitPrompt.d.ts +0 -12
- package/dist/components/WorktreeExitPrompt.js +0 -35
- package/dist/constants/commands.d.ts +0 -2
- package/dist/constants/commands.js +0 -92
- package/dist/contexts/PluginManagerContext.d.ts +0 -3
- package/dist/contexts/PluginManagerContext.js +0 -9
- package/dist/contexts/useAppConfig.d.ts +0 -10
- package/dist/contexts/useAppConfig.js +0 -13
- package/dist/contexts/useChat.d.ts +0 -101
- package/dist/contexts/useChat.js +0 -992
- package/dist/contracts/status.d.ts +0 -7
- package/dist/contracts/status.js +0 -1
- package/dist/daemon/commands.d.ts +0 -49
- package/dist/daemon/commands.js +0 -341
- package/dist/daemon/jsonRpcClient.d.ts +0 -38
- package/dist/daemon/jsonRpcClient.js +0 -129
- package/dist/daemon/socketClient.d.ts +0 -13
- package/dist/daemon/socketClient.js +0 -26
- package/dist/daemon-cli.d.ts +0 -10
- package/dist/daemon-cli.js +0 -15
- package/dist/hooks/useInputManager.d.ts +0 -75
- package/dist/hooks/useInputManager.js +0 -583
- package/dist/hooks/usePluginManager.d.ts +0 -4
- package/dist/hooks/usePluginManager.js +0 -265
- package/dist/hooks/useTasks.d.ts +0 -1
- package/dist/hooks/useTasks.js +0 -5
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -447
- package/dist/managers/inputHandlers.d.ts +0 -30
- package/dist/managers/inputHandlers.js +0 -625
- package/dist/managers/inputReducer.d.ts +0 -271
- package/dist/managers/inputReducer.js +0 -1121
- package/dist/plugin-manager-cli.d.ts +0 -5
- package/dist/plugin-manager-cli.js +0 -12
- package/dist/print-cli.d.ts +0 -10
- package/dist/print-cli.js +0 -209
- package/dist/reducers/agentsManagerReducer.d.ts +0 -26
- package/dist/reducers/agentsManagerReducer.js +0 -54
- package/dist/reducers/backgroundTaskManagerReducer.d.ts +0 -62
- package/dist/reducers/backgroundTaskManagerReducer.js +0 -106
- package/dist/reducers/confirmationReducer.d.ts +0 -37
- package/dist/reducers/confirmationReducer.js +0 -193
- package/dist/reducers/helpSelectorReducer.d.ts +0 -25
- package/dist/reducers/helpSelectorReducer.js +0 -52
- package/dist/reducers/marketplaceAddFormReducer.d.ts +0 -24
- package/dist/reducers/marketplaceAddFormReducer.js +0 -58
- package/dist/reducers/mcpManagerReducer.d.ts +0 -37
- package/dist/reducers/mcpManagerReducer.js +0 -74
- package/dist/reducers/pluginDetailReducer.d.ts +0 -32
- package/dist/reducers/pluginDetailReducer.js +0 -70
- package/dist/reducers/questionReducer.d.ts +0 -82
- package/dist/reducers/questionReducer.js +0 -375
- package/dist/reducers/rewindSelectorReducer.d.ts +0 -21
- package/dist/reducers/rewindSelectorReducer.js +0 -37
- package/dist/reducers/selectorReducer.d.ts +0 -23
- package/dist/reducers/selectorReducer.js +0 -42
- package/dist/reducers/workflowManagerReducer.d.ts +0 -40
- package/dist/reducers/workflowManagerReducer.js +0 -100
- package/dist/session-selector-cli.d.ts +0 -3
- package/dist/session-selector-cli.js +0 -25
- package/dist/stdio/agentBridge.d.ts +0 -139
- package/dist/stdio/agentBridge.js +0 -999
- package/dist/stdio/daemonServer.d.ts +0 -67
- package/dist/stdio/daemonServer.js +0 -191
- package/dist/stdio/index.d.ts +0 -5
- package/dist/stdio/index.js +0 -5
- package/dist/stdio/jsonRpcConnection.d.ts +0 -30
- package/dist/stdio/jsonRpcConnection.js +0 -127
- package/dist/stdio/protocol.d.ts +0 -41
- package/dist/stdio/protocol.js +0 -26
- package/dist/stdio/stdioServer.d.ts +0 -28
- package/dist/stdio/stdioServer.js +0 -36
- package/dist/stdio-cli.d.ts +0 -8
- package/dist/stdio-cli.js +0 -15
- package/dist/types.d.ts +0 -20
- package/dist/types.js +0 -1
- package/dist/utils/bracketedPaste.d.ts +0 -39
- package/dist/utils/bracketedPaste.js +0 -122
- package/dist/utils/clipboard.d.ts +0 -21
- package/dist/utils/clipboard.js +0 -347
- package/dist/utils/constants.d.ts +0 -16
- package/dist/utils/constants.js +0 -18
- package/dist/utils/highlightUtils.d.ts +0 -1
- package/dist/utils/highlightUtils.js +0 -93
- package/dist/utils/inputUtils.d.ts +0 -17
- package/dist/utils/inputUtils.js +0 -67
- package/dist/utils/logger.d.ts +0 -71
- package/dist/utils/logger.js +0 -259
- package/dist/utils/markdownTable.d.ts +0 -34
- package/dist/utils/markdownTable.js +0 -302
- package/dist/utils/rewindCheckpoints.d.ts +0 -8
- package/dist/utils/rewindCheckpoints.js +0 -17
- package/dist/utils/throttle.d.ts +0 -14
- package/dist/utils/throttle.js +0 -55
- package/dist/utils/toolParameterTransforms.d.ts +0 -18
- package/dist/utils/toolParameterTransforms.js +0 -73
- package/dist/utils/usageSummary.d.ts +0 -28
- package/dist/utils/usageSummary.js +0 -121
- package/dist/utils/version.d.ts +0 -1
- package/dist/utils/version.js +0 -4
- package/dist/utils/worktree.d.ts +0 -35
- package/dist/utils/worktree.js +0 -219
package/src/daemon/commands.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `wave daemon` client subcommands — talk to the wave daemon's unix socket
|
|
3
3
|
* (JSON-RPC over newline-delimited JSON) to list hosted sessions, inspect
|
|
4
|
-
* progress, inject messages
|
|
4
|
+
* progress, inject messages, respond to pending permission requests and abort
|
|
5
|
+
* in-flight message generation.
|
|
5
6
|
*
|
|
6
7
|
* All subcommands are non-interactive: results go to stdout, diagnostics to
|
|
7
8
|
* stderr, and every handler calls process.exit() itself (yargs would fall
|
|
@@ -68,7 +69,7 @@ async function connectDaemonOrExit(socketPath: string): Promise<SocketClient> {
|
|
|
68
69
|
} catch (err) {
|
|
69
70
|
const code = (err as NodeJS.ErrnoException).code;
|
|
70
71
|
console.error(
|
|
71
|
-
|
|
72
|
+
`Cannot connect to daemon socket ${socketPath}: is the daemon running? (it auto-exits after 60s idle)` +
|
|
72
73
|
(code ? ` (${code})` : ""),
|
|
73
74
|
);
|
|
74
75
|
process.exit(1);
|
|
@@ -115,7 +116,7 @@ async function attachSession(
|
|
|
115
116
|
// initialize silently started a junk fresh session — remove it from the
|
|
116
117
|
// registry so the failed attach leaves no trace (spec: 会话不存在错误).
|
|
117
118
|
await client.request("destroy", undefined, initId).catch(() => {});
|
|
118
|
-
fail(
|
|
119
|
+
fail(`Session not found or not hosted by this daemon: ${sessionId}`);
|
|
119
120
|
}
|
|
120
121
|
throw err;
|
|
121
122
|
}
|
|
@@ -149,7 +150,7 @@ export async function daemonListCommand(socketPath: string): Promise<void> {
|
|
|
149
150
|
if (sessions.length > 0) {
|
|
150
151
|
const rows = sessions.map((s) => ({
|
|
151
152
|
sessionId: s.sessionId,
|
|
152
|
-
status: s.isLoading ? "
|
|
153
|
+
status: s.isLoading ? "generating" : "idle",
|
|
153
154
|
messageCount: String(s.messageCount),
|
|
154
155
|
workingDirectory: s.workingDirectory,
|
|
155
156
|
}));
|
|
@@ -158,7 +159,7 @@ export async function daemonListCommand(socketPath: string): Promise<void> {
|
|
|
158
159
|
const pad = (value: string, w: number) => value.padEnd(w);
|
|
159
160
|
|
|
160
161
|
console.log(
|
|
161
|
-
`${pad("
|
|
162
|
+
`${pad("Session", width("sessionId"))} ${pad("Status", width("status"))} ${pad("Messages", width("messageCount"))} Working directory`,
|
|
162
163
|
);
|
|
163
164
|
for (const r of rows) {
|
|
164
165
|
console.log(
|
|
@@ -167,10 +168,10 @@ export async function daemonListCommand(socketPath: string): Promise<void> {
|
|
|
167
168
|
}
|
|
168
169
|
} else {
|
|
169
170
|
// Daemon idle-exit is normal — an empty registry is not an error.
|
|
170
|
-
console.log("
|
|
171
|
+
console.log("No sessions");
|
|
171
172
|
}
|
|
172
173
|
} catch (err) {
|
|
173
|
-
fail(`wave daemon list
|
|
174
|
+
fail(`wave daemon list failed: ${(err as Error).message}`);
|
|
174
175
|
} finally {
|
|
175
176
|
await client?.dispose();
|
|
176
177
|
}
|
|
@@ -226,14 +227,18 @@ export async function daemonStatusCommand(
|
|
|
226
227
|
};
|
|
227
228
|
|
|
228
229
|
const status =
|
|
229
|
-
pending.length > 0
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
230
|
+
pending.length > 0
|
|
231
|
+
? "waiting for approval"
|
|
232
|
+
: loading
|
|
233
|
+
? "generating"
|
|
234
|
+
: "idle";
|
|
235
|
+
console.log(`Session: ${initId}`);
|
|
236
|
+
console.log(`Working directory: ${init.workingDirectory}`);
|
|
237
|
+
console.log(`Status: ${status}`);
|
|
233
238
|
|
|
234
239
|
if (pending.length > 0) {
|
|
235
240
|
console.log("");
|
|
236
|
-
console.log("
|
|
241
|
+
console.log("Pending approval requests:");
|
|
237
242
|
for (const r of pending) {
|
|
238
243
|
const params = summarizeToolInput(r.context);
|
|
239
244
|
console.log(
|
|
@@ -245,7 +250,7 @@ export async function daemonStatusCommand(
|
|
|
245
250
|
const recent = messages.messages.slice(-lines);
|
|
246
251
|
if (recent.length > 0) {
|
|
247
252
|
console.log("");
|
|
248
|
-
console.log(
|
|
253
|
+
console.log(`Recent messages (${recent.length}):`);
|
|
249
254
|
for (const m of recent) {
|
|
250
255
|
const text = getMessageContent(m).replace(/\s+/g, " ").trim();
|
|
251
256
|
if (!text) continue; // tool-only messages carry no readable text
|
|
@@ -253,7 +258,7 @@ export async function daemonStatusCommand(
|
|
|
253
258
|
}
|
|
254
259
|
}
|
|
255
260
|
} catch (err) {
|
|
256
|
-
fail(`wave daemon status
|
|
261
|
+
fail(`wave daemon status failed: ${(err as Error).message}`);
|
|
257
262
|
} finally {
|
|
258
263
|
await client?.dispose();
|
|
259
264
|
}
|
|
@@ -311,7 +316,7 @@ export async function daemonSendCommand(
|
|
|
311
316
|
await client.request("sendMessage", { text: message }, initId);
|
|
312
317
|
} catch (err) {
|
|
313
318
|
client.dispose();
|
|
314
|
-
fail(`wave daemon send
|
|
319
|
+
fail(`wave daemon send failed: ${(err as Error).message}`);
|
|
315
320
|
}
|
|
316
321
|
|
|
317
322
|
// Wait for the reply that corresponds to our message.
|
|
@@ -327,13 +332,13 @@ export async function daemonSendCommand(
|
|
|
327
332
|
client.dispose();
|
|
328
333
|
if (pending.length > 0) {
|
|
329
334
|
fail(
|
|
330
|
-
|
|
335
|
+
`Session is waiting for permission approval; handle it with \`wave daemon respond ${sessionId} ${pending[0].requestId}\` and retry`,
|
|
331
336
|
);
|
|
332
337
|
}
|
|
333
338
|
fail(
|
|
334
339
|
options.timeout === 0
|
|
335
|
-
? "
|
|
336
|
-
:
|
|
340
|
+
? "Timed out waiting for a reply"
|
|
341
|
+
: `Timed out waiting for a reply (${options.timeout}s), no assistant reply received`,
|
|
337
342
|
);
|
|
338
343
|
}
|
|
339
344
|
await sleep(200);
|
|
@@ -351,7 +356,7 @@ export async function daemonSendCommand(
|
|
|
351
356
|
if (content) console.log(content);
|
|
352
357
|
}
|
|
353
358
|
} catch (err) {
|
|
354
|
-
fail(`wave daemon send
|
|
359
|
+
fail(`wave daemon send failed: ${(err as Error).message}`);
|
|
355
360
|
} finally {
|
|
356
361
|
client.dispose();
|
|
357
362
|
}
|
|
@@ -376,7 +381,7 @@ export async function daemonRespondCommand(
|
|
|
376
381
|
options: RespondOptions,
|
|
377
382
|
): Promise<void> {
|
|
378
383
|
if (!!options.allow === !!options.deny) {
|
|
379
|
-
fail("
|
|
384
|
+
fail("Specify either --allow or --deny");
|
|
380
385
|
}
|
|
381
386
|
let client: SocketClient | undefined;
|
|
382
387
|
try {
|
|
@@ -387,11 +392,11 @@ export async function daemonRespondCommand(
|
|
|
387
392
|
const pending = await listPendingPermissions(client);
|
|
388
393
|
const req = pending.find((r) => r.requestId === requestId);
|
|
389
394
|
if (!req) {
|
|
390
|
-
fail("
|
|
395
|
+
fail("Request not found or already handled");
|
|
391
396
|
}
|
|
392
397
|
if (req.sessionId && req.sessionId !== sessionId) {
|
|
393
398
|
// Cross-check before notifying; never touch another session's request.
|
|
394
|
-
fail("
|
|
399
|
+
fail("Session not found or not hosted by this daemon");
|
|
395
400
|
}
|
|
396
401
|
|
|
397
402
|
let decision: PermissionDecision;
|
|
@@ -407,13 +412,15 @@ export async function daemonRespondCommand(
|
|
|
407
412
|
decision = { behavior: "allow", newPermissionMode: "default" };
|
|
408
413
|
} else if (toolName === ASK_USER_QUESTION_TOOL_NAME) {
|
|
409
414
|
if (!options.answer) {
|
|
410
|
-
fail(
|
|
415
|
+
fail(
|
|
416
|
+
"AskUserQuestion requests require --answer with the answer JSON",
|
|
417
|
+
);
|
|
411
418
|
}
|
|
412
419
|
let answers: unknown;
|
|
413
420
|
try {
|
|
414
421
|
answers = JSON.parse(options.answer);
|
|
415
422
|
} catch {
|
|
416
|
-
fail("--answer
|
|
423
|
+
fail("--answer is not valid JSON");
|
|
417
424
|
}
|
|
418
425
|
decision = { behavior: "allow", message: JSON.stringify(answers) };
|
|
419
426
|
} else {
|
|
@@ -424,7 +431,7 @@ export async function daemonRespondCommand(
|
|
|
424
431
|
if (options.mode) {
|
|
425
432
|
if (!PERMISSION_MODES.includes(options.mode as PermissionMode)) {
|
|
426
433
|
fail(
|
|
427
|
-
|
|
434
|
+
`Invalid permission mode: ${options.mode} (options: ${PERMISSION_MODES.join(", ")})`,
|
|
428
435
|
);
|
|
429
436
|
}
|
|
430
437
|
decision.newPermissionMode = options.mode as PermissionMode;
|
|
@@ -434,9 +441,32 @@ export async function daemonRespondCommand(
|
|
|
434
441
|
// Mirror desktop stdioAgent.sendPermissionResponse: envelope sessionId
|
|
435
442
|
// present, decision built from the pending request's tool.
|
|
436
443
|
client.notify("permissionResponse", { requestId, decision }, sessionId);
|
|
437
|
-
console.log(
|
|
444
|
+
console.log(`Handled approval request: ${requestId}`);
|
|
445
|
+
} catch (err) {
|
|
446
|
+
fail(`wave daemon respond failed: ${(err as Error).message}`);
|
|
447
|
+
} finally {
|
|
448
|
+
await client?.dispose();
|
|
449
|
+
}
|
|
450
|
+
process.exit(0);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// ── abort ─────────────────────────────────────────────────────
|
|
454
|
+
|
|
455
|
+
export async function daemonAbortCommand(
|
|
456
|
+
socketPath: string,
|
|
457
|
+
sessionId: string,
|
|
458
|
+
): Promise<void> {
|
|
459
|
+
let client: SocketClient | undefined;
|
|
460
|
+
try {
|
|
461
|
+
client = await connectDaemonOrExit(socketPath);
|
|
462
|
+
const init = await attachSession(client, sessionId);
|
|
463
|
+
// abortMessage is idempotent: a no-op on idle sessions, interrupts
|
|
464
|
+
// in-flight generation (incl. subagents / bash / slash / queued messages)
|
|
465
|
+
// otherwise (spec: 中断幂等,无需先确认是否正在生成).
|
|
466
|
+
await client.request("abortMessage", undefined, init.sessionId);
|
|
467
|
+
console.log(`Aborted session: ${sessionId}`);
|
|
438
468
|
} catch (err) {
|
|
439
|
-
fail(`wave daemon
|
|
469
|
+
fail(`wave daemon abort failed: ${(err as Error).message}`);
|
|
440
470
|
} finally {
|
|
441
471
|
await client?.dispose();
|
|
442
472
|
}
|
|
@@ -76,7 +76,7 @@ export abstract class JsonRpcClient {
|
|
|
76
76
|
): Promise<unknown> {
|
|
77
77
|
if (this.closed) {
|
|
78
78
|
throw new Error(
|
|
79
|
-
"
|
|
79
|
+
"Connection closed. The wave process has exited; restart the editor or check your CLI installation.",
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
82
|
const id = this.nextId++;
|
|
@@ -16,7 +16,7 @@ export class SocketClient extends JsonRpcClient {
|
|
|
16
16
|
this.attachReadable(socket);
|
|
17
17
|
|
|
18
18
|
socket.on("close", () => {
|
|
19
|
-
this.handleClosed("
|
|
19
|
+
this.handleClosed("Remote connection closed.");
|
|
20
20
|
});
|
|
21
21
|
socket.on("error", (err) => {
|
|
22
22
|
console.error("[wave-daemon] Socket error:", err.message);
|
|
@@ -28,7 +28,7 @@ export class SocketClient extends JsonRpcClient {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
dispose(): void {
|
|
31
|
-
this.handleClosed("
|
|
31
|
+
this.handleClosed("Remote connection closed.");
|
|
32
32
|
this.socket.destroy();
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -157,7 +157,7 @@ export const useInputManager = (
|
|
|
157
157
|
// Stream partial answers into the overlay so the user sees
|
|
158
158
|
// the response grow in real time (same visual language as
|
|
159
159
|
// assistant text / thinking blocks) instead of a static
|
|
160
|
-
// "Answering
|
|
160
|
+
// "Answering" indicator.
|
|
161
161
|
if (!btwDismissedRef.current) {
|
|
162
162
|
dispatch({
|
|
163
163
|
type: "SET_BTW_STATE",
|
package/src/index.ts
CHANGED
|
@@ -9,13 +9,9 @@ import {
|
|
|
9
9
|
} from "wave-agent-sdk";
|
|
10
10
|
import { createWorktree, type WorktreeSession } from "./utils/worktree.js";
|
|
11
11
|
import path from "path";
|
|
12
|
-
import {
|
|
13
|
-
import { fileURLToPath } from "url";
|
|
12
|
+
import { readNearestPackageJson } from "./utils/readPackageJson.js";
|
|
14
13
|
|
|
15
|
-
const
|
|
16
|
-
const packageJsonPath = path.resolve(__dirname, "../package.json");
|
|
17
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
18
|
-
const version = packageJson.version;
|
|
14
|
+
const version = readNearestPackageJson().version;
|
|
19
15
|
|
|
20
16
|
// Export main function for external use
|
|
21
17
|
export async function main() {
|
|
@@ -379,6 +375,24 @@ export async function main() {
|
|
|
379
375
|
);
|
|
380
376
|
},
|
|
381
377
|
)
|
|
378
|
+
.command(
|
|
379
|
+
"abort <sessionId>",
|
|
380
|
+
"Abort the session's in-flight message generation",
|
|
381
|
+
(yargs) => {
|
|
382
|
+
return yargs.positional("sessionId", {
|
|
383
|
+
describe: "Session ID hosted by the daemon",
|
|
384
|
+
type: "string",
|
|
385
|
+
});
|
|
386
|
+
},
|
|
387
|
+
async (argv) => {
|
|
388
|
+
const { daemonAbortCommand, DEFAULT_DAEMON_SOCKET } =
|
|
389
|
+
await import("./daemon/commands.js");
|
|
390
|
+
await daemonAbortCommand(
|
|
391
|
+
DEFAULT_DAEMON_SOCKET,
|
|
392
|
+
argv.sessionId as string,
|
|
393
|
+
);
|
|
394
|
+
},
|
|
395
|
+
)
|
|
382
396
|
.demandCommand(1, "Please specify a daemon subcommand");
|
|
383
397
|
},
|
|
384
398
|
)
|
|
@@ -497,13 +511,29 @@ export async function main() {
|
|
|
497
511
|
const { startSessionSelectorCli } = await import(
|
|
498
512
|
"./session-selector-cli.js"
|
|
499
513
|
);
|
|
500
|
-
const
|
|
501
|
-
|
|
514
|
+
const { listWorktrees } = await import("./utils/worktree.js");
|
|
515
|
+
const worktreePaths = await listWorktrees(process.cwd());
|
|
516
|
+
const selection = await startSessionSelectorCli({
|
|
517
|
+
workdir,
|
|
518
|
+
worktreePaths,
|
|
519
|
+
});
|
|
520
|
+
if (!selection) {
|
|
502
521
|
return;
|
|
503
522
|
}
|
|
523
|
+
|
|
524
|
+
// Resume a session from a sibling worktree of the same repo — chdir into
|
|
525
|
+
// that worktree so the agent's workdir matches the session's origin
|
|
526
|
+
// (mirrors Claude Code's worktree resume; projectRoot is not set, so
|
|
527
|
+
// skills/history stay anchored to the original project).
|
|
528
|
+
let resumeWorkdir = workdir;
|
|
529
|
+
if (selection.resumeWorkdir) {
|
|
530
|
+
resumeWorkdir = selection.resumeWorkdir;
|
|
531
|
+
process.chdir(resumeWorkdir);
|
|
532
|
+
}
|
|
533
|
+
|
|
504
534
|
// Continue with the selected session
|
|
505
535
|
return startCli({
|
|
506
|
-
restoreSessionId:
|
|
536
|
+
restoreSessionId: selection.sessionId,
|
|
507
537
|
bypassPermissions: argv.dangerouslySkipPermissions as boolean,
|
|
508
538
|
permissionMode: argv.permissionMode as PermissionMode | undefined,
|
|
509
539
|
pluginDirs,
|
|
@@ -512,7 +542,7 @@ export async function main() {
|
|
|
512
542
|
allowedTools,
|
|
513
543
|
disallowedTools,
|
|
514
544
|
worktreeSession,
|
|
515
|
-
workdir,
|
|
545
|
+
workdir: resumeWorkdir,
|
|
516
546
|
originalCwd,
|
|
517
547
|
version,
|
|
518
548
|
model: argv.model as string | undefined,
|
|
@@ -520,6 +550,23 @@ export async function main() {
|
|
|
520
550
|
});
|
|
521
551
|
}
|
|
522
552
|
|
|
553
|
+
// Validate an explicitly-specified restore ID before entering the CLI —
|
|
554
|
+
// loadSessionFromJsonl scans every project dir as a fallback, so a miss
|
|
555
|
+
// here means the session truly does not exist. Fail fast with a clear
|
|
556
|
+
// error instead of silently starting a fresh session.
|
|
557
|
+
if (
|
|
558
|
+
typeof argv.restore === "string" &&
|
|
559
|
+
argv.restore !== "" &&
|
|
560
|
+
!argv.print
|
|
561
|
+
) {
|
|
562
|
+
const { loadSessionFromJsonl } = await import("wave-agent-sdk");
|
|
563
|
+
const exists = await loadSessionFromJsonl(argv.restore, workdir);
|
|
564
|
+
if (!exists) {
|
|
565
|
+
console.error(`Session ${argv.restore} not found on disk.`);
|
|
566
|
+
process.exit(1);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
523
570
|
// Handle print mode directly
|
|
524
571
|
if (argv.print !== undefined) {
|
|
525
572
|
const { startPrintCli } = await import("./print-cli.js");
|