From 0a370ad1ce6b8418e67f3b2bddbc3e181895b1a6 Mon Sep 17 00:00:00 2001 From: Keith Guerin Date: Sun, 1 Mar 2026 02:15:29 -0800 Subject: [PATCH] feat(ui): replace rainbow shell icon with themed blue spinner --- .../__snapshots__/MainContent.test.tsx.snap | 8 ++++---- .../messages/ShellToolMessage.test.tsx | 5 +++++ .../messages/ToolGroupMessage.test.tsx | 5 +++++ .../components/messages/ToolMessage.test.tsx | 4 ++-- .../messages/ToolMessageFocusHint.test.tsx | 6 ++++++ .../src/ui/components/messages/ToolShared.tsx | 11 +++++------ .../ShellToolMessage.test.tsx.snap | 14 +++++++------- .../ToolGroupMessage.test.tsx.snap | 2 +- .../__snapshots__/ToolMessage.test.tsx.snap | 12 ++++++------ .../ToolMessageFocusHint.test.tsx.snap | 18 +++++++++--------- ...g-search-dialog-google_web_search-.snap.svg | 3 ++- ...nder-SVG-snapshot-for-a-shell-tool.snap.svg | 3 ++- ...mpty-slice-following-a-search-tool.snap.svg | 3 ++- .../__snapshots__/borderStyles.test.tsx.snap | 6 +++--- 14 files changed, 59 insertions(+), 41 deletions(-) diff --git a/packages/cli/src/ui/components/__snapshots__/MainContent.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/MainContent.test.tsx.snap index 0599e82f7c..d01043eee9 100644 --- a/packages/cli/src/ui/components/__snapshots__/MainContent.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/MainContent.test.tsx.snap @@ -4,7 +4,7 @@ exports[`MainContent > MainContent Tool Output Height Logic > 'ASB mode - Focuse "ScrollableList AppHeader(full) ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ Shell Command Running a long command... │ +│ ⊶ Shell Command Running a long command... │ │ │ │ Line 10 │ │ Line 11 │ @@ -26,7 +26,7 @@ exports[`MainContent > MainContent Tool Output Height Logic > 'ASB mode - Unfocu "ScrollableList AppHeader(full) ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ Shell Command Running a long command... │ +│ ⊶ Shell Command Running a long command... │ │ │ │ Line 10 │ │ Line 11 │ @@ -47,7 +47,7 @@ ShowMoreLines exports[`MainContent > MainContent Tool Output Height Logic > 'Normal mode - Constrained height' 1`] = ` "AppHeader(full) ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ Shell Command Running a long command... │ +│ ⊶ Shell Command Running a long command... │ │ │ │ ... first 11 lines hidden (Ctrl+O to show) ... │ │ Line 12 │ @@ -67,7 +67,7 @@ ShowMoreLines exports[`MainContent > MainContent Tool Output Height Logic > 'Normal mode - Unconstrained height' 1`] = ` "AppHeader(full) ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ Shell Command Running a long command... │ +│ ⊶ Shell Command Running a long command... │ │ │ │ Line 1 │ │ Line 2 │ diff --git a/packages/cli/src/ui/components/messages/ShellToolMessage.test.tsx b/packages/cli/src/ui/components/messages/ShellToolMessage.test.tsx index 72ce8cec5f..1d5a4ae3b2 100644 --- a/packages/cli/src/ui/components/messages/ShellToolMessage.test.tsx +++ b/packages/cli/src/ui/components/messages/ShellToolMessage.test.tsx @@ -19,6 +19,11 @@ import { renderWithProviders } from '../../../test-utils/render.js'; import { waitFor } from '../../../test-utils/async.js'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import { SHELL_COMMAND_NAME, ACTIVE_SHELL_MAX_LINES } from '../../constants.js'; +import { Text } from 'ink'; + +vi.mock('../CliSpinner.js', () => ({ + CliSpinner: () => , +})); describe('', () => { const baseProps: ShellToolMessageProps = { diff --git a/packages/cli/src/ui/components/messages/ToolGroupMessage.test.tsx b/packages/cli/src/ui/components/messages/ToolGroupMessage.test.tsx index 056e6a54b4..ec0225687b 100644 --- a/packages/cli/src/ui/components/messages/ToolGroupMessage.test.tsx +++ b/packages/cli/src/ui/components/messages/ToolGroupMessage.test.tsx @@ -26,6 +26,11 @@ import { } from '@google/gemini-cli-core'; import os from 'node:os'; import { createMockSettings } from '../../../test-utils/settings.js'; +import { Text } from 'ink'; + +vi.mock('../CliSpinner.js', () => ({ + CliSpinner: () => , +})); describe('', () => { afterEach(() => { diff --git a/packages/cli/src/ui/components/messages/ToolMessage.test.tsx b/packages/cli/src/ui/components/messages/ToolMessage.test.tsx index df4354b1c4..df79beb636 100644 --- a/packages/cli/src/ui/components/messages/ToolMessage.test.tsx +++ b/packages/cli/src/ui/components/messages/ToolMessage.test.tsx @@ -13,8 +13,8 @@ import { type AnsiOutput, CoreToolCallStatus } from '@google/gemini-cli-core'; import { renderWithProviders } from '../../../test-utils/render.js'; import { tryParseJSON } from '../../../utils/jsonoutput.js'; -vi.mock('../GeminiRespondingSpinner.js', () => ({ - GeminiRespondingSpinner: () => MockRespondingSpinner, +vi.mock('../CliSpinner.js', () => ({ + CliSpinner: () => MockCliSpinner, })); vi.mock('../TerminalOutput.js', () => ({ diff --git a/packages/cli/src/ui/components/messages/ToolMessageFocusHint.test.tsx b/packages/cli/src/ui/components/messages/ToolMessageFocusHint.test.tsx index 30863fef06..2492fe8dfb 100644 --- a/packages/cli/src/ui/components/messages/ToolMessageFocusHint.test.tsx +++ b/packages/cli/src/ui/components/messages/ToolMessageFocusHint.test.tsx @@ -20,6 +20,12 @@ import { CoreToolCallStatus, } from '@google/gemini-cli-core'; +import { Text } from 'ink'; + +vi.mock('../CliSpinner.js', () => ({ + CliSpinner: () => , +})); + vi.mock('../GeminiRespondingSpinner.js', () => ({ GeminiRespondingSpinner: () => null, })); diff --git a/packages/cli/src/ui/components/messages/ToolShared.tsx b/packages/cli/src/ui/components/messages/ToolShared.tsx index 21f15f70df..6544543d92 100644 --- a/packages/cli/src/ui/components/messages/ToolShared.tsx +++ b/packages/cli/src/ui/components/messages/ToolShared.tsx @@ -7,7 +7,7 @@ import React, { useState, useEffect } from 'react'; import { Box, Text } from 'ink'; import { ToolCallStatus, mapCoreStatusToDisplayStatus } from '../../types.js'; -import { GeminiRespondingSpinner } from '../GeminiRespondingSpinner.js'; +import { CliSpinner } from '../CliSpinner.js'; import { SHELL_COMMAND_NAME, SHELL_NAME, @@ -145,7 +145,7 @@ export const ToolStatusIndicator: React.FC = ({ }) => { const status = mapCoreStatusToDisplayStatus(coreStatus); const isShell = isShellTool(name); - const statusColor = isShell ? theme.ui.symbol : theme.status.warning; + const statusColor = isShell ? theme.ui.active : theme.status.warning; return ( @@ -153,10 +153,9 @@ export const ToolStatusIndicator: React.FC = ({ {TOOL_STATUS.PENDING} )} {status === ToolCallStatus.Executing && ( - + + + )} {status === ToolCallStatus.Success && ( diff --git a/packages/cli/src/ui/components/messages/__snapshots__/ShellToolMessage.test.tsx.snap b/packages/cli/src/ui/components/messages/__snapshots__/ShellToolMessage.test.tsx.snap index 0d34c7e49d..b51d7c435b 100644 --- a/packages/cli/src/ui/components/messages/__snapshots__/ShellToolMessage.test.tsx.snap +++ b/packages/cli/src/ui/components/messages/__snapshots__/ShellToolMessage.test.tsx.snap @@ -2,7 +2,7 @@ exports[` > Height Constraints > defaults to ACTIVE_SHELL_MAX_LINES in alternate buffer when availableTerminalHeight is undefined 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ Shell Command A shell command │ +│ ⊶ Shell Command A shell command │ │ │ │ Line 86 │ │ Line 87 │ @@ -131,7 +131,7 @@ exports[` > Height Constraints > fully expands in alternate exports[` > Height Constraints > respects availableTerminalHeight when it is smaller than ACTIVE_SHELL_MAX_LINES 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ Shell Command A shell command │ +│ ⊶ Shell Command A shell command │ │ │ │ Line 93 │ │ Line 94 │ @@ -168,7 +168,7 @@ exports[` > Height Constraints > stays constrained in altern exports[` > Height Constraints > uses ACTIVE_SHELL_MAX_LINES when availableTerminalHeight is large 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ Shell Command A shell command │ +│ ⊶ Shell Command A shell command │ │ │ │ Line 86 │ │ Line 87 │ @@ -190,7 +190,7 @@ exports[` > Height Constraints > uses ACTIVE_SHELL_MAX_LINES exports[` > Height Constraints > uses full availableTerminalHeight when focused in alternate buffer mode 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ Shell Command A shell command (Shift+Tab to unfocus) │ +│ ⊶ Shell Command A shell command (Shift+Tab to unfocus) │ │ │ │ Line 3 │ │ Line 4 │ @@ -295,7 +295,7 @@ exports[` > Height Constraints > uses full availableTerminal exports[` > Snapshots > renders in Alternate Buffer mode while focused 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ Shell Command A shell command (Shift+Tab to unfocus) │ +│ ⊶ Shell Command A shell command (Shift+Tab to unfocus) │ │ │ │ Test result │ " @@ -303,7 +303,7 @@ exports[` > Snapshots > renders in Alternate Buffer mode whi exports[` > Snapshots > renders in Alternate Buffer mode while unfocused 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ Shell Command A shell command │ +│ ⊶ Shell Command A shell command │ │ │ │ Test result │ " @@ -319,7 +319,7 @@ exports[` > Snapshots > renders in Error state 1`] = ` exports[` > Snapshots > renders in Executing state 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ Shell Command A shell command │ +│ ⊶ Shell Command A shell command │ │ │ │ Test result │ " diff --git a/packages/cli/src/ui/components/messages/__snapshots__/ToolGroupMessage.test.tsx.snap b/packages/cli/src/ui/components/messages/__snapshots__/ToolGroupMessage.test.tsx.snap index 6adcb80a5c..29da4d5860 100644 --- a/packages/cli/src/ui/components/messages/__snapshots__/ToolGroupMessage.test.tsx.snap +++ b/packages/cli/src/ui/components/messages/__snapshots__/ToolGroupMessage.test.tsx.snap @@ -71,7 +71,7 @@ exports[` > Golden Snapshots > renders mixed tool calls incl │ │ │ Test result │ │ │ -│ ⊷ run_shell_command Run command │ +│ ⊶ run_shell_command Run command │ │ │ │ Test result │ ╰──────────────────────────────────────────────────────────────────────────╯ diff --git a/packages/cli/src/ui/components/messages/__snapshots__/ToolMessage.test.tsx.snap b/packages/cli/src/ui/components/messages/__snapshots__/ToolMessage.test.tsx.snap index f31865874d..806e18637d 100644 --- a/packages/cli/src/ui/components/messages/__snapshots__/ToolMessage.test.tsx.snap +++ b/packages/cli/src/ui/components/messages/__snapshots__/ToolMessage.test.tsx.snap @@ -29,7 +29,7 @@ exports[` > ToolStatusIndicator rendering > shows - for Canceled exports[` > ToolStatusIndicator rendering > shows MockRespondingSpinner for Executing status when streamingState is Responding 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ MockRespondingSpinnertest-tool A tool for testing │ +│ MockCliSpinnertest-tool A tool for testing │ │ │ │ Test result │ " @@ -45,7 +45,7 @@ exports[` > ToolStatusIndicator rendering > shows o for Pending s exports[` > ToolStatusIndicator rendering > shows paused spinner for Executing status when streamingState is Idle 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ MockRespondingSpinnertest-tool A tool for testing │ +│ MockCliSpinnertest-tool A tool for testing │ │ │ │ Test result │ " @@ -53,7 +53,7 @@ exports[` > ToolStatusIndicator rendering > shows paused spinner exports[` > ToolStatusIndicator rendering > shows paused spinner for Executing status when streamingState is WaitingForConfirmation 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ MockRespondingSpinnertest-tool A tool for testing │ +│ MockCliSpinnertest-tool A tool for testing │ │ │ │ Test result │ " @@ -94,7 +94,7 @@ exports[` > renders DiffRenderer for diff results 1`] = ` exports[` > renders McpProgressIndicator with percentage and message for executing tools 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ MockRespondingSpinnertest-tool A tool for testing │ +│ MockCliSpinnertest-tool A tool for testing │ │ │ │ ████████░░░░░░░░░░░░ 42% │ │ Working on it... │ @@ -128,7 +128,7 @@ exports[` > renders emphasis correctly 2`] = ` exports[` > renders indeterminate progress when total is missing 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ MockRespondingSpinnertest-tool A tool for testing │ +│ MockCliSpinnertest-tool A tool for testing │ │ │ │ ███████░░░░░░░░░░░░░ 7 │ │ Test result │ @@ -137,7 +137,7 @@ exports[` > renders indeterminate progress when total is missing exports[` > renders only percentage when progressMessage is missing 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ MockRespondingSpinnertest-tool A tool for testing │ +│ MockCliSpinnertest-tool A tool for testing │ │ │ │ ███████████████░░░░░ 75% │ │ Test result │ diff --git a/packages/cli/src/ui/components/messages/__snapshots__/ToolMessageFocusHint.test.tsx.snap b/packages/cli/src/ui/components/messages/__snapshots__/ToolMessageFocusHint.test.tsx.snap index fb4f1ec722..8da15d7fdb 100644 --- a/packages/cli/src/ui/components/messages/__snapshots__/ToolMessageFocusHint.test.tsx.snap +++ b/packages/cli/src/ui/components/messages/__snapshots__/ToolMessageFocusHint.test.tsx.snap @@ -2,63 +2,63 @@ exports[`Focus Hint > 'ShellToolMessage' > shows focus hint after delay even with NO output > after-delay-no-output 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ Shell Command A tool for testing (Tab to focus) │ +│ ⊶ Shell Command A tool for testing (Tab to focus) │ │ │ " `; exports[`Focus Hint > 'ShellToolMessage' > shows focus hint after delay even with NO output > initial-no-output 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ Shell Command A tool for testing │ +│ ⊶ Shell Command A tool for testing │ │ │ " `; exports[`Focus Hint > 'ShellToolMessage' > shows focus hint after delay with output > after-delay-with-output 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ Shell Command A tool for testing (Tab to focus) │ +│ ⊶ Shell Command A tool for testing (Tab to focus) │ │ │ " `; exports[`Focus Hint > 'ShellToolMessage' > shows focus hint after delay with output > initial-with-output 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ Shell Command A tool for testing │ +│ ⊶ Shell Command A tool for testing │ │ │ " `; exports[`Focus Hint > 'ToolMessage' > shows focus hint after delay even with NO output > after-delay-no-output 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ Shell Command A tool for testing (Tab to focus) │ +│ ⊶ Shell Command A tool for testing (Tab to focus) │ │ │ " `; exports[`Focus Hint > 'ToolMessage' > shows focus hint after delay even with NO output > initial-no-output 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ Shell Command A tool for testing │ +│ ⊶ Shell Command A tool for testing │ │ │ " `; exports[`Focus Hint > 'ToolMessage' > shows focus hint after delay with output > after-delay-with-output 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ Shell Command A tool for testing (Tab to focus) │ +│ ⊶ Shell Command A tool for testing (Tab to focus) │ │ │ " `; exports[`Focus Hint > 'ToolMessage' > shows focus hint after delay with output > initial-with-output 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ Shell Command A tool for testing │ +│ ⊶ Shell Command A tool for testing │ │ │ " `; exports[`Focus Hint > handles long descriptions by shrinking them to show the focus hint > long-description 1`] = ` "╭──────────────────────────────────────────────────────────────────────────────╮ -│ Shell Command AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA… (Tab to focus) │ +│ ⊶ Shell Command AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA… (Tab to focus) │ │ │ " `; diff --git a/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-a-pending-search-dialog-google_web_search-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-a-pending-search-dialog-google_web_search-.snap.svg index b9290efcac..68f56c7794 100644 --- a/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-a-pending-search-dialog-google_web_search-.snap.svg +++ b/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-a-pending-search-dialog-google_web_search-.snap.svg @@ -111,7 +111,8 @@ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ - ⊷ google_web_search + + google_web_search diff --git a/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-a-shell-tool.snap.svg b/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-a-shell-tool.snap.svg index e374b5ab31..1fa93b56ee 100644 --- a/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-a-shell-tool.snap.svg +++ b/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-a-shell-tool.snap.svg @@ -111,7 +111,8 @@ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ - ⊷ run_shell_command + + run_shell_command diff --git a/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-an-empty-slice-following-a-search-tool.snap.svg b/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-an-empty-slice-following-a-search-tool.snap.svg index b9290efcac..68f56c7794 100644 --- a/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-an-empty-slice-following-a-search-tool.snap.svg +++ b/packages/cli/src/ui/utils/__snapshots__/borderStyles-MainContent-tool-group-border-SVG-snapshots-should-render-SVG-snapshot-for-an-empty-slice-following-a-search-tool.snap.svg @@ -111,7 +111,8 @@ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ - ⊷ google_web_search + + google_web_search diff --git a/packages/cli/src/ui/utils/__snapshots__/borderStyles.test.tsx.snap b/packages/cli/src/ui/utils/__snapshots__/borderStyles.test.tsx.snap index fbdc559480..ee871fb258 100644 --- a/packages/cli/src/ui/utils/__snapshots__/borderStyles.test.tsx.snap +++ b/packages/cli/src/ui/utils/__snapshots__/borderStyles.test.tsx.snap @@ -12,7 +12,7 @@ exports[`MainContent tool group border SVG snapshots > should render SVG snapsho ░░░ ░░░░░░░░░ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ google_web_search │ +│ ⊶ google_web_search │ │ │ │ Searching... │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯" @@ -30,7 +30,7 @@ exports[`MainContent tool group border SVG snapshots > should render SVG snapsho ░░░ ░░░░░░░░░ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ run_shell_command │ +│ ⊶ run_shell_command │ │ │ │ Running command... │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯" @@ -48,7 +48,7 @@ exports[`MainContent tool group border SVG snapshots > should render SVG snapsho ░░░ ░░░░░░░░░ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ -│ ⊷ google_web_search │ +│ ⊶ google_web_search │ │ │ │ Searching... │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯"