wave-code 0.19.6 → 0.19.8
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/dist/cli.d.ts +0 -1
- package/dist/commands/plugin/disable.d.ts +0 -1
- package/dist/commands/plugin/enable.d.ts +0 -1
- package/dist/commands/plugin/install.d.ts +0 -1
- package/dist/commands/plugin/list.d.ts +0 -1
- package/dist/commands/plugin/marketplace.d.ts +0 -1
- package/dist/commands/plugin/uninstall.d.ts +0 -1
- package/dist/commands/plugin/update.d.ts +0 -1
- package/dist/commands/update.d.ts +0 -1
- package/dist/components/App.d.ts +0 -1
- package/dist/components/BackgroundTaskManager.d.ts +0 -1
- package/dist/components/BangDisplay.d.ts +0 -1
- package/dist/components/BtwDisplay.d.ts +0 -1
- package/dist/components/ChatInterface.d.ts +0 -1
- package/dist/components/CommandSelector.d.ts +0 -1
- package/dist/components/CompactDisplay.d.ts +0 -1
- package/dist/components/ConfirmationDetails.d.ts +0 -1
- package/dist/components/ConfirmationSelector.d.ts +0 -1
- package/dist/components/ConfirmationSelector.js +4 -3
- package/dist/components/DiffDisplay.d.ts +0 -1
- package/dist/components/DiscoverView.d.ts +0 -1
- package/dist/components/FileSelector.d.ts +0 -1
- package/dist/components/HelpView.d.ts +0 -1
- package/dist/components/HistorySearch.d.ts +0 -1
- package/dist/components/InputBox.d.ts +0 -1
- package/dist/components/InstalledView.d.ts +0 -1
- package/dist/components/LoadingIndicator.d.ts +0 -1
- package/dist/components/LoginCommand.d.ts +0 -1
- package/dist/components/Markdown.d.ts +0 -1
- package/dist/components/MarketplaceAddForm.d.ts +0 -1
- package/dist/components/MarketplaceDetail.d.ts +0 -1
- package/dist/components/MarketplaceList.d.ts +0 -1
- package/dist/components/MarketplaceView.d.ts +0 -1
- package/dist/components/McpManager.d.ts +0 -1
- package/dist/components/MessageBlockItem.d.ts +0 -1
- package/dist/components/MessageList.d.ts +0 -1
- package/dist/components/ModelSelector.d.ts +0 -1
- package/dist/components/PlanDisplay.d.ts +0 -1
- package/dist/components/PluginDetail.d.ts +0 -1
- package/dist/components/PluginList.d.ts +0 -1
- package/dist/components/PluginManagerShell.d.ts +0 -1
- package/dist/components/PluginManagerTypes.d.ts +0 -1
- package/dist/components/QueuedMessageList.d.ts +0 -1
- package/dist/components/ReasoningDisplay.d.ts +0 -1
- package/dist/components/RewindCommand.d.ts +0 -1
- package/dist/components/SessionSelector.d.ts +0 -1
- package/dist/components/StatusCommand.d.ts +0 -1
- package/dist/components/StatusLine.d.ts +0 -1
- package/dist/components/TaskList.d.ts +0 -1
- package/dist/components/TaskNotificationMessage.d.ts +0 -1
- package/dist/components/ToolDisplay.d.ts +0 -1
- package/dist/components/WorkflowManager.d.ts +0 -1
- package/dist/components/WorktreeExitPrompt.d.ts +0 -1
- package/dist/constants/commands.d.ts +0 -1
- package/dist/contexts/PluginManagerContext.d.ts +0 -1
- package/dist/contexts/useAppConfig.d.ts +0 -1
- package/dist/contexts/useChat.d.ts +0 -1
- package/dist/contexts/useChat.js +1 -1
- package/dist/contracts/status.d.ts +0 -1
- package/dist/hooks/useInputManager.d.ts +0 -1
- package/dist/hooks/usePluginManager.d.ts +0 -1
- package/dist/hooks/useTasks.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +3 -2
- package/dist/managers/inputHandlers.d.ts +0 -1
- package/dist/managers/inputReducer.d.ts +0 -1
- package/dist/plugin-manager-cli.d.ts +0 -1
- package/dist/print-cli.d.ts +0 -1
- package/dist/print-cli.js +10 -2
- package/dist/reducers/backgroundTaskManagerReducer.d.ts +0 -1
- package/dist/reducers/confirmationReducer.d.ts +1 -2
- package/dist/reducers/confirmationReducer.js +9 -10
- package/dist/reducers/helpSelectorReducer.d.ts +0 -1
- package/dist/reducers/marketplaceAddFormReducer.d.ts +0 -1
- package/dist/reducers/mcpManagerReducer.d.ts +0 -1
- package/dist/reducers/pluginDetailReducer.d.ts +0 -1
- package/dist/reducers/questionReducer.d.ts +0 -1
- package/dist/reducers/rewindSelectorReducer.d.ts +0 -1
- package/dist/reducers/selectorReducer.d.ts +0 -1
- package/dist/reducers/workflowManagerReducer.d.ts +0 -1
- package/dist/session-selector-cli.d.ts +0 -1
- package/dist/stdio/agentBridge.d.ts +5 -1
- package/dist/stdio/agentBridge.js +60 -28
- package/dist/stdio/index.d.ts +0 -1
- package/dist/stdio/protocol.d.ts +2 -3
- package/dist/stdio/stdioServer.d.ts +0 -1
- package/dist/stdio-cli.d.ts +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/utils/clipboard.d.ts +0 -1
- package/dist/utils/constants.d.ts +0 -1
- package/dist/utils/highlightUtils.d.ts +0 -1
- package/dist/utils/inputUtils.d.ts +0 -1
- package/dist/utils/logger.d.ts +0 -1
- package/dist/utils/throttle.d.ts +0 -1
- package/dist/utils/toolParameterTransforms.d.ts +0 -1
- package/dist/utils/usageSummary.d.ts +0 -1
- package/dist/utils/version.d.ts +0 -1
- package/dist/utils/worktree.d.ts +5 -2
- package/dist/utils/worktree.js +8 -4
- package/package.json +2 -2
- package/src/components/ConfirmationSelector.tsx +16 -15
- package/src/contexts/useChat.tsx +1 -1
- package/src/index.ts +8 -2
- package/src/print-cli.ts +12 -2
- package/src/reducers/confirmationReducer.ts +9 -9
- package/src/stdio/agentBridge.ts +96 -39
- package/src/stdio/protocol.ts +9 -2
- package/src/utils/worktree.ts +12 -4
- package/dist/cli.d.ts.map +0 -1
- package/dist/commands/plugin/disable.d.ts.map +0 -1
- package/dist/commands/plugin/enable.d.ts.map +0 -1
- package/dist/commands/plugin/install.d.ts.map +0 -1
- package/dist/commands/plugin/list.d.ts.map +0 -1
- package/dist/commands/plugin/marketplace.d.ts.map +0 -1
- package/dist/commands/plugin/uninstall.d.ts.map +0 -1
- package/dist/commands/plugin/update.d.ts.map +0 -1
- package/dist/commands/update.d.ts.map +0 -1
- package/dist/components/App.d.ts.map +0 -1
- package/dist/components/BackgroundTaskManager.d.ts.map +0 -1
- package/dist/components/BangDisplay.d.ts.map +0 -1
- package/dist/components/BtwDisplay.d.ts.map +0 -1
- package/dist/components/ChatInterface.d.ts.map +0 -1
- package/dist/components/CommandSelector.d.ts.map +0 -1
- package/dist/components/CompactDisplay.d.ts.map +0 -1
- package/dist/components/ConfirmationDetails.d.ts.map +0 -1
- package/dist/components/ConfirmationSelector.d.ts.map +0 -1
- package/dist/components/DiffDisplay.d.ts.map +0 -1
- package/dist/components/DiscoverView.d.ts.map +0 -1
- package/dist/components/FileSelector.d.ts.map +0 -1
- package/dist/components/HelpView.d.ts.map +0 -1
- package/dist/components/HistorySearch.d.ts.map +0 -1
- package/dist/components/InputBox.d.ts.map +0 -1
- package/dist/components/InstalledView.d.ts.map +0 -1
- package/dist/components/LoadingIndicator.d.ts.map +0 -1
- package/dist/components/LoginCommand.d.ts.map +0 -1
- package/dist/components/Markdown.d.ts.map +0 -1
- package/dist/components/MarketplaceAddForm.d.ts.map +0 -1
- package/dist/components/MarketplaceDetail.d.ts.map +0 -1
- package/dist/components/MarketplaceList.d.ts.map +0 -1
- package/dist/components/MarketplaceView.d.ts.map +0 -1
- package/dist/components/McpManager.d.ts.map +0 -1
- package/dist/components/MessageBlockItem.d.ts.map +0 -1
- package/dist/components/MessageList.d.ts.map +0 -1
- package/dist/components/ModelSelector.d.ts.map +0 -1
- package/dist/components/PlanDisplay.d.ts.map +0 -1
- package/dist/components/PluginDetail.d.ts.map +0 -1
- package/dist/components/PluginList.d.ts.map +0 -1
- package/dist/components/PluginManagerShell.d.ts.map +0 -1
- package/dist/components/PluginManagerTypes.d.ts.map +0 -1
- package/dist/components/QueuedMessageList.d.ts.map +0 -1
- package/dist/components/ReasoningDisplay.d.ts.map +0 -1
- package/dist/components/RewindCommand.d.ts.map +0 -1
- package/dist/components/SessionSelector.d.ts.map +0 -1
- package/dist/components/StatusCommand.d.ts.map +0 -1
- package/dist/components/StatusLine.d.ts.map +0 -1
- package/dist/components/TaskList.d.ts.map +0 -1
- package/dist/components/TaskNotificationMessage.d.ts.map +0 -1
- package/dist/components/ToolDisplay.d.ts.map +0 -1
- package/dist/components/WorkflowManager.d.ts.map +0 -1
- package/dist/components/WorktreeExitPrompt.d.ts.map +0 -1
- package/dist/constants/commands.d.ts.map +0 -1
- package/dist/contexts/PluginManagerContext.d.ts.map +0 -1
- package/dist/contexts/useAppConfig.d.ts.map +0 -1
- package/dist/contexts/useChat.d.ts.map +0 -1
- package/dist/contracts/status.d.ts.map +0 -1
- package/dist/hooks/useInputManager.d.ts.map +0 -1
- package/dist/hooks/usePluginManager.d.ts.map +0 -1
- package/dist/hooks/useTasks.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/managers/inputHandlers.d.ts.map +0 -1
- package/dist/managers/inputReducer.d.ts.map +0 -1
- package/dist/plugin-manager-cli.d.ts.map +0 -1
- package/dist/print-cli.d.ts.map +0 -1
- package/dist/reducers/backgroundTaskManagerReducer.d.ts.map +0 -1
- package/dist/reducers/confirmationReducer.d.ts.map +0 -1
- package/dist/reducers/helpSelectorReducer.d.ts.map +0 -1
- package/dist/reducers/marketplaceAddFormReducer.d.ts.map +0 -1
- package/dist/reducers/mcpManagerReducer.d.ts.map +0 -1
- package/dist/reducers/pluginDetailReducer.d.ts.map +0 -1
- package/dist/reducers/questionReducer.d.ts.map +0 -1
- package/dist/reducers/rewindSelectorReducer.d.ts.map +0 -1
- package/dist/reducers/selectorReducer.d.ts.map +0 -1
- package/dist/reducers/workflowManagerReducer.d.ts.map +0 -1
- package/dist/session-selector-cli.d.ts.map +0 -1
- package/dist/stdio/agentBridge.d.ts.map +0 -1
- package/dist/stdio/index.d.ts.map +0 -1
- package/dist/stdio/protocol.d.ts.map +0 -1
- package/dist/stdio/stdioServer.d.ts.map +0 -1
- package/dist/stdio-cli.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/utils/clipboard.d.ts.map +0 -1
- package/dist/utils/constants.d.ts.map +0 -1
- package/dist/utils/highlightUtils.d.ts.map +0 -1
- package/dist/utils/inputUtils.d.ts.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/throttle.d.ts.map +0 -1
- package/dist/utils/toolParameterTransforms.d.ts.map +0 -1
- package/dist/utils/usageSummary.d.ts.map +0 -1
- package/dist/utils/version.d.ts.map +0 -1
- package/dist/utils/worktree.d.ts.map +0 -1
|
@@ -45,6 +45,11 @@ export declare class AgentBridge {
|
|
|
45
45
|
private deleteQueuedMessageById;
|
|
46
46
|
private getMessages;
|
|
47
47
|
private getFullMessageThread;
|
|
48
|
+
private compact;
|
|
49
|
+
private getBackgroundTaskOutput;
|
|
50
|
+
private stopBackgroundTask;
|
|
51
|
+
private getWorkflowRuns;
|
|
52
|
+
private stopWorkflowRun;
|
|
48
53
|
private setPermissionMode;
|
|
49
54
|
private getPermissionMode;
|
|
50
55
|
private getMcpServers;
|
|
@@ -79,4 +84,3 @@ export declare class RpcError extends Error {
|
|
|
79
84
|
constructor(code: number, message: string);
|
|
80
85
|
toJsonRpcError(): JsonRpcError;
|
|
81
86
|
}
|
|
82
|
-
//# sourceMappingURL=agentBridge.d.ts.map
|
|
@@ -16,20 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { Agent, listSessions, searchFiles, PromptHistoryManager, AuthService, PluginCore, } from "wave-agent-sdk";
|
|
18
18
|
import { INTERNAL_ERROR as PROTOCOL_INTERNAL_ERROR, METHOD_NOT_FOUND as PROTOCOL_METHOD_NOT_FOUND, } from "./protocol.js";
|
|
19
|
-
import { readFileSync } from "fs";
|
|
20
|
-
import path from "path";
|
|
21
|
-
import { fileURLToPath } from "url";
|
|
22
19
|
import { logger } from "../utils/logger.js";
|
|
23
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
24
|
-
const CLI_VERSION = (() => {
|
|
25
|
-
try {
|
|
26
|
-
const pkg = JSON.parse(readFileSync(path.resolve(__dirname, "../../package.json"), "utf-8"));
|
|
27
|
-
return pkg.version ?? "";
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return "";
|
|
31
|
-
}
|
|
32
|
-
})();
|
|
33
20
|
export class AgentBridge {
|
|
34
21
|
constructor(options) {
|
|
35
22
|
this.sessions = new Map();
|
|
@@ -125,6 +112,17 @@ export class AgentBridge {
|
|
|
125
112
|
return this.removeMarketplace(p.name, p.scope, p.workdir, sessionId);
|
|
126
113
|
case "updateMarketplace":
|
|
127
114
|
return this.updateMarketplace(p.name, p.workdir, sessionId);
|
|
115
|
+
case "compact":
|
|
116
|
+
return this.compact(p.customInstructions, sessionId);
|
|
117
|
+
// ── Background tasks ──
|
|
118
|
+
case "getBackgroundTaskOutput":
|
|
119
|
+
return this.getBackgroundTaskOutput(p.taskId, sessionId);
|
|
120
|
+
case "stopBackgroundTask":
|
|
121
|
+
return this.stopBackgroundTask(p.taskId, sessionId);
|
|
122
|
+
case "getWorkflowRuns":
|
|
123
|
+
return this.getWorkflowRuns(sessionId);
|
|
124
|
+
case "stopWorkflowRun":
|
|
125
|
+
return this.stopWorkflowRun(p.runId, sessionId);
|
|
128
126
|
default:
|
|
129
127
|
throw new RpcError(PROTOCOL_METHOD_NOT_FOUND, `Method not found: ${method}`);
|
|
130
128
|
}
|
|
@@ -170,16 +168,11 @@ export class AgentBridge {
|
|
|
170
168
|
agent,
|
|
171
169
|
storedConfig: { ...params },
|
|
172
170
|
});
|
|
173
|
-
if (params.clientVersion) {
|
|
174
|
-
// stdout 是 JSON-RPC 协议通道,诊断日志必须走 stderr 以免污染协议
|
|
175
|
-
process.stderr.write(`[agentBridge] clientVersion=${params.clientVersion} serverVersion=${CLI_VERSION}\n`);
|
|
176
|
-
}
|
|
177
171
|
return {
|
|
178
172
|
sessionId: agent.sessionId,
|
|
179
173
|
workingDirectory: agent.workingDirectory,
|
|
180
174
|
permissionMode: agent.getPermissionMode(),
|
|
181
175
|
latestTotalTokens: agent.latestTotalTokens,
|
|
182
|
-
serverVersion: CLI_VERSION,
|
|
183
176
|
};
|
|
184
177
|
}
|
|
185
178
|
async destroy(sessionId) {
|
|
@@ -320,6 +313,37 @@ export class AgentBridge {
|
|
|
320
313
|
const entry = this.requireSession(sessionId);
|
|
321
314
|
return entry.agent.getFullMessageThread();
|
|
322
315
|
}
|
|
316
|
+
async compact(customInstructions, sessionId) {
|
|
317
|
+
const entry = this.requireSession(sessionId);
|
|
318
|
+
await entry.agent.compact(customInstructions);
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
// ── Background tasks ──
|
|
322
|
+
getBackgroundTaskOutput(taskId, sessionId) {
|
|
323
|
+
const entry = this.requireSession(sessionId);
|
|
324
|
+
return { output: entry.agent.getBackgroundTaskOutput(taskId) };
|
|
325
|
+
}
|
|
326
|
+
stopBackgroundTask(taskId, sessionId) {
|
|
327
|
+
const entry = this.requireSession(sessionId);
|
|
328
|
+
const success = entry.agent.stopBackgroundTask(taskId);
|
|
329
|
+
return { success };
|
|
330
|
+
}
|
|
331
|
+
async getWorkflowRuns(sessionId) {
|
|
332
|
+
const entry = this.requireSession(sessionId);
|
|
333
|
+
const runs = await entry.agent.getWorkflowRuns();
|
|
334
|
+
return {
|
|
335
|
+
runs: runs.map((r) => {
|
|
336
|
+
const { completionPromise, ...rest } = r;
|
|
337
|
+
void completionPromise;
|
|
338
|
+
return rest;
|
|
339
|
+
}),
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
stopWorkflowRun(runId, sessionId) {
|
|
343
|
+
const entry = this.requireSession(sessionId);
|
|
344
|
+
entry.agent.stopWorkflowRun(runId);
|
|
345
|
+
return { success: true };
|
|
346
|
+
}
|
|
323
347
|
// ── Permissions ───────────────────────────────────────────────
|
|
324
348
|
async setPermissionMode(mode, sessionId) {
|
|
325
349
|
const entry = this.requireSession(sessionId);
|
|
@@ -376,16 +400,6 @@ export class AgentBridge {
|
|
|
376
400
|
return new Promise((resolve) => {
|
|
377
401
|
this.pendingPermissions.set(requestId, resolve);
|
|
378
402
|
this.emit("permissionRequest", { requestId, context }, ctx.registeredSessionId);
|
|
379
|
-
// 5-minute timeout → auto-deny
|
|
380
|
-
setTimeout(() => {
|
|
381
|
-
if (this.pendingPermissions.has(requestId)) {
|
|
382
|
-
this.pendingPermissions.delete(requestId);
|
|
383
|
-
resolve({
|
|
384
|
-
behavior: "deny",
|
|
385
|
-
message: "Permission request timed out",
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
}, 5 * 60 * 1000);
|
|
389
403
|
});
|
|
390
404
|
}
|
|
391
405
|
// ── Auth (global) ────────────────────────────────────────────
|
|
@@ -513,6 +527,21 @@ export class AgentBridge {
|
|
|
513
527
|
onTasksChange: (tasks) => {
|
|
514
528
|
this.emit("tasksChange", { tasks }, ctx.registeredSessionId);
|
|
515
529
|
},
|
|
530
|
+
onBackgroundTasksChange: (tasks) => {
|
|
531
|
+
const summaries = tasks.map((t) => ({
|
|
532
|
+
id: t.id,
|
|
533
|
+
type: t.type,
|
|
534
|
+
status: t.status,
|
|
535
|
+
startTime: t.startTime,
|
|
536
|
+
endTime: t.endTime,
|
|
537
|
+
command: t.command,
|
|
538
|
+
description: t.description,
|
|
539
|
+
exitCode: t.exitCode,
|
|
540
|
+
runtime: t.runtime,
|
|
541
|
+
outputPath: t.outputPath,
|
|
542
|
+
}));
|
|
543
|
+
this.emit("backgroundTasksChange", { tasks: summaries }, ctx.registeredSessionId);
|
|
544
|
+
},
|
|
516
545
|
onSessionIdChange: (newSessionId) => {
|
|
517
546
|
const oldSessionId = ctx.registeredSessionId;
|
|
518
547
|
// Emit with the OLD sessionId so the client's router can deliver it
|
|
@@ -554,6 +583,9 @@ export class AgentBridge {
|
|
|
554
583
|
onCompactBlockAdded: (content) => {
|
|
555
584
|
this.emit("compactBlockAdded", { content }, ctx.registeredSessionId);
|
|
556
585
|
},
|
|
586
|
+
onCompactionStateChange: (isCompacting) => {
|
|
587
|
+
this.emit("compactionStateChange", { isCompacting }, ctx.registeredSessionId);
|
|
588
|
+
},
|
|
557
589
|
};
|
|
558
590
|
}
|
|
559
591
|
findLastUserMessage(agent) {
|
package/dist/stdio/index.d.ts
CHANGED
package/dist/stdio/protocol.d.ts
CHANGED
|
@@ -34,9 +34,8 @@ export declare const INVALID_REQUEST = -32600;
|
|
|
34
34
|
export declare const METHOD_NOT_FOUND = -32601;
|
|
35
35
|
export declare const INVALID_PARAMS = -32602;
|
|
36
36
|
export declare const INTERNAL_ERROR = -32603;
|
|
37
|
-
export type RequestMethod = "initialize" | "destroy" | "restoreSession" | "listSessions" | "getSessionInfo" | "sendMessage" | "bang" | "abortMessage" | "clearMessages" | "rewindToMessage" | "deleteQueuedMessage" | "updateQueuedMessage" | "deleteQueuedMessageById" | "getMessages" | "getFullMessageThread" | "setPermissionMode" | "getPermissionMode" | "getMcpServers" | "connectMcpServer" | "disconnectMcpServer" | "getSlashCommands" | "searchFiles" | "getPromptHistory" | "searchPromptHistory" | "updateConfig" | "getAuthStatus" | "login" | "logout" | "listPlugins" | "installPlugin" | "uninstallPlugin" | "enablePlugin" | "disablePlugin" | "updatePlugin" | "listMarketplaces" | "addMarketplace" | "removeMarketplace" | "updateMarketplace";
|
|
37
|
+
export type RequestMethod = "initialize" | "destroy" | "restoreSession" | "listSessions" | "getSessionInfo" | "sendMessage" | "bang" | "abortMessage" | "clearMessages" | "rewindToMessage" | "deleteQueuedMessage" | "updateQueuedMessage" | "deleteQueuedMessageById" | "getMessages" | "getFullMessageThread" | "setPermissionMode" | "getPermissionMode" | "getMcpServers" | "connectMcpServer" | "disconnectMcpServer" | "getSlashCommands" | "searchFiles" | "getPromptHistory" | "searchPromptHistory" | "updateConfig" | "getAuthStatus" | "login" | "logout" | "listPlugins" | "installPlugin" | "uninstallPlugin" | "enablePlugin" | "disablePlugin" | "updatePlugin" | "listMarketplaces" | "addMarketplace" | "removeMarketplace" | "updateMarketplace" | "compact" | "getBackgroundTaskOutput" | "stopBackgroundTask" | "getWorkflowRuns" | "stopWorkflowRun";
|
|
38
38
|
export type ClientNotificationMethod = "permissionResponse";
|
|
39
|
-
export type ServerNotificationMethod = "messagesChange" | "userMessageAdded" | "assistantMessageAdded" | "assistantContentUpdated" | "assistantReasoningUpdated" | "toolBlockUpdated" | "errorBlockAdded" | "loadingChange" | "commandRunningChange" | "queuedMessagesChange" | "tasksChange" | "sessionIdChange" | "permissionModeChange" | "mcpServersChange" | "workdirChange" | "bangMessageAdded" | "bangMessageUpdated" | "bangMessageCompleted" | "notificationMessageAdded" | "permissionRequest" | "authUrl" | "compactBlockAdded";
|
|
39
|
+
export type ServerNotificationMethod = "messagesChange" | "userMessageAdded" | "assistantMessageAdded" | "assistantContentUpdated" | "assistantReasoningUpdated" | "toolBlockUpdated" | "errorBlockAdded" | "loadingChange" | "commandRunningChange" | "queuedMessagesChange" | "tasksChange" | "sessionIdChange" | "permissionModeChange" | "mcpServersChange" | "workdirChange" | "bangMessageAdded" | "bangMessageUpdated" | "bangMessageCompleted" | "notificationMessageAdded" | "permissionRequest" | "authUrl" | "compactBlockAdded" | "compactionStateChange" | "backgroundTasksChange";
|
|
40
40
|
export declare function isRequest(msg: unknown): msg is JsonRpcRequest;
|
|
41
41
|
export declare function isNotification(msg: unknown): msg is JsonRpcNotification;
|
|
42
|
-
//# sourceMappingURL=protocol.d.ts.map
|
package/dist/stdio-cli.d.ts
CHANGED
package/dist/types.d.ts
CHANGED
package/dist/utils/logger.d.ts
CHANGED
package/dist/utils/throttle.d.ts
CHANGED
|
@@ -12,4 +12,3 @@ export interface ThrottledFunction<T extends (...args: unknown[]) => void> {
|
|
|
12
12
|
* every `wait` milliseconds.
|
|
13
13
|
*/
|
|
14
14
|
export declare function throttle<T extends (...args: unknown[]) => void>(func: T, wait: number, options?: ThrottleOptions): ThrottledFunction<T>;
|
|
15
|
-
//# sourceMappingURL=throttle.d.ts.map
|
|
@@ -16,4 +16,3 @@ export declare function transformEditParameters(parameters: EditToolParameters):
|
|
|
16
16
|
* Forces type judgment based on tool name using type assertions
|
|
17
17
|
*/
|
|
18
18
|
export declare function transformToolBlockToChanges(toolName: string, parameters: string, startLineNumber?: number): Change[];
|
|
19
|
-
//# sourceMappingURL=toolParameterTransforms.d.ts.map
|
|
@@ -30,4 +30,3 @@ export declare function calculateTokenSummary(usages: Usage[]): Record<string, T
|
|
|
30
30
|
* @param sessionFilePath Optional session file path to display
|
|
31
31
|
*/
|
|
32
32
|
export declare function displayUsageSummary(usages: Usage[], sessionFilePath?: string): void;
|
|
33
|
-
//# sourceMappingURL=usageSummary.d.ts.map
|
package/dist/utils/version.d.ts
CHANGED
package/dist/utils/worktree.d.ts
CHANGED
|
@@ -11,12 +11,15 @@ export interface WorktreeSession {
|
|
|
11
11
|
* Create a new git worktree
|
|
12
12
|
* @param name Worktree name
|
|
13
13
|
* @param cwd Current working directory
|
|
14
|
+
* @param options Optional creation options
|
|
15
|
+
* @param options.baseRef "fresh" (default, origin/<default-branch>) | "head" (local HEAD)
|
|
14
16
|
* @returns Worktree session details
|
|
15
17
|
*/
|
|
16
|
-
export declare function createWorktree(name: string, cwd: string
|
|
18
|
+
export declare function createWorktree(name: string, cwd: string, options?: {
|
|
19
|
+
baseRef?: "fresh" | "head";
|
|
20
|
+
}): WorktreeSession;
|
|
17
21
|
/**
|
|
18
22
|
* Remove a git worktree and its associated branch
|
|
19
23
|
* @param session Worktree session details
|
|
20
24
|
*/
|
|
21
25
|
export declare function removeWorktree(session: WorktreeSession): void;
|
|
22
|
-
//# sourceMappingURL=worktree.d.ts.map
|
package/dist/utils/worktree.js
CHANGED
|
@@ -6,13 +6,16 @@ import { getDefaultRemoteBranch, getGitMainRepoRoot } from "wave-agent-sdk";
|
|
|
6
6
|
* Create a new git worktree
|
|
7
7
|
* @param name Worktree name
|
|
8
8
|
* @param cwd Current working directory
|
|
9
|
+
* @param options Optional creation options
|
|
10
|
+
* @param options.baseRef "fresh" (default, origin/<default-branch>) | "head" (local HEAD)
|
|
9
11
|
* @returns Worktree session details
|
|
10
12
|
*/
|
|
11
|
-
export function createWorktree(name, cwd) {
|
|
13
|
+
export function createWorktree(name, cwd, options) {
|
|
12
14
|
const repoRoot = getGitMainRepoRoot(cwd);
|
|
13
15
|
const worktreePath = path.join(repoRoot, ".wave", "worktrees", name);
|
|
14
16
|
const branchName = `worktree-${name}`;
|
|
15
|
-
const
|
|
17
|
+
const useHead = options?.baseRef === "head";
|
|
18
|
+
const baseBranch = useHead ? "HEAD" : getDefaultRemoteBranch(cwd);
|
|
16
19
|
// Ensure parent directory exists
|
|
17
20
|
const parentDir = path.dirname(worktreePath);
|
|
18
21
|
if (!fs.existsSync(parentDir)) {
|
|
@@ -70,8 +73,9 @@ export function createWorktree(name, cwd) {
|
|
|
70
73
|
throw new Error(`Failed to add existing worktree branch: ${innerError.message}`);
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
|
-
if (
|
|
74
|
-
stderr.includes("
|
|
76
|
+
if (!useHead &&
|
|
77
|
+
(stderr.includes("not a valid object name") ||
|
|
78
|
+
stderr.includes("unknown revision"))) {
|
|
75
79
|
// Base branch not fetched yet — try fetching then retrying
|
|
76
80
|
const branchNameOnly = baseBranch.split("/").pop();
|
|
77
81
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-code",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.8",
|
|
4
4
|
"description": "CLI-based code assistant powered by AI, built with React and Ink",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"semver": "^7.7.4",
|
|
42
42
|
"yargs": "^17.7.2",
|
|
43
43
|
"zod": "^3.23.8",
|
|
44
|
-
"wave-agent-sdk": "0.19.
|
|
44
|
+
"wave-agent-sdk": "0.19.8"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/react": "^19.1.8",
|
|
@@ -39,7 +39,7 @@ export const ConfirmationSelector: React.FC<ConfirmationSelectorProps> = ({
|
|
|
39
39
|
onCancel,
|
|
40
40
|
}) => {
|
|
41
41
|
const [state, dispatch] = useReducer(confirmationReducer, {
|
|
42
|
-
selectedOption:
|
|
42
|
+
selectedOption: "allow",
|
|
43
43
|
alternativeText: "",
|
|
44
44
|
alternativeCursorPosition: 0,
|
|
45
45
|
hasUserInput: false,
|
|
@@ -212,20 +212,6 @@ export const ConfirmationSelector: React.FC<ConfirmationSelectorProps> = ({
|
|
|
212
212
|
<Text>Do you want to proceed?</Text>
|
|
213
213
|
</Box>
|
|
214
214
|
<Box marginTop={1} flexDirection="column">
|
|
215
|
-
{toolName === EXIT_PLAN_MODE_TOOL_NAME && (
|
|
216
|
-
<Box key="clear-option">
|
|
217
|
-
<Text
|
|
218
|
-
color={state.selectedOption === "clear" ? "black" : "white"}
|
|
219
|
-
backgroundColor={
|
|
220
|
-
state.selectedOption === "clear" ? "yellow" : undefined
|
|
221
|
-
}
|
|
222
|
-
bold={state.selectedOption === "clear"}
|
|
223
|
-
>
|
|
224
|
-
{state.selectedOption === "clear" ? "> " : " "}
|
|
225
|
-
Yes, clear context and auto-accept edits
|
|
226
|
-
</Text>
|
|
227
|
-
</Box>
|
|
228
|
-
)}
|
|
229
215
|
<Box key="allow-option">
|
|
230
216
|
<Text
|
|
231
217
|
color={state.selectedOption === "allow" ? "black" : "white"}
|
|
@@ -254,6 +240,21 @@ export const ConfirmationSelector: React.FC<ConfirmationSelectorProps> = ({
|
|
|
254
240
|
</Text>
|
|
255
241
|
</Box>
|
|
256
242
|
)}
|
|
243
|
+
{(toolName === BASH_TOOL_NAME ||
|
|
244
|
+
toolName === EXIT_PLAN_MODE_TOOL_NAME) && (
|
|
245
|
+
<Box key="bypass-option">
|
|
246
|
+
<Text
|
|
247
|
+
color={state.selectedOption === "bypass" ? "black" : "white"}
|
|
248
|
+
backgroundColor={
|
|
249
|
+
state.selectedOption === "bypass" ? "yellow" : undefined
|
|
250
|
+
}
|
|
251
|
+
bold={state.selectedOption === "bypass"}
|
|
252
|
+
>
|
|
253
|
+
{state.selectedOption === "bypass" ? "> " : " "}
|
|
254
|
+
Yes, and bypass permissions
|
|
255
|
+
</Text>
|
|
256
|
+
</Box>
|
|
257
|
+
)}
|
|
257
258
|
<Box key="alternative-option">
|
|
258
259
|
<Text
|
|
259
260
|
color={
|
package/src/contexts/useChat.tsx
CHANGED
|
@@ -482,7 +482,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
482
482
|
|
|
483
483
|
// Inject worktree session into this agent's own DI container so system
|
|
484
484
|
// prompts and permission checks reflect the CLI -w worktree. This state is
|
|
485
|
-
// per-session, not process-global (see specs/
|
|
485
|
+
// per-session, not process-global (see docs/specs/multi-agent/worktree.md FR-042).
|
|
486
486
|
if (worktreeSession) {
|
|
487
487
|
const session: WorktreeSession = {
|
|
488
488
|
originalCwd: originalCwd ?? worktreeSession.repoRoot,
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import yargs from "yargs";
|
|
2
2
|
import { hideBin } from "yargs/helpers";
|
|
3
3
|
import { startCli } from "./cli.js";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Scope,
|
|
6
|
+
generateRandomName,
|
|
7
|
+
loadMergedWaveConfig,
|
|
8
|
+
type PermissionMode,
|
|
9
|
+
} from "wave-agent-sdk";
|
|
5
10
|
import { createWorktree, type WorktreeSession } from "./utils/worktree.js";
|
|
6
11
|
import path from "path";
|
|
7
12
|
import { readFileSync } from "fs";
|
|
@@ -320,7 +325,8 @@ export async function main() {
|
|
|
320
325
|
if (!name || name === "") {
|
|
321
326
|
name = generateRandomName();
|
|
322
327
|
}
|
|
323
|
-
|
|
328
|
+
const baseRef = loadMergedWaveConfig(originalCwd)?.worktree?.baseRef;
|
|
329
|
+
worktreeSession = createWorktree(name, originalCwd, { baseRef });
|
|
324
330
|
|
|
325
331
|
// Note: the full worktree session (originalCwd etc.) is injected into the
|
|
326
332
|
// agent's DI container after the agent is created in useChat.tsx. This keeps
|
package/src/print-cli.ts
CHANGED
|
@@ -154,8 +154,18 @@ export async function startPrintCli(options: PrintCliOptions): Promise<void> {
|
|
|
154
154
|
process.stdout.write("\n");
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
// Wait for running background tasks
|
|
158
|
-
|
|
157
|
+
// Wait for running background tasks/subagents to complete AND for the main
|
|
158
|
+
// agent to finish processing their completion notifications. The last
|
|
159
|
+
// background task flips status to "completed" before its notification is
|
|
160
|
+
// enqueued and before the main agent's follow-up turn runs, so
|
|
161
|
+
// hasRunningBackgroundWork alone becomes false while the main agent is
|
|
162
|
+
// still mid-turn — causing a TOCTOU race that aborts the final response.
|
|
163
|
+
// Including isLoading and queued notifications closes that gap.
|
|
164
|
+
while (
|
|
165
|
+
agent.hasRunningBackgroundWork ||
|
|
166
|
+
agent.isLoading ||
|
|
167
|
+
agent.hasPendingMessages
|
|
168
|
+
) {
|
|
159
169
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
160
170
|
}
|
|
161
171
|
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "wave-agent-sdk";
|
|
8
8
|
|
|
9
9
|
export interface ConfirmationState {
|
|
10
|
-
selectedOption: "
|
|
10
|
+
selectedOption: "auto" | "bypass" | "allow" | "alternative";
|
|
11
11
|
alternativeText: string;
|
|
12
12
|
alternativeCursorPosition: number;
|
|
13
13
|
hasUserInput: boolean;
|
|
@@ -99,13 +99,7 @@ export function confirmationReducer(
|
|
|
99
99
|
|
|
100
100
|
if (key.return) {
|
|
101
101
|
let decision: PermissionDecision | null = null;
|
|
102
|
-
if (state.selectedOption === "
|
|
103
|
-
decision = {
|
|
104
|
-
behavior: "allow",
|
|
105
|
-
newPermissionMode: "acceptEdits",
|
|
106
|
-
clearContext: true,
|
|
107
|
-
};
|
|
108
|
-
} else if (state.selectedOption === "allow") {
|
|
102
|
+
if (state.selectedOption === "allow") {
|
|
109
103
|
if (toolName === EXIT_PLAN_MODE_TOOL_NAME) {
|
|
110
104
|
decision = { behavior: "allow", newPermissionMode: "default" };
|
|
111
105
|
} else if (toolName === ENTER_PLAN_MODE_TOOL_NAME) {
|
|
@@ -134,6 +128,11 @@ export function confirmationReducer(
|
|
|
134
128
|
} else {
|
|
135
129
|
decision = { behavior: "allow", newPermissionMode: "acceptEdits" };
|
|
136
130
|
}
|
|
131
|
+
} else if (state.selectedOption === "bypass") {
|
|
132
|
+
decision = {
|
|
133
|
+
behavior: "allow",
|
|
134
|
+
newPermissionMode: "bypassPermissions",
|
|
135
|
+
};
|
|
137
136
|
} else if (state.alternativeText.trim()) {
|
|
138
137
|
decision = {
|
|
139
138
|
behavior: "deny",
|
|
@@ -174,9 +173,10 @@ export function confirmationReducer(
|
|
|
174
173
|
}
|
|
175
174
|
|
|
176
175
|
const availableOptions: ConfirmationState["selectedOption"][] = [];
|
|
177
|
-
if (toolName === EXIT_PLAN_MODE_TOOL_NAME) availableOptions.push("clear");
|
|
178
176
|
availableOptions.push("allow");
|
|
179
177
|
if (!hidePersistentOption) availableOptions.push("auto");
|
|
178
|
+
if (toolName === BASH_TOOL_NAME || toolName === EXIT_PLAN_MODE_TOOL_NAME)
|
|
179
|
+
availableOptions.push("bypass");
|
|
180
180
|
availableOptions.push("alternative");
|
|
181
181
|
|
|
182
182
|
if (key.upArrow) {
|