erosolar-cli 1.7.201 → 1.7.203
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/shell/interactiveShell.d.ts +17 -1
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +182 -22
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/shellApp.d.ts.map +1 -1
- package/dist/shell/shellApp.js +5 -3
- package/dist/shell/shellApp.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts +9 -13
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +98 -169
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/orchestration/UIUpdateCoordinator.d.ts +77 -0
- package/dist/ui/orchestration/UIUpdateCoordinator.d.ts.map +1 -0
- package/dist/ui/orchestration/UIUpdateCoordinator.js +265 -0
- package/dist/ui/orchestration/UIUpdateCoordinator.js.map +1 -0
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ import { AgentSession, type ModelSelection } from '../runtime/agentSession.js';
|
|
|
4
4
|
import { LiveStatusTracker } from './liveStatus.js';
|
|
5
5
|
import { type WorkspaceCaptureOptions } from '../workspace.js';
|
|
6
6
|
import { ShellUIAdapter } from '../ui/ShellUIAdapter.js';
|
|
7
|
+
import { UIUpdateCoordinator } from '../ui/orchestration/UIUpdateCoordinator.js';
|
|
7
8
|
export interface ShellConfig {
|
|
8
9
|
profile: ProfileName;
|
|
9
10
|
profileLabel: string;
|
|
@@ -14,6 +15,7 @@ export interface ShellConfig {
|
|
|
14
15
|
agentSelection?: AgentSelectionConfig;
|
|
15
16
|
statusTracker: LiveStatusTracker;
|
|
16
17
|
uiAdapter: ShellUIAdapter;
|
|
18
|
+
uiUpdates?: UIUpdateCoordinator;
|
|
17
19
|
workspaceOptions: WorkspaceCaptureOptions;
|
|
18
20
|
sessionRestore?: SessionRestoreConfig;
|
|
19
21
|
enabledPlugins?: string[];
|
|
@@ -55,6 +57,7 @@ export declare class InteractiveShell {
|
|
|
55
57
|
private bannerSessionState;
|
|
56
58
|
private readonly statusTracker;
|
|
57
59
|
private readonly uiAdapter;
|
|
60
|
+
private readonly uiUpdates;
|
|
58
61
|
private readonly _fileChangeTracker;
|
|
59
62
|
private readonly alphaZeroMetrics;
|
|
60
63
|
private statusSubscription;
|
|
@@ -79,9 +82,11 @@ export declare class InteractiveShell {
|
|
|
79
82
|
private cachedProviderStatus;
|
|
80
83
|
private autoTestInFlight;
|
|
81
84
|
private lastAutoTestRun;
|
|
82
|
-
private
|
|
85
|
+
private autoBuildInFlight;
|
|
86
|
+
private lastAutoBuildRun;
|
|
83
87
|
private streamingHeartbeatStart;
|
|
84
88
|
private streamingHeartbeatFrame;
|
|
89
|
+
private statusMessageOverride;
|
|
85
90
|
private promptRefreshTimer;
|
|
86
91
|
constructor(config: ShellConfig);
|
|
87
92
|
private initializeSessionHistory;
|
|
@@ -262,6 +267,17 @@ export declare class InteractiveShell {
|
|
|
262
267
|
private getLatestTestTimestamp;
|
|
263
268
|
private formatCommandError;
|
|
264
269
|
private enforceAutoTests;
|
|
270
|
+
private isBuildToolCall;
|
|
271
|
+
private getLatestBuildTimestamp;
|
|
272
|
+
/**
|
|
273
|
+
* Auto-build verification after file edits.
|
|
274
|
+
* Runs `npm run build` to catch TypeScript errors and feeds failures back to the agent.
|
|
275
|
+
*/
|
|
276
|
+
private enforceAutoBuild;
|
|
277
|
+
/**
|
|
278
|
+
* Feed build errors back to the agent conversation for automatic fixing.
|
|
279
|
+
*/
|
|
280
|
+
private feedBuildErrorsToAgent;
|
|
265
281
|
private rebuildAgent;
|
|
266
282
|
/**
|
|
267
283
|
* Reset the unified input box to a fresh state after model/provider swap.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactiveShell.d.ts","sourceRoot":"","sources":["../../src/shell/interactiveShell.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAiCtE,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAyB,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAStF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"interactiveShell.d.ts","sourceRoot":"","sources":["../../src/shell/interactiveShell.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,6 +22,7 @@ import { formatShortcutsHelp } from '../ui/shortcutsHelp.js';
|
|
|
22
22
|
import { MetricsTracker } from '../alpha-zero/index.js';
|
|
23
23
|
import { listAvailablePlugins } from '../plugins/index.js';
|
|
24
24
|
import { TerminalInputAdapter } from './terminalInputAdapter.js';
|
|
25
|
+
import { UIUpdateCoordinator } from '../ui/orchestration/UIUpdateCoordinator.js';
|
|
25
26
|
const execAsync = promisify(exec);
|
|
26
27
|
const DROPDOWN_COLORS = [
|
|
27
28
|
theme.primary,
|
|
@@ -87,6 +88,7 @@ export class InteractiveShell {
|
|
|
87
88
|
bannerSessionState = null;
|
|
88
89
|
statusTracker;
|
|
89
90
|
uiAdapter;
|
|
91
|
+
uiUpdates;
|
|
90
92
|
_fileChangeTracker = new FileChangeTracker(); // Reserved for future file tracking features
|
|
91
93
|
alphaZeroMetrics; // Alpha Zero 2 performance tracking
|
|
92
94
|
statusSubscription = null;
|
|
@@ -113,10 +115,13 @@ export class InteractiveShell {
|
|
|
113
115
|
// Auto-test tracking
|
|
114
116
|
autoTestInFlight = false;
|
|
115
117
|
lastAutoTestRun = null;
|
|
118
|
+
// Auto-build tracking
|
|
119
|
+
autoBuildInFlight = false;
|
|
120
|
+
lastAutoBuildRun = null;
|
|
116
121
|
// Streaming UX tracking
|
|
117
|
-
streamingHeartbeat = null;
|
|
118
122
|
streamingHeartbeatStart = null;
|
|
119
123
|
streamingHeartbeatFrame = 0;
|
|
124
|
+
statusMessageOverride = null;
|
|
120
125
|
promptRefreshTimer = null;
|
|
121
126
|
constructor(config) {
|
|
122
127
|
this.profile = config.profile;
|
|
@@ -168,6 +173,12 @@ export class InteractiveShell {
|
|
|
168
173
|
});
|
|
169
174
|
this.statusTracker = config.statusTracker;
|
|
170
175
|
this.uiAdapter = config.uiAdapter;
|
|
176
|
+
this.uiUpdates =
|
|
177
|
+
config.uiUpdates ??
|
|
178
|
+
(typeof this.uiAdapter.getUpdateCoordinator === 'function'
|
|
179
|
+
? this.uiAdapter.getUpdateCoordinator()
|
|
180
|
+
: new UIUpdateCoordinator());
|
|
181
|
+
this.uiUpdates.setMode('idle');
|
|
171
182
|
// Set up file change tracking callback
|
|
172
183
|
this.uiAdapter.setFileChangeCallback((path, type, additions, removals) => {
|
|
173
184
|
this._fileChangeTracker.recordChange(path, type, additions, removals);
|
|
@@ -444,6 +455,7 @@ export class InteractiveShell {
|
|
|
444
455
|
// Stop any active spinner to prevent process hang
|
|
445
456
|
display.stopThinking(false);
|
|
446
457
|
this.stopStreamingHeartbeat();
|
|
458
|
+
this.uiUpdates.dispose();
|
|
447
459
|
this.clearPromptRefreshTimer();
|
|
448
460
|
this.teardownStatusTracking();
|
|
449
461
|
// Clear any pending cleanup to prevent hanging
|
|
@@ -468,7 +480,19 @@ export class InteractiveShell {
|
|
|
468
480
|
/**
|
|
469
481
|
* Update status bar message
|
|
470
482
|
*/
|
|
471
|
-
updateStatusMessage(
|
|
483
|
+
updateStatusMessage(message) {
|
|
484
|
+
this.statusMessageOverride = message;
|
|
485
|
+
const heartbeatActive = this.uiUpdates.isHeartbeatActive('streaming');
|
|
486
|
+
if (heartbeatActive) {
|
|
487
|
+
// During streaming, use display.updateStreamingStatus() to avoid cursor races
|
|
488
|
+
if (message) {
|
|
489
|
+
display.updateStreamingStatus(message);
|
|
490
|
+
}
|
|
491
|
+
// If message is null, let the heartbeat resume control
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
// When not streaming, use normal terminal input rendering
|
|
495
|
+
this.terminalInput.setStatusMessage(message);
|
|
472
496
|
this.terminalInput.render();
|
|
473
497
|
}
|
|
474
498
|
async handleToolSettingsInput(input) {
|
|
@@ -716,28 +740,39 @@ export class InteractiveShell {
|
|
|
716
740
|
}
|
|
717
741
|
startStreamingHeartbeat(label = 'Streaming response') {
|
|
718
742
|
this.stopStreamingHeartbeat();
|
|
743
|
+
this.uiUpdates.setMode('streaming');
|
|
719
744
|
this.streamingHeartbeatStart = Date.now();
|
|
720
745
|
this.streamingHeartbeatFrame = 0;
|
|
721
|
-
const frames = ['
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
746
|
+
const frames = ['⏵', '⏵⏵', '●', '⏵⏵'];
|
|
747
|
+
// Use display.updateStreamingStatus() which is designed for scroll regions
|
|
748
|
+
// Avoids cursor positioning conflicts with streaming content
|
|
749
|
+
this.uiUpdates.startHeartbeat('streaming', {
|
|
750
|
+
lane: 'status',
|
|
751
|
+
mode: 'streaming',
|
|
752
|
+
coalesceKey: 'status:heartbeat',
|
|
753
|
+
description: 'streaming-heartbeat',
|
|
754
|
+
intervalMs: 500,
|
|
755
|
+
run: () => {
|
|
756
|
+
if (this.statusMessageOverride) {
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
const frame = frames[this.streamingHeartbeatFrame % frames.length];
|
|
760
|
+
this.streamingHeartbeatFrame += 1;
|
|
761
|
+
const elapsed = this.streamingHeartbeatStart
|
|
762
|
+
? Math.floor((Date.now() - this.streamingHeartbeatStart) / 1000)
|
|
763
|
+
: 0;
|
|
764
|
+
const suffix = elapsed > 0 ? ` • ${elapsed}s` : '';
|
|
765
|
+
// Use display module's streaming status (avoids terminalInput.render() race)
|
|
766
|
+
display.updateStreamingStatus(`${frame} ${label}${suffix}`);
|
|
767
|
+
},
|
|
768
|
+
});
|
|
733
769
|
}
|
|
734
770
|
stopStreamingHeartbeat() {
|
|
735
|
-
|
|
736
|
-
clearInterval(this.streamingHeartbeat);
|
|
737
|
-
this.streamingHeartbeat = null;
|
|
738
|
-
}
|
|
771
|
+
this.uiUpdates.stopHeartbeat('streaming');
|
|
739
772
|
this.streamingHeartbeatStart = null;
|
|
740
|
-
this.
|
|
773
|
+
this.streamingHeartbeatFrame = 0;
|
|
774
|
+
// Clear the streaming status line
|
|
775
|
+
display.updateStreamingStatus(null);
|
|
741
776
|
}
|
|
742
777
|
refreshQueueIndicators() {
|
|
743
778
|
if (this.isProcessing) {
|
|
@@ -2068,6 +2103,7 @@ export class InteractiveShell {
|
|
|
2068
2103
|
return;
|
|
2069
2104
|
}
|
|
2070
2105
|
this.isProcessing = true;
|
|
2106
|
+
this.uiUpdates.setMode('processing');
|
|
2071
2107
|
this.terminalInput.setStreaming(true);
|
|
2072
2108
|
const requestStartTime = Date.now(); // Alpha Zero 2 timing
|
|
2073
2109
|
this.uiAdapter.startProcessing('Working on your request');
|
|
@@ -2102,6 +2138,7 @@ export class InteractiveShell {
|
|
|
2102
2138
|
}
|
|
2103
2139
|
finally {
|
|
2104
2140
|
display.stopThinking(false);
|
|
2141
|
+
this.uiUpdates.setMode('processing');
|
|
2105
2142
|
this.stopStreamingHeartbeat();
|
|
2106
2143
|
this.isProcessing = false;
|
|
2107
2144
|
this.terminalInput.setStreaming(false);
|
|
@@ -2112,6 +2149,7 @@ export class InteractiveShell {
|
|
|
2112
2149
|
// Claude Code style: Show unified status bar before prompt
|
|
2113
2150
|
// This creates consistent UI between startup and post-streaming
|
|
2114
2151
|
this.showUnifiedStatusBar();
|
|
2152
|
+
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2115
2153
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2116
2154
|
// Claude Code style: New prompt naturally appears at bottom
|
|
2117
2155
|
this.ensureReadlineReady();
|
|
@@ -2147,6 +2185,7 @@ export class InteractiveShell {
|
|
|
2147
2185
|
return;
|
|
2148
2186
|
}
|
|
2149
2187
|
this.isProcessing = true;
|
|
2188
|
+
this.uiUpdates.setMode('processing');
|
|
2150
2189
|
this.terminalInput.setStreaming(true);
|
|
2151
2190
|
const overallStartTime = Date.now();
|
|
2152
2191
|
// Initialize the task completion detector
|
|
@@ -2327,16 +2366,18 @@ What's the next action?`;
|
|
|
2327
2366
|
display.showSystemMessage(`\n🏁 Continuous execution completed: ${iteration} iterations, ${minutes}m ${seconds}s total`);
|
|
2328
2367
|
// Reset completion detector for next task
|
|
2329
2368
|
resetTaskCompletionDetector();
|
|
2369
|
+
this.uiUpdates.setMode('processing');
|
|
2370
|
+
this.stopStreamingHeartbeat();
|
|
2330
2371
|
this.isProcessing = false;
|
|
2331
2372
|
this.terminalInput.setStreaming(false);
|
|
2332
|
-
this.updateStatusMessage(null);
|
|
2333
2373
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2334
2374
|
this.setIdleStatus();
|
|
2335
|
-
this.
|
|
2375
|
+
this.updateStatusMessage(null);
|
|
2336
2376
|
display.newLine();
|
|
2337
2377
|
// Claude Code style: Show unified status bar before prompt
|
|
2338
2378
|
// This creates consistent UI between startup and post-streaming
|
|
2339
2379
|
this.showUnifiedStatusBar();
|
|
2380
|
+
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2340
2381
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2341
2382
|
// Claude Code style: New prompt naturally appears at bottom
|
|
2342
2383
|
this.ensureReadlineReady();
|
|
@@ -2582,6 +2623,121 @@ What's the next action?`;
|
|
|
2582
2623
|
this.autoTestInFlight = false;
|
|
2583
2624
|
}
|
|
2584
2625
|
}
|
|
2626
|
+
isBuildToolCall(entry) {
|
|
2627
|
+
const name = entry.toolName.toLowerCase();
|
|
2628
|
+
if (name === 'run_build' || name === 'build') {
|
|
2629
|
+
return true;
|
|
2630
|
+
}
|
|
2631
|
+
if (name === 'bash' || name === 'execute_bash') {
|
|
2632
|
+
const command = String(entry.args['command'] ?? '').toLowerCase();
|
|
2633
|
+
return (command.includes('npm run build') ||
|
|
2634
|
+
command.includes('yarn build') ||
|
|
2635
|
+
command.includes('pnpm build') ||
|
|
2636
|
+
command.includes('tsc'));
|
|
2637
|
+
}
|
|
2638
|
+
return false;
|
|
2639
|
+
}
|
|
2640
|
+
getLatestBuildTimestamp() {
|
|
2641
|
+
const history = this.runtimeSession.toolRuntime.getToolHistory?.() ?? [];
|
|
2642
|
+
let latest = this.lastAutoBuildRun;
|
|
2643
|
+
for (const entry of history) {
|
|
2644
|
+
if (this.isBuildToolCall(entry)) {
|
|
2645
|
+
latest = latest ? Math.max(latest, entry.timestamp) : entry.timestamp;
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
return latest;
|
|
2649
|
+
}
|
|
2650
|
+
/**
|
|
2651
|
+
* Auto-build verification after file edits.
|
|
2652
|
+
* Runs `npm run build` to catch TypeScript errors and feeds failures back to the agent.
|
|
2653
|
+
*/
|
|
2654
|
+
async enforceAutoBuild(trigger) {
|
|
2655
|
+
if (this.autoBuildInFlight) {
|
|
2656
|
+
return;
|
|
2657
|
+
}
|
|
2658
|
+
if (!this.verificationEnabled) {
|
|
2659
|
+
return;
|
|
2660
|
+
}
|
|
2661
|
+
const latestChange = this.getLatestFileChangeTimestamp();
|
|
2662
|
+
if (!latestChange) {
|
|
2663
|
+
return;
|
|
2664
|
+
}
|
|
2665
|
+
const latestBuild = this.getLatestBuildTimestamp();
|
|
2666
|
+
if (latestBuild && latestChange <= latestBuild) {
|
|
2667
|
+
return;
|
|
2668
|
+
}
|
|
2669
|
+
this.autoBuildInFlight = true;
|
|
2670
|
+
const command = 'npm run build';
|
|
2671
|
+
display.showSystemMessage(`🔨 Auto-building to verify changes (${trigger})...`);
|
|
2672
|
+
this.updateStatusMessage('Running build automatically...');
|
|
2673
|
+
try {
|
|
2674
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
2675
|
+
cwd: this.workingDir,
|
|
2676
|
+
timeout: 5 * 60 * 1000,
|
|
2677
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
2678
|
+
});
|
|
2679
|
+
this.lastAutoBuildRun = Date.now();
|
|
2680
|
+
const outputText = [stdout, stderr].filter(Boolean).join('\n').trim();
|
|
2681
|
+
display.showSystemMessage('✅ Build succeeded.');
|
|
2682
|
+
if (outputText && outputText.length < 500) {
|
|
2683
|
+
process.stdout.write(`${outputText}\n`);
|
|
2684
|
+
}
|
|
2685
|
+
this.statusTracker.clearOverride('build');
|
|
2686
|
+
}
|
|
2687
|
+
catch (error) {
|
|
2688
|
+
this.lastAutoBuildRun = Date.now();
|
|
2689
|
+
const errorOutput = this.formatCommandError(error);
|
|
2690
|
+
display.showWarning('⚠️ Build failed. Feeding errors back to agent...');
|
|
2691
|
+
if (errorOutput) {
|
|
2692
|
+
process.stdout.write(`${errorOutput}\n`);
|
|
2693
|
+
}
|
|
2694
|
+
this.statusTracker.pushOverride('build', 'Build failing', {
|
|
2695
|
+
detail: 'Auto-run npm run build failed',
|
|
2696
|
+
tone: 'danger',
|
|
2697
|
+
});
|
|
2698
|
+
// Feed build errors back to the agent so it can fix them
|
|
2699
|
+
await this.feedBuildErrorsToAgent(errorOutput);
|
|
2700
|
+
}
|
|
2701
|
+
finally {
|
|
2702
|
+
this.updateStatusMessage(null);
|
|
2703
|
+
this.autoBuildInFlight = false;
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
/**
|
|
2707
|
+
* Feed build errors back to the agent conversation for automatic fixing.
|
|
2708
|
+
*/
|
|
2709
|
+
async feedBuildErrorsToAgent(errorOutput) {
|
|
2710
|
+
if (!this.agent || !errorOutput) {
|
|
2711
|
+
return;
|
|
2712
|
+
}
|
|
2713
|
+
// Extract the most relevant error information
|
|
2714
|
+
const errorLines = errorOutput.split('\n');
|
|
2715
|
+
const relevantErrors = errorLines
|
|
2716
|
+
.filter((line) => line.includes('error TS') ||
|
|
2717
|
+
line.includes('Error:') ||
|
|
2718
|
+
line.includes('error:') ||
|
|
2719
|
+
/\(\d+,\d+\)/.test(line) // TypeScript error format: file(line,col)
|
|
2720
|
+
)
|
|
2721
|
+
.slice(0, 20); // Limit to first 20 errors
|
|
2722
|
+
const errorSummary = relevantErrors.length > 0 ? relevantErrors.join('\n') : errorOutput.slice(0, 2000);
|
|
2723
|
+
const prompt = `Build failed with the following errors. Please fix them:\n\n\`\`\`\n${errorSummary}\n\`\`\``;
|
|
2724
|
+
display.showSystemMessage('🔧 Asking agent to fix build errors...');
|
|
2725
|
+
this.updateStatusMessage('Agent fixing build errors...');
|
|
2726
|
+
try {
|
|
2727
|
+
// Send the error to the agent for fixing
|
|
2728
|
+
display.showThinking('Analyzing build errors');
|
|
2729
|
+
const response = await this.agent.send(prompt, true);
|
|
2730
|
+
display.stopThinking();
|
|
2731
|
+
if (response) {
|
|
2732
|
+
display.showAssistantMessage(response, { isFinal: true });
|
|
2733
|
+
}
|
|
2734
|
+
// Recursively verify the fix worked
|
|
2735
|
+
await this.enforceAutoBuild('verification');
|
|
2736
|
+
}
|
|
2737
|
+
catch (agentError) {
|
|
2738
|
+
display.showWarning('Agent could not automatically fix build errors. Please review manually.');
|
|
2739
|
+
}
|
|
2740
|
+
}
|
|
2585
2741
|
rebuildAgent() {
|
|
2586
2742
|
const previousHistory = this.agent ? this.agent.getHistory() : this.cachedHistory;
|
|
2587
2743
|
try {
|
|
@@ -2639,6 +2795,8 @@ What's the next action?`;
|
|
|
2639
2795
|
}
|
|
2640
2796
|
}
|
|
2641
2797
|
display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
|
|
2798
|
+
// Auto-verify changes: build first (catches type errors), then tests
|
|
2799
|
+
void this.enforceAutoBuild('final-response');
|
|
2642
2800
|
void this.enforceAutoTests('final-response');
|
|
2643
2801
|
}
|
|
2644
2802
|
else {
|
|
@@ -2702,12 +2860,14 @@ What's the next action?`;
|
|
|
2702
2860
|
onCancelled: () => {
|
|
2703
2861
|
// Update UI to show operation was cancelled
|
|
2704
2862
|
display.showWarning('Operation cancelled.');
|
|
2705
|
-
this.
|
|
2863
|
+
this.uiUpdates.setMode('processing');
|
|
2706
2864
|
this.stopStreamingHeartbeat();
|
|
2865
|
+
this.updateStatusMessage(null);
|
|
2707
2866
|
this.terminalInput.setStreaming(false);
|
|
2708
2867
|
this.terminalInput.render();
|
|
2709
2868
|
},
|
|
2710
2869
|
onVerificationNeeded: () => {
|
|
2870
|
+
void this.enforceAutoBuild('verification');
|
|
2711
2871
|
void this.enforceAutoTests('verification');
|
|
2712
2872
|
},
|
|
2713
2873
|
});
|