diff --git a/packages/cli/src/ui/IdeIntegrationNudge.tsx b/packages/cli/src/ui/IdeIntegrationNudge.tsx
index d4645d6379..7584e35a8f 100644
--- a/packages/cli/src/ui/IdeIntegrationNudge.tsx
+++ b/packages/cli/src/ui/IdeIntegrationNudge.tsx
@@ -10,6 +10,7 @@ import { Box, Text } from 'ink';
import type { RadioSelectItem } from './components/shared/RadioButtonSelect.js';
import { RadioButtonSelect } from './components/shared/RadioButtonSelect.js';
import { useKeypress } from './hooks/useKeypress.js';
+import { theme } from './semantic-colors.js';
export type IdeIntegrationNudgeResult = {
userSelection: 'yes' | 'no' | 'dismiss';
@@ -79,17 +80,17 @@ export function IdeIntegrationNudge({
- {'> '}
+ {'> '}
{`Do you want to connect ${ideName ?? 'your editor'} to Gemini CLI?`}
- {installText}
+ {installText}
diff --git a/packages/cli/src/ui/auth/AuthDialog.tsx b/packages/cli/src/ui/auth/AuthDialog.tsx
index 5a3a01ca56..7af7cb9b1c 100644
--- a/packages/cli/src/ui/auth/AuthDialog.tsx
+++ b/packages/cli/src/ui/auth/AuthDialog.tsx
@@ -7,7 +7,7 @@
import type React from 'react';
import { useCallback } from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { RadioButtonSelect } from '../components/shared/RadioButtonSelect.js';
import type { LoadedSettings } from '../../config/settings.js';
import { SettingScope } from '../../config/settings.js';
@@ -149,14 +149,16 @@ Logging in with Google... Please restart Gemini CLI to continue.
return (
Get started
- How would you like to authenticate for this project?
+
+ How would you like to authenticate for this project?
+
{authError && (
- {authError}
+ {authError}
)}
- (Use Enter to select)
+ (Use Enter to select)
- Terms of Services and Privacy Notice for Gemini CLI
+
+ Terms of Services and Privacy Notice for Gemini CLI
+
-
+
{
'https://github.com/google-gemini/gemini-cli/blob/main/docs/tos-privacy.md'
}
diff --git a/packages/cli/src/ui/auth/AuthInProgress.tsx b/packages/cli/src/ui/auth/AuthInProgress.tsx
index ce8b54435d..6270ecf1fb 100644
--- a/packages/cli/src/ui/auth/AuthInProgress.tsx
+++ b/packages/cli/src/ui/auth/AuthInProgress.tsx
@@ -8,7 +8,7 @@ import type React from 'react';
import { useState, useEffect } from 'react';
import { Box, Text } from 'ink';
import Spinner from 'ink-spinner';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { useKeypress } from '../hooks/useKeypress.js';
interface AuthInProgressProps {
@@ -41,13 +41,13 @@ export function AuthInProgress({
return (
{timedOut ? (
-
+
Authentication timed out. Please try again.
) : (
diff --git a/packages/cli/src/ui/commands/chatCommand.ts b/packages/cli/src/ui/commands/chatCommand.ts
index 216baaac9c..5ef188981c 100644
--- a/packages/cli/src/ui/commands/chatCommand.ts
+++ b/packages/cli/src/ui/commands/chatCommand.ts
@@ -7,7 +7,7 @@
import * as fsPromises from 'node:fs/promises';
import React from 'react';
import { Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import type {
CommandContext,
SlashCommand,
@@ -126,7 +126,7 @@ const saveCommand: SlashCommand = {
Text,
null,
'A checkpoint with the tag ',
- React.createElement(Text, { color: Colors.AccentPurple }, tag),
+ React.createElement(Text, { color: theme.text.accent }, tag),
' already exists. Do you want to overwrite it?',
),
originalInvocation: {
diff --git a/packages/cli/src/ui/components/AboutBox.tsx b/packages/cli/src/ui/components/AboutBox.tsx
index 1d58495ded..129ed30351 100644
--- a/packages/cli/src/ui/components/AboutBox.tsx
+++ b/packages/cli/src/ui/components/AboutBox.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { GIT_COMMIT_INFO } from '../../generated/git-commit.js';
interface AboutBoxProps {
@@ -30,77 +30,77 @@ export const AboutBox: React.FC = ({
}) => (
-
+
About Gemini CLI
-
+
CLI Version
- {cliVersion}
+ {cliVersion}
{GIT_COMMIT_INFO && !['N/A'].includes(GIT_COMMIT_INFO) && (
-
+
Git Commit
- {GIT_COMMIT_INFO}
+ {GIT_COMMIT_INFO}
)}
-
+
Model
- {modelVersion}
+ {modelVersion}
-
+
Sandbox
- {sandboxEnv}
+ {sandboxEnv}
-
+
OS
- {osVersion}
+ {osVersion}
-
+
Auth Method
-
+
{selectedAuthType.startsWith('oauth') ? 'OAuth' : selectedAuthType}
@@ -108,24 +108,24 @@ export const AboutBox: React.FC = ({
{gcpProject && (
-
+
GCP Project
- {gcpProject}
+ {gcpProject}
)}
{ideClient && (
-
+
IDE Client
- {ideClient}
+ {ideClient}
)}
diff --git a/packages/cli/src/ui/components/AutoAcceptIndicator.tsx b/packages/cli/src/ui/components/AutoAcceptIndicator.tsx
index 273634de61..2fbc20bfdd 100644
--- a/packages/cli/src/ui/components/AutoAcceptIndicator.tsx
+++ b/packages/cli/src/ui/components/AutoAcceptIndicator.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { ApprovalMode } from '@google/gemini-cli-core';
interface AutoAcceptIndicatorProps {
@@ -22,12 +22,12 @@ export const AutoAcceptIndicator: React.FC = ({
switch (approvalMode) {
case ApprovalMode.AUTO_EDIT:
- textColor = Colors.AccentGreen;
+ textColor = theme.status.success;
textContent = 'accepting edits';
subText = ' (shift + tab to toggle)';
break;
case ApprovalMode.YOLO:
- textColor = Colors.AccentRed;
+ textColor = theme.status.error;
textContent = 'YOLO mode';
subText = ' (ctrl + y to toggle)';
break;
@@ -40,7 +40,7 @@ export const AutoAcceptIndicator: React.FC = ({
{textContent}
- {subText && {subText}}
+ {subText && {subText}}
);
diff --git a/packages/cli/src/ui/components/Composer.tsx b/packages/cli/src/ui/components/Composer.tsx
index fa5322e4ae..07d9766029 100644
--- a/packages/cli/src/ui/components/Composer.tsx
+++ b/packages/cli/src/ui/components/Composer.tsx
@@ -14,7 +14,7 @@ import { InputPrompt } from './InputPrompt.js';
import { Footer, type FooterProps } from './Footer.js';
import { ShowMoreLines } from './ShowMoreLines.js';
import { OverflowProvider } from '../contexts/OverflowContext.js';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { isNarrowWidth } from '../utils/isNarrowWidth.js';
import { useUIState } from '../contexts/UIStateContext.js';
import { useUIActions } from '../contexts/UIActionsContext.js';
@@ -112,14 +112,18 @@ export const Composer = () => {
>
{process.env['GEMINI_SYSTEM_MD'] && (
- |⌐■_■|
+ |⌐■_■|
)}
{uiState.ctrlCPressedOnce ? (
- Press Ctrl+C again to exit.
+
+ Press Ctrl+C again to exit.
+
) : uiState.ctrlDPressedOnce ? (
- Press Ctrl+D again to exit.
+
+ Press Ctrl+D again to exit.
+
) : uiState.showEscapePrompt ? (
- Press Esc again to clear.
+ Press Esc again to clear.
) : (
!settings.merged.ui?.hideContextSummary && (
{
const config = useConfig();
@@ -39,7 +40,7 @@ export const ConfigInitDisplay = () => {
return (
- {message}
+ {message}
);
diff --git a/packages/cli/src/ui/components/ConsoleSummaryDisplay.tsx b/packages/cli/src/ui/components/ConsoleSummaryDisplay.tsx
index 68700f2704..2f2f8a2a75 100644
--- a/packages/cli/src/ui/components/ConsoleSummaryDisplay.tsx
+++ b/packages/cli/src/ui/components/ConsoleSummaryDisplay.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
interface ConsoleSummaryDisplayProps {
errorCount: number;
@@ -25,9 +25,9 @@ export const ConsoleSummaryDisplay: React.FC = ({
return (
{errorCount > 0 && (
-
+
{errorIcon} {errorCount} error{errorCount > 1 ? 's' : ''}{' '}
- (ctrl+o for details)
+ (ctrl+o for details)
)}
diff --git a/packages/cli/src/ui/components/ContextSummaryDisplay.tsx b/packages/cli/src/ui/components/ContextSummaryDisplay.tsx
index b3a9286b12..388bd44edc 100644
--- a/packages/cli/src/ui/components/ContextSummaryDisplay.tsx
+++ b/packages/cli/src/ui/components/ContextSummaryDisplay.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { type IdeContext, type MCPServerConfig } from '@google/gemini-cli-core';
import { useTerminalSize } from '../hooks/useTerminalSize.js';
import { isNarrowWidth } from '../utils/isNarrowWidth.js';
@@ -99,9 +99,9 @@ export const ContextSummaryDisplay: React.FC = ({
if (isNarrow) {
return (
- Using:
+ Using:
{summaryParts.map((part, index) => (
-
+
{' '}- {part}
))}
@@ -111,7 +111,9 @@ export const ContextSummaryDisplay: React.FC = ({
return (
- Using: {summaryParts.join(' | ')}
+
+ Using: {summaryParts.join(' | ')}
+
);
};
diff --git a/packages/cli/src/ui/components/ContextUsageDisplay.tsx b/packages/cli/src/ui/components/ContextUsageDisplay.tsx
index 037be33398..d7d8c063f0 100644
--- a/packages/cli/src/ui/components/ContextUsageDisplay.tsx
+++ b/packages/cli/src/ui/components/ContextUsageDisplay.tsx
@@ -5,7 +5,7 @@
*/
import { Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { tokenLimit } from '@google/gemini-cli-core';
export const ContextUsageDisplay = ({
@@ -18,7 +18,7 @@ export const ContextUsageDisplay = ({
const percentage = promptTokenCount / tokenLimit(model);
return (
-
+
({((1 - percentage) * 100).toFixed(0)}% context left)
);
diff --git a/packages/cli/src/ui/components/DebugProfiler.tsx b/packages/cli/src/ui/components/DebugProfiler.tsx
index 22c16cfb22..4a4d6b4c17 100644
--- a/packages/cli/src/ui/components/DebugProfiler.tsx
+++ b/packages/cli/src/ui/components/DebugProfiler.tsx
@@ -6,7 +6,7 @@
import { Text } from 'ink';
import { useEffect, useRef, useState } from 'react';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { useKeypress } from '../hooks/useKeypress.js';
export const DebugProfiler = () => {
@@ -31,6 +31,6 @@ export const DebugProfiler = () => {
}
return (
- Renders: {numRenders.current}
+ Renders: {numRenders.current}
);
};
diff --git a/packages/cli/src/ui/components/DetailedMessagesDisplay.tsx b/packages/cli/src/ui/components/DetailedMessagesDisplay.tsx
index 454977220a..b31d088005 100644
--- a/packages/cli/src/ui/components/DetailedMessagesDisplay.tsx
+++ b/packages/cli/src/ui/components/DetailedMessagesDisplay.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import type { ConsoleMessageItem } from '../types.js';
import { MaxSizedBox } from './shared/MaxSizedBox.js';
@@ -31,31 +31,32 @@ export const DetailedMessagesDisplay: React.FC<
flexDirection="column"
marginTop={1}
borderStyle="round"
- borderColor={Colors.Gray}
+ borderColor={theme.border.default}
paddingX={1}
width={width}
>
-
- Debug Console (ctrl+o to close)
+
+ Debug Console{' '}
+ (ctrl+o to close)
{messages.map((msg, index) => {
- let textColor = Colors.Foreground;
+ let textColor = theme.text.primary;
let icon = '\u2139'; // Information source (ℹ)
switch (msg.type) {
case 'warn':
- textColor = Colors.AccentYellow;
+ textColor = theme.status.warning;
icon = '\u26A0'; // Warning sign (⚠)
break;
case 'error':
- textColor = Colors.AccentRed;
+ textColor = theme.status.error;
icon = '\u2716'; // Heavy multiplication x (✖)
break;
case 'debug':
- textColor = Colors.Gray; // Or Colors.Gray
+ textColor = theme.text.secondary; // Or theme.text.secondary
icon = '\u{1F50D}'; // Left-pointing magnifying glass (🔍)
break;
case 'log':
@@ -70,7 +71,7 @@ export const DetailedMessagesDisplay: React.FC<
{msg.content}
{msg.count && msg.count > 1 && (
- (x{msg.count})
+ (x{msg.count})
)}
diff --git a/packages/cli/src/ui/components/DialogManager.tsx b/packages/cli/src/ui/components/DialogManager.tsx
index 9a79d2eebd..fff3e2f1cc 100644
--- a/packages/cli/src/ui/components/DialogManager.tsx
+++ b/packages/cli/src/ui/components/DialogManager.tsx
@@ -17,7 +17,7 @@ import { EditorSettingsDialog } from './EditorSettingsDialog.js';
import { PrivacyNotice } from '../privacy/PrivacyNotice.js';
import { WorkspaceMigrationDialog } from './WorkspaceMigrationDialog.js';
import { ProQuotaDialog } from './ProQuotaDialog.js';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { useUIState } from '../contexts/UIStateContext.js';
import { useUIActions } from '../contexts/UIActionsContext.js';
import { useConfig } from '../contexts/ConfigContext.js';
@@ -36,8 +36,8 @@ export const DialogManager = () => {
if (uiState.showIdeRestartPrompt) {
return (
-
-
+
+
Workspace trust has changed. Press 'r' to restart Gemini to
apply the changes.
@@ -106,7 +106,7 @@ export const DialogManager = () => {
{uiState.themeError && (
- {uiState.themeError}
+ {uiState.themeError}
)}
{
{uiState.editorError && (
- {uiState.editorError}
+ {uiState.editorError}
)}
{focusedSection === 'editor' ? '> ' : ' '}Select Editor{' '}
- {otherScopeModifiedMessage}
+ {otherScopeModifiedMessage}
({
@@ -147,7 +147,7 @@ export function EditorSettingsDialog({
-
+
(Use Enter to select, Tab to change focus)
@@ -156,17 +156,17 @@ export function EditorSettingsDialog({
Editor Preference
-
+
These editors are currently supported. Please note that some editors
cannot be used in sandbox mode.
-
+
Your preferred editor is:{' '}
diff --git a/packages/cli/src/ui/components/FolderTrustDialog.tsx b/packages/cli/src/ui/components/FolderTrustDialog.tsx
index ebcadd7a35..83799a3506 100644
--- a/packages/cli/src/ui/components/FolderTrustDialog.tsx
+++ b/packages/cli/src/ui/components/FolderTrustDialog.tsx
@@ -6,7 +6,7 @@
import { Box, Text } from 'ink';
import type React from 'react';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import type { RadioSelectItem } from './shared/RadioButtonSelect.js';
import { RadioButtonSelect } from './shared/RadioButtonSelect.js';
import { useKeypress } from '../hooks/useKeypress.js';
@@ -69,14 +69,16 @@ export const FolderTrustDialog: React.FC = ({
- Do you trust this folder?
-
+
+ Do you trust this folder?
+
+
Trusting a folder allows Gemini to execute commands it suggests.
This is a security feature to prevent accidental execution in
untrusted directories.
@@ -91,7 +93,7 @@ export const FolderTrustDialog: React.FC = ({
{isRestarting && (
-
+
To see changes, Gemini CLI must be restarted. Press r to exit and
apply changes now.
diff --git a/packages/cli/src/ui/components/GeminiRespondingSpinner.tsx b/packages/cli/src/ui/components/GeminiRespondingSpinner.tsx
index 057faaffc3..cde45a3ec3 100644
--- a/packages/cli/src/ui/components/GeminiRespondingSpinner.tsx
+++ b/packages/cli/src/ui/components/GeminiRespondingSpinner.tsx
@@ -14,6 +14,7 @@ import {
SCREEN_READER_LOADING,
SCREEN_READER_RESPONDING,
} from '../textConstants.js';
+import { theme } from '../semantic-colors.js';
interface GeminiRespondingSpinnerProps {
/**
@@ -40,7 +41,7 @@ export const GeminiRespondingSpinner: React.FC<
return isScreenReaderEnabled ? (
{SCREEN_READER_LOADING}
) : (
- {nonRespondingDisplay}
+ {nonRespondingDisplay}
);
}
return null;
@@ -59,6 +60,8 @@ export const GeminiSpinner: React.FC = ({
return isScreenReaderEnabled ? (
{altText}
) : (
-
+
+
+
);
};
diff --git a/packages/cli/src/ui/components/Header.tsx b/packages/cli/src/ui/components/Header.tsx
index 5d09ec3b10..694752312f 100644
--- a/packages/cli/src/ui/components/Header.tsx
+++ b/packages/cli/src/ui/components/Header.tsx
@@ -7,7 +7,7 @@
import type React from 'react';
import { Box, Text } from 'ink';
import Gradient from 'ink-gradient';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { shortAsciiLogo, longAsciiLogo, tinyAsciiLogo } from './AsciiArt.js';
import { getAsciiArtWidth } from '../utils/textUtils.js';
import { useTerminalSize } from '../hooks/useTerminalSize.js';
@@ -47,8 +47,8 @@ export const Header: React.FC = ({
flexShrink={0}
flexDirection="column"
>
- {Colors.GradientColors ? (
-
+ {theme.ui.gradient ? (
+
{displayTitle}
) : (
@@ -56,8 +56,8 @@ export const Header: React.FC = ({
)}
{nightly && (
- {Colors.GradientColors ? (
-
+ {theme.ui.gradient ? (
+
v{version}
) : (
diff --git a/packages/cli/src/ui/components/Help.tsx b/packages/cli/src/ui/components/Help.tsx
index b2a8a4400a..90a6b26a9c 100644
--- a/packages/cli/src/ui/components/Help.tsx
+++ b/packages/cli/src/ui/components/Help.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { type SlashCommand, CommandKind } from '../commands/types.js';
interface Help {
@@ -17,42 +17,42 @@ export const Help: React.FC = ({ commands }) => (
{/* Basics */}
-
+
Basics:
-
-
+
+
Add context
: Use{' '}
-
+
@
{' '}
to specify files for context (e.g.,{' '}
-
+
@src/myFile.ts
) to target specific files or folders.
-
-
+
+
Shell mode
: Execute shell commands via{' '}
-
+
!
{' '}
(e.g.,{' '}
-
+
!npm run start
) or use natural language (e.g.{' '}
-
+
start server
).
@@ -61,20 +61,20 @@ export const Help: React.FC = ({ commands }) => (
{/* Commands */}
-
+
Commands:
{commands
.filter((command) => command.description && !command.hidden)
.map((command: SlashCommand) => (
-
-
+
+
{' '}
/{command.name}
{command.kind === CommandKind.MCP_PROMPT && (
- [MCP]
+ [MCP]
)}
{command.description && ' - ' + command.description}
@@ -82,8 +82,8 @@ export const Help: React.FC = ({ commands }) => (
command.subCommands
.filter((subCommand) => !subCommand.hidden)
.map((subCommand) => (
-
-
+
+
{' '}
{subCommand.name}
@@ -92,90 +92,90 @@ export const Help: React.FC = ({ commands }) => (
))}
))}
-
-
+
+
{' '}
!{' '}
- shell command
-
- [MCP] - Model Context Protocol command
- (from external servers)
+
+ [MCP] - Model Context Protocol
+ command (from external servers)
{/* Shortcuts */}
-
+
Keyboard Shortcuts:
-
-
+
+
Alt+Left/Right
{' '}
- Jump through words in the input
-
-
+
+
Ctrl+C
{' '}
- Quit application
-
-
+
+
{process.platform === 'win32' ? 'Ctrl+Enter' : 'Ctrl+J'}
{' '}
{process.platform === 'linux'
? '- New line (Alt+Enter works for certain linux distros)'
: '- New line'}
-
-
+
+
Ctrl+L
{' '}
- Clear the screen
-
-
+
+
{process.platform === 'darwin' ? 'Ctrl+X / Meta+Enter' : 'Ctrl+X'}
{' '}
- Open input in external editor
-
-
+
+
Ctrl+Y
{' '}
- Toggle YOLO mode
-
-
+
+
Enter
{' '}
- Send message
-
-
+
+
Esc
{' '}
- Cancel operation / Clear input (double press)
-
-
+
+
Shift+Tab
{' '}
- Toggle auto-accepting edits
-
-
+
+
Up/Down
{' '}
- Cycle through your prompt history
-
+
For a full list of shortcuts, see{' '}
-
+
docs/keyboard-shortcuts.md
diff --git a/packages/cli/src/ui/components/InputPrompt.tsx b/packages/cli/src/ui/components/InputPrompt.tsx
index dc03b4bea5..10bd2e1812 100644
--- a/packages/cli/src/ui/components/InputPrompt.tsx
+++ b/packages/cli/src/ui/components/InputPrompt.tsx
@@ -714,7 +714,11 @@ export const InputPrompt: React.FC = ({
@@ -797,7 +801,7 @@ export const InputPrompt: React.FC = ({
const color =
token.type === 'command' || token.type === 'file'
? theme.text.accent
- : undefined;
+ : theme.text.primary;
renderedLine.push(
diff --git a/packages/cli/src/ui/components/LoadingIndicator.tsx b/packages/cli/src/ui/components/LoadingIndicator.tsx
index b7a88ee47e..b6bb3a1a4b 100644
--- a/packages/cli/src/ui/components/LoadingIndicator.tsx
+++ b/packages/cli/src/ui/components/LoadingIndicator.tsx
@@ -7,7 +7,7 @@
import type { ThoughtSummary } from '@google/gemini-cli-core';
import type React from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { useStreamingContext } from '../contexts/StreamingContext.js';
import { StreamingState } from '../types.js';
import { GeminiRespondingSpinner } from './GeminiRespondingSpinner.js';
@@ -61,11 +61,9 @@ export const LoadingIndicator: React.FC = ({
}
/>
- {primaryText && (
- {primaryText}
- )}
+ {primaryText && {primaryText}}
{!isNarrow && cancelAndTimerContent && (
- {cancelAndTimerContent}
+ {cancelAndTimerContent}
)}
{!isNarrow && {/* Spacer */}}
@@ -73,7 +71,7 @@ export const LoadingIndicator: React.FC = ({
{isNarrow && cancelAndTimerContent && (
- {cancelAndTimerContent}
+ {cancelAndTimerContent}
)}
{isNarrow && rightContent && {rightContent}}
diff --git a/packages/cli/src/ui/components/MemoryUsageDisplay.tsx b/packages/cli/src/ui/components/MemoryUsageDisplay.tsx
index a8b449e524..1ea3c10693 100644
--- a/packages/cli/src/ui/components/MemoryUsageDisplay.tsx
+++ b/packages/cli/src/ui/components/MemoryUsageDisplay.tsx
@@ -7,20 +7,24 @@
import type React from 'react';
import { useEffect, useState } from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import process from 'node:process';
import { formatMemoryUsage } from '../utils/formatters.js';
export const MemoryUsageDisplay: React.FC = () => {
const [memoryUsage, setMemoryUsage] = useState('');
- const [memoryUsageColor, setMemoryUsageColor] = useState(Colors.Gray);
+ const [memoryUsageColor, setMemoryUsageColor] = useState(
+ theme.text.secondary,
+ );
useEffect(() => {
const updateMemory = () => {
const usage = process.memoryUsage().rss;
setMemoryUsage(formatMemoryUsage(usage));
setMemoryUsageColor(
- usage >= 2 * 1024 * 1024 * 1024 ? Colors.AccentRed : Colors.Gray,
+ usage >= 2 * 1024 * 1024 * 1024
+ ? theme.status.error
+ : theme.text.secondary,
);
};
const intervalId = setInterval(updateMemory, 2000);
@@ -30,7 +34,7 @@ export const MemoryUsageDisplay: React.FC = () => {
return (
- |
+ |
{memoryUsage}
);
diff --git a/packages/cli/src/ui/components/ModelStatsDisplay.tsx b/packages/cli/src/ui/components/ModelStatsDisplay.tsx
index 2316cf8f58..95a8fe4605 100644
--- a/packages/cli/src/ui/components/ModelStatsDisplay.tsx
+++ b/packages/cli/src/ui/components/ModelStatsDisplay.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { formatDuration } from '../utils/formatters.js';
import {
calculateAverageLatency,
@@ -34,13 +34,16 @@ const StatRow: React.FC = ({
}) => (
-
+
{isSubtle ? ` ↳ ${title}` : title}
{values.map((value, index) => (
- {value}
+ {value}
))}
@@ -57,11 +60,13 @@ export const ModelStatsDisplay: React.FC = () => {
return (
- No API calls have been made in this session.
+
+ No API calls have been made in this session.
+
);
}
@@ -83,12 +88,12 @@ export const ModelStatsDisplay: React.FC = () => {
return (
-
+
Model Stats For Nerds
@@ -96,11 +101,15 @@ export const ModelStatsDisplay: React.FC = () => {
{/* Header */}
- Metric
+
+ Metric
+
{modelNames.map((name) => (
- {name}
+
+ {name}
+
))}
@@ -112,6 +121,7 @@ export const ModelStatsDisplay: React.FC = () => {
borderTop={false}
borderLeft={false}
borderRight={false}
+ borderColor={theme.border.default}
/>
{/* API Section */}
@@ -127,7 +137,7 @@ export const ModelStatsDisplay: React.FC = () => {
return (
0 ? Colors.AccentRed : Colors.Foreground
+ m.api.totalErrors > 0 ? theme.status.error : theme.text.primary
}
>
{m.api.totalErrors.toLocaleString()} ({errorRate.toFixed(1)}%)
@@ -150,7 +160,7 @@ export const ModelStatsDisplay: React.FC = () => {
(
-
+
{m.tokens.total.toLocaleString()}
))}
@@ -167,7 +177,7 @@ export const ModelStatsDisplay: React.FC = () => {
values={getModelValues((m) => {
const cacheHitRate = calculateCacheHitRate(m);
return (
-
+
{m.tokens.cached.toLocaleString()} ({cacheHitRate.toFixed(1)}%)
);
diff --git a/packages/cli/src/ui/components/Notifications.tsx b/packages/cli/src/ui/components/Notifications.tsx
index 954945d3ad..a287b10524 100644
--- a/packages/cli/src/ui/components/Notifications.tsx
+++ b/packages/cli/src/ui/components/Notifications.tsx
@@ -7,7 +7,7 @@
import { Box, Text } from 'ink';
import { useAppContext } from '../contexts/AppContext.js';
import { useUIState } from '../contexts/UIStateContext.js';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { StreamingState } from '../types.js';
import { UpdateNotification } from './UpdateNotification.js';
@@ -29,13 +29,13 @@ export const Notifications = () => {
{showStartupWarnings && (
{startupWarnings.map((warning, index) => (
-
+
{warning}
))}
@@ -44,14 +44,14 @@ export const Notifications = () => {
{showInitError && (
-
+
Initialization Error: {initError}
-
+
{' '}
Please check API key and configuration.
diff --git a/packages/cli/src/ui/components/PrepareLabel.tsx b/packages/cli/src/ui/components/PrepareLabel.tsx
index d89c1fe480..37ad5a3313 100644
--- a/packages/cli/src/ui/components/PrepareLabel.tsx
+++ b/packages/cli/src/ui/components/PrepareLabel.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
interface PrepareLabelProps {
label: string;
@@ -21,7 +21,7 @@ export const PrepareLabel: React.FC = ({
matchedIndex,
userInput,
textColor,
- highlightColor = Colors.AccentYellow,
+ highlightColor = theme.status.warning,
}) => {
if (
matchedIndex === undefined ||
diff --git a/packages/cli/src/ui/components/ProQuotaDialog.tsx b/packages/cli/src/ui/components/ProQuotaDialog.tsx
index c547967508..17e5965e0b 100644
--- a/packages/cli/src/ui/components/ProQuotaDialog.tsx
+++ b/packages/cli/src/ui/components/ProQuotaDialog.tsx
@@ -7,7 +7,7 @@
import type React from 'react';
import { Box, Text } from 'ink';
import { RadioButtonSelect } from './shared/RadioButtonSelect.js';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
interface ProQuotaDialogProps {
failedModel: string;
@@ -37,7 +37,7 @@ export function ProQuotaDialog({
return (
-
+
Pro quota limit reached for {failedModel}.
diff --git a/packages/cli/src/ui/components/SettingsDialog.tsx b/packages/cli/src/ui/components/SettingsDialog.tsx
index 390fc2f611..17a56e2de0 100644
--- a/packages/cli/src/ui/components/SettingsDialog.tsx
+++ b/packages/cli/src/ui/components/SettingsDialog.tsx
@@ -6,7 +6,7 @@
import React, { useState, useEffect } from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import type { LoadedSettings, Settings } from '../../config/settings.js';
import { SettingScope } from '../../config/settings.js';
import {
@@ -656,18 +656,18 @@ export function SettingsDialog({
return (
-
+
Settings
- {showScrollUp && ▲}
+ {showScrollUp && ▲}
{visibleItems.map((item, idx) => {
const isActive =
focusSection === 'settings' &&
@@ -748,17 +748,21 @@ export function SettingsDialog({
-
+
{isActive ? '●' : ''}
{item.label}
{scopeMessage && (
- {scopeMessage}
+ {scopeMessage}
)}
@@ -766,10 +770,10 @@ export function SettingsDialog({
{displayValue}
@@ -779,7 +783,7 @@ export function SettingsDialog({
);
})}
- {showScrollDown && ▼}
+ {showScrollDown && ▼}
@@ -798,11 +802,11 @@ export function SettingsDialog({
-
+
(Use Enter to select, Tab to change focus)
{showRestartPrompt && (
-
+
To see changes, Gemini CLI must be restarted. Press r to exit and
apply changes now.
diff --git a/packages/cli/src/ui/components/ShellConfirmationDialog.tsx b/packages/cli/src/ui/components/ShellConfirmationDialog.tsx
index 4315995682..bd5ef15400 100644
--- a/packages/cli/src/ui/components/ShellConfirmationDialog.tsx
+++ b/packages/cli/src/ui/components/ShellConfirmationDialog.tsx
@@ -7,7 +7,7 @@
import { ToolConfirmationOutcome } from '@google/gemini-cli-core';
import { Box, Text } from 'ink';
import type React from 'react';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { RenderInline } from '../utils/InlineMarkdownRenderer.js';
import type { RadioSelectItem } from './shared/RadioButtonSelect.js';
import { RadioButtonSelect } from './shared/RadioButtonSelect.js';
@@ -68,23 +68,27 @@ export const ShellConfirmationDialog: React.FC<
- Shell Command Execution
- A custom command wants to run the following shell commands:
+
+ Shell Command Execution
+
+
+ A custom command wants to run the following shell commands:
+
{commands.map((cmd) => (
-
+
))}
@@ -92,7 +96,7 @@ export const ShellConfirmationDialog: React.FC<
- Do you want to proceed?
+ Do you want to proceed?
diff --git a/packages/cli/src/ui/components/ShellModeIndicator.tsx b/packages/cli/src/ui/components/ShellModeIndicator.tsx
index 23d7174017..6fbde05c68 100644
--- a/packages/cli/src/ui/components/ShellModeIndicator.tsx
+++ b/packages/cli/src/ui/components/ShellModeIndicator.tsx
@@ -6,13 +6,13 @@
import type React from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
export const ShellModeIndicator: React.FC = () => (
-
+
shell mode enabled
- (esc to disable)
+ (esc to disable)
);
diff --git a/packages/cli/src/ui/components/ShowMoreLines.tsx b/packages/cli/src/ui/components/ShowMoreLines.tsx
index 41232d9483..8823eee620 100644
--- a/packages/cli/src/ui/components/ShowMoreLines.tsx
+++ b/packages/cli/src/ui/components/ShowMoreLines.tsx
@@ -8,7 +8,7 @@ import { Box, Text } from 'ink';
import { useOverflowState } from '../contexts/OverflowContext.js';
import { useStreamingContext } from '../contexts/StreamingContext.js';
import { StreamingState } from '../types.js';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
interface ShowMoreLinesProps {
constrainHeight: boolean;
@@ -32,7 +32,7 @@ export const ShowMoreLines = ({ constrainHeight }: ShowMoreLinesProps) => {
return (
-
+
Press ctrl-s to show more lines
diff --git a/packages/cli/src/ui/components/StatsDisplay.tsx b/packages/cli/src/ui/components/StatsDisplay.tsx
index dd9879d77a..f40d055ad3 100644
--- a/packages/cli/src/ui/components/StatsDisplay.tsx
+++ b/packages/cli/src/ui/components/StatsDisplay.tsx
@@ -47,7 +47,7 @@ const SubStatRow: React.FC = ({ title, children }) => (
{/* Adjust width for the "» " prefix */}
- » {title}
+ » {title}
{/* FIX: Apply the same flexGrow fix here */}
{children}
@@ -62,7 +62,9 @@ interface SectionProps {
const Section: React.FC = ({ title, children }) => (
- {title}
+
+ {title}
+
{children}
);
@@ -82,16 +84,24 @@ const ModelUsageTable: React.FC<{
{/* Header */}
- Model Usage
+
+ Model Usage
+
- Reqs
+
+ Reqs
+
- Input Tokens
+
+ Input Tokens
+
- Output Tokens
+
+ Output Tokens
+
{/* Divider */}
@@ -101,6 +111,7 @@ const ModelUsageTable: React.FC<{
borderTop={false}
borderLeft={false}
borderRight={false}
+ borderColor={theme.border.default}
width={nameWidth + requestsWidth + inputTokensWidth + outputTokensWidth}
>
@@ -108,10 +119,12 @@ const ModelUsageTable: React.FC<{
{Object.entries(models).map(([name, modelMetrics]) => (
- {name.replace('-001', '')}
+ {name.replace('-001', '')}
- {modelMetrics.api.totalRequests}
+
+ {modelMetrics.api.totalRequests}
+
@@ -127,7 +140,7 @@ const ModelUsageTable: React.FC<{
))}
{cacheEfficiency > 0 && (
-
+
Savings Highlight:{' '}
{totalCachedTokens.toLocaleString()} ({cacheEfficiency.toFixed(1)}
%) of input tokens were served from the cache, reducing costs.
@@ -202,10 +215,10 @@ export const StatsDisplay: React.FC = ({
- {stats.sessionId}
+ {stats.sessionId}
-
+
{tools.totalCalls} ({' '}
✓ {tools.totalSuccess}{' '}
x {tools.totalFail} )
@@ -227,7 +240,7 @@ export const StatsDisplay: React.FC = ({
{files &&
(files.totalLinesAdded > 0 || files.totalLinesRemoved > 0) && (
-
+
+{files.totalLinesAdded}
{' '}
@@ -241,13 +254,15 @@ export const StatsDisplay: React.FC = ({
- {duration}
+ {duration}
- {formatDuration(computed.agentActiveTime)}
+
+ {formatDuration(computed.agentActiveTime)}
+
-
+
{formatDuration(computed.totalApiTime)}{' '}
({computed.apiTimePercent.toFixed(1)}%)
@@ -255,7 +270,7 @@ export const StatsDisplay: React.FC = ({
-
+
{formatDuration(computed.totalToolTime)}{' '}
({computed.toolTimePercent.toFixed(1)}%)
diff --git a/packages/cli/src/ui/components/SuggestionsDisplay.tsx b/packages/cli/src/ui/components/SuggestionsDisplay.tsx
index b1be0e255f..0e8bf8e18f 100644
--- a/packages/cli/src/ui/components/SuggestionsDisplay.tsx
+++ b/packages/cli/src/ui/components/SuggestionsDisplay.tsx
@@ -5,7 +5,7 @@
*/
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { PrepareLabel } from './PrepareLabel.js';
import { CommandKind } from '../commands/types.js';
export interface Suggestion {
@@ -56,12 +56,12 @@ export function SuggestionsDisplay({
return (
- {scrollOffset > 0 && ▲}
+ {scrollOffset > 0 && ▲}
{visibleSuggestions.map((suggestion, index) => {
const originalIndex = startIndex + index;
const isActive = originalIndex === activeIndex;
- const textColor = isActive ? Colors.AccentPurple : Colors.Gray;
+ const textColor = isActive ? theme.text.accent : theme.text.secondary;
const labelElement = (
{labelElement}
{suggestion.commandKind === CommandKind.MCP_PROMPT && (
- [MCP]
+ [MCP]
)}
) : (
diff --git a/packages/cli/src/ui/components/ThemeDialog.tsx b/packages/cli/src/ui/components/ThemeDialog.tsx
index 21fc78161d..c4bc64c302 100644
--- a/packages/cli/src/ui/components/ThemeDialog.tsx
+++ b/packages/cli/src/ui/components/ThemeDialog.tsx
@@ -7,7 +7,7 @@
import type React from 'react';
import { useCallback, useState } from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { themeManager, DEFAULT_THEME } from '../themes/theme-manager.js';
import { RadioButtonSelect } from './shared/RadioButtonSelect.js';
import { DiffRenderer } from './messages/DiffRenderer.js';
@@ -183,7 +183,7 @@ export function ThemeDialog({
return (
{mode === 'theme' ? '> ' : ' '}Select Theme{' '}
- {otherScopeModifiedMessage}
+
+ {otherScopeModifiedMessage}
+
)}
-
+
(Use Enter to {mode === 'theme' ? 'select' : 'apply scope'}, Tab to{' '}
{mode === 'theme' ? 'configure scope' : 'select theme'})
diff --git a/packages/cli/src/ui/components/Tips.tsx b/packages/cli/src/ui/components/Tips.tsx
index 7fb9431c3b..576b8494c5 100644
--- a/packages/cli/src/ui/components/Tips.tsx
+++ b/packages/cli/src/ui/components/Tips.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { type Config } from '@google/gemini-cli-core';
interface TipsProps {
@@ -17,25 +17,25 @@ export const Tips: React.FC = ({ config }) => {
const geminiMdFileCount = config.getGeminiMdFileCount();
return (
- Tips for getting started:
-
+ Tips for getting started:
+
1. Ask questions, edit files, or run commands.
-
+
2. Be specific for the best results.
{geminiMdFileCount === 0 && (
-
+
3. Create{' '}
-
+
GEMINI.md
{' '}
files to customize your interactions with Gemini.
)}
-
+
{geminiMdFileCount === 0 ? '4.' : '3.'}{' '}
-
+
/help
{' '}
for more information.
diff --git a/packages/cli/src/ui/components/ToolStatsDisplay.tsx b/packages/cli/src/ui/components/ToolStatsDisplay.tsx
index e77e191c69..64c0d146ce 100644
--- a/packages/cli/src/ui/components/ToolStatsDisplay.tsx
+++ b/packages/cli/src/ui/components/ToolStatsDisplay.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { formatDuration } from '../utils/formatters.js';
import {
getStatusColor,
@@ -37,16 +37,16 @@ const StatRow: React.FC<{
return (
- {name}
+ {name}
- {stats.count}
+ {stats.count}
{successRate.toFixed(1)}%
- {formatDuration(avgDuration)}
+ {formatDuration(avgDuration)}
);
@@ -63,11 +63,13 @@ export const ToolStatsDisplay: React.FC = () => {
return (
- No tool calls have been made in this session.
+
+ No tool calls have been made in this session.
+
);
}
@@ -94,13 +96,13 @@ export const ToolStatsDisplay: React.FC = () => {
return (
-
+
Tool Stats For Nerds
@@ -108,16 +110,24 @@ export const ToolStatsDisplay: React.FC = () => {
{/* Header */}
- Tool Name
+
+ Tool Name
+
- Calls
+
+ Calls
+
- Success Rate
+
+ Success Rate
+
- Avg Duration
+
+ Avg Duration
+
@@ -128,6 +138,7 @@ export const ToolStatsDisplay: React.FC = () => {
borderTop={false}
borderLeft={false}
borderRight={false}
+ borderColor={theme.border.default}
width="100%"
/>
@@ -139,45 +150,47 @@ export const ToolStatsDisplay: React.FC = () => {
{/* User Decision Summary */}
- User Decision Summary
+
+ User Decision Summary
+
- Total Reviewed Suggestions:
+ Total Reviewed Suggestions:
- {totalReviewed}
+ {totalReviewed}
- » Accepted:
+ » Accepted:
- {totalDecisions.accept}
+ {totalDecisions.accept}
- » Rejected:
+ » Rejected:
- {totalDecisions.reject}
+ {totalDecisions.reject}
- » Modified:
+ » Modified:
- {totalDecisions.modify}
+ {totalDecisions.modify}
@@ -188,6 +201,7 @@ export const ToolStatsDisplay: React.FC = () => {
borderTop={false}
borderLeft={false}
borderRight={false}
+ borderColor={theme.border.default}
width="100%"
/>
@@ -195,7 +209,7 @@ export const ToolStatsDisplay: React.FC = () => {
- Overall Agreement Rate:
+ Overall Agreement Rate:
0 ? agreementColor : undefined}>
diff --git a/packages/cli/src/ui/components/UpdateNotification.tsx b/packages/cli/src/ui/components/UpdateNotification.tsx
index b88c9bd5d0..8142a2018e 100644
--- a/packages/cli/src/ui/components/UpdateNotification.tsx
+++ b/packages/cli/src/ui/components/UpdateNotification.tsx
@@ -5,7 +5,7 @@
*/
import { Box, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
interface UpdateNotificationProps {
message: string;
@@ -14,10 +14,10 @@ interface UpdateNotificationProps {
export const UpdateNotification = ({ message }: UpdateNotificationProps) => (
- {message}
+ {message}
);
diff --git a/packages/cli/src/ui/components/WorkspaceMigrationDialog.tsx b/packages/cli/src/ui/components/WorkspaceMigrationDialog.tsx
index c53de1cfb4..e642407db5 100644
--- a/packages/cli/src/ui/components/WorkspaceMigrationDialog.tsx
+++ b/packages/cli/src/ui/components/WorkspaceMigrationDialog.tsx
@@ -10,7 +10,7 @@ import {
performWorkspaceExtensionMigration,
} from '../../config/extension.js';
import { RadioButtonSelect } from './shared/RadioButtonSelect.js';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { useState } from 'react';
export function WorkspaceMigrationDialog(props: {
@@ -40,15 +40,15 @@ export function WorkspaceMigrationDialog(props: {
{failedExtensions.length > 0 ? (
<>
-
+
The following extensions failed to migrate. Please try installing
them manually. To see other changes, Gemini CLI must be restarted.
- Press {"'q'"} to quit.
+ Press 'q' to quit.
{failedExtensions.map((failed) => (
@@ -57,9 +57,9 @@ export function WorkspaceMigrationDialog(props: {
>
) : (
-
+
Migration complete. To see changes, Gemini CLI must be restarted.
- Press {"'q'"} to quit.
+ Press 'q' to quit.
)}
@@ -70,15 +70,19 @@ export function WorkspaceMigrationDialog(props: {
- Workspace-level extensions are deprecated{'\n'}
- Would you like to install them at the user level?
-
+
+ Workspace-level extensions are deprecated{'\n'}
+
+
+ Would you like to install them at the user level?
+
+
The extension definition will remain in your workspace directory.
-
+
If you opt to skip, you can install them manually using the extensions
install command.
diff --git a/packages/cli/src/ui/components/messages/CompressionMessage.tsx b/packages/cli/src/ui/components/messages/CompressionMessage.tsx
index 7663172e23..929150b5bf 100644
--- a/packages/cli/src/ui/components/messages/CompressionMessage.tsx
+++ b/packages/cli/src/ui/components/messages/CompressionMessage.tsx
@@ -8,7 +8,7 @@ import type React from 'react';
import { Box, Text } from 'ink';
import type { CompressionProps } from '../../types.js';
import Spinner from 'ink-spinner';
-import { Colors } from '../../colors.js';
+import { theme } from '../../semantic-colors.js';
import { SCREEN_READER_MODEL_PREFIX } from '../../textConstants.js';
export interface CompressionDisplayProps {
@@ -33,13 +33,13 @@ export const CompressionMessage: React.FC = ({
{compression.isPending ? (
) : (
- ✦
+ ✦
)}
diff --git a/packages/cli/src/ui/components/messages/DiffRenderer.tsx b/packages/cli/src/ui/components/messages/DiffRenderer.tsx
index f855c97f56..d962d683b8 100644
--- a/packages/cli/src/ui/components/messages/DiffRenderer.tsx
+++ b/packages/cli/src/ui/components/messages/DiffRenderer.tsx
@@ -6,11 +6,11 @@
import type React from 'react';
import { Box, Text, useIsScreenReaderEnabled } from 'ink';
-import { Colors } from '../../colors.js';
import crypto from 'node:crypto';
import { colorizeCode, colorizeLine } from '../../utils/CodeColorizer.js';
import { MaxSizedBox } from '../shared/MaxSizedBox.js';
-import { theme } from '../../semantic-colors.js';
+import { theme as semanticTheme } from '../../semantic-colors.js';
+import type { Theme } from '../../themes/theme.js';
interface DiffLine {
type: 'add' | 'del' | 'context' | 'hunk' | 'other';
@@ -42,18 +42,9 @@ function parseDiffWithLineNumbers(diffContent: string): DiffLine[] {
}
if (!inHunk) {
// Skip standard Git header lines more robustly
- if (
- line.startsWith('--- ') ||
- line.startsWith('+++ ') ||
- line.startsWith('diff --git') ||
- line.startsWith('index ') ||
- line.startsWith('similarity index') ||
- line.startsWith('rename from') ||
- line.startsWith('rename to') ||
- line.startsWith('new file mode') ||
- line.startsWith('deleted file mode')
- )
+ if (line.startsWith('--- ')) {
continue;
+ }
// If it's not a hunk or header, skip (or handle as 'other' if needed)
continue;
}
@@ -94,7 +85,7 @@ interface DiffRendererProps {
tabWidth?: number;
availableTerminalHeight?: number;
terminalWidth: number;
- theme?: import('../../themes/theme.js').Theme;
+ theme?: Theme;
}
const DEFAULT_TAB_WIDTH = 4; // Spaces per tab for normalization
@@ -109,14 +100,18 @@ export const DiffRenderer: React.FC = ({
}) => {
const screenReaderEnabled = useIsScreenReaderEnabled();
if (!diffContent || typeof diffContent !== 'string') {
- return No diff content.;
+ return No diff content.;
}
const parsedLines = parseDiffWithLineNumbers(diffContent);
if (parsedLines.length === 0) {
return (
-
+
No changes detected.
);
@@ -196,7 +191,11 @@ const renderDiffContent = (
if (displayableLines.length === 0) {
return (
-
+
No changes detected.
);
@@ -260,7 +259,7 @@ const renderDiffContent = (
) {
acc.push(
-
+
{'═'.repeat(terminalWidth)}
,
@@ -301,12 +300,12 @@ const renderDiffContent = (
acc.push(
@@ -323,16 +322,16 @@ const renderDiffContent = (
{prefixSymbol}
diff --git a/packages/cli/src/ui/components/messages/ErrorMessage.tsx b/packages/cli/src/ui/components/messages/ErrorMessage.tsx
index 52a03a89de..71794ee41c 100644
--- a/packages/cli/src/ui/components/messages/ErrorMessage.tsx
+++ b/packages/cli/src/ui/components/messages/ErrorMessage.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Text, Box } from 'ink';
-import { Colors } from '../../colors.js';
+import { theme } from '../../semantic-colors.js';
interface ErrorMessageProps {
text: string;
@@ -19,10 +19,10 @@ export const ErrorMessage: React.FC = ({ text }) => {
return (
- {prefix}
+ {prefix}
-
+
{text}
diff --git a/packages/cli/src/ui/components/messages/GeminiMessage.tsx b/packages/cli/src/ui/components/messages/GeminiMessage.tsx
index 9473c12885..389b5ac151 100644
--- a/packages/cli/src/ui/components/messages/GeminiMessage.tsx
+++ b/packages/cli/src/ui/components/messages/GeminiMessage.tsx
@@ -7,7 +7,7 @@
import type React from 'react';
import { Text, Box } from 'ink';
import { MarkdownDisplay } from '../../utils/MarkdownDisplay.js';
-import { Colors } from '../../colors.js';
+import { theme } from '../../semantic-colors.js';
import { SCREEN_READER_MODEL_PREFIX } from '../../textConstants.js';
interface GeminiMessageProps {
@@ -29,10 +29,7 @@ export const GeminiMessage: React.FC = ({
return (
-
+
{prefix}
diff --git a/packages/cli/src/ui/components/messages/InfoMessage.tsx b/packages/cli/src/ui/components/messages/InfoMessage.tsx
index 3d7866bec0..e8d09d637e 100644
--- a/packages/cli/src/ui/components/messages/InfoMessage.tsx
+++ b/packages/cli/src/ui/components/messages/InfoMessage.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Text, Box } from 'ink';
-import { Colors } from '../../colors.js';
+import { theme } from '../../semantic-colors.js';
import { RenderInline } from '../../utils/InlineMarkdownRenderer.js';
interface InfoMessageProps {
@@ -20,10 +20,10 @@ export const InfoMessage: React.FC = ({ text }) => {
return (
- {prefix}
+ {prefix}
-
+
diff --git a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx
index a440e59e85..427e3fb38c 100644
--- a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx
+++ b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx
@@ -7,7 +7,6 @@
import type React from 'react';
import { Box, Text } from 'ink';
import { DiffRenderer } from './DiffRenderer.js';
-import { Colors } from '../../colors.js';
import { RenderInline } from '../../utils/InlineMarkdownRenderer.js';
import type {
ToolCallConfirmationDetails,
@@ -20,6 +19,7 @@ import type { RadioSelectItem } from '../shared/RadioButtonSelect.js';
import { RadioButtonSelect } from '../shared/RadioButtonSelect.js';
import { MaxSizedBox } from '../shared/MaxSizedBox.js';
import { useKeypress } from '../../hooks/useKeypress.js';
+import { theme } from '../../semantic-colors.js';
export interface ToolConfirmationMessageProps {
confirmationDetails: ToolCallConfirmationDetails;
@@ -113,13 +113,13 @@ export const ToolConfirmationMessage: React.FC<
- Modify in progress:
-
+ Modify in progress:
+
Save and close external editor to continue
@@ -193,7 +193,7 @@ export const ToolConfirmationMessage: React.FC<
maxWidth={Math.max(childWidth - 4, 1)}
>
- {executionProps.command}
+ {executionProps.command}
@@ -223,12 +223,12 @@ export const ToolConfirmationMessage: React.FC<
bodyContent = (
-
+
{displayUrls && infoProps.urls && infoProps.urls.length > 0 && (
- URLs to fetch:
+ URLs to fetch:
{infoProps.urls.map((url) => (
{' '}
@@ -245,8 +245,8 @@ export const ToolConfirmationMessage: React.FC<
bodyContent = (
- MCP Server: {mcpProps.serverName}
- Tool: {mcpProps.toolName}
+ MCP Server: {mcpProps.serverName}
+ Tool: {mcpProps.toolName}
);
@@ -281,7 +281,9 @@ export const ToolConfirmationMessage: React.FC<
{/* Confirmation Question */}
- {question}
+
+ {question}
+
{/* Select Input for Options */}
diff --git a/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx b/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx
index bfa2db3343..65ac70a58c 100644
--- a/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx
+++ b/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx
@@ -122,7 +122,9 @@ export const ToolGroupMessage: React.FC = ({
)}
{tool.outputFile && (
- Output too long and was saved to: {tool.outputFile}
+
+ Output too long and was saved to: {tool.outputFile}
+
)}
diff --git a/packages/cli/src/ui/components/messages/ToolMessage.tsx b/packages/cli/src/ui/components/messages/ToolMessage.tsx
index c4e5b6baf4..e5e193067c 100644
--- a/packages/cli/src/ui/components/messages/ToolMessage.tsx
+++ b/packages/cli/src/ui/components/messages/ToolMessage.tsx
@@ -9,11 +9,11 @@ import { Box, Text } from 'ink';
import type { IndividualToolCallDisplay } from '../../types.js';
import { ToolCallStatus } from '../../types.js';
import { DiffRenderer } from './DiffRenderer.js';
-import { Colors } from '../../colors.js';
import { MarkdownDisplay } from '../../utils/MarkdownDisplay.js';
import { GeminiRespondingSpinner } from '../GeminiRespondingSpinner.js';
import { MaxSizedBox } from '../shared/MaxSizedBox.js';
import { TOOL_STATUS } from '../../constants.js';
+import { theme } from '../../semantic-colors.js';
const STATIC_HEIGHT = 1;
const RESERVED_LINE_COUNT = 5; // for tool name, status, padding etc.
@@ -120,7 +120,7 @@ const ToolStatusIndicator: React.FC = ({
}) => (
{status === ToolCallStatus.Pending && (
- {TOOL_STATUS.PENDING}
+ {TOOL_STATUS.PENDING}
)}
{status === ToolCallStatus.Executing && (
= ({
/>
)}
{status === ToolCallStatus.Success && (
-
+
{TOOL_STATUS.SUCCESS}
)}
{status === ToolCallStatus.Confirming && (
-
+
{TOOL_STATUS.CONFIRMING}
)}
{status === ToolCallStatus.Canceled && (
-
+
{TOOL_STATUS.CANCELED}
)}
{status === ToolCallStatus.Error && (
-
+
{TOOL_STATUS.ERROR}
)}
@@ -166,11 +166,11 @@ const ToolInfo: React.FC = ({
const nameColor = React.useMemo(() => {
switch (emphasis) {
case 'high':
- return Colors.Foreground;
+ return theme.text.primary;
case 'medium':
- return Colors.Foreground;
+ return theme.text.primary;
case 'low':
- return Colors.Gray;
+ return theme.text.secondary;
default: {
const exhaustiveCheck: never = emphasis;
return exhaustiveCheck;
@@ -186,14 +186,14 @@ const ToolInfo: React.FC = ({
{name}
{' '}
- {description}
+ {description}
);
};
const TrailingIndicator: React.FC = () => (
-
+
{' '}
←
diff --git a/packages/cli/src/ui/components/messages/UserMessage.tsx b/packages/cli/src/ui/components/messages/UserMessage.tsx
index 4f279a747f..2de3ed0df8 100644
--- a/packages/cli/src/ui/components/messages/UserMessage.tsx
+++ b/packages/cli/src/ui/components/messages/UserMessage.tsx
@@ -6,7 +6,7 @@
import type React from 'react';
import { Text, Box } from 'ink';
-import { Colors } from '../../colors.js';
+import { theme } from '../../semantic-colors.js';
import { SCREEN_READER_USER_PREFIX } from '../../textConstants.js';
import { isSlashCommand as checkIsSlashCommand } from '../../utils/commandUtils.js';
@@ -19,8 +19,8 @@ export const UserMessage: React.FC = ({ text }) => {
const prefixWidth = prefix.length;
const isSlashCommand = checkIsSlashCommand(text);
- const textColor = isSlashCommand ? Colors.AccentPurple : Colors.Gray;
- const borderColor = isSlashCommand ? Colors.AccentPurple : Colors.Gray;
+ const textColor = isSlashCommand ? theme.text.accent : theme.text.secondary;
+ const borderColor = isSlashCommand ? theme.text.accent : theme.text.secondary;
return (
= ({ text }) => {
return (
- $
- {commandToDisplay}
+ $
+ {commandToDisplay}
);
};
diff --git a/packages/cli/src/ui/components/shared/MaxSizedBox.tsx b/packages/cli/src/ui/components/shared/MaxSizedBox.tsx
index 74092324a7..86b36cd28d 100644
--- a/packages/cli/src/ui/components/shared/MaxSizedBox.tsx
+++ b/packages/cli/src/ui/components/shared/MaxSizedBox.tsx
@@ -7,7 +7,7 @@
import React, { Fragment, useEffect, useId } from 'react';
import { Box, Text } from 'ink';
import stringWidth from 'string-width';
-import { Colors } from '../../colors.js';
+import { theme } from '../../semantic-colors.js';
import { toCodePoints } from '../../utils/textUtils.js';
import { useOverflowActions } from '../../contexts/OverflowContext.js';
@@ -186,14 +186,14 @@ export const MaxSizedBox: React.FC = ({
return (
{totalHiddenLines > 0 && overflowDirection === 'top' && (
-
+
... first {totalHiddenLines} line{totalHiddenLines === 1 ? '' : 's'}{' '}
hidden ...
)}
{visibleLines}
{totalHiddenLines > 0 && overflowDirection === 'bottom' && (
-
+
... last {totalHiddenLines} line{totalHiddenLines === 1 ? '' : 's'}{' '}
hidden ...
diff --git a/packages/cli/src/ui/components/shared/RadioButtonSelect.tsx b/packages/cli/src/ui/components/shared/RadioButtonSelect.tsx
index 719d263b96..ab62e5d1b1 100644
--- a/packages/cli/src/ui/components/shared/RadioButtonSelect.tsx
+++ b/packages/cli/src/ui/components/shared/RadioButtonSelect.tsx
@@ -7,7 +7,7 @@
import type React from 'react';
import { useEffect, useState, useRef } from 'react';
import { Text, Box } from 'ink';
-import { Colors } from '../../colors.js';
+import { theme } from '../../semantic-colors.js';
import { useKeypress } from '../../hooks/useKeypress.js';
/**
@@ -164,7 +164,9 @@ export function RadioButtonSelect({
return (
{showScrollArrows && (
- 0 ? Colors.Foreground : Colors.Gray}>
+ 0 ? theme.text.primary : theme.text.secondary}
+ >
▲
)}
@@ -172,18 +174,18 @@ export function RadioButtonSelect({
const itemIndex = scrollOffset + index;
const isSelected = activeIndex === itemIndex;
- let textColor = Colors.Foreground;
- let numberColor = Colors.Foreground;
+ let textColor = theme.text.primary;
+ let numberColor = theme.text.primary;
if (isSelected) {
- textColor = Colors.AccentGreen;
- numberColor = Colors.AccentGreen;
+ textColor = theme.status.success;
+ numberColor = theme.status.success;
} else if (item.disabled) {
- textColor = Colors.Gray;
- numberColor = Colors.Gray;
+ textColor = theme.text.secondary;
+ numberColor = theme.text.secondary;
}
if (!showNumbers) {
- numberColor = Colors.Gray;
+ numberColor = theme.text.secondary;
}
const numberColumnWidth = String(items.length).length;
@@ -195,7 +197,7 @@ export function RadioButtonSelect({
{isSelected ? '●' : ' '}
@@ -212,7 +214,9 @@ export function RadioButtonSelect({
{item.themeNameDisplay && item.themeTypeDisplay ? (
{item.themeNameDisplay}{' '}
- {item.themeTypeDisplay}
+
+ {item.themeTypeDisplay}
+
) : (
@@ -226,8 +230,8 @@ export function RadioButtonSelect({
▼
diff --git a/packages/cli/src/ui/privacy/CloudFreePrivacyNotice.tsx b/packages/cli/src/ui/privacy/CloudFreePrivacyNotice.tsx
index a1c279304e..b6be9a7269 100644
--- a/packages/cli/src/ui/privacy/CloudFreePrivacyNotice.tsx
+++ b/packages/cli/src/ui/privacy/CloudFreePrivacyNotice.tsx
@@ -9,7 +9,7 @@ import { RadioButtonSelect } from '../components/shared/RadioButtonSelect.js';
import { usePrivacySettings } from '../hooks/usePrivacySettings.js';
import { CloudPaidPrivacyNotice } from './CloudPaidPrivacyNotice.js';
import type { Config } from '@google/gemini-cli-core';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { useKeypress } from '../hooks/useKeypress.js';
interface CloudFreePrivacyNoticeProps {
@@ -34,16 +34,16 @@ export const CloudFreePrivacyNotice = ({
);
if (privacyState.isLoading) {
- return Loading...;
+ return Loading...;
}
if (privacyState.error) {
return (
-
+
Error loading Opt-in settings: {privacyState.error}
- Press Esc to exit.
+ Press Esc to exit.
);
}
@@ -59,17 +59,17 @@ export const CloudFreePrivacyNotice = ({
return (
-
+
Gemini Code Assist for Individuals Privacy Notice
-
+
This notice and our Privacy Policy
- [1] describe how Gemini Code
- Assist handles your data. Please read them carefully.
+ [1] describe how Gemini Code Assist
+ handles your data. Please read them carefully.
-
+
When you use Gemini Code Assist for individuals with Gemini CLI, Google
collects your prompts, related code, generated output, code edits,
related feature usage information, and your feedback to provide,
@@ -77,7 +77,7 @@ export const CloudFreePrivacyNotice = ({
technologies.
-
+
To help with quality and improve our products (such as generative
machine-learning models), human reviewers may read, annotate, and
process the data collected above. We take steps to protect your privacy
@@ -90,7 +90,7 @@ export const CloudFreePrivacyNotice = ({
-
+
Allow Google to use this data to develop and improve our products?
- [1]{' '}
+ [1]{' '}
https://policies.google.com/privacy
- Press Enter to choose an option and exit.
+
+ Press Enter to choose an option and exit.
+
);
};
diff --git a/packages/cli/src/ui/privacy/CloudPaidPrivacyNotice.tsx b/packages/cli/src/ui/privacy/CloudPaidPrivacyNotice.tsx
index f0adbb68e2..ce640308ec 100644
--- a/packages/cli/src/ui/privacy/CloudPaidPrivacyNotice.tsx
+++ b/packages/cli/src/ui/privacy/CloudPaidPrivacyNotice.tsx
@@ -5,7 +5,7 @@
*/
import { Box, Newline, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { useKeypress } from '../hooks/useKeypress.js';
interface CloudPaidPrivacyNoticeProps {
@@ -26,14 +26,14 @@ export const CloudPaidPrivacyNotice = ({
return (
-
+
Vertex AI Notice
-
- Service Specific Terms[1] are
+
+ Service Specific Terms[1] are
incorporated into the agreement under which Google has agreed to provide
- Google Cloud Platform[2] to
+ Google Cloud Platform[2] to
Customer (the “Agreement”). If the Agreement authorizes the resale or
supply of Google Cloud Platform under a Google Cloud partner or reseller
program, then except for in the section entitled “Partner-Specific
@@ -44,16 +44,16 @@ export const CloudPaidPrivacyNotice = ({
them in the Agreement.
-
- [1]{' '}
+
+ [1]{' '}
https://cloud.google.com/terms/service-terms
-
- [2]{' '}
+
+ [2]{' '}
https://cloud.google.com/terms/services
- Press Esc to exit.
+ Press Esc to exit.
);
};
diff --git a/packages/cli/src/ui/privacy/GeminiPrivacyNotice.tsx b/packages/cli/src/ui/privacy/GeminiPrivacyNotice.tsx
index c0eaa74f2d..1f4015b5c2 100644
--- a/packages/cli/src/ui/privacy/GeminiPrivacyNotice.tsx
+++ b/packages/cli/src/ui/privacy/GeminiPrivacyNotice.tsx
@@ -5,7 +5,7 @@
*/
import { Box, Newline, Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { useKeypress } from '../hooks/useKeypress.js';
interface GeminiPrivacyNoticeProps {
@@ -24,39 +24,39 @@ export const GeminiPrivacyNotice = ({ onExit }: GeminiPrivacyNoticeProps) => {
return (
-
+
Gemini API Key Notice
-
- By using the Gemini API[1],
- Google AI Studio
- [2], and the other Google
+
+ By using the Gemini API[1], Google
+ AI Studio
+ [2], and the other Google
developer services that reference these terms (collectively, the
"APIs" or "Services"), you are agreeing to Google
APIs Terms of Service (the "API Terms")
- [3], and the Gemini API
+ [3], and the Gemini API
Additional Terms of Service (the "Additional Terms")
- [4].
+ [4].
-
- [1]{' '}
+
+ [1]{' '}
https://ai.google.dev/docs/gemini_api_overview
-
- [2] https://aistudio.google.com/
+
+ [2] https://aistudio.google.com/
-
- [3]{' '}
+
+ [3]{' '}
https://developers.google.com/terms
-
- [4]{' '}
+
+ [4]{' '}
https://ai.google.dev/gemini-api/terms
- Press Esc to exit.
+ Press Esc to exit.
);
};
diff --git a/packages/cli/src/ui/themes/theme.ts b/packages/cli/src/ui/themes/theme.ts
index ed6db89714..c04893c669 100644
--- a/packages/cli/src/ui/themes/theme.ts
+++ b/packages/cli/src/ui/themes/theme.ts
@@ -410,31 +410,31 @@ export function createCustomTheme(customTheme: CustomTheme): Theme {
const semanticColors: SemanticColors = {
text: {
- primary: colors.Foreground,
- secondary: colors.Gray,
- link: colors.AccentBlue,
- accent: colors.AccentPurple,
+ primary: customTheme.text?.primary ?? colors.Foreground,
+ secondary: customTheme.text?.secondary ?? colors.Gray,
+ link: customTheme.text?.link ?? colors.AccentBlue,
+ accent: customTheme.text?.accent ?? colors.AccentPurple,
},
background: {
- primary: colors.Background,
+ primary: customTheme.background?.primary ?? colors.Background,
diff: {
- added: colors.DiffAdded,
- removed: colors.DiffRemoved,
+ added: customTheme.background?.diff?.added ?? colors.DiffAdded,
+ removed: customTheme.background?.diff?.removed ?? colors.DiffRemoved,
},
},
border: {
- default: colors.Gray,
- focused: colors.AccentBlue,
+ default: customTheme.border?.default ?? colors.Gray,
+ focused: customTheme.border?.focused ?? colors.AccentBlue,
},
ui: {
- comment: colors.Comment,
- symbol: colors.Gray,
- gradient: colors.GradientColors,
+ comment: customTheme.ui?.comment ?? colors.Comment,
+ symbol: customTheme.ui?.symbol ?? colors.Gray,
+ gradient: customTheme.ui?.gradient ?? colors.GradientColors,
},
status: {
- error: colors.AccentRed,
- success: colors.AccentGreen,
- warning: colors.AccentYellow,
+ error: customTheme.status?.error ?? colors.AccentRed,
+ success: customTheme.status?.success ?? colors.AccentGreen,
+ warning: customTheme.status?.warning ?? colors.AccentYellow,
},
};
diff --git a/packages/cli/src/ui/utils/InlineMarkdownRenderer.tsx b/packages/cli/src/ui/utils/InlineMarkdownRenderer.tsx
index 4c05a28f4e..4320c51967 100644
--- a/packages/cli/src/ui/utils/InlineMarkdownRenderer.tsx
+++ b/packages/cli/src/ui/utils/InlineMarkdownRenderer.tsx
@@ -6,13 +6,13 @@
import React from 'react';
import { Text } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import stringWidth from 'string-width';
// Constants for Markdown parsing
const BOLD_MARKER_LENGTH = 2; // For "**"
const ITALIC_MARKER_LENGTH = 1; // For "*" or "_"
-const STRIKETHROUGH_MARKER_LENGTH = 2; // For "~~"
+const STRIKETHROUGH_MARKER_LENGTH = 2; // For "~~")
const INLINE_CODE_MARKER_LENGTH = 1; // For "`"
const UNDERLINE_TAG_START_LENGTH = 3; // For ""
const UNDERLINE_TAG_END_LENGTH = 4; // For ""
@@ -24,7 +24,7 @@ interface RenderInlineProps {
const RenderInlineInternal: React.FC = ({ text }) => {
// Early return for plain text without markdown or URLs
if (!/[*_~`<[https?:]/.test(text)) {
- return {text};
+ return {text};
}
const nodes: React.ReactNode[] = [];
@@ -96,7 +96,7 @@ const RenderInlineInternal: React.FC = ({ text }) => {
const codeMatch = fullMatch.match(/^(`+)(.+?)\1$/s);
if (codeMatch && codeMatch[2]) {
renderedNode = (
-
+
{codeMatch[2]}
);
@@ -113,7 +113,7 @@ const RenderInlineInternal: React.FC = ({ text }) => {
renderedNode = (
{linkText}
- ({url})
+ ({url})
);
}
@@ -133,7 +133,7 @@ const RenderInlineInternal: React.FC = ({ text }) => {
);
} else if (fullMatch.match(/^https?:\/\//)) {
renderedNode = (
-
+
{fullMatch}
);
@@ -168,6 +168,6 @@ export const getPlainTextLength = (text: string): number => {
.replace(/~~(.*?)~~/g, '$1')
.replace(/`(.*?)`/g, '$1')
.replace(/(.*?)<\/u>/g, '$1')
- .replace(/\[(.*?)\]\(.*?\)/g, '$1');
+ .replace(/.*\[(.*?)\]\(.*\)/g, '$1');
return stringWidth(cleanText);
};
diff --git a/packages/cli/src/ui/utils/MarkdownDisplay.tsx b/packages/cli/src/ui/utils/MarkdownDisplay.tsx
index f5cbd84b3f..42ea164805 100644
--- a/packages/cli/src/ui/utils/MarkdownDisplay.tsx
+++ b/packages/cli/src/ui/utils/MarkdownDisplay.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { Text, Box } from 'ink';
import { EOL } from 'node:os';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { colorizeCode } from './CodeColorizer.js';
import { TableRenderer } from './TableRenderer.js';
import { RenderInline } from './InlineMarkdownRenderer.js';
@@ -174,14 +174,14 @@ const MarkdownDisplayInternal: React.FC = ({
switch (level) {
case 1:
headerNode = (
-
+
);
break;
case 2:
headerNode = (
-
+
);
@@ -195,14 +195,14 @@ const MarkdownDisplayInternal: React.FC = ({
break;
case 4:
headerNode = (
-
+
);
break;
default:
headerNode = (
-
+
);
@@ -246,7 +246,7 @@ const MarkdownDisplayInternal: React.FC = ({
} else {
addContentBlock(
-
+
,
@@ -315,7 +315,9 @@ const RenderCodeBlockInternal: React.FC = ({
// Not enough space to even show the message meaningfully
return (
- ... code is being written ...
+
+ ... code is being written ...
+
);
}
@@ -331,7 +333,7 @@ const RenderCodeBlockInternal: React.FC = ({
return (
{colorizedTruncatedCode}
- ... generating more ...
+ ... generating more ...
);
}
diff --git a/packages/cli/src/ui/utils/TableRenderer.tsx b/packages/cli/src/ui/utils/TableRenderer.tsx
index 2ec195491d..3c1af38170 100644
--- a/packages/cli/src/ui/utils/TableRenderer.tsx
+++ b/packages/cli/src/ui/utils/TableRenderer.tsx
@@ -6,7 +6,7 @@
import React from 'react';
import { Text, Box } from 'ink';
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
import { RenderInline, getPlainTextLength } from './InlineMarkdownRenderer.js';
interface TableRendererProps {
@@ -89,7 +89,7 @@ export const TableRenderer: React.FC = ({
return (
{isHeader ? (
-
+
) : (
@@ -112,7 +112,7 @@ export const TableRenderer: React.FC = ({
const borderParts = adjustedWidths.map((w) => char.horizontal.repeat(w));
const border = char.left + borderParts.join(char.middle) + char.right;
- return {border};
+ return {border};
};
// Helper function to render a table row
@@ -123,7 +123,7 @@ export const TableRenderer: React.FC = ({
});
return (
-
+
│{' '}
{renderedCells.map((cell, index) => (
diff --git a/packages/cli/src/ui/utils/displayUtils.ts b/packages/cli/src/ui/utils/displayUtils.ts
index a52c6ff045..6f6c9209db 100644
--- a/packages/cli/src/ui/utils/displayUtils.ts
+++ b/packages/cli/src/ui/utils/displayUtils.ts
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { Colors } from '../colors.js';
+import { theme } from '../semantic-colors.js';
// --- Thresholds ---
export const TOOL_SUCCESS_RATE_HIGH = 95;
@@ -23,10 +23,10 @@ export const getStatusColor = (
options: { defaultColor?: string } = {},
) => {
if (value >= thresholds.green) {
- return Colors.AccentGreen;
+ return theme.status.success;
}
if (value >= thresholds.yellow) {
- return Colors.AccentYellow;
+ return theme.status.warning;
}
- return options.defaultColor || Colors.AccentRed;
+ return options.defaultColor || theme.status.error;
};