fix(desktop): guard terminal resume against in-flight connect
Follow-up to #5135, addressing the race flagged by Greptile (P1) and cubic (P2) in review.
Problem
handleResume only bailed when transport.socket was OPEN/CONNECTING. But for remote /hosts/ URLs, connect() runs primeRelayAffinity asynchronously before opening the socket, so there's a window where transport.socket is null while connectionState is "connecting".
Wake-time sequence that orphans a socket:
- watchdog fires →
reconnectNow→connect()starts the async pre-flight →transport.socketisnull, state"connecting" - an
online/focus/visibilitychangeevent fires →handleResumesees thenullsocket, skips the early-return, callsreconnectNowagain - both pre-flights resolve and each calls
openSocket()(both pass thecurrentUrl/connectionStateguards), opening two WebSockets — the first is overwritten intransport.socketwithout being closed, leaving it orphaned on client and server.
Fix
Bail out of handleResume when connectionState === "connecting" too, covering the pre-flight window. reconnectNow is deliberately left unguarded so the watchdog can still force-recycle a genuinely half-open socket (which reports "open") or a hung connect.
Testing
bun test (3 pass), bun run lint (clean), bun run typecheck (pass).
Summary by cubic
Prevent double WebSocket openings during terminal resume by bailing out when a connect is already in flight. This avoids orphaned sockets on remote /hosts/ connections.
- Bug Fixes
- In
handleResume, return early whenconnectionState === "connecting"or the socket isOPEN, covering the pre-flight window beforetransport.socketis set.
- In
Summary by CodeRabbit
- Bug Fixes
- Improved terminal connection handling to prevent duplicate reconnections by better checking the connection state before attempting to reconnect.