feat(ui): make accept edits & yolo mode match shell mode styles (#8200)

This commit is contained in:
Miguel Solorio
2025-09-11 10:34:29 -07:00
committed by GitHub
parent ba85aa49c7
commit 6be054513b
8 changed files with 89 additions and 15 deletions

View File

@@ -22,7 +22,7 @@ export const AutoAcceptIndicator: React.FC<AutoAcceptIndicatorProps> = ({
switch (approvalMode) {
case ApprovalMode.AUTO_EDIT:
textColor = theme.status.success;
textColor = theme.status.warning;
textContent = 'accepting edits';
subText = ' (shift + tab to toggle)';
break;

View File

@@ -174,6 +174,7 @@ export const Composer = () => {
commandContext={uiState.commandContext}
shellModeActive={uiState.shellModeActive}
setShellModeActive={uiActions.setShellModeActive}
approvalMode={showAutoAcceptIndicator}
onEscapePromptChange={uiActions.onEscapePromptChange}
focus={uiState.isFocused}
vimHandleInput={uiActions.vimHandleInput}

View File

@@ -138,7 +138,7 @@ export const Footer: React.FC<FooterProps> = ({
<Box alignItems="center" paddingLeft={2}>
{corgiMode && (
<Text>
<Text color={theme.ui.symbol}>| </Text>
<Text color={theme.ui.comment}>| </Text>
<Text color={theme.status.error}></Text>
<Text color={theme.text.primary}>(´</Text>
<Text color={theme.status.error}></Text>
@@ -148,7 +148,7 @@ export const Footer: React.FC<FooterProps> = ({
)}
{!showErrorDetails && errorCount > 0 && (
<Box>
<Text color={theme.ui.symbol}>| </Text>
<Text color={theme.ui.comment}>| </Text>
<ConsoleSummaryDisplay errorCount={errorCount} />
</Box>
)}

View File

@@ -10,6 +10,7 @@ import type { InputPromptProps } from './InputPrompt.js';
import { InputPrompt } from './InputPrompt.js';
import type { TextBuffer } from './shared/text-buffer.js';
import type { Config } from '@google/gemini-cli-core';
import { ApprovalMode } from '@google/gemini-cli-core';
import * as path from 'node:path';
import type { CommandContext, SlashCommand } from '../commands/types.js';
import { CommandKind } from '../commands/types.js';
@@ -207,6 +208,7 @@ describe('InputPrompt', () => {
commandContext: mockCommandContext,
shellModeActive: false,
setShellModeActive: vi.fn(),
approvalMode: ApprovalMode.DEFAULT,
inputWidth: 80,
suggestionsWidth: 80,
focus: true,
@@ -1786,4 +1788,36 @@ describe('InputPrompt', () => {
unmount();
});
});
describe('snapshots', () => {
it('should render correctly in shell mode', async () => {
props.shellModeActive = true;
const { stdout, unmount } = renderWithProviders(
<InputPrompt {...props} />,
);
await wait();
expect(stdout.lastFrame()).toMatchSnapshot();
unmount();
});
it('should render correctly when accepting edits', async () => {
props.approvalMode = ApprovalMode.AUTO_EDIT;
const { stdout, unmount } = renderWithProviders(
<InputPrompt {...props} />,
);
await wait();
expect(stdout.lastFrame()).toMatchSnapshot();
unmount();
});
it('should render correctly in yolo mode', async () => {
props.approvalMode = ApprovalMode.YOLO;
const { stdout, unmount } = renderWithProviders(
<InputPrompt {...props} />,
);
await wait();
expect(stdout.lastFrame()).toMatchSnapshot();
unmount();
});
});
});

View File

@@ -23,6 +23,7 @@ import { useKeypress } from '../hooks/useKeypress.js';
import { keyMatchers, Command } from '../keyMatchers.js';
import type { CommandContext, SlashCommand } from '../commands/types.js';
import type { Config } from '@google/gemini-cli-core';
import { ApprovalMode } from '@google/gemini-cli-core';
import { parseInputForHighlighting } from '../utils/highlight.js';
import {
clipboardHasImage,
@@ -46,6 +47,7 @@ export interface InputPromptProps {
suggestionsWidth: number;
shellModeActive: boolean;
setShellModeActive: (value: boolean) => void;
approvalMode: ApprovalMode;
onEscapePromptChange?: (showPrompt: boolean) => void;
vimHandleInput?: (key: Key) => boolean;
}
@@ -64,6 +66,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
suggestionsWidth,
shellModeActive,
setShellModeActive,
approvalMode,
onEscapePromptChange,
vimHandleInput,
}) => {
@@ -709,21 +712,36 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
const { inlineGhost, additionalLines } = getGhostTextLines();
const showAutoAcceptStyling =
!shellModeActive && approvalMode === ApprovalMode.AUTO_EDIT;
const showYoloStyling =
!shellModeActive && approvalMode === ApprovalMode.YOLO;
let statusColor: string | undefined;
let statusText = '';
if (shellModeActive) {
statusColor = theme.ui.symbol;
statusText = 'Shell mode';
} else if (showYoloStyling) {
statusColor = theme.status.error;
statusText = 'YOLO mode';
} else if (showAutoAcceptStyling) {
statusColor = theme.status.warning;
statusText = 'Accepting edits';
}
return (
<>
<Box
borderStyle="round"
borderColor={
shellModeActive
? theme.status.warning
: focus
? theme.border.focused
: theme.border.default
statusColor ?? (focus ? theme.border.focused : theme.border.default)
}
paddingX={1}
>
<Text
color={shellModeActive ? theme.status.warning : theme.text.accent}
color={statusColor ?? theme.text.accent}
aria-label={statusText || undefined}
>
{shellModeActive ? (
reverseSearchActive ? (
@@ -734,11 +752,13 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
(r:){' '}
</Text>
) : (
'! '
'!'
)
) : showYoloStyling ? (
'*'
) : (
'> '
)}
'>'
)}{' '}
</Text>
<Box flexGrow={1} flexDirection="column">
{buffer.text.length === 0 && placeholder ? (

View File

@@ -10,7 +10,7 @@ import { theme } from '../semantic-colors.js';
export const ShellModeIndicator: React.FC = () => (
<Box>
<Text color={theme.status.warning}>
<Text color={theme.ui.symbol}>
shell mode enabled
<Text color={theme.text.secondary}> (esc to disable)</Text>
</Text>

View File

@@ -0,0 +1,19 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`InputPrompt > snapshots > should render correctly in shell mode 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ! Type your message or @path/to/file │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`InputPrompt > snapshots > should render correctly in yolo mode 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * Type your message or @path/to/file │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`InputPrompt > snapshots > should render correctly when accepting edits 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ > Type your message or @path/to/file │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;

View File

@@ -174,8 +174,8 @@ export class Theme {
focused: this.colors.AccentBlue,
},
ui: {
comment: this.colors.Comment,
symbol: this.colors.Gray,
comment: this.colors.Gray,
symbol: this.colors.AccentCyan,
gradient: this.colors.GradientColors,
},
status: {