v1.5.0
1.5.0 (2026-06-20)
β¨ What's new in v1.5.0
WaveFlow 1.5.0 is the skins & extensibility release. The UI grew four extra skins on top of the Apple-Music baseline, a permission-gated plugin SDK landed with the first plugin (Web Radio) bundled in, and the lyrics waterfall now reaches five providers instead of one. Plenty of plumbing for the upcoming waveflow-server shipped under the hood too, but none of it changes the app's local-first model in 1.5.0.
π¨ Skins β four new visual identities
The theme system grew an orthogonal "skin" axis. 5 skins Γ 14 themes = 70 combinations, each persisted per profile. Studio stays as the default Apple-Music-inspired baseline; four new identities land alongside it:
- Editorial β broadsheet magazine layout, Playfair Display serifs, halftone artwork via
mix-blend-luminosity, ornateWaveFlow Gazettemasthead. - Lounge β warm burgundy glass over a blurred cover backdrop, Apple-Vibrancy
backdrop-filterrecipe. - Pulse β OLED neon-club aesthetic, dual magenta/cyan aurora, vinyl-spin cover that mirrors playback state.
- Liquid β full Apple Vibrancy with the 8-layer inset
box-shadowglass recipe, theme-aware (works in light + dark).
![]() |
![]() |
![]() |
![]() |
Picker lives in Settings β Appearance alongside the existing theme picker. Onboarding got a "Pick a vibe" step so first-run users land on the right combo. Motion is dispatched per-skin via Framer Motion β Pulse uses a bouncy spring, calmer skins inherit the soft default. Typography is bundled (Playfair Display, Lora, Space Grotesk, Space Mono, DM Sans Variable) β zero Google Fonts request at runtime.
π§© Plugin SDK β sandboxed WASI plugins (RFC-002)
The plugin layer landed as a sandboxed runtime with explicit permission gates:
- WIT + wasmtime β plugins ship as WASM components compiled against a
waveflow-plugin-sdkinterface (host imports for HTTP, storage, audio, UI). - Permission gates β every host import is gated by a manifest declaration the user approves on install. No silent network access, no silent filesystem reach.
- Guardrails by default β 50 MB max
plugin.wasmsize, 5 s HTTP timeouts, response-body cap, no redirect following (SSRF guard), per-plugin mutex on install/enable/uninstall to close TOCTOU races, offline-mode short-circuit on every outbound request. - Settings panel β installed plugins list with one-click enable/disable/uninstall, per-plugin permission chips (network / storage / assets), version + size.
π» Web Radio β the first plugin
Ships bundled in the app (so you have something to try the SDK against): a Web Radio plugin that streams internet stations through the same cpal engine the rest of the app uses. Stations route through the audio decoder thread so EQ / ReplayGain / spectrum visualizer all work over live streams. Switching stations fast doesn't deadlock β in-flight requests are cancelled cleanly.
![]() |
π€ Lyrics β multi-provider waterfall + new save modes
The lyrics fetcher used to be LRCLIB-only. 1.5.0 ships a dedicated waveflow-syncedlyrics crate with five providers chained as a graceful fallback:
- Musixmatch (enhanced word-level only) β opt-in, gated on
MUSIXMATCH_ENABLEDenv. - LRCLIB β exact metadata match, primary line-level source.
- NetEase β large Asian catalogue, native LRC.
- Megalobiz β community-scraped enrichment.
- Genius β plain-text last resort.
Each provider error is non-fatal: the chain degrades to a clean miss + cache-empty so the panel never shows a raw HTTP error. Sidecar .lrc/.txt discovery runs before the network, so locally-bundled lyrics never pay a network round-trip.
On the editor side:
- App-wide save destination β write back to the audio tag, to a sidecar file, or to the DB only. Three radio buttons in Settings β Library.
- Export to standalone .lrc / .txt β Tauri save dialog, file written exactly where you point it, audio file left untouched.
- Musixmatch translation language β pick a target language in Settings; each line comes back with its
(translation)companion. - Word-mode auto-advance β capturing the last word of a line bumps the cursor to the next line automatically, no more reaching for the keyboard between lines.
- Opt-in centering for synced lyrics in fullscreen β toggle in Appearance.
πͺ Sidebar hide/show toggle (#167)
A single button in the topbar collapses the sidebar to a thin rail or hides it entirely β useful on 13" / cramped 1080p screens where the right panels (Now Playing / Queue / Lyrics) deserve the room. The hidden sidebar is marked inert so it can't trap Tab focus or steal pointer events.
π§± Under the hood β waveflow-server plumbing (not user-facing yet)
Under the hood, a lot of groundwork landed for the future waveflow-server companion: tenant-scoped Postgres repositories in waveflow-core, auth + sync plumbing, public playlist share canonical IDs, and per-track snapshots in playlist sync ops. None of this is exposed as a user-facing feature in 1.5.0 β the desktop app remains fully local-first today, and the sync stack will surface in a later release once the server companion is ready.
π©Ή Quality pass
- Locales β 579 fixes across 16 locales over four validator passes, followed by a manual review pass across the non-source languages. Brand tokens (
WaveFlow,Daily Mix,On Repeat,Last.fm,Deezer,ReplayGain,LRCLIB,BPM) stay verbatim across every language per the new convention. CJK punctuation normalized (full-widthοΌοΌοΌοΌοΌbetween CJK chars, half-width for Latin content). Russian plural forms, French_zeroslots, German typographic quotes β all aligned. - Audio robustness β Web Radio session survives a
DeviceNotAvailablerebuild (output device unplugged + replugged mid-stream). Decoder reports the current track id on error during a crossfade so the analytics layer credits the right row. - Settings β language dropdown β portaled to escape the
backdrop-filterstacking trap on Lounge / Liquid Glass (was painting behind the cards below it). Focus-restoration on Escape + option pick + Tab matches WAI-ARIA combobox APG. - Plugin SDK security hardening β 16+ rounds of CodeRabbit review across 5 phases. Highlights: TOCTOU mutex on install/uninstall, full-column upsert on
app_settingto satisfy NOT NULL constraints,take()bounded read onplugin.wasm, redirect following disabled to close SSRF, response body cap, race-free state writes, offline-mode short-circuit on every host import. - Lyrics raw-error leak β fetch errors no longer paint themselves as lyrics content in the panel; collapsed into a localized "Couldn't reach lyrics providers" empty state with retry hint.
π¦ Recommended install
Use the package manager that fits your platform when one is available, so updates keep flowing through the same tool you already use.
Windows
winget install InstaZDLL.WaveFlowArch / Manjaro / EndeavourOS / CachyOS
yay -S waveflow-bin
# or: paru -S waveflow-binFedora / RHEL / Rocky / Alma / CentOS Stream
sudo dnf copr enable instazdll/waveflow
sudo dnf install waveflowDebian / Ubuntu / Mint / Pop!_OS
The Debian package is wave-flow (kebab-case, required by the Debian naming spec β Tauri bundles it that way from the WaveFlow product name).
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://packages.buildkite.com/instazdll/waveflow/gpgkey \
| sudo gpg --dearmor -o /etc/apt/keyrings/waveflow.gpg
echo "deb [signed-by=/etc/apt/keyrings/waveflow.gpg] https://packages.buildkite.com/instazdll/waveflow/any/ any main" \
| sudo tee /etc/apt/sources.list.d/waveflow.list
sudo apt update && sudo apt install wave-flowmacOS
No Homebrew cask yet β grab the .dmg from the assets below. The bundle is not Apple-Developer-signed; right-click β Open the first time, or run xattr -cr /Applications/WaveFlow.app to clear the quarantine flag.
Standalone download
Everything is also available as a raw bundle in the assets below β .AppImage, .deb, .rpm, .exe, .msi, .dmg for users who'd rather skip the repo.




