From 6e5c1c709e0b94a8d96167ba68ab4648be51a977 Mon Sep 17 00:00:00 2001 From: "gemini-cli[bot]" Date: Wed, 13 May 2026 18:57:03 +0000 Subject: [PATCH] ui(cli): display small tag for nightly/preview versions This PR implements a more compact version display in the AppHeader, as requested in Issue #21373. Long pre-release version strings (e.g., `0.42.0-nightly.20260428.g59b2dea0e`) are now parsed to show the base version followed by a small bracketed tag (e.g., `v0.42.0 [nightly]`). Changes: - Modified `AppHeader.tsx` to parse version strings for pre-release tags (`nightly`, `preview`, `alpha`, `beta`, `rc`). - Added `AppHeaderVersion.test.tsx` to verify the new rendering logic for various version formats. This makes the header cleaner, especially on narrower terminals where long version strings could cause layout issues. cc @jacob314 @keithguerin labels: bot-fix --- packages/cli/src/ui/components/AppHeader.tsx | 73 ++++++++++++------- .../ui/components/AppHeaderVersion.test.tsx | 51 +++++++++++++ 2 files changed, 96 insertions(+), 28 deletions(-) create mode 100644 packages/cli/src/ui/components/AppHeaderVersion.test.tsx diff --git a/packages/cli/src/ui/components/AppHeader.tsx b/packages/cli/src/ui/components/AppHeader.tsx index 1b3d9b2cfa..e1b4e1ca56 100644 --- a/packages/cli/src/ui/components/AppHeader.tsx +++ b/packages/cli/src/ui/components/AppHeader.tsx @@ -107,36 +107,53 @@ export const AppHeader = ({ version, showDetails = true }: AppHeaderProps) => { ); - const renderMetadata = (isBelow = false) => ( - - {/* Line 1: Gemini CLI vVersion [Updating] */} - - - Gemini CLI - - v{version} - {updateInfo?.isUpdating && ( - - - Updating - - + const renderMetadata = (isBelow = false) => { + // Parse version for a "small tag" if it's a long pre-release string (e.g. nightly) + // Example: 0.42.0-nightly.20260428.g59b2dea0e -> v0.42.0 [nightly] + let displayVersion = version; + let tag = ''; + + const tagMatch = version.match(/^(.+)-(nightly|preview|alpha|beta|rc)(\..+)?$/); + + if (tagMatch) { + displayVersion = tagMatch[1]; + tag = tagMatch[2]; + } + + return ( + + {/* Line 1: Gemini CLI vVersion [tag] [Updating] */} + + + Gemini CLI + + v{displayVersion} + {tag && ( + {`[${tag}]`} + )} + {updateInfo?.isUpdating && ( + + + Updating + + + )} + + + {showDetails && ( + <> + {/* Line 2: Blank */} + + + {/* Lines 3 & 4: User Identity info (Email /auth and Plan /upgrade) */} + {settings.merged.ui.showUserIdentity !== false && ( + + )} + )} - - {showDetails && ( - <> - {/* Line 2: Blank */} - - - {/* Lines 3 & 4: User Identity info (Email /auth and Plan /upgrade) */} - {settings.merged.ui.showUserIdentity !== false && ( - - )} - - )} - - ); + ); + }; const useColumnLayout = !!logoTextArt || isNarrow; diff --git a/packages/cli/src/ui/components/AppHeaderVersion.test.tsx b/packages/cli/src/ui/components/AppHeaderVersion.test.tsx new file mode 100644 index 0000000000..5800e01f1e --- /dev/null +++ b/packages/cli/src/ui/components/AppHeaderVersion.test.tsx @@ -0,0 +1,51 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { renderWithProviders } from '../../test-utils/render.js'; +import { AppHeader } from './AppHeader.js'; +import { describe, it, expect, vi } from 'vitest'; + +// Mock dependencies to avoid complex setup +vi.mock('@google/gemini-cli-core', async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + isAppleTerminal: () => false, + }; +}); + +describe('AppHeader Version Rendering', () => { + it('renders nightly version with a small tag instead of long string', async () => { + const version = '0.42.0-nightly.20260428.g59b2dea0e'; + const { lastFrame } = await renderWithProviders( + + ); + + // Desired: Gemini CLI v0.42.0 [nightly] + expect(lastFrame()).toContain('Gemini CLI v0.42.0 [nightly]'); + expect(lastFrame()).not.toContain(version); + }); + + it('renders preview version with a small tag', async () => { + const version = '0.42.0-preview.1'; + const { lastFrame } = await renderWithProviders( + + ); + + expect(lastFrame()).toContain('Gemini CLI v0.42.0 [preview]'); + expect(lastFrame()).not.toContain(version); + }); + + it('renders standard version without tag', async () => { + const version = '0.42.0'; + const { lastFrame } = await renderWithProviders( + + ); + + expect(lastFrame()).toContain('Gemini CLI v0.42.0'); + expect(lastFrame()).not.toContain('['); + }); +});