macOS menu bar status item that shows your Claude Code agent metrics at a glance.
● 6 | 22m | $137.1
Green dot = open sessions. Click to expand detailed metrics.
Menu bar: ● [open sessions] | [time] | [cost]
- Green dot
●— sessions are open - Gray dot
●— no open sessions - Time — total wall-clock session time today
- Cost — total USD spent today
Dropdown (click to open):
- Sessions (total + open count)
- Cost (total USD today)
- Prompts (total today)
- Tokens (input / output / cache)
- Git activity (commits, files changed)
- Open sessions breakdown (project, duration, cost)
-
macOS 13 (Ventura) or later
-
Xcode Command Line Tools (provides the Swift compiler)
xcode-select --install
Verify with:
swiftc -version(should show Swift 5.9+) -
Hook Hero — the Claude Code telemetry plugin that generates the data
# Clone and install Hook Hero git clone https://github.com/damahua/claude-code-hook-hero.git cd claude-code-hook-hero npm install cd dashboard && npm install && npm link && cd .. claude plugin marketplace add "$(pwd)" claude plugin install hook-hero
Verify with:
hook-hero live(should show the dashboard) -
Claude Code — the CLI tool that fires hook events
- Hook Hero Bar only shows data when Claude Code sessions are running or have run today
git clone https://github.com/damahua/hook-hero-bar.git
cd hook-hero-bar
./scripts/bundle.shThis builds a release binary and wraps it in HookHeroBar.app (a proper macOS app bundle with LSUIElement — no Dock icon, no Terminal window).
open HookHeroBar.app- No dock icon, no Terminal window — runs as a menu bar agent
- The menu bar item appears immediately (right side, near the clock)
- If no
status.jsonexists yet, it shows● 0 | 0m | $0.00until the first Claude Code session fires a hook
pkill -x HookHeroBar; ./scripts/bundle.sh && open HookHeroBar.apppkill -x HookHeroBarTo start automatically when you log in:
- Open System Settings > General > Login Items
- Click + and add
HookHeroBar.appfrom the project directory
The data file hasn't been generated yet. Start a Claude Code session (or interact with an existing one) — the hooks will write ~/.claude/hook-hero/status.json automatically.
To force an immediate write:
cd /path/to/claude-code-hook-hero
node --input-type=module -e "
import { writeStatus } from './lib/write-status.mjs';
import { SessionStore } from './lib/session-store.mjs';
const store = new SessionStore();
writeStatus(store);
"- Check if the app is running:
pgrep -l HookHeroBar - Some menu bar managers (Bartender, Hidden Bar) may hide new items — check their settings
- Try quitting other menu bar apps to free space
The menu bar and dashboard use slightly different computation methods. Small differences (~5%) are expected. Large gaps may indicate the plugin cache is stale:
# Reinstall the plugin to refresh the cache
claude plugin uninstall hook-hero
claude plugin marketplace remove hook-hero
claude plugin marketplace add /path/to/claude-code-hook-hero
claude plugin install hook-hero
# Install dependencies in cache
npm install --prefix ~/.claude/plugins/cache/hook-hero/hook-hero/1.0.0The plugin cache is missing dependencies. Fix with:
npm install --prefix ~/.claude/plugins/cache/hook-hero/hook-hero/1.0.0Your Swift compiler doesn't match the macOS SDK. Update Command Line Tools:
softwareupdate --list
# Find and install the Command Line Tools update:
softwareupdate --install "Command Line Tools for Xcode <version>"Hook Hero (Claude Code plugin) writes ~/.claude/hook-hero/status.json whenever hook events fire (session start/end, prompts, AI turns). This app watches that file with FSEvents and updates the menu bar display in real time.
Claude Code hooks → Hook Hero writes status.json → Hook Hero Bar reads & displays
Zero IPC, zero networking — just a JSON file on disk.
The menu bar updates whenever a hook event fires:
SessionStart— new session opensSessionEnd— session closesStop— AI finishes a turn (cost/token updates)UserPromptSubmit— you send a prompt
Between events, the display stays static. During long AI turns, numbers may be a few minutes stale.
The app compares the updated_at timestamp against the current date. When a new day starts, it resets to zeros until the first hook event of the day.
Sources/HookHeroBar/
├── main.swift — Entry point, no dock icon
├── AppDelegate.swift — Starts file watcher + menu bar
├── StatusModel.swift — Codable structs for status.json
├── StatusFileWatcher.swift — FSEvents-based file watcher
├── MenuBarController.swift — NSStatusItem + popover
└── DropdownView.swift — SwiftUI dropdown with metrics
See config/status-schema.json in the Hook Hero repo for the full JSON Schema.
MIT