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 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 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 and docs/traps.md.
β setup, Windows hosts, background agents, the right-click actionsUser guideβ the collector/app split, state derivation, liveness, the security modelArchitectureβ the hard-won gotchas: the Store-stub Python, the macOS Local Network deadlock, the SSH control-socket that makes every test lieTrapsβ empty list, no prompt, notificationsTroubleshootingΒ·ContributingΒ·SupportLicence (MIT)
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.