From 0f5bcfad1ed9eda55d5230eea920efef9a6987a0 Mon Sep 17 00:00:00 2001 From: jacob314 Date: Fri, 9 Jan 2026 08:44:16 -0800 Subject: [PATCH] Compact mode. --- packages/cli/src/config/settingsSchema.ts | 4 +- .../cli/src/ui/components/AppHeader.test.tsx | 35 +++++++++++++++- packages/cli/src/ui/components/AppHeader.tsx | 42 ++++++++++++------- .../cli/src/ui/components/Header.test.tsx | 10 ++--- packages/cli/src/ui/components/Header.tsx | 20 +-------- packages/cli/src/ui/components/Tips.tsx | 2 +- ...ternateBufferQuittingDisplay.test.tsx.snap | 20 +++------ .../__snapshots__/AppHeader.test.tsx.snap | 33 +++++++-------- 8 files changed, 92 insertions(+), 74 deletions(-) diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts index 3ae9806340..296ade5ce4 100644 --- a/packages/cli/src/config/settingsSchema.ts +++ b/packages/cli/src/config/settingsSchema.ts @@ -528,8 +528,8 @@ const SETTINGS_SCHEMA = { type: 'boolean', label: 'Compact UI', category: 'UI', - requiresRestart: false, - default: false, + requiresRestart: true, + default: true, description: 'Enable a more compact UI layout.', showInDialog: true, }, diff --git a/packages/cli/src/ui/components/AppHeader.test.tsx b/packages/cli/src/ui/components/AppHeader.test.tsx index 74388c816a..3b1283a03b 100644 --- a/packages/cli/src/ui/components/AppHeader.test.tsx +++ b/packages/cli/src/ui/components/AppHeader.test.tsx @@ -4,7 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { renderWithProviders } from '../../test-utils/render.js'; +import { + renderWithProviders, + createMockSettings, +} from '../../test-utils/render.js'; import { AppHeader } from './AppHeader.js'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import { makeFakeConfig } from '@google/gemini-cli-core'; @@ -200,4 +203,34 @@ describe('', () => { expect(lastFrame()).not.toContain('First line\\nSecond line'); unmount(); }); + + it('should render in compact mode', () => { + const mockConfig = makeFakeConfig(); + const uiState = { + history: [], + bannerData: { + defaultText: '', + warningText: '', + }, + nightly: true, + }; + + const { lastFrame, unmount } = renderWithProviders( + , + { + config: mockConfig, + uiState, + settings: createMockSettings({ + ui: { + compact: true, + }, + }), + }, + ); + + expect(lastFrame()).toContain('Tips for getting started:'); + expect(lastFrame()).toContain('v1.0.0'); + expect(lastFrame()).toMatchSnapshot(); + unmount(); + }); }); diff --git a/packages/cli/src/ui/components/AppHeader.tsx b/packages/cli/src/ui/components/AppHeader.tsx index c404c0e9f9..1ed1b9e3da 100644 --- a/packages/cli/src/ui/components/AppHeader.tsx +++ b/packages/cli/src/ui/components/AppHeader.tsx @@ -21,25 +21,39 @@ export const AppHeader = ({ version }: AppHeaderProps) => { const settings = useSettings(); const config = useConfig(); const { nightly, mainAreaWidth, bannerData, bannerVisible } = useUIState(); + const compact = settings.merged.ui?.compact; const { bannerText } = useBanner(bannerData, config); - return ( + const showHeader = !( + settings.merged.ui?.hideBanner || config.getScreenReader() + ); + const showTips = !(settings.merged.ui?.hideTips || config.getScreenReader()); + + const headerContent = showHeader && ( - {!(settings.merged.ui?.hideBanner || config.getScreenReader()) && ( - <> -
- {bannerVisible && bannerText && ( - - )} - +
+ {bannerVisible && bannerText && ( + )} - {!(settings.merged.ui?.hideTips || config.getScreenReader()) && ( - + + ); + + const tipsContent = showTips && ; + + return ( + + {headerContent} + {tipsContent && ( + {tipsContent} )} ); diff --git a/packages/cli/src/ui/components/Header.test.tsx b/packages/cli/src/ui/components/Header.test.tsx index 0c4c76c51b..1461e2b099 100644 --- a/packages/cli/src/ui/components/Header.test.tsx +++ b/packages/cli/src/ui/components/Header.test.tsx @@ -59,7 +59,7 @@ describe('
', () => { renderWithProviders(
); expect(Text).toHaveBeenCalledWith( expect.objectContaining({ - children: longAsciiLogo, + children: longAsciiLogo.trim(), }), undefined, ); @@ -75,7 +75,7 @@ describe('
', () => { renderWithProviders(
); expect(Text).toHaveBeenCalledWith( expect.objectContaining({ - children: longAsciiLogoIde, + children: longAsciiLogoIde.trim(), }), undefined, ); @@ -138,13 +138,13 @@ describe('
', () => { }); expect(Text).toHaveBeenCalledWith( expect.objectContaining({ - children: longAsciiLogoCompact, + children: longAsciiLogoCompact.trim(), }), undefined, ); }); - it('renders the version to the right in compact mode when nightly is true', () => { + it('renders the version under the logo in compact mode when nightly is true', () => { vi.spyOn(useTerminalSize, 'useTerminalSize').mockReturnValue({ columns: 120, rows: 20, @@ -160,7 +160,7 @@ describe('
', () => { }, ); expect(lastFrame()).toContain('v1.0.0'); - // In compact mode, logo and version are in the same Box with flexDirection="row" + // In compact mode, logo and version are in the same Box with flexDirection="column" }); it('renders with no gradient when theme.ui.gradient is undefined', async () => { diff --git a/packages/cli/src/ui/components/Header.tsx b/packages/cli/src/ui/components/Header.tsx index f8dfce335e..867e17314e 100644 --- a/packages/cli/src/ui/components/Header.tsx +++ b/packages/cli/src/ui/components/Header.tsx @@ -70,27 +70,11 @@ export const Header: React.FC = ({ displayTitle = tinyLogo; } + displayTitle = displayTitle.trim(); + const artWidth = getAsciiArtWidth(displayTitle); const title = useSnowfall(displayTitle); - if (compact) { - return ( - - {title} - {nightly && ( - - v{version} - - )} - - ); - } - return ( = ({ config }) => { const geminiMdFileCount = config.getGeminiMdFileCount(); return ( - Tips for getting started: + Tips for getting started: 1. Ask questions, edit files, or run commands. diff --git a/packages/cli/src/ui/components/__snapshots__/AlternateBufferQuittingDisplay.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/AlternateBufferQuittingDisplay.test.tsx.snap index 75debcab74..a51defd97d 100644 --- a/packages/cli/src/ui/components/__snapshots__/AlternateBufferQuittingDisplay.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/AlternateBufferQuittingDisplay.test.tsx.snap @@ -1,8 +1,7 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`AlternateBufferQuittingDisplay > renders with active and pending tool messages > with_history_and_pending 1`] = ` -" - ███ █████████ +"███ █████████ ░░░███ ███░░░░░███ ░░░███ ███ ░░░ ░░░███░███ @@ -10,7 +9,6 @@ exports[`AlternateBufferQuittingDisplay > renders with active and pending tool m ███░ ░░███ ░░███ ███░ ░░█████████ ░░░ ░░░░░░░░░ - Tips for getting started: 1. Ask questions, edit files, or run commands. 2. Be specific for the best results. @@ -31,8 +29,7 @@ Tips for getting started: `; exports[`AlternateBufferQuittingDisplay > renders with empty history and no pending items > empty 1`] = ` -" - ███ █████████ +"███ █████████ ░░░███ ███░░░░░███ ░░░███ ███ ░░░ ░░░███░███ @@ -40,7 +37,6 @@ exports[`AlternateBufferQuittingDisplay > renders with empty history and no pend ███░ ░░███ ░░███ ███░ ░░█████████ ░░░ ░░░░░░░░░ - Tips for getting started: 1. Ask questions, edit files, or run commands. 2. Be specific for the best results. @@ -49,8 +45,7 @@ Tips for getting started: `; exports[`AlternateBufferQuittingDisplay > renders with history but no pending items > with_history_no_pending 1`] = ` -" - ███ █████████ +"███ █████████ ░░░███ ███░░░░░███ ░░░███ ███ ░░░ ░░░███░███ @@ -58,7 +53,6 @@ exports[`AlternateBufferQuittingDisplay > renders with history but no pending it ███░ ░░███ ░░███ ███░ ░░█████████ ░░░ ░░░░░░░░░ - Tips for getting started: 1. Ask questions, edit files, or run commands. 2. Be specific for the best results. @@ -75,8 +69,7 @@ Tips for getting started: `; exports[`AlternateBufferQuittingDisplay > renders with pending items but no history > with_pending_no_history 1`] = ` -" - ███ █████████ +"███ █████████ ░░░███ ███░░░░░███ ░░░███ ███ ░░░ ░░░███░███ @@ -84,7 +77,6 @@ exports[`AlternateBufferQuittingDisplay > renders with pending items but no hist ███░ ░░███ ░░███ ███░ ░░█████████ ░░░ ░░░░░░░░░ - Tips for getting started: 1. Ask questions, edit files, or run commands. 2. Be specific for the best results. @@ -97,8 +89,7 @@ Tips for getting started: `; exports[`AlternateBufferQuittingDisplay > renders with user and gemini messages > with_user_gemini_messages 1`] = ` -" - ███ █████████ +"███ █████████ ░░░███ ███░░░░░███ ░░░███ ███ ░░░ ░░░███░███ @@ -106,7 +97,6 @@ exports[`AlternateBufferQuittingDisplay > renders with user and gemini messages ███░ ░░███ ░░███ ███░ ░░█████████ ░░░ ░░░░░░░░░ - Tips for getting started: 1. Ask questions, edit files, or run commands. 2. Be specific for the best results. diff --git a/packages/cli/src/ui/components/__snapshots__/AppHeader.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/AppHeader.test.tsx.snap index 6da8b523f2..c89430d3db 100644 --- a/packages/cli/src/ui/components/__snapshots__/AppHeader.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/AppHeader.test.tsx.snap @@ -1,8 +1,7 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[` > should not render the banner when no flags are set 1`] = ` -" - ███ █████████ +"███ █████████ ░░░███ ███░░░░░███ ░░░███ ███ ░░░ ░░░███░███ @@ -10,7 +9,6 @@ exports[` > should not render the banner when no flags are set 1`] ███░ ░░███ ░░███ ███░ ░░█████████ ░░░ ░░░░░░░░░ - Tips for getting started: 1. Ask questions, edit files, or run commands. 2. Be specific for the best results. @@ -19,8 +17,7 @@ Tips for getting started: `; exports[` > should not render the banner when previewFeatures is enabled 1`] = ` -" - ███ █████████ +"███ █████████ ░░░███ ███░░░░░███ ░░░███ ███ ░░░ ░░░███░███ @@ -28,7 +25,6 @@ exports[` > should not render the banner when previewFeatures is en ███░ ░░███ ░░███ ███░ ░░█████████ ░░░ ░░░░░░░░░ - Tips for getting started: 1. Ask questions, edit files, or run commands. 2. Be specific for the best results. @@ -37,8 +33,7 @@ Tips for getting started: `; exports[` > should not render the default banner if shown count is 5 or more 1`] = ` -" - ███ █████████ +"███ █████████ ░░░███ ███░░░░░███ ░░░███ ███ ░░░ ░░░███░███ @@ -46,7 +41,6 @@ exports[` > should not render the default banner if shown count is ███░ ░░███ ░░███ ███░ ░░█████████ ░░░ ░░░░░░░░░ - Tips for getting started: 1. Ask questions, edit files, or run commands. 2. Be specific for the best results. @@ -54,9 +48,17 @@ Tips for getting started: 4. /help for more information." `; -exports[` > should render the banner when previewFeatures is disabled 1`] = ` +exports[` > should render in compact mode 1`] = ` " - ███ █████████ +▝▜▄ ▗█▀▀▜▙▝█▛▀▀▌▜██▖▟██▘▜█▘▜██▖▝█▛▝█▛ Tips for getting started: + ▝▜▄ █▌ █▙▟ ▐█▝█▛▐█ ▐█ ▐█▝█▖█▌ █▌ 1. Ask questions, edit files, or run commands. + ▗▟▀ ▜▙ ▝█▛ █▌▝ ▖▐█ ▐█ ▐█ ▐█ ▝██▌ █▌ 2. Be specific for the best results. +▝▀ ▀▀▀▀▘▝▀▀▀▀▘▀▀▘ ▀▀▘▀▀▘▀▀▘ ▝▀▀▝▀▀ 3. Create GEMINI.md files to customize your interactions with Gemini. + v1.0.0 4. /help for more information." +`; + +exports[` > should render the banner when previewFeatures is disabled 1`] = ` +"███ █████████ ░░░███ ███░░░░░███ ░░░███ ███ ░░░ ░░░███░███ @@ -64,7 +66,6 @@ exports[` > should render the banner when previewFeatures is disabl ███░ ░░███ ░░███ ███░ ░░█████████ ░░░ ░░░░░░░░░ - ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ This is the default banner │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ @@ -76,8 +77,7 @@ Tips for getting started: `; exports[` > should render the banner with default text 1`] = ` -" - ███ █████████ +"███ █████████ ░░░███ ███░░░░░███ ░░░███ ███ ░░░ ░░░███░███ @@ -85,7 +85,6 @@ exports[` > should render the banner with default text 1`] = ` ███░ ░░███ ░░███ ███░ ░░█████████ ░░░ ░░░░░░░░░ - ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ This is the default banner │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ @@ -97,8 +96,7 @@ Tips for getting started: `; exports[` > should render the banner with warning text 1`] = ` -" - ███ █████████ +"███ █████████ ░░░███ ███░░░░░███ ░░░███ ███ ░░░ ░░░███░███ @@ -106,7 +104,6 @@ exports[` > should render the banner with warning text 1`] = ` ███░ ░░███ ░░███ ███░ ░░█████████ ░░░ ░░░░░░░░░ - ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ There are capacity issues │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