From 38cf81ade3b2e8caee2abc30261388e1fad6d96f Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 10 Sep 2025 10:00:37 -0700 Subject: [PATCH 1/8] Add accept edits mode --- packages/cli/src/ui/components/Composer.tsx | 1 + .../src/ui/components/InputPrompt.test.tsx | 2 ++ .../cli/src/ui/components/InputPrompt.tsx | 19 +++++++++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/ui/components/Composer.tsx b/packages/cli/src/ui/components/Composer.tsx index fa5322e4ae9..68ed4c8dffb 100644 --- a/packages/cli/src/ui/components/Composer.tsx +++ b/packages/cli/src/ui/components/Composer.tsx @@ -170,6 +170,7 @@ export const Composer = () => { commandContext={uiState.commandContext} shellModeActive={uiState.shellModeActive} setShellModeActive={uiActions.setShellModeActive} + approvalMode={showAutoAcceptIndicator} onEscapePromptChange={uiActions.onEscapePromptChange} focus={uiState.isFocused} vimHandleInput={uiActions.vimHandleInput} diff --git a/packages/cli/src/ui/components/InputPrompt.test.tsx b/packages/cli/src/ui/components/InputPrompt.test.tsx index 5c6fddecec2..1d842d2861b 100644 --- a/packages/cli/src/ui/components/InputPrompt.test.tsx +++ b/packages/cli/src/ui/components/InputPrompt.test.tsx @@ -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, diff --git a/packages/cli/src/ui/components/InputPrompt.tsx b/packages/cli/src/ui/components/InputPrompt.tsx index dc03b4bea52..f2b6c3698ff 100644 --- a/packages/cli/src/ui/components/InputPrompt.tsx +++ b/packages/cli/src/ui/components/InputPrompt.tsx @@ -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 = ({ suggestionsWidth, shellModeActive, setShellModeActive, + approvalMode, onEscapePromptChange, vimHandleInput, }) => { @@ -709,17 +712,29 @@ export const InputPrompt: React.FC = ({ const { inlineGhost, additionalLines } = getGhostTextLines(); + const showAutoAcceptStyling = !shellModeActive && approvalMode === ApprovalMode.AUTO_EDIT; + return ( <> {shellModeActive ? ( reverseSearchActive ? ( From 375cdf358a7dc0271f2ad0982c7b2b23e03f3756 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 10 Sep 2025 10:13:01 -0700 Subject: [PATCH 2/8] Add yolo mode styles --- .../cli/src/ui/components/InputPrompt.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/cli/src/ui/components/InputPrompt.tsx b/packages/cli/src/ui/components/InputPrompt.tsx index f2b6c3698ff..6faf623355c 100644 --- a/packages/cli/src/ui/components/InputPrompt.tsx +++ b/packages/cli/src/ui/components/InputPrompt.tsx @@ -713,6 +713,7 @@ export const InputPrompt: React.FC = ({ const { inlineGhost, additionalLines } = getGhostTextLines(); const showAutoAcceptStyling = !shellModeActive && approvalMode === ApprovalMode.AUTO_EDIT; + const showYoloStyling = !shellModeActive && approvalMode === ApprovalMode.YOLO; return ( <> @@ -721,9 +722,11 @@ export const InputPrompt: React.FC = ({ borderColor={ shellModeActive ? theme.status.warning - : showAutoAcceptStyling - ? theme.status.success - : theme.border.focused + : showYoloStyling + ? theme.status.error + : showAutoAcceptStyling + ? theme.status.success + : theme.border.focused } paddingX={1} > @@ -731,9 +734,11 @@ export const InputPrompt: React.FC = ({ color={ shellModeActive ? theme.status.warning - : showAutoAcceptStyling - ? theme.status.success - : theme.text.accent + : showYoloStyling + ? theme.status.error + : showAutoAcceptStyling + ? theme.status.success + : theme.text.accent } > {shellModeActive ? ( @@ -747,6 +752,8 @@ export const InputPrompt: React.FC = ({ ) : ( '! ' ) + ) : showYoloStyling ? ( + '* ' ) : ( '> ' )} From a14bd98c769293782fe0880b7d6ea6ec9ba184bc Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 10 Sep 2025 11:01:40 -0700 Subject: [PATCH 3/8] Format --- packages/cli/src/ui/components/InputPrompt.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/ui/components/InputPrompt.tsx b/packages/cli/src/ui/components/InputPrompt.tsx index 6faf623355c..d04d0f07642 100644 --- a/packages/cli/src/ui/components/InputPrompt.tsx +++ b/packages/cli/src/ui/components/InputPrompt.tsx @@ -712,8 +712,10 @@ export const InputPrompt: React.FC = ({ const { inlineGhost, additionalLines } = getGhostTextLines(); - const showAutoAcceptStyling = !shellModeActive && approvalMode === ApprovalMode.AUTO_EDIT; - const showYoloStyling = !shellModeActive && approvalMode === ApprovalMode.YOLO; + const showAutoAcceptStyling = + !shellModeActive && approvalMode === ApprovalMode.AUTO_EDIT; + const showYoloStyling = + !shellModeActive && approvalMode === ApprovalMode.YOLO; return ( <> From f37f1a183e1049c6cc1dcc77a21a7d81d1f3c89a Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 10 Sep 2025 11:44:13 -0700 Subject: [PATCH 4/8] Refactor logic --- .../cli/src/ui/components/InputPrompt.tsx | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/packages/cli/src/ui/components/InputPrompt.tsx b/packages/cli/src/ui/components/InputPrompt.tsx index d04d0f07642..08053bbd9b7 100644 --- a/packages/cli/src/ui/components/InputPrompt.tsx +++ b/packages/cli/src/ui/components/InputPrompt.tsx @@ -717,31 +717,24 @@ export const InputPrompt: React.FC = ({ const showYoloStyling = !shellModeActive && approvalMode === ApprovalMode.YOLO; + let statusColor: string | undefined; + if (shellModeActive) { + statusColor = theme.status.warning; + } else if (showYoloStyling) { + statusColor = theme.status.error; + } else if (showAutoAcceptStyling) { + statusColor = theme.status.success; + } + return ( <> {shellModeActive ? ( reverseSearchActive ? ( From ff58427f7846924e5d9544248060a0bc024df176 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 10 Sep 2025 12:10:36 -0700 Subject: [PATCH 5/8] Update colors to use cyan for shell mode, warning for accept edits --- packages/cli/src/ui/components/AutoAcceptIndicator.tsx | 2 +- packages/cli/src/ui/components/Footer.tsx | 4 ++-- packages/cli/src/ui/components/InputPrompt.tsx | 4 ++-- packages/cli/src/ui/components/ShellModeIndicator.tsx | 2 +- packages/cli/src/ui/themes/theme.ts | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/ui/components/AutoAcceptIndicator.tsx b/packages/cli/src/ui/components/AutoAcceptIndicator.tsx index 2fbc20bfdd6..c72d366bb15 100644 --- a/packages/cli/src/ui/components/AutoAcceptIndicator.tsx +++ b/packages/cli/src/ui/components/AutoAcceptIndicator.tsx @@ -22,7 +22,7 @@ export const AutoAcceptIndicator: React.FC = ({ switch (approvalMode) { case ApprovalMode.AUTO_EDIT: - textColor = theme.status.success; + textColor = theme.status.warning; textContent = 'accepting edits'; subText = ' (shift + tab to toggle)'; break; diff --git a/packages/cli/src/ui/components/Footer.tsx b/packages/cli/src/ui/components/Footer.tsx index f1cb7445fcb..d3bfbf064c9 100644 --- a/packages/cli/src/ui/components/Footer.tsx +++ b/packages/cli/src/ui/components/Footer.tsx @@ -138,7 +138,7 @@ export const Footer: React.FC = ({ {corgiMode && ( - | + | @@ -148,7 +148,7 @@ export const Footer: React.FC = ({ )} {!showErrorDetails && errorCount > 0 && ( - | + | )} diff --git a/packages/cli/src/ui/components/InputPrompt.tsx b/packages/cli/src/ui/components/InputPrompt.tsx index 6889426cbe0..551165b468f 100644 --- a/packages/cli/src/ui/components/InputPrompt.tsx +++ b/packages/cli/src/ui/components/InputPrompt.tsx @@ -719,11 +719,11 @@ export const InputPrompt: React.FC = ({ let statusColor: string | undefined; if (shellModeActive) { - statusColor = theme.status.warning; + statusColor = theme.ui.symbol; } else if (showYoloStyling) { statusColor = theme.status.error; } else if (showAutoAcceptStyling) { - statusColor = theme.status.success; + statusColor = theme.status.warning; } return ( diff --git a/packages/cli/src/ui/components/ShellModeIndicator.tsx b/packages/cli/src/ui/components/ShellModeIndicator.tsx index 6fbde05c688..10370d2e553 100644 --- a/packages/cli/src/ui/components/ShellModeIndicator.tsx +++ b/packages/cli/src/ui/components/ShellModeIndicator.tsx @@ -10,7 +10,7 @@ import { theme } from '../semantic-colors.js'; export const ShellModeIndicator: React.FC = () => ( - + shell mode enabled (esc to disable) diff --git a/packages/cli/src/ui/themes/theme.ts b/packages/cli/src/ui/themes/theme.ts index c04893c6695..df33a59a108 100644 --- a/packages/cli/src/ui/themes/theme.ts +++ b/packages/cli/src/ui/themes/theme.ts @@ -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: { From 124f680c80d08129d8929e96b8dfb7cde1af76d8 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 10 Sep 2025 12:12:54 -0700 Subject: [PATCH 6/8] Remove extra space from cases, move to its own line --- packages/cli/src/ui/components/InputPrompt.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/ui/components/InputPrompt.tsx b/packages/cli/src/ui/components/InputPrompt.tsx index 551165b468f..2a843eff668 100644 --- a/packages/cli/src/ui/components/InputPrompt.tsx +++ b/packages/cli/src/ui/components/InputPrompt.tsx @@ -745,13 +745,13 @@ export const InputPrompt: React.FC = ({ (r:){' '} ) : ( - '! ' + '!' ) ) : showYoloStyling ? ( - '* ' + '*' ) : ( - '> ' - )} + '>' + )}{' '} {buffer.text.length === 0 && placeholder ? ( From bdd0dbec49e118a5e085cea9abf16902bdd5c026 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 10 Sep 2025 12:54:09 -0700 Subject: [PATCH 7/8] Add snapshot tests --- .../src/ui/components/InputPrompt.test.tsx | 32 +++++++++++++++++++ .../__snapshots__/InputPrompt.test.tsx.snap | 19 +++++++++++ 2 files changed, 51 insertions(+) create mode 100644 packages/cli/src/ui/components/__snapshots__/InputPrompt.test.tsx.snap diff --git a/packages/cli/src/ui/components/InputPrompt.test.tsx b/packages/cli/src/ui/components/InputPrompt.test.tsx index 1d842d2861b..888fff0bca7 100644 --- a/packages/cli/src/ui/components/InputPrompt.test.tsx +++ b/packages/cli/src/ui/components/InputPrompt.test.tsx @@ -1788,4 +1788,36 @@ describe('InputPrompt', () => { unmount(); }); }); + + describe('snapshots', () => { + it('should render correctly in shell mode', async () => { + props.shellModeActive = true; + const { stdout, unmount } = renderWithProviders( + , + ); + await wait(); + expect(stdout.lastFrame()).toMatchSnapshot(); + unmount(); + }); + + it('should render correctly when accepting edits', async () => { + props.approvalMode = ApprovalMode.AUTO_EDIT; + const { stdout, unmount } = renderWithProviders( + , + ); + await wait(); + expect(stdout.lastFrame()).toMatchSnapshot(); + unmount(); + }); + + it('should render correctly in yolo mode', async () => { + props.approvalMode = ApprovalMode.YOLO; + const { stdout, unmount } = renderWithProviders( + , + ); + await wait(); + expect(stdout.lastFrame()).toMatchSnapshot(); + unmount(); + }); + }); }); diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/InputPrompt.test.tsx.snap new file mode 100644 index 00000000000..b955931d417 --- /dev/null +++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt.test.tsx.snap @@ -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 │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────╯" +`; From dc30cf6c492d85b657bc8dba7cf4f05b2f2c805a Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 10 Sep 2025 12:57:13 -0700 Subject: [PATCH 8/8] Add aria label for announcing modes --- packages/cli/src/ui/components/InputPrompt.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/ui/components/InputPrompt.tsx b/packages/cli/src/ui/components/InputPrompt.tsx index 2a843eff668..8fe6fb82f56 100644 --- a/packages/cli/src/ui/components/InputPrompt.tsx +++ b/packages/cli/src/ui/components/InputPrompt.tsx @@ -718,12 +718,16 @@ export const InputPrompt: React.FC = ({ !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 ( @@ -735,7 +739,10 @@ export const InputPrompt: React.FC = ({ } paddingX={1} > - + {shellModeActive ? ( reverseSearchActive ? (