diff --git a/packages/cli/src/ui/AppContainer.tsx b/packages/cli/src/ui/AppContainer.tsx
index 03e001546b..c3607c7041 100644
--- a/packages/cli/src/ui/AppContainer.tsx
+++ b/packages/cli/src/ui/AppContainer.tsx
@@ -1754,7 +1754,8 @@ Logging in with Google... Restarting Gemini CLI to continue.
if (!isAlternateBuffer) {
refreshStatic();
}
- return true;
+ // Return false to allow other components (e.g. ToolConfirmationMessage) to also handle expansion.
+ return false;
} else if (
(keyMatchers[Command.FOCUS_SHELL_INPUT](key) ||
keyMatchers[Command.UNFOCUS_BACKGROUND_SHELL_LIST](key)) &&
diff --git a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx
index 113852cb8d..e440d43d65 100644
--- a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx
+++ b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx
@@ -176,7 +176,8 @@ export const ToolConfirmationMessage: React.FC<
callId,
expanded: !isMcpToolDetailsExpanded,
});
- return true;
+ // Return false to let the global app container also expand its view.
+ return false;
}
if (keyMatchers[Command.ESCAPE](key)) {
handleConfirm(ToolConfirmationOutcome.Cancel);
diff --git a/packages/cli/src/ui/components/shared/MaxSizedBox.test.tsx b/packages/cli/src/ui/components/shared/MaxSizedBox.test.tsx
index d21cebe971..6d25efffb9 100644
--- a/packages/cli/src/ui/components/shared/MaxSizedBox.test.tsx
+++ b/packages/cli/src/ui/components/shared/MaxSizedBox.test.tsx
@@ -6,7 +6,7 @@
import { render, renderWithProviders } from '../../../test-utils/render.js';
import { OverflowProvider } from '../../contexts/OverflowContext.js';
-import { MaxSizedBox } from './MaxSizedBox.js';
+import { MaxSizedBox, ceilHeight } from './MaxSizedBox.js';
import { MarkdownDisplay } from '../../utils/MarkdownDisplay.js';
import { Box, Text } from 'ink';
import { act } from 'react';
@@ -316,4 +316,17 @@ describe('', () => {
expect(lastFrame()).toMatchSnapshot();
unmount();
});
+
+ describe('ceilHeight', () => {
+ it('should round up fractional heights to next integer', () => {
+ expect(ceilHeight(2.1)).toBe(3);
+ expect(ceilHeight(2.9)).toBe(3);
+ expect(ceilHeight(2.0)).toBe(2);
+ expect(ceilHeight(0.1)).toBe(1);
+ });
+
+ it('should handle zero correctly', () => {
+ expect(ceilHeight(0)).toBe(0);
+ });
+ });
});
diff --git a/packages/cli/src/ui/components/shared/MaxSizedBox.tsx b/packages/cli/src/ui/components/shared/MaxSizedBox.tsx
index 0e3869a3f0..e659ce94b1 100644
--- a/packages/cli/src/ui/components/shared/MaxSizedBox.tsx
+++ b/packages/cli/src/ui/components/shared/MaxSizedBox.tsx
@@ -28,6 +28,9 @@ export interface MaxSizedBoxProps {
additionalHiddenLinesCount?: number;
}
+/** Ensures that fractional heights are correctly identified as overflowing. */
+export const ceilHeight = (height: number): number => Math.ceil(height);
+
/**
* A React component that constrains the size of its children and provides
* content-aware truncation when the content exceeds the specified `maxHeight`.
@@ -55,7 +58,8 @@ export const MaxSizedBox: React.FC = ({
const observer = new ResizeObserver((entries) => {
const entry = entries[0];
if (entry) {
- setContentHeight(Math.round(entry.contentRect.height));
+ // Use ceilHeight to ensure that fractional heights (e.g. from zooming) that exceed the limit are correctly identified as overflowing.
+ setContentHeight(ceilHeight(entry.contentRect.height));
}
});
observer.observe(node);