Introduction

beegui is a desktop GUI cockpit for Ethereum Swarm Bee node operators. It is the GUI sibling of bee-tui: same cockpit logic — health gates, stamp TTLs, fleet roll-up, redistribution skip reasons, durability checks, manifest walking, feed timelines, pubsub watches — rendered with egui instead of ratatui.

What it shows

15 screens. Some are status views (health gates, bin saturation, fleet roll-up). Some are inspectors with drill panels (per-stamp bucket histograms, per-peer balances + cheques, manifest fork walks). Two are subscribers (pubsub PSS/GSOC, feed timelines). One spawns and supervises a Bee process for the session (v0.11+).

ScreenWhat it surfaces
S1HealthGate ladder + worst-batch stamp TTL
S2StampsBatch table + bucket-histogram drill
S3SwapChequebook + cheques + settlements
S4LotteryRound phase + anchors + stake + rchash bench
S5WarmupBootstrap checklist + progress bars
S6PeersBin strip + peer drill (6-endpoint fan-out)
S7NetworkIdentity + reachability + underlays
S8API HealthChain state + pending tx + HTTP call-stats
S9TagsUpload progress + counts
S10PinsPinned-reference inspector + integrity check
S11ManifestLazy Mantaray fork walker
S12WatchlistDurability worker + result history
S13Feed TimelineOwner+topic walker
S14PubsubPSS/GSOC subscriber + ring buffer + filter
S15FleetMulti-node roll-up + switch active

How it differs from bee-tui

The two share the bee-cockpit-core crate — every gate ladder, every bucket histogram, every fleet roll-up comes from the same view_for(snapshot) -> View functions. The widget layer is the only thing that differs: bee-tui paints with ratatui; beegui paints with egui. Visuals come from the same logic.

What you'd pick beegui for:

  • You prefer a native desktop window to a terminal.
  • You want drag-and-drop uploads (drop a file → palette pre-fills :upload <path>).
  • You want OS-native desktop notifications on gate failures.

What you'd pick bee-tui for:

  • You SSH into nodes and live in the terminal.
  • You want every screen scrollable with vim-style keys + a longer command bar.

Install

Prebuilt installers

# macOS / Linux
curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/ethswarm-tools/beegui/releases/latest/download/beegui-installer.sh \
  | sh

# Windows (PowerShell)
powershell -c "irm https://github.com/ethswarm-tools/beegui/releases/latest/download/beegui-installer.ps1 | iex"

cargo-dist produces prebuilt binaries for:

  • aarch64-apple-darwin
  • x86_64-apple-darwin
  • aarch64-unknown-linux-gnu
  • x86_64-unknown-linux-gnu
  • x86_64-pc-windows-msvc

The installer drops the beegui binary into the platform's standard local-bin location and prepends it to PATH for new shells.

From source

Needs Rust ≥ 1.85.

cargo install beegui

Or clone + build:

git clone https://github.com/ethswarm-tools/beegui
cd beegui
cargo run --release

Linux dependencies

beegui uses egui's default eframe backend (glow / GLFW). On a fresh Debian/Ubuntu install you may need:

sudo apt install libgl1 libglib2.0-0 libxkbcommon0 libwayland-cursor0

Desktop notifications use notify-rust's zbus backend, which relies on the operator's session bus — no extra packages needed on GNOME/KDE/Hyprland.

Verifying

beegui --version    # should print e.g. "beegui 0.12.0"
beegui --once readiness    # exits 0 if a Bee is reachable on localhost:1633

Launching beegui

Quickstart

beegui                            # talk to http://localhost:1633
beegui --node http://host:1633    # explicit node URL
beegui --token <bearer>           # restricted-mode auth
beegui --config ~/beegui.toml     # explicit config file
beegui --theme light              # auto | light | dark
beegui http://a:1633 http://b:1633  # positional URLs (ad-hoc fleet)

CLI flags

