@@ -28,7 +28,7 @@ export interface LiveCommandEntry {
2828 isExpanded : boolean ;
2929}
3030
31- const LIVE_COMMAND_COLLAPSED_LINES = 12 ;
31+ const LIVE_COMMAND_COLLAPSED_LINES = 5 ;
3232
3333function getVisibleTail ( text : string , maxLines : number ) : { lines : string [ ] ; hiddenLineCount : number } {
3434 const normalized = text . trimEnd ( ) ;
@@ -47,6 +47,51 @@ function getVisibleTail(text: string, maxLines: number): { lines: string[]; hidd
4747 } ;
4848}
4949
50+ function getLines ( text : string ) : string [ ] {
51+ const normalized = text . trimEnd ( ) ;
52+ return normalized ? normalized . split ( '\n' ) : [ ] ;
53+ }
54+
55+ function getCollapsedLiveCommandViews (
56+ stdout : string ,
57+ stderr : string ,
58+ maxLines : number
59+ ) : {
60+ stdoutView : { lines : string [ ] ; hiddenLineCount : number } ;
61+ stderrView : { lines : string [ ] ; hiddenLineCount : number } ;
62+ } {
63+ const stdoutLines = getLines ( stdout ) ;
64+ const stderrLines = getLines ( stderr ) ;
65+
66+ if ( stdoutLines . length === 0 ) {
67+ return {
68+ stdoutView : { lines : [ ] , hiddenLineCount : 0 } ,
69+ stderrView : getVisibleTail ( stderr , maxLines ) ,
70+ } ;
71+ }
72+
73+ if ( stderrLines . length === 0 ) {
74+ return {
75+ stdoutView : getVisibleTail ( stdout , maxLines ) ,
76+ stderrView : { lines : [ ] , hiddenLineCount : 0 } ,
77+ } ;
78+ }
79+
80+ const stderrBudget = Math . min ( stderrLines . length , Math . max ( 1 , Math . floor ( maxLines / 3 ) ) ) ;
81+ const stdoutBudget = Math . max ( 0 , maxLines - stderrBudget ) ;
82+
83+ return {
84+ stdoutView : {
85+ lines : stdoutBudget > 0 ? stdoutLines . slice ( - stdoutBudget ) : [ ] ,
86+ hiddenLineCount : Math . max ( 0 , stdoutLines . length - stdoutBudget ) ,
87+ } ,
88+ stderrView : {
89+ lines : stderrLines . slice ( - stderrBudget ) ,
90+ hiddenLineCount : Math . max ( 0 , stderrLines . length - stderrBudget ) ,
91+ } ,
92+ } ;
93+ }
94+
5095/** A single tool call within a batch group */
5196export interface BatchToolItem {
5297 tool : string ;
@@ -242,14 +287,15 @@ export function ToolOutputList({ entries, maxVisible = 50 }: ToolOutputListProps
242287
243288export function LiveCommandBlock ( { entry } : { entry : LiveCommandEntry } ) {
244289 const { colors } = useTheme ( ) ;
245- const stdoutView = entry . isExpanded
246- ? { lines : entry . stdout . trimEnd ( ) ? entry . stdout . trimEnd ( ) . split ( '\n' ) : [ ] , hiddenLineCount : 0 }
247- : getVisibleTail ( entry . stdout , LIVE_COMMAND_COLLAPSED_LINES ) ;
248- const stderrView = entry . isExpanded
249- ? { lines : entry . stderr . trimEnd ( ) ? entry . stderr . trimEnd ( ) . split ( '\n' ) : [ ] , hiddenLineCount : 0 }
250- : getVisibleTail ( entry . stderr , Math . max ( 4 , Math . floor ( LIVE_COMMAND_COLLAPSED_LINES / 3 ) ) ) ;
290+ const { stdoutView, stderrView } = entry . isExpanded
291+ ? {
292+ stdoutView : { lines : getLines ( entry . stdout ) , hiddenLineCount : 0 } ,
293+ stderrView : { lines : getLines ( entry . stderr ) , hiddenLineCount : 0 } ,
294+ }
295+ : getCollapsedLiveCommandViews ( entry . stdout , entry . stderr , LIVE_COMMAND_COLLAPSED_LINES ) ;
251296 const hiddenLineCount = stdoutView . hiddenLineCount + stderrView . hiddenLineCount ;
252297 const hint = entry . isExpanded ? 'Ctrl+O collapse' : 'Ctrl+O expand' ;
298+ const hasVisibleOutput = stdoutView . lines . length > 0 || stderrView . lines . length > 0 ;
253299
254300 return (
255301 < Box flexDirection = "column" marginBottom = { 1 } >
@@ -262,15 +308,23 @@ export function LiveCommandBlock({ entry }: { entry: LiveCommandEntry }) {
262308 ) : (
263309 < Text color = { colors . muted } > { hint } </ Text >
264310 ) }
265- { stdoutView . lines . length > 0 ? (
266- < Text color = { colors . toolOutput } > { renderTerminalMarkdown ( stdoutView . lines . join ( '\n' ) ) } </ Text >
267- ) : null }
268- { stderrView . lines . length > 0 ? (
269- < Box flexDirection = "column" >
270- < Text color = { colors . error } > stderr</ Text >
271- < Text color = { colors . error } > { renderTerminalMarkdown ( stderrView . lines . join ( '\n' ) ) } </ Text >
272- </ Box >
273- ) : null }
311+ < Box flexDirection = "column" borderStyle = "single" borderColor = { colors . borderMuted } paddingX = { 1 } >
312+ { hasVisibleOutput ? (
313+ < >
314+ { stdoutView . lines . length > 0 ? (
315+ < Text color = { colors . toolOutput } > { renderTerminalMarkdown ( stdoutView . lines . join ( '\n' ) ) } </ Text >
316+ ) : null }
317+ { stderrView . lines . length > 0 ? (
318+ < Box flexDirection = "column" >
319+ < Text color = { colors . error } > stderr</ Text >
320+ < Text color = { colors . error } > { renderTerminalMarkdown ( stderrView . lines . join ( '\n' ) ) } </ Text >
321+ </ Box >
322+ ) : null }
323+ </ >
324+ ) : (
325+ < Text color = { colors . muted } > No output yet</ Text >
326+ ) }
327+ </ Box >
274328 </ Box >
275329 ) ;
276330}
0 commit comments