mirror of
https://github.com/stablyai/orca.git
synced 2026-10-08 00:02:38 +00:00
* fix(terminal): leave the alt screen before replaying a pushed host snapshot A remote terminal running a full-screen agent (Claude Code) could show old output (e.g. a setup script's pnpm log) interleaved with the agent's screen after switching back to the tab. The host's pushed snapshot is a serialized image that starts on the normal buffer and enters the alternate screen itself, but the replay drain cleared with ESC[2J without leaving alt. The image's history painted into the agent's screen, its own ?1049h was a no-op, and the agent's diff paints landed on top of the stale cells. The remote-runtime transport now marks snapshots as serialized images, and the drain grounds them with the shared snapshot prologue (switching to the normal buffer first). Raw byte replays (SSH relay ring buffers) keep the in-place clear. * fix(terminal): paint folded remote snapshots from the normal buffer everywhere Review follow-ups: - Rename the flag to carriesNormalBuffer: what the painters rely on is that the image starts on the normal buffer and enters alt itself. - Hidden-output restore had the same bug for remote requested snapshots (history folded into data, alternateScreen set): the painter entered alt first and painted the normal buffer into the TUI's screen. Requested remote snapshots now carry the flag and take the normal-buffer start. - Flag pushed snapshots replayed after a cancelled shutdown too. - Pushed snapshots carry only the screen, so over a live TUI the drain keeps the normal-buffer history it covers instead of wiping it. - Read the pane's buffer after queued output parses. - Tests compare whole buffers against a fresh terminal, use production image shapes, and pin the raw-replay path with the same oracle. * fix(terminal): let the replay drain own the recovery snapshot clear The recovery prefix's own \x1b[3J ran after the drain's prologue and wiped the history the drain keeps under a live TUI. Keep only the latch release, which still makes an empty recovery snapshot non-empty so it is applied. * fix(terminal): keep the recovery snapshot's own screen clear Consumers that write recovery snapshots straight into xterm (no replay drain) rely on the prefix clearing the stale screen. Restore \x1b[2J\x1b[H and drop only \x1b[3J, which wiped history the image does not carry. * test(terminal): drive the drain with the real recovery payload The multiplexer prepends its own screen clear; replaying that exact payload pins that the prefix cannot wipe the history a TUI covers. * fix(terminal): keep TUI-covered history only when the grids match Second review follow-ups: - A pushed image carries only the host's screen; the pane's frozen history continues it exactly only on the same grid. On another grid keeping it duplicated or dropped lines, so the image replaces it there. - Tests replay the pane's writes and grid changes into a real terminal and compare whole buffers with the host, including a mismatched-grid case. - The split branch shares the normal-buffer preamble; drop the now single-use abort helper. - Type serializeBuffer as RemoteRuntimeSnapshotImage so the flag is carried by type, not by object pass-through. - Register the grid and raw-replay cases in the reliability gate. * fix(terminal): keep TUI-covered history only while the host is still on alt The drain kept the pane's history whenever the pane was on the alt screen. If the host's TUI exited while the tab was hidden, the shell wrote past that history and the kept lines no longer continued the host's screen. Require the host's own alternateScreen too; an absent flag proves nothing, so the image replaces history as on main. Also: one buildSnapshotReplayPreamble for every first replay write, the drain's image and raw clears as separate branches (raw byte-identical to main, comment restored), and a single paneAtSourceGrid check. * fix(terminal): gate kept history on the host's shell-owner proof The host sends alternateScreen only with terminalOwner 'shell', i.e. once it has proven the TUI exited, so `alternateScreen === true` never held for a live TUI and the drain wiped the history it should keep. Replace the history only once the host proves the TUI exited; tests now use production snapshot shapes. Move the relay-overlap comment into the raw-replay branch it describes. * fix(terminal): keep TUI-covered history only on a proven shared grid An image without its grid cannot prove the pane's history continues its screen, so it now replaces history. Also update a stale recovery-prefix test comment. * test(terminal): replay host-serialized snapshots through the real wire and drain Hand-written replay meta hid a gate that production never satisfies. Drive the host's own emulator, ownership mirror, serializer and recovery publisher through the real wire, client parser, remote transport and pane drain, for a live TUI and after the host proves it exited. * fix(terminal): repaint only the alt frame over a live TUI, leaving history alone Keeping the pane's history by clearing only the normal screen assumed a pushed image carries no history, which the host does not guarantee: a 0-row push can reuse a concurrent requested capture, and its history then landed twice in scrollback. It also wiped history on a grid mismatch, where main kept it. When pane and image are both on alt, the image's normal part adds nothing (the normal buffers froze together), so paint only its alt payload after an alt-side clear, split at the host's own boundary (splitAtAlternateScreenEntry, now shared with the daemon). Any other image paints from the normal buffer. This drops keepScrollback, the owner and grid gates, and the recovery-prefix change, so history behaves exactly as on main. * test(terminal): pin the parse wait and the cancelled-shutdown flag Final-review follow-ups: a drain test where the TUI's ?1049h is still queued when the image arrives, and a transport test replaying a push buffered during a cancelled shutdown; each fails when its guard is removed. The requested-image test now names the exited-TUI case it covers, requestSnapshot shares the snapshot image type, and the clear comment no longer implies every clear drops scrollback.