Skip to content

fix: scrollback retention and proxy-router resilience#280

Open
mattleaverton wants to merge 2 commits intodanshapiro:mainfrom
mattleaverton:fix/scrollback-and-proxy-bugs
Open

fix: scrollback retention and proxy-router resilience#280
mattleaverton wants to merge 2 commits intodanshapiro:mainfrom
mattleaverton:fix/scrollback-and-proxy-bugs

Conversation

@mattleaverton
Copy link
Copy Markdown
Collaborator

Summary

  • Raise default scrollback sizes — Long Claude Code and Codex conversations easily outgrow the old defaults, causing scrollback loss on reattach. Client scrollback: 5,000 → 10,000 lines. Server buffer: 64KB → 512KB (max 4MB). ReplayRing: 256KB → 1MB. Chars-per-line estimate: 200 → 300.
  • Proxy-router sends 502 on WebSocket ECONNREFUSED — When an extension server port becomes stale (e.g. after server restart), the WebSocket proxy was silently destroying the socket, causing the client to retry endlessly and thrash the UI. Now sends a proper HTTP 502 response before closing so the client can handle the error cleanly.

Context

Reported by a user: "Every time I close a pane I lose all the scrollback on my other panes, at least with Codex." Investigation revealed the scrollback loss was caused by the server-side ReplayRing (256KB) being too small to retain coding CLI conversation history. On reattach after pane/tab close, only the tail of the conversation was replayed.

The proxy-router issue was discovered during investigation — opening a Claude/Freshclaude tab after a server restart caused wild blinking and failure to load due to the proxy repeatedly failing to connect to a dead extension server port with no error feedback to the client.

Test plan

  • All existing tests pass (3 pre-existing WSL/Windows-only failures unrelated)
  • Verified in Chrome: Codex session with substantial output → close tab → reopen from sidebar → scrollback preserved on reattach
  • Proxy-router unit tests pass including existing 502-for-unreachable-port test

🤖 Generated with Claude Code

mattleaverton and others added 2 commits April 2, 2026 14:00
Default client scrollback: 5000 → 10000 lines
Default server buffer: 64KB → 512KB (max 4MB)
Default ReplayRing: 256KB → 1MB
Chars-per-line estimate: 200 → 300

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously the WebSocket proxy silently destroyed the socket when the
target port was unreachable, causing the client to retry endlessly
and thrash the UI. Now sends a proper HTTP 502 response before
closing so the client can handle the error cleanly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 53ea01d381

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +209 to +211
if (socket.writable) {
socket.write('HTTP/1.1 502 Bad Gateway\r\nContent-Type: text/plain\r\n\r\nExtension server on port ' + targetPort + ' is unavailable\r\n')
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict 502 writes to pre-upgrade failures only

The new proxySocket error handler always writes an HTTP 502 response whenever the client socket is writable, but this handler also runs for errors that can happen after the WebSocket handshake/piping is already established (for example if the extension process restarts mid-session). In that state, sending an HTTP status line into an active WebSocket stream corrupts the protocol and can produce noisy disconnect/retry behavior; the safe behavior is to send 502 only before upgrade bytes have been relayed, and otherwise just close/destroy the socket.

Useful? React with 👍 / 👎.

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.

1 participant