FlagEffect
--node <URL>Override the active node URL. Falls back to $BEE_NODE_URL, then http://localhost:1633.
--token <bearer>Restricted-mode auth. Also reads $BEE_NODE_TOKEN.
--config <PATH>Explicit config file. Without it beegui searches the platform default path.
--theme <auto|light|dark>Visual scheme. Auto follows the OS.
--bee-log <PATH>Tail an external Bee log file. See Bee log tailing.
--bee-log-cmd <CMD>Tail a shell command's stdout instead.
--bee-bin <PATH>Spawn Bee as a child process. See Bee process supervision.
--bee-config <PATH>Path to the Bee YAML config. Required with --bee-bin.
--once <verb>Run a single verb and exit (no GUI). See --once CLI.
--jsonWhen combined with --once, emit JSON.
<urls...>Positional ad-hoc fleet URLs — replaces the config's node list for the session. First URL is the active node.

Environment

Env varEffect
BEE_NODE_URLDefault node URL if no CLI flag and no config.
BEE_NODE_TOKENDefault token.
BEEGUI_CONFIGPath to the config file (alternative to --config).
BEEGUI_DATAOverride the data directory beegui writes state into.
BEEGUI_LOG_LEVELtracing filter (e.g. debug, beegui=trace,reqwest=warn).
RUST_LOGFallback if BEEGUI_LOG_LEVEL isn't set.
NO_COLOR=1Force the dark/mono visual scheme regardless of OS.

Ad-hoc fleet (no config)

The shortest path to a multi-node session:

beegui http://10.0.0.1:1633 http://10.0.0.2:1633 http://10.0.0.3:1633

The first URL is the active node. All three appear in S15 Fleet and Ctrl+N's node picker. The fleet poller cycles them every 15 seconds; per-screen pollers (health, stamps, peers, …) only run against the active node.

Switching the active node

Ctrl+NOpen the centered picker; arrows / j-k to select; Enter to switch.
:nodesSame as Ctrl+N from the command palette.
:context <name>Switch by typed name (no picker).
S15 FleetEnter on any row, or double-click, or the Switch to button.

Configuration

beegui reads the same TOML schema as bee-tui — minus the TUI-only [keybindings] and [styles] sections. The default search path is ~/.config/beegui/config.toml on Linux, the platform equivalents on macOS and Windows. Override with --config <path> or BEEGUI_CONFIG=<path>.

Full example

[[nodes]]
name = "local"
url = "http://localhost:1633"
default = true

[[nodes]]
name = "remote"
url = "http://bee.example.com:1633"
token = "@env:BEE_TOKEN"
log_command = "ssh bee-host 'tail -f /var/log/bee.log'"

[[nodes]]
name = "supervised"
url = "http://localhost:1733"
log_file = "/var/log/bee/bee.log"

[bee]
bin = "/usr/local/bin/bee"
config = "/etc/bee/config.yaml"

[bee.logs]
rotate_size_mb = 64       # rotate when reaching this size
keep_files = 5            # how many rotated files to retain

[alerts]
webhook_url = "https://hooks.slack.com/services/…"
debounce_secs = 300

[notifications]
desktop = true            # libnotify / macOS notif center / Windows toast

[pubsub]
history_file = "~/pubsub.jsonl"
rotate_size_mb = 64
keep_files = 5

[ui]
theme = "auto"            # auto | light | dark

Sections

[[nodes]]

One block per node. Required: name, url. Optional: token, default, log_file, log_command.

  • default = true marks the active node at startup. If no node sets it, the first one wins.
  • token accepts "@env:VAR" to read from an environment variable.
  • log_file and log_command are per-node bee-log sources; see Bee log tailing for the priority order.

[bee]

When set, beegui spawns Bee as a child process at startup. Both bin and config are required; partial config is a hard error. See Bee process supervision.

[bee.logs]

Log rotation knobs for the supervised Bee's stdout+stderr capture file. Defaults: 64 MiB × 5 files (≈320 MiB ceiling).

[alerts]

webhook_url fires gate-transition alerts at a Slack-compatible webhook. debounce_secs suppresses re-firing a gate within that window (default 60s; 300 is more humane for chat channels).

[notifications]

desktop = true raises OS-native notifications on Fail / Warn gate transitions. Linux uses libnotify (zbus), macOS uses the Notification Center, Windows uses toasts — all via notify-rust.

[pubsub]

