Skip to content

feat(cli): implement compact tool output#20974

Merged
jwhelangoog merged 3 commits intomainfrom
feature/dense-output-build-0225
Mar 30, 2026
Merged

feat(cli): implement compact tool output#20974
jwhelangoog merged 3 commits intomainfrom
feature/dense-output-build-0225

Conversation

@jwhelangoog
Copy link
Copy Markdown
Contributor

@jwhelangoog jwhelangoog commented Mar 3, 2026

Summary

(Part 2 of 2 - Follows foundational layout and diff accuracy improvements in #23286)

This PR provides the core implementation of the Compact Tool Output feature, building upon the original proposal in #18728. It introduces a compact, high-signal rendering mode for tool outputs that improves terminal ergonomics and reduces the visual gap between user prompts and system/agent responses.

Details

Key architectural and UI improvements include:

  • Compact Output Setting: Introduces the ui.compactToolOutput setting (defaults to false).
  • Structured Tool Results: Refactors grep, ls, and read_many_files in packages/core to return structured payloads (GrepResult, ListDirectoryResult, ReadManyFilesResult). This allows the UI to render concise summaries while preserving the full data payload for sub-views or agent context.
  • Dense Tool Rendering: Implements the DenseToolMessage component for single-line tool summaries (status, description, and diff stats), complete with an interactive toggle to expand file diffs within the Alternate Screen Buffer (ASB).
  • Smart Interleaving & Grouping: Updates ToolGroupMessage with a segment-based rendering approach. It densely packs consecutive compact outputs while isolating standard, verbose tools (like ShellToolMessage) into their own bordered boxes with consistent spacing.
  • UI Decoupling: Introduces ToolActionsContext to manage tool confirmations, cancellations, and IDE side-effects, cleanly separating this logic from the presentation layer.

Related Issues

How to Validate

  1. Enable ui.compactToolOutput: true in your settings.
  2. File Edits: Run a tool that modifies a file (e.g., edit). Verify the output is a single line and that clicking the status expands the diff correctly.
  3. Structured Tools: Run ls, read_many_files, and grep_search. Verify they output clean, 1-2 line summaries instead of their full payloads.
  4. Interleaving: Run a sequence of tools including both compact tools and standard tools (e.g., run_shell_command). Verify that shell commands are properly isolated in their own boxes with correct spacing.

@gemini-cli gemini-cli bot added priority/p2 Important but can be addressed in a future release. area/core Issues related to User Interface, OS Support, Core Functionality labels Mar 3, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 3, 2026

Size Change: +28.9 kB (+0.11%)

Total Size: 26.5 MB

Filename Size Change
./bundle/chunk-OC6WAGQK.js 0 B -3.78 MB (removed) 🏆
./bundle/chunk-QGLNP2IW.js 0 B -1.96 MB (removed) 🏆
./bundle/chunk-RUIRTAT7.js 0 B -14.7 MB (removed) 🏆
./bundle/core-CEB4UTV5.js 0 B -44.5 kB (removed) 🏆
./bundle/devtoolsService-3IR3GEHW.js 0 B -28.4 kB (removed) 🏆
./bundle/interactiveCli-3TBZGEIM.js 0 B -1.63 MB (removed) 🏆
./bundle/oauth2-provider-QUVRCJK5.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-ACJUZQQ3.js 1.96 MB +1.96 MB (new file) 🆕
./bundle/chunk-NT6AFNXH.js 14.7 MB +14.7 MB (new file) 🆕
./bundle/chunk-PD446NAB.js 3.78 MB +3.78 MB (new file) 🆕
./bundle/core-W2Y6S4TO.js 44.5 kB +44.5 kB (new file) 🆕
./bundle/devtoolsService-MUI5TLYH.js 28.4 kB +28.4 kB (new file) 🆕
./bundle/interactiveCli-TFTKNGRF.js 1.66 MB +1.66 MB (new file) 🆕
./bundle/oauth2-provider-TCTOBOO4.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./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-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/chunk-U4FACSVX.js 1.13 kB 0 B
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-T73EYRDX.js 356 B 0 B
./bundle/events-CLX3JQHP.js 418 B 0 B
./bundle/gemini.js 532 kB 0 B
./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-XKQPPGVK.js 0 B -922 B (removed) 🏆
./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/memoryDiscovery-FAPON353.js 922 B +922 B (new file) 🆕

compressed-size-action

@jwhelangoog jwhelangoog force-pushed the feature/dense-output-build-0225 branch from a72642f to 26d83d5 Compare March 3, 2026 16:44
@jwhelangoog jwhelangoog force-pushed the feature/dense-output-build-0225 branch from 79cbd3c to 3dc7dc9 Compare March 3, 2026 22:25
@gemini-cli gemini-cli bot added the 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. label Mar 5, 2026
@jwhelangoog jwhelangoog force-pushed the feature/dense-output-build-0225 branch 7 times, most recently from 87cc10e to 251a79f Compare March 10, 2026 07:37
@jwhelangoog
Copy link
Copy Markdown
Contributor Author

Compact Tool Output Vid: http://screencast/cast/NjEwNjgzMzAyOTY5MzQ0MHw2MGMyZDJjYi1mMQ

@jwhelangoog jwhelangoog force-pushed the feature/dense-output-build-0225 branch 6 times, most recently from 211a5b2 to f357b17 Compare March 19, 2026 09:13
@jwhelangoog jwhelangoog force-pushed the feature/dense-output-build-0225 branch 3 times, most recently from 73e7db3 to ba264fa Compare March 19, 2026 23:32
@jwhelangoog jwhelangoog marked this pull request as ready for review March 19, 2026 23:39
@jwhelangoog jwhelangoog requested review from a team as code owners March 19, 2026 23:39
@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 significantly enhances the user interface for tool output in the CLI by introducing a 'Compact Tool Output' feature. It refactors how tool results are displayed, moving towards a more structured and ergonomic presentation. The changes aim to provide users with high-signal information at a glance, with the option to delve into details, thereby streamlining the interaction with agent and tool responses in the terminal.

Highlights

  • Compact Tool Output UI: Introduced a new DenseToolMessage component for rendering tool outputs in a compact, single-line format, improving terminal ergonomics and reducing visual clutter. This includes concise summaries for various tool results like file diffs, grep matches, and directory listings.
  • Structured Tool Results: Enhanced core tools (Grep, LS, ReadManyFiles) to return structured result objects, enabling the UI to render high-signal summaries and optional detailed sub-views. This provides more context without overwhelming the user.
  • Dynamic Tool Grouping & Spacing: Implemented intelligent grouping and spacing logic within ToolGroupMessage to densely group consecutive compact tool outputs while isolating standard (non-compact) tools in distinct bordered boxes, ensuring consistent visual separation.
  • Diff Accuracy Improvements: Resolved an issue with misleading 'large deletion' reports in diffs by implementing LF-normalization in getDiffStat and ensuring accurate diff statistics are derived from patches, even for cancelled or errored operations.
  • Tool Expansion Management: Added state management and actions (isExpanded, toggleExpansion, toggleAllExpansion) to control the visibility of detailed tool outputs, allowing users to expand or collapse information as needed, particularly in alternate buffer mode.
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.

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 UI setting for compact tool output, allowing tool results like file diffs and directory listings to be displayed in a more concise, structured format. It refactors tool call ID generation to ensure uniqueness and updates UI components to support toggleable expansion of tool outputs, especially in alternate buffer mode. A code review comment highlights a duplication of logic for identifying target tool call IDs in AppContainer.tsx that should be extracted into a reusable helper function to improve maintainability and prevent inconsistencies.

Note: Security Review did not run due to the size of the PR.

@jwhelangoog jwhelangoog force-pushed the feature/dense-output-build-0225 branch 4 times, most recently from 45d9438 to 038daab Compare March 28, 2026 04:17
Copy link
Copy Markdown
Contributor

@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.

lgtm

@jwhelangoog jwhelangoog force-pushed the feature/dense-output-build-0225 branch 4 times, most recently from 5655b88 to 55f98e7 Compare March 30, 2026 16:57
Copy link
Copy Markdown
Contributor

@g-samroberts g-samroberts left a comment

Choose a reason for hiding this comment

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

lgtm for docs.

@gundermanc
Copy link
Copy Markdown
Member

Is it normal to include SVGs as part of the UI tests?

@jwhelangoog
Copy link
Copy Markdown
Contributor Author

jwhelangoog commented Mar 30, 2026

Is it normal to include SVGs as part of the UI tests?

This was recently added by Jacob I believe as an option to support color validation within the tests.

@jwhelangoog jwhelangoog enabled auto-merge March 30, 2026 19:31
@jwhelangoog jwhelangoog force-pushed the feature/dense-output-build-0225 branch 3 times, most recently from 974fd7a to fdb33f5 Compare March 30, 2026 23:14
@jwhelangoog jwhelangoog disabled auto-merge March 30, 2026 23:15
@jwhelangoog jwhelangoog enabled auto-merge March 30, 2026 23:25
…e safety

This commit establishes the structural foundation and required infrastructure to support the upcoming compact tool output changes. It includes identity management improvements, layout fixes, and type-safety enhancements that stand independently.

1. Identity & History Management:
- useHistoryManager: Ensure strictly increasing IDs for history items, even with identical timestamps.
- acpClient: Introduced callIdCounter to prevent callId collisions during rapid execution.
- MainContent: Implemented negative ID logic for pending items to ensure stable React keys and prevent collisions.
- historyUtils: New file containing extracted history logic (isToolExecuting, getAllToolCalls) hoisted from AppContainer.

2. UI Infrastructure & Layout:
- test-utils/render: Modernized renderWithProviders and removed legacy props.
- AskUserDialog: Fixed layout, scroll visibility, and alignment issues.
- toolLayoutUtils: Increased TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT for better spacing.
- ShellToolMessage/ToolGroupMessage: Updated line-count expectations and snapshots to align with layout changes.

3. IDE & Diffing Improvements:
- ToolActionsContext: Refactored IdeClient initialization to fix a race condition and potential memory leak.
- edit/diffOptions: Improved accuracy of diff stat derivation, ensuring "full content" stats are available for the model.
- coreToolScheduler: Automatically derive diff stats from patches if missing.
- state-manager: Ensure diffStat preservation for rejected tool calls.

4. Type Safety & Constants:
- types/tools: Added foundational types like DiffStat, FileDiff, and StructuredToolResult.
- Type Guards: Added guards for isFileDiff, isTodoList, isAnsiOutput, and hasSummary.
- CodeColorizer: Added function overloads to gracefully handle null language detection.
- tool-names: Introduced DISPLAY_NAME constants for consistent tool labeling.

This commit passes all workspace tests and builds successfully. Feature-specific logic for compact output is excluded.
This commit introduces the compactToolOutput feature to optimize terminal vertical space usage for common, high-volume tools.

1. Compact Tool Output UI:
- Added DenseToolMessage component for rendering compact, single-line tool summaries.
- Updated ToolGroupMessage to detect contiguous compact tools and render them with stitched borders for a streamlined look.
- Added Ctrl+O shortcut in AppContainer to toggle full expansion of tool results from the last turn.
- Implemented useGeminiStream border logic to correctly render borders around dense sections.

2. Core Tool Structured Results:
- grep: Updated to return GrepResult with matches, file paths, and line numbers instead of a raw formatted string.
- ls (list_directory): Updated to return ListDirectoryResult with an array of files.
- read_many_files: Updated to return ReadManyFilesResult with read files, skipped files, and reasons.
- Modified ToolResultDisplay and isStructuredToolResult type guards to support these new structured interfaces.

3. User Settings & Documentation:
- Added compactToolOutput to the UI settings schema (default: true).
- Updated configuration docs and schema to reflect the new setting.
- Adjusted compact subview line limits (COMPACT_TOOL_SUBVIEW_MAX_LINES).

test(cli): refine settings and tool action mocks to resolve test rig regressions

This update addresses incomplete settings store contracts and default state mismatches that caused snapshot runtime errors and verification failures in compact tool output tests.

1. Settings Mock Completeness:
- Updated `createMockSettings` in `mockConfig.ts` to include required functional methods (`subscribe`, `getSnapshot`, `setValue`) to satisfy React's `useSyncExternalStore` contract. This resolves "store.getSnapshot is not a function" errors in snapshot tests.

2. Tool Actions Provider Configuration:
- Modified `renderWithProviders` to accept a `toolActions` options object, allowing individual tests to inject specific tool expansion states.
- Changed the default mock for `isExpanded` from `true` to `false` to align with the application's default behavior (collapsed outputs) in alternate buffer mode.

3. Test Refactoring:
- Refactored `ToolGroupMessage.compact.test.tsx` to use the standardized `createMockSettings` utility rather than a manual generic object, ensuring proper context evaluation during rendering.

refactor(cli): address nuanced snapshot rendering scenarios through layout and padding refinements

- Refined height calculation logic in ToolGroupMessage to ensure consistent spacing between compact and standard tools.
- Adjusted padding and margins in StickyHeader, ToolConfirmationQueue, ShellToolMessage, and ToolMessage for visual alignment.
- Updated TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT to account for internal layout changes.
- Improved ToolResultDisplay height handling in alternate buffer mode.
- Updated test snapshots to reflect layout and spacing corrections.

refactor(cli): cleanup and simplify UI components

- Reduced UI refresh delay in AppContainer.tsx for a more responsive user experience.
- Reorder imports and hook definitions within AppContainer.tsx to reduce diff 'noise'.

refactor(cli): enhance compact output robustness and visual regression testing

Addressing automated review feedback to improve code maintainability and layout stability.

1. Robust File Extension Parsing:
- Introduced getFileExtension utility in packages/cli/src/ui/utils/fileUtils.ts using node:path for reliable extension extraction.
- Updated DenseToolMessage and DiffRenderer to use the new utility, replacing fragile string splitting.

2. Visual Regression Coverage:
- Added SVG snapshot tests to DenseToolMessage.test.tsx to verify semantic color rendering and layout integrity in compact mode.

fix(cli): resolve dense tool output code quality issues

- Replaced manual string truncation with Ink's `wrap="truncate-end"` to adhere to UI guidelines.
- Added `isReadManyFilesResult` type guard to `packages/core/src/tools/tools.ts` to improve typing for structured tool results.
- Fixed an incomplete test case in `DenseToolMessage.test.tsx` to properly simulate expansion via context instead of missing mouse events.
- Abstracted hardcoded padding, margin, and width calculations in `DenseToolMessage` into explicit constants to improve readability.
- Made `terminalWidth` a required property on `DenseToolMessageProps` to ensure consistent layout calculations, simplifying internal ternary checks.
- Updated `DenseToolMessage` tests to provide the now-required `terminalWidth` prop.
- Removed expensive `node:crypto` usage in `DiffRenderer` key generation, opting for a simpler optional key.
- Simplified terminal refresh logic in `AppContainer` by removing `setTimeout` from the "show more lines" handler, as it was redundant.
- Streamlined `staticHeight` calculation loop in `ToolGroupMessage` to use layout constants.
- Removed redundant `height={0}` properties on Box borders in `ToolGroupMessage`.
- Simplified `effectiveMaxHeight` assignment in `ToolResultDisplay` by using the pre-calculated `availableHeight` directly.
- Restore tool message padding by moving `paddingTop={1}` from `ToolMessage` and `ShellToolMessage` content boxes back to `paddingBottom={1}` in `StickyHeader`.
- Restore `ToolConfirmationQueue` layout.
- Removed excluded file information from ReadManyFiles tool's compact output
@jwhelangoog jwhelangoog force-pushed the feature/dense-output-build-0225 branch from fdb33f5 to 91a73c9 Compare March 30, 2026 23:28
@jwhelangoog jwhelangoog added this pull request to the merge queue Mar 30, 2026
Merged via the queue into main with commit 1df5c98 Mar 30, 2026
27 of 28 checks passed
@jwhelangoog jwhelangoog deleted the feature/dense-output-build-0225 branch March 30, 2026 23:59
kalenkevich pushed a commit to kalenkevich/gemini-cli that referenced this pull request Apr 3, 2026
afanty2021 pushed a commit to afanty2021/gemini-cli that referenced this pull request Apr 4, 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/p0 Critical and urgent (e.g., critical security vulnerability, major breakage). priority/p2 Important but can be addressed in a future release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Densify ReadFile and ReadManyFile output [Feature Request] Suppress or control verbose tool output (JSON) in the CLI UI

4 participants