@@ -12,6 +12,7 @@ import type {
1212 ClineAskUseMcpServer ,
1313 ClineSayTool ,
1414} from "@roo-code/types"
15+ import type { CollapseDecision } from "@src/utils/messageSize"
1516
1617import { Mode } from "@roo/modes"
1718
@@ -43,7 +44,7 @@ import { BatchFilePermission } from "./BatchFilePermission"
4344import { BatchDiffApproval } from "./BatchDiffApproval"
4445import { ProgressIndicator } from "./ProgressIndicator"
4546import { Markdown } from "./Markdown"
46- import { CommandExecution } from "./CommandExecution"
47+ import { CommandExecution , parseCommandAndOutput } from "./CommandExecution"
4748import { CommandExecutionError } from "./CommandExecutionError"
4849import { AutoApprovedRequestLimitWarning } from "./AutoApprovedRequestLimitWarning"
4950import { InProgressRow , CondensationResultRow , CondensationErrorRow , TruncationResultRow } from "./context-management"
@@ -109,10 +110,13 @@ function getPreviousTodos(messages: ClineMessage[], currentMessageTs: number): a
109110 return [ ]
110111}
111112
113+ import { MessageCollapsePreview } from "./MessageCollapsePreview"
114+
112115interface ChatRowProps {
113116 message : ClineMessage
114117 lastModifiedMessage ?: ClineMessage
115118 isExpanded : boolean
119+ collapseDecision ?: CollapseDecision | null
116120 isLast : boolean
117121 isStreaming : boolean
118122 onToggleExpand : ( ts : number ) => void
@@ -138,7 +142,7 @@ const ChatRow = memo(
138142 const prevHeightRef = useRef ( 0 )
139143
140144 const [ chatrow , { height } ] = useSize (
141- < div className = "px-[15px] py-[10px] pr-[6px]" >
145+ < div data-message-row = { message . ts } className = "px-[15px] py-[10px] pr-[6px]" >
142146 < ChatRowContent { ...props } />
143147 </ div > ,
144148 )
@@ -170,6 +174,7 @@ export const ChatRowContent = ({
170174 message,
171175 lastModifiedMessage,
172176 isExpanded,
177+ collapseDecision,
173178 isLast,
174179 isStreaming,
175180 onToggleExpand,
@@ -277,17 +282,41 @@ export const ChatRowContent = ({
277282 case "error" :
278283 case "mistake_limit_reached" :
279284 return [ null , null ] // These will be handled by ErrorRow component
280- case "command" :
285+ case "command" : {
286+ const { exitCode } = parseCommandAndOutput ( message . text )
287+ const hasExited = ! isCommandExecuting && exitCode !== undefined
288+ const commandFailed = hasExited && exitCode !== 0
289+ const commandSucceeded = hasExited && exitCode === 0
290+
281291 return [
282292 isCommandExecuting ? (
283293 < ProgressIndicator />
284294 ) : (
285- < TerminalSquare className = "size-4" aria-label = "Terminal icon" />
295+ < TerminalSquare
296+ className = "size-4"
297+ aria-label = "Terminal icon"
298+ style = { { color : commandFailed ? errorColor : commandSucceeded ? successColor : undefined } }
299+ />
300+ ) ,
301+ isCommandExecuting ? (
302+ < span style = { { color : normalColor , fontWeight : "bold" } } >
303+ { t ( "chat:commandExecution.running" ) }
304+ </ span >
305+ ) : commandFailed ? (
306+ < span style = { { color : errorColor , fontWeight : "bold" } } >
307+ { t ( "chat:commandExecution.failed" ) }
308+ </ span >
309+ ) : commandSucceeded ? (
310+ < span style = { { color : successColor , fontWeight : "bold" } } >
311+ { t ( "chat:commandExecution.completed" ) }
312+ </ span >
313+ ) : (
314+ < span style = { { color : normalColor , fontWeight : "bold" } } >
315+ { t ( "chat:commandExecution.running" ) }
316+ </ span >
286317 ) ,
287- < span style = { { color : normalColor , fontWeight : "bold" } } >
288- { t ( "chat:commandExecution.running" ) }
289- </ span > ,
290318 ]
319+ }
291320 case "use_mcp_server" :
292321 const mcpServerUse = safeJsonParse < ClineAskUseMcpServer > ( message . text )
293322 if ( mcpServerUse === undefined ) {
@@ -1008,6 +1037,19 @@ export const ChatRowContent = ({
10081037 }
10091038 }
10101039
1040+ // Auto-collapse: when message is collapsed and has a collapse decision,
1041+ // render the preview instead of full content.
1042+ if ( ! isExpanded && collapseDecision ) {
1043+ return (
1044+ < MessageCollapsePreview
1045+ message = { message }
1046+ decision = { collapseDecision }
1047+ onExpand = { ( ) => onToggleExpand ( message . ts ) }
1048+ isCommandExecuting = { isCommandExecuting }
1049+ />
1050+ )
1051+ }
1052+
10111053 switch ( message . type ) {
10121054 case "say" :
10131055 switch ( message . say ) {
0 commit comments