Skip to content

fix(ssh): restore exitAlternateScreenBuffer to prevent character loss on session open#138

Open
rlagentflowbeta[bot] wants to merge 1 commit intomainfrom
agent/fix-ssh-character-loss
Open

fix(ssh): restore exitAlternateScreenBuffer to prevent character loss on session open#138
rlagentflowbeta[bot] wants to merge 1 commit intomainfrom
agent/fix-ssh-character-loss

Conversation

@rlagentflowbeta
Copy link
Copy Markdown
Contributor

Summary

  • Restores `exitAlternateScreenBuffer()` to `releaseTerminal()` in `InteractiveSpawn` so SSH runs in the normal screen buffer, isolated from Ink's rendering activity
  • Removes the `setRawMode(false)` call that was invoking `tcsetattr(TCSAFLUSH)` and switching the terminal to canonical mode during SSH connection setup

Root Cause

Two related issues were introduced when `exitAlternateScreenBuffer()` was removed from the spawn flow (in a previous refactor aimed at eliminating the brief visual flash on SSH exit):

  1. SSH ran inside Ink's alternate screen buffer. Any Ink re-renders during the SSH connection setup wrote ANSI escape sequences to the same buffer SSH was using, corrupting terminal state and causing initial keystrokes to be swallowed.

  2. `setRawMode(false)` was called before spawning SSH. Node.js's `setRawMode` uses `tcsetattr(TCSAFLUSH)` internally. `TCSAFLUSH` discards all pending kernel input and switches the terminal to canonical (line-buffered) mode. Characters typed during the SSH connection handshake were therefore either discarded or held until Enter was pressed — never reaching the remote shell.

Fix

  • Call `exitAlternateScreenBuffer()` first in `releaseTerminal()` so SSH runs in the normal screen buffer. Ink's renders (targeting the alt buffer) no longer interfere with SSH's terminal I/O.
  • Remove `setRawMode(false)`: the terminal stays in raw mode throughout the transition, so keystrokes are immediately available in the kernel buffer. SSH sets its own terminal mode via `tcsetattr(TCSADRAIN)` which preserves buffered input.

Test plan

  • Open an SSH session to a devbox via the TUI
  • Immediately start typing a command as soon as the shell prompt appears — characters should no longer be dropped
  • Verify SSH session functions normally (Ctrl+C, Ctrl+D, exit all work)
  • Verify the TUI renders correctly after the SSH session ends

🤖 Generated with Claude Code

… on session open

Characters were being lost at the start of an SSH session due to two issues
introduced in a previous refactor:

1. exitAlternateScreenBuffer() was removed from releaseTerminal(), causing SSH
   to run inside Ink's alternate screen buffer. Any Ink re-renders during the
   connection setup wrote ANSI sequences to the same buffer, corrupting terminal
   state and swallowing early keystrokes.

2. setRawMode(false) was called before spawning SSH, which invokes
   tcsetattr(TCSAFLUSH) under the hood. TCSAFLUSH discards pending kernel input
   and switches the terminal to canonical (line-buffered) mode. Characters typed
   during the SSH connection handshake were therefore either discarded or held
   until Enter was pressed, never reaching SSH.

Fix: call exitAlternateScreenBuffer() first in releaseTerminal() so SSH runs
in the normal screen buffer (isolated from Ink's rendering), and remove the
setRawMode(false) call so the terminal stays in raw mode throughout the
transition.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

0 participants