feat(stats): hive-wide "favorite tools" rollup on ST4TS

Swarm-level companion to the per-agent favorite-tools doughnut (#1433).
Aggregates each agent's bash_commands(ts, head) table (written by
hive-bash-mcp) across the whole hive and surfaces the top-10 most-run
command heads on the dashboard ST4TS tab, alongside the existing model
mix.

- hive_stats.rs: AgentAgg gains a `bash` head→count map, filled by a new
  guarded `read_bash_heads()` that reuses read_agent's read-only
  connection. A missing `bash_commands` table (capture hasn't run for
  that agent) or any read error yields an empty map — isolated from
  read_agent's error path so it never drops an agent from the rollup.
  HiveStats gains `bash_mix: Vec<KeyCount>` (busiest-first, top 10).
  Unit tests cover the per-head tally + window cutoff and the
  missing-table degrade-to-empty path (in-memory sqlite).
- dashboard: a "favorite tools (bash commands across the swarm)" CSS-bar
  list on the ST4TS pane, mirroring the model-mix bars. Header + list
  stay hidden until bash_mix has data, so a fresh hive shows no empty
  block. (Dashboard ships no chart lib — bars, not a doughnut.)
- docs: dashboard.md ST4TS section documents the new rollup.

Closes #1449. Inert until the hive-bash-mcp capture (#1448, merged) has
recorded data across agents.
This commit is contained in:
iris 2026-06-06 07:47:43 +02:00 committed by mara
commit d9d2a52221
4 changed files with 130 additions and 0 deletions

View file

@ -321,6 +321,11 @@ charts): ST4TS is the swarm-level rollup.
- **Busiest agents** table — one row per agent (most turns first):
turns, input / output / cache-read tokens, est cost.
- **Model mix** — turns per model across the swarm, as CSS bars.
- **Favorite tools** — most-run normalised bash-command heads across the
swarm (top 10, as CSS bars), aggregated from each agent's
`bash_commands` table (written by the hive-bash-mcp capture). The
header + list stay hidden until at least one agent has recorded a
command, so the section never shows an empty block on a fresh hive.
Backed by `GET /api/stats-hive?window=<w>` in `hive-c0re`
(`hive_stats.rs`): for every name from