wave-code 0.17.5 → 0.17.6
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 +3 -0
- package/dist/acp/agent.d.ts.map +1 -1
- package/dist/acp/agent.js +95 -1
- package/dist/components/BtwDisplay.d.ts.map +1 -1
- package/dist/components/BtwDisplay.js +2 -2
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +10 -8
- package/dist/components/StatusLine.d.ts +0 -1
- package/dist/components/StatusLine.d.ts.map +1 -1
- package/dist/components/StatusLine.js +2 -2
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +1 -38
- package/dist/managers/inputHandlers.d.ts.map +1 -1
- package/dist/managers/inputHandlers.js +14 -41
- package/dist/managers/inputReducer.d.ts +0 -1
- package/dist/managers/inputReducer.d.ts.map +1 -1
- package/dist/managers/inputReducer.js +16 -34
- package/package.json +2 -2
- package/src/acp/agent.ts +174 -10
- package/src/components/BtwDisplay.tsx +4 -1
- package/src/components/InputBox.tsx +40 -46
- package/src/components/StatusLine.tsx +1 -7
- package/src/hooks/useInputManager.ts +1 -38
- package/src/managers/inputHandlers.ts +14 -49
- package/src/managers/inputReducer.ts +17 -39
package/dist/acp/agent.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { type Agent as AcpAgent, type AgentSideConnection, type InitializeRespon
|
|
|
2
2
|
export declare class WaveAcpAgent implements AcpAgent {
|
|
3
3
|
private agents;
|
|
4
4
|
private connection;
|
|
5
|
+
private taskCache;
|
|
5
6
|
constructor(connection: AgentSideConnection);
|
|
6
7
|
private getSessionModeState;
|
|
7
8
|
private getSessionConfigOptions;
|
|
@@ -19,6 +20,8 @@ export declare class WaveAcpAgent implements AcpAgent {
|
|
|
19
20
|
prompt(params: PromptRequest): Promise<PromptResponse>;
|
|
20
21
|
cancel(params: CancelNotification): Promise<void>;
|
|
21
22
|
private getAllowAlwaysName;
|
|
23
|
+
private handleAskQuestion;
|
|
24
|
+
private handleCreatePlan;
|
|
22
25
|
private handlePermissionRequest;
|
|
23
26
|
private getToolContent;
|
|
24
27
|
private getToolLocations;
|
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":"AAyBA,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,EAOpC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/acp/agent.ts"],"names":[],"mappings":"AAyBA,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,EAOpC,MAAM,0BAA0B,CAAC;AAwBlC,qBAAa,YAAa,YAAW,QAAQ;IAC3C,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,SAAS,CAA6B;gBAElC,UAAU,EAAE,mBAAmB;IAI3C,OAAO,CAAC,mBAAmB;IAkC3B,OAAO,CAAC,uBAAuB;YAmCjB,gBAAgB;IASxB,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAyBzC,YAAY,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAI5C,WAAW;IA2EnB,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAalE,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAcrE,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;IAuBpC,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,iBAAiB;YAsEjB,gBAAgB;YAgDhB,uBAAuB;IAmNrC,OAAO,CAAC,cAAc;IA6FtB,OAAO,CAAC,gBAAgB;IAmCxB,OAAO,CAAC,WAAW;YAmBL,yBAAyB;IAiIvC,OAAO,CAAC,eAAe;CA4OxB"}
|
package/dist/acp/agent.js
CHANGED
|
@@ -4,6 +4,7 @@ import { AGENT_METHODS, } from "@agentclientprotocol/sdk";
|
|
|
4
4
|
export class WaveAcpAgent {
|
|
5
5
|
constructor(connection) {
|
|
6
6
|
this.agents = new Map();
|
|
7
|
+
this.taskCache = new Map();
|
|
7
8
|
this.connection = connection;
|
|
8
9
|
}
|
|
9
10
|
getSessionModeState(agent) {
|
|
@@ -327,6 +328,83 @@ export class WaveAcpAgent {
|
|
|
327
328
|
}
|
|
328
329
|
return "Allow Always";
|
|
329
330
|
}
|
|
331
|
+
async handleAskQuestion(sessionId, toolCallId, context) {
|
|
332
|
+
try {
|
|
333
|
+
const questions = context.toolInput?.questions || [];
|
|
334
|
+
const request = {
|
|
335
|
+
toolCallId,
|
|
336
|
+
title: questions.length === 1 ? questions[0].header : undefined,
|
|
337
|
+
questions: questions.map((q, qi) => ({
|
|
338
|
+
id: `q${qi}`,
|
|
339
|
+
prompt: q.question,
|
|
340
|
+
options: q.options.map((opt, oi) => ({
|
|
341
|
+
id: String(oi),
|
|
342
|
+
label: opt.label,
|
|
343
|
+
description: opt.description,
|
|
344
|
+
})),
|
|
345
|
+
allowMultiple: q.multiSelect,
|
|
346
|
+
})),
|
|
347
|
+
};
|
|
348
|
+
const response = await this.connection.extMethod("wave/ask_question", request);
|
|
349
|
+
const outcome = response.outcome;
|
|
350
|
+
if (outcome === "cancelled") {
|
|
351
|
+
return { behavior: "deny", message: "Cancelled by user" };
|
|
352
|
+
}
|
|
353
|
+
// outcome === "answered"
|
|
354
|
+
const answers = response.answers || [];
|
|
355
|
+
const answerMap = {};
|
|
356
|
+
for (const answer of answers) {
|
|
357
|
+
const qIndex = parseInt(answer.questionId.replace("q", ""), 10);
|
|
358
|
+
const question = questions[qIndex];
|
|
359
|
+
if (!question)
|
|
360
|
+
continue;
|
|
361
|
+
const selectedLabels = answer.selectedOptionIds
|
|
362
|
+
.map((id) => question.options[parseInt(id, 10)]?.label)
|
|
363
|
+
.filter(Boolean);
|
|
364
|
+
answerMap[question.question] = selectedLabels.join(", ");
|
|
365
|
+
}
|
|
366
|
+
return { behavior: "allow", message: JSON.stringify(answerMap) };
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
logger.warn("wave/ask_question extMethod failed, falling back to requestPermission", { error });
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
async handleCreatePlan(sessionId, toolCallId, context) {
|
|
374
|
+
try {
|
|
375
|
+
const cachedTasks = this.taskCache.get(sessionId) || [];
|
|
376
|
+
const request = {
|
|
377
|
+
toolCallId,
|
|
378
|
+
plan: context.planContent || "",
|
|
379
|
+
todos: cachedTasks
|
|
380
|
+
.filter((t) => t.status !== "deleted")
|
|
381
|
+
.map((t) => ({
|
|
382
|
+
id: t.id,
|
|
383
|
+
content: t.subject,
|
|
384
|
+
status: t.status === "completed"
|
|
385
|
+
? "completed"
|
|
386
|
+
: t.status === "in_progress"
|
|
387
|
+
? "in_progress"
|
|
388
|
+
: "pending",
|
|
389
|
+
})),
|
|
390
|
+
};
|
|
391
|
+
const response = await this.connection.extMethod("wave/create_plan", request);
|
|
392
|
+
const outcome = response.outcome;
|
|
393
|
+
if (outcome === "accepted") {
|
|
394
|
+
return { behavior: "allow", newPermissionMode: "default" };
|
|
395
|
+
}
|
|
396
|
+
if (outcome === "rejected") {
|
|
397
|
+
const reason = response.reason;
|
|
398
|
+
return { behavior: "deny", message: reason || "Plan rejected" };
|
|
399
|
+
}
|
|
400
|
+
// cancelled or unknown outcome
|
|
401
|
+
return { behavior: "deny", message: "Cancelled by user" };
|
|
402
|
+
}
|
|
403
|
+
catch (error) {
|
|
404
|
+
logger.warn("wave/create_plan extMethod failed, falling back to requestPermission", { error });
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
330
408
|
async handlePermissionRequest(sessionId, context) {
|
|
331
409
|
logger.info(`Handling permission request for ${context.toolName} in session ${sessionId}`);
|
|
332
410
|
const agent = this.agents.get(sessionId);
|
|
@@ -420,6 +498,19 @@ export class WaveAcpAgent {
|
|
|
420
498
|
const kind = context.toolName
|
|
421
499
|
? this.getToolKind(context.toolName)
|
|
422
500
|
: undefined;
|
|
501
|
+
// Try extension methods first, fall back to requestPermission
|
|
502
|
+
if (context.toolName === ASK_USER_QUESTION_TOOL_NAME) {
|
|
503
|
+
const extResult = await this.handleAskQuestion(sessionId, toolCallId, context);
|
|
504
|
+
if (extResult !== null)
|
|
505
|
+
return extResult;
|
|
506
|
+
// Fall through to existing requestPermission logic
|
|
507
|
+
}
|
|
508
|
+
if (context.toolName === EXIT_PLAN_MODE_TOOL_NAME) {
|
|
509
|
+
const extResult = await this.handleCreatePlan(sessionId, toolCallId, context);
|
|
510
|
+
if (extResult !== null)
|
|
511
|
+
return extResult;
|
|
512
|
+
// Fall through to existing requestPermission logic
|
|
513
|
+
}
|
|
423
514
|
try {
|
|
424
515
|
const response = await this.connection.requestPermission({
|
|
425
516
|
sessionId: sessionId,
|
|
@@ -842,11 +933,14 @@ export class WaveAcpAgent {
|
|
|
842
933
|
}
|
|
843
934
|
},
|
|
844
935
|
onTasksChange: (tasks) => {
|
|
936
|
+
this.taskCache.set(sessionId, tasks);
|
|
845
937
|
this.connection.sessionUpdate({
|
|
846
938
|
sessionId: sessionId,
|
|
847
939
|
update: {
|
|
848
940
|
sessionUpdate: "plan",
|
|
849
|
-
entries: tasks
|
|
941
|
+
entries: tasks
|
|
942
|
+
.filter((t) => t.status !== "deleted")
|
|
943
|
+
.map((task) => ({
|
|
850
944
|
content: task.subject,
|
|
851
945
|
status: task.status === "completed"
|
|
852
946
|
? "completed"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BtwDisplay.d.ts","sourceRoot":"","sources":["../../src/components/BtwDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,UAAU,eAAe;IACvB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"BtwDisplay.d.ts","sourceRoot":"","sources":["../../src/components/BtwDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,UAAU,eAAe;IACvB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA0BhD,CAAC"}
|
|
@@ -2,8 +2,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
3
|
import { Markdown } from "./Markdown.js";
|
|
4
4
|
export const BtwDisplay = ({ btwState }) => {
|
|
5
|
-
if (!btwState.
|
|
5
|
+
if (!btwState.question) {
|
|
6
6
|
return null;
|
|
7
7
|
}
|
|
8
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 0, marginBottom: 0, children: [btwState.question && (_jsxs(Box, { children: [_jsx(Text, { color: btwState.isLoading ? "yellow" : "green", children: "/ " }), _jsxs(Text, { italic: true, color: "gray", children: ["btw ", btwState.question] })] })), btwState.answer && (
|
|
8
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 0, marginBottom: 0, children: [btwState.question && (_jsxs(Box, { children: [_jsx(Text, { color: btwState.isLoading ? "yellow" : "green", children: "/ " }), _jsxs(Text, { italic: true, color: "gray", children: ["btw ", btwState.question] })] })), btwState.answer && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Markdown, { children: btwState.answer }), _jsx(Text, { color: "gray", dimColor: true, children: "ESC to dismiss" })] }))] }));
|
|
9
9
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAoB9D,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;IAEjD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,
|
|
1
|
+
{"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAoB9D,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;IAEjD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA8T5C,CAAC"}
|
|
@@ -136,12 +136,14 @@ export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mc
|
|
|
136
136
|
if (showModelSelector) {
|
|
137
137
|
return (_jsx(ModelSelector, { onCancel: () => setShowModelSelector(false), currentModel: currentModel, configuredModels: configuredModels, onSelectModel: setModel }));
|
|
138
138
|
}
|
|
139
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(BtwDisplay, { btwState: btwState }), showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, isLoading: isFileSearching, onSelect: handleFileSelect, onCancel: handleCancelFileSelect })), showCommandSelector && (_jsx(CommandSelector, { searchQuery: commandSearchQuery, onSelect: handleCommandSelect, onInsert: handleCommandInsert, onCancel: handleCancelCommandSelect, commands: slashCommands })), showHistorySearch && (_jsx(HistorySearch, { searchQuery: historySearchQuery, onSelect: handleHistorySearchSelect, onCancel: handleCancelHistorySearch })), showBackgroundTaskManager && (_jsx(BackgroundTaskManager, { onCancel: () => setShowBackgroundTaskManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showWorkflowManager && (_jsx(WorkflowManager, { onCancel: () => setShowWorkflowManager(false) })),
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
139
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(BtwDisplay, { btwState: btwState }), showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, isLoading: isFileSearching, onSelect: handleFileSelect, onCancel: handleCancelFileSelect })), showCommandSelector && (_jsx(CommandSelector, { searchQuery: commandSearchQuery, onSelect: handleCommandSelect, onInsert: handleCommandInsert, onCancel: handleCancelCommandSelect, commands: slashCommands })), showHistorySearch && (_jsx(HistorySearch, { searchQuery: historySearchQuery, onSelect: handleHistorySearchSelect, onCancel: handleCancelHistorySearch })), showBackgroundTaskManager && (_jsx(BackgroundTaskManager, { onCancel: () => setShowBackgroundTaskManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showWorkflowManager && (_jsx(WorkflowManager, { onCancel: () => setShowWorkflowManager(false) })), btwState.question
|
|
140
|
+
? null
|
|
141
|
+
: showBackgroundTaskManager ||
|
|
142
|
+
showMcpManager ||
|
|
143
|
+
showRewindManager ||
|
|
144
|
+
showHelp ||
|
|
145
|
+
showStatusCommand ||
|
|
146
|
+
showLoginCommand ||
|
|
147
|
+
showPluginManager ||
|
|
148
|
+
showWorkflowManager || (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { borderStyle: "single", borderColor: "gray", borderLeft: false, borderRight: false, children: _jsx(Text, { color: isPlaceholder ? "gray" : "white", children: shouldShowCursor ? (_jsxs(_Fragment, { children: [beforeCursor, _jsx(Text, { backgroundColor: "white", color: "black", children: atCursor }), afterCursor] })) : (displayText) }) }), _jsx(StatusLine, { permissionMode: permissionMode, isShellCommand: isShellCommand, isGoalActive: isGoalActive, goalElapsed: goalElapsed, latestTotalTokens: latestTotalTokens, maxInputTokens: maxInputTokens })] }))] }));
|
|
147
149
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusLine.d.ts","sourceRoot":"","sources":["../../src/components/StatusLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,
|
|
1
|
+
{"version":3,"file":"StatusLine.d.ts","sourceRoot":"","sources":["../../src/components/StatusLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAqDhD,CAAC"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
|
-
export const StatusLine = ({ permissionMode, isShellCommand,
|
|
3
|
+
export const StatusLine = ({ permissionMode, isShellCommand, isGoalActive, goalElapsed, latestTotalTokens = 0, maxInputTokens = 128000, }) => {
|
|
4
4
|
const percentage = latestTotalTokens > 0
|
|
5
5
|
? Math.min(Math.round((latestTotalTokens / maxInputTokens) * 100), 100)
|
|
6
6
|
: 0;
|
|
7
7
|
const contextColor = percentage > 95 ? "red" : percentage > 80 ? "yellow" : "gray";
|
|
8
|
-
return (_jsxs(Box, { paddingRight: 1, justifyContent: "space-between", width: "100%", children: [
|
|
8
|
+
return (_jsxs(Box, { paddingRight: 1, justifyContent: "space-between", width: "100%", children: [isShellCommand ? (_jsxs(Text, { color: "gray", children: ["Shell: ", _jsx(Text, { color: "yellow", children: "Run shell command" })] })) : (_jsxs(Box, { children: [isGoalActive && (_jsxs(Text, { color: "gray", children: [_jsx(Text, { color: "cyan", children: "\u25CE /goal" }), " active", " ", goalElapsed && _jsxs(Text, { children: ["(", goalElapsed, ")"] }), " |", " "] })), _jsxs(Text, { color: "gray", children: ["Mode:", " ", _jsx(Text, { color: permissionMode === "plan"
|
|
9
9
|
? "yellow"
|
|
10
10
|
: permissionMode === "bypassPermissions"
|
|
11
11
|
? "red"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInputManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAGL,qBAAqB,EACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,cAAc,EACd,WAAW,EAEZ,MAAM,gBAAgB,CAAC;AAGxB,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;+
|
|
1
|
+
{"version":3,"file":"useInputManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAGL,qBAAqB,EACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,cAAc,EACd,WAAW,EAEZ,MAAM,gBAAgB,CAAC;AAGxB,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;+BAgTA,MAAM;;;;;qCAoBA,MAAM;iCAIV,MAAM;;mCAQJ,MAAM;oCAK1C,MAAM;wCAQmC,MAAM;mCAIX,MAAM;mCAIN,MAAM;;sCAQH,MAAM;uCAK7C,MAAM;uCAMkC,WAAW;;iCASxD,MAAM;yCAcyC,OAAO;8BAIlB,OAAO;iCAIJ,OAAO;wBAIhB,OAAO;iCAIE,OAAO;gCAIR,OAAO;iCAIN,OAAO;iCAIP,OAAO;mCAIL,OAAO;8BAKhD,cAAc;2BAQX,OAAO,CAAC,OAAO,6BAA6B,EAAE,QAAQ,CAAC;0BAM1B,MAAM,YAAY,MAAM;2BAIvB,MAAM;;;8BAatC,MAAM;;uCA2BP,MAAM;;yBAYJ,MAAM,OACR,GAAG,mBACS,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,gBACxD,MAAM,IAAI;yBAtHY,MAAM;kCAIG,MAAM;;CAmOxD,CAAC"}
|
|
@@ -165,12 +165,6 @@ export const useInputManager = (callbacks = {}) => {
|
|
|
165
165
|
else if (command === "workflows") {
|
|
166
166
|
dispatch({ type: "SET_SHOW_WORKFLOW_MANAGER", payload: true });
|
|
167
167
|
}
|
|
168
|
-
else if (command === "btw") {
|
|
169
|
-
dispatch({
|
|
170
|
-
type: "SET_BTW_STATE",
|
|
171
|
-
payload: { isActive: true, question: "", isLoading: false },
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
168
|
}
|
|
175
169
|
break;
|
|
176
170
|
case "RECALL_QUEUED_MESSAGE":
|
|
@@ -248,38 +242,7 @@ export const useInputManager = (callbacks = {}) => {
|
|
|
248
242
|
useEffect(() => {
|
|
249
243
|
onImagesStateChange?.(state.attachedImages);
|
|
250
244
|
}, [state.attachedImages, onImagesStateChange]);
|
|
251
|
-
//
|
|
252
|
-
useEffect(() => {
|
|
253
|
-
if (state.btwState.isActive &&
|
|
254
|
-
state.btwState.isLoading &&
|
|
255
|
-
state.btwState.question) {
|
|
256
|
-
const askBtw = async () => {
|
|
257
|
-
try {
|
|
258
|
-
const answer = await onAskBtw?.(state.btwState.question);
|
|
259
|
-
dispatch({
|
|
260
|
-
type: "SET_BTW_STATE",
|
|
261
|
-
payload: { answer, isLoading: false },
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
catch (error) {
|
|
265
|
-
console.error("Failed to ask side question:", error);
|
|
266
|
-
dispatch({
|
|
267
|
-
type: "SET_BTW_STATE",
|
|
268
|
-
payload: {
|
|
269
|
-
answer: "Error: Failed to get an answer for your side question.",
|
|
270
|
-
isLoading: false,
|
|
271
|
-
},
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
askBtw();
|
|
276
|
-
}
|
|
277
|
-
}, [
|
|
278
|
-
state.btwState.isActive,
|
|
279
|
-
state.btwState.isLoading,
|
|
280
|
-
state.btwState.question,
|
|
281
|
-
onAskBtw,
|
|
282
|
-
]);
|
|
245
|
+
// /btw side question is handled via pendingEffect "ASK_BTW" above
|
|
283
246
|
// Methods
|
|
284
247
|
const insertTextAtCursor = useCallback((text) => {
|
|
285
248
|
dispatch({ type: "INSERT_TEXT", payload: text });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAwB,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EACL,UAAU,EACV,WAAW,EACX,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,0BAA0B,GACrC,MAAM,MAAM,EACZ,aAAa,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAClC,MAcF,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,yBAAyB,KAAK,CAAC;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,KACD,OAAO,CAAC,IAAI,CA8Dd,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,KACpC,OAAO,CAAC,OAAO,CAiBjB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,aAAa,cAAc,EAC3B,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,SAmB1C,CAAC;AAgCF,eAAO,MAAM,qBAAqB,GAChC,MAAM,MAAM,EACZ,gBAAgB,MAAM,KACrB,MAaF,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,MAAM,MAAM,EACZ,gBAAgB,MAAM,KACrB,MAaF,CAAC;AAEF,eAAO,MAAM,qCAAqC,GAChD,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,MAAM,EACjB,gBAAgB,MAAM,KACrB,IAYF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,MAAM,MAAM,KACX,IAkDF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,KACZ,IAwBF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,EAAE,UAAU,MAAM,KAAG,MAM3D,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,SAAS,MAAM;;;
|
|
1
|
+
{"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -273,12 +273,6 @@ export const handleCommandSelect = (state, dispatch, callbacks, command) => {
|
|
|
273
273
|
else if (command === "workflows") {
|
|
274
274
|
dispatch({ type: "SET_SHOW_WORKFLOW_MANAGER", payload: true });
|
|
275
275
|
}
|
|
276
|
-
else if (command === "btw") {
|
|
277
|
-
dispatch({
|
|
278
|
-
type: "SET_BTW_STATE",
|
|
279
|
-
payload: { isActive: true, question: "", isLoading: false },
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
276
|
}
|
|
283
277
|
})();
|
|
284
278
|
dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
|
|
@@ -507,35 +501,17 @@ export const handleNormalInput = async (state, dispatch, callbacks, input, key,
|
|
|
507
501
|
return false;
|
|
508
502
|
};
|
|
509
503
|
export const handleInput = async (state, dispatch, callbacks, input, key, clearImages) => {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
return true;
|
|
522
|
-
}
|
|
523
|
-
if (key.return) {
|
|
524
|
-
if (state.inputText.trim() && !state.btwState.isLoading) {
|
|
525
|
-
dispatch({
|
|
526
|
-
type: "SET_BTW_STATE",
|
|
527
|
-
payload: {
|
|
528
|
-
question: state.inputText.trim(),
|
|
529
|
-
isLoading: true,
|
|
530
|
-
answer: undefined,
|
|
531
|
-
},
|
|
532
|
-
});
|
|
533
|
-
dispatch({ type: "CLEAR_INPUT" });
|
|
534
|
-
}
|
|
535
|
-
return true;
|
|
536
|
-
}
|
|
537
|
-
// Handle normal input for the question
|
|
538
|
-
return await handleNormalInput(state, dispatch, callbacks, input, key, clearImages);
|
|
504
|
+
// Handle ESC to dismiss btw answer
|
|
505
|
+
if (key.escape && state.btwState.question && !state.btwState.isLoading) {
|
|
506
|
+
dispatch({
|
|
507
|
+
type: "SET_BTW_STATE",
|
|
508
|
+
payload: {
|
|
509
|
+
question: "",
|
|
510
|
+
answer: undefined,
|
|
511
|
+
isLoading: false,
|
|
512
|
+
},
|
|
513
|
+
});
|
|
514
|
+
return true;
|
|
539
515
|
}
|
|
540
516
|
if (key.escape) {
|
|
541
517
|
if (!(state.showFileSelector ||
|
|
@@ -548,8 +524,7 @@ export const handleInput = async (state, dispatch, callbacks, input, key, clearI
|
|
|
548
524
|
state.showStatusCommand ||
|
|
549
525
|
state.showPluginManager ||
|
|
550
526
|
state.showModelSelector ||
|
|
551
|
-
state.showWorkflowManager
|
|
552
|
-
state.btwState.isActive)) {
|
|
527
|
+
state.showWorkflowManager)) {
|
|
553
528
|
callbacks.onAbortMessage?.();
|
|
554
529
|
return true;
|
|
555
530
|
}
|
|
@@ -568,8 +543,7 @@ export const handleInput = async (state, dispatch, callbacks, input, key, clearI
|
|
|
568
543
|
state.showStatusCommand ||
|
|
569
544
|
state.showPluginManager ||
|
|
570
545
|
state.showModelSelector ||
|
|
571
|
-
state.showWorkflowManager
|
|
572
|
-
state.btwState.isActive) {
|
|
546
|
+
state.showWorkflowManager) {
|
|
573
547
|
if (state.showBackgroundTaskManager ||
|
|
574
548
|
state.showMcpManager ||
|
|
575
549
|
state.showRewindManager ||
|
|
@@ -577,8 +551,7 @@ export const handleInput = async (state, dispatch, callbacks, input, key, clearI
|
|
|
577
551
|
state.showStatusCommand ||
|
|
578
552
|
state.showPluginManager ||
|
|
579
553
|
state.showModelSelector ||
|
|
580
|
-
state.showWorkflowManager
|
|
581
|
-
state.btwState.isActive) {
|
|
554
|
+
state.showWorkflowManager) {
|
|
582
555
|
return true;
|
|
583
556
|
}
|
|
584
557
|
if (state.showHistorySearch) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inputReducer.d.ts","sourceRoot":"","sources":["../../src/managers/inputReducer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,cAAc,EACd,MAAM,EACN,WAAW,EACX,OAAO,EACR,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAU1B,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"inputReducer.d.ts","sourceRoot":"","sources":["../../src/managers/inputReducer.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,7 +36,6 @@ export const initialState = {
|
|
|
36
36
|
originalLongTextMap: {},
|
|
37
37
|
isFileSearching: false,
|
|
38
38
|
btwState: {
|
|
39
|
-
isActive: false,
|
|
40
39
|
question: "",
|
|
41
40
|
isLoading: false,
|
|
42
41
|
},
|
|
@@ -466,40 +465,19 @@ export function inputReducer(state, action) {
|
|
|
466
465
|
case "HANDLE_KEY": {
|
|
467
466
|
const { input, key } = action.payload;
|
|
468
467
|
const hasQueuedMessages = action.payload.hasQueuedMessages ?? false;
|
|
469
|
-
// 1.
|
|
470
|
-
if (
|
|
471
|
-
|
|
468
|
+
// 1. Escape Handling
|
|
469
|
+
if (key.escape) {
|
|
470
|
+
// Dismiss btw answer
|
|
471
|
+
if (state.btwState.question && !state.btwState.isLoading) {
|
|
472
472
|
return {
|
|
473
473
|
...state,
|
|
474
474
|
btwState: {
|
|
475
|
-
isActive: false,
|
|
476
475
|
question: "",
|
|
477
476
|
answer: undefined,
|
|
478
477
|
isLoading: false,
|
|
479
478
|
},
|
|
480
479
|
};
|
|
481
480
|
}
|
|
482
|
-
if (key.return) {
|
|
483
|
-
const question = state.inputText.trim();
|
|
484
|
-
if (question && !state.btwState.isLoading) {
|
|
485
|
-
return {
|
|
486
|
-
...state,
|
|
487
|
-
inputText: "",
|
|
488
|
-
cursorPosition: 0,
|
|
489
|
-
btwState: {
|
|
490
|
-
...state.btwState,
|
|
491
|
-
question,
|
|
492
|
-
isLoading: true,
|
|
493
|
-
answer: undefined,
|
|
494
|
-
},
|
|
495
|
-
pendingEffect: { type: "ASK_BTW", question },
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
|
-
return state;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
// 2. Escape Handling
|
|
502
|
-
if (key.escape) {
|
|
503
481
|
if (state.showFileSelector) {
|
|
504
482
|
return {
|
|
505
483
|
...state,
|
|
@@ -748,11 +726,12 @@ export function inputReducer(state, action) {
|
|
|
748
726
|
const contentWithPlaceholders = state.inputText
|
|
749
727
|
.replace(imageRegex, "")
|
|
750
728
|
.trim();
|
|
751
|
-
if (contentWithPlaceholders
|
|
752
|
-
contentWithPlaceholders.
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
729
|
+
if (contentWithPlaceholders.startsWith("/btw ")) {
|
|
730
|
+
const question = contentWithPlaceholders.substring(5).trim();
|
|
731
|
+
if (!question) {
|
|
732
|
+
// Bare /btw with no question text — ignore
|
|
733
|
+
return state;
|
|
734
|
+
}
|
|
756
735
|
return {
|
|
757
736
|
...state,
|
|
758
737
|
inputText: "",
|
|
@@ -760,14 +739,17 @@ export function inputReducer(state, action) {
|
|
|
760
739
|
historyIndex: -1,
|
|
761
740
|
longTextMap: {},
|
|
762
741
|
btwState: {
|
|
763
|
-
isActive: true,
|
|
764
742
|
question,
|
|
765
|
-
isLoading:
|
|
743
|
+
isLoading: true,
|
|
766
744
|
answer: undefined,
|
|
767
745
|
},
|
|
768
|
-
pendingEffect:
|
|
746
|
+
pendingEffect: { type: "ASK_BTW", question },
|
|
769
747
|
};
|
|
770
748
|
}
|
|
749
|
+
if (contentWithPlaceholders === "/btw") {
|
|
750
|
+
// Bare /btw — ignore
|
|
751
|
+
return state;
|
|
752
|
+
}
|
|
771
753
|
// Check if the content is a CLI-internal slash command (help, tasks,
|
|
772
754
|
// etc.) that should be executed locally rather than sent as a message.
|
|
773
755
|
// Agent slash commands and unknown /commands always go to SEND_MESSAGE.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-code",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.6",
|
|
4
4
|
"description": "CLI-based code assistant powered by AI, built with React and Ink",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"semver": "^7.7.4",
|
|
43
43
|
"yargs": "^17.7.2",
|
|
44
44
|
"zod": "^3.23.8",
|
|
45
|
-
"wave-agent-sdk": "0.17.
|
|
45
|
+
"wave-agent-sdk": "0.17.6"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/react": "^19.1.8",
|
package/src/acp/agent.ts
CHANGED
|
@@ -58,9 +58,31 @@ import {
|
|
|
58
58
|
} from "@agentclientprotocol/sdk";
|
|
59
59
|
import type { McpServerConfig, McpServerStatus } from "wave-agent-sdk";
|
|
60
60
|
|
|
61
|
+
interface WaveAskQuestionRequest {
|
|
62
|
+
toolCallId: string;
|
|
63
|
+
title?: string;
|
|
64
|
+
questions: Array<{
|
|
65
|
+
id: string;
|
|
66
|
+
prompt: string;
|
|
67
|
+
options: Array<{ id: string; label: string; description?: string }>;
|
|
68
|
+
allowMultiple?: boolean;
|
|
69
|
+
}>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface WaveCreatePlanRequest {
|
|
73
|
+
toolCallId: string;
|
|
74
|
+
plan: string;
|
|
75
|
+
todos?: Array<{
|
|
76
|
+
id: string;
|
|
77
|
+
content: string;
|
|
78
|
+
status: "pending" | "in_progress" | "completed";
|
|
79
|
+
}>;
|
|
80
|
+
}
|
|
81
|
+
|
|
61
82
|
export class WaveAcpAgent implements AcpAgent {
|
|
62
83
|
private agents: Map<string, WaveAgent> = new Map();
|
|
63
84
|
private connection: AgentSideConnection;
|
|
85
|
+
private taskCache = new Map<string, Task[]>();
|
|
64
86
|
|
|
65
87
|
constructor(connection: AgentSideConnection) {
|
|
66
88
|
this.connection = connection;
|
|
@@ -458,6 +480,124 @@ export class WaveAcpAgent implements AcpAgent {
|
|
|
458
480
|
return "Allow Always";
|
|
459
481
|
}
|
|
460
482
|
|
|
483
|
+
private async handleAskQuestion(
|
|
484
|
+
sessionId: string,
|
|
485
|
+
toolCallId: string,
|
|
486
|
+
context: ToolPermissionContext,
|
|
487
|
+
): Promise<PermissionDecision | null> {
|
|
488
|
+
try {
|
|
489
|
+
const questions =
|
|
490
|
+
(context.toolInput?.questions as Array<{
|
|
491
|
+
question: string;
|
|
492
|
+
header?: string;
|
|
493
|
+
options: Array<{ label: string; description?: string }>;
|
|
494
|
+
multiSelect?: boolean;
|
|
495
|
+
}>) || [];
|
|
496
|
+
|
|
497
|
+
const request: WaveAskQuestionRequest = {
|
|
498
|
+
toolCallId,
|
|
499
|
+
title: questions.length === 1 ? questions[0].header : undefined,
|
|
500
|
+
questions: questions.map((q, qi) => ({
|
|
501
|
+
id: `q${qi}`,
|
|
502
|
+
prompt: q.question,
|
|
503
|
+
options: q.options.map((opt, oi) => ({
|
|
504
|
+
id: String(oi),
|
|
505
|
+
label: opt.label,
|
|
506
|
+
description: opt.description,
|
|
507
|
+
})),
|
|
508
|
+
allowMultiple: q.multiSelect,
|
|
509
|
+
})),
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
const response = await this.connection.extMethod(
|
|
513
|
+
"wave/ask_question",
|
|
514
|
+
request as unknown as Record<string, unknown>,
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
const outcome = (response as { outcome?: string }).outcome;
|
|
518
|
+
if (outcome === "cancelled") {
|
|
519
|
+
return { behavior: "deny", message: "Cancelled by user" };
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// outcome === "answered"
|
|
523
|
+
const answers =
|
|
524
|
+
(
|
|
525
|
+
response as {
|
|
526
|
+
answers?: Array<{
|
|
527
|
+
questionId: string;
|
|
528
|
+
selectedOptionIds: string[];
|
|
529
|
+
}>;
|
|
530
|
+
}
|
|
531
|
+
).answers || [];
|
|
532
|
+
const answerMap: Record<string, string> = {};
|
|
533
|
+
for (const answer of answers) {
|
|
534
|
+
const qIndex = parseInt(answer.questionId.replace("q", ""), 10);
|
|
535
|
+
const question = questions[qIndex];
|
|
536
|
+
if (!question) continue;
|
|
537
|
+
const selectedLabels = answer.selectedOptionIds
|
|
538
|
+
.map((id) => question.options[parseInt(id, 10)]?.label)
|
|
539
|
+
.filter(Boolean);
|
|
540
|
+
answerMap[question.question] = selectedLabels.join(", ");
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
return { behavior: "allow", message: JSON.stringify(answerMap) };
|
|
544
|
+
} catch (error) {
|
|
545
|
+
logger.warn(
|
|
546
|
+
"wave/ask_question extMethod failed, falling back to requestPermission",
|
|
547
|
+
{ error },
|
|
548
|
+
);
|
|
549
|
+
return null;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
private async handleCreatePlan(
|
|
554
|
+
sessionId: string,
|
|
555
|
+
toolCallId: string,
|
|
556
|
+
context: ToolPermissionContext,
|
|
557
|
+
): Promise<PermissionDecision | null> {
|
|
558
|
+
try {
|
|
559
|
+
const cachedTasks = this.taskCache.get(sessionId) || [];
|
|
560
|
+
const request: WaveCreatePlanRequest = {
|
|
561
|
+
toolCallId,
|
|
562
|
+
plan: context.planContent || "",
|
|
563
|
+
todos: cachedTasks
|
|
564
|
+
.filter((t) => t.status !== "deleted")
|
|
565
|
+
.map((t) => ({
|
|
566
|
+
id: t.id,
|
|
567
|
+
content: t.subject,
|
|
568
|
+
status:
|
|
569
|
+
t.status === "completed"
|
|
570
|
+
? ("completed" as const)
|
|
571
|
+
: t.status === "in_progress"
|
|
572
|
+
? ("in_progress" as const)
|
|
573
|
+
: ("pending" as const),
|
|
574
|
+
})),
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
const response = await this.connection.extMethod(
|
|
578
|
+
"wave/create_plan",
|
|
579
|
+
request as unknown as Record<string, unknown>,
|
|
580
|
+
);
|
|
581
|
+
|
|
582
|
+
const outcome = (response as { outcome?: string }).outcome;
|
|
583
|
+
if (outcome === "accepted") {
|
|
584
|
+
return { behavior: "allow", newPermissionMode: "default" };
|
|
585
|
+
}
|
|
586
|
+
if (outcome === "rejected") {
|
|
587
|
+
const reason = (response as { reason?: string }).reason;
|
|
588
|
+
return { behavior: "deny", message: reason || "Plan rejected" };
|
|
589
|
+
}
|
|
590
|
+
// cancelled or unknown outcome
|
|
591
|
+
return { behavior: "deny", message: "Cancelled by user" };
|
|
592
|
+
} catch (error) {
|
|
593
|
+
logger.warn(
|
|
594
|
+
"wave/create_plan extMethod failed, falling back to requestPermission",
|
|
595
|
+
{ error },
|
|
596
|
+
);
|
|
597
|
+
return null;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
461
601
|
private async handlePermissionRequest(
|
|
462
602
|
sessionId: string,
|
|
463
603
|
context: ToolPermissionContext,
|
|
@@ -573,6 +713,27 @@ export class WaveAcpAgent implements AcpAgent {
|
|
|
573
713
|
? this.getToolKind(context.toolName)
|
|
574
714
|
: undefined;
|
|
575
715
|
|
|
716
|
+
// Try extension methods first, fall back to requestPermission
|
|
717
|
+
if (context.toolName === ASK_USER_QUESTION_TOOL_NAME) {
|
|
718
|
+
const extResult = await this.handleAskQuestion(
|
|
719
|
+
sessionId,
|
|
720
|
+
toolCallId,
|
|
721
|
+
context,
|
|
722
|
+
);
|
|
723
|
+
if (extResult !== null) return extResult;
|
|
724
|
+
// Fall through to existing requestPermission logic
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
if (context.toolName === EXIT_PLAN_MODE_TOOL_NAME) {
|
|
728
|
+
const extResult = await this.handleCreatePlan(
|
|
729
|
+
sessionId,
|
|
730
|
+
toolCallId,
|
|
731
|
+
context,
|
|
732
|
+
);
|
|
733
|
+
if (extResult !== null) return extResult;
|
|
734
|
+
// Fall through to existing requestPermission logic
|
|
735
|
+
}
|
|
736
|
+
|
|
576
737
|
try {
|
|
577
738
|
const response = await this.connection.requestPermission({
|
|
578
739
|
sessionId: sessionId as AcpSessionId,
|
|
@@ -1081,20 +1242,23 @@ export class WaveAcpAgent implements AcpAgent {
|
|
|
1081
1242
|
}
|
|
1082
1243
|
},
|
|
1083
1244
|
onTasksChange: (tasks) => {
|
|
1245
|
+
this.taskCache.set(sessionId, tasks);
|
|
1084
1246
|
this.connection.sessionUpdate({
|
|
1085
1247
|
sessionId: sessionId as AcpSessionId,
|
|
1086
1248
|
update: {
|
|
1087
1249
|
sessionUpdate: "plan",
|
|
1088
|
-
entries: tasks
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
task.
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
? "
|
|
1095
|
-
: "
|
|
1096
|
-
|
|
1097
|
-
|
|
1250
|
+
entries: tasks
|
|
1251
|
+
.filter((t) => t.status !== "deleted")
|
|
1252
|
+
.map((task) => ({
|
|
1253
|
+
content: task.subject,
|
|
1254
|
+
status:
|
|
1255
|
+
task.status === "completed"
|
|
1256
|
+
? "completed"
|
|
1257
|
+
: task.status === "in_progress"
|
|
1258
|
+
? "in_progress"
|
|
1259
|
+
: "pending",
|
|
1260
|
+
priority: "medium" as const,
|
|
1261
|
+
})),
|
|
1098
1262
|
},
|
|
1099
1263
|
});
|
|
1100
1264
|
},
|
|
@@ -8,7 +8,7 @@ interface BtwDisplayProps {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export const BtwDisplay: React.FC<BtwDisplayProps> = ({ btwState }) => {
|
|
11
|
-
if (!btwState.
|
|
11
|
+
if (!btwState.question) {
|
|
12
12
|
return null;
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -26,6 +26,9 @@ export const BtwDisplay: React.FC<BtwDisplayProps> = ({ btwState }) => {
|
|
|
26
26
|
{btwState.answer && (
|
|
27
27
|
<Box flexDirection="column">
|
|
28
28
|
<Markdown>{btwState.answer}</Markdown>
|
|
29
|
+
<Text color="gray" dimColor>
|
|
30
|
+
ESC to dismiss
|
|
31
|
+
</Text>
|
|
29
32
|
</Box>
|
|
30
33
|
)}
|
|
31
34
|
</Box>
|
|
@@ -328,53 +328,47 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
328
328
|
<WorkflowManager onCancel={() => setShowWorkflowManager(false)} />
|
|
329
329
|
)}
|
|
330
330
|
|
|
331
|
-
{
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
331
|
+
{btwState.question
|
|
332
|
+
? null
|
|
333
|
+
: showBackgroundTaskManager ||
|
|
334
|
+
showMcpManager ||
|
|
335
|
+
showRewindManager ||
|
|
336
|
+
showHelp ||
|
|
337
|
+
showStatusCommand ||
|
|
338
|
+
showLoginCommand ||
|
|
339
|
+
showPluginManager ||
|
|
340
|
+
showWorkflowManager || (
|
|
341
|
+
<Box flexDirection="column">
|
|
342
|
+
<Box
|
|
343
|
+
borderStyle="single"
|
|
344
|
+
borderColor="gray"
|
|
345
|
+
borderLeft={false}
|
|
346
|
+
borderRight={false}
|
|
347
|
+
>
|
|
348
|
+
<Text color={isPlaceholder ? "gray" : "white"}>
|
|
349
|
+
{shouldShowCursor ? (
|
|
350
|
+
<>
|
|
351
|
+
{beforeCursor}
|
|
352
|
+
<Text backgroundColor="white" color="black">
|
|
353
|
+
{atCursor}
|
|
354
|
+
</Text>
|
|
355
|
+
{afterCursor}
|
|
356
|
+
</>
|
|
357
|
+
) : (
|
|
358
|
+
displayText
|
|
359
|
+
)}
|
|
360
|
+
</Text>
|
|
361
|
+
</Box>
|
|
362
|
+
<StatusLine
|
|
363
|
+
permissionMode={permissionMode}
|
|
364
|
+
isShellCommand={isShellCommand}
|
|
365
|
+
isGoalActive={isGoalActive}
|
|
366
|
+
goalElapsed={goalElapsed}
|
|
367
|
+
latestTotalTokens={latestTotalTokens}
|
|
368
|
+
maxInputTokens={maxInputTokens}
|
|
369
|
+
/>
|
|
366
370
|
</Box>
|
|
367
|
-
|
|
368
|
-
permissionMode={permissionMode}
|
|
369
|
-
isShellCommand={isShellCommand}
|
|
370
|
-
isBtwActive={btwState.isActive}
|
|
371
|
-
isGoalActive={isGoalActive}
|
|
372
|
-
goalElapsed={goalElapsed}
|
|
373
|
-
latestTotalTokens={latestTotalTokens}
|
|
374
|
-
maxInputTokens={maxInputTokens}
|
|
375
|
-
/>
|
|
376
|
-
</Box>
|
|
377
|
-
)}
|
|
371
|
+
)}
|
|
378
372
|
</Box>
|
|
379
373
|
);
|
|
380
374
|
};
|
|
@@ -4,7 +4,6 @@ import { Box, Text } from "ink";
|
|
|
4
4
|
export interface StatusLineProps {
|
|
5
5
|
permissionMode: string;
|
|
6
6
|
isShellCommand: boolean;
|
|
7
|
-
isBtwActive: boolean;
|
|
8
7
|
isGoalActive?: boolean;
|
|
9
8
|
goalElapsed?: string;
|
|
10
9
|
latestTotalTokens?: number;
|
|
@@ -14,7 +13,6 @@ export interface StatusLineProps {
|
|
|
14
13
|
export const StatusLine: React.FC<StatusLineProps> = ({
|
|
15
14
|
permissionMode,
|
|
16
15
|
isShellCommand,
|
|
17
|
-
isBtwActive,
|
|
18
16
|
isGoalActive,
|
|
19
17
|
goalElapsed,
|
|
20
18
|
latestTotalTokens = 0,
|
|
@@ -30,11 +28,7 @@ export const StatusLine: React.FC<StatusLineProps> = ({
|
|
|
30
28
|
|
|
31
29
|
return (
|
|
32
30
|
<Box paddingRight={1} justifyContent="space-between" width="100%">
|
|
33
|
-
{
|
|
34
|
-
<Text color="gray">
|
|
35
|
-
Mode: <Text color="cyan">BTW</Text> (ESC to dismiss)
|
|
36
|
-
</Text>
|
|
37
|
-
) : isShellCommand ? (
|
|
31
|
+
{isShellCommand ? (
|
|
38
32
|
<Text color="gray">
|
|
39
33
|
Shell: <Text color="yellow">Run shell command</Text>
|
|
40
34
|
</Text>
|
|
@@ -212,11 +212,6 @@ export const useInputManager = (
|
|
|
212
212
|
dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: true });
|
|
213
213
|
} else if (command === "workflows") {
|
|
214
214
|
dispatch({ type: "SET_SHOW_WORKFLOW_MANAGER", payload: true });
|
|
215
|
-
} else if (command === "btw") {
|
|
216
|
-
dispatch({
|
|
217
|
-
type: "SET_BTW_STATE",
|
|
218
|
-
payload: { isActive: true, question: "", isLoading: false },
|
|
219
|
-
});
|
|
220
215
|
}
|
|
221
216
|
}
|
|
222
217
|
break;
|
|
@@ -320,39 +315,7 @@ export const useInputManager = (
|
|
|
320
315
|
onImagesStateChange?.(state.attachedImages);
|
|
321
316
|
}, [state.attachedImages, onImagesStateChange]);
|
|
322
317
|
|
|
323
|
-
//
|
|
324
|
-
useEffect(() => {
|
|
325
|
-
if (
|
|
326
|
-
state.btwState.isActive &&
|
|
327
|
-
state.btwState.isLoading &&
|
|
328
|
-
state.btwState.question
|
|
329
|
-
) {
|
|
330
|
-
const askBtw = async () => {
|
|
331
|
-
try {
|
|
332
|
-
const answer = await onAskBtw?.(state.btwState.question);
|
|
333
|
-
dispatch({
|
|
334
|
-
type: "SET_BTW_STATE",
|
|
335
|
-
payload: { answer, isLoading: false },
|
|
336
|
-
});
|
|
337
|
-
} catch (error) {
|
|
338
|
-
console.error("Failed to ask side question:", error);
|
|
339
|
-
dispatch({
|
|
340
|
-
type: "SET_BTW_STATE",
|
|
341
|
-
payload: {
|
|
342
|
-
answer: "Error: Failed to get an answer for your side question.",
|
|
343
|
-
isLoading: false,
|
|
344
|
-
},
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
askBtw();
|
|
349
|
-
}
|
|
350
|
-
}, [
|
|
351
|
-
state.btwState.isActive,
|
|
352
|
-
state.btwState.isLoading,
|
|
353
|
-
state.btwState.question,
|
|
354
|
-
onAskBtw,
|
|
355
|
-
]);
|
|
318
|
+
// /btw side question is handled via pendingEffect "ASK_BTW" above
|
|
356
319
|
|
|
357
320
|
// Methods
|
|
358
321
|
const insertTextAtCursor = useCallback((text: string) => {
|
|
@@ -373,11 +373,6 @@ export const handleCommandSelect = (
|
|
|
373
373
|
dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: true });
|
|
374
374
|
} else if (command === "workflows") {
|
|
375
375
|
dispatch({ type: "SET_SHOW_WORKFLOW_MANAGER", payload: true });
|
|
376
|
-
} else if (command === "btw") {
|
|
377
|
-
dispatch({
|
|
378
|
-
type: "SET_BTW_STATE",
|
|
379
|
-
payload: { isActive: true, question: "", isLoading: false },
|
|
380
|
-
});
|
|
381
376
|
}
|
|
382
377
|
}
|
|
383
378
|
})();
|
|
@@ -701,44 +696,17 @@ export const handleInput = async (
|
|
|
701
696
|
key: Key,
|
|
702
697
|
clearImages?: () => void,
|
|
703
698
|
): Promise<boolean> => {
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
return true;
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
if (key.return) {
|
|
719
|
-
if (state.inputText.trim() && !state.btwState.isLoading) {
|
|
720
|
-
dispatch({
|
|
721
|
-
type: "SET_BTW_STATE",
|
|
722
|
-
payload: {
|
|
723
|
-
question: state.inputText.trim(),
|
|
724
|
-
isLoading: true,
|
|
725
|
-
answer: undefined,
|
|
726
|
-
},
|
|
727
|
-
});
|
|
728
|
-
dispatch({ type: "CLEAR_INPUT" });
|
|
729
|
-
}
|
|
730
|
-
return true;
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
// Handle normal input for the question
|
|
734
|
-
return await handleNormalInput(
|
|
735
|
-
state,
|
|
736
|
-
dispatch,
|
|
737
|
-
callbacks,
|
|
738
|
-
input,
|
|
739
|
-
key,
|
|
740
|
-
clearImages,
|
|
741
|
-
);
|
|
699
|
+
// Handle ESC to dismiss btw answer
|
|
700
|
+
if (key.escape && state.btwState.question && !state.btwState.isLoading) {
|
|
701
|
+
dispatch({
|
|
702
|
+
type: "SET_BTW_STATE",
|
|
703
|
+
payload: {
|
|
704
|
+
question: "",
|
|
705
|
+
answer: undefined,
|
|
706
|
+
isLoading: false,
|
|
707
|
+
},
|
|
708
|
+
});
|
|
709
|
+
return true;
|
|
742
710
|
}
|
|
743
711
|
|
|
744
712
|
if (key.escape) {
|
|
@@ -754,8 +722,7 @@ export const handleInput = async (
|
|
|
754
722
|
state.showStatusCommand ||
|
|
755
723
|
state.showPluginManager ||
|
|
756
724
|
state.showModelSelector ||
|
|
757
|
-
state.showWorkflowManager
|
|
758
|
-
state.btwState.isActive
|
|
725
|
+
state.showWorkflowManager
|
|
759
726
|
)
|
|
760
727
|
) {
|
|
761
728
|
callbacks.onAbortMessage?.();
|
|
@@ -779,8 +746,7 @@ export const handleInput = async (
|
|
|
779
746
|
state.showStatusCommand ||
|
|
780
747
|
state.showPluginManager ||
|
|
781
748
|
state.showModelSelector ||
|
|
782
|
-
state.showWorkflowManager
|
|
783
|
-
state.btwState.isActive
|
|
749
|
+
state.showWorkflowManager
|
|
784
750
|
) {
|
|
785
751
|
if (
|
|
786
752
|
state.showBackgroundTaskManager ||
|
|
@@ -790,8 +756,7 @@ export const handleInput = async (
|
|
|
790
756
|
state.showStatusCommand ||
|
|
791
757
|
state.showPluginManager ||
|
|
792
758
|
state.showModelSelector ||
|
|
793
|
-
state.showWorkflowManager
|
|
794
|
-
state.btwState.isActive
|
|
759
|
+
state.showWorkflowManager
|
|
795
760
|
) {
|
|
796
761
|
return true;
|
|
797
762
|
}
|
|
@@ -22,7 +22,6 @@ export interface AttachedImage {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export interface BtwState {
|
|
25
|
-
isActive: boolean;
|
|
26
25
|
question: string;
|
|
27
26
|
answer?: string;
|
|
28
27
|
isLoading: boolean;
|
|
@@ -164,7 +163,6 @@ export const initialState: InputState = {
|
|
|
164
163
|
originalLongTextMap: {},
|
|
165
164
|
isFileSearching: false,
|
|
166
165
|
btwState: {
|
|
167
|
-
isActive: false,
|
|
168
166
|
question: "",
|
|
169
167
|
isLoading: false,
|
|
170
168
|
},
|
|
@@ -688,42 +686,19 @@ export function inputReducer(
|
|
|
688
686
|
const { input, key } = action.payload;
|
|
689
687
|
const hasQueuedMessages = action.payload.hasQueuedMessages ?? false;
|
|
690
688
|
|
|
691
|
-
// 1.
|
|
692
|
-
if (
|
|
693
|
-
|
|
689
|
+
// 1. Escape Handling
|
|
690
|
+
if (key.escape) {
|
|
691
|
+
// Dismiss btw answer
|
|
692
|
+
if (state.btwState.question && !state.btwState.isLoading) {
|
|
694
693
|
return {
|
|
695
694
|
...state,
|
|
696
695
|
btwState: {
|
|
697
|
-
isActive: false,
|
|
698
696
|
question: "",
|
|
699
697
|
answer: undefined,
|
|
700
698
|
isLoading: false,
|
|
701
699
|
},
|
|
702
700
|
};
|
|
703
701
|
}
|
|
704
|
-
|
|
705
|
-
if (key.return) {
|
|
706
|
-
const question = state.inputText.trim();
|
|
707
|
-
if (question && !state.btwState.isLoading) {
|
|
708
|
-
return {
|
|
709
|
-
...state,
|
|
710
|
-
inputText: "",
|
|
711
|
-
cursorPosition: 0,
|
|
712
|
-
btwState: {
|
|
713
|
-
...state.btwState,
|
|
714
|
-
question,
|
|
715
|
-
isLoading: true,
|
|
716
|
-
answer: undefined,
|
|
717
|
-
},
|
|
718
|
-
pendingEffect: { type: "ASK_BTW", question },
|
|
719
|
-
};
|
|
720
|
-
}
|
|
721
|
-
return state;
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
// 2. Escape Handling
|
|
726
|
-
if (key.escape) {
|
|
727
702
|
if (state.showFileSelector) {
|
|
728
703
|
return {
|
|
729
704
|
...state,
|
|
@@ -1017,13 +992,12 @@ export function inputReducer(
|
|
|
1017
992
|
.replace(imageRegex, "")
|
|
1018
993
|
.trim();
|
|
1019
994
|
|
|
1020
|
-
if (
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
: "";
|
|
995
|
+
if (contentWithPlaceholders.startsWith("/btw ")) {
|
|
996
|
+
const question = contentWithPlaceholders.substring(5).trim();
|
|
997
|
+
if (!question) {
|
|
998
|
+
// Bare /btw with no question text — ignore
|
|
999
|
+
return state;
|
|
1000
|
+
}
|
|
1027
1001
|
|
|
1028
1002
|
return {
|
|
1029
1003
|
...state,
|
|
@@ -1032,15 +1006,19 @@ export function inputReducer(
|
|
|
1032
1006
|
historyIndex: -1,
|
|
1033
1007
|
longTextMap: {},
|
|
1034
1008
|
btwState: {
|
|
1035
|
-
isActive: true,
|
|
1036
1009
|
question,
|
|
1037
|
-
isLoading:
|
|
1010
|
+
isLoading: true,
|
|
1038
1011
|
answer: undefined,
|
|
1039
1012
|
},
|
|
1040
|
-
pendingEffect:
|
|
1013
|
+
pendingEffect: { type: "ASK_BTW", question },
|
|
1041
1014
|
};
|
|
1042
1015
|
}
|
|
1043
1016
|
|
|
1017
|
+
if (contentWithPlaceholders === "/btw") {
|
|
1018
|
+
// Bare /btw — ignore
|
|
1019
|
+
return state;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1044
1022
|
// Check if the content is a CLI-internal slash command (help, tasks,
|
|
1045
1023
|
// etc.) that should be executed locally rather than sent as a message.
|
|
1046
1024
|
// Agent slash commands and unknown /commands always go to SEND_MESSAGE.
|