System metrics in the Herdr sidebar — a faithful port of a
tmux-cpu / tmux-battery / tmux-online-status status bar into Herdr
workspace tokens.
Renders in the left sidebar, per workspace:
- CPU % (100 − idle)
- Memory — active + wired pages → GB (port of
~/dotfiles/tmux/memory.sh) - Battery — Nerd Font glyph + percentage, charging-aware
- Network — on / off (ping)
- Disk — free space on the home filesystem
- Clock — weekday, month, day, time
- Focused pane path (basename, truncated), zoom flag, prefix indicator
Built-in workspace / branch / git_status tokens are reused, so the
sidebar also covers what tmux status-left showed for session name and Git
context.
Herdr's startup hook is one-shot, so the plugin's startup hook detaches a
long-running poll.sh poller and exits. The poller:
- Collects every metric once per cycle (default 5s).
- Pushes them as custom workspace metadata tokens via
herdr workspace report-metadata --source sysmon. - Repeats across all workspaces, picking up new ones on the next cycle.
The sidebar config renders those tokens as $sys_*.
- No
set -ein the loop — a single metric or CLI failure never exits. - Never-empty tokens — every collector falls back to
--; a total command failure is coerced to a placeholder so a sidebar row never vanishes. - Primed on first cycle — tokens exist before the sidebar first paints.
- Pidfile guard — Herdr restarts never spawn duplicate pollers.
- Graceful on socket loss — if the Herdr server is stopped, the poller retries next cycle; tokens are restored the moment a workspace reappears.
Once Herdr is installed and the plugin API is available:
# from a local checkout
herdr plugin install ~/local-dev/getpipher/herdr-sysmon
# or, once published, from GitHub
herdr plugin install getpipher/herdr-sysmonThen merge the sidebar config into your config.toml:
cat ~/local-dev/getpipher/herdr-sysmon/config/sidebar.toml.snippet >> ~/.config/herdr/config.toml
herdr server reload-configVerify the path with prefix+s (in-app settings) if ~/.config/herdr/ is not
correct on your system.
- Herdr ≥ 0.7.0
- macOS (v0.1 uses
pmset,vm_stat,df). Linux reads land in v0.2. jq(for parsingherdr … --json)- A Nerd Font for the battery / wifi / clock glyphs (JetBrainsMono Nerd Font works, matching the existing Ghostty config)
| Env var | Default | Meaning |
|---|---|---|
SYSMON_CADENCE_SEC |
5 |
Seconds between pushes. Lower = fresher, more CPU. |
HERDR_BIN_PATH |
herdr |
Set by the plugin runtime; override for manual runs. |
HERDR_PLUGIN_STATE_DIR |
<plugin>/.state |
Where the pidfile + log live. |
State files (in HERDR_PLUGIN_STATE_DIR or .state/):
sysmon.pid— poller pidsysmon.log— per-cycle log
# start manually (foreground, for testing)
bash scripts/poll.sh --run
# spawn detached (what the startup hook does)
bash scripts/poll.sh --spawn
# stop the poller
bash scripts/poll.sh --stop
# tail the log
tail -f .state/sysmon.log- macOS only (
pmset,vm_stat,df ~). v0.2 adds Linux reads. $sys_path/$sys_prefixare best-effort —$sys_pathreadsherdr pane current(.result.pane.cwd, confirmed shape);$sys_zoomreadsherdr pane layout(.result.layout.zoomed, confirmed it flips on toggle).$sys_prefixhas no CLI/snapshot exposure in v0.1 (prefix-active state is not surfaced) and stays empty pending a socket subscription in v0.2. The 6 system metrics (the core requirement) are fully covered regardless.- No supervisor beyond the startup hook. The poller is self-healing within
a run (a failed metric never kills the loop), but a shell crash leaves it
down until the next Herdr restart relaunches via the startup hook. A
launchdKeepAlivewrapper is planned as a Phase 2 belt-and-suspenders layer for "never down" guarantees. - No theming — v0.1 renders tokens in the sidebar's contextual style. The
Catppuccin per-widget color map (maroon / teal / lavender / peach / blue /
yellow from the old status bar) is v0.2 via inline
fgstyle tables.
herdr plugin uninstall getpipher.herdr-sysmon
# remove the merged sidebar block from config.toml, then:
herdr server reload-configMIT © 2026 RECTOR