+
+
+
+ Fleet
+
+ {#if aggregates.running > 0}
+ {aggregates.running} running
+ {/if}
+ {#if aggregates.idle > 0}
+ {aggregates.idle} idle
+ {/if}
+ {#if aggregates.stalled > 0}
+ {aggregates.stalled} stalled
+ {/if}
+
+
+
+ Burn
+ {fmtBurnRate(aggregates.totalBurnRatePerHour)}
+
+
+
+
+ {#if health}
+
+
+
+ Status
+
+ {health.activityState}
+ {#if health.activeTool}
+ ({health.activeTool})
+ {/if}
+
+
+
+ Burn Rate
+ {fmtBurnRate(health.burnRatePerHour)}
+
+
+ Context
+ {fmtPressure(health.contextPressure)}
+
+
+ Idle
+ {fmtIdle(health.idleDurationMs)}
+
+ {#if session}
+
+ Tokens
+ {(session.inputTokens + session.outputTokens).toLocaleString()}
+
+
+ Cost
+ ${session.costUsd.toFixed(4)}
+
+
+ Turns
+ {session.numTurns}
+
+
+ Model
+ {session.model ?? '—'}
+
+ {/if}
+ {#if health.fileConflictCount > 0}
+
+ Conflicts
+ {health.fileConflictCount}
+
+ {/if}
+ {#if health.externalConflictCount > 0}
+
+ External
+ {health.externalConflictCount}
+
+ {/if}
+ {#if health.attentionScore > 0}
+
+ Attention
+ {health.attentionScore}
+ {#if health.attentionReason}
+ {health.attentionReason}
+ {/if}
+
+ {/if}
+
+ {:else}
+
No health data — start an agent session
+ {/if}
+
+
+ {#if groupId}
+
+
+ {#each ['todo', 'progress', 'review', 'done', 'blocked'] as status}
+
0}>
+ {taskCounts[status]}
+ {status === 'progress' ? 'In Prog' : status === 'todo' ? 'To Do' : status.charAt(0).toUpperCase() + status.slice(1)}
+
+ {/each}
+
+ {/if}
+
+
+ {#if allHealth.filter(h => h.attentionScore > 0).length > 0}
+
+
+ {#each allHealth.filter(h => h.attentionScore > 0).slice(0, 5) as item}
+
+ {item.attentionScore}
+ {item.projectId.slice(0, 8)}
+ {item.attentionReason ?? '—'}
+
+ {/each}
+
+ {/if}
+
+ {#if historyLoading}
+
Loading history...
+ {:else if historyData.length === 0}
+
No session history for this project
+ {:else}
+
+
+ {#each (['cost', 'tokens', 'turns', 'tools', 'duration'] as const) as metric}
+
+ {/each}
+
+
+
+ {@const values = getHistoryValues(selectedHistoryMetric)}
+ {@const maxVal = Math.max(...values, 0.001)}
+ {@const minVal = Math.min(...values)}
+ {@const lastVal = values[values.length - 1] ?? 0}
+ {@const avgVal = values.length > 0 ? values.reduce((a, b) => a + b, 0) / values.length : 0}
+
+
+
+
+
+
+
+
+ Last
+ {formatMetricValue(selectedHistoryMetric, lastVal)}
+
+
+ Avg
+ {formatMetricValue(selectedHistoryMetric, avgVal)}
+
+
+ Max
+ {formatMetricValue(selectedHistoryMetric, maxVal)}
+
+
+ Min
+ {formatMetricValue(selectedHistoryMetric, minVal)}
+
+
+ Sessions
+ {historyData.length}
+
+
+
+
+
+
+
+ {#each historyData.slice(-10).reverse() as row}
+
+ {new Date(row.endTime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
+ {row.durationMin.toFixed(0)}m
+ ${row.costUsd.toFixed(3)}
+ {row.peakTokens >= 1000 ? `${(row.peakTokens / 1000).toFixed(0)}K` : row.peakTokens}
+ {row.turnCount}
+ {row.toolCallCount}
+
+ {/each}
+
+
+
+ {/if}
+