https://github.com/yrstm/agentdash
w for your AI agents - a terminal table of every coding agent on a box and whether it needs your input
https://github.com/yrstm/agentdash
ai-agent bash claude-code cli monitoring tmux tui
Last synced: 9 days ago
JSON representation
w for your AI agents - a terminal table of every coding agent on a box and whether it needs your input
- Host: GitHub
- URL: https://github.com/yrstm/agentdash
- Owner: yrstm
- License: mit
- Created: 2026-06-11T02:52:51.000Z (14 days ago)
- Default Branch: main
- Last Pushed: 2026-06-11T18:26:33.000Z (13 days ago)
- Last Synced: 2026-06-11T19:16:42.042Z (13 days ago)
- Topics: ai-agent, bash, claude-code, cli, monitoring, tmux, tui
- Language: Shell
- Homepage:
- Size: 472 KB
- Stars: 3
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# agentdash
`w`, but for AI coding agents. agentdash prints a table of the agent
processes on a Linux box: what each one is working on, what model it is
on, how full its context is, and whether it is blocked waiting on you.
`-w` turns the table into a small interactive TUI.
It is a single static binary with zero runtime dependencies, reading
the session files agent CLIs already write locally (Claude Code and
Codex are supported; adding another agent is a small parser, see
CONTRIBUTING.md) and /proc directly. No daemon, no server, no API
calls, no telemetry, and it never launches or manages sessions. Watch
mode is event-driven: a session write reaches the screen in
milliseconds, not at the next poll. I wrote it because I kept losing
track of agents across tmux sessions; maybe it is useful to you too.
Linux only.

