feat(cli): Allow custom title in CLI header (#706)

This commit is contained in:
Scott Densmore 2025-06-02 17:09:55 -07:00 committed by GitHub
parent 91fa770196
commit 2ab7e3da71
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 57 additions and 4 deletions

View File

@ -31,6 +31,7 @@ export interface Settings {
mcpServers?: Record<string, MCPServerConfig>; mcpServers?: Record<string, MCPServerConfig>;
showMemoryUsage?: boolean; showMemoryUsage?: boolean;
contextFileName?: string; contextFileName?: string;
title?: string;
// Add other settings here. // Add other settings here.
} }

View File

@ -322,7 +322,7 @@ export const App = ({
key={staticKey} key={staticKey}
items={[ items={[
<Box flexDirection="column" key="header"> <Box flexDirection="column" key="header">
<Header /> <Header title={settings.merged.title} />
<Tips config={config} /> <Tips config={config} />
</Box>, </Box>,
...history.map((h) => ( ...history.map((h) => (

View File

@ -0,0 +1,48 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { render } from 'ink-testing-library';
import { Header } from './Header.js';
import { vi } from 'vitest';
// Mock ink-gradient and ink-big-text as they might have complex rendering
vi.mock('ink-gradient', () => ({
default: vi.fn(({ children }) => children), // Pass through children
}));
import { Text } from 'ink'; // Import the actual Text component from Ink
vi.mock('ink-big-text', () => ({
default: vi.fn(({ text }) => <Text>{text}</Text>), // Use Ink's Text component
}));
describe('<Header />', () => {
it('should render with the default title "GEMINI" when no title prop is provided', () => {
const { lastFrame } = render(<Header />);
const output = lastFrame();
// Check if the output contains the default text "GEMINI"
// The actual output will be simple text due to mocking
expect(output).toContain('GEMINI');
});
it('should render with a custom title when the title prop is provided', () => {
const customTitle = 'My Custom CLI';
const { lastFrame } = render(<Header title={customTitle} />);
const output = lastFrame();
// Check if the output contains the custom title
expect(output).toContain(customTitle);
});
it('should render with an empty title if an empty string is provided', () => {
const customTitle = '';
const { lastFrame } = render(<Header title={customTitle} />);
const output = lastFrame();
// Depending on how BigText handles empty strings,
// it might render nothing or a specific representation.
// For this test, we'll assume it renders the empty string.
expect(output).toContain(''); // or check for a specific structure if BigText behaves differently
});
});

View File

@ -10,15 +10,19 @@ import Gradient from 'ink-gradient';
import BigText from 'ink-big-text'; import BigText from 'ink-big-text';
import { Colors } from '../colors.js'; import { Colors } from '../colors.js';
export const Header: React.FC = () => ( interface HeaderProps {
title?: string;
}
export const Header: React.FC<HeaderProps> = ({ title = 'GEMINI' }) => (
<> <>
<Box alignItems="flex-start"> <Box alignItems="flex-start">
{Colors.GradientColors ? ( {Colors.GradientColors ? (
<Gradient colors={Colors.GradientColors}> <Gradient colors={Colors.GradientColors}>
<BigText text="GEMINI" letterSpacing={0} space={false} /> <BigText text={title} letterSpacing={0} space={false} />
</Gradient> </Gradient>
) : ( ) : (
<BigText text="GEMINI" letterSpacing={0} space={false} /> <BigText text={title} letterSpacing={0} space={false} />
)} )}
</Box> </Box>
</> </>