Kefir for Omarchy
Control KEF wireless speakers (LSX II, LS50 Wireless II, LS60) from the Omarchy bar. Talks directly to the speaker's KEF Connect HTTP API on the local network — no daemon, no CLI dependency. Same protocol as SwiftKEF / Kefir / KefirCLI.
Features
- Bar pill showing speaker state (off/standby, on, muted), with tooltip
- Popup panel: power switch, volume slider with mute, input source picker, and a now-playing card with album art, track/artist/album, a progress bar, and play/pause/next/previous
- Transport buttons follow the speaker's own
controlscapability report, so they enable only on sources that support them (streaming, not passthrough); passthrough pseudo-tracks ("COAX", "OPT", ...) are filtered out of the card - Scroll the bar icon to change volume (with OSD), right-click to mute, middle-click to play/pause
- Panel keys:
h/lvolume,mmute,Enter/Spaceplay/pause,Escclose
Install
omarchy plugin add https://github.com/melonamin/omarchy-kefir.git --enable
omarchy bar set melonamin.kefir host <speaker-ip>
Or skip the second step: with no host configured, opening the panel scans the local network (mDNS via avahi) and lists the KEF speakers it finds — click one to adopt it. Setting the IP manually remains available for networks without mDNS.
To remove:
omarchy plugin remove melonamin.kefir
Removal deletes the plugin checkout and its bar entry; the plugin stores no other state.
Dependencies
Only curl and avahi-browse (for discovery), both shipped with Omarchy by
default. The plugin talks HTTP to the speaker on your LAN and never contacts
anything else. (node is used for the test suite only.)
IPC
For Hyprland keybindings:
omarchy-shell melonamin.kefir toggle # open/close the panel
omarchy-shell melonamin.kefir volumeUp # +5
omarchy-shell melonamin.kefir volumeDown # -5
omarchy-shell melonamin.kefir mute
omarchy-shell melonamin.kefir playPause
Notes
- Mute is volume-0 with the previous level remembered, matching Kefir.
- Writes are POSTs with a JSON body; firmware p20.x rejects the older query-param setData with 405.
- Selecting a source while in standby powers the speaker on (KEF behavior).
Tests
node --test tests/model.test.js # unit: wire-format parsing/building
tests/integration.sh <speaker-ip> # live read-only poll against a speaker