Status & Changelog

iOS App Store

17.0.0 (80)

LIVE since 2026-04-27

Download on the App Store

Server

v1.0.47

Self-hosted Docker image

Changelog

v18.0 · Shipped 2026-05-06 #

  • Multi-stage python:3.11-alpine AS generator + nginx:alpine runtime Dockerfile with repo-root build context + default-deny .dockerignore allowlist; MILESTONES.md backfilled with v16.x and v17.0 entries (Phase 162)
  • iOS-led hero with App Store badge, "Self-hosted. No signup." brand pivot, all four https://github.com/your-repo/soundstash placeholders removed, six-card Server features grid, How-it-works iPhone↔server sync SVG diagram, OG/Twitter card meta tags on six pages, build-time-generated 1200×630 og-image.jpg (Phase 163)
  • Build-time pages/status.html generator (Python+Jinja2+Markdown) reading VERSION + MILESTONES.md + ios-status.json with strict regex lint, fail-fast on heading drift (Phase 164)
  • Windows installer (dist/SoundStash-Setup.exe, 29 MB) bundled into nginx image as separate early COPY layer with click-through pages/download.html showing version + size + SHA-256 + SmartScreen caveat; build fails fast if installer missing (Phase 165)
  • Full pages/docs.html rewrite into Server / iOS / Podcasts / Troubleshooting sections current with v14.0–v17.0 features; sticky two-level sidebar ToC with IntersectionObserver scroll-spy; ten zero-footprint anchor-alias spans for SEO carry-forward (Phase 166)
  • verify_phase167.sh runs 8 automated QA gates (Lighthouse mobile 97/100/100/92, Lychee 0 broken, axe-core 0 WCAG, image 52 MB ≤ 90 MB cap, og-image 26 KB ≤ 300 KB cap, Phase 163 placeholder-grep inheritance, ToS hygiene gate H) (Phase 167)
  • Post-ship editorial pivot 2026-05-06: homepage feature section split into "In your pocket" (6 iOS cards) leading + "On your server" (4 server cards) secondary; nav split App / Server
  • Post-ship YouTube ToS hygiene pass 2026-05-06: replaced "YouTube downloader" marketing copy with yt-dlp / "URL" framing across index/docs/changelog; build-time gate H prevents regression; CLAUDE.md "YouTube ToS hygiene (CRITICAL)" policy added

v17.0 · Shipped 2026-04-23 #

  • Podcast subscribe / discover / OPML import (Phase 151)
  • Episode browse / detail / FTS5 search (Phase 152)
  • Core download pipeline + background conditional-GET refresh (Phases 153, 158)
  • Server-fallback bulk download + storage management (Phase 154)
  • Playback position sync + PC2.0 / PSC chapters (Phases 155, 156)
  • Continuous-playback queues (Phase 157)
  • Bidirectional sync hardening with absorbing tombstones + per-field LWW (Phase 159)
  • App Store ship polish + multi-device test + 2.5.4 background-modes audit (Phase 160)
  • Phase 160.1 paywall gating closed the unified 20-download free-tier loophole on podcasts (ship-blocker)
  • Phase 161 closed v17.0 doc hygiene with 4 cleanup plans (27 stale REQ-IDs flipped Pending→Satisfied; ROADMAP Progress table refreshed; retrofit *-VERIFICATION.md scaffolding for Phases 152, 153, 158)

v16.3 · Shipped 2026-04-06 #

  • getSeriesEpisodeTrackIds() database-driven track discovery (Phase 147)
  • Complete cascade deletion with before/after orphan sweep (Phase 148)
  • Playback guard via TrackPlayer.reset() before deletion to prevent dangling playback handles (Phase 149)
  • "Delete All Local Data" reset button added under Settings → Storage
  • v1.2.3 (build 57) submitted to App Store review

v16.2 · Shipped 2026-04-04 #

  • LEFT JOIN exclusion queries in offlineDb.ts for standalone-track detection (Phase 143)
  • BrowseScreen Tracks section with dual-path loading and TrackRow rendering (Phase 144)
  • Tap-to-play via loadPlaylistForOfflinePlayback with album search (Phase 145)
  • Debounced live refresh on download completion / deletion (Phase 146)
  • v1.2.2 (build 52) submitted to App Store review
  • Expo deprecation warnings fixed (newArchEnabled, userInterfaceStyle)

