bee-tui
A k9s-style terminal cockpit for Ethereum Swarm Bee node operators — nine live screens that surface the state Bee's API hides: bucket collisions, redistribution skip reasons, bin starvation, NAT reality, and a live HTTP tail so operators trust what they see.
bee-tui prod-1 @ http://10.0.1.5:1633 ping 12ms UTC 14:32:18
[Health] Stamps Swap Lottery Peers Network Warmup API Tags :cmd · Tab · ? help
─────────────────────────────────────────────────────────────────────────────────────
HEALTH prod-1 · http://10.0.1.5:1633 ping: 8ms
✓ API reachable /health 200 in 3ms
⚠ Chain RPC block 8412930 · Δ +1
✓ Wallet funded BZZ 27.97 · native 5.02
✓ Warmup complete ready
✓ Peers 87 connected
✓ Reserve 65,536 chunks (in-radius: 65,536) · radius 8
⚠ Bin saturation 2 starving: bin 4, bin 5
└─ manually `connect` more peers or wait — kademlia fills bins…
✓ Healthy for redistribution yes
✓ Not frozen yes
✓ Sufficient funds to play yes
─────────────────────────────────────────────────────────────────────────────────────
:cmd
┌ bee::http ──────────────────────────────────────────────────────────────────────────┐
│ 14:32:18 GET /status 200 3ms │
│ 14:32:18 GET /redistributionstate 200 104ms │
│ 14:32:18 GET /chainstate 200 0ms │
└─────────────────────────────────────────────────────────────────────────────────────┘
Install
Prebuilt installer (Linux / macOS / Windows — no Rust toolchain required):
# Linux / macOS — picks the right tarball for your arch
|
# Windows (PowerShell)
Or grab a tarball directly from the releases page.
Builds are produced for aarch64-apple-darwin, x86_64-apple-darwin,
aarch64-unknown-linux-gnu, x86_64-unknown-linux-gnu, and
x86_64-pc-windows-msvc.
From source (needs Rust ≥ 1.85):
Quickstart
Point bee-tui at a running Bee node:
# Default config talks to http://localhost:1633
# Or point at a remote node via env
BEE_TUI_CONFIG=/.config/bee-tui/config.toml
# Force ASCII glyphs (Windows Terminal pre-Win11, screen readers, broken SSH chains)
# Suppress colour (also honours NO_COLOR env per <https://no-color.org>)
A minimal ~/.config/bee-tui/config.toml:
[[]]
= "prod-1"
= "http://10.0.1.5:1633"
= "@env:BEE_TOKEN_PROD1" # resolves at startup; never logged
= true
[[]]
= "lab"
= "http://localhost:1633"
[]
= "default" # "default" | "mono"
= false # true = same as `--ascii`
The @env:VAR token form keeps Bearer tokens out of the config file. With the
local default profile, bee-tui works with zero config against a local Bee.
What you get
Nine operator screens plus an always-on command-log pane:
| Screen | What it answers |
|---|---|
| S1 Health | "Why is my node unhealthy?" — 10 gates with WHY tooltips encoding tribal knowledge (e.g. "storageRadius decreases ONLY on the 30-min reserve worker tick"). |
| S2 Stamps | "Which batch is about to fail uploads?" — worst-bucket fill bar, immutable-vs-mutable rejection semantics (bee#5334), 5-state status ladder. ↵ drills into the per-bucket fill histogram. |
| S3 Swap / cheques | Chequebook headroom (with on-chain contract address), per-peer net (received − sent) with |net| > 0.5 BZZ flagging, last-received cheque table. |
| S4 Lottery | "Why am I not earning rewards?" — round timeline, anchor summary (last won / played / selected / frozen with Δ), stake card with frozen / unhealthy / insufficient-gas reasoning, on-demand r-key rchash benchmark. |
| S5 Warmup | "What's Bee actually doing during the 25–60-minute cold start?" — five-step checklist with a depth-stability window. |
| S6 Peers | Bin saturation strip (Empty / Starving / Healthy / Over) anchored on bee-go's SaturationPeers=8 and OverSaturationPeers=18 constants — surfaces the bin-starvation gap no other tool derives. ↵ drills into per-peer balance / cheques / settlement / ping. |
| S7 Network / NAT | "Why am I unreachable?" — public-vs-private underlay classification, AutoNAT reachability with stability window (flickers under symmetric NAT). |
| S8 RPC / API health | Bee API call stats (p50 / p99 latency, error rate over the last 100 calls), pending operator transactions. |
| S9 Tags / uploads | "Where is my upload stuck?" — per-tag lifecycle counters (split → sent → synced) and a TagStatus ladder. Long lists scroll with j k / PgUp PgDn / Home. |
| S10 Command log | Always-visible bee::http request tail (lazygit-style). The trust anchor — operators learn the API by watching it. |
Drill panes
Two screens have a per-row drill that fans out to the relevant Bee endpoints
on demand. Both follow the same UX: ↑↓ / j k move selection, ↵
opens the drill, Esc closes it.
- S2 Stamps drill: fetches
/stamps/{id}/bucketsand renders a fill-percentage histogram (six bins from0%to100%) plus the top 10 worst buckets. Two batches with the same headlineutilizationcan fail uploads under wildly different conditions — the drill answers how concentrated the load is. - S6 Peers drill: parallel fetch of
peer_balance+peer_chequespeer_settlement+ping_peerfor the selected peer. Each field fails independently — a 404 on/chequebook/cheque/{peer}(peers you've never exchanged cheques with) showserror: 404for that one field instead of blanking the drill.
Keys
Tab |
cycle screens |
? |
toggle per-screen help overlay |
: |
open command bar |
q, Ctrl+C |
quit |
↑↓ / j k |
move selection (S2, S6) or scroll (S9) |
↵ |
drill selected row (S2, S6) |
Esc |
close drill / overlay |
r |
run rchash benchmark (S4 Lottery) |
PgUp / PgDn / Home |
page through long lists (S9) |
? is the source of truth for screen-specific keymaps — every screen advertises
its keys in the overlay.
Copying values out of the cockpit: mouse mode is off by default, so your terminal's native selection works. Click-drag a peer overlay or batch ID, then paste it into a block explorer / Discord / etc. — bee-tui doesn't intercept it.
Command bar
:health, :stamps, :swap, :lottery, :peers, :network, :warmup, :api, :tags |
jump to that screen |
:context <name> |
switch to another node from config.nodes |
:diagnose |
export a redacted bundle to $TMPDIR/bee-tui-diagnostic-<ts>.txt (paste-ready for support threads — Bearer tokens never captured) |
:pins-check |
walk every pinned root via /pins/check, write results to $TMPDIR/bee-tui-pins-check-<profile>-<ts>.txt (NDJSON streamed by Bee, collected and tail-friendly) |
:loggers |
snapshot /loggers to $TMPDIR/bee-tui-loggers-<profile>-<ts>.txt, sorted loudest-first |
:set-logger <expr> <level> |
call PUT /loggers/{exp}/{level} — bump a Bee subsystem to debug / info / etc. without curl |
:quit, :q |
quit |
Multi-node
Define multiple [[nodes]] in config.toml. The default profile loads at
startup; :context <name> swaps the active connection without restarting. The
top bar reflects the active profile.
Theme & accessibility
[]
= "default" # vibrant green/yellow/red
# theme = "mono" # monochrome — same status glyphs, no colour
= false # true → ASCII glyphs (OK / X / ! / > / # / .)
Themes are slot-based (Pass / Warn / Fail / Accent / Dim / Info) — adding a
new theme is one file. Glyphs are slot-based too: every component reads
theme::active().glyphs.X rather than hardcoding ✓, so --ascii (or
ascii_fallback = true) flips every screen at once.
CLI overrides (highest priority):
--ascii— same asascii_fallback = true--no-color— same astheme = "mono"NO_COLOR=1env honours no-color.org
Runtime theme switching (:theme <name>) lands in v0.6.
Status
v1.0.0 on crates.io (May 2026). Full nine-screen cockpit with drill panes,
command bar, multi-node, theme system, ASCII fallback, scrollbars, ? help
overlay, and prebuilt installers for all five major targets.
| Version | Scope | State |
|---|---|---|
| v0.1.0 | S1 Health, S2 Stamps, S10 Command log; single-node; CI; insta tests | ✅ shipped |
| v0.2.0 | S3 SWAP, S4 Lottery, S5 Warmup, S6 Peers, S7 NAT, S8 RPC, S9 Tags, command bar, multi-node, theme system | ✅ shipped |
| v0.9.0 | :pins-check / :loggers / :set-logger, S2 + S6 drill panes, scrollbars, ? help, --ascii / --no-color, cargo-dist |
✅ shipped |
| v1.0.0 | Cold-start spinner, footer ? chips, copy-affordance docs, semver-stable surface |
✅ shipped |
Backed by bee-rs v1.6 (full
coverage of the Bee 8.0.0 OpenAPI surface). Full screen specs in
docs/PLAN.md.
Stack
- Ratatui 0.30 — terminal UI framework
- crossterm — terminal backend
- Tokio — async runtime
- bee-rs ≥ 1.6 — Bee API client
- 106 lib + insta tests cover every gate / status ladder / drill view / scroll edge / glyph slot
- MSRV 1.85,
clippy --all-targets -- -D warningsclean
Contributing
Issues and PRs welcome at github.com/ethswarm-tools/bee-tui.
The [lib] + [[bin]] layout makes integration tests cheap — every new screen
should ship with insta snapshot tests of its pure view_for function. Drill
panes follow the same pattern: pure compute_*_view fn + insta tests for
realistic / pathological / empty inputs (see tests/s2_stamps_drill.rs and
tests/s6_peers_drill.rs).
License
Dual-licensed under either Apache-2.0 or MIT at your option.