fix: surface engine logs in dashboard TUI via console capture

The dashboard TUI Logs tab only showed the handful of lines emitted
through DashboardLogSink directly. Everything from @fusion/engine
(scheduler, executor, triage, merger, PR monitor, heartbeat, etc.)
logs via createLogger() which writes straight to console.error —
bypassing the sink. Under the TUI's alt screen those writes either
overdrew the frame or scrolled off, leaving the Logs tab near-empty.

DashboardLogSink now offers captureConsole() / releaseConsole():
while the TUI is running, console.log/warn/error are intercepted
and routed into the ring buffer. A leading `[prefix]` tag is
extracted so entries carry the subsystem name. Original console
functions are restored (by identity) on TUI shutdown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-04-23 12:05:48 -07:00
parent 316e94d653
commit b6d69ea85e
4 changed files with 255 additions and 3 deletions

View File

@@ -388,6 +388,10 @@ export async function runDashboard(port: number, opts: { paused?: boolean; dev?:
// Wire the TUI into the log sink so all console output routes through TUI
logSink.setTUI(tui);
// Capture stdlib console.* so engine/scheduler/pi/etc. log lines (which
// go straight to console.error via createLogger in @fusion/engine) land
// in the TUI's ring buffer instead of being overwritten by the alt screen.
logSink.captureConsole();
}
store = new TaskStore(cwd);
@@ -794,6 +798,10 @@ export async function runDashboard(port: number, opts: { paused?: boolean; dev?:
// Stop TUI if active
if (tui) {
// Restore console.* before stopping the TUI so any log lines emitted
// during teardown (or by late-firing listeners) go to the real terminal
// instead of a ring buffer that's about to disappear.
logSink.releaseConsole();
void tui.stop();
}