Skip to content

Commit 0151ff8

Browse files
feat(fleet-metrics): add autonomous fleet metrics dashboard page (#29)
Static HTML dashboard showing Bob's fleet-level metrics over the last 30 days: - Headline stat tiles (sessions, productive rate, deliverables, quality score) - Sessions/day bar chart with productive overlay and quality score trend - Model × harness productivity table (prod rate + LLM judge score per combo) Generated by scripts/generate-fleet-metrics-dashboard.py reading from state/sessions/sessions.db. Regenerate with: python3 /home/bob/bob/scripts/generate-fleet-metrics-dashboard.py generate
1 parent 0f1b439 commit 0151ff8

1 file changed

Lines changed: 261 additions & 0 deletions

File tree

fleet-metrics/index.html

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width,initial-scale=1">
6+
<title>Bob Fleet Metrics — last 30 days</title>
7+
<style>
8+
:root {
9+
--bg: #0f172a;
10+
--surface: #1e293b;
11+
--surface2: #273549;
12+
--border: #334155;
13+
--text: #f1f5f9;
14+
--muted: #94a3b8;
15+
--accent: #3b82f6;
16+
--green: #22c55e;
17+
--amber: #f59e0b;
18+
--indigo: #6366f1;
19+
}
20+
* { box-sizing: border-box; margin: 0; padding: 0; }
21+
body { background: var(--bg); color: var(--text); font-family: system-ui, sans-serif;
22+
font-size: 14px; line-height: 1.5; }
23+
a { color: var(--accent); text-decoration: none; }
24+
a:hover { text-decoration: underline; }
25+
26+
header { padding: 32px 24px 24px; border-bottom: 1px solid var(--border); }
27+
header h1 { font-size: 20px; font-weight: 600; color: var(--text); }
28+
header p { color: var(--muted); margin-top: 4px; font-size: 13px; }
29+
30+
.main { max-width: 900px; margin: 0 auto; padding: 24px; }
31+
32+
/* Stat tiles */
33+
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
34+
gap: 12px; margin-bottom: 32px; }
35+
.tile { background: var(--surface); border: 1px solid var(--border);
36+
border-radius: 8px; padding: 16px; }
37+
.tile-label { font-size: 12px; color: var(--muted); text-transform: uppercase;
38+
letter-spacing: 0.05em; }
39+
.tile-value { font-size: 28px; font-weight: 700; margin: 4px 0; color: var(--text); }
40+
.tile-sub { font-size: 12px; color: var(--muted); }
41+
42+
/* Chart panels */
43+
.panel { background: var(--surface); border: 1px solid var(--border);
44+
border-radius: 8px; padding: 20px; margin-bottom: 20px; }
45+
.panel h2 { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
46+
.panel .desc { font-size: 12px; color: var(--muted); margin-bottom: 16px; }
47+
48+
/* SVG charts */
49+
.chart { width: 100%; overflow: visible; display: block; }
50+
.bar-total { fill: #93c5fd; opacity: 0.5; }
51+
.bar-prod { fill: var(--green); opacity: 0.85; }
52+
.axis-label { font-size: 10px; fill: var(--muted); font-family: monospace; }
53+
.legend { font-size: 12px; color: var(--muted); margin-top: 8px; display: flex;
54+
align-items: center; gap: 4px; flex-wrap: wrap; }
55+
.legend-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 2px; }
56+
57+
/* Model table */
58+
.bm-table { width: 100%; border-collapse: collapse; }
59+
.bm-table th { font-size: 11px; color: var(--muted); text-align: left; padding: 4px 8px;
60+
border-bottom: 1px solid var(--border); }
61+
.bm-table td { padding: 5px 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
62+
.bm-label { font-size: 12px; color: var(--text); font-family: monospace; white-space: nowrap; }
63+
.bm-bar-cell { width: 240px; }
64+
.bm-bar { height: 14px; border-radius: 2px; min-width: 2px; }
65+
.bm-pct { font-size: 12px; color: var(--text); font-variant-numeric: tabular-nums; width: 42px; }
66+
.bm-score { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; width: 48px; }
67+
.bm-n { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
68+
69+
footer { border-top: 1px solid var(--border); padding: 16px 24px;
70+
font-size: 12px; color: var(--muted); }
71+
</style>
72+
</head>
73+
<body>
74+
<header>
75+
<div class="main" style="padding-top:0;padding-bottom:0">
76+
<h1>Bob Fleet Metrics</h1>
77+
<p>Last 30 days of autonomous agent sessions &mdash; generated 2026-07-27 02:59 UTC</p>
78+
</div>
79+
</header>
80+
81+
<main class="main">
82+
<div class="tiles">
83+
<div class="tile">
84+
<div class="tile-label">Total Sessions</div>
85+
<div class="tile-value">8,359</div>
86+
<div class="tile-sub">last 30 days</div>
87+
</div>
88+
<div class="tile">
89+
<div class="tile-label">Productive</div>
90+
<div class="tile-value">82.0%</div>
91+
<div class="tile-sub">6,858 sessions</div>
92+
</div>
93+
<div class="tile">
94+
<div class="tile-label">Deliverables</div>
95+
<div class="tile-value">35,894</div>
96+
<div class="tile-sub">commits · PRs · artifacts</div>
97+
</div>
98+
<div class="tile">
99+
<div class="tile-label">Avg Quality</div>
100+
<div class="tile-value">0.54</div>
101+
<div class="tile-sub">LLM judge score 0–1</div>
102+
</div></div>
103+
104+
<div class="panel">
105+
<h2>Sessions per day</h2>
106+
<p class="desc">Daily autonomous sessions with productive overlay and average quality score trend</p>
107+
108+
<svg viewBox="0 0 465 184" class="chart" aria-label="Sessions per day">
109+
<g><rect class="bar-total" x="0" y="152" width="12" height="8" rx="2"><title>2026-06-27: 32 sessions (5 productive)</title></rect><rect class="bar-prod" x="0" y="159" width="12" height="1" rx="2"><title>2026-06-27: 5 productive</title></rect><rect class="bar-total" x="15" y="102" width="12" height="58" rx="2"><title>2026-06-28: 233 sessions (180 productive)</title></rect><rect class="bar-prod" x="15" y="115" width="12" height="45" rx="2"><title>2026-06-28: 180 productive</title></rect><rect class="bar-total" x="30" y="93" width="12" height="67" rx="2"><title>2026-06-29: 267 sessions (220 productive)</title></rect><rect class="bar-prod" x="30" y="105" width="12" height="55" rx="2"><title>2026-06-29: 220 productive</title></rect><rect class="bar-total" x="45" y="87" width="12" height="73" rx="2"><title>2026-06-30: 292 sessions (136 productive)</title></rect><rect class="bar-prod" x="45" y="126" width="12" height="34" rx="2"><title>2026-06-30: 136 productive</title></rect><rect class="bar-total" x="60" y="64" width="12" height="96" rx="2"><title>2026-07-01: 383 sessions (224 productive)</title></rect><rect class="bar-prod" x="60" y="104" width="12" height="56" rx="2"><title>2026-07-01: 224 productive</title></rect><rect class="bar-total" x="75" y="48" width="12" height="112" rx="2"><title>2026-07-02: 450 sessions (436 productive)</title></rect><rect class="bar-prod" x="75" y="51" width="12" height="109" rx="2"><title>2026-07-02: 436 productive</title></rect><rect class="bar-total" x="90" y="4" width="12" height="156" rx="2"><title>2026-07-03: 623 sessions (506 productive)</title></rect><rect class="bar-prod" x="90" y="34" width="12" height="126" rx="2"><title>2026-07-03: 506 productive</title></rect><rect class="bar-total" x="105" y="0" width="12" height="160" rx="2"><title>2026-07-04: 640 sessions (522 productive)</title></rect><rect class="bar-prod" x="105" y="30" width="12" height="130" rx="2"><title>2026-07-04: 522 productive</title></rect><rect class="bar-total" x="120" y="66" width="12" height="94" rx="2"><title>2026-07-05: 374 sessions (319 productive)</title></rect><rect class="bar-prod" x="120" y="80" width="12" height="80" rx="2"><title>2026-07-05: 319 productive</title></rect><rect class="bar-total" x="135" y="104" width="12" height="56" rx="2"><title>2026-07-06: 223 sessions (192 productive)</title></rect><rect class="bar-prod" x="135" y="112" width="12" height="48" rx="2"><title>2026-07-06: 192 productive</title></rect><rect class="bar-total" x="150" y="140" width="12" height="20" rx="2"><title>2026-07-07: 82 sessions (80 productive)</title></rect><rect class="bar-prod" x="150" y="140" width="12" height="20" rx="2"><title>2026-07-07: 80 productive</title></rect><rect class="bar-total" x="165" y="120" width="12" height="40" rx="2"><title>2026-07-08: 162 sessions (147 productive)</title></rect><rect class="bar-prod" x="165" y="123" width="12" height="37" rx="2"><title>2026-07-08: 147 productive</title></rect><rect class="bar-total" x="180" y="122" width="12" height="38" rx="2"><title>2026-07-09: 150 sessions (138 productive)</title></rect><rect class="bar-prod" x="180" y="126" width="12" height="34" rx="2"><title>2026-07-09: 138 productive</title></rect><rect class="bar-total" x="195" y="102" width="12" height="58" rx="2"><title>2026-07-10: 233 sessions (202 productive)</title></rect><rect class="bar-prod" x="195" y="110" width="12" height="50" rx="2"><title>2026-07-10: 202 productive</title></rect><rect class="bar-total" x="210" y="116" width="12" height="44" rx="2"><title>2026-07-11: 177 sessions (158 productive)</title></rect><rect class="bar-prod" x="210" y="120" width="12" height="40" rx="2"><title>2026-07-11: 158 productive</title></rect><rect class="bar-total" x="225" y="24" width="12" height="136" rx="2"><title>2026-07-12: 544 sessions (488 productive)</title></rect><rect class="bar-prod" x="225" y="38" width="12" height="122" rx="2"><title>2026-07-12: 488 productive</title></rect><rect class="bar-total" x="240" y="80" width="12" height="80" rx="2"><title>2026-07-13: 319 sessions (222 productive)</title></rect><rect class="bar-prod" x="240" y="104" width="12" height="56" rx="2"><title>2026-07-13: 222 productive</title></rect><rect class="bar-total" x="255" y="59" width="12" height="101" rx="2"><title>2026-07-14: 405 sessions (266 productive)</title></rect><rect class="bar-prod" x="255" y="94" width="12" height="66" rx="2"><title>2026-07-14: 266 productive</title></rect><rect class="bar-total" x="270" y="82" width="12" height="78" rx="2"><title>2026-07-15: 310 sessions (291 productive)</title></rect><rect class="bar-prod" x="270" y="87" width="12" height="73" rx="2"><title>2026-07-15: 291 productive</title></rect><rect class="bar-total" x="285" y="108" width="12" height="52" rx="2"><title>2026-07-16: 206 sessions (184 productive)</title></rect><rect class="bar-prod" x="285" y="114" width="12" height="46" rx="2"><title>2026-07-16: 184 productive</title></rect><rect class="bar-total" x="300" y="116" width="12" height="44" rx="2"><title>2026-07-17: 177 sessions (157 productive)</title></rect><rect class="bar-prod" x="300" y="121" width="12" height="39" rx="2"><title>2026-07-17: 157 productive</title></rect><rect class="bar-total" x="315" y="124" width="12" height="36" rx="2"><title>2026-07-18: 143 sessions (126 productive)</title></rect><rect class="bar-prod" x="315" y="128" width="12" height="32" rx="2"><title>2026-07-18: 126 productive</title></rect><rect class="bar-total" x="330" y="137" width="12" height="23" rx="2"><title>2026-07-19: 93 sessions (76 productive)</title></rect><rect class="bar-prod" x="330" y="141" width="12" height="19" rx="2"><title>2026-07-19: 76 productive</title></rect><rect class="bar-total" x="345" y="110" width="12" height="50" rx="2"><title>2026-07-20: 202 sessions (186 productive)</title></rect><rect class="bar-prod" x="345" y="114" width="12" height="46" rx="2"><title>2026-07-20: 186 productive</title></rect><rect class="bar-total" x="360" y="105" width="12" height="55" rx="2"><title>2026-07-21: 220 sessions (204 productive)</title></rect><rect class="bar-prod" x="360" y="109" width="12" height="51" rx="2"><title>2026-07-21: 204 productive</title></rect><rect class="bar-total" x="375" y="101" width="12" height="59" rx="2"><title>2026-07-22: 237 sessions (228 productive)</title></rect><rect class="bar-prod" x="375" y="103" width="12" height="57" rx="2"><title>2026-07-22: 228 productive</title></rect><rect class="bar-total" x="390" y="82" width="12" height="78" rx="2"><title>2026-07-23: 310 sessions (271 productive)</title></rect><rect class="bar-prod" x="390" y="92" width="12" height="68" rx="2"><title>2026-07-23: 271 productive</title></rect><rect class="bar-total" x="405" y="100" width="12" height="60" rx="2"><title>2026-07-24: 239 sessions (187 productive)</title></rect><rect class="bar-prod" x="405" y="113" width="12" height="47" rx="2"><title>2026-07-24: 187 productive</title></rect><rect class="bar-total" x="420" y="68" width="12" height="92" rx="2"><title>2026-07-25: 367 sessions (256 productive)</title></rect><rect class="bar-prod" x="420" y="96" width="12" height="64" rx="2"><title>2026-07-25: 256 productive</title></rect><rect class="bar-total" x="435" y="98" width="12" height="62" rx="2"><title>2026-07-26: 249 sessions (235 productive)</title></rect><rect class="bar-prod" x="435" y="101" width="12" height="59" rx="2"><title>2026-07-26: 235 productive</title></rect><rect class="bar-total" x="450" y="156" width="12" height="4" rx="2"><title>2026-07-27: 17 sessions (16 productive)</title></rect><rect class="bar-prod" x="450" y="156" width="12" height="4" rx="2"><title>2026-07-27: 16 productive</title></rect></g>
110+
<g><polyline class="score-line" points="21,87 36,81 51,69 66,76 81,71 96,71 111,73 126,64 141,72 156,72 171,71 186,68 201,75 216,70 231,74 246,79 261,79 276,69 291,77 306,71 321,70 336,71 351,78 366,69 381,76 396,71 411,81 426,72 441,73 456,80" fill="none" stroke="#6366f1" stroke-width="1.5" stroke-linejoin="round"/></g>
111+
<g><text x="0" y="176" class="axis-label">2026-06-27</text><text x="465" y="176" class="axis-label" text-anchor="end">2026-07-27</text></g>
112+
</svg>
113+
114+
<div class="legend">
115+
<span class="legend-swatch" style="background:#93c5fd"></span> Total sessions&nbsp;
116+
<span class="legend-swatch" style="background:#22c55e"></span> Productive&nbsp;
117+
<span class="legend-swatch" style="background:#6366f1;border-radius:1px;height:2px;width:16px;display:inline-block"></span> Quality score (right y)
118+
</div>
119+
</div>
120+
121+
<div class="panel">
122+
<h2>Productivity by model &times; harness</h2>
123+
<p class="desc">
124+
Productive rate and LLM judge quality score per model+harness combination
125+
(min 8 sessions, last 30 days).
126+
<span style="color:#3b82f6">&#9632;</span> claude-code &nbsp;
127+
<span style="color:#f59e0b">&#9632;</span> codex &nbsp;
128+
<span style="color:#10b981">&#9632;</span> gptme
129+
</p>
130+
131+
<table class="bm-table" aria-label="Model productivity">
132+
<thead>
133+
<tr>
134+
<th>Harness:Model</th>
135+
<th>Productive rate</th>
136+
<th>%</th>
137+
<th>Score</th>
138+
<th>Sessions</th>
139+
</tr>
140+
</thead>
141+
<tbody>
142+
<tr>
143+
<td class="bm-label">claude-code:Sonnet 4.6</td>
144+
<td class="bm-bar-cell">
145+
<div class="bm-bar" style="width:196px;background:#3b82f6" title="87.8% productive, n=4237"></div>
146+
</td>
147+
<td class="bm-pct">87.8%</td>
148+
<td class="bm-score">0.55</td>
149+
<td class="bm-n">4,237</td>
150+
</tr>
151+
<tr>
152+
<td class="bm-label">claude-code:Haiku 4.5</td>
153+
<td class="bm-bar-cell">
154+
<div class="bm-bar" style="width:213px;background:#3b82f6" title="95.5% productive, n=797"></div>
155+
</td>
156+
<td class="bm-pct">95.5%</td>
157+
<td class="bm-score"></td>
158+
<td class="bm-n">797</td>
159+
</tr>
160+
<tr>
161+
<td class="bm-label">claude-code:Sonnet (old)</td>
162+
<td class="bm-bar-cell">
163+
<div class="bm-bar" style="width:116px;background:#3b82f6" title="52.2% productive, n=722"></div>
164+
</td>
165+
<td class="bm-pct">52.2%</td>
166+
<td class="bm-score">0.57</td>
167+
<td class="bm-n">722</td>
168+
</tr>
169+
<tr>
170+
<td class="bm-label">codex:GPT-5.5</td>
171+
<td class="bm-bar-cell">
172+
<div class="bm-bar" style="width:220px;background:#f59e0b" title="98.8% productive, n=521"></div>
173+
</td>
174+
<td class="bm-pct">98.8%</td>
175+
<td class="bm-score">0.49</td>
176+
<td class="bm-n">521</td>
177+
</tr>
178+
<tr>
179+
<td class="bm-label">gptme:GPT-5.6 (sub)</td>
180+
<td class="bm-bar-cell">
181+
<div class="bm-bar" style="width:121px;background:#10b981" title="54.2% productive, n=330"></div>
182+
</td>
183+
<td class="bm-pct">54.2%</td>
184+
<td class="bm-score"></td>
185+
<td class="bm-n">330</td>
186+
</tr>
187+
<tr>
188+
<td class="bm-label">claude-code:Opus</td>
189+
<td class="bm-bar-cell">
190+
<div class="bm-bar" style="width:210px;background:#3b82f6" title="94.1% productive, n=256"></div>
191+
</td>
192+
<td class="bm-pct">94.1%</td>
193+
<td class="bm-score">0.42</td>
194+
<td class="bm-n">256</td>
195+
</tr>
196+
<tr>
197+
<td class="bm-label">codex:GPT-5.4</td>
198+
<td class="bm-bar-cell">
199+
<div class="bm-bar" style="width:215px;background:#f59e0b" title="96.6% productive, n=234"></div>
200+
</td>
201+
<td class="bm-pct">96.6%</td>
202+
<td class="bm-score">0.51</td>
203+
<td class="bm-n">234</td>
204+
</tr>
205+
<tr>
206+
<td class="bm-label">gptme:GPT-5.6</td>
207+
<td class="bm-bar-cell">
208+
<div class="bm-bar" style="width:208px;background:#10b981" title="93.6% productive, n=233"></div>
209+
</td>
210+
<td class="bm-pct">93.6%</td>
211+
<td class="bm-score">0.53</td>
212+
<td class="bm-n">233</td>
213+
</tr>
214+
<tr>
215+
<td class="bm-label">gptme:DeepSeek V4</td>
216+
<td class="bm-bar-cell">
217+
<div class="bm-bar" style="width:190px;background:#10b981" title="85.4% productive, n=233"></div>
218+
</td>
219+
<td class="bm-pct">85.4%</td>
220+
<td class="bm-score"></td>
221+
<td class="bm-n">233</td>
222+
</tr>
223+
<tr>
224+
<td class="bm-label">gptme:DeepSeek V4</td>
225+
<td class="bm-bar-cell">
226+
<div class="bm-bar" style="width:165px;background:#10b981" title="74.3% productive, n=101"></div>
227+
</td>
228+
<td class="bm-pct">74.3%</td>
229+
<td class="bm-score">0.46</td>
230+
<td class="bm-n">101</td>
231+
</tr>
232+
<tr>
233+
<td class="bm-label">claude-code:Haiku (old)</td>
234+
<td class="bm-bar-cell">
235+
<div class="bm-bar" style="width:149px;background:#3b82f6" title="67.0% productive, n=97"></div>
236+
</td>
237+
<td class="bm-pct">67.0%</td>
238+
<td class="bm-score">0.69</td>
239+
<td class="bm-n">97</td>
240+
</tr>
241+
<tr>
242+
<td class="bm-label">claude-code:Fable 5</td>
243+
<td class="bm-bar-cell">
244+
<div class="bm-bar" style="width:220px;background:#3b82f6" title="98.8% productive, n=85"></div>
245+
</td>
246+
<td class="bm-pct">98.8%</td>
247+
<td class="bm-score">0.72</td>
248+
<td class="bm-n">85</td>
249+
</tr></tbody>
250+
</table>
251+
</div>
252+
</main>
253+
254+
<footer>
255+
<div style="max-width:900px;margin:0 auto">
256+
Data from <a href="https://github.com/TimeToBuildBob">TimeToBuildBob</a> session ledger &middot;
257+
<a href="https://timetobuildbob.com">timetobuildbob.com</a>
258+
</div>
259+
</footer>
260+
</body>
261+
</html>

0 commit comments

Comments
 (0)