diff --git a/docs/cli/settings.md b/docs/cli/settings.md
index 8a5c888db6..2cd0c5aa3a 100644
--- a/docs/cli/settings.md
+++ b/docs/cli/settings.md
@@ -62,7 +62,7 @@ they appear in the UI.
| 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` |
-| Hide Footer During Approval | `ui.hideFooterDuringApproval` | Hide the footer when a tool approval request is displayed. | `true` |
+| 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` |
diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md
index c523e1dbda..19bd7da0d0 100644
--- a/docs/reference/configuration.md
+++ b/docs/reference/configuration.md
@@ -275,8 +275,9 @@ their corresponding top-level category object in your `settings.json` file.
- **Description:** Hide the footer from the UI
- **Default:** `false`
-- **`ui.hideFooterDuringApproval`** (boolean):
- - **Description:** Hide the footer when a tool approval request is displayed.
+- **`ui.collapseDrawerDuringApproval`** (boolean):
+ - **Description:** Collapse the entire drawer (status, context, input, footer)
+ when a tool approval request is displayed.
- **Default:** `true`
- **`ui.newFooterLayout`** (enum):
diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts
index 98387a561e..989da8d9b1 100644
--- a/packages/cli/src/config/settingsSchema.ts
+++ b/packages/cli/src/config/settingsSchema.ts
@@ -619,14 +619,14 @@ const SETTINGS_SCHEMA = {
description: 'Hide the footer from the UI',
showInDialog: true,
},
- hideFooterDuringApproval: {
+ collapseDrawerDuringApproval: {
type: 'boolean',
- label: 'Hide Footer During Approval',
+ label: 'Collapse Drawer During Approval',
category: 'UI',
requiresRestart: false,
default: true,
description:
- 'Hide the footer when a tool approval request is displayed.',
+ 'Collapse the entire drawer (status, context, input, footer) when a tool approval request is displayed.',
showInDialog: true,
},
newFooterLayout: {
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/components/Composer.test.tsx b/packages/cli/src/ui/components/Composer.test.tsx
index ced4d3497f..21701191e7 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 () => {
@@ -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 b46e994cf9..91c4d808db 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 &&
@@ -751,8 +759,6 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
{showUiDetails &&
!settings.merged.ui.hideFooter &&
- (!hasPendingActionRequired ||
- !settings.merged.ui.hideFooterDuringApproval) &&
!isScreenReaderEnabled && }
);
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..f3c4a31839 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;
@@ -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__/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/schemas/settings.schema.json b/schemas/settings.schema.json
index 5481844531..b9165622ab 100644
--- a/schemas/settings.schema.json
+++ b/schemas/settings.schema.json
@@ -365,10 +365,10 @@
"default": false,
"type": "boolean"
},
- "hideFooterDuringApproval": {
- "title": "Hide Footer During Approval",
- "description": "Hide the footer when a tool approval request is displayed.",
- "markdownDescription": "Hide the footer when a tool approval request is displayed.\n\n- Category: `UI`\n- Requires restart: `no`\n- Default: `true`",
+ "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"
},