Dev Tools & Software
GitHub - ppetermann/crew-watch: TUI fleet monitor: htop-styl
github.com ↗TUI tool to monitor firstmate controlled fleets
Overview
crew-watch is a terminal UI fleet monitor for machines running AI coding agents. It displays an htop-style system overview in the top half and a per-agent-session table below, showing CPU and memory aggregated over each agent's process subtree, the model in use, elapsed time, and a one-line task description. It is built as a companion to firstmate and is developed by ppetermann on GitHub.
What it is / What it does
- Top half: htop-style system overview — per-core usage bars, memory and swap bars with used/total figures, task count, load average (1/5/15), and uptime.
- Bottom half: one row per running agent session, with CPU and memory aggregated over the agent's entire process subtree (including spawned compilers, test runners, and tools).
- Per-row columns: STATE (activity glyph), RUNTIME (agent kind), MODEL (from
--modelargument, provider prefix stripped), PID, ELAPSED, CPU%, MEM, and TASK. - Rows sorted by aggregated CPU% descending; numeric columns right-aligned, text columns left-aligned.
- Narrow-terminal behavior: fixed columns shrink, values shorten by unit and precision first, never losing leading digits.
- firstmate integration: when pointed at a firstmate home, each row picks up the task title and a live activity state (busy, waiting, blocked, needs-decision, done) read from firstmate's own task state files. No fork, plugin, or configuration required.
- Without a firstmate home, process detection, subtree CPU/memory, model, and elapsed still work; TASK falls back to the project directory and STATE falls back to interactive/unknown glyphs.
--oncemode: collects two samples about a second apart, prints system summary and agent table as plain text to stdout, no TTY needed. Output is grep- and diff-friendly with no emoji or bars.- Optional quota row: shows per-provider session/week/per-model usage bars with percentage and reset countdown, populated by shelling out to the external
quota-axitool. - Supported agent runtimes (matched by process basename with prefix matching): claude, opencode, codex, grok, kimi, muse, pi.
- Adding a runtime is one row in
AGENT_KINDSinsrc/detect.rs. - Sessions and nesting: the top-most agent process in a subtree gets one row; child processes are folded into their nearest enclosing agent's CPU/memory aggregate; nested agents get their own row and are excluded from ancestor totals.
- Task descriptions resolved from layered sources (first match wins): firstmate task record, then git repository name (or directory basename), then a short excerpt of positional arguments.
- Config file at
${XDG_CONFIG_HOME:-~/.config}/crew-watch/configstores quota provider selection as key=value lines; written by thepdialog; unknown keys preserved. - Keybindings:
q/Esc/Ctrl-Cto quit;pto choose quota providers.
Stack / Implementation
- Language: Rust (Cargo project;
Cargo.tomlandCargo.lockpresent). - Platform: Linux only. Reads
/procdirectly with no other backend. - Build requirement: recent stable Rust toolchain plus a working C link chain (
build-essentialon Debian/Ubuntu,gccon Fedora). - Not published on crates.io; installed from source via
cargo install --gitorcargo install --path. - Optional external dependency:
quota-axi(npm package, installed vianpm i -g quota-axi) for the quota row. Without it, the tool works normally and the row is absent. - No daemon, no pre-run config, no network access on the monitoring path.
/procis read exactly once per refresh. - Documentation files:
docs/development.md(building, testing, linting, CI, adding a runtime) anddocs/design-notes.md(architecture, layout contracts).
Author / Source
- Author: ppetermann (GitHub user).
- Repository: https://github.com/ppetermann/crew-watch
- License: MIT.
Notes
- CLI flags:
--interval <secs>(default 2),--once,--fm-home <dir>(also settable viaCREW_WATCH_FM_HOME, defaults to~/agents/firstmate),--no-quota,--quota-interval <secs>(default 600, clamped 60..=3600),--help,--version. - STATE column has TUI emoji glyphs and
--onceword equivalents; on terminals too narrow for two-cell columns, glyphs fall back to single ASCII characters. Authoritative tables live insrc/activity.rs. - firstmate files read per task:
state/<task>.meta(process matching, project name),state/<task>.status(lifecycle verb),state/<task>.busy-state+state/<task>.busy-gen(busy vs. waiting split),data/backlog.md(task title),data/<task>/brief.md(fallback title). Records are re-read on every refresh. - Quota fetch runs on a background thread at its own cadence with a 10s timeout, never on the refresh path. The 60s floor exists because quota tooling rate-limits under faster polling. Stale/cached data is dimmed and marked; repeated misses dim the whole row and add an
(Xm old)suffix while retaining last good numbers. - The repository contains 42 commits and includes
AGENTS.mdandCLAUDE.mdfiles alongside the source.