mirror of
https://github.com/stablyai/orca.git
synced 2026-09-27 16:02:35 +00:00
* fix(daemon): rebase durable checkpoints on the live terminal A durable checkpoint was folded from the previous checkpoint plus recorded output, so it inherited that checkpoint's modes forever. After a daemon restart killed a full-screen TUI and a new process started inline, the chain kept the dead TUI's alt screen and mouse tracking (?1049h ?1003h ?1006h) while the live emulator was clean. Every reattach and getBufferSnapshot served the stale chain, the renderer re-armed mouse tracking, and wheel scrolling went to a program that never asked for it: scrolling froze. Each full checkpoint is now the live snapshot verbatim (screen, layout, alt frame, modes, owner) with only the normal-buffer rows live has evicted taken from the durable replay. A checkpoint can no longer carry a dead process's modes, and checkpoints already poisoned on disk heal on the next compaction. - The first fold after a cold restore replays the same seed segments live was given, so rows line up even over a dead TUI's alt screen. - Idle zero-record folds keep the disk copy when it already agrees with live, so quit and relaunch bursts don't replay every session. - Held teardown bytes are already in the drained records and the live snapshot, so they are no longer replayed twice or appended as a tail. - The bounded getBufferSnapshot path honors the requested depth even when the live window is deeper, without phantom link rows. - The fold's ownership scanner and frame merge are removed; owner and frame come from live. * fix(terminal): one process-boundary ground for every known or proven boundary Three copies of the "the process that armed these modes is gone" reset had drifted: the cold-restore seed cleared only pen and mouse, the recovery barrier used the renderer's dead-TUI profile, and the cold-restore payload had none. A cold restore therefore left the dead process's focus reporting, bracketed paste, application cursor and keypad modes armed in the live emulator, the first checkpoint, and main's mirror. And the seed wrote the dead process's torn escape after the reset, so the new shell's first bytes could complete it (for example retitling the pane). PROCESS_BOUNDARY_GROUND replaces them: CAN, leave the alt screen without moving the normal-buffer cursor, every mouse protocol and encoding off, focus/paste/app-cursor/keypad off, cursor shown and style reset, kitty popped, SGR reset, grounded DECSC. It stays inert for the lifecycle scanner. The seed, the recovery barrier, and the cold-restore payload all use it, and the seed no longer carries the torn tail. The first fold after a cold restore now always rebases on live, because focus and keypad are not in TerminalModes and the zero-record shortcut could not see them differ. * fix(terminal): ground a program that dies with input modes armed on the normal screen The daemon's in-stream crash detector only fired when a program died with the alternate screen up. A normal-buffer program that armed mouse tracking, focus reporting, keypad or kitty keyboard flags and exited without disabling them was cleaned up only in the renderer, so the daemon kept the modes and re-armed them on the next reattach, mobile included (#13077's garbage-at-the-prompt family). The lifecycle scanner now tracks armed input modes (mouse protocols and encodings, ?1004, ?66, and kitty flags as per-screen stacks that mirror xterm's main/alt swap and its 16-entry cap). ?2004 and ?1 are excluded: shells arm them at their own prompts. Modes armed when a command starts (OSC 133;C) count as the shell's, so a prompt that leaves modes on never triggers. At OSC 133;D the trigger is now "alt screen or a program-armed input mode", still one-shot and still gated by the shell proof, and the existing PROCESS_BOUNDARY_GROUND is recorded through the stream so live and durable history change together. WSL panes spawn wsl.exe, which the shell proof does not recognise, so the detector never grounds them; a test pins that and the renderer keeps covering them. The mouse-leak e2e now keeps its arming process alive until the live pane is checked, because the daemon grounds a proven exit. * fix(terminal): keep shell- and host-armed input modes through the process-boundary ground ConPTY arms focus reporting (?1004h) before the first prompt, and the live recovery ground cleared it for the rest of the pane. The barrier now re-arms the modes that were on at OSC 133;C right after the ground, so only the dead program's modes are reset. * fix(terminal): re-assert only modes the shell or host armed outside a command A mode a program leaked past a refuted proof was still on at the next OSC 133;C, so the baseline snapshot re-armed it after a later ground. Record who armed each mode instead: only enables outside a command (before any marker, or between 133;A/D and C) form the baseline. * fix(daemon): keep OSC links and kitty flags through durable checkpoint folds and trims Stop seeding persisted OSC link ranges into the fold replay: they index the base buffer, so rows evicted by pending output left a link on the wrong text. The serializer already writes OSC 8 into the ANSI the fold replays. Re-apply kitty keyboard flags when replaying a snapshot for trimming, since rehydrateSequences omits them. Bound a smaller restore request by trimming the committed checkpoint instead of re-reading disk and rebasing the live window at a smaller depth. * test(daemon): follow the isFirstTake rename in the process-boundary ground suite * refactor(daemon): drop the unreachable deep-live branch from the durable fold The live window's override cap now derives from the restore depth, so live can never be deeper than the fold. pendingRecords and isFirstTake are required. * test(daemon): pass pendingRecords to the process-boundary ground fold * fix(terminal): reset alt-screen kitty flags in the process boundary ground Kitty keyboard stacks are per screen, so resetting only after ?1049l left a dead TUI's alt-screen flags for the next alt-screen app. Also drop the inert CAN from the ground (every site grounds after complete bytes) and correct two stale comments. * fix(terminal): track input-mode ownership in one map Each armed mode now has one owner: host (before any marker, or a prompt a 133;C proved), prompt (unproven until C), command, or stale (left past a D). Host arming is sticky, 133;D demotes command modes (the one-shot), and the ground re-asserts only host modes. Fixes a D without C triggering on host modes, an ESC c mid-command turning later enables into host modes, and a program's repeated host enable dropping host ownership. The reattach e2e now keeps the arming program alive so only the reattach reset can disarm it. * refactor(terminal): stop treating kitty flags as host state fish, the one shell that pushes kitty flags at its prompt, pops them before running a command and re-pushes at the next prompt, so the ground never needs to restore them. Only host private modes are re-asserted now. * fix(terminal): keep host input-mode ownership across RIS ConPTY answers a mid-command ESC c by re-sending ?1004h, which reset() had recorded as the command's, so the ground turned host focus reporting off for the rest of the pane. RIS now drops only non-host ownership. * fix(terminal): let only the host own focus reporting and leave it in the ground Host ownership covered every mode armed before the first marker, so a tmux that died with mouse on had it re-armed by the ground. And the re-assert's ?1004h enable made the runtime's ownership mirror revoke, so remote owners never settled on Windows. Only ?1004 can be host-owned now, and the ground skips its ?1004l instead of turning it off and back on, so injected bytes carry no enables.