Skip to main content

legbar

One screen for the whole fleet: live agent sessions beside GitHub CI, drawn from a single discovery layer so the two panes can never disagree.

roost answers what are the models doing. leghorn answers what are the repos doing. Both are true at once and neither view contains the other — so watching a fleet has meant watching two windows and joining them by eye. legbar draws both lanes on one canvas.

legbar  5 sessions | 1 cursor | 1 need input | 15 ci red | 125k held | 18:37:00

SESSIONS                                                    CI / PRS
--------                                                    --------
cc heron-ops-3c FB5  ###-------  32% needsinput  dev        X  roost          ci
cc swamp-ops-ad OP5  ###-------  25% working     dev        X  roost          #56 ci: skip winget~
cc heron-ops-16 FB5  #---------  10% working     dev        X  copilot-money~ Tests
cc claude-10    OP5  #---------   8% idle        Claude     >  leghorn        release
cu c5468eb1     -                  - idle        dev        .  leghorn        #61 checks pending

legbar watching a fleet: two contested trees, sessions waiting on a human, and red CI that cannot scroll away

The short ambient loop below is the same program, idling — which is how it spends almost all of its time:

legbar's ambient loop, context bars climbing while the CI pane holds its failures

Both are real legbar, unmodified, reading a staged fleet — see demo/ for how it is built and how to re-record. The second contested row is the one worth looking at: a Claude session and a Cursor agent in the same working copy. Cursor writes no session marker and no claim, so a dashboard reading only Claude's session directory cannot see that collision at all.

What each lane shows

SESSIONS — every live agent on the machine. Claude Code sessions are joined by pid against ~/.claude/sessions/<pid>.json, with model, context burn, and status read from the session's own JSONL transcript. Cursor agents appear too, marked cu — Cursor writes no session marker and no claim, so a fleet view that only reads Claude's session directory is blind to every Cursor agent running beside it.

CI / PRS — GitHub Actions runs and open pull requests across every clone, with failures pinned so a red build cannot scroll away.

Install

pipx install legbar

Python 3.9+, standard library only. Works on macOS, Linux and Windows.

legbar also publishes to a few other channels, picked automatically off the same release:

pip install legbar                          # if you'd rather skip pipx
npm install -g legbar                        # Node's on the box already anyway
brew install gmhoward9289-ops/tap/legbar     # macOS / Linux
winget install gmhoward9289-ops.legbar       # Windows

Debian and Ubuntu can add the signed apt repo instead of a one-shot .deb:

curl -fsSL https://gmhoward9289-ops.github.io/legbar/legbar-archive-keyring.asc \
  | sudo gpg --dearmor -o /usr/share/keyrings/legbar-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/legbar-archive-keyring.gpg] \
  https://gmhoward9289-ops.github.io/legbar stable main" \
  | sudo tee /etc/apt/sources.list.d/legbar.list
sudo apt update && sudo apt install legbar

Windows without a package manager: grab the frozen .exe zip from the latest release.

Usage

legbar              # the full-screen view
legbar --once       # render one frame and exit (pipes, CI, screenshots)
legbar --json       # the joined state, for piping somewhere else
legbar --no-git     # skip git probing if it is ever slow
legbar --no-ci      # skip the gh sweep (offline, or when it is slow)

In the full-screen view: q quit, g toggle git probing, r refresh now.

Configuration

Every override is LEGBAR_*. The older roost / leghorn / ccwork variable names are still honoured, so an existing install keeps whatever it had configured; the new name wins when both are set.

Variable Default What it points at
LEGBAR_REPOS_ROOT ~/GitHub where the clones live
LEGBAR_SESSIONS_DIR ~/.claude/sessions live-session markers
LEGBAR_PROJECTS_DIR ~/.claude/projects session transcripts
LEGBAR_CURSOR_HOME ~/.cursor Cursor's agent transcripts
LEGBAR_CURSOR_MAX_IDLE_SECS 86400 how far back a Cursor agent counts as live
LEGBAR_BACKENDS claude,cursor which discovery lanes run at all

Two honest caveats

Cursor liveness is inferred, not probed. A Claude row means this process exists (os.kill(pid, 0)). A Cursor row means this transcript moved recently — Cursor writes no pid to join against. That is a weaker signal and it is labelled as one; pid is None for Cursor rows rather than invented.

Cursor's project slugs are lossy. The slug joins path parts with -, and - is legal inside a directory name, so c-Users-me-dev-heron-ops reads equally as dev/heron/ops and dev/heron-ops. legbar resolves each segment longest-first against what actually exists on disk. A slug that resolves nowhere — another machine's checkout, a deleted clone — falls back to the naive split rather than raising.

It is ASCII on purpose

Block-drawing characters mojibake in the Windows console, so the context bars, the pane rules and the status glyphs are all plain ASCII. Same constraint roost's sparklines and leghorn's tables are built around.

       ,__
     _(o  \__
    /        \
   |  ======  |
   |  ======  |
    \  ====  /
     \______/
      ||  ||
      ^^  ^^

Read-only

legbar reads transcripts and registries, and runs git and gh in read-only modes. It never writes to a repo.

The family

  • roosttop for Claude Code: per-session context burn, models, and the subagents a session spawned.
  • leghorn — the repo lane on its own: sessions joined to worktrees and real git state, CI, and a commit feed.
  • legbar — both lanes on one screen, over one discovery layer.

henhouse.py is that discovery layer: sessions, transcripts, git, GitHub, and Cursor. It is a working CLI in its own right (python henhouse.py).

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

legbar-0.2.1.tar.gz (60.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

legbar-0.2.1-py3-none-any.whl (45.5 kB view details)

Uploaded Python 3

File details

Details for the file legbar-0.2.1.tar.gz.

File metadata

  • Download URL: legbar-0.2.1.tar.gz
  • Upload date:
  • Size: 60.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for legbar-0.2.1.tar.gz
Algorithm Hash digest
SHA256 ed22a8b8da242d7386e84c6f28a071622351b3f77673eaa5c8f94bab0987879b
MD5 39980ca0f6c0cb1b99e982ab4e0363f2
BLAKE2b-256 b337a0f4e4e2aa3478f7f38df918bca3796f74f7ed1c277e401301c30abc4826

See more details on using hashes here.

Provenance

The following attestation bundles were made for legbar-0.2.1.tar.gz:

Publisher: release.yml on gmhoward9289-ops/legbar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file legbar-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: legbar-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 45.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for legbar-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ac6d8f32dbb0caeb6e901f8fec92ff0b6386815695c48bbda53df5522572f1a2
MD5 f0ff961ab1de1557ca751efd57fa2d7e
BLAKE2b-256 ecf39c1d296fe1f1b0ac6a37945ae8a0f0cfc2f84ac42f524ba338663316a83f

See more details on using hashes here.

Provenance

The following attestation bundles were made for legbar-0.2.1-py3-none-any.whl:

Publisher: release.yml on gmhoward9289-ops/legbar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page