mirror of
https://github.com/stablyai/orca.git
synced 2026-09-21 16:02:20 +00:00
fix(ssh): stop the reconnect prepaint firing after its mount is spent
Regression I introduced with the snapshot-first reconnect paint. The payload path consumes mountFollowsTerminalPark — it clears the flag after the first reattach so a later in-place reconnect on the SAME mount cannot repaint. I replaced the prepaint's read of that mutable flag with a const snapshot of it, so my combined flag stayed true for the life of the mount. A snapshot could then be written on a later reattach, into a terminal that already had live content, and its own isCurrent() guard could no longer go false either. The visible symptom was a tab that came up blank with no prompt and stayed generically titled Terminal N — the title only stays generic when the shell never printed a prompt for Orca to read one from. Every such tab in my session had been through a remount; four tabs created cleanly with Cmd+T were all fine. So the flag is mutable again and is consumed alongside the one it was derived from. Both reasons a mount paints into an empty terminal — a park and a reconnect — are spent by the first reattach, which is what the original code meant. Worth stating plainly: my earlier claim that the snapshot change was non-regressing was tested only against reconnect scenarios. I never exercised creating a tab afterwards, which is exactly where this showed up.
This commit is contained in:
@@ -7973,7 +7973,11 @@ export function connectPanePty(
|
||||
// it is only set when a pending or live SSH pane retry matches this connection AND this tab
|
||||
// generation.
|
||||
const isSshReconnectRemount = Boolean(directSshRetryAttempt)
|
||||
const paintsIntoEmptyTerminal = mountFollowsTerminalPark || isSshReconnectRemount
|
||||
// MUTABLE, and consumed with mountFollowsTerminalPark below. A const here is a bug: the payload
|
||||
// path clears mountFollowsTerminalPark after the first reattach so a later in-place reconnect on
|
||||
// the SAME mount cannot repaint, and a snapshot written then lands on a terminal that already
|
||||
// has live content. Reading a frozen copy reintroduced exactly that.
|
||||
let paintsIntoEmptyTerminal = mountFollowsTerminalPark || isSshReconnectRemount
|
||||
|
||||
let parkedSshSnapshotPrefetch: {
|
||||
ptyId: string
|
||||
@@ -8230,6 +8234,9 @@ export function connectPanePty(
|
||||
mountFollowsTerminalPark &&
|
||||
(connectResult?.isReattach === true || isRemoteRuntimePtyId(ptyId))
|
||||
mountFollowsTerminalPark = false
|
||||
// Consumed together: the prepaint's own guard reads this, and both reasons a mount paints into
|
||||
// an empty terminal are spent by the first reattach.
|
||||
paintsIntoEmptyTerminal = false
|
||||
// Why: ordinary parking destroys xterm. Rebuild from the authoritative
|
||||
// host snapshot before releasing queued live bytes; null falls back to
|
||||
// the subscribe screen without keeping the old xterm mounted.
|
||||
|
||||
Reference in New Issue
Block a user