2026-03-10 14:30:31 -04:00
> [!NOTE]
> This project was developed entirely with AI coding assistance (Claude Opus 4.6 via Cursor IDE) and has not undergone manual review. It is provided as-is and may require adjustments for other environments.
2026-03-10 02:57:31 -04:00
# cursor-flasher
2026-03-10 08:03:22 -04:00
A macOS daemon that flashes a pulsing border and plays a sound when your [Cursor ](https://cursor.com ) AI agent needs attention.
2026-03-10 07:01:52 -04:00
## How It Works
Uses [Cursor hooks ](https://cursor.com/docs/agent/hooks ) for reliable detection:
2026-03-10 14:30:31 -04:00
- `**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.
2026-03-10 07:01:52 -04:00
Only tools in the `approval_tools` list trigger the pulse (default: `Shell` , `Write` , `Delete` ). Auto-approved tools like `Read` and `Grep` are ignored.
2026-03-10 02:57:31 -04:00
## Prerequisites
- macOS
2026-03-10 07:01:52 -04:00
- [uv ](https://docs.astral.sh/uv/ )
- Cursor IDE
2026-03-10 08:03:22 -04:00
- **Accessibility** permission for your terminal (System Settings → Privacy & Security → Accessibility) — needed for window enumeration
- **Input Monitoring** permission for the daemon process (System Settings → Privacy & Security → Input Monitoring) — needed for input-based pulse dismissal
2026-03-10 02:57:31 -04:00
## Installation
```bash
2026-03-10 07:01:52 -04:00
# Clone and install
2026-03-10 08:03:22 -04:00
git clone https://code.cottongin.xyz/cursor-flasher && cd cursor-flasher
2026-03-10 03:12:10 -04:00
uv sync
2026-03-10 02:57:31 -04:00
2026-03-10 07:01:52 -04:00
# Install Cursor hooks (global, applies to all projects)
uv run cursor-flasher install
2026-03-10 03:12:10 -04:00
2026-03-10 07:01:52 -04:00
# Start the daemon
2026-03-10 03:12:10 -04:00
uv run cursor-flasher start
2026-03-10 07:01:52 -04:00
```
2026-03-10 02:57:31 -04:00
2026-03-10 07:01:52 -04:00
The `install` command copies the hook script to `~/.cursor/hooks/` and adds entries to `~/.cursor/hooks.json` . Cursor auto-reloads hooks.
2026-03-10 02:57:31 -04:00
2026-03-10 07:01:52 -04:00
## Usage
2026-03-10 02:57:31 -04:00
2026-03-10 07:01:52 -04:00
```bash
uv run cursor-flasher start # background daemon
uv run cursor-flasher start --foreground # foreground (for debugging)
uv run cursor-flasher status
2026-03-10 03:12:10 -04:00
uv run cursor-flasher stop
2026-03-10 02:57:31 -04:00
```
## Configuration
2026-03-10 07:01:52 -04:00
Optional config file at `~/.cursor-flasher/config.yaml` :
2026-03-10 02:57:31 -04:00
```yaml
2026-03-10 09:06:09 -04:00
theme: "auto" # "dark", "light", or "auto" (follows macOS appearance)
dark: # styles used when OS is in dark mode
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
light: # styles used when OS is in light mode
running:
color: "#3B82F6 "
width: 4
opacity: 0.9
pulse_speed: 1.5
sound: "Glass"
volume: 0.5
completed:
color: "#22C55E "
width: 4
opacity: 0.9
duration: 1.5
sound: ""
volume: 0.0
2026-03-10 07:01:52 -04:00
flash:
2026-03-10 09:06:09 -04:00
mode: "screen" # "window", "screen", or "allscreens"
2026-03-10 07:01:52 -04:00
# Tools that trigger the pulse + sound (approval mode).
# Others are silently ignored (e.g., Read, Grep, Glob, Task).
approval_tools:
- Shell
- Write
- Delete
general:
2026-03-10 09:06:09 -04:00
approval_delay: 2.5 # seconds to wait before pulsing (filters auto-approvals)
2026-03-10 07:01:52 -04:00
cooldown: 2.0 # minimum seconds between flashes
2026-03-10 02:57:31 -04:00
```
2026-03-10 09:06:09 -04:00
Styles are organized under `dark` and `light` theme sections, each containing `running` (approval pulse) and `completed` (stop flash) modes with their own color, border, and sound settings. The `theme` option controls which styles are active: set `"auto"` to follow macOS appearance in real-time, or force `"dark"` / `"light"` . Set `sound: ""` to disable sound for a particular mode.
2026-03-10 03:12:10 -04:00
2026-03-10 07:01:52 -04:00
## Uninstall
2026-03-10 03:12:10 -04:00
```bash
2026-03-10 07:01:52 -04:00
uv run cursor-flasher uninstall
uv run cursor-flasher stop
2026-03-10 03:12:10 -04:00
```
2026-03-10 07:01:52 -04:00
## Troubleshooting
2026-03-10 02:57:31 -04:00
2026-03-10 07:01:52 -04:00
**Flashing on every tool call (too noisy):**
2026-03-10 14:30:31 -04:00
2026-03-10 07:01:52 -04:00
- Edit `~/.cursor-flasher/config.yaml` and narrow down `approval_tools` to just `Shell` .
2026-03-10 02:57:31 -04:00
2026-03-10 07:01:52 -04:00
**No flash at all:**
2026-03-10 14:30:31 -04:00
2026-03-10 07:01:52 -04:00
- 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
2026-03-10 02:57:31 -04:00
2026-03-10 07:01:52 -04:00
**Pulse doesn't stop:**
2026-03-10 14:30:31 -04:00
2026-03-10 07:01:52 -04:00
- Click the Cursor window to bring it to focus — the pulse auto-dismisses when Cursor is the frontmost app.
2026-03-10 14:30:31 -04:00