Upgrading from Deezy? Start Wavekeep once before uninstalling Deezy, and do not tick "Delete the application data" in the Deezy uninstaller before that first start. Wavekeep moves your settings, history, themes and saved logins on first launch. MSI installs upgrade Deezy in place; the
.exeinstaller installs Wavekeep next to it.
The installers are not code-signed, so Windows SmartScreen may warn on first run.
Added
- Spotify source — Wavekeep can now search Spotify and download from pasted Spotify track, album, artist, or playlist links. The encrypted audio stream is decrypted with the track's own key and written with metadata and cover art. At each bitrate OGG Vorbis is preferred over MP3; FLAC is only requested for Lossless, and if a track offers none of the usual formats, Wavekeep falls back in a fixed order (MP3 256, AAC 320 and 160, MP4 128, AAC 48 and 24, FLAC, then xHE-AAC) and refuses formats it cannot decrypt; a stream that does not decrypt to audio of the expected type fails instead of being saved. Connect once through a browser login; the credential is normally stored in the OS keyring, separate from the ARL. Access tokens refresh safely when several requests need one at once, and a stored token that Spotify rejects is refreshed once before asking for a new login.
- Spotify quality — Normal (96 kbps), High (160 kbps), Very high (320 kbps), or Lossless (FLAC, Premium). Wavekeep does not check the account type, so what a Free account can download depends on what Spotify serves.
- Spotify catalog — Direct track, album, artist and playlist lookups, download metadata, and Loved Tracks come from the librespot AP session rather than the rate-limited Web API; search, playlist search and your playlist list still use the Web API. Track lists load with bounded concurrency, unavailable individual tracks are skipped, a complete metadata failure is reported instead of appearing as an empty list, and artist discographies fall back to the Web API when the AP rejects the request.
- Custom Spotify Client ID — Settings accepts an optional Client ID from your own Spotify developer app, with the loopback redirect URI shown alongside it. The ID is used only for Web API requests (search and your playlist list) so they draw on your own quota; the AP session behind downloads always uses the default ID, because Spotify rejects AP metadata requests from other IDs, so connecting with a custom ID opens the browser login twice. Changing the ID disconnects the existing token so the next login uses the new app. The saved setting takes precedence over
WAVEKEEP_SPOTIFY_CLIENT_ID(or the olderDEEZY_SPOTIFY_CLIENT_ID). - Spotify rate-limit handling — Web API 429 responses are retried at most twice and only for
Retry-Afterwaits of five seconds or less, avoiding long UI stalls. Track, album, and artist searches then try Spotify Pathfinder, and failures include the underlying error. As of 2026-10-23 Spotify answers Pathfinder with403 Client/request not allowed, so a custom Client ID is the reliable fix for a rate-limited default ID. - Tag editor for OGG and M4A — The Tag Editor reads and writes OGG and M4A files, so Spotify downloads can be edited, and the Downloads view offers it for them.
- Startup warning and Info & FAQ — A warning about terms of service, account risk, credential safety and unofficial support appears when the app opens, with a "Don't show this again" option that is remembered per notice version. A new Info & FAQ button in the sidebar opens the same information plus a short FAQ (upgrading from Deezy, legality, bans, getting an ARL, quality limits, Spotify rate limits and double login, failed downloads, tags, privacy) in all six languages.
- Local diagnostic log — Wavekeep logs what it does to
wavekeep-debug.login its logs folder (%LOCALAPPDATA%\com.pierr.wavekeep\logson Windows,~/Library/Logs/com.pierr.wavekeepon macOS, and~/.local/share/com.pierr.wavekeep/logson Linux), which the system does not clean up on its own, with UTC times, levels and areas: startup, the move from Deezy, login results (account type only), quality fallbacks, the start and result of every download plus each Spotify download step, Spotify connect and rate limits, settings-storage warnings, panics, and frontend errors. It stays on the computer and Wavekeep never uploads it. Passwords, the ARL and login tokens are never written to it; on top of that, every line is cleaned before it is saved: the home folder appears as~, web addresses lose their query part (where tokens travel), and any long token-like string is replaced with[redacted]. Info & FAQ has Copy recent log, Open log folder and Delete log buttons (deleting asks for a second click) and a new "How do I report a problem?" entry. A new Track Details in Log setting (on by default) writes[hidden]instead of track names, artists and file paths when turned off. The file rotates towavekeep-debug.old.logat 1 MB. - Clearer privacy information — The in-app answer "What does Wavekeep collect or send?" and the FAQ now say exactly what is sent (only to Deezer and Spotify, nothing to the developer), what is stored on the computer, and how to remove each part. The System Tray setting is now translated too.
Changed
- Renamed to Wavekeep — Deezy is now called Wavekeep, now that it downloads from Spotify as well as Deezer. The app identifier changed from
com.pierr.deezytocom.pierr.wavekeep: on first start Wavekeep moves settings, download history, custom themes, and saved Deezer and Spotify logins over (old copies are removed only after the new ones check out), and MSI installs upgrade the existing Deezy install. New installs default to aMusic/Wavekeepdownload folder; existing download folders are kept.WAVEKEEP_NO_KEYRINGandWAVEKEEP_SPOTIFY_CLIENT_IDreplace theDEEZY_variables, which still work. Unfinished downloads now use.wavekeep.part. The.exeinstaller installs Wavekeep next to Deezy instead of replacing it: start Wavekeep once before uninstalling Deezy, so the data has been moved first. After the move, the old Deezy app starts without settings or logins. - New logo and icons — A white sound wave shaped like a "W" on a rounded purple square (in the app's accent colour) replaces the "D" logo in the app, the installers, and all platform icons. The tray shows the same icon on Windows and Linux, and the wave alone as a template image on macOS, which follows the menu-bar colours.
- Deezer-free settings — Saving settings no longer requires an ARL, so the Spotify source can be used without a Deezer account.
Fixed
- Tag Editor failures — Saving tags now first copies the file next to itself (a hidden
.<name>.<hex>.wavekeep.bakfile) and puts the original bytes back if the write fails half way or a tag library hits an internal error, so a failed save such as a full disk normally leaves the song as it was. The copy is deleted afterwards. If Wavekeep itself is killed during a save, the file may be damaged and the copy stays next to it; if putting the original back fails, the error gives the copy's path. The file is still edited in place, so hard links, permissions and alternate data streams are kept. - Artist links — Pasting an artist URL now asks for confirmation, showing the number of albums, before every track is added to the download queue. An artist without albums shows the usual message instead.
- Spotify Liked Songs on large libraries — Liked Songs used only the pages in the first reply from Spotify, so a large library could be cut short. The remaining pages are now followed (only
hm://links, at most 200 extra pages and 10,000 tracks), and a page that cannot be read gives an error instead of a shorter list. - Untranslated texts — The tray menu, the Deezer Free quality hint, and errors for pasted links now follow the selected language instead of always being English.
- Minimize shortcut on macOS — Wavekeep no longer registers its own Cmd+H there, which clashed with the system "Hide" shortcut; the system shortcut hides the app instead.
- Download action buttons — The retry and edit-tags buttons rendered as empty circles because the generic button padding squeezed the icon out.
- Settings toggles — The switches in Settings sit next to their labels again instead of the text hanging at the switch's baseline with no gap.
- Download progress bar — The bar now spans the whole row instead of stopping where the status text begins, which made it end at a different place on every row.
- Hung downloads and an app that would not close — An internal error during a download (for example a Deezer release date with accented characters, which crashed tagging) left the download hanging forever, kept its unfinished file, blocked that track from being retried, and stopped Wavekeep from closing. Downloads now end with an error and clean up (after a hard crash an unfinished
.wavekeep.partfile can remain, because there is no cleanup at startup), closing refuses new downloads and waits at most 30 seconds for the running ones, Wavekeep closes by itself if the window stops responding, and quitting from the macOS menu or Dock cleans up too. - Spotify login that never ends — A browser login left open now times out after 5 minutes and frees its port, so Connect works again without restarting. A second Connect while one is waiting is refused, and connecting, restoring and disconnecting can no longer overlap (a disconnect during startup could be undone). Two small gaps remain: the login library discards the OAuth
state, so another program on the same computer could answer the login with its own account, and a program holding an idle connection to port 5588 can keep it busy until it disconnects. - Long track names — File and folder names are shortened to 180 bytes, always keeping the extension, so tracks with very long titles or artist lists can be downloaded. Names that already fit are unchanged.
- Settings that could not be saved — An out-of-range value in
settings.json(for example after editing it by hand) blocked every later save; such values are now repaired on load and the repaired fields are logged. - Show in folder — Folders with a comma in their name (such as
AC,DC) open correctly. - Tag editor — The "saved" message now appears, errors from the file and cover pickers are shown, and closing the editor while a file is loading no longer shows that file's tags the next time it opens.
- Spotify Client ID — An invalid Client ID is now reported in Settings instead of failing silently.
- Smaller fixes — Deezer sends a progress update per whole percent instead of every 2 KB, a cancelled download no longer slows the next one under a speed limit, a failed legacy-URL quality no longer stops the remaining qualities from being tried, and the tray tooltip can no longer overflow its Windows buffer.
Security
These come from a full audit of the app (AUDIT.md).
- Network paths — On Windows, file paths sent by the interface are checked before any disk access, and network (
\\server\share) paths are refused unless that share was chosen in a file dialog or holds the download folder. This stops a compromised page from making Windows send login hashes to another computer. Every refusal of the same kind (audio file, cover image, folder) now gives the same message, so it no longer reveals whether a file exists. - Narrower interface permissions — The window may now only listen to events, hide itself and send notifications. Unused dialog, restart, tray and window permissions were removed, along with the unused
@tauri-apps/plugin-dialogand@tauri-apps/plugin-processpackages and the Rust process plugin. - Stricter content policy — The CSP now also forbids plugins, frames, workers,
<base>changes and form submissions; built-in prototypes are frozen; and the window can no longer navigate away from the app. - Validated input — Deezer and Spotify IDs must be numeric or 22-character base62 before they reach an API address; theme colours must be plain colour values (a shared theme could cover the whole window); theme names refuse every Windows device name; the ARL may contain only letters and digits; and a Spotify Client ID must be 32 hex characters.
- ARL only through login —
save_settingsno longer accepts an ARL from the interface; only a verified login can change it. The ARL field turns off autofill and spell-check, and is emptied after a failed login. - Spotify network hardening — Spotify requests are HTTPS-only with connect, read and total timeouts, responses and cover art are size-capped while they download, token refreshes time out, and the access token is never sent to a pagination link outside
api.spotify.com. - Log integrity — A single log call always writes one line (line breaks show as
⏎), so text in a track title or error cannot fake extra log lines; web addresses lose their query in any letter case, includingws://andwss://; and a closed console no longer crashes logging. Pathfinder rejections and failures no longer put the server's response text in the log or in the error, because it could repeat what you searched for. - Other hardening — A non-hex legacy CDN letter or a missing track ID now fails instead of building a wrong address or key, error messages no longer include download addresses, a stored Spotify expiry time can no longer crash startup, keyring access no longer blocks the app's worker threads, two downloads finishing under the same name on drives without hard links (macOS/Linux) can no longer overwrite each other (this code has not been compiled on those systems yet), CSV exports neutralise more spreadsheet formulas, and size limits are enforced while history and theme files are read.
- Dependencies — Vite 6.4.5, devalue 5.9.4 and source-map-js 1.2.2 fix known advisories in build tools, and the Rust crates h2, crossbeam-epoch, tokio, anyhow and event-listener were updated to fixed versions.
Cargo.lockis now committed so every build uses the same versions. Known advisories that need a Tauri 2.12 or librespot upgrade (quick-xml, andrsa, which has no fix yet) are listed inAUDIT.md, which also notes thatcargo auditstill reportsrustls,rustls-webpkiand a few unmaintained crates that are not part of the Windows build.