v16.1 · Shipped 2026-04-03 #

  • INSERT OR REPLACE in upsertSeries() silently zeroed episode_count → switched to ON CONFLICT DO UPDATE
  • Sync engine previously ignored delta.series.updated → now processes full series metadata on incremental sync
  • Offline completion check loosened from progressPct === 100 → requires all episodes downloaded AND completed
  • Zero-denominator "X of 0 episodes" display replaced with "No episodes" fallback
  • Fastlane release lane added for automated App Store submissions
  • App version bumped to 1.2.1; submitted to App Store review

v16.0 · Shipped 2026-04-02 #

  • PyInstaller spec includes all new dependencies (feedparser, listparser, nh3, podcastindex, rapidfuzz, zeroconf) via collect_submodules()
  • rapidfuzz>=3.9.5 version floor pinned to fix PyInstaller SIMD bundling
  • Native extensions (nh3, rapidfuzz) confirmed bundled as .pyd in the Windows build
  • Windows entrypoint switched from waitress.serve() to socketio.run() so WebSocket transport works on the bundled runtime
  • Real-time download progress now delivers WebSocket events on the Windows runtime (was silent before)
  • Background podcast-refresh service works under Windows threading mode
  • Expanded smoke test covers podcasts, podcast queues, BorrowBox, homepage dashboard, and the WebSocket handshake
  • PyInstaller build completes without errors on the Windows host; all expanded smoke tests pass against the Windows-built runtime
  • Manual podcast subscribe-download-playback flow verified end-to-end on the Windows runtime

v15.0 · Shipped 2026-03-30 #

  • Per-podcast playback order with feed-type defaults, episode list filtering/ordering API, order-aware auto-advance, and PodcastQueue database tables for Phase 132
  • Player context discriminator, episode filter segmented control, and play order indicator/settings wired to API endpoints from Plan 01
  • Smart playlist rule engine for PodcastEpisode with 7 filterable fields, 5 sort modes including grouped-by-podcast interleaving, and 4 idempotent default queues
  • REST API blueprint with 11 endpoints for podcast queue CRUD, episode management with D-09 sort mode application, smart playlist preview, and bootstrap integration creating 4 default queues on startup
  • Queue list page with card grid and smart queue rule editor with 7 podcast-specific fields, relative date presets, podcast dropdown, and live preview
  • Queue detail page with episode display, drag-to-reorder, inline rename, and +Q flyout on podcast detail for adding episodes to queues
  • GET next-episode endpoint resolves queue sort order server-side and returns the adjacent episode for queue-driven auto-advance playback
  • Queue-driven playback with auto-advance countdown, session persistence via localStorage, interruption/resume flow, and Now Playing queue context display
  • Download worker hardened with 15-min timeout watchdog and persistent queue, plus 4 new bulk download API endpoints with filter presets (all_undownloaded, last_5, last_10, all_unlistened) and count queries
  • Download Episodes dropdown with 4 filter presets on podcast detail page and Download New Episodes button on subscriptions page, with batch completion toast via WebSocket tracking

v14.0 · Shipped 2026-03-28 #

  • Podcast data foundation with RSS parsing, iTunes namespace, and malformed feed tolerance
  • Subscribe, search (iTunes + Podcast Index), and discover with sidebar mode toggle
  • Full episode lifecycle: download with WebSocket progress, storage retention, playback with resume and speed control
  • Chapter navigation supporting Podcasting 2.0 JSON, PSC, and ID3 CHAP formats
  • Background refresh with configurable intervals, auto-download per podcast, conditional HTTP caching
  • OPML import/export for subscription migration from Apple Podcasts, Overcast, Pocket Casts
  • Episode/season promotion to main library with Track/Series creation and symlink
  • Integration hardening via gap closure phase (OPML WebSocket, auto-download toast, refresh service restart, promotion file_path)

v13.0 · Shipped 2026-03-25 #

  • Researched podcast RSS ecosystem: feedparser for parsing, iTunes Search API for discovery, python-podcastindex for secondary search, listparser for OPML
  • Competitive analysis of Overcast and Amazon Podcasts — SoundStash already has ~60% of podcast infrastructure (player, downloads, series, scheduled tasks)
  • Architecture decision: dedicated Podcast/PodcastEpisode models (not reusing Track/Series), sidebar navigation (not mode toggle), shared Player with isPodcast branching
  • Identified key pitfalls: GUID fragility, unbounded storage growth, Track model contamination, iTunes namespace requirements, feed HTTP edge cases
  • Produced 6-phase implementation recommendation: Foundation → Download/Player → Refresh/Auto-download → Chapters/Queue → Audio Enhancement → Library Migration