Optional persistence of S14 pubsub messages to a JSONL file. Rotates on size; older rotations get unlinked. Replayable by any tool that understands the same format (bee-tui has :pubsub-replay; beegui's replay is on the roadmap).

[ui]

theme accepts auto / light / dark. CLI --theme overrides.

Screens

beegui has 15 screens accessible via the tab strip at the top, the number keys 19, or Tab / Shift+Tab to cycle. The active screen is highlighted in the strip.

Common interactions:

  • ↑ / ↓ (or j / k) move selection in the active list.
  • PgUp / PgDn page selection ±10 rows; Home / End jump to the first / last row.
  • Enter (or click) drills into the selected row.
  • Esc closes any drill or overlay.

S1 — Health gates

Status ladder built by views::health::gates_for_with_stamps: API reachable → chain RPC fresh → wallet funded → warmup complete → peer count → reserve fill → bin saturation → redistribution healthy → not frozen → stamp TTL. Each gate shows Pass / Warn / Fail with a one-line why. Stamp TTL surfaces the worst-batch TTL (the one most likely to expire).

The gate ladder also drives the alerts pipeline — every transition that crosses a Warn / Fail boundary lands in the alerts ring (Ctrl+A).

S2 — Stamps

Postage batches in a sortable table: batch ID prefix, depth, amount, TTL, status (Healthy / Skewed / Empty / Expiring). Selecting a row (Enter or click) loads the bucket histogram drill — per-bucket fill across the six bins, plus the top-10 worst buckets by collision count.

The drill calls GET /stamps/{id}/buckets once and caches the result; press Esc to close it.

S3 — Swap

Chequebook balance + on-chain debit/credit + the cheques and settlements tables. Cheques are split by direction (in / out) with last-cashed timestamps.

S4 — Lottery

Redistribution round state: phase ribbon (Commit / Reveal / Claim / Sample), block-of-round counter, anchor history, stake card. Stake status surfaces why: Healthy / Skewed / Frozen / Unstaked / Insufficient gas.

r runs an rchash benchmark at the health-derived storage depth against the full anchor range. Verdict turns green under 95 s (the reveal-phase deadline) and red above.

S5 — Warmup

Boot sequence checklist for a freshly-started node: peers connected → bin coverage → reserve fill → ready. Progress bars plus an elapsed counter; useful when triaging "is Bee actually making progress?" complaints.

S6 — Peers

Bin saturation strip (one cell per kademlia bin, color by fill ratio) + the peer table. Selecting a row triggers a 6-endpoint fan-out: peer_balance, peer_cheques, peer_settlement, ping_peer, status_peers, local status. The drill renders balance, ping, settl. in/out, last cheques in/out, storage radius, reserve size, pullsync rate, batch commitment (with >5% outlier flag).

S7 — Network

Identity (overlay + underlay), NAT reachability (via AutoNAT), listed underlays. Useful for confirming "is my node reachable from outside?".

S8 — API Health

Chain state (block height + sync lag), pending tx count, plus HTTP call-stats from the cockpit's own outbound requests (count, P50/P95/P99 latency by endpoint). The call-stats panel reads from the same LogCapture that drives the bee::http tab in the bottom log pane.

S9 — Tags

Upload tag table: ID, progress (sent / received / synced), counters. Useful when checking why a bee-rs upload is stuck.

S10 — Pins

Pinned references with check states. Enter on a row (or c for "check all") runs GET /pins/check per reference. s cycles sort modes: by reference / bad first / total chunks.

S11 — Manifest

Paste a root reference + click Load. The Mantaray tree renders with lazy fork expansion — to expand a fork; only the visible subtree is fetched. Useful for inspecting upload contents without downloading the whole collection.

S12 — Watchlist

Add references one at a time and run durability checks. Each ref runs through bee_cockpit_core::durability::check; results roll into a 50-entry history. The Re-check all button refreshes every entry.

S13 — Feed Timeline

Owner + topic + max-entries. Walk feed spawns feed_timeline::walk and renders newest-first results with the reference column shortened. Clicking a row reveals the full reference hex.

S14 — Pubsub

Live tail of PSS topic + GSOC subscriptions. The mode toggle switches between PSS (topic-only) and GSOC (owner + identifier). Messages land in a 200-entry ring with an optional case-insensitive substring filter. When [pubsub].history_file is set, every message also appends to a JSONL file with size-rotation.

S15 — Fleet

Multi-node health roll-up: one row per [[nodes]] entry (or positional CLI URL), polled every 15 seconds in parallel. Aggregate status, peer count, worst stamp TTL, /health ping.

Enter on a row (or double-click, or the Switch to button) switches the active node — beegui tears down the BeeWatch hub and rebuilds it against the new endpoint. The fleet poller keeps running so the roll-up doesn't blink.

r re-polls the fleet immediately (kicks the resync channel).

Bottom log pane

Ctrl+L toggles. Seven tabs:

  • Errors / Warning / Info / Debug — Bee process log lines by severity (from the bee-log tailer; see Bee log tailing).
  • Bee HTTP — Bee's own incoming /api request log.
  • bee::http — the cockpit's outbound calls (the "trust anchor" tab).
  • Cockpit — beegui's own tracing events.

Tab counts surface in the strip; the pane header shows the resolved bee-log source + origin (CLI / config / discovered / supervised).

Command palette

Open with : or Ctrl+P. Type to filter the verb list; ↑/↓ navigates; Enter submits; Esc dismisses.

Drag-and-drop a file onto the beegui window to pre-fill :upload <path> — the operator just hits Enter to ship.

Verbs

VerbWhat it does
:go <screen> (also :health, :stamps, :fleet, …)Switch to a screen by name.
:nodes (also :node)Open the centered node picker. Same as Ctrl+N.
:context <name> (aliases :ctx, :switch)Switch active node by typed name.
:logsToggle the bottom log pane.
:alertsToggle the alerts panel.
:help (also :?)Open the help overlay.
:quit (also :q, :exit)Exit beegui.

Inspection (no Bee write)

VerbWhat it does
:hash <path>Compute the swarm hash of a local file. Result on the banner.
:cid <ref> [manifest|feed]Compute the IPFS-style CID for a swarm reference.
:inspect <ref> (alias :manifest)Switch to S11 and load that root reference.
:feed-timeline <owner> <topic> [max] (alias :ft)Switch to S13 and walk the feed.
:durability <ref>Switch to S12 and add the reference + run the check.
:feed-probe <owner> <topic> (alias :fp)Fetch the latest feed update; banner reports index + payload size.
:diagnoseWrite a 10-second pprof bundle to /tmp/beegui-diagnose-<ts>/. Banner reports the path.

Active (Bee writes)

VerbWhat it does
:upload <path> [batch-prefix]Upload a file or directory. Batch is auto-picked when no prefix is supplied.
:pss <topic> <payload> [batch-prefix]Send a PSS message. Hex 32-byte topics pass through verbatim; anything else is keccak256-of-string.
:batch buy <depth> [amount]Stamp-batch buy preview.
:batch topup|dilute|extend <id> <arg>Stamp-batch topup / dilute / extend previews. No transactions are sent.

One-shot verbs (:hash, :cid, :feed-probe, :diagnose, :batch *) surface their result as a transient banner at the bottom of the screen (8 second TTL). Error states are red, OK states green.

Tab completion

Not yet implemented — typing a prefix narrows the suggestion list, and ↑/↓ navigate the matches. Pressing Enter on an empty input commits the currently-highlighted suggestion.

Keymap

KeyAction
19Jump to that screen.
Tab / Shift+TabCycle screens.
: or Ctrl+POpen the command palette.
Ctrl+NOpen the node picker.
Ctrl+LToggle the bottom log pane.
Ctrl+AToggle the alerts popup.
?Open the help overlay.
↑ ↓ or j kMove selection in the active list.
Enter / clickDrill into the selected row (or switch node in S15 / picker).
PgUp / PgDnPage selection ±10 rows.
Home / EndFirst / last row.
rRe-poll fleet (S15) · run rchash bench (S4).
cCheck all pins (S10).
sCycle pin sort mode (S10).
EscClose any overlay or drill.
Click a tabSame as 19 for that index.

Focus-aware shortcuts

Global key shortcuts (digit screen-jumps, Tab cycling, ?, arrow nav) suppress themselves when a text input owns keyboard focus. Typing 5 into a text field doesn't jump to S5; pressing in a feed-timeline owner field moves the caret, not the selection.

Ctrl-modified shortcuts (Ctrl+P, Ctrl+L, Ctrl+A, Ctrl+N) work regardless of focus — those are unambiguous.

Comparison with bee-tui

Conceptbee-tuibeegui
Open palette:: or Ctrl+P
Switch screenAlt+1Alt+9 or Tab19 or Tab
Switch nodeCtrl+N picker / S15 EnterCtrl+N picker / S15 Enter
Help??
Quit:q or Ctrl+C:q or window close
Log paneCtrl+L (also Shift+L fullscreen)Ctrl+L

Bee log tailing

beegui can tail Bee's own log output and surface it in the bottom log pane alongside the cockpit's own bee::http events. Bee's log is the operator's primary source of truth for things the API doesn't reveal — kademlia kicks, batch updates, postage stamp errors, RocksDB compactions.

Source priority

beegui picks one source per node. Highest priority wins:

  1. Supervisor — when --bee-bin is set, the supervisor's rotating capture file is the source.
  2. CLI flag--bee-log <path> or --bee-log-cmd <cmd>.
  3. Config[[nodes]].log_file or [[nodes]].log_command.
  4. Auto-discovery — Linux only, local nodes only. See below.
  5. None — the Bee-side tabs stay empty; the pane header explains why.

Within a tier, a command beats a file.

CLI flags

beegui --bee-log /var/log/bee/bee.log
beegui --bee-log-cmd "journalctl -u bee -f"
beegui --bee-log-cmd "docker logs -f bee 2>&1"
beegui --bee-log-cmd "ssh bee-host 'tail -f /var/log/bee.log'"

--bee-log tails from EOF — pre-existing history doesn't replay. The tailer survives log rotation (logrotate-style inode swaps) and truncation.

--bee-log-cmd runs the command through sh -c, so pipes / quoting / redirects in the operator's string behave as typed. The child is killed on quit. Stderr is discarded — sources that write to stderr (e.g. docker logs) should redirect with 2>&1.

Per-node config

[[nodes]]
name = "production"
url = "http://bee-prod.internal:1633"
log_command = "ssh bee-prod.internal 'tail -f /var/log/bee.log'"

[[nodes]]
name = "supervised"
url = "http://localhost:1733"
log_file = "/var/log/bee/bee.log"

When switching nodes (Ctrl+N or S15 Enter), beegui re-resolves the source against the new node and respawns the tailer. The log-pane rings clear so stale lines don't bleed across nodes.

Auto-discovery (Linux only)

When no explicit source is set, beegui walks /proc to find the Bee process behind the active node URL:

  1. Parse the node URL — must be a loopback host (localhost, 127.0.0.1, ::1).
  2. Find the PID listening on the API port (from /proc/net/tcp{,6}).
  3. Classify /proc/<pid>/fd/1 (Bee logs to stdout):
    • Regular file → tail it directly.
    • Pipe under dockerdocker logs -f <id>.
    • Pipe under systemdjournalctl -u <unit> -f.
    • TTY / null / opaque pipe → can't capture; the pane header explains and suggests log_command.

Non-Linux hosts and remote URLs fall through to the no-source placeholder.

The seven log tabs

Ctrl+L opens the pane. Tabs (from the parser in bee_cockpit_core::bee_log):

TabSource
ErrorsBee log lines with level=error.
Warninglevel=warning.
Infolevel=info.
Debuglevel=debug.
Bee HTTPBee's own incoming API request log lines.
bee::httpThe cockpit's outbound calls (a different stream).
Cockpitbeegui's own tracing events (tracing::info! and friends).

The bee::http and Cockpit tabs are populated whether or not a bee-log source is configured — they're powered by the cockpit's own tracing capture, not by an external file.

Filtering

Severity-tab routing already filters by level. Free-text filtering inside a tab isn't implemented yet (it is in bee-tui's / filter — beegui will catch up in a later release).

