diff --git a/packages/cli/src/ui/colors.ts b/packages/cli/src/ui/colors.ts index 0825527cf5..c602f587fb 100644 --- a/packages/cli/src/ui/colors.ts +++ b/packages/cli/src/ui/colors.ts @@ -53,6 +53,12 @@ export const Colors: ColorsTheme = { get DarkGray() { return themeManager.getColors().DarkGray; }, + get InputBackground() { + return themeManager.getColors().InputBackground; + }, + get MessageBackground() { + return themeManager.getColors().MessageBackground; + }, get GradientColors() { return themeManager.getActiveTheme().colors.GradientColors; }, diff --git a/packages/cli/src/ui/components/Header.test.tsx b/packages/cli/src/ui/components/Header.test.tsx index 59c04e9938..4d59bf14aa 100644 --- a/packages/cli/src/ui/components/Header.test.tsx +++ b/packages/cli/src/ui/components/Header.test.tsx @@ -96,6 +96,8 @@ describe('
', () => { }, background: { primary: '', + message: '', + input: '', diff: { added: '', removed: '' }, }, border: { diff --git a/packages/cli/src/ui/components/InputPrompt.tsx b/packages/cli/src/ui/components/InputPrompt.tsx index 689df105ca..ad84dd27f6 100644 --- a/packages/cli/src/ui/components/InputPrompt.tsx +++ b/packages/cli/src/ui/components/InputPrompt.tsx @@ -56,10 +56,6 @@ import { } from '../utils/commandUtils.js'; import * as path from 'node:path'; import { SCREEN_READER_USER_PREFIX } from '../textConstants.js'; -import { - DEFAULT_BACKGROUND_OPACITY, - DEFAULT_INPUT_BACKGROUND_OPACITY, -} from '../constants.js'; import { getSafeLowColorBackground } from '../themes/color-utils.js'; import { isLowColorDepth } from '../utils/terminalUtils.js'; import { useShellFocusState } from '../contexts/ShellFocusContext.js'; @@ -226,7 +222,6 @@ export const InputPrompt: React.FC = ({ backgroundShells, backgroundShellHeight, shortcutsHelpVisible, - hintMode, } = useUIState(); const [suppressCompletion, setSuppressCompletion] = useState(false); const { handlePress: registerPlainTabPress, resetCount: resetPlainTabPress } = @@ -1422,14 +1417,8 @@ export const InputPrompt: React.FC = ({ /> ) : null} = ({ text, width }) => { return ( = ({ return ( { it('should interpolate DarkGray when not provided', () => { const theme = createCustomTheme(baseTheme); - // Interpolate between Gray (#cccccc) and Background (#000000) at 0.5 + // Interpolate between Background (#000000) and Gray (#cccccc) at 0.4 // #cccccc is RGB(204, 204, 204) // #000000 is RGB(0, 0, 0) - // Midpoint is RGB(102, 102, 102) which is #666666 - expect(theme.colors.DarkGray).toBe('#666666'); + // Result is RGB(82, 82, 82) which is #525252 + expect(theme.colors.DarkGray).toBe('#525252'); }); it('should use provided DarkGray', () => { @@ -64,8 +64,8 @@ describe('createCustomTheme', () => { }, }; const theme = createCustomTheme(customTheme); - // Should be interpolated between #cccccc and #000000 at 0.5 -> #666666 - expect(theme.colors.DarkGray).toBe('#666666'); + // Should be interpolated between #000000 and #cccccc at 0.4 -> #525252 + expect(theme.colors.DarkGray).toBe('#525252'); }); it('should prefer text.secondary over Gray for interpolation', () => { @@ -81,8 +81,8 @@ describe('createCustomTheme', () => { }, }; const theme = createCustomTheme(customTheme); - // Interpolate between #cccccc and #000000 -> #666666 - expect(theme.colors.DarkGray).toBe('#666666'); + // Interpolate between #000000 and #cccccc -> #525252 + expect(theme.colors.DarkGray).toBe('#525252'); }); }); diff --git a/packages/cli/src/ui/themes/theme.ts b/packages/cli/src/ui/themes/theme.ts index 2e39b1b6c7..c4277cd834 100644 --- a/packages/cli/src/ui/themes/theme.ts +++ b/packages/cli/src/ui/themes/theme.ts @@ -15,7 +15,11 @@ import { } from './color-utils.js'; import type { CustomTheme } from '@google/gemini-cli-core'; -import { DEFAULT_BORDER_OPACITY } from '../constants.js'; +import { + DEFAULT_BACKGROUND_OPACITY, + DEFAULT_INPUT_BACKGROUND_OPACITY, + DEFAULT_BORDER_OPACITY, +} from '../constants.js'; export type { CustomTheme }; @@ -37,6 +41,8 @@ export interface ColorsTheme { Comment: string; Gray: string; DarkGray: string; + InputBackground?: string; + MessageBackground?: string; GradientColors?: string[]; } @@ -55,7 +61,17 @@ export const lightTheme: ColorsTheme = { DiffRemoved: '#FFCCCC', Comment: '#008000', Gray: '#97a0b0', - DarkGray: interpolateColor('#97a0b0', '#FAFAFA', 0.5), + DarkGray: interpolateColor('#FAFAFA', '#97a0b0', DEFAULT_BORDER_OPACITY), + InputBackground: interpolateColor( + '#FAFAFA', + '#97a0b0', + DEFAULT_INPUT_BACKGROUND_OPACITY, + ), + MessageBackground: interpolateColor( + '#FAFAFA', + '#97a0b0', + DEFAULT_BACKGROUND_OPACITY, + ), GradientColors: ['#4796E4', '#847ACE', '#C3677F'], }; @@ -74,7 +90,17 @@ export const darkTheme: ColorsTheme = { DiffRemoved: '#430000', Comment: '#6C7086', Gray: '#6C7086', - DarkGray: interpolateColor('#6C7086', '#1E1E2E', 0.5), + DarkGray: interpolateColor('#1E1E2E', '#6C7086', DEFAULT_BORDER_OPACITY), + InputBackground: interpolateColor( + '#1E1E2E', + '#6C7086', + DEFAULT_INPUT_BACKGROUND_OPACITY, + ), + MessageBackground: interpolateColor( + '#1E1E2E', + '#6C7086', + DEFAULT_BACKGROUND_OPACITY, + ), GradientColors: ['#4796E4', '#847ACE', '#C3677F'], }; @@ -94,6 +120,8 @@ export const ansiTheme: ColorsTheme = { Comment: 'gray', Gray: 'gray', DarkGray: 'gray', + InputBackground: 'black', + MessageBackground: 'black', }; export class Theme { @@ -131,17 +159,27 @@ export class Theme { }, background: { primary: this.colors.Background, + message: + this.colors.MessageBackground ?? + interpolateColor( + this.colors.Background, + this.colors.Gray, + DEFAULT_BACKGROUND_OPACITY, + ), + input: + this.colors.InputBackground ?? + interpolateColor( + this.colors.Background, + this.colors.Gray, + DEFAULT_INPUT_BACKGROUND_OPACITY, + ), diff: { added: this.colors.DiffAdded, removed: this.colors.DiffRemoved, }, }, border: { - default: interpolateColor( - this.colors.Background, - this.colors.Gray, - DEFAULT_BORDER_OPACITY, - ), + default: this.colors.DarkGray, focused: this.colors.AccentBlue, }, ui: { @@ -242,10 +280,20 @@ export function createCustomTheme(customTheme: CustomTheme): Theme { DarkGray: customTheme.DarkGray ?? interpolateColor( - customTheme.text?.secondary ?? customTheme.Gray ?? '', customTheme.background?.primary ?? customTheme.Background ?? '', - 0.5, + customTheme.text?.secondary ?? customTheme.Gray ?? '', + DEFAULT_BORDER_OPACITY, ), + InputBackground: interpolateColor( + customTheme.background?.primary ?? customTheme.Background ?? '', + customTheme.text?.secondary ?? customTheme.Gray ?? '', + DEFAULT_INPUT_BACKGROUND_OPACITY, + ), + MessageBackground: interpolateColor( + customTheme.background?.primary ?? customTheme.Background ?? '', + customTheme.text?.secondary ?? customTheme.Gray ?? '', + DEFAULT_BACKGROUND_OPACITY, + ), GradientColors: customTheme.ui?.gradient ?? customTheme.GradientColors, }; @@ -400,19 +448,15 @@ export function createCustomTheme(customTheme: CustomTheme): Theme { }, background: { primary: customTheme.background?.primary ?? colors.Background, + message: colors.MessageBackground!, + input: colors.InputBackground!, diff: { added: customTheme.background?.diff?.added ?? colors.DiffAdded, removed: customTheme.background?.diff?.removed ?? colors.DiffRemoved, }, }, border: { - default: - customTheme.border?.default ?? - interpolateColor( - colors.Background, - colors.Gray, - DEFAULT_BORDER_OPACITY, - ), + default: colors.DarkGray, focused: customTheme.border?.focused ?? colors.AccentBlue, }, ui: {