Skip to content

About

A macOS menu-bar traffic light for your Cursor & Claude Code agents. Green = your turn, orange = working, red = needs you.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

AgentLights

A tiny macOS menu-bar app (with an optional floating traffic light) that shows what your AI coding agent is doing at a glance — like the physical traffic light some people stick on their monitor, but in software.

Works with both Cursor and Claude Code, and aggregates across all of them: if any session is working the light is orange.

🌐 Website & live demo: https://agentlights.com

Download

⬇︎ Download the latest release (.dmg)

Universal (Apple Silicon + Intel), signed with a Developer ID, notarized, and stapled — it opens with no Gatekeeper warning. macOS 13 or later. You can also grab it from agentlights.com.

Color State Meaning
🟢 Green idle Done — the agent finished and is waiting for your input
🟠 Orange working A turn is running (thinking or using tools)
🔴 Red waiting / error The agent needs you (a question/permission) or the last turn errored
⚪️ Gray unknown No recent activity recorded yet

It aggregates across all open Cursor/Claude windows and conversations: if any conversation is actively working, the light is orange; otherwise it reflects the most recent finished turn.

How it works

Both Cursor (hooks) and Claude Code (hooks) can run scripts on agent lifecycle events. A single, observe-only hook script records the current state per conversation/session into ~/.cursor/cursor-traffic-light/state/<id>.json:

Tool working idle (done) waiting / error
Cursor beforeSubmitPrompt, tool events stop (completed), sessionEnd shell/MCP awaiting approval → red; stop (error)
Claude Code UserPromptSubmit, PreToolUse, PostToolUse Stop, SessionEnd Notification (needs you) → red; StopFailure

The menu-bar app watches that directory and updates the indicator. The hook never blocks, denies, or rewrites anything the agent does — it only records state (and emits no stdout for Claude, so nothing is injected into its context). A working entry older than 15 minutes is treated as stale (e.g. the window was closed) and ignored.

Cursor / Claude event ──hook──▶ ~/.cursor/cursor-traffic-light/state/*.json ──watch──▶ menu bar + overlay

Build & run

Scripts/build_app.sh
open dist/AgentLights.app

build_app.sh produces a universal binary (arm64 + x86_64). On launch the app installs the hooks automatically (idempotent), merging into any existing ~/.cursor/hooks.json and — when Claude Code is detected (~/.claude exists) — ~/.claude/settings.json, rather than overwriting them. Cursor reloads hooks.json on save, so it starts reporting within seconds. Claude Code picks up the new hooks on the next session.

For development you can also just run the executable directly:

swift run

To build a signed, notarized .dmg for distribution:

SIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
NOTARY_PROFILE="your-notary-profile" Scripts/make_dmg.sh

Using it

Click the menu-bar dot for:

  • Show Floating Light (⌘L) — draggable, always-on-top traffic light(s). Each light's position and visibility are remembered.
  • Floating Light Layout — choose how the overlay is shown:
    • Combined — a single light showing the overall state.
    • One per Cursor Window — a separate, labeled traffic light for each active window/workspace, so you can watch every worker at once.
    • Row of dots — a compact strip with one colored dot per agent.
  • One Light per Tab — split a window into one light per conversation (tab).
  • Orientation — arrange lights vertically or horizontally.
  • Light Size — resize the floating light(s), or pick a preset (Small … Huge).
  • Settings… (⌘,) — pick the layout, drag the Size slider, toggle labels, drag to reorder your lights, and see detected windows/tabs.
  • Launch at Login — register/unregister via SMAppService.
  • Check for Updates… — compares your version against the latest release.
  • Install / Reinstall Hooks — re-run the hook installer if needed.
  • Quit.

In per-window mode, windows are grouped by workspace (the folder open in the Cursor/Claude window). A window appears once it has recent activity and drops off after two hours of inactivity.

Files

Path Purpose
Sources/AgentLights/AgentState.swift State enum + colors + labels.
StatusStore.swift Watches the state dir, computes overall + per-window/tab state.
Settings.swift Persisted settings (AppSettings) + Settings window.
MenuBarController.swift Menu-bar dot + menu (layout, settings).
TrafficLightOverlay.swift Floating light(s): combined, per window, or row.
HookInstaller.swift Installs/merges the Cursor + Claude hooks.
Updater.swift "Check for Updates" against the published manifest.
AppDelegate.swift / main.swift Agent (LSUIElement) entry point.
hooks/cursor-traffic-light.sh The shared observe-only hook script (Cursor + Claude).

Notes

  • The hook depends on jq (preinstalled on most dev Macs; brew install jq otherwise). Without it the script still records a coarse state.
  • To remove: delete ~/.cursor/hooks/cursor-traffic-light.sh, remove the matching entries from ~/.cursor/hooks.json and ~/.claude/settings.json, and drop the app.

Author

Created by Daniel Leonti.

License

MIT © 2026 Daniel Leonti.

About

A macOS menu-bar traffic light for your Cursor & Claude Code agents. Green = your turn, orange = working, red = needs you.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages