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.
@@ -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 streamingHeartbeat;
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":"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"}
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;AAwBzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AAIjF,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,cAAc,CAAC;IAC7B,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,aAAa,EAAE,iBAAiB,CAAC;IACjC,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,gBAAgB,EAAE,uBAAuB,CAAC;IAC1C,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,YAAY,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,oBAAoB;IAC5B,cAAc,EAAE,WAAW,CAAC;IAC5B,gBAAgB,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,qBAAqB,EAAE,CAAC;CAClC;AAkGD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAe;IAC9C,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,kBAAkB,CAAmC;IAC7D,OAAO,CAAC,kBAAkB,CAAmD;IAC7E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuB;IACrD,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAuC;IACzE,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA2B;IACzD,OAAO,CAAC,kBAAkB,CAAwD;IAClF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2B;IAC9D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAiB;IAClD,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0B;IACxD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,yBAAyB,CAAuB;IACxD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IACxD,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,mBAAmB,CAAU;IACrC,OAAO,CAAC,mBAAmB,CAAQ;IACnC,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,sBAAsB,CAAuB;IACrD,OAAO,CAAC,kBAAkB,CAAsC;IAChE,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IACvD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmC;IACpE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAuB;IAC5D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAW;IAE3C,OAAO,CAAC,oBAAoB,CAKpB;IAER,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,eAAe,CAAuB;IAE9C,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,gBAAgB,CAAuB;IAE/C,OAAO,CAAC,uBAAuB,CAAuB;IACtD,OAAO,CAAC,uBAAuB,CAAK;IACpC,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,kBAAkB,CAA+B;gBAE7C,MAAM,EAAE,WAAW;IAyG/B,OAAO,CAAC,wBAAwB;IAsChC,OAAO,CAAC,uBAAuB;IAQzB,KAAK,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlD;;OAEG;IACH,OAAO,CAAC,YAAY;IAapB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,mBAAmB;IAwB3B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAkC7B,OAAO,CAAC,oBAAoB;IAe5B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAqChB;;OAEG;IACH,OAAO,CAAC,mBAAmB;YAkBb,uBAAuB;YAyDvB,oBAAoB;YAoBpB,yBAAyB;YA8CzB,qBAAqB;IA6BnC,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,+BAA+B;IAmBvC,OAAO,CAAC,6BAA6B;IAUrC,OAAO,CAAC,uBAAuB;IAgB/B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,oBAAoB;IAc5B,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,uBAAuB;IA+B/B,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,qBAAqB;IA2B7B,OAAO,CAAC,uBAAuB;IAW/B;;OAEG;YACW,oBAAoB;YA2BpB,iBAAiB;IAiD/B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;YAWlB,wBAAwB;YA6BxB,mBAAmB;YAoFnB,qBAAqB;IA+BnC,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,SAAS;YAwCH,oBAAoB;YAiBpB,8BAA8B;IAkC5C,OAAO,CAAC,0BAA0B;YAgDpB,oBAAoB;YAsCpB,mBAAmB;YA0EnB,eAAe;IAS7B,OAAO,CAAC,qBAAqB;IA6B7B,OAAO,CAAC,sBAAsB;IAK9B,OAAO,CAAC,qBAAqB;IA4C7B,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,0BAA0B;IA4BlC,OAAO,CAAC,gBAAgB;IAmCxB,OAAO,CAAC,eAAe;YAmCT,kBAAkB;YA8BlB,kBAAkB;IA8BhC,OAAO,CAAC,oBAAoB;IAkB5B,OAAO,CAAC,iBAAiB;IAmBzB,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,yBAAyB;IAqBjC,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,wBAAwB;IAqBhC,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,oBAAoB;IAqB5B,OAAO,CAAC,sBAAsB;IAO9B,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,wBAAwB;IAOhC,OAAO,CAAC,4BAA4B;IAIpC,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,qBAAqB;YAQf,aAAa;IA+B3B,OAAO,CAAC,oBAAoB;IAuB5B,OAAO,CAAC,iCAAiC;IA8EzC,OAAO,CAAC,kBAAkB;IAkE1B,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,cAAc;IAkBtB,OAAO,CAAC,qBAAqB;YA0Bf,4BAA4B;YAsC5B,oBAAoB;YA6CpB,gBAAgB;YAyBhB,qBAAqB;YAuCrB,iBAAiB;YA+CjB,cAAc;IAkF5B;;;;;;;;;;;OAWG;YACW,wBAAwB;IAuQtC;;;;OAIG;IACH,OAAO,CAAC,+BAA+B;IAiGvC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAwBhC;;OAEG;IACH,OAAO,CAAC,sBAAsB;YAahB,mBAAmB;IAwBjC,OAAO,CAAC,4BAA4B;IAYpC,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,kBAAkB;YAOZ,gBAAgB;IAqD9B,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,uBAAuB;IAa/B;;;OAGG;YACW,gBAAgB;IAwD9B;;OAEG;YACW,sBAAsB;IA0CpC,OAAO,CAAC,YAAY;IAiKpB;;;OAGG;IACH,OAAO,CAAC,0BAA0B;IAOlC,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,sBAAsB;IAoB9B,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,sBAAsB;IA8B9B,OAAO,CAAC,WAAW;YAaL,iBAAiB;IAyD/B,OAAO,CAAC,gBAAgB;YAkBV,mBAAmB;IA2BjC,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,mBAAmB;IAyB3B,OAAO,CAAC,qBAAqB;IAmB7B,OAAO,CAAC,uBAAuB;IAU/B,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,iBAAiB;IA+BzB,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,4BAA4B;IAUpC,OAAO,CAAC,wBAAwB;IAmBhC,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,qBAAqB;IAyB7B,OAAO,CAAC,qBAAqB;IAuB7B,OAAO,CAAC,wBAAwB;IAUhC;;OAEG;YACW,qBAAqB;IA6DnC;;OAEG;YACW,qBAAqB;IAyCnC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA0B/B;;OAEG;YACW,kBAAkB;IAyBhC;;OAEG;YACW,kBAAkB;IA6EhC;;OAEG;IACH,OAAO,CAAC,aAAa;IAsBrB;;;OAGG;IACH,iBAAiB,CAAC,SAAS,EAAE,KAAK,CAAC;QACjC,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,OAAO,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,GAAG,IAAI;IAIT;;;OAGG;IACH,OAAO,CAAC,oBAAoB;CAG7B"}
@@ -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(_message) {
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
- const tick = () => {
723
- const frame = frames[this.streamingHeartbeatFrame % frames.length];
724
- this.streamingHeartbeatFrame++;
725
- const elapsed = this.streamingHeartbeatStart
726
- ? Math.floor((Date.now() - this.streamingHeartbeatStart) / 1000)
727
- : 0;
728
- const suffix = elapsed > 0 ? ` • ${elapsed}s` : '';
729
- this.terminalInput.setStatusMessage(`${frame} ${label}${suffix}`);
730
- };
731
- tick();
732
- this.streamingHeartbeat = setInterval(tick, 500);
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
- if (this.streamingHeartbeat) {
736
- clearInterval(this.streamingHeartbeat);
737
- this.streamingHeartbeat = null;
738
- }
771
+ this.uiUpdates.stopHeartbeat('streaming');
739
772
  this.streamingHeartbeatStart = null;
740
- this.terminalInput.setStatusMessage(null);
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.stopStreamingHeartbeat();
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.updateStatusMessage(null);
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
  });