refactor(terminal): explicit history buffer + virtual scrolling
Replace the spacer-estimate scrollback model with an explicit history row buffer owned by TerminalCore, rendered with absolute-positioned virtual scrolling so huge outputs (cat of 50k-line files) stay smooth. core.rs: - TerminalCore owns history_rows + a cached screen, captured after each process() via a bounded "conveyor belt" read of vt100 scrollback - feed bytes in newline-bounded safe slices so a capture never reads deeper than viewport_rows (works around vt100 0.15 visible_rows subtract-overflow panic) - handle clear (ESC[3J) by wiping our own history buffer - TerminalSegment carries grid column count for exact-width rendering - collect_window() clones only the visible slice component.rs: - TerminalCore lives in an RwSignal; render driven by an rAF-coalesced render_tick so packet bursts collapse into one frame - virtual_window pins to the bottom in live mode, follows scroll_top in history mode; absolute-positioned rows in a fixed-height sizer keep scroll geometry constant (fixes the "keeps drifting up" bounce) - position-based programmatic-scroll detection replaces the racy ignore-next-scroll flag - alt-screen wheel events translate to arrow keys (vim/less paging) - try_* signal access guards against disposal during hydration style: lock row height to 18px, segment width to Nch (exact grid so fallback-font glyphs like btm braille can't push the row sideways), absolute-position the virtual rows layer. Adds 12 unit tests (capture, clear, alt-screen, window slicing, wheel mapping) and TERMINAL_ROADMAP.md tracking xterm.js parity work. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in: