diff --git a/docs/cli/settings.md b/docs/cli/settings.md index 3597cd2387..2cd0c5aa3a 100644 --- a/docs/cli/settings.md +++ b/docs/cli/settings.md @@ -43,37 +43,40 @@ they appear in the UI. ### UI -| UI Label | Setting | Description | Default | -| ------------------------------------ | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| Auto Theme Switching | `ui.autoThemeSwitching` | Automatically switch between default light and dark themes based on terminal background color. | `true` | -| Terminal Background Polling Interval | `ui.terminalBackgroundPollingInterval` | Interval in seconds to poll the terminal background color. | `60` | -| Hide Window Title | `ui.hideWindowTitle` | Hide the window title bar | `false` | -| Inline Thinking | `ui.inlineThinkingMode` | Display model thinking inline: off or full. | `"off"` | -| Show Thoughts in Title | `ui.showStatusInTitle` | Show Gemini CLI model thoughts in the terminal window title during the working phase | `false` | -| Dynamic Window Title | `ui.dynamicWindowTitle` | Update the terminal window title with current status icons (Ready: ◇, Action Required: ✋, Working: ✦) | `true` | -| Show Home Directory Warning | `ui.showHomeDirectoryWarning` | Show a warning when running Gemini CLI in the home directory. | `true` | -| Show Compatibility Warnings | `ui.showCompatibilityWarnings` | Show warnings about terminal or OS compatibility issues. | `true` | -| Hide Tips | `ui.hideTips` | Hide helpful tips in the UI | `false` | -| Show Shortcuts Hint | `ui.showShortcutsHint` | Show the "? for shortcuts" hint above the input. | `true` | -| Hide Banner | `ui.hideBanner` | Hide the application banner | `false` | -| Hide Context Summary | `ui.hideContextSummary` | Hide the context summary (GEMINI.md, MCP servers) above the input. | `false` | -| Hide CWD | `ui.footer.hideCWD` | Hide the current working directory in the footer. | `false` | -| Hide Sandbox Status | `ui.footer.hideSandboxStatus` | Hide the sandbox status indicator in the footer. | `false` | -| Hide Model Info | `ui.footer.hideModelInfo` | Hide the model name and context usage in the footer. | `false` | -| Hide Context Window Percentage | `ui.footer.hideContextPercentage` | Hides the context window remaining percentage. | `true` | -| Hide Footer | `ui.hideFooter` | Hide the footer from the UI | `false` | -| Show Memory Usage | `ui.showMemoryUsage` | Display memory usage information in the UI | `false` | -| Show Line Numbers | `ui.showLineNumbers` | Show line numbers in the chat. | `true` | -| Show Citations | `ui.showCitations` | Show citations for generated text in the chat. | `false` | -| Show Model Info In Chat | `ui.showModelInfoInChat` | Show the model name in the chat for each model turn. | `false` | -| Show User Identity | `ui.showUserIdentity` | Show the logged-in user's identity (e.g. email) in the UI. | `true` | -| Use Alternate Screen Buffer | `ui.useAlternateBuffer` | Use an alternate screen buffer for the UI, preserving shell history. | `false` | -| Use Background Color | `ui.useBackgroundColor` | Whether to use background colors in the UI. | `true` | -| Incremental Rendering | `ui.incrementalRendering` | Enable incremental rendering for the UI. This option will reduce flickering but may cause rendering artifacts. Only supported when useAlternateBuffer is enabled. | `true` | -| Show Spinner | `ui.showSpinner` | Show the spinner during operations. | `true` | -| Loading Phrases | `ui.loadingPhrases` | What to show while the model is working: tips, witty comments, both, or nothing. | `"tips"` | -| Error Verbosity | `ui.errorVerbosity` | Controls whether recoverable errors are hidden (low) or fully shown (full). | `"low"` | -| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` | +| UI Label | Setting | Description | Default | +| ------------------------------------ | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| Auto Theme Switching | `ui.autoThemeSwitching` | Automatically switch between default light and dark themes based on terminal background color. | `true` | +| Terminal Background Polling Interval | `ui.terminalBackgroundPollingInterval` | Interval in seconds to poll the terminal background color. | `60` | +| Hide Window Title | `ui.hideWindowTitle` | Hide the window title bar | `false` | +| Inline Thinking | `ui.inlineThinkingMode` | Display model thinking inline: off or full. | `"off"` | +| Show Thoughts in Title | `ui.showStatusInTitle` | Show Gemini CLI model thoughts in the terminal window title during the working phase | `false` | +| Dynamic Window Title | `ui.dynamicWindowTitle` | Update the terminal window title with current status icons (Ready: ◇, Action Required: ✋, Working: ✦) | `true` | +| Show Home Directory Warning | `ui.showHomeDirectoryWarning` | Show a warning when running Gemini CLI in the home directory. | `true` | +| Show Compatibility Warnings | `ui.showCompatibilityWarnings` | Show warnings about terminal or OS compatibility issues. | `true` | +| Hide Tips | `ui.hideTips` | Hide helpful tips in the UI | `false` | +| Show Shortcuts Hint | `ui.showShortcutsHint` | Show the "? for shortcuts" hint above the input. | `true` | +| Hide Banner | `ui.hideBanner` | Hide the application banner | `false` | +| Hide Context Summary | `ui.hideContextSummary` | Hide the context summary (GEMINI.md, MCP servers) above the input. | `false` | +| Hide CWD | `ui.footer.hideCWD` | Hide the current working directory path in the footer. | `false` | +| Hide Sandbox Status | `ui.footer.hideSandboxStatus` | Hide the sandbox status indicator in the footer. | `false` | +| Hide Model Info | `ui.footer.hideModelInfo` | Hide the model name and context usage in the footer. | `false` | +| Hide Context Window Percentage | `ui.footer.hideContextPercentage` | Hides the context window remaining percentage. | `true` | +| Hide Footer | `ui.hideFooter` | Hide the footer from the UI | `false` | +| Collapse Drawer During Approval | `ui.collapseDrawerDuringApproval` | Collapse the entire drawer (status, context, input, footer) when a tool approval request is displayed. | `true` | +| New Footer Layout | `ui.newFooterLayout` | Use the new 2-row layout with inline tips. | `"legacy"` | +| Show Tips | `ui.showTips` | Show informative tips on the right side of the status line. | `true` | +| Show Witty Phrases | `ui.showWit` | Show witty phrases while waiting. | `true` | +| Show Memory Usage | `ui.showMemoryUsage` | Display memory usage information in the UI | `false` | +| Show Line Numbers | `ui.showLineNumbers` | Show line numbers in the chat. | `true` | +| Show Citations | `ui.showCitations` | Show citations for generated text in the chat. | `false` | +| Show Model Info In Chat | `ui.showModelInfoInChat` | Show the model name in the chat for each model turn. | `false` | +| Show User Identity | `ui.showUserIdentity` | Show the logged-in user's identity (e.g. email) in the UI. | `true` | +| Use Alternate Screen Buffer | `ui.useAlternateBuffer` | Use an alternate screen buffer for the UI, preserving shell history. | `false` | +| Use Background Color | `ui.useBackgroundColor` | Whether to use background colors in the UI. | `true` | +| Incremental Rendering | `ui.incrementalRendering` | Enable incremental rendering for the UI. This option will reduce flickering but may cause rendering artifacts. Only supported when useAlternateBuffer is enabled. | `true` | +| Show Spinner | `ui.showSpinner` | Show the spinner during operations. | `true` | +| Error Verbosity | `ui.errorVerbosity` | Controls whether recoverable errors are hidden (low) or fully shown (full). | `"low"` | +| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` | ### IDE diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 13b10c00a7..6aa7a5ceb5 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -285,6 +285,11 @@ their corresponding top-level category object in your `settings.json` file. - **Description:** Hide the footer from the UI - **Default:** `false` +- **`ui.collapseDrawerDuringApproval`** (boolean): + - **Description:** Collapse the entire drawer (status, context, input, footer) + when a tool approval request is displayed. + - **Default:** `true` + - **`ui.newFooterLayout`** (enum): - **Description:** Use the new 2-row layout with inline tips. - **Default:** `"legacy"` diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts index 20b47189f3..8d93136364 100644 --- a/packages/cli/src/config/settingsSchema.ts +++ b/packages/cli/src/config/settingsSchema.ts @@ -639,6 +639,16 @@ const SETTINGS_SCHEMA = { description: 'Hide the footer from the UI', showInDialog: true, }, + collapseDrawerDuringApproval: { + type: 'boolean', + label: 'Collapse Drawer During Approval', + category: 'UI', + requiresRestart: false, + default: true, + description: + 'Collapse the entire drawer (status, context, input, footer) when a tool approval request is displayed.', + showInDialog: true, + }, newFooterLayout: { type: 'enum', label: 'New Footer Layout', diff --git a/packages/cli/src/test-utils/AppRig.tsx b/packages/cli/src/test-utils/AppRig.tsx index 3ff65c4067..55df39e1c7 100644 --- a/packages/cli/src/test-utils/AppRig.tsx +++ b/packages/cli/src/test-utils/AppRig.tsx @@ -264,6 +264,9 @@ export class AppRig { enabled: false, hasSeenNudge: true, }, + ui: { + collapseDrawerDuringApproval: false, + }, }, }); } diff --git a/packages/cli/src/ui/__snapshots__/App.test.tsx.snap b/packages/cli/src/ui/__snapshots__/App.test.tsx.snap index cfaa0d97a7..a5cd6993b4 100644 --- a/packages/cli/src/ui/__snapshots__/App.test.tsx.snap +++ b/packages/cli/src/ui/__snapshots__/App.test.tsx.snap @@ -130,7 +130,7 @@ HistoryItemDisplay │ Allow execution of: 'ls'? │ │ │ │ ● 1. Allow once │ -│ 2. Allow for this session │ +│ 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to cancel │ │ 3. No, suggest changes (esc) │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/packages/cli/src/ui/components/Composer.test.tsx b/packages/cli/src/ui/components/Composer.test.tsx index f52d887a79..76c26445c6 100644 --- a/packages/cli/src/ui/components/Composer.test.tsx +++ b/packages/cli/src/ui/components/Composer.test.tsx @@ -457,9 +457,8 @@ describe('Composer', () => { const { lastFrame } = await renderComposer(uiState); - const output = lastFrame(); - expect(output).not.toContain('LoadingIndicator'); - expect(output).not.toContain('esc to cancel'); + const output = lastFrame({ allowEmpty: true }); + expect(output).toBe(''); }); it('renders LoadingIndicator when embedded shell is focused but background shell is visible', async () => { @@ -564,7 +563,7 @@ describe('Composer', () => { const output = lastFrame(); expect(output).toContain('ToastDisplay'); expect(output).not.toContain('ApprovalModeIndicator'); - expect(output).toContain('StatusDisplay'); + expect(output).not.toContain('StatusDisplay'); }); it('shows ToastDisplay for other toast types', async () => { @@ -712,9 +711,7 @@ describe('Composer', () => { }); const { lastFrame } = await renderComposer(uiState); - const output = lastFrame(); - expect(output).not.toContain('plan'); - expect(output).not.toContain('ShortcutsHint'); + expect(lastFrame({ allowEmpty: true })).toBe(''); }); it('shows Esc rewind prompt in minimal mode without showing full UI', async () => { @@ -867,9 +864,10 @@ describe('Composer', () => { ), }); - const { lastFrame } = await renderComposer(uiState); + const { lastFrame, unmount } = await renderComposer(uiState); - expect(lastFrame()).not.toContain('ShortcutsHint'); + expect(lastFrame({ allowEmpty: true })).toBe(''); + unmount(); }); it('keeps shortcuts hint visible when no action is required', async () => { @@ -1003,24 +1001,22 @@ describe('Composer', () => { expect(lastFrame()).not.toContain('ShortcutsHelp'); unmount(); }); - it('hides shortcuts help when action is required', async () => { const uiState = createMockUIState({ shortcutsHelpVisible: true, customDialog: ( - Dialog content + Test Dialog ), }); const { lastFrame, unmount } = await renderComposer(uiState); - expect(lastFrame()).not.toContain('ShortcutsHelp'); + expect(lastFrame({ allowEmpty: true })).toBe(''); unmount(); }); }); - describe('Snapshots', () => { it('matches snapshot in idle state', async () => { const uiState = createMockUIState(); diff --git a/packages/cli/src/ui/components/Composer.tsx b/packages/cli/src/ui/components/Composer.tsx index ed9d09791e..e8c1043498 100644 --- a/packages/cli/src/ui/components/Composer.tsx +++ b/packages/cli/src/ui/components/Composer.tsx @@ -91,6 +91,7 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => { Boolean(uiState.quota.proQuotaRequest) || Boolean(uiState.quota.validationRequest) || Boolean(uiState.customDialog); + const isPassiveShortcutsHelpState = uiState.isInputActive && uiState.streamingState === StreamingState.Idle && @@ -180,6 +181,13 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => { return () => clearTimeout(timeout); }, [canShowShortcutsHint]); + if ( + hasPendingActionRequired && + settings.merged.ui.collapseDrawerDuringApproval + ) { + return null; + } + const showShortcutsHint = settings.merged.ui.showShortcutsHint && !hideShortcutsHintForSuggestions && @@ -518,28 +526,20 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => { {showShortcutsHelp && } {showUiDetails && ( - - {hasToast ? ( - - ) : ( + {hasToast ? ( + + ) : ( + <> {showApprovalIndicator && ( { {!showLoadingIndicator && ( <> {uiState.shellModeActive && ( - + )} {showRawMarkdownIndicator && ( - + )} )} - )} - - - - {!showLoadingIndicator && ( - - )} - + {!showLoadingIndicator && ( + <> + + · + + + + )} + + )} )} diff --git a/packages/cli/src/ui/components/ConsentPrompt.tsx b/packages/cli/src/ui/components/ConsentPrompt.tsx index 3f255d2606..859d29281d 100644 --- a/packages/cli/src/ui/components/ConsentPrompt.tsx +++ b/packages/cli/src/ui/components/ConsentPrompt.tsx @@ -9,6 +9,7 @@ import { type ReactNode } from 'react'; import { theme } from '../semantic-colors.js'; import { MarkdownDisplay } from '../utils/MarkdownDisplay.js'; import { RadioButtonSelect } from './shared/RadioButtonSelect.js'; +import { DialogFooter } from './shared/DialogFooter.js'; type ConsentPromptProps = { // If a simple string is given, it will render using markdown by default. @@ -37,7 +38,7 @@ export const ConsentPrompt = (props: ConsentPromptProps) => { ) : ( prompt )} - + { ]} onSelect={onConfirm} /> + ); diff --git a/packages/cli/src/ui/components/ContextSummaryDisplay.test.tsx b/packages/cli/src/ui/components/ContextSummaryDisplay.test.tsx index f48cfb2a31..43b733da3d 100644 --- a/packages/cli/src/ui/components/ContextSummaryDisplay.test.tsx +++ b/packages/cli/src/ui/components/ContextSummaryDisplay.test.tsx @@ -78,32 +78,6 @@ describe('', () => { unmount(); }); - it('should switch layout at the 80-column breakpoint', async () => { - const props = { - ...baseProps, - geminiMdFileCount: 1, - contextFileNames: ['GEMINI.md'], - mcpServers: { 'test-server': { command: 'test' } }, - ideContext: { - workspaceState: { - openFiles: [{ path: '/a/b/c', timestamp: Date.now() }], - }, - }, - }; - - // At 80 columns, should be on one line - const { lastFrame: wideFrame, unmount: unmountWide } = - await renderWithWidth(80, props); - expect(wideFrame().trim().includes('\n')).toBe(false); - unmountWide(); - - // At 79 columns, should be on multiple lines - const { lastFrame: narrowFrame, unmount: unmountNarrow } = - await renderWithWidth(79, props); - expect(narrowFrame().trim().includes('\n')).toBe(true); - expect(narrowFrame().trim().split('\n').length).toBe(4); - unmountNarrow(); - }); it('should not render empty parts', async () => { const props = { ...baseProps, diff --git a/packages/cli/src/ui/components/ContextSummaryDisplay.tsx b/packages/cli/src/ui/components/ContextSummaryDisplay.tsx index c9f67e34b3..696793bc06 100644 --- a/packages/cli/src/ui/components/ContextSummaryDisplay.tsx +++ b/packages/cli/src/ui/components/ContextSummaryDisplay.tsx @@ -8,8 +8,6 @@ import type React from 'react'; import { Box, Text } from 'ink'; 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'; interface ContextSummaryDisplayProps { geminiMdFileCount: number; @@ -30,8 +28,6 @@ export const ContextSummaryDisplay: React.FC = ({ skillCount, backgroundProcessCount = 0, }) => { - const { columns: terminalWidth } = useTerminalSize(); - const isNarrow = isNarrowWidth(terminalWidth); const mcpServerCount = Object.keys(mcpServers || {}).length; const blockedMcpServerCount = blockedMcpServers?.length || 0; const openFileCount = ideContext?.workspaceState?.openFiles?.length ?? 0; @@ -44,7 +40,7 @@ export const ContextSummaryDisplay: React.FC = ({ skillCount === 0 && backgroundProcessCount === 0 ) { - return ; // Render an empty space to reserve height + return null; } const openFilesText = (() => { @@ -113,21 +109,14 @@ export const ContextSummaryDisplay: React.FC = ({ backgroundText, ].filter(Boolean); - if (isNarrow) { - return ( - - {summaryParts.map((part, index) => ( - - - {part} - - ))} - - ); - } - return ( - - {summaryParts.join(' | ')} + + {summaryParts.map((part, index) => ( + + {index > 0 && {' · '}} + {part} + + ))} ); }; diff --git a/packages/cli/src/ui/components/__snapshots__/Composer.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/Composer.test.tsx.snap index 8e6533a556..0bffdf3d3e 100644 --- a/packages/cli/src/ui/components/__snapshots__/Composer.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/Composer.test.tsx.snap @@ -2,7 +2,7 @@ exports[`Composer > Snapshots > matches snapshot in idle state 1`] = ` " ShortcutsHint - ApprovalModeIndicator StatusDisplay + ApprovalModeIndicator ·StatusDisplay InputPrompt: Type your message or @path/to/file Footer " @@ -23,9 +23,7 @@ InputPrompt: Type your message or @path/to/file exports[`Composer > Snapshots > matches snapshot in narrow view 1`] = ` " ShortcutsHint - ApprovalModeIndicator - -StatusDisplay + ApprovalModeIndicator ·StatusDisplay InputPrompt: Type your message or @path/to/file Footer diff --git a/packages/cli/src/ui/components/__snapshots__/ContextSummaryDisplay.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/ContextSummaryDisplay.test.tsx.snap index e28d884acf..876524bdb8 100644 --- a/packages/cli/src/ui/components/__snapshots__/ContextSummaryDisplay.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/ContextSummaryDisplay.test.tsx.snap @@ -1,19 +1,16 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[` > should not render empty parts 1`] = ` -" - 1 open file (ctrl+g to view) +" 1 open file (ctrl+g to view) " `; exports[` > should render on a single line on a wide screen 1`] = ` -" 1 open file (ctrl+g to view) | 1 GEMINI.md file | 1 MCP server | 1 skill +" 1 open file (ctrl+g to view) · 1 GEMINI.md file · 1 MCP server · 1 skill " `; exports[` > should render on multiple lines on a narrow screen 1`] = ` -" - 1 open file (ctrl+g to view) - - 1 GEMINI.md file - - 1 MCP server - - 1 skill +" 1 open file (ctrl+g to view) · 1 GEMINI.md file · 1 MCP server · 1 skill " `; diff --git a/packages/cli/src/ui/components/__snapshots__/ToolConfirmationQueue.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/ToolConfirmationQueue.test.tsx.snap index a39d668825..265e4a7313 100644 --- a/packages/cli/src/ui/components/__snapshots__/ToolConfirmationQueue.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/ToolConfirmationQueue.test.tsx.snap @@ -11,8 +11,8 @@ exports[`ToolConfirmationQueue > calculates availableContentHeight based on avai │ Apply this change? │ │ │ │ ● 1. Allow once │ -│ 2. Allow for this session │ -│ 3. Modify with external editor │ +│ 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to │ +│ 3. Modify with external edi…cancel │ │ 4. No, suggest changes (esc) │ │ │ ╰──────────────────────────────────────────────────────────────────────────────╯ @@ -33,8 +33,8 @@ exports[`ToolConfirmationQueue > does not render expansion hint when constrainHe │ Apply this change? │ │ │ │ ● 1. Allow once │ -│ 2. Allow for this session │ -│ 3. Modify with external editor │ +│ 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to │ +│ 3. Modify with external edi…cancel │ │ 4. No, suggest changes (esc) │ │ │ ╰──────────────────────────────────────────────────────────────────────────────╯ @@ -101,8 +101,8 @@ exports[`ToolConfirmationQueue > renders expansion hint when content is long and │ Apply this change? │ │ │ │ ● 1. Allow once │ -│ 2. Allow for this session │ -│ 3. Modify with external editor │ +│ 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to │ +│ 3. Modify with external edi…cancel │ │ 4. No, suggest changes (esc) │ │ │ ╰──────────────────────────────────────────────────────────────────────────────╯ @@ -120,8 +120,8 @@ exports[`ToolConfirmationQueue > renders the confirming tool with progress indic │ Allow execution of: 'ls'? │ │ │ │ ● 1. Allow once │ -│ 2. Allow for this session │ -│ 3. No, suggest changes (esc) │ +│ 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to │ +│ 3. No, suggest changes (e… cancel │ │ │ ╰──────────────────────────────────────────────────────────────────────────────╯ " diff --git a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.test.tsx b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.test.tsx index b3b34ae0a8..45f0f7309d 100644 --- a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.test.tsx +++ b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.test.tsx @@ -574,7 +574,7 @@ describe('ToolConfirmationMessage', () => { const output = lastFrame(); expect(output).toContain('MCP Tool Details:'); - expect(output).toContain('(press Ctrl+O to expand MCP tool details)'); + expect(output).toContain('Ctrl+O to expand details'); expect(output).not.toContain('https://www.google.co.jp'); expect(output).not.toContain('Navigates browser to a URL.'); unmount(); @@ -606,7 +606,7 @@ describe('ToolConfirmationMessage', () => { const output = lastFrame(); expect(output).toContain('MCP Tool Details:'); - expect(output).toContain('(press Ctrl+O to expand MCP tool details)'); + expect(output).toContain('Ctrl+O to expand details'); expect(output).not.toContain('Invocation Arguments:'); unmount(); }); diff --git a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx index 022a68e953..a5951dc95b 100644 --- a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx +++ b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx @@ -40,6 +40,7 @@ import { import { AskUserDialog } from '../AskUserDialog.js'; import { ExitPlanModeDialog } from '../ExitPlanModeDialog.js'; import { WarningMessage } from './WarningMessage.js'; +import { DialogFooter } from '../shared/DialogFooter.js'; import { getDeceptiveUrlDetails, toUnicodeUrl, @@ -603,17 +604,8 @@ export const ToolConfirmationMessage: React.FC< {hasMcpToolDetails && ( MCP Tool Details: - {isMcpToolDetailsExpanded ? ( - <> - - (press {expandDetailsHintKey} to collapse MCP tool details) - - {mcpToolDetailsText} - - ) : ( - - (press {expandDetailsHintKey} to expand MCP tool details) - + {isMcpToolDetailsExpanded && ( + {mcpToolDetailsText} )} )} @@ -632,7 +624,6 @@ export const ToolConfirmationMessage: React.FC< isMcpToolDetailsExpanded, hasMcpToolDetails, mcpToolDetailsText, - expandDetailsHintKey, getPreferredEditor, ]); @@ -698,6 +689,17 @@ export const ToolConfirmationMessage: React.FC< onSelect={handleSelect} isFocused={isFocused} /> + )} diff --git a/packages/cli/src/ui/components/messages/__snapshots__/RedirectionConfirmation.test.tsx.snap b/packages/cli/src/ui/components/messages/__snapshots__/RedirectionConfirmation.test.tsx.snap index f584e7f483..c44ca0c871 100644 --- a/packages/cli/src/ui/components/messages/__snapshots__/RedirectionConfirmation.test.tsx.snap +++ b/packages/cli/src/ui/components/messages/__snapshots__/RedirectionConfirmation.test.tsx.snap @@ -8,7 +8,7 @@ Tip: Toggle auto-edit (Shift+Tab) to allow redirection in the future. Allow execution of: 'echo, redirection (>)'? ● 1. Allow once - 2. Allow for this session + 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to cancel 3. No, suggest changes (esc) " `; diff --git a/packages/cli/src/ui/components/messages/__snapshots__/ToolConfirmationMessage.test.tsx.snap b/packages/cli/src/ui/components/messages/__snapshots__/ToolConfirmationMessage.test.tsx.snap index 9e8dfe3a15..d00210cea5 100644 --- a/packages/cli/src/ui/components/messages/__snapshots__/ToolConfirmationMessage.test.tsx.snap +++ b/packages/cli/src/ui/components/messages/__snapshots__/ToolConfirmationMessage.test.tsx.snap @@ -7,7 +7,7 @@ whoami Allow execution of 3 commands? ● 1. Allow once - 2. Allow for this session + 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to cancel 3. No, suggest changes (esc) " `; @@ -20,7 +20,7 @@ URLs to fetch: Do you want to proceed? ● 1. Allow once - 2. Allow for this session + 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to cancel 3. No, suggest changes (esc) " `; @@ -30,7 +30,7 @@ exports[`ToolConfirmationMessage > should not display urls if prompt and url are Do you want to proceed? ● 1. Allow once - 2. Allow for this session + 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to cancel 3. No, suggest changes (esc) " `; @@ -41,7 +41,7 @@ Tool: testtool Allow execution of MCP tool "testtool" from server "testserver"? ● 1. Allow once - 2. Allow tool for this session + 2. Allow tool for this session Enter to select · ↑/↓ to navigate · Esc to cancel 3. Allow all server tools for this session 4. No, suggest changes (esc) " @@ -56,7 +56,7 @@ exports[`ToolConfirmationMessage > with folder trust > 'for edit confirmations' Apply this change? ● 1. Allow once - 2. Modify with external editor + 2. Modify with external editorEnter to select · ↑/↓ to navigate · Esc to cancel 3. No, suggest changes (esc) " `; @@ -70,7 +70,7 @@ exports[`ToolConfirmationMessage > with folder trust > 'for edit confirmations' Apply this change? ● 1. Allow once - 2. Allow for this session + 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to cancel 3. Modify with external editor 4. No, suggest changes (esc) " @@ -81,7 +81,7 @@ exports[`ToolConfirmationMessage > with folder trust > 'for exec confirmations' Allow execution of: 'echo'? ● 1. Allow once - 2. No, suggest changes (esc) + 2. No, suggest changes (esc)Enter to select · ↑/↓ to navigate · Esc to cancel " `; @@ -90,7 +90,7 @@ exports[`ToolConfirmationMessage > with folder trust > 'for exec confirmations' Allow execution of: 'echo'? ● 1. Allow once - 2. Allow for this session + 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to cancel 3. No, suggest changes (esc) " `; @@ -100,7 +100,7 @@ exports[`ToolConfirmationMessage > with folder trust > 'for info confirmations' Do you want to proceed? ● 1. Allow once - 2. No, suggest changes (esc) + 2. No, suggest changes (esc)Enter to select · ↑/↓ to navigate · Esc to cancel " `; @@ -109,7 +109,7 @@ exports[`ToolConfirmationMessage > with folder trust > 'for info confirmations' Do you want to proceed? ● 1. Allow once - 2. Allow for this session + 2. Allow for this session Enter to select · ↑/↓ to navigate · Esc to cancel 3. No, suggest changes (esc) " `; @@ -120,7 +120,7 @@ Tool: test-tool Allow execution of MCP tool "test-tool" from server "test-server"? ● 1. Allow once - 2. No, suggest changes (esc) + 2. No, suggest changes (esc)Enter to select · ↑/↓ to navigate · Esc to cancel " `; @@ -130,7 +130,7 @@ Tool: test-tool Allow execution of MCP tool "test-tool" from server "test-server"? ● 1. Allow once - 2. Allow tool for this session + 2. Allow tool for this session Enter to select · ↑/↓ to navigate · Esc to cancel 3. Allow all server tools for this session 4. No, suggest changes (esc) " diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json index 9f9edd0ea8..1627c48834 100644 --- a/schemas/settings.schema.json +++ b/schemas/settings.schema.json @@ -381,6 +381,13 @@ "default": false, "type": "boolean" }, + "collapseDrawerDuringApproval": { + "title": "Collapse Drawer During Approval", + "description": "Collapse the entire drawer (status, context, input, footer) when a tool approval request is displayed.", + "markdownDescription": "Collapse the entire drawer (status, context, input, footer) when a tool approval request is displayed.\n\n- Category: `UI`\n- Requires restart: `no`\n- Default: `true`", + "default": true, + "type": "boolean" + }, "newFooterLayout": { "title": "New Footer Layout", "description": "Use the new 2-row layout with inline tips.",