hermes-agent/ui-opentui
alt-glitch c04aaecb51 opentui(v6): windowing S2 — pin selected rows instead of freezing on a lingering highlight
Adversarial-review follow-up to the S2 slice. The S1 rule froze ALL window
recomputes while renderer.getSelection()?.isActive — but a finished mouse
selection persists by design (boundary/renderer.ts keeps the highlight so
Ctrl+C can re-copy), so a long streaming turn behind a lingering highlight
ballooned the mounted set exactly like pre-windowing (and permanently
ratcheted the Yoga-WASM high-water).

Refinement:
- full freeze only while selection.isDragging (the native walk touches the
  live tree on every drag update — destroying a row mid-walk corrupts the
  highlight; unchanged from S1 where it matters),
- a finished highlight instead PINS the rows containing
  selection.selectedRenderables (parent-climb to the row wrapper via a
  WeakMap) as neverWindow — the highlight and a later Ctrl+C copy stay
  byte-exact while everything else keeps windowing,
- an active highlight counts as activity (no idle measure churn under it).

Test (headless mock-mouse drag): finished selection persists (isActive,
!isDragging) → 300-row burst keeps peakMounted < 120 AND
getSelectedText() returns the identical text afterward, the selected rows
having been pinned while long scrolled past the margin.

Verified on this build: gate digest otui-capped d5e9558583159eac… (2/2),
mem2000 otui-capped windowing-ON vmhwm 312MB (target ≤ 350), scroll2000
otui-capped p50 2.0ms / p99 6.0ms (gate ≤ 17ms). check exit 0 (648 tests).

Review verdicts on the remaining findings (verified against core source):
- "scrollTop compensation race": rejected — scrollTop is an imperative
  scrollbar property (no signal staleness); records fire in document order,
  each compensation immediately visible to the next.
- "heights map leak on /new": rejected — the countChanged cleanup prunes
  every per-key map against the live key set (test-verified).
- remount-in-viewport estimate shift: only reachable when one frame jumps
  past the margin (> 1 viewport); the design's accepted "remounted for
  view" path — documented in the header.
- expanded tool/reasoning re-collapse on far-remount: S1-accepted,
  deferred (component-local state; out of S2 file ownership).
2026-06-12 08:29:24 +05:30
..
scripts opentui(v6): double-click word / triple-click line selection with held drag-extend 2026-06-11 15:58:33 +05:30
src opentui(v6): windowing S2 — pin selected rows instead of freezing on a lingering highlight 2026-06-12 08:29:24 +05:30
.gitignore opentui(v6): degrade SyntaxStyle exhaustion, unmask the exit-7 crash, clamp the cap to the 65k native handle table 2026-06-11 04:06:19 +05:30
.prettierrc feat(tui): run on Node 26 (one runtime), finalize copy UX, rename to ui-opentui 2026-06-09 16:16:48 +00:00
eslint.config.mjs opentui(v6): degrade SyntaxStyle exhaustion, unmask the exit-7 crash, clamp the cap to the 65k native handle table 2026-06-11 04:06:19 +05:30
package-lock.json opentui(v6): standardize fuzzy search on fuzzysort (adapter keeps our API) 2026-06-10 21:04:22 +05:30
package.json opentui(v6): standardize fuzzy search on fuzzysort (adapter keeps our API) 2026-06-10 21:04:22 +05:30
tsconfig.json feat(tui): run on Node 26 (one runtime), finalize copy UX, rename to ui-opentui 2026-06-09 16:16:48 +00:00
vitest.config.ts opentui(v6): background-agents tray — down-arrow focus + enter to dashboard 2026-06-10 21:00:59 +05:30