## Install
```sh
curl -fsSL https://raw.githubusercontent.com/yrstm/agentdash/main/install.sh | sh
```
or grab the binary directly:
```sh
curl -fsSLo ~/.local/bin/agentdash https://github.com/yrstm/agentdash/releases/latest/download/agentdash-linux-amd64
chmod +x ~/.local/bin/agentdash
```
or with Homebrew (this also works on Linux), or go install:
```sh
brew install yrstm/agentdash/agentdash
go install github.com/yrstm/agentdash/cmd/agentdash@latest
```
It is a single static binary with zero runtime dependencies. Optional:
tmux (pane jumping, attachment glyphs), docker (sandbox section, skipped
if absent), jq (only for the integrations). The auditable v1 bash
version lives in `legacy/` and keeps working.
## Usage
```
agentdash print the table once
agentdash -w [secs] watch mode (default 5s), keys below
agentdash -a expand collapsed rows and healthy sections
agentdash -l long view: adds PID, TTY, UP columns
agentdash -t tree view: group agents under the wrapper that spawned them
agentdash --json machine-readable output (schema_version 1)
agentdash --plain no color, no glyphs; NO_COLOR is honored
agentdash --any-waiting exit 0 if anything needs you
agentdash go [row|pid] jump to that agent's tmux pane
agentdash show drill-down with recent turns and resume command
agentdash why where every value on the row came from
agentdash label "text" pin a task label
agentdash resume print the resume command for a session
agentdash recap [4h] what changed since you last looked
```
### Watch mode keys
Watch mode has a cursor (`▸`); keys act on the selected row. Panels open
over the board and any key returns to it.
```
j/k or arrows move the cursor
g jump to the agent's tmux pane
s drill-down panel: recent turns, session path, resume command
y provenance panel: where each value on the row came from
L edit the task label
r show the resume command
/ filter rows across task, cwd, model, status (Esc clears)
o cycle sort: urgency, last-write, tokens, uptime
t toggle tree view l toggle long view
a toggle expanded view ? help
mouse wheel scrolls, click selects (off under --plain)
q quit
```
The board refreshes when a session file changes (fsnotify, debounced),
not on a timer; process starts and exits are picked up by a cheap /proc
scan every second (`AGENTDASH_PROC_TICK`).
## The table
```
devbox 14:02 · 2 need you · 3 working · 6 idle · 8m ctx held idle · load 0.27
AGENT LAST MODEL TOKENS CTX ACT STATUS CWD TASK
▸ claude ○ 4m opus-4-8 34m/359k ▓▓▓░░ 45% ▅▂▁ waiting ~/c/api settlement reconciliation
claude ● 12s fable-5 18m/285k ▓▓░░░ 35% ▆█▇▅ working ~ migrate the queue
+ 2 wrappers · 1 unmatched (-a to list)
ok: tmux ×4 · logins ×2 · sandboxes ×3 · ports ×4 · no zombies
```
Rows sort by urgency and keep their order between refreshes. Healthy
sections collapse into the `ok:` line and expand only when something is
flagged; pass `-a` (or set `AGENTDASH_EXPAND=1`) to always expand
everything. Defunct (zombie) processes and orphaned wrapper processes — a
`bash -c`/`nohup` launcher still running with no controlling tty after its
agent has exited — surface in a ZOMBIES & ORPHANS section when present.
Glyphs: `●` tmux attached, `○` detached; a red `○` means the agent is
waiting and nobody is attached.
Columns: LAST is time since the session file was written. TOKENS is
cumulative input/output, where input includes cache reads and writes (it
measures context fill, not billing). CTX is the last request against the
model's context window, yellow at 70%, red at 85%. ACT is bytes appended
per refresh over the last 8 intervals. TASK is your label, else the
session's summary, else the first prompt; a trailing `?` means the
process-to-session pairing was heuristic.
Colors carry one meaning each: green working, yellow worth a look, red
needs you now, dim ignorable. A healthy board is almost colorless.
Tree view (`-t`, or `t` in watch mode) regroups the rows so an agent sits
under the wrapper process that spawned it, found by walking the ppid
chain. Urgency order still applies to the top level.
## Design notes
agentdash started life as a bash script with an embedded stdlib-only
Python parser: session files are JSONL with nested, escaped content
(prompts hold quotes, unicode, pasted code), which bash regex cannot
parse correctly, and jq would have been a lateral dependency swap that
loses the stateful incremental scan. v1 proved the heuristics in
bash+python; v2 compiles them. The genre's reference tools (`w`,
`htop`) are compiled C for a reason: the Go version reads /proc and
the session files directly, drops the procps/iproute2/python3
dependencies entirely, and turns the polling watch loop into an
fsnotify subscription. The v1 script is preserved, working, in
`legacy/agentdash.sh`; `tools/parity.sh` holds the two implementations
to identical `--json` output. The only socket the tool will ever open
is the local docker unix socket for the sandboxes section, and CI
enforces that with strace.
The scanner is incremental by byte offset: each render stats every
paired session file and parses only the bytes appended since the last
look, folding them into a cached per-session entry. Only complete lines
are consumed, since an agent may be mid-write; a partial tail line
waits for the next refresh. That is why a board over gigabytes of
session history costs milliseconds once the cache is warm.
Pairing a pid to a session file never guesses silently. A five-tier
evidence chain runs from exact to heuristic, records which tier fired,
and anything below the confident tiers is marked with a `?` on the
board. `agentdash why ` prints the recorded evidence for every
value on the row.
## Performance
Measured with the reproducible suite in `bench/` (4-core container,
25 MB session corpus, methodology and caveats in
[docs/benchmarks/](docs/benchmarks/v2-comparison.md)):
| metric | v1 (bash+python) | v2 (Go) |
|---|---|---|
| one-shot render, warm cache | 174 ms | 15 ms |
| one-shot render, cold cache (25 MB) | 562 ms | 368 ms |
| idle watch CPU, 10 min avg | 3.65 % | 0.29 % |
| session write to screen | ~2.3 s | ~80 ms |
| peak memory (PSS), cold render | 38 MB | 17 MB |
| dependencies on a clean box | bash python3 procps iproute2 | none |
## How values are derived
Pairing a process to a session file walks an evidence chain: an open fd
in /proc, then a unique session file in the project dir for the process
cwd, then a first-entry timestamp within 5 minutes of process start,
then a sticky previous guess, then the newest unclaimed recent file
(the last two are heuristic and marked `?`). Codex sessions record
their cwd and start time in the rollout file, which pairs them
directly. `agentdash why ` prints which tier applied.
Status: file written under 60s ago is `working`; over 10 minutes quiet is
`idle`; in between, `waiting` if the last entry is an assistant turn, else
it is graded by how long it has been quiet on a user/tool entry: `busy?`
(dim) under `AGENTDASH_STUCK_SECS` (default 90s) — likely a slow tool call,
not alarming — and `stuck?` (red) past it. This grading replaces the old
flat "silent over a minute = stuck?" false positive. `respawn ×N` means
three or more fresh pids on one session file within 10 minutes. Thresholds
are configurable via `AGENTDASH_WORKING_SECS`, `AGENTDASH_STUCK_SECS` and
`AGENTDASH_IDLE_SECS`.
Context windows come from `~/.config/agentdash/context-windows.conf`
(` `, first match wins), then built-in
defaults, then self-correction: if observed context exceeds the assumed
window, the larger tier is adopted and written back to the conf.
Port flags: `NEW` is first seen since the previous run, `dup-cwd` is two
listeners in one project directory, `no-agent` is a tty-less listener in a
project directory no agent or tmux pane is using.
## Privacy
The TASK column shows prompt text and the cache at
`~/.cache/agentdash/usage.json` persists it (mode 0600). Mind
screen-sharing and log shipping.
## License
MIT.