Skip to content

Improve terminal redraws to reduce navigation flickering - #252

Merged
shouze merged 4 commits into
mainfrom
shouze-reduce-terminal-flickering
Oct 29, 2026
Merged

shouze merged 4 commits into
mainfrom
shouze-reduce-terminal-flickering

Conversation

@shouze

@shouze shouze commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes #251.

The interactive TUI previously erased the entire screen and wrote the replacement frame separately on every redraw, exposing an intermediate blank screen during Up/Down navigation.

  • Add a pure differential frame builder, consumed through the rendering façade: overwrite only changed lines, clear obsolete tails/rows, emit each changed frame in one write and emit nothing for unchanged frames.
  • Clip styled/Unicode content to the viewport and invalidate the cached frame after resizing. Preserve existing selection/output and terminal cleanup behavior.
  • Address all three Copilot review findings: remove carriage returns before clipping/comparison, expand tabs at visible-column-aware eight-column stops, and omit the tail erase for full-width lines so their final cell is preserved.
  • Add cell-level regressions for CRLF snippets, stale indentation, tab-indented scrolling over occupied cells, styled Unicode and full-width ASCII/wide-glyph content.
  • Extract and reuse the existing TUI key constants in src/terminal-control.ts, alongside named cursor/erase/style/mouse controls and LINE_FEED, CARRIAGE_RETURN, TAB. Reuse them across the TUI, rendering, progress bars and CLI; new frame tests no longer embed protocol strings.
  • Update AGENTS.md, the bug-fixing skill and a dedicated terminal instruction file. Add an architecture guard to the normal Bun/CI suite that rejects raw control encodings outside the shared vocabulary and enforces named line controls on terminal surfaces and new render tests. Only established legacy protocol fixtures and the independent vocabulary contract tests are exempt.
  • Merge current main and resolve the render.ts conflict by preserving both buildFrameUpdate and the terminal-wrapper façade exports.
  • Address the subsequent CodeQL incomplete-escaping finding by escaping every CSI opening bracket when building the SGR matcher, with an independent wire-format regression. The latest CodeQL check passes.

Reproduction and manual verification: Run an interactive query with multiple results; navigate Up/Down across viewport boundaries, then exercise folding, filtering, help and resizing. Before this change, redraws cleared the entire screen. Afterward only affected lines change. The original reporter's exact query, terminal emulator and installed binary version were not provided.

How did you verify your code works?

  • bun test --dots — passed: 1,079 tests, including the three reproduced review defects, additional Unicode/cell regressions, independent control-protocol contracts and the architecture guard. The frame builder has 100% function/line coverage.
  • bun run typecheck — passed, no type errors in 63 files.
  • bun run format:check — passed, all 154 files formatted.
  • bun run knip — passed; two existing informational configuration hints for native Bun commands remain.
  • bun run build.ts — passed; the macOS ARM64 binary compiled and passed codesign verification.
  • git diff --check — passed.
  • Local pseudo-terminal harness — passed using a temporary, network-free fixture that calls the real runInteractive(): 44 interactions and two resizes for each of q, Ctrl+C and Enter. Confirmed one write per changed redraw, no full-screen erase during interaction, no output at navigation boundaries, restored terminal attributes/mouse mode, and valid JSON on confirmation. The first navigation update was 339 bytes versus 2,793 bytes for the initial frame. This local harness is not committed.
  • Latest published commit 1facfdd: repository CI (Bun checks and bats) and all CodeQL checks passed. All review threads are resolved, and GitHub reports the PR as conflict-free.
  • Published merge and fix commits are locally GPG-signed; the pre-commit secret scan passed.

Security scan limitation: aikido_full_scan remains unavailable because the Aikido MCP server is not installed/connected in this session. Setup guide: https://help.aikido.dev/ide-plugins/aikido-mcp.

Replace full-screen redraws with buffered differential line updates. Clear stale tails, clip output to the viewport and invalidate the frame on resize. Add regression coverage for navigation, ANSI styles and Unicode.\n\nFixes #251

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 29, 2026 11:44
@github-actions

Copy link
Copy Markdown
Contributor

Coverage after merging shouze-reduce-terminal-flickering into main will be

96.62%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
scripts
   a11y-utils.ts100%100%100%100%
src
   aggregate.ts100%100%100%100%
   api-utils.ts92.80%100%91.67%92.92%101–103, 165, 86–87, 92–93
   api.ts94.96%100%100%94.42%340–343, 405, 422, 53, 64–67, 69
   cache.ts94.37%100%100%93.94%139–141, 39
   completions.ts99.44%100%100%99.39%268
   gh-cli.ts100%100%100%100%
   group.ts98.37%100%98.33%98.37%1105, 263–265, 525, 531, 607, 865, 980
   output.ts99.31%100%95.83%99.62%89
   regex.ts99.37%100%100%99.32%360
   render.ts90.37%100%88.24%90.45%176, 178–179, 202–207, 209–211, 214, 235–236, 428–429, 529–533, 563–570, 572–580, 583–585
   scroll-cooldown.ts100%100%100%100%
   style.ts100%100%100%100%
   upgrade.ts86.73%100%92.31%86.36%128, 131, 133–134, 153–154, 167–169, 188–193, 195, 198–202, 209, 214, 250–253
