Surface device connection state changes (configured target online/offline)
and discovery events (new WLED on LAN, new serial port, devices that
disappear) through a configurable per-event channel matrix:
none / snack / OS / both.
- Backend: long-running mDNS browser + 10 s serial poller in
core/devices/discovery_watcher.py, gated by user pref. Reuses the
existing device_health_changed event for online/offline transitions.
New GET/PUT /api/v1/preferences/notifications endpoint with Pydantic v2
schema (channel matrix + background-discovery flag + grace/debounce).
13 new tests, full suite still 899 passing.
- Frontend: features/notifications-watcher.ts with startup-grace +
flap-debounce + bulk-coalesce pipeline. Web Notifications API for the
OS channel (no platform-specific code, works in PWA shell).
New "Notifications" tab in Settings with 4 IconSelect rows + bg toggle
+ permission row + test button. en/ru/zh translations.
Defaults: device_offline=both (urgent), online/discovered=snack, lost=none,
background discovery on. Already-configured devices are filtered from
discovery events to avoid double-notifications.