diff --git a/packages/cli/src/ui/hooks/useTerminalTheme.ts b/packages/cli/src/ui/hooks/useTerminalTheme.ts index e7e4826ecc..93b9bb48bc 100644 --- a/packages/cli/src/ui/hooks/useTerminalTheme.ts +++ b/packages/cli/src/ui/hooks/useTerminalTheme.ts @@ -6,7 +6,7 @@ import { useEffect } from 'react'; import { useStdout } from 'ink'; -import { parseX11Rgb, getLuminance } from '../themes/color-utils.js'; +import { getLuminance, parseColor } from '../themes/color-utils.js'; import { themeManager, DEFAULT_THEME } from '../themes/theme-manager.js'; import { DefaultLight } from '../themes/default-light.js'; import { useSettings } from '../contexts/SettingsContext.js'; @@ -47,7 +47,7 @@ export function useTerminalTheme( ); if (!match) return; - const hexColor = parseX11Rgb(match[1], match[2], match[3]); + const hexColor = parseColor(match[1], match[2], match[3]); const luminance = getLuminance(hexColor); config.setTerminalBackground(hexColor); diff --git a/packages/cli/src/ui/themes/color-utils.test.ts b/packages/cli/src/ui/themes/color-utils.test.ts index 0c00e5abe2..5e40abc9b0 100644 --- a/packages/cli/src/ui/themes/color-utils.test.ts +++ b/packages/cli/src/ui/themes/color-utils.test.ts @@ -12,8 +12,8 @@ import { CSS_NAME_TO_HEX_MAP, INK_SUPPORTED_NAMES, getThemeTypeFromBackgroundColor, - parseX11Rgb, getLuminance, + parseColor, } from './color-utils.js'; describe('Color Utils', () => { @@ -310,33 +310,33 @@ describe('Color Utils', () => { }); }); - describe('parseX11Rgb', () => { + describe('parseColor', () => { it('should parse 1-digit components', () => { // F/F/F => #ffffff - expect(parseX11Rgb('f', 'f', 'f')).toBe('#ffffff'); + expect(parseColor('f', 'f', 'f')).toBe('#ffffff'); // 0/0/0 => #000000 - expect(parseX11Rgb('0', '0', '0')).toBe('#000000'); + expect(parseColor('0', '0', '0')).toBe('#000000'); }); it('should parse 2-digit components', () => { // ff/ff/ff => #ffffff - expect(parseX11Rgb('ff', 'ff', 'ff')).toBe('#ffffff'); + expect(parseColor('ff', 'ff', 'ff')).toBe('#ffffff'); // 80/80/80 => #808080 - expect(parseX11Rgb('80', '80', '80')).toBe('#808080'); + expect(parseColor('80', '80', '80')).toBe('#808080'); }); it('should parse 4-digit components (standard X11)', () => { // ffff/ffff/ffff => #ffffff (65535/65535 * 255 = 255) - expect(parseX11Rgb('ffff', 'ffff', 'ffff')).toBe('#ffffff'); + expect(parseColor('ffff', 'ffff', 'ffff')).toBe('#ffffff'); // 0000/0000/0000 => #000000 - expect(parseX11Rgb('0000', '0000', '0000')).toBe('#000000'); + expect(parseColor('0000', '0000', '0000')).toBe('#000000'); // 7fff/7fff/7fff => approx #7f7f7f (32767/65535 * 255 = 127.498... -> 127 -> 7f) - expect(parseX11Rgb('7fff', '7fff', '7fff')).toBe('#7f7f7f'); + expect(parseColor('7fff', '7fff', '7fff')).toBe('#7f7f7f'); }); it('should handle mixed case', () => { - expect(parseX11Rgb('FFFF', 'FFFF', 'FFFF')).toBe('#ffffff'); - expect(parseX11Rgb('Ffff', 'fFFF', 'ffFF')).toBe('#ffffff'); + expect(parseColor('FFFF', 'FFFF', 'FFFF')).toBe('#ffffff'); + expect(parseColor('Ffff', 'fFFF', 'ffFF')).toBe('#ffffff'); }); }); }); diff --git a/packages/cli/src/ui/themes/color-utils.ts b/packages/cli/src/ui/themes/color-utils.ts index 3d9f007f95..fed63b93ef 100644 --- a/packages/cli/src/ui/themes/color-utils.ts +++ b/packages/cli/src/ui/themes/color-utils.ts @@ -318,7 +318,7 @@ export function getLuminance(backgroundColor: string): number { * @param bHex Blue component as hex string * @returns Hex color string (e.g. #RRGGBB) */ -export function parseX11Rgb(rHex: string, gHex: string, bHex: string): string { +export function parseColor(rHex: string, gHex: string, bHex: string): string { const parseComponent = (hex: string) => { const val = parseInt(hex, 16); if (hex.length === 1) return (val / 15) * 255; diff --git a/packages/cli/src/ui/utils/terminalCapabilityManager.ts b/packages/cli/src/ui/utils/terminalCapabilityManager.ts index b24647abe5..5b2b20a428 100644 --- a/packages/cli/src/ui/utils/terminalCapabilityManager.ts +++ b/packages/cli/src/ui/utils/terminalCapabilityManager.ts @@ -14,6 +14,7 @@ import { enableBracketedPasteMode, disableBracketedPasteMode, } from '@google/gemini-cli-core'; +import { parseColor } from '../themes/color-utils.js'; export type TerminalBackgroundColor = string | undefined; @@ -129,7 +130,7 @@ export class TerminalCapabilityManager { const match = buffer.match(TerminalCapabilityManager.OSC_11_REGEX); if (match) { bgReceived = true; - this.terminalBackgroundColor = this.parseColor( + this.terminalBackgroundColor = parseColor( match[1], match[2], match[3], @@ -234,24 +235,6 @@ export class TerminalCapabilityManager { isKittyProtocolEnabled(): boolean { return this.kittyEnabled; } - - private parseColor(rHex: string, gHex: string, bHex: string): string { - const parseComponent = (hex: string) => { - const val = parseInt(hex, 16); - if (hex.length === 1) return (val / 15) * 255; - if (hex.length === 2) return val; - if (hex.length === 3) return (val / 4095) * 255; - if (hex.length === 4) return (val / 65535) * 255; - return val; - }; - - const r = parseComponent(rHex); - const g = parseComponent(gHex); - const b = parseComponent(bHex); - - const toHex = (c: number) => Math.round(c).toString(16).padStart(2, '0'); - return `#${toHex(r)}${toHex(g)}${toHex(b)}`; - } } export const terminalCapabilityManager =