Bee process supervision

When --bee-bin and --bee-config are set (or the [bee] block is present in config), beegui forks Bee as a child process for the session and owns its lifecycle:

beegui --bee-bin ./bee --bee-config ./bee.yaml

At startup:

  1. The binary's existence + executability are checked.
  2. A rotating log file is opened in $TMPDIR/beegui-spawned-<ts>.log.
  3. bee start --config <yaml> is forked. Stdout + stderr are captured to the rotating writer; the child gets its own process group so SIGTERM-pgroup later kills the whole tree.
  4. beegui polls /health until it returns 200, up to 60 s. Bee's first start can include chain-state catch-up, hence the generous timeout.
  5. The cockpit window opens.

Status chip

The bottom status bar (right side) shows the supervisor state:

LabelMeaning
● bee runningProcess alive. Green.
○ bee exited (0)Clean exit. Grey.
✕ bee exited (137)Non-zero exit. Red (137 typically = OOM kill).
✕ bee killed (sig 9)Killed by signal. Red.

Polled every frame.

Auto-routed log

The supervisor's rotating capture file is automatically wired as the bee-log source — Errors / Warn / Info / Debug / Bee HTTP tabs populate without any --bee-log flag. The pane header shows [supervised] as the source origin.

When the supervisor is active, --bee-log / --bee-log-cmd / auto-discovery are ignored for the active node — the supervisor's file is always the freshest source.

