fix(cli): fix crash on startup in NO_COLOR mode (#13343) due to ungua… (#13352)

This commit is contained in:
avilladsen
2025-11-18 20:18:18 -08:00
committed by GitHub
parent e8d0e0d342
commit 1e8ae5b9d7
3 changed files with 53 additions and 24 deletions

View File

@@ -5,8 +5,7 @@
*/
import { Box, Text } from 'ink';
import Gradient from 'ink-gradient';
import { theme } from '../semantic-colors.js';
import { ThemedGradient } from './ThemedGradient.js';
interface BannerProps {
bannerText: string;
@@ -14,20 +13,17 @@ interface BannerProps {
width: number;
}
export const Banner = ({ bannerText, color, width }: BannerProps) => {
const gradient = theme.ui.gradient;
return (
<Box
flexDirection="column"
borderStyle="round"
borderColor={color}
width={width}
paddingLeft={1}
paddingRight={1}
>
<Gradient colors={gradient}>
<Text>{bannerText}</Text>
</Gradient>
</Box>
);
};
export const Banner = ({ bannerText, color, width }: BannerProps) => (
<Box
flexDirection="column"
borderStyle="round"
borderColor={color}
width={width}
paddingLeft={1}
paddingRight={1}
>
<ThemedGradient>
<Text>{bannerText}</Text>
</ThemedGradient>
</Box>
);

View File

@@ -6,10 +6,13 @@
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';
import { Banner } from './Banner.js';
import { Footer } from './Footer.js';
import { Header } from './Header.js';
import { ModelDialog } from './ModelDialog.js';
import { StatsDisplay } from './StatsDisplay.js';
// Mock the theme module
vi.mock('../semantic-colors.js', async (importOriginal) => {
@@ -63,6 +66,36 @@ useSessionStatsMock.mockReturnValue({
});
describe('Gradient Crash Regression Tests', () => {
it('<Header /> should not crash when theme.ui.gradient is empty', () => {
const { lastFrame } = renderWithProviders(
<Header version="1.0.0" nightly={false} />,
{
width: 120,
},
);
expect(lastFrame()).toBeDefined();
});
it('<ModelDialog /> should not crash when theme.ui.gradient is empty', () => {
const { lastFrame } = renderWithProviders(
<ModelDialog onClose={() => {}} />,
{
width: 120,
},
);
expect(lastFrame()).toBeDefined();
});
it('<Banner /> should not crash when theme.ui.gradient is empty', () => {
const { lastFrame } = renderWithProviders(
<Banner bannerText="Test Banner" color="blue" width={80} />,
{
width: 120,
},
);
expect(lastFrame()).toBeDefined();
});
it('<Footer /> should not crash when theme.ui.gradient has only one color (or empty) and nightly is true', () => {
const { lastFrame } = renderWithProviders(<Footer />, {
width: 120,

View File

@@ -23,7 +23,7 @@ import { useKeypress } from '../hooks/useKeypress.js';
import { theme } from '../semantic-colors.js';
import { DescriptiveRadioButtonSelect } from './shared/DescriptiveRadioButtonSelect.js';
import { ConfigContext } from '../contexts/ConfigContext.js';
import Gradient from 'ink-gradient';
import { ThemedGradient } from './ThemedGradient.js';
interface ModelDialogProps {
onClose: () => void;
@@ -115,9 +115,9 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
<Text bold>Select Model</Text>
<Box marginTop={1} marginBottom={1} flexDirection="column">
<Gradient colors={theme.ui.gradient}>
<ThemedGradient>
<Text>{header}</Text>
</Gradient>
</ThemedGradient>
<Text>{subheader}</Text>
</Box>