@dreb/coding-agent 2.31.0 → 2.32.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/CHANGELOG.md +2 -0
- package/dist/core/nested-context.d.ts +49 -2
- package/dist/core/nested-context.d.ts.map +1 -1
- package/dist/core/nested-context.js +220 -11
- package/dist/core/nested-context.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +18 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +139 -94
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/tui.md +2 -9
- package/package.json +1 -1
|
@@ -7,7 +7,7 @@ import * as fs from "node:fs";
|
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import * as path from "node:path";
|
|
9
9
|
import { supportsAdaptiveThinking } from "@dreb/ai";
|
|
10
|
-
import { CombinedAutocompleteProvider, Container, fuzzyFilter,
|
|
10
|
+
import { CombinedAutocompleteProvider, Container, fuzzyFilter, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TUI, visibleWidth, } from "@dreb/tui";
|
|
11
11
|
import { spawn, spawnSync } from "child_process";
|
|
12
12
|
import { APP_NAME, getAgentDir, getAuthPath, getDebugLogPath, getUpdateInstruction, VERSION } from "../../config.js";
|
|
13
13
|
import { parseSkillBlock } from "../../core/agent-session.js";
|
|
@@ -87,9 +87,16 @@ export class InteractiveMode {
|
|
|
87
87
|
version;
|
|
88
88
|
isInitialized = false;
|
|
89
89
|
onInputCallback;
|
|
90
|
-
loadingAnimation = undefined;
|
|
91
90
|
pendingWorkingMessage = undefined;
|
|
92
91
|
defaultWorkingMessage = "Working...";
|
|
92
|
+
workingFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
93
|
+
workingFrame = 0;
|
|
94
|
+
workingInterval = undefined;
|
|
95
|
+
inlineStatusOwner = undefined;
|
|
96
|
+
inlineStatusSpinner = (spinner) => theme.fg("accent", spinner);
|
|
97
|
+
warnedMissingInlineStatus = false;
|
|
98
|
+
isAgentWorking = false;
|
|
99
|
+
currentWorkingMessage = this.defaultWorkingMessage;
|
|
93
100
|
lastSigintTime = 0;
|
|
94
101
|
lastEscapeTime = 0;
|
|
95
102
|
changelogMarkdown = undefined;
|
|
@@ -1016,10 +1023,7 @@ export class InteractiveMode {
|
|
|
1016
1023
|
commandContextActions: {
|
|
1017
1024
|
waitForIdle: () => this.session.agent.waitForIdle(),
|
|
1018
1025
|
newSession: async (options) => {
|
|
1019
|
-
|
|
1020
|
-
this.loadingAnimation.stop();
|
|
1021
|
-
this.loadingAnimation = undefined;
|
|
1022
|
-
}
|
|
1026
|
+
this.stopAllInlineStatus();
|
|
1023
1027
|
this.statusContainer.clear();
|
|
1024
1028
|
// Delegate to AgentSession (handles setup + agent state sync)
|
|
1025
1029
|
const success = await this.session.newSession(options);
|
|
@@ -1230,8 +1234,8 @@ export class InteractiveMode {
|
|
|
1230
1234
|
this.setCustomEditorComponent(undefined);
|
|
1231
1235
|
this.defaultEditor.onExtensionShortcut = undefined;
|
|
1232
1236
|
this.updateTerminalTitle();
|
|
1233
|
-
if (this.
|
|
1234
|
-
this.
|
|
1237
|
+
if (this.isAgentWorking) {
|
|
1238
|
+
this.setWorkingMessage();
|
|
1235
1239
|
}
|
|
1236
1240
|
// Re-mount buddy so it survives reload
|
|
1237
1241
|
if (buddyState) {
|
|
@@ -1343,6 +1347,100 @@ export class InteractiveMode {
|
|
|
1343
1347
|
}
|
|
1344
1348
|
this.extensionTerminalInputUnsubscribers.clear();
|
|
1345
1349
|
}
|
|
1350
|
+
defaultInterruptWorkingMessage() {
|
|
1351
|
+
return `${this.defaultWorkingMessage} (${keyText("app.interrupt")} to interrupt)`;
|
|
1352
|
+
}
|
|
1353
|
+
setEditorInlineStatus(text) {
|
|
1354
|
+
this.defaultEditor.setInlineStatus(text);
|
|
1355
|
+
if (this.editor === this.defaultEditor)
|
|
1356
|
+
return;
|
|
1357
|
+
this.editor.setInlineStatus?.(text);
|
|
1358
|
+
if (!text || this.editor.setInlineStatus || this.warnedMissingInlineStatus)
|
|
1359
|
+
return;
|
|
1360
|
+
this.warnedMissingInlineStatus = true;
|
|
1361
|
+
this.showWarning("Custom editor component does not support inline working status; progress and interrupt hints may be hidden.");
|
|
1362
|
+
}
|
|
1363
|
+
renderWorkingIndicator() {
|
|
1364
|
+
if (!this.inlineStatusOwner)
|
|
1365
|
+
return;
|
|
1366
|
+
const frame = this.workingFrames[this.workingFrame] ?? this.workingFrames[0];
|
|
1367
|
+
this.setEditorInlineStatus(`${this.inlineStatusSpinner(frame)} ${theme.fg("muted", this.currentWorkingMessage)}`);
|
|
1368
|
+
}
|
|
1369
|
+
startInlineStatus(owner, message, spinner = (frame) => theme.fg("accent", frame)) {
|
|
1370
|
+
this.stopInlineStatus();
|
|
1371
|
+
this.inlineStatusOwner = owner;
|
|
1372
|
+
this.inlineStatusSpinner = spinner;
|
|
1373
|
+
this.currentWorkingMessage = message;
|
|
1374
|
+
this.workingFrame = 0;
|
|
1375
|
+
this.renderWorkingIndicator();
|
|
1376
|
+
this.workingInterval = setInterval(() => {
|
|
1377
|
+
this.workingFrame = (this.workingFrame + 1) % this.workingFrames.length;
|
|
1378
|
+
this.renderWorkingIndicator();
|
|
1379
|
+
}, 80);
|
|
1380
|
+
}
|
|
1381
|
+
stopInlineStatus(owner) {
|
|
1382
|
+
if (owner && this.inlineStatusOwner !== owner)
|
|
1383
|
+
return;
|
|
1384
|
+
if (this.workingInterval) {
|
|
1385
|
+
clearInterval(this.workingInterval);
|
|
1386
|
+
this.workingInterval = undefined;
|
|
1387
|
+
}
|
|
1388
|
+
if (this.inlineStatusOwner) {
|
|
1389
|
+
this.inlineStatusOwner = undefined;
|
|
1390
|
+
this.currentWorkingMessage = this.defaultWorkingMessage;
|
|
1391
|
+
this.inlineStatusSpinner = (spinner) => theme.fg("accent", spinner);
|
|
1392
|
+
this.setEditorInlineStatus(null);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
startInlineLoader(owner, message, spinner = (frame) => theme.fg("accent", frame)) {
|
|
1396
|
+
this.startInlineStatus(owner, message, spinner);
|
|
1397
|
+
return {
|
|
1398
|
+
stop: () => this.stopInlineStatus(owner),
|
|
1399
|
+
setText: (text) => {
|
|
1400
|
+
if (this.inlineStatusOwner !== owner)
|
|
1401
|
+
return;
|
|
1402
|
+
this.currentWorkingMessage = text;
|
|
1403
|
+
this.renderWorkingIndicator();
|
|
1404
|
+
},
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
startAgentWorking(message) {
|
|
1408
|
+
this.stopAgentWorking();
|
|
1409
|
+
this.isAgentWorking = true;
|
|
1410
|
+
this.startInlineStatus("agent", message || this.defaultInterruptWorkingMessage());
|
|
1411
|
+
}
|
|
1412
|
+
stopAgentWorking() {
|
|
1413
|
+
if (this.isAgentWorking) {
|
|
1414
|
+
this.isAgentWorking = false;
|
|
1415
|
+
this.stopInlineStatus("agent");
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
stopAllInlineStatus() {
|
|
1419
|
+
this.isAgentWorking = false;
|
|
1420
|
+
this.pendingWorkingMessage = undefined;
|
|
1421
|
+
this.stopInlineStatus();
|
|
1422
|
+
this.autoCompactionLoader = undefined;
|
|
1423
|
+
this.retryLoader = undefined;
|
|
1424
|
+
if (this.autoCompactionEscapeHandler) {
|
|
1425
|
+
this.defaultEditor.onEscape = this.autoCompactionEscapeHandler;
|
|
1426
|
+
this.autoCompactionEscapeHandler = undefined;
|
|
1427
|
+
}
|
|
1428
|
+
if (this.retryEscapeHandler) {
|
|
1429
|
+
this.defaultEditor.onEscape = this.retryEscapeHandler;
|
|
1430
|
+
this.retryEscapeHandler = undefined;
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
setWorkingMessage(message) {
|
|
1434
|
+
const nextMessage = message || this.defaultInterruptWorkingMessage();
|
|
1435
|
+
if (this.isAgentWorking) {
|
|
1436
|
+
this.currentWorkingMessage = nextMessage;
|
|
1437
|
+
this.renderWorkingIndicator();
|
|
1438
|
+
}
|
|
1439
|
+
else {
|
|
1440
|
+
// Queue message for when the next agent_start arrives.
|
|
1441
|
+
this.pendingWorkingMessage = message;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1346
1444
|
/**
|
|
1347
1445
|
* Create the ExtensionUIContext for extensions.
|
|
1348
1446
|
*/
|
|
@@ -1354,20 +1452,7 @@ export class InteractiveMode {
|
|
|
1354
1452
|
notify: (message, type) => this.showExtensionNotify(message, type),
|
|
1355
1453
|
onTerminalInput: (handler) => this.addExtensionTerminalInputListener(handler),
|
|
1356
1454
|
setStatus: (key, text) => this.setExtensionStatus(key, text),
|
|
1357
|
-
setWorkingMessage: (message) =>
|
|
1358
|
-
if (this.loadingAnimation) {
|
|
1359
|
-
if (message) {
|
|
1360
|
-
this.loadingAnimation.setMessage(message);
|
|
1361
|
-
}
|
|
1362
|
-
else {
|
|
1363
|
-
this.loadingAnimation.setMessage(`${this.defaultWorkingMessage} (${keyText("app.interrupt")} to interrupt)`);
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
else {
|
|
1367
|
-
// Queue message for when loadingAnimation is created (handles agent_start race)
|
|
1368
|
-
this.pendingWorkingMessage = message;
|
|
1369
|
-
}
|
|
1370
|
-
},
|
|
1455
|
+
setWorkingMessage: (message) => this.setWorkingMessage(message),
|
|
1371
1456
|
setWidget: (key, content, options) => this.setExtensionWidget(key, content, options),
|
|
1372
1457
|
setFooter: (factory) => this.setExtensionFooter(factory),
|
|
1373
1458
|
setHeader: (factory) => this.setExtensionHeader(factory),
|
|
@@ -1563,6 +1648,9 @@ export class InteractiveMode {
|
|
|
1563
1648
|
this.defaultEditor.setText(currentText);
|
|
1564
1649
|
this.editor = this.defaultEditor;
|
|
1565
1650
|
}
|
|
1651
|
+
if (this.isAgentWorking) {
|
|
1652
|
+
this.renderWorkingIndicator();
|
|
1653
|
+
}
|
|
1566
1654
|
this.editorContainer.addChild(this.editor);
|
|
1567
1655
|
this.ui.setFocus(this.editor);
|
|
1568
1656
|
this.ui.requestRender();
|
|
@@ -1676,7 +1764,7 @@ export class InteractiveMode {
|
|
|
1676
1764
|
this.defaultEditor.onEscape = () => {
|
|
1677
1765
|
// Always clear ghost text on Escape (CustomEditor intercepts before super.handleInput)
|
|
1678
1766
|
this.editor.setGhostText?.(null);
|
|
1679
|
-
if (this.
|
|
1767
|
+
if (this.isAgentWorking) {
|
|
1680
1768
|
this.cancelBackgroundAgents();
|
|
1681
1769
|
this.restoreQueuedMessagesToEditor({ abort: true });
|
|
1682
1770
|
}
|
|
@@ -1972,20 +2060,9 @@ export class InteractiveMode {
|
|
|
1972
2060
|
this.retryLoader.stop();
|
|
1973
2061
|
this.retryLoader = undefined;
|
|
1974
2062
|
}
|
|
1975
|
-
if (this.loadingAnimation) {
|
|
1976
|
-
this.loadingAnimation.stop();
|
|
1977
|
-
}
|
|
1978
2063
|
this.statusContainer.clear();
|
|
1979
|
-
this.
|
|
1980
|
-
this.
|
|
1981
|
-
// Apply any pending working message queued before loader existed
|
|
1982
|
-
if (this.pendingWorkingMessage !== undefined) {
|
|
1983
|
-
if (this.pendingWorkingMessage) {
|
|
1984
|
-
this.loadingAnimation.setMessage(this.pendingWorkingMessage);
|
|
1985
|
-
}
|
|
1986
|
-
this.pendingWorkingMessage = undefined;
|
|
1987
|
-
}
|
|
1988
|
-
this.ui.requestRender();
|
|
2064
|
+
this.startAgentWorking(this.pendingWorkingMessage);
|
|
2065
|
+
this.pendingWorkingMessage = undefined;
|
|
1989
2066
|
break;
|
|
1990
2067
|
case "message_start":
|
|
1991
2068
|
if (event.message.role === "custom") {
|
|
@@ -2128,10 +2205,7 @@ export class InteractiveMode {
|
|
|
2128
2205
|
this.retryLoader.stop();
|
|
2129
2206
|
this.retryLoader = undefined;
|
|
2130
2207
|
}
|
|
2131
|
-
|
|
2132
|
-
this.loadingAnimation.stop();
|
|
2133
|
-
this.loadingAnimation = undefined;
|
|
2134
|
-
}
|
|
2208
|
+
this.stopAgentWorking();
|
|
2135
2209
|
this.statusContainer.clear();
|
|
2136
2210
|
if (this.streamingComponent) {
|
|
2137
2211
|
this.chatContainer.removeChild(this.streamingComponent);
|
|
@@ -2155,12 +2229,10 @@ export class InteractiveMode {
|
|
|
2155
2229
|
this.defaultEditor.onEscape = () => {
|
|
2156
2230
|
this.session.abortCompaction();
|
|
2157
2231
|
};
|
|
2158
|
-
// Show compacting indicator
|
|
2232
|
+
// Show compacting indicator inside the editor line so start/end is constant-height.
|
|
2159
2233
|
this.statusContainer.clear();
|
|
2160
2234
|
const reasonText = event.reason === "overflow" ? "Context overflow detected, " : "";
|
|
2161
|
-
this.autoCompactionLoader =
|
|
2162
|
-
this.statusContainer.addChild(this.autoCompactionLoader);
|
|
2163
|
-
this.ui.requestRender();
|
|
2235
|
+
this.autoCompactionLoader = this.startInlineLoader("autoCompaction", `${reasonText}Auto-compacting... (${keyText("app.interrupt")} to cancel)`);
|
|
2164
2236
|
break;
|
|
2165
2237
|
}
|
|
2166
2238
|
case "auto_compaction_end": {
|
|
@@ -2208,12 +2280,10 @@ export class InteractiveMode {
|
|
|
2208
2280
|
this.defaultEditor.onEscape = () => {
|
|
2209
2281
|
this.session.abortRetry();
|
|
2210
2282
|
};
|
|
2211
|
-
// Show retry indicator
|
|
2283
|
+
// Show retry indicator inside the editor line so start/end is constant-height.
|
|
2212
2284
|
this.statusContainer.clear();
|
|
2213
2285
|
const delaySeconds = Math.round(event.delayMs / 1000);
|
|
2214
|
-
this.retryLoader =
|
|
2215
|
-
this.statusContainer.addChild(this.retryLoader);
|
|
2216
|
-
this.ui.requestRender();
|
|
2286
|
+
this.retryLoader = this.startInlineLoader("autoRetry", `Retrying (${event.attempt}/${event.maxAttempts}) in ${delaySeconds}s... (${keyText("app.interrupt")} to cancel)`, (spinner) => theme.fg("warning", spinner));
|
|
2217
2287
|
break;
|
|
2218
2288
|
}
|
|
2219
2289
|
case "auto_retry_end": {
|
|
@@ -2247,8 +2317,8 @@ export class InteractiveMode {
|
|
|
2247
2317
|
this.chatContainer.removeChild(component);
|
|
2248
2318
|
}
|
|
2249
2319
|
this.pendingTools.clear();
|
|
2250
|
-
// Warn in the chat scrollback — keep the working
|
|
2251
|
-
// aborts via the normal
|
|
2320
|
+
// Warn in the chat scrollback — keep the inline working indicator active so ESC
|
|
2321
|
+
// aborts via the normal agent-working path (same AbortController).
|
|
2252
2322
|
this.showWarning(`Stream dropped, retrying (${event.attempt}/${event.maxAttempts})…`);
|
|
2253
2323
|
break;
|
|
2254
2324
|
}
|
|
@@ -2264,8 +2334,8 @@ export class InteractiveMode {
|
|
|
2264
2334
|
this.chatContainer.removeChild(component);
|
|
2265
2335
|
}
|
|
2266
2336
|
this.pendingTools.clear();
|
|
2267
|
-
// Warn in the chat scrollback — keep the working
|
|
2268
|
-
// aborts via the normal
|
|
2337
|
+
// Warn in the chat scrollback — keep the inline working indicator active so ESC
|
|
2338
|
+
// aborts via the normal agent-working path (same AbortController).
|
|
2269
2339
|
this.showWarning(`Response truncated, retrying with larger token budget (${event.attempt}/${event.maxAttempts})…`);
|
|
2270
2340
|
break;
|
|
2271
2341
|
}
|
|
@@ -3492,7 +3562,7 @@ export class InteractiveMode {
|
|
|
3492
3562
|
break;
|
|
3493
3563
|
}
|
|
3494
3564
|
}
|
|
3495
|
-
// Set up escape handler and loader if summarizing
|
|
3565
|
+
// Set up escape handler and inline loader if summarizing
|
|
3496
3566
|
let summaryLoader;
|
|
3497
3567
|
const originalOnEscape = this.defaultEditor.onEscape;
|
|
3498
3568
|
if (wantsSummary) {
|
|
@@ -3500,9 +3570,7 @@ export class InteractiveMode {
|
|
|
3500
3570
|
this.session.abortBranchSummary();
|
|
3501
3571
|
};
|
|
3502
3572
|
this.chatContainer.addChild(new Spacer(1));
|
|
3503
|
-
summaryLoader =
|
|
3504
|
-
this.statusContainer.addChild(summaryLoader);
|
|
3505
|
-
this.ui.requestRender();
|
|
3573
|
+
summaryLoader = this.startInlineLoader("branchSummary", `Summarizing branch... (${keyText("app.interrupt")} to cancel)`);
|
|
3506
3574
|
}
|
|
3507
3575
|
try {
|
|
3508
3576
|
const result = await this.session.navigateTree(entryId, {
|
|
@@ -3571,11 +3639,8 @@ export class InteractiveMode {
|
|
|
3571
3639
|
});
|
|
3572
3640
|
}
|
|
3573
3641
|
async handleResumeSession(sessionPath) {
|
|
3574
|
-
// Stop
|
|
3575
|
-
|
|
3576
|
-
this.loadingAnimation.stop();
|
|
3577
|
-
this.loadingAnimation = undefined;
|
|
3578
|
-
}
|
|
3642
|
+
// Stop inline working indicator/status loader
|
|
3643
|
+
this.stopAllInlineStatus();
|
|
3579
3644
|
this.statusContainer.clear();
|
|
3580
3645
|
// Clear UI state
|
|
3581
3646
|
this.editor.setGhostText?.(null);
|
|
@@ -3803,11 +3868,8 @@ export class InteractiveMode {
|
|
|
3803
3868
|
return;
|
|
3804
3869
|
}
|
|
3805
3870
|
try {
|
|
3806
|
-
// Stop
|
|
3807
|
-
|
|
3808
|
-
this.loadingAnimation.stop();
|
|
3809
|
-
this.loadingAnimation = undefined;
|
|
3810
|
-
}
|
|
3871
|
+
// Stop inline working indicator/status loader
|
|
3872
|
+
this.stopAllInlineStatus();
|
|
3811
3873
|
this.statusContainer.clear();
|
|
3812
3874
|
// Clear UI state
|
|
3813
3875
|
this.pendingMessagesContainer.clear();
|
|
@@ -4108,11 +4170,8 @@ ${cycleModelForward || cycleModelBackward ? `| \`${cycleModelForward}\` / \`${cy
|
|
|
4108
4170
|
this.ui.requestRender();
|
|
4109
4171
|
}
|
|
4110
4172
|
async handleClearCommand() {
|
|
4111
|
-
// Stop
|
|
4112
|
-
|
|
4113
|
-
this.loadingAnimation.stop();
|
|
4114
|
-
this.loadingAnimation = undefined;
|
|
4115
|
-
}
|
|
4173
|
+
// Stop inline working indicator/status loader
|
|
4174
|
+
this.stopAllInlineStatus();
|
|
4116
4175
|
this.statusContainer.clear();
|
|
4117
4176
|
// New session via session (emits extension session events)
|
|
4118
4177
|
await this.session.newSession();
|
|
@@ -4275,11 +4334,8 @@ ${cycleModelForward || cycleModelBackward ? `| \`${cycleModelForward}\` / \`${cy
|
|
|
4275
4334
|
}
|
|
4276
4335
|
}
|
|
4277
4336
|
async executeDream() {
|
|
4278
|
-
// Stop any existing
|
|
4279
|
-
|
|
4280
|
-
this.loadingAnimation.stop();
|
|
4281
|
-
this.loadingAnimation = undefined;
|
|
4282
|
-
}
|
|
4337
|
+
// Stop any existing inline working indicator/status loader
|
|
4338
|
+
this.stopAllInlineStatus();
|
|
4283
4339
|
this.statusContainer.clear();
|
|
4284
4340
|
let releaseLock;
|
|
4285
4341
|
let dreamContext;
|
|
@@ -4289,12 +4345,10 @@ ${cycleModelForward || cycleModelBackward ? `| \`${cycleModelForward}\` / \`${cy
|
|
|
4289
4345
|
// User pressed escape — abort the dream
|
|
4290
4346
|
this.session.abort();
|
|
4291
4347
|
};
|
|
4292
|
-
// Show loading spinner
|
|
4348
|
+
// Show loading spinner inside the editor line so start/end is constant-height.
|
|
4293
4349
|
this.chatContainer.addChild(new Spacer(1));
|
|
4294
4350
|
const cancelHint = `(${keyText("app.interrupt")} to cancel)`;
|
|
4295
|
-
const dreamLoader =
|
|
4296
|
-
this.statusContainer.addChild(dreamLoader);
|
|
4297
|
-
this.ui.requestRender();
|
|
4351
|
+
const dreamLoader = this.startInlineLoader("dream", `Dreaming... ${cancelHint}`);
|
|
4298
4352
|
try {
|
|
4299
4353
|
// Acquire lock
|
|
4300
4354
|
try {
|
|
@@ -4334,7 +4388,6 @@ ${cycleModelForward || cycleModelBackward ? `| \`${cycleModelForward}\` / \`${cy
|
|
|
4334
4388
|
}
|
|
4335
4389
|
// Update loader text
|
|
4336
4390
|
dreamLoader.setText(`Consolidating memories... ${cancelHint}`);
|
|
4337
|
-
this.ui.requestRender();
|
|
4338
4391
|
// Build prompt and inject into session
|
|
4339
4392
|
const prompt = buildDreamPrompt(dreamContext, backupResult);
|
|
4340
4393
|
await this.session.prompt(prompt);
|
|
@@ -4381,24 +4434,19 @@ ${cycleModelForward || cycleModelBackward ? `| \`${cycleModelForward}\` / \`${cy
|
|
|
4381
4434
|
await this.executeCompaction(customInstructions, false);
|
|
4382
4435
|
}
|
|
4383
4436
|
async executeCompaction(customInstructions, isAuto = false) {
|
|
4384
|
-
// Stop
|
|
4385
|
-
|
|
4386
|
-
this.loadingAnimation.stop();
|
|
4387
|
-
this.loadingAnimation = undefined;
|
|
4388
|
-
}
|
|
4437
|
+
// Stop inline working indicator/status loader
|
|
4438
|
+
this.stopAllInlineStatus();
|
|
4389
4439
|
this.statusContainer.clear();
|
|
4390
4440
|
// Set up escape handler during compaction
|
|
4391
4441
|
const originalOnEscape = this.defaultEditor.onEscape;
|
|
4392
4442
|
this.defaultEditor.onEscape = () => {
|
|
4393
4443
|
this.session.abortCompaction();
|
|
4394
4444
|
};
|
|
4395
|
-
// Show compacting status
|
|
4445
|
+
// Show compacting status inside the editor line so start/end is constant-height.
|
|
4396
4446
|
this.chatContainer.addChild(new Spacer(1));
|
|
4397
4447
|
const cancelHint = `(${keyText("app.interrupt")} to cancel)`;
|
|
4398
4448
|
const label = isAuto ? `Auto-compacting context... ${cancelHint}` : `Compacting context... ${cancelHint}`;
|
|
4399
|
-
const compactingLoader =
|
|
4400
|
-
this.statusContainer.addChild(compactingLoader);
|
|
4401
|
-
this.ui.requestRender();
|
|
4449
|
+
const compactingLoader = this.startInlineLoader("compaction", label);
|
|
4402
4450
|
let result;
|
|
4403
4451
|
try {
|
|
4404
4452
|
result = await this.session.compact(customInstructions);
|
|
@@ -4632,10 +4680,7 @@ ${cycleModelForward || cycleModelBackward ? `| \`${cycleModelForward}\` / \`${cy
|
|
|
4632
4680
|
}
|
|
4633
4681
|
stop() {
|
|
4634
4682
|
this.buddyController.stop();
|
|
4635
|
-
|
|
4636
|
-
this.loadingAnimation.stop();
|
|
4637
|
-
this.loadingAnimation = undefined;
|
|
4638
|
-
}
|
|
4683
|
+
this.stopAllInlineStatus();
|
|
4639
4684
|
this.removeBuddy();
|
|
4640
4685
|
this.clearExtensionTerminalInputListeners();
|
|
4641
4686
|
this.footer.dispose();
|