| ... | ... | @@ -123,16 +123,28 @@ export function AgentActivity( |
| 123 | 123 | ? phaseTint(failedRow.phase) |
| 124 | 124 | : tint; |
| 125 | 125 | |
| 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 | |
| 126 | 137 | // Header copy: "5 active agents" + (", 1 needs attention"). The banner renders |
| 127 | 138 | // the two parts in-line so the attention half can carry the accent color; |
| 128 | 139 | // `summary` is the short form for tight spots (expanded center, watch card). |
| 129 | 140 | const agentWord = props.activeCount === 1 ? "agent" : "agents"; |
| 130 | | const agentsLabel = `${props.activeCount} active ${agentWord}`; |
| 141 | const agentsLabel = allDone ? outcomeLabel : `${props.activeCount} active ${agentWord}`; |
| 131 | 142 | const attentionSuffix = |
| 132 | 143 | attentionRows.length > 0 |
| 133 | 144 | ? `${attentionRows.length} need${attentionRows.length === 1 ? "s" : ""} attention` |
| 134 | 145 | : ""; |
| 135 | | const summary = attentionSuffix || `${props.activeCount} active`; |
| 146 | const activeLabel = allDone ? doneLabel : `${props.activeCount} active`; |
| 147 | const summary = attentionSuffix || activeLabel; |
| 136 | 148 | |
| 137 | 149 | // Any registered scheme variant routes back to this app; taps are delivered |
| 138 | 150 | // to the widget's containing app, so the prod scheme is safe for all builds. |
| ... | ... | @@ -142,8 +154,6 @@ export function AgentActivity( |
| 142 | 154 | ? `t3code://${deepLinkRow.deepLink.slice(1)}` |
| 143 | 155 | : null; |
| 144 | 156 | |
| 145 | | const activeLabel = `${props.activeCount} active`; |
| 146 | | |
| 147 | 157 | // A scannable status glyph per phase — reads faster than colored words and |
| 148 | 158 | // ties the compact / expanded / banner / watch presentations together. |
| 149 | 159 | type SFName = NonNullable<ComponentProps<typeof Image>["systemName"]>; |
| ... | ... | @@ -245,7 +255,9 @@ export function AgentActivity( |
| 245 | 255 | <Text |
| 246 | 256 | modifiers={[ |
| 247 | 257 | 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), |
| 249 | 261 | lineLimit(1), |
| 250 | 262 | ]} |
| 251 | 263 | > |
| ... | ... | @@ -322,16 +334,17 @@ export function AgentActivity( |
| 322 | 334 | </Text> |
| 323 | 335 | ), |
| 324 | 336 | // 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). |
| 326 | 339 | minimal: |
| 327 | | attentionRow || failedRow |
| 340 | (attentionRow || failedRow || allDone) && heroRow |
| 328 | 341 | ? renderGlyph(phaseSymbol(heroRow.phase), 13, phaseTint(heroRow.phase)) |
| 329 | 342 | : renderLogo(11, tint), |
| 330 | 343 | expandedLeading: ( |
| 331 | 344 | <HStack spacing={5} alignment="center" modifiers={[padding({ leading: 4, vertical: 4 })]}> |
| 332 | 345 | {renderLogo(15, tint)} |
| 333 | 346 | <Text modifiers={[font({ weight: "bold", size: 13 }), foregroundStyle(tint)]}> |
| 334 | | {`${props.activeCount}`} |
| 347 | {allDone ? doneLabel : `${props.activeCount}`} |
| 335 | 348 | </Text> |
| 336 | 349 | </HStack> |
| 337 | 350 | ), |