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
1.6 KiB
1.6 KiB
Per-mode Style and Sound Config
Task
Restructure the cursor-flasher config to have independent visual style and sound settings for "running" (approval pulse) and "completed" (agent stop flash), replacing the shared flat config and play_on field.
Changes
src/cursor_flasher/config.py— AddedStyleConfigdataclass (color,width,opacity,duration,pulse_speed,sound,volume).Confignow hasrunning: StyleConfigandcompleted: StyleConfigwith sensible defaults. Removed flatflash_*,sound_*, andplay_onfields. Updatedload_configto parserunning:andcompleted:YAML sections.src/cursor_flasher/overlay.py—flash()andpulse()accept aStyleConfigparameter.OverlayManager.__init__no longer takesConfig.src/cursor_flasher/sound.py—play_alert()acceptsStyleConfiginstead ofConfig. Skips playback whensoundis empty.src/cursor_flasher/daemon.py— Passesconfig.runningto pulse/play_alert,config.completedto flash/play_alert. Removedplay_onconditionals.OverlayManager()instantiated without args.tests/test_config.py— Rewritten for new config structure (13 tests).tests/test_daemon.py— Updated overlay call assertions to include StyleConfig arg. Replacedplay_ontests with per-style sound tests. Addedtest_custom_colors_per_mode. 40/40 pass.README.md— Updated config docs to showrunning:/completed:YAML structure.
Follow-up
- Restart daemon to pick up new config structure
- Update user's
~/.cursor-flasher/config.yamlif it uses the oldflash:/sound:format