Skip to content

feat(ui): enable "TerminalBuffer" mode to solve flicker#24512

Merged
jacob314 merged 5 commits intomainfrom
branch_terminal_buffer_LAND2
Apr 3, 2026
Merged

feat(ui): enable "TerminalBuffer" mode to solve flicker#24512
jacob314 merged 5 commits intomainfrom
branch_terminal_buffer_LAND2

Conversation

@jacob314
Copy link
Copy Markdown
Contributor

@jacob314 jacob314 commented Apr 2, 2026

This PR introduces a new TerminalBuffer rendering mode to resolve UI flicker issues experienced in the traditional alternate buffer mode.

Key Changes

  • Terminal Buffer Mode: Introduces TerminalBuffer for a smooth, flicker-free rendering experience by leveraging static rendering for history items.
  • Settings Updates: Adds renderProcess and terminalBuffer configuration options to customize the rendering strategy.
  • Serializer Fixes: Fixes the terminal serializer to correctly handle and preserve wide characters (multi-byte unicode) during rendering.
  • Mouse Mode Toggle: Adds a new shortcut to toggle mouse mode explicitly, managing scrollback behaviour cleanly.
  • Debug Tooling: Incorporates new commands for dumping frame data and recording sessions to aid UI development.

Motivation

The standard Ink alternate buffer mode relies on full-screen rewrites which causes flicker, especially on slower terminal emulators. TerminalBuffer separates static content (chat history) from dynamic elements (input prompt, spinners), drastically reducing the screen area that needs redrawing.

Fixed Issues

@jacob314 jacob314 requested review from a team as code owners April 2, 2026 08:04
@gemini-cli
Copy link
Copy Markdown
Contributor

gemini-cli Bot commented Apr 2, 2026

Hi @jacob314, thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this.

We're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: Improving Our Contribution Process & Introducing New Guidelines.

Key Update: Starting January 26, 2026, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed.

Thank you for your understanding and for being a part of our community!

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant update to the terminal rendering architecture by adding support for a new terminal buffer mode. These changes aim to improve rendering performance and stability, particularly when handling complex terminal output. Additionally, the PR includes various UI enhancements, updated keyboard shortcuts for better usability, and dependency updates to fix existing bugs.

Highlights

  • New Terminal Buffer Architecture: Introduced a new terminal buffer architecture for rendering, configurable via ui.terminalBuffer and ui.renderProcess settings.
  • Updated Dependencies: Updated the ink dependency to version 6.6.7 to resolve issues with terminal worker launching.
  • Keyboard Shortcuts: Updated keyboard shortcuts, including moving copy mode to F9 and adding new shortcuts for frame dumping and session recording.
  • UI Improvements: Added mouse mode support, improved scroll-to-bottom behavior, and enhanced terminal rendering stability.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 2, 2026

Size Change: +12.7 kB (+0.04%)

Total Size: 34.7 MB

Filename Size Change
./bundle/chunk-E6FD6MZH.js 0 B -3.82 MB (removed) 🏆
./bundle/chunk-HR7JL2FP.js 0 B -14.8 MB (removed) 🏆
./bundle/chunk-U4FACSVX.js 0 B -1.13 kB (removed) 🏆
./bundle/core-JR5RZRDT.js 0 B -45.1 kB (removed) 🏆
./bundle/devtoolsService-4E5O5ABK.js 0 B -28.4 kB (removed) 🏆
./bundle/interactiveCli-24GII3FW.js 0 B -1.66 MB (removed) 🏆
./bundle/oauth2-provider-ULBBA3YS.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-5PS3AYFU.js 1.18 kB +1.18 kB (new file) 🆕
./bundle/chunk-7QJYVPZO.js 14.8 MB +14.8 MB (new file) 🆕
./bundle/chunk-O2TKVHLV.js 3.82 MB +3.82 MB (new file) 🆕
./bundle/core-T4THY6JA.js 45.1 kB +45.1 kB (new file) 🆕
./bundle/devtoolsService-3VVMAQO2.js 28.4 kB +28.4 kB (new file) 🆕
./bundle/interactiveCli-ESRRRNVI.js 1.67 MB +1.67 MB (new file) 🆕
./bundle/oauth2-provider-LHMD5NER.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./bundle/bundled/third_party/index.js 8 MB 0 B
./bundle/chunk-34MYV7JD.js 2.45 kB 0 B
./bundle/chunk-5AUYMPVF.js 858 B 0 B
./bundle/chunk-664ZODQF.js 124 kB 0 B
./bundle/chunk-CEPJKI2L.js 1.96 MB 0 B
./bundle/chunk-DAHVX5MI.js 206 kB 0 B
./bundle/chunk-IUUIT4SU.js 56.5 kB 0 B
./bundle/chunk-RJTRUG2J.js 39.8 kB 0 B
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-T73EYRDX.js 356 B 0 B
./bundle/events-CLX3JQHP.js 0 B -418 B (removed) 🏆
./bundle/gemini.js 550 kB +102 B (+0.02%)
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB 0 B
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB 0 B
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB 0 B
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB 0 B
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB 0 B
./bundle/memoryDiscovery-QMN7XULO.js 980 B 0 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B
./bundle/src-QVCVGIUX.js 47 kB 0 B
./bundle/tree-sitter-7U6MW5PS.js 274 kB 0 B
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB 0 B
./bundle/events-XB7DADIJ.js 418 B +418 B (new file) 🆕