v12.0 · Shipped 2026-03-24 #

  • Deployed demo server via Cloudflare Quick Tunnel with LibriVox public domain audiobooks for Apple reviewer (Named Tunnel not possible — ihelm.org.uk DNS not on Cloudflare)
  • Removed nginx basic auth layer after mobile Safari re-prompted credentials on every page navigation
  • Captured screen recording on iPhone 16 Pro and verified IAP sandbox purchase flow end-to-end
  • Submitted Resolution Center reply addressing all 5 Apple Guideline 2.1 requirements with recording attached
  • Added demo/README.md documenting Quick Tunnel decision and operational caveats

v11.0 · Shipped 2026-03-23 #

  • Reverted detection page from v9.1 multi-stage queue to simple candidate cards with accept/modify/reject (5,400-line JS → 1,240 lines)
  • Added "Add Track" modal to series detail page with library search, smart episode number guessing from track titles, and insert-and-shift positioning
  • Extended accept-candidate endpoint with cover_track_id for user-selected series cover art
  • Stripped ~2,100 lines of dead v9.1 gap-fill/queue/completeness UI code while preserving all backend APIs and database tables
  • Added .m4b audiobook format support (Libation/Audible imports)
  • Extended library search to match file paths (folder names find tracks)

v9.0 · Shipped 2026-03-20 #

v9.1 · Shipped 2026-03-14 #

v8.0 · Shipped 2026-03-07 #

  • Route restructuring with homepage at /, download at /download, BorrowBox at /borrowbox, and grouped sidebar navigation with three sections
  • Homepage dashboard with Continue Listening, library stats cards, Recently Added, listening time statistics, Continue Series, Chart.js charts, and Recently Finished
  • BorrowBox ZIP import with automatic chapter extraction, ID3 metadata reading, series creation, and duplicate conflict resolution via WebSocket
  • BorrowBox account connection with Fernet-encrypted credentials, multi-strategy login, loan browsing with cover art, and one-click audiobook download with chapter-level progress
  • BorrowBox loan lifecycle with expiry tracking (active/expiring/expired computed status), visual badges in library and series views, and legal disclaimer acceptance modal
  • PlaybackSession delta recording for accurate listening time statistics with time-bucketed aggregation

v7.0 · Shipped 2026-03-06 #

  • Web Audio API FFT pipeline with AnalyserNode, 1024-bin-to-64-bar logarithmic processing, and exponential decay smoothing
  • Five Canvas2D visualizer modes (Spectrum Bars, Oscilloscope, Circular, Milkdrop-Lite, Frequency Landscape) with full-screen overlay, mode switching, and 5 color palettes
  • iOS native Swift FFT module using MTAudioProcessingTap + vDSP with Expo Modules bridge, 30fps CADisplayLink, and KVO-based track re-attachment
  • Five View-based iOS visualizer modes with React.memo optimization, dB-scaled FFT data, and full-bleed layout outside SafeAreaView
  • Cross-platform parity: identical palette hex values, mode names, FFT processing constants (64 bars, 0.85 decay, log binning), and dB range mapping
  • Visual polish: peak hold indicators (500ms hold, 3.0 gravity), per-mode glow effects, album art color extraction (Canvas + react-native-image-colors), and complete v6.5 legacy removal
  • All 26 requirements verified including genuine physical device testing on iPhone 16 Pro (TestFlight build 24)

v6.5 · Shipped 2026-03-03 #

  • iPhone rotation unlocked app-wide with compact landscape-safe shell, browse, downloads, detail, modal, and settings layouts
  • Now Playing redesigned into a deliberate landscape surface with stable scrub state, compact utility sheets, and queue-safe dismissal flow
  • Retro visualizer mode added inside Now Playing with a reusable shell, two distinct presets, and track-aware palette treatment
  • Visualizer preset persistence, lighter split live/idle animation timing, and failure-aware artwork fallback hardened the visualizer for real playback
  • TestFlight build 1.1.0 (7) validated the shipped landscape + visualizer flow, and the upload helper permission issue was fixed for future deploys

