wave-code 0.10.4 → 0.11.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.
- package/dist/acp/agent.d.ts +1 -0
- package/dist/acp/agent.d.ts.map +1 -1
- package/dist/acp/agent.js +122 -18
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/App.js +4 -4
- package/dist/components/BackgroundTaskManager.d.ts.map +1 -1
- package/dist/components/BackgroundTaskManager.js +3 -2
- package/dist/components/ChatInterface.d.ts.map +1 -1
- package/dist/components/ChatInterface.js +2 -1
- package/dist/components/ConfirmationDetails.d.ts.map +1 -1
- package/dist/components/ConfirmationDetails.js +2 -2
- package/dist/components/ConfirmationSelector.d.ts.map +1 -1
- package/dist/components/ConfirmationSelector.js +20 -4
- package/dist/components/InputBox.d.ts +1 -1
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +1 -2
- package/dist/components/MessageList.d.ts +2 -1
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +18 -17
- package/dist/constants/commands.d.ts.map +1 -1
- package/dist/constants/commands.js +0 -6
- package/dist/contexts/useChat.d.ts +3 -2
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +32 -28
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -1
- package/dist/managers/inputHandlers.d.ts.map +1 -1
- package/dist/managers/inputHandlers.js +7 -8
- package/dist/managers/inputReducer.d.ts +2 -3
- package/dist/managers/inputReducer.d.ts.map +1 -1
- package/dist/managers/inputReducer.js +4 -4
- package/dist/print-cli.d.ts.map +1 -1
- package/dist/print-cli.js +5 -3
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/acp/agent.ts +147 -21
- package/src/cli.tsx +4 -0
- package/src/components/App.tsx +8 -0
- package/src/components/BackgroundTaskManager.tsx +17 -1
- package/src/components/ChatInterface.tsx +4 -1
- package/src/components/ConfirmationDetails.tsx +5 -1
- package/src/components/ConfirmationSelector.tsx +18 -4
- package/src/components/InputBox.tsx +1 -2
- package/src/components/MessageList.tsx +21 -18
- package/src/constants/commands.ts +0 -6
- package/src/contexts/useChat.tsx +49 -35
- package/src/hooks/useInputManager.ts +4 -1
- package/src/index.ts +43 -1
- package/src/managers/inputHandlers.ts +8 -10
- package/src/managers/inputReducer.ts +6 -6
- package/src/print-cli.ts +6 -2
- package/src/types.ts +2 -0
package/dist/acp/agent.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export declare class WaveAcpAgent implements AcpAgent {
|
|
|
18
18
|
setSessionConfigOption(params: SetSessionConfigOptionRequest): Promise<SetSessionConfigOptionResponse>;
|
|
19
19
|
prompt(params: PromptRequest): Promise<PromptResponse>;
|
|
20
20
|
cancel(params: CancelNotification): Promise<void>;
|
|
21
|
+
private getAllowAlwaysName;
|
|
21
22
|
private handlePermissionRequest;
|
|
22
23
|
private getToolContentAsync;
|
|
23
24
|
private getToolContent;
|
package/dist/acp/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/acp/agent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/acp/agent.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,KAAK,KAAK,IAAI,QAAQ,EACtB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EAUzB,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,EAClC,KAAK,8BAA8B,EAMpC,MAAM,0BAA0B,CAAC;AAElC,qBAAa,YAAa,YAAW,QAAQ;IAC3C,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,UAAU,CAAsB;gBAE5B,UAAU,EAAE,mBAAmB;IAI3C,OAAO,CAAC,mBAAmB;IAkC3B,OAAO,CAAC,uBAAuB;YAmBjB,gBAAgB;IASxB,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAwBzC,YAAY,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAI5C,WAAW;IAiEnB,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAalE,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAWrE,YAAY,CAChB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,oBAAoB,CAAC;IAuB1B,qBAAqB,CACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAc7B,SAAS,CACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAO7B,cAAc,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAc5D,sBAAsB,CAC1B,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,8BAA8B,CAAC;IAqBpC,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAyDtD,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IASvD,OAAO,CAAC,kBAAkB;YA2BZ,uBAAuB;YAsKvB,mBAAmB;IA6EjC,OAAO,CAAC,cAAc;IA6CtB,OAAO,CAAC,gBAAgB;IAmCxB,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,eAAe;CAgMxB"}
|
package/dist/acp/agent.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Agent as WaveAgent, listSessions as listWaveSessions, listAllSessions as listAllWaveSessions, deleteSession as deleteWaveSession, truncateContent, } from "wave-agent-sdk";
|
|
1
|
+
import { Agent as WaveAgent, listSessions as listWaveSessions, listAllSessions as listAllWaveSessions, deleteSession as deleteWaveSession, truncateContent, BASH_TOOL_NAME, EDIT_TOOL_NAME, WRITE_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, } from "wave-agent-sdk";
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { logger } from "../utils/logger.js";
|
|
@@ -32,6 +32,11 @@ export class WaveAcpAgent {
|
|
|
32
32
|
name: "Bypass Permissions",
|
|
33
33
|
description: "Automatically accept all tool calls",
|
|
34
34
|
},
|
|
35
|
+
{
|
|
36
|
+
id: "dontAsk",
|
|
37
|
+
name: "Don't Ask",
|
|
38
|
+
description: "Automatically deny restricted tools unless pre-approved",
|
|
39
|
+
},
|
|
35
40
|
],
|
|
36
41
|
};
|
|
37
42
|
}
|
|
@@ -48,6 +53,7 @@ export class WaveAcpAgent {
|
|
|
48
53
|
{ value: "acceptEdits", name: "Accept Edits" },
|
|
49
54
|
{ value: "plan", name: "Plan" },
|
|
50
55
|
{ value: "bypassPermissions", name: "Bypass Permissions" },
|
|
56
|
+
{ value: "dontAsk", name: "Don't Ask" },
|
|
51
57
|
],
|
|
52
58
|
},
|
|
53
59
|
];
|
|
@@ -74,6 +80,10 @@ export class WaveAcpAgent {
|
|
|
74
80
|
list: {},
|
|
75
81
|
close: {},
|
|
76
82
|
},
|
|
83
|
+
promptCapabilities: {
|
|
84
|
+
image: true,
|
|
85
|
+
embeddedContext: true,
|
|
86
|
+
},
|
|
77
87
|
},
|
|
78
88
|
};
|
|
79
89
|
}
|
|
@@ -86,7 +96,7 @@ export class WaveAcpAgent {
|
|
|
86
96
|
const agent = await WaveAgent.create({
|
|
87
97
|
workdir: cwd,
|
|
88
98
|
restoreSessionId: sessionId,
|
|
89
|
-
stream:
|
|
99
|
+
stream: true,
|
|
90
100
|
canUseTool: (context) => {
|
|
91
101
|
if (!agentRef.instance) {
|
|
92
102
|
throw new Error("Agent instance not yet initialized");
|
|
@@ -210,27 +220,39 @@ export class WaveAcpAgent {
|
|
|
210
220
|
async prompt(params) {
|
|
211
221
|
const { sessionId, prompt } = params;
|
|
212
222
|
logger.info(`Received prompt for session ${sessionId}`);
|
|
223
|
+
logger.debug(`Prompt content for session ${sessionId}:`, prompt);
|
|
213
224
|
const agent = this.agents.get(sessionId);
|
|
214
225
|
if (!agent) {
|
|
215
226
|
logger.error(`Session ${sessionId} not found`);
|
|
216
227
|
throw new Error(`Session ${sessionId} not found`);
|
|
217
228
|
}
|
|
218
229
|
// Map ACP prompt to Wave Agent sendMessage
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
.
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
230
|
+
const textBlocks = [];
|
|
231
|
+
const images = [];
|
|
232
|
+
for (const block of prompt) {
|
|
233
|
+
if (block.type === "text") {
|
|
234
|
+
textBlocks.push(block.text);
|
|
235
|
+
}
|
|
236
|
+
else if (block.type === "resource_link") {
|
|
237
|
+
const link = block;
|
|
238
|
+
textBlocks.push(`[${link.name}](${link.uri})`);
|
|
239
|
+
}
|
|
240
|
+
else if (block.type === "resource") {
|
|
241
|
+
const embedded = block;
|
|
242
|
+
textBlocks.push(`[Resource](${embedded.resource.uri})`);
|
|
243
|
+
}
|
|
244
|
+
else if (block.type === "image") {
|
|
245
|
+
const img = block;
|
|
246
|
+
images.push({
|
|
247
|
+
path: img.data.startsWith("data:")
|
|
248
|
+
? img.data
|
|
249
|
+
: `data:${img.mimeType};base64,${img.data}`,
|
|
250
|
+
mimeType: img.mimeType,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const textContent = textBlocks.join("");
|
|
232
255
|
try {
|
|
233
|
-
logger.info(`Sending message to agent: ${textContent.substring(0, 50)}...`);
|
|
234
256
|
await agent.sendMessage(textContent, images.length > 0 ? images : undefined);
|
|
235
257
|
logger.info(`Message sent successfully for session ${sessionId}`);
|
|
236
258
|
return {
|
|
@@ -256,6 +278,29 @@ export class WaveAcpAgent {
|
|
|
256
278
|
agent.abortMessage();
|
|
257
279
|
}
|
|
258
280
|
}
|
|
281
|
+
getAllowAlwaysName(context) {
|
|
282
|
+
if (context.toolName === BASH_TOOL_NAME) {
|
|
283
|
+
const command = context.toolInput?.command || "";
|
|
284
|
+
if (command.startsWith("mkdir")) {
|
|
285
|
+
return "Yes, and auto-accept edits";
|
|
286
|
+
}
|
|
287
|
+
if (context.suggestedPrefix) {
|
|
288
|
+
const prefix = context.suggestedPrefix.length > 12
|
|
289
|
+
? context.suggestedPrefix.substring(0, 9) + "..."
|
|
290
|
+
: context.suggestedPrefix;
|
|
291
|
+
return `Yes, always allow ${prefix}`;
|
|
292
|
+
}
|
|
293
|
+
return "Yes, always allow this command";
|
|
294
|
+
}
|
|
295
|
+
if (context.toolName === EDIT_TOOL_NAME ||
|
|
296
|
+
context.toolName === WRITE_TOOL_NAME) {
|
|
297
|
+
return "Yes, and auto-accept edits";
|
|
298
|
+
}
|
|
299
|
+
if (context.toolName === EXIT_PLAN_MODE_TOOL_NAME) {
|
|
300
|
+
return "Yes, auto-accept edits";
|
|
301
|
+
}
|
|
302
|
+
return "Allow Always";
|
|
303
|
+
}
|
|
259
304
|
async handlePermissionRequest(sessionId, context) {
|
|
260
305
|
logger.info(`Handling permission request for ${context.toolName} in session ${sessionId}`);
|
|
261
306
|
const agent = this.agents.get(sessionId);
|
|
@@ -277,7 +322,7 @@ export class WaveAcpAgent {
|
|
|
277
322
|
const displayTitle = effectiveName && effectiveCompactParams
|
|
278
323
|
? `${effectiveName}: ${effectiveCompactParams}`
|
|
279
324
|
: effectiveName || "Tool Call";
|
|
280
|
-
|
|
325
|
+
let options = [
|
|
281
326
|
{
|
|
282
327
|
optionId: "allow_once",
|
|
283
328
|
name: "Allow Once",
|
|
@@ -294,6 +339,36 @@ export class WaveAcpAgent {
|
|
|
294
339
|
kind: "reject_once",
|
|
295
340
|
},
|
|
296
341
|
];
|
|
342
|
+
if (context.toolName === BASH_TOOL_NAME ||
|
|
343
|
+
context.toolName === EDIT_TOOL_NAME ||
|
|
344
|
+
context.toolName === WRITE_TOOL_NAME) {
|
|
345
|
+
options = [
|
|
346
|
+
{
|
|
347
|
+
optionId: "allow_once",
|
|
348
|
+
name: "Yes, proceed",
|
|
349
|
+
kind: "allow_once",
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
optionId: "allow_always",
|
|
353
|
+
name: this.getAllowAlwaysName(context),
|
|
354
|
+
kind: "allow_always",
|
|
355
|
+
},
|
|
356
|
+
];
|
|
357
|
+
}
|
|
358
|
+
else if (context.toolName === EXIT_PLAN_MODE_TOOL_NAME) {
|
|
359
|
+
options = [
|
|
360
|
+
{
|
|
361
|
+
optionId: "allow_once",
|
|
362
|
+
name: "Yes, manually approve edits",
|
|
363
|
+
kind: "allow_once",
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
optionId: "allow_always",
|
|
367
|
+
name: "Yes, auto-accept edits",
|
|
368
|
+
kind: "allow_always",
|
|
369
|
+
},
|
|
370
|
+
];
|
|
371
|
+
}
|
|
297
372
|
const content = context.toolName
|
|
298
373
|
? await this.getToolContentAsync(context.toolName, context.toolInput, workdir)
|
|
299
374
|
: undefined;
|
|
@@ -324,11 +399,31 @@ export class WaveAcpAgent {
|
|
|
324
399
|
logger.info(`User selected permission option: ${selectedOptionId}`);
|
|
325
400
|
switch (selectedOptionId) {
|
|
326
401
|
case "allow_always":
|
|
402
|
+
if (context.toolName === BASH_TOOL_NAME) {
|
|
403
|
+
const command = context.toolInput?.command || "";
|
|
404
|
+
const rule = context.suggestedPrefix
|
|
405
|
+
? `${context.suggestedPrefix}*`
|
|
406
|
+
: command;
|
|
407
|
+
return {
|
|
408
|
+
behavior: "allow",
|
|
409
|
+
newPermissionRule: `${BASH_TOOL_NAME}(${rule})`,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
if (context.toolName === EDIT_TOOL_NAME ||
|
|
413
|
+
context.toolName === WRITE_TOOL_NAME) {
|
|
414
|
+
return {
|
|
415
|
+
behavior: "allow",
|
|
416
|
+
newPermissionMode: "acceptEdits",
|
|
417
|
+
};
|
|
418
|
+
}
|
|
327
419
|
return {
|
|
328
420
|
behavior: "allow",
|
|
329
|
-
newPermissionRule:
|
|
421
|
+
newPermissionRule: context.toolName,
|
|
330
422
|
};
|
|
331
423
|
case "allow_once":
|
|
424
|
+
if (context.toolName === EXIT_PLAN_MODE_TOOL_NAME) {
|
|
425
|
+
return { behavior: "allow", newPermissionMode: "default" };
|
|
426
|
+
}
|
|
332
427
|
return { behavior: "allow" };
|
|
333
428
|
case "reject_once":
|
|
334
429
|
return { behavior: "deny", message: "Rejected by user" };
|
|
@@ -434,6 +529,15 @@ export class WaveAcpAgent {
|
|
|
434
529
|
newText: parameters.new_string,
|
|
435
530
|
});
|
|
436
531
|
}
|
|
532
|
+
else if (name === EXIT_PLAN_MODE_TOOL_NAME) {
|
|
533
|
+
contents.push({
|
|
534
|
+
type: "content",
|
|
535
|
+
content: {
|
|
536
|
+
type: "text",
|
|
537
|
+
text: parameters.plan_content,
|
|
538
|
+
},
|
|
539
|
+
});
|
|
540
|
+
}
|
|
437
541
|
}
|
|
438
542
|
if (shortResult) {
|
|
439
543
|
contents.push({
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAgEjE"}
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { App } from "./components/App.js";
|
|
|
4
4
|
import { cleanupLogs } from "./utils/logger.js";
|
|
5
5
|
import { removeWorktree } from "./utils/worktree.js";
|
|
6
6
|
export async function startCli(options) {
|
|
7
|
-
const { restoreSessionId, continueLastSession, bypassPermissions, permissionMode, pluginDirs, tools, worktreeSession, workdir, version, model, } = options;
|
|
7
|
+
const { restoreSessionId, continueLastSession, bypassPermissions, permissionMode, pluginDirs, tools, allowedTools, disallowedTools, worktreeSession, workdir, version, model, } = options;
|
|
8
8
|
// Continue with ink-based UI for normal mode
|
|
9
9
|
let shouldRemoveWorktree = false;
|
|
10
10
|
const handleExit = (shouldRemove) => {
|
|
@@ -12,7 +12,7 @@ export async function startCli(options) {
|
|
|
12
12
|
unmount();
|
|
13
13
|
};
|
|
14
14
|
// Render the application
|
|
15
|
-
const { unmount, waitUntilExit } = render(_jsx(App, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, tools: tools, worktreeSession: worktreeSession, workdir: workdir, version: version, model: model, onExit: handleExit }), { exitOnCtrlC: false });
|
|
15
|
+
const { unmount, waitUntilExit } = render(_jsx(App, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, tools: tools, allowedTools: allowedTools, disallowedTools: disallowedTools, worktreeSession: worktreeSession, workdir: workdir, version: version, model: model, onExit: handleExit }), { exitOnCtrlC: false });
|
|
16
16
|
// Wait for the app to finish unmounting
|
|
17
17
|
await waitUntilExit();
|
|
18
18
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAWxE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,UAAU,QAAS,SAAQ,YAAY;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAWxE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,UAAU,QAAS,SAAQ,YAAY;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC;AAgJD,eAAO,MAAM,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAmClC,CAAC"}
|
package/dist/components/App.js
CHANGED
|
@@ -6,7 +6,7 @@ import { ChatProvider, useChat } from "../contexts/useChat.js";
|
|
|
6
6
|
import { AppProvider } from "../contexts/useAppConfig.js";
|
|
7
7
|
import { WorktreeExitPrompt } from "./WorktreeExitPrompt.js";
|
|
8
8
|
import { hasUncommittedChanges, hasNewCommits, getDefaultRemoteBranch, } from "wave-agent-sdk";
|
|
9
|
-
const AppWithProviders = ({ bypassPermissions, permissionMode, pluginDirs, tools, worktreeSession, workdir, version, model, onExit, }) => {
|
|
9
|
+
const AppWithProviders = ({ bypassPermissions, permissionMode, pluginDirs, tools, allowedTools, disallowedTools, worktreeSession, workdir, version, model, onExit, }) => {
|
|
10
10
|
const [isExiting, setIsExiting] = useState(false);
|
|
11
11
|
const [worktreeStatus, setWorktreeStatus] = useState(null);
|
|
12
12
|
const handleSignal = useCallback(async () => {
|
|
@@ -48,7 +48,7 @@ const AppWithProviders = ({ bypassPermissions, permissionMode, pluginDirs, tools
|
|
|
48
48
|
if (isExiting && worktreeSession && worktreeStatus) {
|
|
49
49
|
return (_jsx(WorktreeExitPrompt, { name: worktreeSession.name, path: worktreeSession.path, hasUncommittedChanges: worktreeStatus.hasUncommittedChanges, hasNewCommits: worktreeStatus.hasNewCommits, onKeep: () => onExit(false), onRemove: () => onExit(true), onCancel: () => setIsExiting(false) }));
|
|
50
50
|
}
|
|
51
|
-
return (_jsx(ChatProvider, { bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, tools: tools, workdir: workdir, worktreeSession: worktreeSession, version: version, model: model, children: _jsx(ChatInterfaceWithRemount, {}) }));
|
|
51
|
+
return (_jsx(ChatProvider, { bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, tools: tools, allowedTools: allowedTools, disallowedTools: disallowedTools, workdir: workdir, worktreeSession: worktreeSession, version: version, model: model, children: _jsx(ChatInterfaceWithRemount, {}) }));
|
|
52
52
|
};
|
|
53
53
|
const ChatInterfaceWithRemount = () => {
|
|
54
54
|
const { stdout } = useStdout();
|
|
@@ -86,6 +86,6 @@ const ChatInterfaceWithRemount = () => {
|
|
|
86
86
|
]);
|
|
87
87
|
return _jsx(ChatInterface, {}, remountKey);
|
|
88
88
|
};
|
|
89
|
-
export const App = ({ restoreSessionId, continueLastSession, bypassPermissions, permissionMode, pluginDirs, tools, worktreeSession, workdir, version, model, onExit, }) => {
|
|
90
|
-
return (_jsx(AppProvider, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, children: _jsx(AppWithProviders, { bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, tools: tools, worktreeSession: worktreeSession, workdir: workdir, version: version, model: model, onExit: onExit }) }));
|
|
89
|
+
export const App = ({ restoreSessionId, continueLastSession, bypassPermissions, permissionMode, pluginDirs, tools, allowedTools, disallowedTools, worktreeSession, workdir, version, model, onExit, }) => {
|
|
90
|
+
return (_jsx(AppProvider, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, children: _jsx(AppWithProviders, { bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, tools: tools, allowedTools: allowedTools, disallowedTools: disallowedTools, worktreeSession: worktreeSession, workdir: workdir, version: version, model: model, onExit: onExit }) }));
|
|
91
91
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackgroundTaskManager.d.ts","sourceRoot":"","sources":["../../src/components/BackgroundTaskManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"BackgroundTaskManager.d.ts","sourceRoot":"","sources":["../../src/components/BackgroundTaskManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAenD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CA6UtE,CAAC"}
|
|
@@ -20,6 +20,7 @@ export const BackgroundTaskManager = ({ onCancel, }) => {
|
|
|
20
20
|
startTime: task.startTime,
|
|
21
21
|
exitCode: task.exitCode,
|
|
22
22
|
runtime: task.runtime,
|
|
23
|
+
outputPath: task.outputPath,
|
|
23
24
|
})));
|
|
24
25
|
}, [backgroundTasks]);
|
|
25
26
|
// Load detail output for selected task
|
|
@@ -101,7 +102,7 @@ export const BackgroundTaskManager = ({ onCancel, }) => {
|
|
|
101
102
|
setViewMode("list");
|
|
102
103
|
return null;
|
|
103
104
|
}
|
|
104
|
-
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)] }))] }) })] }), 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: detailOutput.stdout.split("\n").slice(-10).join("\n") }) })] })), 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: detailOutput.stderr.split("\n").slice(-10).join("\n") }) })] })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: [task.status === "running" ? "k to stop · " : "", "Esc to go back"] }) })] }));
|
|
105
|
+
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: detailOutput.stdout.split("\n").slice(-10).join("\n") }) })] })), 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: detailOutput.stderr.split("\n").slice(-10).join("\n") }) })] })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: [task.status === "running" ? "k to stop · " : "", "Esc to go back"] }) })] }));
|
|
105
106
|
}
|
|
106
107
|
if (!backgroundTasks) {
|
|
107
108
|
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" })] }));
|
|
@@ -116,7 +117,7 @@ export const BackgroundTaskManager = ({ onCancel, }) => {
|
|
|
116
117
|
? "green"
|
|
117
118
|
: task.status === "completed"
|
|
118
119
|
? "blue"
|
|
119
|
-
: "red", children: [" ", "(", task.status, ")"] })] }), isSelected && (_jsx(Box, { marginLeft: 4, flexDirection: "column", children: _jsxs(Text, { color: "gray", dimColor: true, children: ["
|
|
120
|
+
: "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 &&
|
|
120
121
|
` | Runtime: ${formatDuration(task.runtime)}`, task.exitCode !== undefined && ` | Exit: ${task.exitCode}`] }) }))] }, task.id));
|
|
121
122
|
}) }), _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"] }) })] }));
|
|
122
123
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAatE,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAatE,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EA0KjC,CAAC"}
|
|
@@ -17,6 +17,7 @@ export const ChatInterface = () => {
|
|
|
17
17
|
const [isConfirmationTooTall, setIsConfirmationTooTall] = useState(false);
|
|
18
18
|
const { messages, isLoading, isCommandRunning, isCompressing, sendMessage, abortMessage, mcpServers, connectMcpServer, disconnectMcpServer, isExpanded, sessionId, latestTotalTokens, slashCommands, hasSlashCommand, isConfirmationVisible, confirmingTool, handleConfirmationDecision, handleConfirmationCancel: originalHandleConfirmationCancel, setWasLastDetailsTooTall, version, workdir, getModelConfig, } = useChat();
|
|
19
19
|
const model = getModelConfig().model;
|
|
20
|
+
const displayMessages = messages;
|
|
20
21
|
const handleDetailsHeightMeasured = useCallback((height) => {
|
|
21
22
|
setDetailsHeight(height);
|
|
22
23
|
}, []);
|
|
@@ -74,7 +75,7 @@ export const ChatInterface = () => {
|
|
|
74
75
|
]);
|
|
75
76
|
if (!sessionId)
|
|
76
77
|
return null;
|
|
77
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(MessageList, { messages:
|
|
78
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(MessageList, { messages: displayMessages, isExpanded: isExpanded, forceStatic: isConfirmationVisible && isConfirmationTooTall, isFinished: !isLoading && !isCommandRunning && !isCompressing, version: version, workdir: workdir, model: model, onDynamicBlocksHeightMeasured: handleDynamicBlocksHeightMeasured }), (isLoading || isCommandRunning || isCompressing) &&
|
|
78
79
|
!isConfirmationVisible &&
|
|
79
80
|
!isExpanded && (_jsx(LoadingIndicator, { isLoading: isLoading, isCommandRunning: isCommandRunning, isCompressing: isCompressing, latestTotalTokens: latestTotalTokens })), !isConfirmationVisible && !isExpanded && _jsx(TaskList, {}), isConfirmationVisible && (_jsxs(_Fragment, { children: [_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, isExpanded: isExpanded, onHeightMeasured: handleDetailsHeightMeasured, isStatic: isConfirmationTooTall }), _jsx(ConfirmationSelector, { toolName: confirmingTool.name, toolInput: confirmingTool.input, suggestedPrefix: confirmingTool.suggestedPrefix, hidePersistentOption: confirmingTool.hidePersistentOption, isExpanded: isExpanded, onDecision: wrappedHandleConfirmationDecision, onCancel: handleConfirmationCancel, onAbort: abortMessage, onHeightMeasured: handleSelectorHeightMeasured })] })), !isConfirmationVisible && !isExpanded && (_jsxs(_Fragment, { children: [_jsx(QueuedMessageList, {}), _jsx(InputBox, { isLoading: isLoading, isCommandRunning: isCommandRunning, sendMessage: sendMessage, abortMessage: abortMessage, mcpServers: mcpServers, connectMcpServer: connectMcpServer, disconnectMcpServer: disconnectMcpServer, slashCommands: slashCommands, hasSlashCommand: hasSlashCommand })] }))] }));
|
|
80
81
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfirmationDetails.d.ts","sourceRoot":"","sources":["../../src/components/ConfirmationDetails.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAqCvD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,
|
|
1
|
+
{"version":3,"file":"ConfirmationDetails.d.ts","sourceRoot":"","sources":["../../src/components/ConfirmationDetails.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAqCvD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CA8DlE,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useLayoutEffect, useRef } from "react";
|
|
2
|
+
import React, { useLayoutEffect, useRef } from "react";
|
|
3
3
|
import { Box, Text, useStdout, measureElement, Static } from "ink";
|
|
4
4
|
import { BASH_TOOL_NAME, EDIT_TOOL_NAME, WRITE_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, ASK_USER_QUESTION_TOOL_NAME, } from "wave-agent-sdk";
|
|
5
5
|
import { DiffDisplay } from "./DiffDisplay.js";
|
|
@@ -39,7 +39,7 @@ export const ConfirmationDetails = ({ toolName, toolInput, isExpanded = false, o
|
|
|
39
39
|
toolName === EXIT_PLAN_MODE_TOOL_NAME &&
|
|
40
40
|
!!toolInput?.plan_content && (_jsx(PlanDisplay, { plan: toolInput.plan_content, isExpanded: isExpanded }))] }));
|
|
41
41
|
if (isStatic) {
|
|
42
|
-
return _jsx(Static, { items: [1], children: () => content });
|
|
42
|
+
return (_jsx(Static, { items: [1], children: (item) => _jsx(React.Fragment, { children: content }, item) }));
|
|
43
43
|
}
|
|
44
44
|
return content;
|
|
45
45
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfirmationSelector.d.ts","sourceRoot":"","sources":["../../src/components/ConfirmationSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuD,MAAM,OAAO,CAAC;AAE5E,OAAO,KAAK,EAAE,kBAAkB,EAAwB,MAAM,gBAAgB,CAAC;AAgB/E,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AASD,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,
|
|
1
|
+
{"version":3,"file":"ConfirmationSelector.d.ts","sourceRoot":"","sources":["../../src/components/ConfirmationSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuD,MAAM,OAAO,CAAC;AAE5E,OAAO,KAAK,EAAE,kBAAkB,EAAwB,MAAM,gBAAgB,CAAC;AAgB/E,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AASD,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CA2nBpE,CAAC"}
|
|
@@ -49,11 +49,18 @@ export const ConfirmationSelector = ({ toolName, toolInput, suggestedPrefix, hid
|
|
|
49
49
|
return "Yes, auto-accept edits";
|
|
50
50
|
}
|
|
51
51
|
if (toolName === BASH_TOOL_NAME) {
|
|
52
|
+
const command = toolInput?.command || "";
|
|
53
|
+
if (command.trim().startsWith("mkdir")) {
|
|
54
|
+
return "Yes, and auto-accept edits";
|
|
55
|
+
}
|
|
52
56
|
if (suggestedPrefix) {
|
|
53
57
|
return `Yes, and don't ask again for: ${suggestedPrefix}`;
|
|
54
58
|
}
|
|
55
59
|
return "Yes, and don't ask again for this command in this workdir";
|
|
56
60
|
}
|
|
61
|
+
if (toolName.startsWith("mcp__")) {
|
|
62
|
+
return `Yes, and don't ask again for: ${toolName}`;
|
|
63
|
+
}
|
|
57
64
|
return "Yes, and auto-accept edits";
|
|
58
65
|
};
|
|
59
66
|
useInput((input, key) => {
|
|
@@ -292,10 +299,19 @@ export const ConfirmationSelector = ({ toolName, toolInput, suggestedPrefix, hid
|
|
|
292
299
|
}
|
|
293
300
|
else if (state.selectedOption === "auto") {
|
|
294
301
|
if (toolName === BASH_TOOL_NAME) {
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
:
|
|
298
|
-
|
|
302
|
+
const command = toolInput?.command || "";
|
|
303
|
+
if (command.trim().startsWith("mkdir")) {
|
|
304
|
+
onDecision({ behavior: "allow", newPermissionMode: "acceptEdits" });
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
const rule = suggestedPrefix
|
|
308
|
+
? `Bash(${suggestedPrefix}*)`
|
|
309
|
+
: `Bash(${toolInput?.command})`;
|
|
310
|
+
onDecision({ behavior: "allow", newPermissionRule: rule });
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
else if (toolName.startsWith("mcp__")) {
|
|
314
|
+
onDecision({ behavior: "allow", newPermissionRule: toolName });
|
|
299
315
|
}
|
|
300
316
|
else {
|
|
301
317
|
onDecision({ behavior: "allow", newPermissionMode: "acceptEdits" });
|
|
@@ -9,7 +9,7 @@ export interface InputBoxProps {
|
|
|
9
9
|
sendMessage?: (message: string, images?: Array<{
|
|
10
10
|
path: string;
|
|
11
11
|
mimeType: string;
|
|
12
|
-
}>) => void;
|
|
12
|
+
}>, longTextMap?: Record<string, string>) => void;
|
|
13
13
|
abortMessage?: () => void;
|
|
14
14
|
mcpServers?: McpServerStatus[];
|
|
15
15
|
connectMcpServer?: (serverName: string) => Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAezC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,mDACe,CAAC;AAEnD,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAezC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,mDACe,CAAC;AAEnD,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,EAClD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACjC,IAAI,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAE1B,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAClD;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA8O5C,CAAC"}
|
|
@@ -16,7 +16,7 @@ import { useChat } from "../contexts/useChat.js";
|
|
|
16
16
|
export const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
|
|
17
17
|
export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
|
|
18
18
|
export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
|
|
19
|
-
const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread,
|
|
19
|
+
const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, sessionId, workingDirectory, } = useChat();
|
|
20
20
|
// Input manager with all input state and functionality (including images)
|
|
21
21
|
const { inputText, cursorPosition,
|
|
22
22
|
// Image management
|
|
@@ -40,7 +40,6 @@ export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mc
|
|
|
40
40
|
onAbortMessage: abortMessage,
|
|
41
41
|
onBackgroundCurrentTask: backgroundCurrentTask,
|
|
42
42
|
onPermissionModeChange: setChatPermissionMode,
|
|
43
|
-
onClearMessages: clearMessages,
|
|
44
43
|
sessionId,
|
|
45
44
|
workdir: workingDirectory,
|
|
46
45
|
getFullMessageThread,
|
|
@@ -4,10 +4,11 @@ export interface MessageListProps {
|
|
|
4
4
|
messages: Message[];
|
|
5
5
|
isExpanded?: boolean;
|
|
6
6
|
forceStatic?: boolean;
|
|
7
|
+
isFinished?: boolean;
|
|
7
8
|
version?: string;
|
|
8
9
|
workdir?: string;
|
|
9
10
|
model?: string;
|
|
10
11
|
onDynamicBlocksHeightMeasured?: (height: number) => void;
|
|
11
12
|
}
|
|
12
|
-
export declare const MessageList: React.MemoExoticComponent<({ messages, isExpanded, forceStatic, version, workdir, model, onDynamicBlocksHeightMeasured, }: MessageListProps) => import("react/jsx-runtime").JSX.Element>;
|
|
13
|
+
export declare const MessageList: React.MemoExoticComponent<({ messages, isExpanded, forceStatic, isFinished, version, workdir, model, onDynamicBlocksHeightMeasured, }: MessageListProps) => import("react/jsx-runtime").JSX.Element>;
|
|
13
14
|
//# sourceMappingURL=MessageList.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAGvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAGvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED,eAAO,MAAM,WAAW,yIAUnB,gBAAgB,6CA+GpB,CAAC"}
|
|
@@ -3,22 +3,16 @@ import React, { useLayoutEffect, useRef } from "react";
|
|
|
3
3
|
import os from "os";
|
|
4
4
|
import { Box, Text, Static, measureElement } from "ink";
|
|
5
5
|
import { MessageBlockItem } from "./MessageBlockItem.js";
|
|
6
|
-
export const MessageList = React.memo(({ messages, isExpanded = false, forceStatic = false, version, workdir, model, onDynamicBlocksHeightMeasured, }) => {
|
|
6
|
+
export const MessageList = React.memo(({ messages, isExpanded = false, forceStatic = false, isFinished = false, version, workdir, model, onDynamicBlocksHeightMeasured, }) => {
|
|
7
7
|
const welcomeMessage = (_jsxs(Box, { flexDirection: "column", paddingTop: 1, children: [_jsxs(Text, { color: "gray", children: ["WAVE", version ? ` v${version}` : "", model ? ` • ${model}` : ""] }), workdir && (_jsx(Text, { color: "gray", wrap: "truncate-middle", children: workdir.replace(os.homedir(), "~") }))] }));
|
|
8
|
-
// Limit messages
|
|
9
|
-
const
|
|
10
|
-
const shouldLimitMessages = isExpanded && messages.length > maxExpandedMessages;
|
|
11
|
-
const displayMessages = shouldLimitMessages
|
|
12
|
-
? messages.slice(-maxExpandedMessages)
|
|
13
|
-
: messages;
|
|
8
|
+
// Limit messages to prevent long rendering times
|
|
9
|
+
const maxMessages = 10;
|
|
14
10
|
// Flatten messages into blocks with metadata
|
|
15
|
-
const allBlocks =
|
|
16
|
-
const messageIndex = shouldLimitMessages
|
|
17
|
-
? messages.length - maxExpandedMessages + index
|
|
18
|
-
: index;
|
|
11
|
+
const allBlocks = messages.flatMap((message, messageIndex) => {
|
|
19
12
|
return message.blocks.map((block, blockIndex) => ({
|
|
20
13
|
block,
|
|
21
14
|
message,
|
|
15
|
+
messageIndex,
|
|
22
16
|
isLastMessage: messageIndex === messages.length - 1,
|
|
23
17
|
// Unique key for each block to help Static component
|
|
24
18
|
key: `${message.id}-${blockIndex}`,
|
|
@@ -26,11 +20,8 @@ export const MessageList = React.memo(({ messages, isExpanded = false, forceStat
|
|
|
26
20
|
});
|
|
27
21
|
// Determine which blocks are static vs dynamic
|
|
28
22
|
const blocksWithStatus = allBlocks.map((item) => {
|
|
29
|
-
const {
|
|
30
|
-
const isDynamic = !forceStatic &&
|
|
31
|
-
isLastMessage &&
|
|
32
|
-
((block.type === "tool" && block.stage !== "end") ||
|
|
33
|
-
(block.type === "bang" && block.isRunning));
|
|
23
|
+
const { isLastMessage } = item;
|
|
24
|
+
const isDynamic = !forceStatic && !isFinished && isLastMessage;
|
|
34
25
|
return { ...item, isDynamic };
|
|
35
26
|
});
|
|
36
27
|
const staticBlocks = blocksWithStatus.filter((b) => !b.isDynamic);
|
|
@@ -46,13 +37,23 @@ export const MessageList = React.memo(({ messages, isExpanded = false, forceStat
|
|
|
46
37
|
}
|
|
47
38
|
}, [dynamicBlocks, isExpanded, onDynamicBlocksHeightMeasured]);
|
|
48
39
|
const staticItems = [
|
|
49
|
-
{
|
|
40
|
+
{
|
|
41
|
+
isWelcome: true,
|
|
42
|
+
key: "welcome",
|
|
43
|
+
block: undefined,
|
|
44
|
+
message: undefined,
|
|
45
|
+
messageIndex: -1,
|
|
46
|
+
},
|
|
50
47
|
...staticBlocks.map((b) => ({ ...b, isWelcome: false })),
|
|
51
48
|
];
|
|
52
49
|
return (_jsxs(Box, { flexDirection: "column", paddingBottom: 1, children: [staticItems.length > 0 && (_jsx(Static, { items: staticItems, children: (item) => {
|
|
53
50
|
if (item.isWelcome) {
|
|
54
51
|
return (_jsx(React.Fragment, { children: welcomeMessage }, item.key));
|
|
55
52
|
}
|
|
53
|
+
if (messages.length > maxMessages &&
|
|
54
|
+
item.messageIndex < messages.length - maxMessages) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
56
57
|
return (_jsx(MessageBlockItem, { block: item.block, message: item.message, isExpanded: isExpanded, paddingTop: 1 }, item.key));
|
|
57
58
|
} })), dynamicBlocks.length > 0 && (_jsx(Box, { ref: dynamicBlocksRef, flexDirection: "column", children: dynamicBlocks.map((item) => (_jsx(MessageBlockItem, { block: item.block, message: item.message, isExpanded: isExpanded, paddingTop: 1 }, item.key))) }))] }));
|
|
58
59
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/constants/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,kBAAkB,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/constants/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,kBAAkB,EAAE,YAAY,EAsC5C,CAAC"}
|
|
@@ -15,15 +15,15 @@ export interface ChatContextType {
|
|
|
15
15
|
path: string;
|
|
16
16
|
mimeType: string;
|
|
17
17
|
}>;
|
|
18
|
+
longTextMap?: Record<string, string>;
|
|
18
19
|
}>;
|
|
19
20
|
sessionId: string;
|
|
20
21
|
sendMessage: (content: string, images?: Array<{
|
|
21
22
|
path: string;
|
|
22
23
|
mimeType: string;
|
|
23
|
-
}>) => Promise<void>;
|
|
24
|
+
}>, longTextMap?: Record<string, string>) => Promise<void>;
|
|
24
25
|
abortMessage: () => void;
|
|
25
26
|
latestTotalTokens: number;
|
|
26
|
-
clearMessages: () => void;
|
|
27
27
|
mcpServers: McpServerStatus[];
|
|
28
28
|
connectMcpServer: (serverName: string) => Promise<boolean>;
|
|
29
29
|
disconnectMcpServer: (serverName: string) => Promise<boolean>;
|
|
@@ -33,6 +33,7 @@ export interface ChatContextType {
|
|
|
33
33
|
stdout: string;
|
|
34
34
|
stderr: string;
|
|
35
35
|
status: string;
|
|
36
|
+
outputPath?: string;
|
|
36
37
|
} | null;
|
|
37
38
|
stopBackgroundTask: (taskId: string) => boolean;
|
|
38
39
|
slashCommands: SlashCommand[];
|