refactor(cli): consume simplified ToolDisplay property

This commit is contained in:
Michael Bleigh
2026-04-10 11:15:36 -07:00
parent da2fb08069
commit fbc87675f0
4 changed files with 83 additions and 3 deletions

View File

@@ -17,6 +17,7 @@ import {
isGrepResult,
isListResult,
isReadManyFilesResult,
type ToolDisplay,
} from '@google/gemini-cli-core';
import {
type IndividualToolCallDisplay,
@@ -46,6 +47,7 @@ const PAYLOAD_SCROLL_GUTTER = 4;
const PAYLOAD_MAX_WIDTH = 120 + PAYLOAD_SCROLL_GUTTER;
interface DenseToolMessageProps extends IndividualToolCallDisplay {
display?: ToolDisplay;
terminalWidth: number;
availableTerminalHeight?: number;
}
@@ -269,6 +271,7 @@ export const DenseToolMessage: React.FC<DenseToolMessageProps> = (props) => {
terminalWidth,
availableTerminalHeight,
description: originalDescription,
display,
} = props;
const settings = useSettings();
@@ -322,6 +325,58 @@ export const DenseToolMessage: React.FC<DenseToolMessageProps> = (props) => {
// State-to-View Coordination
const viewParts = useMemo((): ViewParts => {
if (display) {
const descriptionText = (
<Text color={theme.text.secondary} wrap="truncate-end">
{display.description || originalDescription}
</Text>
);
const summaryText = display.resultSummary ? (
<Text color={theme.text.accent} wrap="truncate-end">
{display.resultSummary}
</Text>
) : status === CoreToolCallStatus.Error ? (
<Text color={theme.status.error} wrap="truncate-end">
{typeof resultDisplay === 'string' ? resultDisplay : 'Failed'}
</Text>
) : undefined;
// For now, DenseToolMessage still handles complex resultDisplay types
// like FileDiff or ListResult manually if display.result is not provided
// or doesn't cover them.
if (!display.result) {
if (diff) {
return {
...getFileOpData(
diff,
status,
resultDisplay,
terminalWidth,
availableTerminalHeight,
isAlternateBuffer,
),
description: descriptionText,
summary: summaryText,
};
}
if (isListResult(resultDisplay)) {
return {
...getListResultData(resultDisplay, originalDescription),
description: descriptionText,
summary: summaryText,
};
}
}
// If we have a display.result or a simple success, use it
return {
description: descriptionText,
summary: summaryText,
payload: undefined, // Payload rendering will be updated in Step 5
};
}
if (diff) {
return getFileOpData(
diff,
@@ -383,6 +438,7 @@ export const DenseToolMessage: React.FC<DenseToolMessageProps> = (props) => {
availableTerminalHeight,
originalDescription,
isAlternateBuffer,
display,
]);
const { description, summary } = viewParts;

View File

@@ -43,6 +43,7 @@ export interface ShellToolMessageProps extends ToolMessageProps {
export const ShellToolMessage: React.FC<ShellToolMessageProps> = ({
name,
description,
display,
resultDisplay,
status,
availableTerminalHeight,
@@ -167,6 +168,7 @@ export const ShellToolMessage: React.FC<ShellToolMessageProps> = ({
name={name}
status={status}
description={description}
display={display}
emphasis={emphasis}
originalRequestName={originalRequestName}
/>

View File

@@ -21,13 +21,20 @@ import {
useFocusHint,
FocusHint,
} from './ToolShared.js';
import { type Config, CoreToolCallStatus, Kind } from '@google/gemini-cli-core';
import {
type Config,
CoreToolCallStatus,
Kind,
type ToolDisplay,
} from '@google/gemini-cli-core';
import { ShellInputPrompt } from '../ShellInputPrompt.js';
import { SUBAGENT_MAX_LINES } from '../../constants.js';
export type { TextEmphasis };
export interface ToolMessageProps extends IndividualToolCallDisplay {
description: string;
display?: ToolDisplay;
availableTerminalHeight?: number;
terminalWidth: number;
emphasis?: TextEmphasis;
@@ -44,6 +51,7 @@ export interface ToolMessageProps extends IndividualToolCallDisplay {
export const ToolMessage: React.FC<ToolMessageProps> = ({
name,
description,
display,
resultDisplay,
status,
kind,
@@ -99,6 +107,7 @@ export const ToolMessage: React.FC<ToolMessageProps> = ({
name={name}
status={status}
description={description}
display={display}
emphasis={emphasis}
progressMessage={progressMessage}
originalRequestName={originalRequestName}

View File

@@ -21,6 +21,7 @@ import {
isCompletedAskUserTool,
type ToolResultDisplay,
CoreToolCallStatus,
type ToolDisplay,
} from '@google/gemini-cli-core';
import { useInactivityTimer } from '../../hooks/useInactivityTimer.js';
import { formatCommand } from '../../key/keybindingUtils.js';
@@ -192,6 +193,7 @@ type ToolInfoProps = {
description: string;
status: CoreToolCallStatus;
emphasis: TextEmphasis;
display?: ToolDisplay;
progressMessage?: string;
originalRequestName?: string;
};
@@ -201,6 +203,7 @@ export const ToolInfo: React.FC<ToolInfoProps> = ({
description,
status: coreStatus,
emphasis,
display,
progressMessage: _progressMessage,
originalRequestName,
}) => {
@@ -223,11 +226,15 @@ export const ToolInfo: React.FC<ToolInfoProps> = ({
// Hide description for completed Ask User tools (the result display speaks for itself)
const isCompletedAskUser = isCompletedAskUserTool(name, status);
const displayName = display?.name || name;
const displayDescription = display?.description || description;
const displaySummary = display?.resultSummary;
return (
<Box overflow="hidden" height={1} flexGrow={1} flexShrink={1}>
<Text strikethrough={status === ToolCallStatus.Canceled} wrap="truncate">
<Text color={nameColor} bold>
{name}
{displayName}
</Text>
{originalRequestName && originalRequestName !== name && (
<Text color={theme.text.secondary} italic>
@@ -238,7 +245,13 @@ export const ToolInfo: React.FC<ToolInfoProps> = ({
{!isCompletedAskUser && (
<>
{' '}
<Text color={theme.text.secondary}>{description}</Text>
<Text color={theme.text.secondary}>{displayDescription}</Text>
</>
)}
{displaySummary && (
<>
<Text color={theme.text.accent}> </Text>
<Text color={theme.text.accent}>{displaySummary}</Text>
</>
)}
</Text>