v6.4 · Shipped 2026-03-03 #

  • Author-aware series auto-detection with RapidFuzz fuzzy matching, author-based grouping, and enhanced online enrichment with persistent caching
  • Post-save series editing: drag-to-reorder episodes, add library tracks to existing series, quick-create series from multi-select, and cross-series track moves
  • Series merge with two-phase flow (picker + preview), duplicate detection, drag-to-reorder combined episodes, and atomic commit
  • Completeness tracking: expected episode count, gap placeholder rendering, file unavailability indicators, library gap-fill search, and URL-based gap-fill with download-then-assign
  • Series browse polish: author dropdown filter, author-inclusive search, completeness indicators on cards, and startup author backfill migration

v6.2 · Shipped 2026-03-01 #

  • Device-local SQLite database with FTS5 search indexes all downloaded track and collection metadata for offline browsing and filtering
  • Two-layer server reachability (NetInfo + health polling) with OfflineError fail-fast on API calls, amber offline banner, and green back-online toast
  • Offline-aware browse screens: all three browse views (Browse, PlaylistDetail, SeriesDetail) fall back to cached/local data with dimmed non-downloaded tracks
  • Downloaded content filter across Browse, Series, and Playlist screens with two-layer state (user preference + auto-override) and automatic offline activation
  • Server auto-discovery: Flask mDNS advertisement via Bonjour + iOS react-native-zeroconf scanning with auto-connect, multi-server list, and manual IP fallback
  • Gap closure: full metadata pass-through for playlist/series downloads, one-time repair scan, season-grouped rendering, resetReachability wiring, and server version display

v6.1 · Shipped 2026-02-28 #

  • App Store Connect app record and API key (.p8) infrastructure configured on Mac Mini for automated iOS distribution
  • Branded SoundStash app icon and dark-themed splash screen generated via reproducible Pillow asset pipeline (generate-assets.py)
  • Fastlane automation pipeline (Gemfile, Appfile, Fastfile) with beta/build_only lanes, pre-flight validation, auto build number increment, and Xcode 26.2 altool workaround
  • One-command WSL-to-TestFlight deploy script (deploy-testflight.sh) with --sync/--release modes and --notes changelog support
  • Build reproducibility hardened: expo-splash-screen pinned in package.json, lock file regenerated, script permissions fixed, error messages corrected
  • All documentation and traceability gaps from milestone audit closed (INFRA-02 traceability, CLAUDE.md deps, ROADMAP.md plan status)

v6.0 · Shipped 2026-02-27 #

  • Expo SDK 54 + RNTP 4.1.1 iOS build pipeline with WSL-to-Mac Mini SSH deployment and Ad Hoc distribution to physical iPhone
  • Full offline audio playback on iPhone with background audio, lock screen/Control Center controls, sleep timer (15/30/45/60/end-of-track), and 0.5x-2.0x speed control
  • Flask delta sync API with deletion tombstones, and bidirectional position/listening status sync with offline queue and auto-push on reconnect
  • Download manager with concurrent queue, pause/resume, retry on failure, WiFi-only mode, and per-track progress indicators
  • Library browsing from server with combined playlist+series list, drill-down detail views, search, and cover art caching via expo-image
  • Series browsing with season picker, auto-advance playback (global/per-series toggle), and Continue Listening home section with one-tap resume
  • Dark theme matching SoundStash web aesthetic, offline indicator badges, and storage management screen with swipe-to-delete and undo

v5.2 · Shipped 2026-02-25 #

  • Backend batch hydration delivers full track metadata (title, artist, duration, cover art) for every candidate via 2 chunked SQL queries
  • Rich candidate cards with cover art thumbnails, episode numbers, match reasons, and aggregate summary (duration + format distribution)
  • Shared renderRichTrackRow() component used consistently across candidate cards and Modify modal
  • Drag-to-reorder episodes in Modify modal with HTML5 Drag API, visual feedback, and Reset Order button
  • Edit protection guard deferring background refreshes while Modify modal is open with external change detection

v5.1 · Shipped 2026-02-24 #

  • Database migration to soundstash.db with backwards-compatible four-scenario handling and WAL companion file support
  • Docker configuration renamed (service, container, project name, compose project) to soundstash
  • All 15+ templates branded as SoundStash with consistent "Page | SoundStash — Personal Audio Library" title format
  • Backend identifiers updated: health endpoint, Plex headers, MusicBrainz User-Agent, backup filenames, client ID format
  • Legal documents revised with multi-source language, Plex privacy sections, and broadened copyright disclaimers
  • 45 planning files bulk-updated across milestones, phases, codebase docs, and research docs with historical rename context preserved

