- Emote face is now stable all day; /wake picks a fresh random face each
morning instead of rotating every 5 minutes. Removes EMOTE_ROTATION_INTERVAL
and last_emote_change entirely.
- Added 10 new synthesized sounds for /notify: doorbell, knock, ding, blip,
siren, tada, ping, bubble, fanfare, and alarm (loops until tapped or TTL
expires). stopAlarm() wired into tap handler and handleStateChange().
- openapi.yaml: new sound names added to enum.
- CLAUDE.md / README.md updated to reflect both changes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extract shared send_event/clear_event into detectors/base.py, removing
~150 lines of duplication across all 6 detectors
- Fix default aggregator URL from port 5000 to 5100 in all detectors
- Standardize cpu.py and memory.py to use active_alerts set pattern
- Fix immediate emote rotation on startup (last_emote_change = time.time())
- Extract magic numbers to named constants in aggregator
- Protect write_status() with try/except OSError
- Fix notify event ID collision with monotonic counter
- Replace blocking stream_output() with background daemon threads in kao.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add /clear-all endpoint and wire it to the tap handler so tapping the
display dismisses active warnings/critical alerts. Fix docker detector
to track restart count deltas instead of relying on the transient
"restarting" state. Wrap cleanup thread in try/except so it can't die
silently and leave events stuck forever.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>