wave-code 0.10.4 → 0.11.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/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.map +1 -1
- package/dist/components/MessageList.js +17 -16
- 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 +26 -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 +3 -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 +19 -18
- package/src/constants/commands.ts +0 -6
- package/src/contexts/useChat.tsx +43 -34
- 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,EAyKjC,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, 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,
|
|
@@ -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,6HASnB,gBAAgB,
|
|
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,6HASnB,gBAAgB,6CA+GpB,CAAC"}
|
|
@@ -5,20 +5,14 @@ import { Box, Text, Static, measureElement } from "ink";
|
|
|
5
5
|
import { MessageBlockItem } from "./MessageBlockItem.js";
|
|
6
6
|
export const MessageList = React.memo(({ messages, isExpanded = false, forceStatic = 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 && 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[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,cAAc,EACd,IAAI,EACJ,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACf,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
|