@@ -123,16 +123,28 @@ export function AgentActivity(
123123 ? phaseTint ( failedRow . phase )
124124 : tint ;
125125
126+ // With nothing active the aggregate only carries recently finished work, so
127+ // "0 active agents" (and a lone "0" in the expanded island) read as broken.
128+ // Lead with the outcome instead. The outcome is derived here from the rows
129+ // rather than taken from the server subtitle (which keys off the newest
130+ // terminal row): every presentation — header text, tint, count slots,
131+ // minimal glyph — must agree, and a failure anywhere should dominate a
132+ // newer success.
133+ const allDone = props . activeCount === 0 ;
134+ const doneLabel = failedRow ? "Failed" : "Done" ;
135+ const outcomeLabel = failedRow ? "Agent work failed" : "Agent work completed" ;
136+
126137 // Header copy: "5 active agents" + (", 1 needs attention"). The banner renders
127138 // the two parts in-line so the attention half can carry the accent color;
128139 // `summary` is the short form for tight spots (expanded center, watch card).
129140 const agentWord = props . activeCount === 1 ? "agent" : "agents" ;
130- const agentsLabel = `${ props . activeCount } active ${ agentWord } ` ;
141+ const agentsLabel = allDone ? outcomeLabel : `${ props . activeCount } active ${ agentWord } ` ;
131142 const attentionSuffix =
132143 attentionRows . length > 0
133144 ? `${ attentionRows . length } need${ attentionRows . length === 1 ? "s" : "" } attention`
134145 : "" ;
135- const summary = attentionSuffix || `${ props . activeCount } active` ;
146+ const activeLabel = allDone ? doneLabel : `${ props . activeCount } active` ;
147+ const summary = attentionSuffix || activeLabel ;
136148
137149 // Any registered scheme variant routes back to this app; taps are delivered
138150 // to the widget's containing app, so the prod scheme is safe for all builds.
@@ -142,8 +154,6 @@ export function AgentActivity(
142154 ? `t3code://${ deepLinkRow . deepLink . slice ( 1 ) } `
143155 : null ;
144156
145- const activeLabel = `${ props . activeCount } active` ;
146-
147157 // A scannable status glyph per phase — reads faster than colored words and
148158 // ties the compact / expanded / banner / watch presentations together.
149159 type SFName = NonNullable < ComponentProps < typeof Image > [ "systemName" ] > ;
@@ -245,7 +255,9 @@ export function AgentActivity(
245255 < Text
246256 modifiers = { [
247257 font ( { weight : "semibold" , size : 13 } ) ,
248- foregroundStyle ( primaryForeground ) ,
258+ // The all-done header carries the outcome tint (emerald /
259+ // red) the way the Done/Failed status labels do.
260+ foregroundStyle ( allDone ? headerTint : primaryForeground ) ,
249261 lineLimit ( 1 ) ,
250262 ] }
251263 >
@@ -322,16 +334,17 @@ export function AgentActivity(
322334 </ Text >
323335 ) ,
324336 // The shared/minimal form is a ~22pt circle — a single signal reads there,
325- // the wordmark does not. Show the blocking phase glyph, else the mark.
337+ // the wordmark does not. Show the blocking/outcome phase glyph, else the
338+ // mark (all-done shows the hero row's checkmark/cross).
326339 minimal :
327- attentionRow || failedRow
340+ ( attentionRow || failedRow || allDone ) && heroRow
328341 ? renderGlyph ( phaseSymbol ( heroRow . phase ) , 13 , phaseTint ( heroRow . phase ) )
329342 : renderLogo ( 11 , tint ) ,
330343 expandedLeading : (
331344 < HStack spacing = { 5 } alignment = "center" modifiers = { [ padding ( { leading : 4 , vertical : 4 } ) ] } >
332345 { renderLogo ( 15 , tint ) }
333346 < Text modifiers = { [ font ( { weight : "bold" , size : 13 } ) , foregroundStyle ( tint ) ] } >
334- { `${ props . activeCount } ` }
347+ { allDone ? doneLabel : `${ props . activeCount } ` }
335348 </ Text >
336349 </ HStack >
337350 ) ,
0 commit comments