Files
Jinwoo-HandOrca bd0f36433b fix(terminal): place cursor correctly after restart for persistent TUIs
SerializeAddon emits a relative cursor-move tail (\x1b[NA\x1b[MD)
computed from the last content cell it serialized to the terminal's real
cursor. That math drifts when a TUI drew rows below the cursor (border,
status lines) and then parked the cursor back on an input prompt above
— on replay the cursor lands one row below the prompt.

Append an authoritative absolute CSI row;col H after SerializeAddon
output at both capture sites (renderer captureBuffers and daemon
HeadlessEmulator.getSnapshot) using the terminal's live
buffer.active.cursorY/cursorX. The absolute positioner is the last
cursor-move seen on replay, overriding SerializeAddon's drifty relative
tail.

Also remove two cooperating bugs in restoreScrollbackBuffers and
document the contract:

  1. Alt-screen trim (slice(0, lastIndexOf('\x1b[?1049h'))) discarded
     not only alt-buffer content but the cursor-position tail, mode
     bits, and scroll region — fueling the "cursor lands below input
     box" bug for Claude Code, vim, lazygit.
  2. Unconditional trailing \r\n append for PROMPT_EOL_MARK pushed the
     cursor one extra row down on top of the alt-trim drift.

The reattach path in pty-connection.ts is authoritative when it has
data; restoreScrollbackBuffers is the pre-paint and must replay the
serialized buffer verbatim + POST_REPLAY_MODE_RESET only.

Co-authored-by: Orca <help@stably.ai>
2026-05-01 17:38:40 -04:00
..