cd /news/developer-tools/claude-code-lightbar-for-mac-os Β· home β€Ί topics β€Ί developer-tools β€Ί article
[ARTICLE Β· art-73438] src=github.com β†— pub= topic=developer-tools verified=true sentiment=Β· neutral

Claude Code Lightbar for Mac OS

Claude Code Lightbar for Mac OS, a full-width red bar that displays Claude Code session status across all screens, is now available in version 1.0 exclusively for macOS. The bar shows a solid red when a session is busy, pulses when user input is needed, and disappears when a turn finishes, driven by Claude Code hooks via a local Swift app and LaunchAgent.

read5 min views3 publishedJul 25, 2026
Claude Code Lightbar for Mac OS
Image: source

Version 1.0 Β· macOS only (uses AppKit + launchd

; there is no Windows or Linux build).

A full-width red bar along one edge of every screen that tells you, from across the room, what Claude Code is doing. It sits on the top edge by default (position, thickness, and color are all changeable β€” see Configuration).

Solid red barβ€” at least one session is busy (Claude working).** Pulsing red bar**β€” a session** needs a response from younow (a permission prompt, or Claude blocked waiting for input). No bar**β€” a turn simply finished, or nothing running.

Busy wins: if any session is still working the bar is solid; it pulses only when one has an active prompt for you (a permission request or an explicit question). A turn that just finishes clears the bar. The bar is click-through (it never intercepts your mouse) and floats above everything, including fullscreen apps, on every Space and every monitor.

Note: pulsing is driven by Claude Code's

Notification

hook, which fires for a real prompt (a permission request, etc.). The ~60sidlenotification is deliberately ignored (hook.sh

filters the "waiting for your input" message), so the bar never blinks just because a finished session is sitting there. One consequence: Claude Code has no distinct event for "ended a turn with a question," so a plain conversational question at the end of a turn reads as done (no bar) β€” only actual prompts pulse. StructuredAskUserQuestion

promptsdopulse, via aPreToolUse

/PostToolUse

hook on that tool.

Left: solid red along the bottom edge = Claude is working; it pulses when Claude needs a response from you. Right: the menu-bar menu for live configuration.

macOS(uses AppKit +launchd

).Xcode Command Line Toolsβ€” providesswiftc

to build. Install with:

xcode-select --install

Claude Code CLIβ€” this is driven byClaude Codehooks. It works with any** locally-runningClaude Code (terminal or IDE extension). It does not**work with cloud sessions (claude.ai/code) β€” those run remotely and can't reach your local machine.

No other dependencies: no Homebrew, no jq

, no runtime. Just the system Swift compiler and plutil

(built into macOS).

git clone https://github.com/gregsramblings/claude-status-bar.git
cd claude-status-bar
./install.sh

install.sh

builds the app, installs a run-at-login LaunchAgent (paths derived from wherever you cloned β€” nothing hardcoded), starts it, then prints a hooks block. Copy that block into

~/.claude/settings.json

(merge it into the top-level JSON object; if you already have a "hooks"

key, add the four events to it). The block looks like this, with real paths filled in:

"hooks": {
  "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "bash /path/to/claude-status-bar/hook.sh busy" }] }],
  "Stop":            [{ "hooks": [{ "type": "command", "command": "bash /path/to/claude-status-bar/hook.sh waiting" }] }],
  "Notification":    [{ "hooks": [{ "type": "command", "command": "bash /path/to/claude-status-bar/hook.sh needs_input" }] }],
  "SessionEnd":      [{ "hooks": [{ "type": "command", "command": "bash /path/to/claude-status-bar/hook.sh end" }] }]
}

Then start a new Claude Code session and give it something to do β€” the red bar appears while it works. (Hooks load at session start, so already-open sessions won't drive the bar until restarted.)

echo '{"session_id":"test"}' | ./hook.sh busy    # bar should appear
echo '{"session_id":"test"}' | ./hook.sh end     # bar should disappear
./uninstall.sh

Stops and removes the LaunchAgent and the state directory. It intentionally does not edit settings.json

β€” remove the four ccbar hooks

entries yourself, then delete the repo folder.

  • Claude Code hooks fire on state change and runhook.sh

, which writes one small JSON file per session into~/.claude/ccbar/state/<session_id>.json

:UserPromptSubmit

β†’busy

(you handed off; Claude is working)Stop

β†’waiting

(turn finished)Notification

β†’notify

, whichhook.sh

splits intoneeds_input

(a real prompt β†’ pulse) orwaiting

(the idle timeout β†’ no bar)PreToolUse

(matchingAskUserQuestion

) β†’needs_input

(pulse while a multiple-choice question waits on you);PostToolUse

β†’busy

(solid again once you answer)SessionEnd

β†’ deletes the file

ccbar

(a tiny AppKit app, one borderless click-through window per screen at.screenSaver

level, on all Spaces) polls the state directory every 0.4s:solid if any live session isbusy

, elsepulsing if any isneeds_input

, else hidden (waiting

β€” a finished turn β€” shows nothing).

Multi-session just works: each session is its own file keyed by session_id

, so three concurrent sessions share one bar β€” solid if any is working, pulsing if any needs your input. Stale files (older than 12h, e.g. from a crash that skipped SessionEnd

) are ignored.

ccbar adds a small bar-shaped icon to the macOS menu bar. Click it to configure the bar live β€” no rebuild, no restart:

Menu item Default Meaning
Position
Top Pin the bar to the Top or Bottom edge.
Thickness
6 px
Bar thickness (presets 4 –30 ). Bump for a big room.
Bar Color…
red Opens the macOS color picker; recolors the bar live.
About ccbar
β€” Description, author, link to this repo.
Quit ccbar
β€” Stops the app (unloads the LaunchAgent so it stays down).

Choices persist in UserDefaults

across restarts. The remaining tunables are still compile-time constants at the top of ccbar.swift

(rebuild + restart after changing β€” ./install.sh

again does both):

Constant Default Meaning
pollInterval
0.4
Seconds between state-dir polls.
staleAfter
43200
Ignore state files older than this (seconds).
File Purpose
ccbar.swift
The whole app (AppKit, single file).
hook.sh
Claude Code hook target; writes one state file per session.
install.sh
Build + install LaunchAgent + print the hooks block.
uninstall.sh
Stop + remove the LaunchAgent and state dir.
ccbar
Compiled binary (gitignored β€” built by install.sh ).

Fragility β€” the idle filter is a string match.hook.sh

distinguishes the ~60s idle notification from a real prompt by matching the substringwaiting for your input

in the notificationmessage

. This is Claude Code's current idle wording, not a stable API. If Anthropic changes that text, the idle timeout will start pulsing the bar again. The fix is one line β€” update thecase

pattern inhook.sh

. (Conversely, only known idle text is suppressed, so any new message defaults topulse, never to silently hiding a real prompt.)Stop

is the main-agent stop only (SubagentStop

is a separate, unhooked event), so the bar tracks real turn boundaries, not sub-agent churn.- The bar defaults to the top edge. Switch Position β†’ Bottom(or the reverse) and bump** Thickness**in the menu-bar menu to taste β€” e.g. move it off an edge where a bottom Dock or the notch would hide it.

Public domain β€” The Unlicense. Do whatever you want with it, no attribution required, no warranty, no liability.

── more in #developer-tools 4 stories Β· sorted by recency
── more on @claude code 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/claude-code-lightbar…] indexed:0 read:5min 2026-07-25 Β· β€”