From e5615f47c45730839daec95ca3ca264ef1db4541 Mon Sep 17 00:00:00 2001 From: Adib234 <30782825+Adib234@users.noreply.github.com> Date: Tue, 10 Mar 2026 15:34:10 -0400 Subject: [PATCH] fix(plan): prevent plan truncation in approval dialog by supporting unconstrained heights (#21037) Co-authored-by: jacob314 --- packages/cli/src/ui/AppContainer.tsx | 6 +----- packages/cli/src/ui/components/AskUserDialog.tsx | 15 ++++++++++----- .../cli/src/ui/components/ExitPlanModeDialog.tsx | 1 + .../ui/components/ToolConfirmationQueue.test.tsx | 5 ++++- packages/core/src/confirmation-bus/types.ts | 2 ++ 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/packages/cli/src/ui/AppContainer.tsx b/packages/cli/src/ui/AppContainer.tsx index 42d40ec73a..c3288ee728 100644 --- a/packages/cli/src/ui/AppContainer.tsx +++ b/packages/cli/src/ui/AppContainer.tsx @@ -1389,11 +1389,7 @@ Logging in with Google... Restarting Gemini CLI to continue. // Compute available terminal height based on controls measurement const availableTerminalHeight = Math.max( 0, - terminalHeight - - controlsHeight - - staticExtraHeight - - 2 - - backgroundShellHeight, + terminalHeight - controlsHeight - backgroundShellHeight - 1, ); config.setShellExecutionConfig({ diff --git a/packages/cli/src/ui/components/AskUserDialog.tsx b/packages/cli/src/ui/components/AskUserDialog.tsx index 3c8ccbfb34..4233616144 100644 --- a/packages/cli/src/ui/components/AskUserDialog.tsx +++ b/packages/cli/src/ui/components/AskUserDialog.tsx @@ -807,16 +807,21 @@ const ChoiceQuestionView: React.FC = ({ const TITLE_MARGIN = 1; const FOOTER_HEIGHT = 2; // DialogFooter + margin const overhead = HEADER_HEIGHT + TITLE_MARGIN + FOOTER_HEIGHT; + const listHeight = availableHeight ? Math.max(1, availableHeight - overhead) : undefined; - const questionHeight = + + const questionHeightLimit = 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; + const maxItemsToShow = - listHeight && questionHeight - ? Math.max(1, Math.floor((listHeight - questionHeight) / 2)) + listHeight && questionHeightLimit + ? Math.max(1, Math.floor((listHeight - questionHeightLimit) / 2)) : selectionItems.length; return ( @@ -824,7 +829,7 @@ const ChoiceQuestionView: React.FC = ({ {progressHeader} diff --git a/packages/cli/src/ui/components/ExitPlanModeDialog.tsx b/packages/cli/src/ui/components/ExitPlanModeDialog.tsx index ec5a4c2a9b..4124a7c6d7 100644 --- a/packages/cli/src/ui/components/ExitPlanModeDialog.tsx +++ b/packages/cli/src/ui/components/ExitPlanModeDialog.tsx @@ -249,6 +249,7 @@ export const ExitPlanModeDialog: React.FC = ({ ], placeholder: 'Type your feedback...', multiSelect: false, + unconstrainedHeight: false, }, ]} onSubmit={(answers) => { diff --git a/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx b/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx index 7b45bd0458..ab12ae496f 100644 --- a/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx +++ b/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx @@ -282,7 +282,10 @@ describe('ToolConfirmationQueue', () => { // hideToolIdentity is true for ask_user -> subtracts 4 instead of 6 // availableContentHeight = 19 - 4 = 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(() => { expect(lastFrame()).toContain('Line 6'); expect(lastFrame()).not.toContain('lines hidden'); diff --git a/packages/core/src/confirmation-bus/types.ts b/packages/core/src/confirmation-bus/types.ts index 99df9da616..91aeab8308 100644 --- a/packages/core/src/confirmation-bus/types.ts +++ b/packages/core/src/confirmation-bus/types.ts @@ -167,6 +167,8 @@ export interface Question { multiSelect?: boolean; /** Placeholder hint text. For type='text', shown in the input field. For type='choice', shown in the "Other" custom input. */ placeholder?: string; + /** Allow the question to consume more vertical space instead of being strictly capped. */ + unconstrainedHeight?: boolean; } export interface AskUserRequest {