Skip to content

Fix Windows backspace and initial prompt - #53

Closed
l1a wants to merge 2 commits into
mainfrom
fix/windows-backspace-and-initial-prompt
Closed

Fix Windows backspace and initial prompt#53
l1a wants to merge 2 commits into
mainfrom
fix/windows-backspace-and-initial-prompt

Conversation

@l1a

@l1a l1a commented Jul 10, 2026

Copy link
Copy Markdown
Owner

What & why

Two fixes for connecting from a Windows etr client to a Unix etrs host. Both were invisible over plain ssh from the same Windows machine, which is why they looked like etr-specific regressions.

  • Backspace behaved like a delete / didn't erase. The Windows console delivers legacy key codes to raw byte reads (Backspace as 0x08), whereas a Unix PTY expects the xterm convention 0x7f (DEL) to match the default stty erase. etr forwarded the raw 0x08 verbatim, so the remote never saw the erase char it expected. The client now switches the console into virtual-terminal mode after enabling raw mode — ENABLE_VIRTUAL_TERMINAL_INPUT on stdin (keys become the same VT byte sequences a real terminal emits: Backspace → DEL, arrows → escape sequences) and ENABLE_VIRTUAL_TERMINAL_PROCESSING on stdout (renders the remote's ANSI). No-op on Unix. New Windows-only dependency: windows-sys (Console).

  • Blank screen until the first Enter. etrs spawned the shell and started reading its PTY at session start, before any client connected. The shell's initial prompt could be produced in the window between the server snapshotting replay data and installing the live PTY channel — so on the first connection it was recorded to history but neither replayed nor sent, and pressing Enter forced a fresh prompt. The PTY reader task is now started lazily on the first connection, after the client's PTY channel is live (mirrors how SSH emits shell output only once the channel exists). Replay-on-reconnect is unchanged — the reader persists across reconnects and picks up each new outbound channel.

Also bumped two transitive deps to clear RustSec advisories published while this branch was in flight (neither introduced here): crossbeam-epoch 0.9.18→0.9.20 (RUSTSEC-2026-0204, dev-only via criterion, not in the shipped binaries) and anyhow 1.0.102→1.0.103 (RUSTSEC-2026-0190 unsoundness).

Version bumped 0.6.2 → 0.6.3; NOTES.md, man pages, and the wiki Troubleshooting page updated.

Test plan

  • cargo fmt --check, cargo clippy --all-targets -D warnings, cargo test (110) — green on Windows (x86_64-pc-windows-msvc) and Linux (WSL Fedora; the #[cfg(unix)] etrs path compiles, lints, and tests clean).
  • CI matrix green on ubuntu x86/arm, macOS, Windows, plus Security Audit.
  • Manual verification for a reviewer (needs a Windows client + a Unix host, which CI cannot exercise):
    1. Build etr on Windows; deploy etrs 0.6.3 to a Linux host.
    2. etr user@host from a native Windows console (PowerShell/Windows Terminal).
    3. Confirm the shell prompt appears immediately, without pressing Enter.
    4. Type some text and press Backspace — it should erase left, and stty -a should show erase = ^?.
    5. Drop the network and confirm reconnect still replays session output.

🤖 Generated with Claude Code

l1a added 2 commits July 9, 2026 21:13
Two fixes for connecting to a Unix etrs from a Windows etr client, both
invisible over plain ssh from the same machine:

- Backspace behaved like a stray/delete key. The Windows console hands raw
  byte reads legacy key codes (Backspace as 0x08), whereas a Unix PTY expects
  the xterm conventions (Backspace as 0x7f/DEL, matching stty erase). The
  client now switches the console into virtual-terminal mode after enabling
  raw mode (ENABLE_VIRTUAL_TERMINAL_INPUT on stdin, plus
  ENABLE_VIRTUAL_TERMINAL_PROCESSING on stdout for ANSI rendering), so it emits
  the same key bytes a real terminal does. No-op on Unix. New Windows-only
  dependency: windows-sys (Console).

- Blank screen until the first Enter. etrs started reading the shell's PTY at
  session start, before any client connected, so the initial prompt could be
  produced in the window between snapshotting replay data and installing the
  live PTY channel: it was recorded to history but neither replayed nor sent on
  the first connection. The PTY reader task is now started lazily on the first
  connection, after the client's PTY channel is live (mirrors how ssh emits
  shell output only once the channel exists). Replay-on-reconnect is unchanged.

Validated: clippy -D warnings + cargo test green on both Windows
(x86_64-pc-windows-msvc) and Linux (WSL Fedora); man pages rebuilt at 0.6.3.

Assisted-By: Claude Opus 4.8 (1M context)
Bump crossbeam-epoch 0.9.18->0.9.20 (RUSTSEC-2026-0204, dev-only via criterion)
and anyhow 1.0.102->1.0.103 (RUSTSEC-2026-0190 unsoundness) so the CI security
audit passes. Both advisories were published against pre-existing transitive
deps while this branch was in flight; neither was introduced by this work.

Assisted-By: Claude Opus 4.8 (1M context)
@l1a

l1a commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #55, which keeps only the confirmed-working Windows Backspace fix plus the dependency-advisory bumps. The server-side deferred-PTY-reader change and the crossterm-events input rewrite from this branch were experiments targeting the 'first line not echoed until Enter' bug; that bug is still unresolved and is now tracked in #54. Closing in favor of #55.

@l1a l1a closed this Jul 10, 2026
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