Skip to content

[Bugfix #205] Fix terminal garbled output when revisiting tabs#207

Merged
waleedkadous merged 3 commits intomainfrom
builder/bugfix-205-terminal-renders-garbled-outpu
Feb 9, 2026
Merged

[Bugfix #205] Fix terminal garbled output when revisiting tabs#207
waleedkadous merged 3 commits intomainfrom
builder/bugfix-205-terminal-renders-garbled-outpu

Conversation

@waleedkadous
Copy link
Copy Markdown
Contributor

Summary

Fixes #205

Root Cause

When switching tabs in the dashboard, React unmounted and remounted Terminal components. Each remount:

  1. Created a fresh xterm.js instance
  2. Opened a new WebSocket connection
  3. Replayed the full ring buffer (up to 1000 lines of historical output) onto an empty terminal with no context for cursor positions, ANSI state, or line wrapping

This produced garbled output — scattered characters, repeated partial words (e.g., "thinking" dozens of times), and rendering artifacts.

Fix

Keep Terminal components mounted when switching tabs by:

  • Tracking which terminal tabs have been visited at least once (activatedTerminals state)
  • Rendering all activated terminals persistently, using CSS display: none for inactive tabs
  • Only mounting a terminal on its first visit (avoiding pre-mounting unvisited tabs)

When switching back to a terminal tab, the existing xterm.js instance is simply made visible — no reconnection, no buffer replay.

Files changed:

  • packages/codev/dashboard/src/components/App.tsx — Replaced renderContent() with renderPersistentContent() that keeps terminals mounted
  • packages/codev/dashboard/src/index.css — Added .terminal-tab-pane wrapper class

Test Plan

  • Added regression test (App.terminal-persistence.test.tsx) verifying:
    • Terminal stays in DOM when switching to dashboard tab
    • Terminal wrapper gets display: none when hidden, cleared when active
    • Same DOM element is preserved across tab switches (no unmount/remount)
  • TypeScript compilation passes
  • All new tests pass (3/3)
  • Existing tests unaffected (pre-existing StatusPanel test failures are unrelated)

CMAP Review

To be added after 3-way review

Terminal components were unmounted/remounted on every tab switch, triggering
WebSocket reconnection and full ring-buffer replay on fresh xterm.js instances.
This produced garbled output with scattered characters and rendering artifacts.

Fix: Track activated terminal tabs and render them persistently with CSS
display:none for hidden tabs, avoiding reconnection and buffer replay entirely.
Verifies that Terminal components remain mounted (hidden via CSS) when
switching tabs, and the same DOM element is reused when switching back.
When a terminal tab has no wsPath, show "No terminal session" message
instead of rendering nothing. Preserves original behavior from renderTerminal.
@waleedkadous waleedkadous merged commit 3df825e into main Feb 9, 2026
0 of 2 checks passed
@waleedkadous waleedkadous deleted the builder/bugfix-205-terminal-renders-garbled-outpu branch February 9, 2026 20:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Terminal renders garbled output when revisiting existing tabs

1 participant