cottongin 5b71b2275b Restructure config for per-mode style/sound and fix pulse dismiss
Major changes:
- Add StyleConfig dataclass with independent color, width, opacity,
  duration, pulse_speed, sound, and volume per mode (running/completed)
- Replace flat flash_*/sound_*/play_on config with running: and
  completed: YAML sections
- Replace CGEventTap (silently fails in forked daemon) with
  CGEventSourceSecondsSinceLastEventType polling for reliable
  input-based pulse dismissal when Cursor is already frontmost
- Update overlay, sound, and daemon to pass StyleConfig per call
- Rewrite tests for new config shape and dismiss mechanism

Made-with: Cursor
2026-03-10 07:01:52 -04:00

cursor-flasher

Flash a colored border on the Cursor IDE window when the AI agent needs your attention — tool approval, questions, or task completion.

How It Works

Uses Cursor hooks for reliable detection:

  • preToolUse — fires when the agent wants to run a shell command, write a file, or use any tool that may need approval. Pulses the border continuously and plays a sound until you click the Cursor window.
  • stop — fires when the agent loop ends. Flashes the border once, briefly.

Only tools in the approval_tools list trigger the pulse (default: Shell, Write, Delete). Auto-approved tools like Read and Grep are ignored.

Prerequisites

  • macOS
  • uv
  • Cursor IDE
  • Accessibility permission for your terminal (System Settings → Privacy & Security → Accessibility)

Installation

# Clone and install
git clone <repo-url> && cd cursor-flasher
uv sync

# Install Cursor hooks (global, applies to all projects)
uv run cursor-flasher install

# Start the daemon
uv run cursor-flasher start

The install command copies the hook script to ~/.cursor/hooks/ and adds entries to ~/.cursor/hooks.json. Cursor auto-reloads hooks.

Usage

uv run cursor-flasher start              # background daemon
uv run cursor-flasher start --foreground  # foreground (for debugging)
uv run cursor-flasher status
uv run cursor-flasher stop

Configuration

Optional config file at ~/.cursor-flasher/config.yaml:

running:                    # approval pulse (continuous until you interact)
  color: "#FF9500"          # border color (hex)
  width: 4                  # border thickness in pixels
  opacity: 0.85             # max border opacity
  pulse_speed: 1.5          # pulse cycle speed in seconds
  sound: "Glass"            # macOS system sound ("" to disable)
  volume: 0.5               # 0.0 to 1.0
  # sounds: Basso, Blow, Bottle, Frog, Funk, Glass, Hero,
  #         Morse, Ping, Pop, Purr, Sosumi, Submarine, Tink

completed:                  # agent stop flash (brief fade-in/out)
  color: "#00FF00"          # different color for completion
  width: 4
  opacity: 0.85
  duration: 1.5             # flash duration in seconds
  sound: ""                 # no sound by default (Cursor plays its own)
  volume: 0.0

flash:
  mode: "screen"            # "window", "screen", or "allscreens"

# Tools that trigger the pulse + sound (approval mode).
# Others are silently ignored (e.g., Read, Grep, Glob, Task).
approval_tools:
  - Shell
  - Write
  - Delete

general:
  approval_delay: 2.5       # seconds to wait before pulsing (filters auto-approvals)
  cooldown: 2.0              # minimum seconds between flashes

Each mode (running and completed) has its own color, border style, and sound settings. Set sound: "" to disable sound for a particular mode.

Uninstall

uv run cursor-flasher uninstall
uv run cursor-flasher stop

Troubleshooting

Flashing on every tool call (too noisy):

  • Edit ~/.cursor-flasher/config.yaml and narrow down approval_tools to just Shell.

No flash at all:

  • Check daemon: uv run cursor-flasher status
  • Check hooks installed: ls ~/.cursor/hooks/cursor-flasher-notify.py
  • Check Cursor Settings → Hooks tab for execution logs

Pulse doesn't stop:

  • Click the Cursor window to bring it to focus — the pulse auto-dismisses when Cursor is the frontmost app.
Description
A macOS daemon that flashes a pulsing border and plays a sound when your Cursor AI agent needs attention.
Readme MIT 188 KiB
Languages
Python 100%