Log rotation

The capture file rotates by size; defaults are 64 MiB per file, 5 retained files (≈320 MiB ceiling). Override in config:

[bee.logs]
rotate_size_mb = 128
keep_files = 10

Rotation is transparent to the tailer.

Clean shutdown

on_exit fires when the window closes. beegui:

  1. Sends SIGTERM to Bee's process group.
  2. Waits up to 5 s for clean exit (Bee's shutdown closes RocksDB cleanly — rushing it leaves the DB in recovery-required state on next start).
  3. Escalates to SIGKILL if Bee hasn't exited.

The terminal output reports the final status (bee exited cleanly / bee killed (signal 9)).

What's not (yet) supported

  • Auto-restart watchdog. bee-tui supports [bee.supervisor] auto_restart = true for crash-loop recovery; beegui currently always behaves as if auto_restart = false: log the exit, dim the chip, no respawn. Operators restart beegui to retry.
  • Interactive restart. No palette verb to restart Bee in place — quit and relaunch beegui.

Both are reasonable v1.x additions.

When supervision is the right tool

  • Dev rigs. beegui takes care of Bee lifecycle so you only manage one process.
  • Testnet/Sepolia experiments. Especially with the bee-rs Sepolia integration-check rig.
  • Single-shot debugging. Start Bee, observe its logs, close the window — Bee is gone too.

When not:

  • Production nodes. Use systemd / Docker as the supervisor and have beegui connect to the API + tail logs (--bee-log).
  • Multi-node fleets. Supervision is per-cockpit-session; the fleet view is fine but the supervisor only owns the active node's process.

--once CLI

beegui ships the full bee-tui --once verb surface for CI / cron / scripting use. No GUI is opened; the result is printed to stdout (text by default, JSON with --json) and beegui exits with a status code:

CodeMeaning
0Ok.
1Unhealthy / verb produced a sad result.
2Error (network, parse, …).
64Usage error (bad args).

Usage

beegui --once readiness --json http://localhost:1633
beegui --once depth-table
beegui --once hash ./somefile
beegui --once durability-check <ref>
beegui --once buy-preview --json

The verb takes positional arguments after it; the node URL (when needed) is taken from --node, BEE_NODE_URL, or the trailing positional. --config <path> works the same as in interactive mode.

Verbs

Inspection (no Bee write)

VerbWhat it does
readinessRun the gate ladder; exit 0 if green, 1 if any gate fails.
version-check (alias check-version)Compare beegui's expected Bee API version against the live server.
config-doctorValidate the config file; flag missing nodes / bad tokens / unknown keys.
hash <path>Compute the swarm hash of a local file.
cid <ref> [manifest|feed]Compute the CID.
depth-tablePrint the stamp depth → chunks-storable table.
pss-targetPrint the recommended target for the current overlay.
gsoc-mine <nonce>Mine a GSOC identifier for the given nonce.
priceCurrent chain price.
basefeeCurrent chain basefee.
inspect <ref>One-shot manifest walk; report children + sizes.
durability-check <ref>Walk the chunk graph; report bad/missing.
feed-probe <owner> <topic>Fetch latest feed update.
feed-timeline <owner> <topic> [max]Walk feed history.
grantees-list <ref>List grantees of an ACT-controlled reference.

Stamp-math previews (no transactions)

VerbWhat it does
buy-preview <depth> [amount]What would :batch buy cost?
buy-suggestRecommend a depth based on current reserve fill.
topup-preview <id> <amount>TTL extension preview.
dilute-preview <id> <new-depth>Dilute preview.
extend-preview <id> <seconds>Time-extend preview.
plan-batchEnd-to-end batch plan (depth + amount + estimated TTL).

Active (Bee writes)

VerbWhat it does
upload-file <path> [batch-prefix]Upload a single file.
upload-collection <dir> [batch-prefix]Upload a directory as a Mantaray collection.

Output

Default is one human-readable line. --json emits a single object with verb, status, message, and data fields — parseable with jq.

$ beegui --once readiness --json
{"verb":"readiness","status":"ok","message":"all 11 gates pass","data":null}

Why a separate CLI mode

bee-tui's --once exists for the same reason: operators want to script the same logic the cockpit visualises. Drop a beegui --once readiness into a cron and you have a health probe that returns the same verdict as opening the GUI and reading the gate ladder by eye.

FAQ

How is beegui different from bee-tui?

Both speak the same logic from bee-cockpit-core (gates, drills, fleet roll-up, …). bee-tui paints with ratatui in a terminal; beegui paints with egui in a native desktop window. Pick beegui when you'd prefer the window — clickable rows, drag-and-drop uploads, OS notifications.

Where is the config file?

~/.config/beegui/config.toml on Linux. macOS uses ~/Library/Application Support/beegui/config.toml; Windows uses %APPDATA%\beegui\config.toml. Override with --config <path> or BEEGUI_CONFIG.

Why is the bottom log pane mostly empty?

The Errors / Warn / Info / Debug / Bee HTTP tabs depend on a bee-log source. Without one (no --bee-log, no [[nodes]] log_file/log_command, no --bee-bin, no Linux auto-discovery match), those tabs stay empty. The bee::http tab (cockpit's outbound calls) and the Cockpit tab (beegui's own tracing) are populated regardless.

The pane header shows the resolved source — if it says "(no bee-log source)" the empty tabs are expected.

Why doesn't auto-discovery work for my remote Bee?

It's Linux-only and local-only: it walks the host's /proc to find the Bee process behind the URL. Remote URLs and non-Linux hosts fall through. Set [[nodes]].log_command to a ssh remote 'tail -f /var/log/bee.log' or the equivalent for your setup.

Why does my screencast/screenshot directory look empty?

Because we haven't captured them yet. docs/screenshots/ ships with just the capture recipe. Captures are user-side — beegui is a real desktop app and there's no faithful headless renderer.

Can I get desktop notifications across SSH?

Not for the OS-native ones. notify-rust talks to the local session bus (libnotify on Linux, Notification Center on macOS). For remote-node notifications use the [alerts] webhook_url instead, which fires Slack-compatible webhooks.

How do I switch nodes mid-session?

Ctrl+N opens the picker from anywhere. :context <name> does the same from the palette. S15 Fleet shows every node; Enter on a row switches.

Does beegui restart Bee if it crashes?

Not yet — the supervisor in v0.11 always behaves as if auto_restart = false. The status chip turns red on exit; you restart beegui to retry. bee-tui has the watchdog; beegui's catch-up is a v1.x item.

Where does beegui write data?

~/.local/share/beegui/ on Linux (or $XDG_DATA_HOME/beegui). macOS/Windows equivalents follow the platform conventions. Override with BEEGUI_DATA.

Why does cargo install beegui take a while?

eframe pulls in glow, winit, glutin, and a chain of windowing deps. First build on a fresh machine is ~5 minutes; subsequent incremental builds are seconds.

Why is my Ctrl+L log-pane toggle eaten by something else?

Some terminal emulators bind Ctrl+L to clear-screen and pass that to the foreground app. beegui is a native window, not a terminal app, so this shouldn't happen — but check that the keyboard focus is on beegui's window and not e.g. a transparent terminal you forgot was on top.

Where do I file a bug?

https://github.com/ethswarm-tools/beegui/issues. Mention the beegui version (beegui --version), the OS, and either reproduce steps or relevant log lines from the Cockpit tab.