fix(plan): prevent plan truncation in approval dialog by supporting unconstrained heights (#21037)

Co-authored-by: jacob314 <jacob314@gmail.com>
This commit is contained in:
Adib234
2026-03-10 15:34:10 -04:00
committed by GitHub
parent bc75a61982
commit e5615f47c4
5 changed files with 18 additions and 11 deletions

View File

@@ -1389,11 +1389,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
// Compute available terminal height based on controls measurement // Compute available terminal height based on controls measurement
const availableTerminalHeight = Math.max( const availableTerminalHeight = Math.max(
0, 0,
terminalHeight - terminalHeight - controlsHeight - backgroundShellHeight - 1,
controlsHeight -
staticExtraHeight -
2 -
backgroundShellHeight,
); );
config.setShellExecutionConfig({ config.setShellExecutionConfig({

View File

@@ -807,16 +807,21 @@ const ChoiceQuestionView: React.FC<ChoiceQuestionViewProps> = ({
const TITLE_MARGIN = 1; const TITLE_MARGIN = 1;
const FOOTER_HEIGHT = 2; // DialogFooter + margin const FOOTER_HEIGHT = 2; // DialogFooter + margin
const overhead = HEADER_HEIGHT + TITLE_MARGIN + FOOTER_HEIGHT; const overhead = HEADER_HEIGHT + TITLE_MARGIN + FOOTER_HEIGHT;
const listHeight = availableHeight const listHeight = availableHeight
? Math.max(1, availableHeight - overhead) ? Math.max(1, availableHeight - overhead)
: undefined; : undefined;
const questionHeight =
const questionHeightLimit =
listHeight && !isAlternateBuffer listHeight && !isAlternateBuffer
? Math.min(15, Math.max(1, listHeight - DIALOG_PADDING)) ? question.unconstrainedHeight
? Math.max(1, listHeight - selectionItems.length * 2)
: Math.min(15, Math.max(1, listHeight - DIALOG_PADDING))
: undefined; : undefined;
const maxItemsToShow = const maxItemsToShow =
listHeight && questionHeight listHeight && questionHeightLimit
? Math.max(1, Math.floor((listHeight - questionHeight) / 2)) ? Math.max(1, Math.floor((listHeight - questionHeightLimit) / 2))
: selectionItems.length; : selectionItems.length;
return ( return (
@@ -824,7 +829,7 @@ const ChoiceQuestionView: React.FC<ChoiceQuestionViewProps> = ({
{progressHeader} {progressHeader}
<Box marginBottom={TITLE_MARGIN}> <Box marginBottom={TITLE_MARGIN}>
<MaxSizedBox <MaxSizedBox
maxHeight={questionHeight} maxHeight={questionHeightLimit}
maxWidth={availableWidth} maxWidth={availableWidth}
overflowDirection="bottom" overflowDirection="bottom"
> >

View File

@@ -249,6 +249,7 @@ export const ExitPlanModeDialog: React.FC<ExitPlanModeDialogProps> = ({
], ],
placeholder: 'Type your feedback...', placeholder: 'Type your feedback...',
multiSelect: false, multiSelect: false,
unconstrainedHeight: false,
}, },
]} ]}
onSubmit={(answers) => { onSubmit={(answers) => {

View File

@@ -282,7 +282,10 @@ describe('ToolConfirmationQueue', () => {
// hideToolIdentity is true for ask_user -> subtracts 4 instead of 6 // hideToolIdentity is true for ask_user -> subtracts 4 instead of 6
// availableContentHeight = 19 - 4 = 15 // availableContentHeight = 19 - 4 = 15
// ToolConfirmationMessage handlesOwnUI=true -> returns full 15 // ToolConfirmationMessage handlesOwnUI=true -> returns full 15
// AskUserDialog uses 15 lines to render its multi-line question and options. // AskUserDialog allocates questionHeight = availableHeight - overhead - DIALOG_PADDING.
// listHeight = 15 - overhead (Header:0, Margin:1, Footer:2) = 12.
// maxQuestionHeight = listHeight - 4 = 8.
// 8 lines is enough for the 6-line question.
await waitFor(() => { await waitFor(() => {
expect(lastFrame()).toContain('Line 6'); expect(lastFrame()).toContain('Line 6');
expect(lastFrame()).not.toContain('lines hidden'); expect(lastFrame()).not.toContain('lines hidden');

View File

@@ -167,6 +167,8 @@ export interface Question {
multiSelect?: boolean; multiSelect?: boolean;
/** Placeholder hint text. For type='text', shown in the input field. For type='choice', shown in the "Other" custom input. */ /** Placeholder hint text. For type='text', shown in the input field. For type='choice', shown in the "Other" custom input. */
placeholder?: string; placeholder?: string;
/** Allow the question to consume more vertical space instead of being strictly capped. */
unconstrainedHeight?: boolean;
} }
export interface AskUserRequest { export interface AskUserRequest {