- crontab_manager.get_alarms now parses --style from the cron command
(defaults to 'blink' for legacy entries without --style)
- GraphQL Alarm type gains a 'style' field
- setAlarm accepts a 'style' arg (default 'simple') and validates it
against the styles registry; unknown styles raise a GraphQL error
- _default_command embeds --style <name> into the cron command
- startRinging accepts 'style' (default 'simple') and passes --style to
the spawned wecker.py
The crontab remains the single source of truth; the style simply rides
in the cron command alongside --music-file.
Introduce a styles/ plugin package:
- styles/base.py: AlarmStyle ABC (injected set_led, update()->bool contract)
- styles/blink.py: BlinkStyle, the existing count-the-blinks puzzle moved
out of wecker.py's AlarmClock
- styles/simple.py: SimpleStyle, press-once-to-stop (the new default style)
- styles/__init__.py: STYLES registry + get_style() validator + LEGACY_STYLE
wecker.py now resolves the style via the registry and owns only the shared
music/button/cleanup loop; the --style CLI arg defaults to blink so existing
cron entries keep their behaviour. Unknown styles raise before hardware init.