diff --git a/packages/cli/src/ui/components/Footer.tsx b/packages/cli/src/ui/components/Footer.tsx index 3e51acd740..6a803a39eb 100644 --- a/packages/cli/src/ui/components/Footer.tsx +++ b/packages/cli/src/ui/components/Footer.tsx @@ -10,7 +10,7 @@ import { theme } from '../semantic-colors.js'; import { shortenPath, tildeifyPath } from '@google/gemini-cli-core'; import { ConsoleSummaryDisplay } from './ConsoleSummaryDisplay.js'; import process from 'node:process'; -import Gradient from 'ink-gradient'; +import { ThemedGradient } from './ThemedGradient.js'; import { MemoryUsageDisplay } from './MemoryUsageDisplay.js'; import { ContextUsageDisplay } from './ContextUsageDisplay.js'; import { DebugProfiler } from './DebugProfiler.js'; @@ -87,12 +87,10 @@ export const Footer: React.FC = () => { )} {!hideCWD && (nightly ? ( - - - {displayPath} - {branchName && ({branchName}*)} - - + + {displayPath} + {branchName && ({branchName}*)} + ) : ( {displayPath} diff --git a/packages/cli/src/ui/components/GradientRegression.test.tsx b/packages/cli/src/ui/components/GradientRegression.test.tsx new file mode 100644 index 0000000000..1b4bc8a4f7 --- /dev/null +++ b/packages/cli/src/ui/components/GradientRegression.test.tsx @@ -0,0 +1,94 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { describe, it, expect, vi } from 'vitest'; +import { renderWithProviders } from '../../test-utils/render.js'; +import { Footer } from './Footer.js'; +import { StatsDisplay } from './StatsDisplay.js'; +import * as SessionContext from '../contexts/SessionContext.js'; +import type { SessionStatsState } from '../contexts/SessionContext.js'; + +// Mock the theme module +vi.mock('../semantic-colors.js', async (importOriginal) => { + const original = + await importOriginal(); + return { + ...original, + theme: { + ...original.theme, + ui: { + ...original.theme.ui, + gradient: [], // Empty array to potentially trigger the crash + }, + }, + }; +}); + +// Mock the context to provide controlled data for testing +vi.mock('../contexts/SessionContext.js', async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + useSessionStats: vi.fn(), + }; +}); + +const mockSessionStats: SessionStatsState = { + sessionId: 'test-session', + sessionStartTime: new Date(), + lastPromptTokenCount: 0, + promptCount: 0, + metrics: { + models: {}, + tools: { + totalCalls: 0, + totalSuccess: 0, + totalFail: 0, + totalDurationMs: 0, + totalDecisions: { accept: 0, reject: 0, modify: 0, auto_accept: 0 }, + byName: {}, + }, + files: { totalLinesAdded: 0, totalLinesRemoved: 0 }, + }, +}; + +const useSessionStatsMock = vi.mocked(SessionContext.useSessionStats); +useSessionStatsMock.mockReturnValue({ + stats: mockSessionStats, + getPromptCount: () => 0, + startNewPrompt: vi.fn(), +}); + +describe('Gradient Crash Regression Tests', () => { + it('