# Claude-Fleet

> Source: <https://github.com/Shubhamgupta2612/claude-fleet>
> Published: 2026-07-31 23:48:21+00:00

A native macOS **menu bar** app that shows every Claude Code session you have
running — on this Mac and on a remote machine over SSH — grouped by git repo, so
you can tell at a glance which one is stuck waiting on you.

The one thing it exists to tell you: **which session is sitting at an unanswered
permission prompt right now.** When Claude asks "can I run this command?" inside a
window you're not looking at, that session freezes and you have no idea until you
happen to switch to it. Claude Fleet puts that in your menu bar — and when a session
starts needing you, it jumps to the top.

An independent, community-built tool. Not affiliated with, or endorsed by, Anthropic.

This is a personal tool, built for one setup and published as-is under MIT. It reads Claude Code's on-disk files, which are

undocumentedand can change in any Claude Code release — when they do, this breaks until someone fixes it.

I fix what breaks for me.Issues are open but may go unanswered; PRs are welcome but may sit. There is no roadmap and no release cadence. If that's not what you need, fork it — that's what the licence is for.When it does break, it breaks

loudly: the reason lands inSettings → Diagnosticsand in`~/.claude-fleet/last-poll.log`

. Please include that in any issue. See[SUPPORT.md].

Sessions. That's it — grouped by the git repo they're in.

No machine names, no connection status, no error rows, no "unreachable" warnings.
If the remote machine is off-network the list is simply **empty and calm**.
Anything the app can't reach, or chooses to hide, is explained only in **Settings →
Diagnostics** — never in the session list itself.

Grouping is by **git repo**, not by directory: sessions in `acme-web`

,
`acme-web/services/api`

and `acme-web/worker`

collapse into one `acme-web`

group
rather than scattering into three. The row shows the path within the repo so you can
still tell subfolder sessions apart.

| dot | state | meaning |
|---|---|---|
| 🟠 | Needs approval |
A tool call was issued and nothing has moved since — an unanswered permission prompt. This is the state the app is for. |
| 🟡 | Your turn |
Claude finished its turn and is waiting for you to type something |
| 🟢 | Working |
A tool call is in flight and the transcript is actively moving |
| ⚪️ | Idle |
A "your turn" session you walked away from — grey, de-emphasised, uncounted |

Repos containing a **Needs approval** session float to the top, so the thing that
needs you is always the first thing you see. The menu bar badge counts only the
sessions that need you now (**Needs approval** + **Your turn**).

Requires macOS 14+ and the Xcode command line tools (`xcode-select --install`

).

```
git clone <this-repo> claude-fleet
cd claude-fleet
./build.sh
open ~/Applications/ClaudeFleet.app
```

`build.sh`

compiles, signs (ad-hoc by default — no Apple account needed), and installs
to `~/Applications/ClaudeFleet.app`

. It's an `LSUIElement`

app: menu bar only, no Dock
icon, no app-switcher entry.

**Start at login:** System Settings → General → Login Items → **+** →
`~/Applications/ClaudeFleet.app`

. (Documented rather than done for you, so nothing
adds itself to your login silently.)

**On first launch**, macOS asks to allow Claude Fleet to access devices on your local
network — **click Allow**, or the remote machine can never be reached. See
[docs/troubleshooting.md](/Shubhamgupta2612/claude-fleet/blob/main/docs/troubleshooting.md) if no prompt appears.

Open the panel → **Settings**:

**Machine**— an alias from your`~/.ssh/config`

(the same one you already SSH or VS Code Remote-SSH with, so its user, port and key are inherited). Leave blank for this-Mac-only.**Include this Mac**— on by default; turn it off to watch only the remote.** Refresh every**— 5s / 15s / 30s / 1m (default 15s).

The remote needs nothing installed: the collector is piped over SSH and is
stdlib-only Python. See [docs/user-guide.md](/Shubhamgupta2612/claude-fleet/blob/main/docs/user-guide.md) for the full setup,
including Windows hosts.

```
ClaudeFleet.app  ──every 15s──▶  python3 collector.py            (this Mac)
                 ──every 15s──▶  ssh <host> '<py|python3> -' < collector.py   (remote)
                        │
                        └─▶  framed JSON  ──▶  repo groups  ──▶  menu bar
```

`collector.py`

reads two things Claude Code writes on each machine — a per-process
registry (`~/.claude/sessions/<pid>.json`

) and a per-session transcript
(`~/.claude/projects/<slug>/<sessionId>.jsonl`

) — and prints one small JSON document.
It is **piped over SSH stdin**, so nothing is ever installed on the remote and nothing
needs to be kept in sync there.

The full design, and the traps that make it non-trivial, are in
[docs/architecture.md](/Shubhamgupta2612/claude-fleet/blob/main/docs/architecture.md) and [docs/traps.md](/Shubhamgupta2612/claude-fleet/blob/main/docs/traps.md).

— setup, Windows hosts, background agents, the right-click actions[User guide](/Shubhamgupta2612/claude-fleet/blob/main/docs/user-guide.md)— the collector/app split, state derivation, liveness, the security model[Architecture](/Shubhamgupta2612/claude-fleet/blob/main/docs/architecture.md)— the hard-won gotchas: the Store-stub Python, the macOS Local Network deadlock, the SSH control-socket that makes every test lie[Traps](/Shubhamgupta2612/claude-fleet/blob/main/docs/traps.md)— empty list, no prompt, notifications[Troubleshooting](/Shubhamgupta2612/claude-fleet/blob/main/docs/troubleshooting.md)·[Contributing](/Shubhamgupta2612/claude-fleet/blob/main/CONTRIBUTING.md)·[Support](/Shubhamgupta2612/claude-fleet/blob/main/SUPPORT.md)[Licence (MIT)](/Shubhamgupta2612/claude-fleet/blob/main/LICENSE)

Offline preview — rasterises the real panel to a PNG, no screen needed:

```
swiftc -O -parse-as-library -DPREVIEW -target arm64-apple-macos14.0 \
    -o /tmp/cfpreview Sources/*.swift && /tmp/cfpreview fixture.json /tmp/panel.png dark
```

Tests:

```
python3 -m unittest discover -s tests -t tests   # collector logic
./swift-tests/run.sh                              # notifier + security checks
```

`fixture.json`

is a synthetic multi-repo snapshot; the same file drives the app itself
via `CLAUDE_FLEET_FIXTURE=/path/to/fixture.json`

, bypassing SSH entirely.