src/render
   filter-match.ts97.22%100%92.31%100%
   filter.ts100%100%100%100%
   frame.ts100%100%100%100%
   highlight.ts96.53%100%90.40%99.28%284–285
   layout-constants.ts100%100%100%100%
   mouse-hit.ts100%100%100%100%
   mouse.ts100%100%100%100%
   rows.ts99.34%100%100%99.29%239
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%
   terminal.ts100%100%100%100%

This comment was marked as resolved.

shouze and others added 2 commits October 29, 2026 13:02
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Normalize CRLF and tab-indented snippets before diffing, preserve full-width edge cells, and add cell-level scrolling regressions. Reuse shared named controls across terminal consumers and enforce the convention through agent instructions and CI architecture tests.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

Coverage after merging shouze-reduce-terminal-flickering into main will be

96.78%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
scripts
   a11y-utils.ts100%100%100%100%
src
   aggregate.ts100%100%100%100%
   api-utils.ts92.80%100%91.67%92.92%101–103, 165, 86–87, 92–93
   api.ts96.24%100%100%95.83%428–433, 518, 73–76, 78
   cache.ts94.37%100%100%93.94%139–141, 39
   completions.ts99.44%100%100%99.39%268
   gh-cli.ts100%100%100%100%
   group.ts98.37%100%98.33%98.37%1105, 263–265, 525, 531, 607, 865, 980
   output.ts99.31%100%95.83%99.62%89
   regex.ts99.37%100%100%99.32%360
   render.ts90.41%100%88.24%90.50%185, 187–188, 211–216, 218–220, 223, 244–245, 437–438, 538–542, 572–579, 581–589, 592–594
   scroll-cooldown.ts100%100%100%100%
   style.ts100%100%100%100%
   terminal-control.ts100%100%100%100%
   upgrade.ts86.73%100%92.31%86.36%128, 131, 133–134, 153–154, 167–169, 188–193, 195, 198–202, 209, 214, 250–253
src/render
   filter-match.ts97.22%100%92.31%100%
   filter.ts100%100%100%100%
   frame.ts100%100%100%100%
   highlight.ts96.54%100%90.40%99.29%285–286
   layout-constants.ts100%100%100%100%
   mouse-hit.ts100%100%100%100%
   mouse.ts100%100%100%100%
   rows.ts99.34%100%100%99.29%240
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%
   terminal.ts100%100%100%100%

Comment thread src/terminal-control.ts Fixed
Address the CodeQL incomplete-escaping finding and verify the wire-format matcher preserves surrounding text.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

Coverage after merging shouze-reduce-terminal-flickering into main will be

96.78%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
scripts
   a11y-utils.ts100%100%100%100%
src
   aggregate.ts100%100%100%100%
   api-utils.ts92.80%100%91.67%92.92%101–103, 165, 86–87, 92–93
   api.ts96.24%100%100%95.83%428–433, 518, 73–76, 78
   cache.ts94.37%100%100%93.94%139–141, 39
   completions.ts99.44%100%100%99.39%268
   gh-cli.ts100%100%100%100%
   group.ts98.37%100%98.33%98.37%1105, 263–265, 525, 531, 607, 865, 980
   output.ts99.31%100%95.83%99.62%89
   regex.ts99.37%100%100%99.32%360
   render.ts90.41%100%88.24%90.50%185, 187–188, 211–216, 218–220, 223, 244–245, 437–438, 538–542, 572–579, 581–589, 592–594
   scroll-cooldown.ts100%100%100%100%
   style.ts100%100%100%100%
   terminal-control.ts100%100%100%100%
   upgrade.ts86.73%100%92.31%86.36%128, 131, 133–134, 153–154, 167–169, 188–193, 195, 198–202, 209, 214, 250–253
src/render
   filter-match.ts97.22%100%92.31%100%
   filter.ts100%100%100%100%
   frame.ts100%100%100%100%
   highlight.ts96.54%100%90.40%99.29%285–286
   layout-constants.ts100%100%100%100%
   mouse-hit.ts100%100%100%100%
   mouse.ts100%100%100%100%
   rows.ts99.34%100%100%99.29%240
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%
   terminal.ts100%100%100%100%

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Runtime verification is needed to confirm that per-line SGR resets preserve the footer’s cross-line styling, but Bun is unavailable.

No open issues 🎉

3 resolved since last review

Review effort: Balanced

@shouze
shouze merged commit d9cf6fa into main Oct 29, 2026
6 checks passed
@shouze
shouze deleted the shouze-reduce-terminal-flickering branch October 29, 2026 12:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve terminal redraws to reduce flickering during result navigation

3 participants