fix(tui): address Copilot review comments

- stringWidth: true LRU on cache hit (touch-on-read via delete+set) so
  hot strings stay resident under long sessions; was insertion-order
  FIFO before
- virtualHeights: include todos, panel sections, and intro version in
  messageHeightKey so height-cache reuse correctly invalidates when
  todo content / panel sections change
- virtualHeights: estimate trail+todos rows at todos.length+2 (or 2
  collapsed) instead of the generic ~1-line fallback, so initial
  virtualization offsets are closer to reality
- useInputHandlers: clearTimeout on unmount for scrollIdleTimer so
  pending relaxStreaming() never fires after teardown
- render-node-to-output: drop unused declined.noHint counter from
  scrollFastPathStats; it was always 0 (the "hint missing" branch is
  outside the diagnostics block)
- perfPane / hermes-ink.d.ts: follow the noHint removal
- wheelAccel: replace ~/claude-code path comment with generic
  attribution that doesn't reference a developer-local checkout
This commit is contained in:
Brooklyn Nicholson 2026-04-26 20:07:41 -05:00
parent b115ea62da
commit 527ac351b4
7 changed files with 42 additions and 13 deletions

View file

@ -79,7 +79,6 @@ export type ScrollFastPathStats = {
declined: {
noPrevScreen: number
heightDeltaMismatch: number
noHint: number
other: number
}
lastDeclineReason?: string
@ -95,7 +94,6 @@ export const scrollFastPathStats: ScrollFastPathStats = {
declined: {
noPrevScreen: 0,
heightDeltaMismatch: 0,
noHint: 0,
other: 0
}
}
@ -105,7 +103,6 @@ export function resetScrollFastPathStats(): void {
scrollFastPathStats.taken = 0
scrollFastPathStats.declined.noPrevScreen = 0
scrollFastPathStats.declined.heightDeltaMismatch = 0
scrollFastPathStats.declined.noHint = 0
scrollFastPathStats.declined.other = 0
scrollFastPathStats.lastDeclineReason = undefined
scrollFastPathStats.lastHeightDelta = undefined

View file

@ -311,13 +311,16 @@ export const stringWidth: (str: string) => number = str => {
const cached = widthCache.get(str)
if (cached !== undefined) {
// True LRU: refresh recency by re-inserting (Map iteration is insertion order).
widthCache.delete(str)
widthCache.set(str, cached)
return cached
}
const w = rawStringWidth(str)
if (widthCache.size >= WIDTH_CACHE_LIMIT) {
// Drop oldest entry — Map iteration order is insertion order.
widthCache.delete(widthCache.keys().next().value!)
}