From 33743d347b6721f8eec537d01ad9f6a95b4c6683 Mon Sep 17 00:00:00 2001
From: Taylor Mullen <ntaylormullen@google.com>
Date: Thu, 15 May 2025 00:19:41 -0700
Subject: Fix: Prevent UI tearing and improve display of long content

This commit introduces several changes to better manage terminal height and prevent UI tearing, especially when displaying long tool outputs or when the pending history item exceeds the available terminal height.

- Calculate and utilize available terminal height in `App.tsx`, `HistoryItemDisplay.tsx`, `ToolGroupMessage.tsx`, and `ToolMessage.tsx`.
- Refresh the static display area in `App.tsx` when a pending history item is too large, working around an Ink bug (see https://github.com/vadimdemedes/ink/pull/717).
- Truncate long tool output in `ToolMessage.tsx` and indicate the number of hidden lines.
- Refactor `App.tsx` to correctly measure and account for footer height.

Fixes https://b.corp.google.com/issues/414196943
---
 packages/cli/src/ui/components/messages/ToolGroupMessage.tsx | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

(limited to 'packages/cli/src/ui/components/messages/ToolGroupMessage.tsx')

diff --git a/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx b/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx
index 35408114..33460405 100644
--- a/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx
+++ b/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx
@@ -14,18 +14,23 @@ import { Colors } from '../../colors.js';
 interface ToolGroupMessageProps {
   groupId: number;
   toolCalls: IndividualToolCallDisplay[];
+  availableTerminalHeight: number;
 }
 
 // Main component renders the border and maps the tools using ToolMessage
 export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
   groupId,
   toolCalls,
+  availableTerminalHeight,
 }) => {
   const hasPending = !toolCalls.every(
     (t) => t.status === ToolCallStatus.Success,
   );
   const borderColor = hasPending ? Colors.AccentYellow : Colors.SubtleComment;
 
+  const staticHeight = /* border */ 2 + /* marginBottom */ 1;
+  availableTerminalHeight -= staticHeight;
+
   return (
     <Box
       key={groupId}
@@ -46,13 +51,14 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
       {toolCalls.map((tool) => (
         <Box key={groupId + '-' + tool.callId} flexDirection="column">
           <ToolMessage
-            key={tool.callId} // Use callId as the key
-            callId={tool.callId} // Pass callId
+            key={tool.callId}
+            callId={tool.callId}
             name={tool.name}
             description={tool.description}
             resultDisplay={tool.resultDisplay}
             status={tool.status}
-            confirmationDetails={tool.confirmationDetails} // Pass confirmationDetails
+            confirmationDetails={tool.confirmationDetails}
+            availableTerminalHeight={availableTerminalHeight}
           />
           {tool.status === ToolCallStatus.Confirming &&
             tool.confirmationDetails && (
-- 
cgit v1.2.3

