erosolar-cli 1.7.200 → 1.7.202
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 +193 -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/display.d.ts +1 -0
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +7 -12
- package/dist/ui/display.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,8 +480,23 @@ export class InteractiveShell {
|
|
|
468
480
|
/**
|
|
469
481
|
* Update status bar message
|
|
470
482
|
*/
|
|
471
|
-
updateStatusMessage(
|
|
472
|
-
this.
|
|
483
|
+
updateStatusMessage(message) {
|
|
484
|
+
this.statusMessageOverride = message;
|
|
485
|
+
const heartbeatActive = this.uiUpdates.isHeartbeatActive('streaming');
|
|
486
|
+
if (message === null && heartbeatActive) {
|
|
487
|
+
// Let the streaming heartbeat resume control of the status line.
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
this.uiUpdates.enqueue({
|
|
491
|
+
lane: 'status',
|
|
492
|
+
description: message ? 'status-message' : 'clear-status-message',
|
|
493
|
+
coalesceKey: 'status:heartbeat',
|
|
494
|
+
priority: message ? 'high' : 'normal',
|
|
495
|
+
run: () => {
|
|
496
|
+
this.terminalInput.setStatusMessage(message);
|
|
497
|
+
this.terminalInput.render();
|
|
498
|
+
},
|
|
499
|
+
});
|
|
473
500
|
}
|
|
474
501
|
async handleToolSettingsInput(input) {
|
|
475
502
|
const pending = this.pendingInteraction;
|
|
@@ -716,28 +743,47 @@ export class InteractiveShell {
|
|
|
716
743
|
}
|
|
717
744
|
startStreamingHeartbeat(label = 'Streaming response') {
|
|
718
745
|
this.stopStreamingHeartbeat();
|
|
746
|
+
this.uiUpdates.setMode('streaming');
|
|
719
747
|
this.streamingHeartbeatStart = Date.now();
|
|
720
748
|
this.streamingHeartbeatFrame = 0;
|
|
721
749
|
const frames = ['●', '◐', '◉', '◐'];
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
750
|
+
this.uiUpdates.startHeartbeat('streaming', {
|
|
751
|
+
lane: 'status',
|
|
752
|
+
mode: 'streaming',
|
|
753
|
+
coalesceKey: 'status:heartbeat',
|
|
754
|
+
description: 'streaming-heartbeat',
|
|
755
|
+
intervalMs: 500,
|
|
756
|
+
run: () => {
|
|
757
|
+
if (this.statusMessageOverride) {
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
const frame = frames[this.streamingHeartbeatFrame % frames.length];
|
|
761
|
+
this.streamingHeartbeatFrame += 1;
|
|
762
|
+
const elapsed = this.streamingHeartbeatStart
|
|
763
|
+
? Math.floor((Date.now() - this.streamingHeartbeatStart) / 1000)
|
|
764
|
+
: 0;
|
|
765
|
+
const suffix = elapsed > 0 ? ` • ${elapsed}s` : '';
|
|
766
|
+
this.terminalInput.setStatusMessage(`${frame} ${label}${suffix}`);
|
|
767
|
+
this.terminalInput.render();
|
|
768
|
+
},
|
|
769
|
+
});
|
|
733
770
|
}
|
|
734
771
|
stopStreamingHeartbeat() {
|
|
735
|
-
|
|
736
|
-
clearInterval(this.streamingHeartbeat);
|
|
737
|
-
this.streamingHeartbeat = null;
|
|
738
|
-
}
|
|
772
|
+
this.uiUpdates.stopHeartbeat('streaming');
|
|
739
773
|
this.streamingHeartbeatStart = null;
|
|
740
|
-
this.
|
|
774
|
+
this.streamingHeartbeatFrame = 0;
|
|
775
|
+
if (!this.statusMessageOverride) {
|
|
776
|
+
this.uiUpdates.enqueue({
|
|
777
|
+
lane: 'status',
|
|
778
|
+
description: 'clear-streaming-heartbeat',
|
|
779
|
+
coalesceKey: 'status:heartbeat',
|
|
780
|
+
priority: 'low',
|
|
781
|
+
run: () => {
|
|
782
|
+
this.terminalInput.setStatusMessage(null);
|
|
783
|
+
this.terminalInput.render();
|
|
784
|
+
},
|
|
785
|
+
});
|
|
786
|
+
}
|
|
741
787
|
}
|
|
742
788
|
refreshQueueIndicators() {
|
|
743
789
|
if (this.isProcessing) {
|
|
@@ -2068,6 +2114,7 @@ export class InteractiveShell {
|
|
|
2068
2114
|
return;
|
|
2069
2115
|
}
|
|
2070
2116
|
this.isProcessing = true;
|
|
2117
|
+
this.uiUpdates.setMode('processing');
|
|
2071
2118
|
this.terminalInput.setStreaming(true);
|
|
2072
2119
|
const requestStartTime = Date.now(); // Alpha Zero 2 timing
|
|
2073
2120
|
this.uiAdapter.startProcessing('Working on your request');
|
|
@@ -2102,6 +2149,7 @@ export class InteractiveShell {
|
|
|
2102
2149
|
}
|
|
2103
2150
|
finally {
|
|
2104
2151
|
display.stopThinking(false);
|
|
2152
|
+
this.uiUpdates.setMode('processing');
|
|
2105
2153
|
this.stopStreamingHeartbeat();
|
|
2106
2154
|
this.isProcessing = false;
|
|
2107
2155
|
this.terminalInput.setStreaming(false);
|
|
@@ -2112,6 +2160,7 @@ export class InteractiveShell {
|
|
|
2112
2160
|
// Claude Code style: Show unified status bar before prompt
|
|
2113
2161
|
// This creates consistent UI between startup and post-streaming
|
|
2114
2162
|
this.showUnifiedStatusBar();
|
|
2163
|
+
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2115
2164
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2116
2165
|
// Claude Code style: New prompt naturally appears at bottom
|
|
2117
2166
|
this.ensureReadlineReady();
|
|
@@ -2147,6 +2196,7 @@ export class InteractiveShell {
|
|
|
2147
2196
|
return;
|
|
2148
2197
|
}
|
|
2149
2198
|
this.isProcessing = true;
|
|
2199
|
+
this.uiUpdates.setMode('processing');
|
|
2150
2200
|
this.terminalInput.setStreaming(true);
|
|
2151
2201
|
const overallStartTime = Date.now();
|
|
2152
2202
|
// Initialize the task completion detector
|
|
@@ -2327,16 +2377,18 @@ What's the next action?`;
|
|
|
2327
2377
|
display.showSystemMessage(`\n🏁 Continuous execution completed: ${iteration} iterations, ${minutes}m ${seconds}s total`);
|
|
2328
2378
|
// Reset completion detector for next task
|
|
2329
2379
|
resetTaskCompletionDetector();
|
|
2380
|
+
this.uiUpdates.setMode('processing');
|
|
2381
|
+
this.stopStreamingHeartbeat();
|
|
2330
2382
|
this.isProcessing = false;
|
|
2331
2383
|
this.terminalInput.setStreaming(false);
|
|
2332
|
-
this.updateStatusMessage(null);
|
|
2333
2384
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2334
2385
|
this.setIdleStatus();
|
|
2335
|
-
this.
|
|
2386
|
+
this.updateStatusMessage(null);
|
|
2336
2387
|
display.newLine();
|
|
2337
2388
|
// Claude Code style: Show unified status bar before prompt
|
|
2338
2389
|
// This creates consistent UI between startup and post-streaming
|
|
2339
2390
|
this.showUnifiedStatusBar();
|
|
2391
|
+
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2340
2392
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2341
2393
|
// Claude Code style: New prompt naturally appears at bottom
|
|
2342
2394
|
this.ensureReadlineReady();
|
|
@@ -2582,6 +2634,121 @@ What's the next action?`;
|
|
|
2582
2634
|
this.autoTestInFlight = false;
|
|
2583
2635
|
}
|
|
2584
2636
|
}
|
|
2637
|
+
isBuildToolCall(entry) {
|
|
2638
|
+
const name = entry.toolName.toLowerCase();
|
|
2639
|
+
if (name === 'run_build' || name === 'build') {
|
|
2640
|
+
return true;
|
|
2641
|
+
}
|
|
2642
|
+
if (name === 'bash' || name === 'execute_bash') {
|
|
2643
|
+
const command = String(entry.args['command'] ?? '').toLowerCase();
|
|
2644
|
+
return (command.includes('npm run build') ||
|
|
2645
|
+
command.includes('yarn build') ||
|
|
2646
|
+
command.includes('pnpm build') ||
|
|
2647
|
+
command.includes('tsc'));
|
|
2648
|
+
}
|
|
2649
|
+
return false;
|
|
2650
|
+
}
|
|
2651
|
+
getLatestBuildTimestamp() {
|
|
2652
|
+
const history = this.runtimeSession.toolRuntime.getToolHistory?.() ?? [];
|
|
2653
|
+
let latest = this.lastAutoBuildRun;
|
|
2654
|
+
for (const entry of history) {
|
|
2655
|
+
if (this.isBuildToolCall(entry)) {
|
|
2656
|
+
latest = latest ? Math.max(latest, entry.timestamp) : entry.timestamp;
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
return latest;
|
|
2660
|
+
}
|
|
2661
|
+
/**
|
|
2662
|
+
* Auto-build verification after file edits.
|
|
2663
|
+
* Runs `npm run build` to catch TypeScript errors and feeds failures back to the agent.
|
|
2664
|
+
*/
|
|
2665
|
+
async enforceAutoBuild(trigger) {
|
|
2666
|
+
if (this.autoBuildInFlight) {
|
|
2667
|
+
return;
|
|
2668
|
+
}
|
|
2669
|
+
if (!this.verificationEnabled) {
|
|
2670
|
+
return;
|
|
2671
|
+
}
|
|
2672
|
+
const latestChange = this.getLatestFileChangeTimestamp();
|
|
2673
|
+
if (!latestChange) {
|
|
2674
|
+
return;
|
|
2675
|
+
}
|
|
2676
|
+
const latestBuild = this.getLatestBuildTimestamp();
|
|
2677
|
+
if (latestBuild && latestChange <= latestBuild) {
|
|
2678
|
+
return;
|
|
2679
|
+
}
|
|
2680
|
+
this.autoBuildInFlight = true;
|
|
2681
|
+
const command = 'npm run build';
|
|
2682
|
+
display.showSystemMessage(`🔨 Auto-building to verify changes (${trigger})...`);
|
|
2683
|
+
this.updateStatusMessage('Running build automatically...');
|
|
2684
|
+
try {
|
|
2685
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
2686
|
+
cwd: this.workingDir,
|
|
2687
|
+
timeout: 5 * 60 * 1000,
|
|
2688
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
2689
|
+
});
|
|
2690
|
+
this.lastAutoBuildRun = Date.now();
|
|
2691
|
+
const outputText = [stdout, stderr].filter(Boolean).join('\n').trim();
|
|
2692
|
+
display.showSystemMessage('✅ Build succeeded.');
|
|
2693
|
+
if (outputText && outputText.length < 500) {
|
|
2694
|
+
process.stdout.write(`${outputText}\n`);
|
|
2695
|
+
}
|
|
2696
|
+
this.statusTracker.clearOverride('build');
|
|
2697
|
+
}
|
|
2698
|
+
catch (error) {
|
|
2699
|
+
this.lastAutoBuildRun = Date.now();
|
|
2700
|
+
const errorOutput = this.formatCommandError(error);
|
|
2701
|
+
display.showWarning('⚠️ Build failed. Feeding errors back to agent...');
|
|
2702
|
+
if (errorOutput) {
|
|
2703
|
+
process.stdout.write(`${errorOutput}\n`);
|
|
2704
|
+
}
|
|
2705
|
+
this.statusTracker.pushOverride('build', 'Build failing', {
|
|
2706
|
+
detail: 'Auto-run npm run build failed',
|
|
2707
|
+
tone: 'danger',
|
|
2708
|
+
});
|
|
2709
|
+
// Feed build errors back to the agent so it can fix them
|
|
2710
|
+
await this.feedBuildErrorsToAgent(errorOutput);
|
|
2711
|
+
}
|
|
2712
|
+
finally {
|
|
2713
|
+
this.updateStatusMessage(null);
|
|
2714
|
+
this.autoBuildInFlight = false;
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
/**
|
|
2718
|
+
* Feed build errors back to the agent conversation for automatic fixing.
|
|
2719
|
+
*/
|
|
2720
|
+
async feedBuildErrorsToAgent(errorOutput) {
|
|
2721
|
+
if (!this.agent || !errorOutput) {
|
|
2722
|
+
return;
|
|
2723
|
+
}
|
|
2724
|
+
// Extract the most relevant error information
|
|
2725
|
+
const errorLines = errorOutput.split('\n');
|
|
2726
|
+
const relevantErrors = errorLines
|
|
2727
|
+
.filter((line) => line.includes('error TS') ||
|
|
2728
|
+
line.includes('Error:') ||
|
|
2729
|
+
line.includes('error:') ||
|
|
2730
|
+
/\(\d+,\d+\)/.test(line) // TypeScript error format: file(line,col)
|
|
2731
|
+
)
|
|
2732
|
+
.slice(0, 20); // Limit to first 20 errors
|
|
2733
|
+
const errorSummary = relevantErrors.length > 0 ? relevantErrors.join('\n') : errorOutput.slice(0, 2000);
|
|
2734
|
+
const prompt = `Build failed with the following errors. Please fix them:\n\n\`\`\`\n${errorSummary}\n\`\`\``;
|
|
2735
|
+
display.showSystemMessage('🔧 Asking agent to fix build errors...');
|
|
2736
|
+
this.updateStatusMessage('Agent fixing build errors...');
|
|
2737
|
+
try {
|
|
2738
|
+
// Send the error to the agent for fixing
|
|
2739
|
+
display.showThinking('Analyzing build errors');
|
|
2740
|
+
const response = await this.agent.send(prompt, true);
|
|
2741
|
+
display.stopThinking();
|
|
2742
|
+
if (response) {
|
|
2743
|
+
display.showAssistantMessage(response, { isFinal: true });
|
|
2744
|
+
}
|
|
2745
|
+
// Recursively verify the fix worked
|
|
2746
|
+
await this.enforceAutoBuild('verification');
|
|
2747
|
+
}
|
|
2748
|
+
catch (agentError) {
|
|
2749
|
+
display.showWarning('Agent could not automatically fix build errors. Please review manually.');
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2585
2752
|
rebuildAgent() {
|
|
2586
2753
|
const previousHistory = this.agent ? this.agent.getHistory() : this.cachedHistory;
|
|
2587
2754
|
try {
|
|
@@ -2639,6 +2806,8 @@ What's the next action?`;
|
|
|
2639
2806
|
}
|
|
2640
2807
|
}
|
|
2641
2808
|
display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
|
|
2809
|
+
// Auto-verify changes: build first (catches type errors), then tests
|
|
2810
|
+
void this.enforceAutoBuild('final-response');
|
|
2642
2811
|
void this.enforceAutoTests('final-response');
|
|
2643
2812
|
}
|
|
2644
2813
|
else {
|
|
@@ -2702,12 +2871,14 @@ What's the next action?`;
|
|
|
2702
2871
|
onCancelled: () => {
|
|
2703
2872
|
// Update UI to show operation was cancelled
|
|
2704
2873
|
display.showWarning('Operation cancelled.');
|
|
2705
|
-
this.
|
|
2874
|
+
this.uiUpdates.setMode('processing');
|
|
2706
2875
|
this.stopStreamingHeartbeat();
|
|
2876
|
+
this.updateStatusMessage(null);
|
|
2707
2877
|
this.terminalInput.setStreaming(false);
|
|
2708
2878
|
this.terminalInput.render();
|
|
2709
2879
|
},
|
|
2710
2880
|
onVerificationNeeded: () => {
|
|
2881
|
+
void this.enforceAutoBuild('verification');
|
|
2711
2882
|
void this.enforceAutoTests('verification');
|
|
2712
2883
|
},
|
|
2713
2884
|
});
|