# Stats Tab — Implementation Plan
Generated: 2026-03-11
---
## Goal
Add a **Stats** tab to the Claudomator web UI that shows:
1. Task state distribution (counts by state)
2. Execution health metrics for the last 24h (total runs, success rate, total cost, avg duration)
3. A simple visual bar chart of execution outcomes
---
## Data Sources (no backend changes needed)
| Metric | Endpoint | Fields Used |
|--------|----------|-------------|
| Task state counts | `GET /api/tasks` | `state` |
| Execution history | `GET /api/executions?since=24h` | `state`, `cost_usd`, `duration_ms`, `started_at`, `finished_at` |
Both endpoints already exist. No new API endpoints required.
---
## Component Structure
```
Executions (Last 24h)
42
Total Runs
88%
Success Rate
$1.24
Total Cost
4m 12s
Avg Duration
```
---
## Data Transformation Functions (exported for testing)
### `computeTaskStats(tasks)`
Input: `Task[]`
Output:
```js
{
byState: { PENDING: 2, RUNNING: 1, COMPLETED: 45, ... } // all states present in tasks
}
```
### `computeExecutionStats(executions)`
Input: `RecentExecution[]`
Output:
```js
{
total: 42,
successRate: 0.88, // fraction (0–1)
totalCostUSD: 1.24,
avgDurationMs: 252000, // null if no finished executions
byOutcome: { completed: 37, failed: 3, cancelled: 2, ... }
}
```
---
## Files Changed
| File | Change |
|------|--------|
| `web/index.html` | Add Stats tab button + `` |
| `web/app.js` | Add `computeTaskStats`, `computeExecutionStats`, `renderStatsPanel`; update `switchTab` and `poll` |
| `web/style.css` | Add `.stats-*` CSS rules |
| `web/test/stats.test.mjs` | Unit tests for `computeTaskStats` and `computeExecutionStats` |
---
## Visualization Approach
No external library. Pure CSS:
- **State count boxes**: small colored badges using existing `--state-*` CSS variables
- **KPI boxes**: large number + label in a 4-column grid
- **Bar chart**: flex row of divs with percentage widths, colored per outcome state
---
## Tab Integration
In `switchTab(name)`:
- When `name === 'stats'`: fetch tasks + recent executions, then call `renderStatsPanel`
- Hide `#btn-new-task` (same as other non-tasks tabs)
In `poll()`:
- If stats tab is active: re-render stats after fetching tasks
---
## Tests (TDD — write first, then implement)
`web/test/stats.test.mjs`:
1. `computeTaskStats` groups tasks by state correctly
2. `computeTaskStats` returns zero counts for missing states
3. `computeExecutionStats` calculates total, success rate, cost, avg duration
4. `computeExecutionStats` handles empty array (zero total, null avg duration)
5. `computeExecutionStats` calculates success rate = 0 when all failed
6. `computeExecutionStats` ignores executions with no `duration_ms` in avg calculation
---
## Implementation Order (TDD)
1. Write `web/test/stats.test.mjs` — all tests fail (red)
2. Add `computeTaskStats` and `computeExecutionStats` to `app.js` — tests pass (green)
3. Add `renderStatsPanel` and integrate into `switchTab` / `poll`
4. Add HTML panel to `index.html`
5. Add CSS to `style.css`
6. Manual smoke test