v1.1.0
Features
- Liked Songs page (
g y) — browse and play your liked music - Recently Played page (
g r) — local history from SQLite - Download for offline — right-click any track → "Download for Offline"
- Discord Rich Presence — show what you're listening to (optional,
pip install -e ".[discord]") - Last.fm scrobbling — automatic scrobbling + Now Playing (optional,
pip install -e ".[lastfm]") - Gapless playback enabled by default
- Queue persistence across restarts (saved in session.json)
- Track change notifications wired to
[notifications]config section - New config sections:
[discord],[lastfm],[playback].gapless,[playback].api_timeout - Configurable column widths via
[ui]settings (col_index,col_title,col_artist,col_album,col_duration) - Liked Songs and Recently Played pinned in library sidebar
Security & Stability
- IPC socket security hardening (permissions, command whitelist, input validation)
- File permissions hardened to 0o600 across all config/state files
- Thread safety for queue manager (prevents race conditions)
- mpv crash detection and automatic recovery
- Auth validation distinguishes network errors from invalid credentials
- Disk-full (OSError) handling in cache and history managers
- API timeout handling (15s default, prevents TUI hangs on slow networks)
Performance
- Batch DELETE for cache eviction (replaces per-row deletes)
- Deferred cache-hit commits (every 10 hits instead of every hit)
- Reuse yt-dlp instance across stream resolves (was creating new per call)
- Concurrent Spotify import matching with ThreadPoolExecutor
- Stream URL expiry checks before playback
Testing & CI
- GitHub Actions CI pipeline (ruff lint + pytest with coverage)
- 231 tests covering queue, IPC, stream resolver, cache, history, auth, downloads, Discord RPC, Last.fm, and settings