--- name: navidrome description: Query and edit the Navidrome music library/playlists (search artists/albums, inspect or build playlists, audit for accidental full-album dumps). Use for any SUB/WAVE anchor-playlist curation work or general Navidrome library lookups. --- # Navidrome (Subsonic API) A CLI wrapper (`navidrome_api.py`, in this skill's directory) around Navidrome's Subsonic API, distilled from a long session of building SUB/WAVE anchor-playlist shows by hand. Use it instead of writing one-off `curl`/Python snippets — every gotcha below was hit at least once doing it the ad-hoc way. ## Setup Auth/URL come from `/srv/subwave/state/setup-config.json` (world-readable), already pointed at `navidrome:4533` — the script rewrites that host to `localhost` for you. No flags needed for auth. Run it as: `python3 .claude/skills/navidrome/navidrome_api.py ...` ## Commands ``` search [--artists N] [--albums N] [--songs N] # raw multi-type search artist # albums + track counts for one artist album # track ids for one album playlists # list all playlists (id, count, name) playlist get # dump entries playlist create --ids id1,id2,... # new playlist playlist replace --ids id1,id2,... # FULL REPLACE of contents playlist add --ids id1,id2,... # append in place playlist remove --ids id1,id2,... # remove by id, in place playlist audit [--min-size N] # full-album-dump check (see below) ``` ## Gotchas learned the hard way - **Artist name casing is inconsistent and case-sensitive matching silently drops real hits.** `eels` is lowercase, `CAKE` is uppercase, most others are title-case. A naive `artist["name"] == "Eels"` filter returns "not found" even though the artist is right there. `artist`/`album` in this script already do case-insensitive exact matching — don't re-derive this bug with a fresh `curl`. - **An artist with 0 albums from `getArtist` isn't necessarily absent** — it may only have loose tracks scattered across compilations (soundtrack/box-set albums credited to "Various Artists"). Fall back to `search3` with a high `songCount` and filter by exact artist name (the `artist` command does this automatically when it finds zero grouped albums). - **Reissues/deluxe editions duplicate the base album's tracks under a different album name** (`Doolittle` vs `Doolittle 25`, `Bricks Are Heavy` vs a live/remix bonus disc, etc). When curating, pick tracks from ONE edition — check `album` output for suspiciously large counts before assuming it's all distinct songs. - **`createPlaylist` with `playlistId` set REPLACES the entire contents** — it is not additive. Use `playlist replace` only when you intend to overwrite everything (e.g., rebuilding after a curation pass). Use `playlist add` / `playlist remove` for incremental edits to an existing playlist. - **No native "remove by id" in the Subsonic API** — `playlist remove` here works by reading the current entries, filtering out the unwanted ids in Python, then doing a full `replace`. This is safe (order-preserving for everything you keep) but means a remove is really a replace under the hood. - **`playlist audit`'s "FULL ALBUM" flag is a signal, not a verdict.** A genuinely short album (say, 10 tracks) will always show `10/10` with nothing left to trim, and an artist you were explicitly told to go "heavy" on is fine full. Use it to know where to *look*, then use judgment (or ask) before trimming. ## Curation conventions established this session - Default to **~15–20 tracks per artist** for an anchor playlist, not a full discography — unless the user explicitly asks for heavier coverage of a specific artist ("heavy Nirvana", "triple that, focusing on XTC"). - Prefer **`playlistStrict: true`** on SUB/WAVE shows with a pinned anchor playlist. Soft-anchor (`playlistStrict: false`) was tried and rolled back station-wide after live testing showed the playlist rarely won picks over the genre/mood fallback pool, and the fallback's unfiltered "explore" source could drift the show off-genre (see `subwave/bug-report-soft-anchor-drift.md`). - Cross-show duplicate tracks are fine for these anchor-genre shows (the no-duplicate rule only applies to the historical radio-chart recreation shows) — don't spend time deduplicating against other playlists unless asked.