Phase 8 of design 01. The daemon's per-tab Term task currently emits only TerminalFrame::Full at each pacer tick, paying one Arc<GridSnapshot> allocation per emit. Chatty TUIs (htop, animated progress bars, streaming agent output) hit this on the hot path.
Trigger: allocator pressure surfaced by a profile run on htop-class output, or an iroh-bandwidth complaint from a paired mobile peer.
Implementation sketch (recap from the design doc):
- Track previous viewport rows + cursor + mode in the Term task.
- On emit, if <= K rows changed since the last
Full, build a Diff { rows_changed, cursor, mode, scroll_offset, bell }; otherwise re-emit Full.
- Periodic keyframe
Full every N seconds (or every M seq) so a viewer that joined mid-stream picks up canonical state without a RequestFullFrame round-trip.
- Viewer side:
LiveTerminalRuntime::ingest_frame's Diff arm currently logs and discards (app/src/terminal_runtime.rs ~line 400). Replace with a row-overlay path that mutates the cached live_snapshot.viewport in place, falls through to recompute_cached_snapshot.
Wire compatibility: TerminalFrame::Diff is already on the wire (daemon-proto/src/lib.rs). No protocol changes needed.
Surfaced from rc/terminal-hardening.
Phase 8 of design 01. The daemon's per-tab Term task currently emits only
TerminalFrame::Fullat each pacer tick, paying oneArc<GridSnapshot>allocation per emit. Chatty TUIs (htop, animated progress bars, streaming agent output) hit this on the hot path.Trigger: allocator pressure surfaced by a profile run on
htop-class output, or an iroh-bandwidth complaint from a paired mobile peer.Implementation sketch (recap from the design doc):
Full, build aDiff { rows_changed, cursor, mode, scroll_offset, bell }; otherwise re-emitFull.Fullevery N seconds (or every M seq) so a viewer that joined mid-stream picks up canonical state without aRequestFullFrameround-trip.LiveTerminalRuntime::ingest_frame'sDiffarm currently logs and discards (app/src/terminal_runtime.rs ~line 400). Replace with a row-overlay path that mutates the cachedlive_snapshot.viewportin place, falls through torecompute_cached_snapshot.Wire compatibility:
TerminalFrame::Diffis already on the wire (daemon-proto/src/lib.rs). No protocol changes needed.Surfaced from rc/terminal-hardening.