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
This commit is contained in:
cottongin
2026-03-10 07:01:52 -04:00
parent c0477d2f40
commit 5b71b2275b
24 changed files with 1504 additions and 1034 deletions

View File

@@ -0,0 +1,19 @@
# Tweaks: approval filtering + two flash modes
## Task
Added tool filtering and differentiated flash behavior for approval vs. completion events.
## Changes
- **`config.py`**: Added `approval_tools` list (default: Shell, Write, Delete), `sound_name`/`sound_volume`, `pulse_speed`
- **`overlay.py`**: Two modes — `pulse()` with sine-wave animation + auto-dismiss when Cursor is focused, `flash()` for brief single flash
- **`daemon.py`**: Routes `preToolUse` to pulse+sound (filtered by approval_tools), `stop` to brief flash; stop dismisses active pulse
- **`sound.py`**: Re-added for approval pulse events
- **Tests**: 19 tests covering tool filtering, both flash modes, cooldown, fallback behavior
- **`README.md`**: Documented both behaviors and config options
## Behavior
| Event | Tool in approval_tools? | Action |
|-------|------------------------|--------|
| preToolUse | Yes (Shell, Write, Delete) | Pulse border + play sound until user clicks window |
| preToolUse | No (Read, Grep, etc.) | Ignored |
| stop | N/A | Brief single flash |