compressed-size-action

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new terminal buffer architecture and an Ink-based render process to improve UI performance and capabilities. Key features include the addition of a toggleable mouse mode (Ctrl+S), session recording (F6/F7), and frame snapshots (F8). Keyboard shortcuts were updated, notably moving copy mode to F9. The VirtualizedList component was refactored to support static rendering and backbuffer overflow. Feedback identifies a regression where ANSI arrays are no longer rendered in standard terminal mode, a logic error in the renderStatic condition within VirtualizedList, and a suggestion to use loose equality checks for optional exit codes to correctly handle undefined values.

Comment thread packages/cli/src/ui/components/messages/ToolResultDisplay.tsx Outdated
Comment thread packages/cli/src/ui/components/shared/VirtualizedList.tsx
Comment thread packages/cli/src/ui/hooks/useExecutionLifecycle.ts Outdated
@jacob314 jacob314 changed the title branch terminal buffer LAND2 feat(ui): add terminal buffer mode to address flicker Apr 2, 2026
Copy link
Copy Markdown
Contributor Author

@jacob314 jacob314 left a comment

Choose a reason for hiding this comment

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

Thanks for the PR! I've updated the PR description and title to match the Conventional Commits format.

I also pushed a small fix directly to the branch to resolve a strict React guideline violation where a side effect (appEvents.emit) was occurring inside the setMouseMode state setter callback within AppContainer.tsx.

One minor note: The useAlternateBuffer hook now returns true if either the alternate buffer or the terminal buffer is enabled. This makes the hook name slightly misleading (as evidenced by its usage as isAlternateBufferOrTerminalBuffer in MainContent.tsx). It's not a blocker, but you might consider renaming it to useAlternateOrTerminalBuffer or splitting them in a future PR for clarity.

Looks good to go!

@jacob314 jacob314 changed the title feat(ui): add terminal buffer mode to address flicker feat(ui): enable "TerminalBuffer" mode to solve flicker Apr 2, 2026
@gemini-cli gemini-cli Bot added priority/p1 Important and should be addressed in the near term. area/core Issues related to User Interface, OS Support, Core Functionality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. labels Apr 2, 2026
@jacob314 jacob314 force-pushed the branch_terminal_buffer_LAND2 branch from 98d50b9 to dcd0c8e Compare April 2, 2026 09:06
Copy link
Copy Markdown
Contributor

@jkcinouye jkcinouye left a comment

Choose a reason for hiding this comment

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

LGTM.

Comment thread packages/core/src/config/config.ts Outdated
this.useRipgrep = params.useRipgrep ?? true;
this.useBackgroundColor = params.useBackgroundColor ?? true;
this.useAlternateBuffer = params.useAlternateBuffer ?? false;
this.useTerminalBuffer = params.useTerminalBuffer ?? false;
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.

In schemas/settings.schema.json line 468, terminalBuffer is declared with default true. In this service initialization block, it fallbacks to false. should we align?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

aligned. in the near feature will run lints to fix these to all be non-nullable. in practice we are never passing in null but we have just messed up our types.

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.

instead of spawning a new JSX wrapper inside renderItem, should we fetch a cached/pre-existing list element reference to avoid instance recreation?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

good call out. fixed.

@jacob314 jacob314 force-pushed the branch_terminal_buffer_LAND2 branch from 239062f to 7707bd5 Compare April 2, 2026 18:08
@jacob314 jacob314 enabled auto-merge April 2, 2026 18:11
jacob314 added 4 commits April 2, 2026 14:56
test: update test utils and resolve snapshot differences for ink changes

feat: refactor VirtualizedList to support static rendering and terminal buffers

feat: wire up AppContainer mouse mode and recording state for ink buffer

Fix stale ref in ScrollProvider breaking scrolling.

The ScrollProvider was getting stuck with a stale reference because the
`scrollables` Map was being registered and unregistered whenever the entry
identity changed. The underlying `ScrollableList` component dynamically created
a new ID which caused React remount cycles, while the `ScrollProvider` itself
suffered from state lag where the event handler ref was one tick behind the
actual registration.

This commit resolves these issues by:
1. Adding a stable `id` and `key` to `ScrollableList` in `MainContent.tsx`
2. Making `scrollablesRef` synchronously update in `ScrollProvider.tsx`
3. Using a proxy entry in `useScrollable` to avoid constant re-registering.

chore: add useEffect cleanup for ResizeObservers

Checkpoint fixing terminal buffer support.

Termina Serializer Optimization

CHECKPOINT_BS_NOT_FOR_COMMIT

Setting schema stuff missed earlier.

Tool Result display fixes.

Checkpoint no commit.

Checkpoint of compile fixes

feat: Auto-scroll to bottom via Events

feat: Auto-scroll to bottom on exiting mouse mode

Fix snapshots

Update ink version to fix terminal worker launching bug.

List fixes.

fix(ui): remove side effect from setState in AppContainer
@jacob314 jacob314 force-pushed the branch_terminal_buffer_LAND2 branch from 03c383f to 571866a Compare April 2, 2026 22:09
@jacob314 jacob314 force-pushed the branch_terminal_buffer_LAND2 branch from 99eef17 to 3b99d8c Compare April 3, 2026 00:07
@jacob314 jacob314 added this pull request to the merge queue Apr 3, 2026
Merged via the queue into main with commit 1f5d701 Apr 3, 2026
26 of 27 checks passed
@jacob314 jacob314 deleted the branch_terminal_buffer_LAND2 branch April 3, 2026 01:10
afanty2021 pushed a commit to afanty2021/gemini-cli that referenced this pull request Apr 4, 2026
warrenzhu25 pushed a commit to warrenzhu25/gemini-cli that referenced this pull request Apr 9, 2026
HaleTom pushed a commit to HaleTom/gemini-cli that referenced this pull request Apr 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. priority/p1 Important and should be addressed in the near term.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Address user feedback on alternate buffer mode

4 participants