From c6338917e5196c86f8de284af04be93d9ae0f103 Mon Sep 17 00:00:00 2001 From: claude-code-best Date: Mon, 27 Apr 2026 10:37:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=9C=81=E7=95=A5=E6=97=A7=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E7=9A=84=E4=BB=A3=E7=A0=81=20diff=20=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=EF=BC=8C=E4=BB=85=E4=BF=9D=E7=95=99=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E7=9A=84=E5=AE=8C=E6=95=B4=20diff?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Message.tsx | 7 +++++++ src/components/MessageRow.tsx | 3 +++ src/components/Messages.tsx | 7 +++++++ .../UserToolResultMessage/UserToolResultMessage.tsx | 3 +++ .../UserToolResultMessage/UserToolSuccessMessage.tsx | 8 +++++++- 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/components/Message.tsx b/src/components/Message.tsx index c069a4e1d..52f90a446 100644 --- a/src/components/Message.tsx +++ b/src/components/Message.tsx @@ -77,6 +77,8 @@ export type Props = { lastThinkingBlockId?: string | null /** UUID of the latest user bash output message (for auto-expanding) */ latestBashOutputUUID?: string | null + /** Whether to collapse diff display for this message */ + shouldCollapseDiffs?: boolean } function MessageImpl({ @@ -99,6 +101,7 @@ function MessageImpl({ isUserContinuation = false, lastThinkingBlockId, latestBashOutputUUID, + shouldCollapseDiffs, }: Props): React.ReactNode { switch (message.type) { case 'attachment': @@ -181,6 +184,7 @@ function MessageImpl({ isUserContinuation={isUserContinuation} lookups={lookups} isTranscriptMode={isTranscriptMode} + shouldCollapseDiffs={shouldCollapseDiffs} /> ))} @@ -293,6 +297,7 @@ function UserMessage({ isUserContinuation, lookups, isTranscriptMode, + shouldCollapseDiffs, }: { message: NormalizedUserMessage addMargin: boolean @@ -309,6 +314,7 @@ function UserMessage({ isUserContinuation: boolean lookups: ReturnType isTranscriptMode: boolean + shouldCollapseDiffs?: boolean }): React.ReactNode { const { columns } = useTerminalSize() switch (param.type) { @@ -344,6 +350,7 @@ function UserMessage({ verbose={verbose} width={columns - 5} isTranscriptMode={isTranscriptMode} + shouldCollapseDiffs={shouldCollapseDiffs} /> ) default: diff --git a/src/components/MessageRow.tsx b/src/components/MessageRow.tsx index dbcfe8e4e..cb74205ba 100644 --- a/src/components/MessageRow.tsx +++ b/src/components/MessageRow.tsx @@ -55,6 +55,7 @@ export type Props = { columns: number isLoading: boolean lookups: ReturnType + shouldCollapseDiffs?: boolean } /** @@ -141,6 +142,7 @@ function MessageRowImpl({ columns, isLoading, lookups, + shouldCollapseDiffs, }: Props): React.ReactNode { const isTranscriptMode = screen === 'transcript' const isGrouped = msg.type === 'grouped_tool_use' @@ -221,6 +223,7 @@ function MessageRowImpl({ isUserContinuation={isUserContinuation} lastThinkingBlockId={lastThinkingBlockId} latestBashOutputUUID={latestBashOutputUUID} + shouldCollapseDiffs={shouldCollapseDiffs} /> ) // OffscreenFreeze: the outer React.memo already bails for static messages, diff --git a/src/components/Messages.tsx b/src/components/Messages.tsx index 7bcbe96a5..a93eadfdc 100644 --- a/src/components/Messages.tsx +++ b/src/components/Messages.tsx @@ -814,6 +814,12 @@ const MessagesImpl = ({ streamingToolUseIDs, )) + // Collapse diffs for messages beyond the latest N messages. + // verbose (ctrl+o) overrides and always shows full diffs. + const DIFF_COLLAPSE_DISTANCE = 0 + const shouldCollapseDiffs = + renderableMessages.length - 1 - index > DIFF_COLLAPSE_DISTANCE + const k = messageKey(msg) const row = ( ) diff --git a/src/components/messages/UserToolResultMessage/UserToolResultMessage.tsx b/src/components/messages/UserToolResultMessage/UserToolResultMessage.tsx index abd7a8fce..17bab7bcb 100644 --- a/src/components/messages/UserToolResultMessage/UserToolResultMessage.tsx +++ b/src/components/messages/UserToolResultMessage/UserToolResultMessage.tsx @@ -27,6 +27,7 @@ type Props = { verbose: boolean width: number | string isTranscriptMode?: boolean + shouldCollapseDiffs?: boolean } export function UserToolResultMessage({ @@ -39,6 +40,7 @@ export function UserToolResultMessage({ verbose, width, isTranscriptMode, + shouldCollapseDiffs, }: Props): React.ReactNode { const toolUse = useGetToolFromMessages(param.tool_use_id, tools, lookups) if (!toolUse) { @@ -96,6 +98,7 @@ export function UserToolResultMessage({ verbose={verbose} width={width} isTranscriptMode={isTranscriptMode} + shouldCollapseDiffs={shouldCollapseDiffs} /> ) } diff --git a/src/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx b/src/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx index ff215671c..39ea9c893 100644 --- a/src/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx +++ b/src/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx @@ -33,6 +33,7 @@ type Props = { verbose: boolean width: number | string isTranscriptMode?: boolean + shouldCollapseDiffs?: boolean } export function UserToolSuccessMessage({ @@ -46,6 +47,7 @@ export function UserToolSuccessMessage({ verbose, width, isTranscriptMode, + shouldCollapseDiffs, }: Props): React.ReactNode { const [theme] = useTheme() // Hook stays inside feature() ternary so external builds don't pay a @@ -83,12 +85,16 @@ export function UserToolSuccessMessage({ } const toolResult = parsedOutput?.data ?? message.toolUseResult + // Collapse diff display for old messages (verbose/ctrl+o overrides) + const effectiveStyle = + shouldCollapseDiffs && !verbose ? 'condensed' : style + const renderedMessage = tool.renderToolResultMessage?.( toolResult as never, filterToolProgressMessages(progressMessagesForMessage), { - style, + style: effectiveStyle, theme, tools, verbose,