v5.0 · Shipped 2026-02-24 #

  • 30-second skip forward/back buttons on mini player and Now Playing overlay with keyboard shortcuts and position persistence
  • Full-screen Now Playing overlay with responsive layout, large cover art, all playback controls, queue drag-to-reorder, and mobile swipe gestures
  • Player tech debt cleanup: fixed default-cover.png references across 9 files, consolidated play button logic, standardized event handlers
  • Bulk metadata re-scan pipeline with WebSocket progress, diff preview modal, fill-empty/overwrite modes, and crash recovery checkpointing
  • Scheduled background scanning with configurable intervals (startup/daily/weekly/custom), conflict detection, and settings UI toggle
  • Series auto-detection engine with four-strategy local pattern matching and opt-in online enrichment via MusicBrainz, OpenLibrary, and Google Books

v4.0 · Shipped 2026-02-22 #

  • Three-state listening status (Unplayed/In Progress/Completed) with automatic transitions, manual override, and library-wide filter
  • Visual status indicators (dot/ring/checkmark) in grid and list views, smart playlist listening_status rule support
  • Series entity with full CRUD: create, edit, delete, cover art auto-populate, seasons, ordered episodes
  • Series browse mode as 4th library mode with progress rings, completion badges, and drill-down navigation
  • Continue Listening series context and auto-advance playback with countdown overlay and per-series toggle
  • Playlist URL detection with preview, batch download, and automatic series creation with episode ordering
  • Retroactive data migration for existing tracks (play_count > 0 → Completed)

v3.0 · Shipped 2026-02-21 #

  • Docker CLI and Compose installed in container with socket detection and graceful degradation when Docker unavailable
  • Host filesystem browsing with WSL drive letter detection, path translation (/host → /mnt), and last-path persistence
  • Compose file self-editing via ruamel.yaml round-trip with automatic backups, validation, and atomic writes
  • Mount CRUD UI with pending changes queue, protected mount badges, and affected track warnings before removal
  • Container self-recreation via fire-and-forget subprocess with WebSocket pre-notification across tabs
  • End-to-end restart flow with active download guard, reconnect overlay with health polling, and post-reconnect data auto-refresh

v2.0 · Shipped 2026-02-17 #

  • Playback position persistence across sessions with auto-resume via write-through cache, localStorage queue storage, and sendBeacon sync
  • Player enhancements: adjustable speed (0.5x-2.0x), sleep timer with timed/end-of-track modes, and Continue Listening section
  • Multi-folder library foundation with centralized PathResolver, default folder bootstrap, and folder management UI
  • Automated folder scanning with availability checking, offline track indicators, and batch import with deduplication
  • Multi-folder download integration with target folder selection in URL/Plex downloads and cross-folder track moves

v1.2 · Shipped 2026-02-13 #

  • Codec detection and in-place conversion system with WebSocket progress and library badges for unplayable formats
  • Plex download-time codec warnings with one-click conversion format selection for video extraction and music tracks
  • Hardened URL source quality analysis with ABR fallback and real-time upsample/downsample format warnings
  • File path display in track detail panel with library-relative path stripping
  • Hierarchical library browsing with artist/album/folder navigation, breadcrumbs, and full track interactivity

v1.1 · Shipped 2026-02-10 #

  • Full metadata editing: inline editing, detail drawer with 9 fields, cover art upload with crop, batch edit
  • Smart URL title parsing with regex engine, confidence scoring, and preview-before-apply
  • Configurable Artist/Album folder organization with dry-run preview, atomic moves, and auto-organize on download
  • Rule-based smart playlists with visual builder, AND/OR logic, sort/limit, preview, and auto-refresh
  • Watch folder monitoring with auto-scan, browser drag-drop upload, and cloud placeholder detection
  • Database backup with SHA-256 file manifest and merge/replace restore with integrity verification

v1.0 · Shipped 2026-02-08 #

  • Database foundation with Fernet-encrypted Plex credential storage
  • Dual authentication — OAuth server discovery + manual token fallback
  • Full music library browsing hierarchy (Libraries → Artists → Albums → Tracks)
  • Music download pipeline with real-time WebSocket progress and metadata preservation
  • Two-stage format conversion pipeline with FFmpeg (download → convert → metadata)
  • Video audio extraction from movies/TV shows with multi-track selection
  • Unified library with source badges and filtering across all configured sources