18 Commits

Author SHA1 Message Date
Your Name 60892c12e7 fix: multi-container docker-compose proxy, audiobookshelf sync bugs, add sync button
Fixes #158 -- fresh docker-compose install shows login instead of setup
wizard because Next.js rewrites were compiled with 127.0.0.1:3006 baked
in. Added NEXT_PUBLIC_BACKEND_URL as a Dockerfile build arg, defaulting
to http://backend:3006 in docker-compose.yml so the frontend container
proxies to the backend service correctly.

Audiobookshelf sync fixes:
- syncAudiobook returns boolean; skipped books no longer count as synced
- Sync notification now surfaces failed/skipped counts
- downloadCover has 10s fetch timeout (was unbounded)
- book.size changed to book.media?.size for audio-only size

Added sync button on audiobooks page so users can trigger a sync without
going through settings or the enrichment system.

Bump to v1.7.2
2026-03-18 13:50:18 -05:00
Your Name d67c8f49ef release: v1.5.7
BullMQ enrichment migration
- Rewrote enrichment pipeline on BullMQ v5: artist, track, podcast workers with
  pause/resume/stop support and Bull Board visibility
- Essentia publishes audio:analysis:complete events; CLAP subscribes reactively
  instead of polling (eliminates scan delay between phases)
- Thread-safe DB pool in CLAP worker, all DB calls in run_in_executor
- Fixed psycopg2.pool submodule import crash on BullMQ vibe worker startup
- Silenced EnrichmentStateService disconnect error on already-closed Redis conn

Enrichment fixes
- lastfmTags NULL caused mood-tags phase to silently skip all tracks; migration
  backfills NULL -> '{}' and sets column default
- Cover art fetch errors for temp-MBID albums (temp-* passed to Cover Art Archive)
- VIBE-VOCAB vocabulary JSON not copied to Docker image (TypeScript omits .json)
- Wired cleanupOldResolved() to run daily; added missing enrichment status indexes
- Fixed circuit breaker reset, orphan cleanup, podcast entityType, hang detection

Soulseek
- Track search-page downloads in activity tracker
- Use async fs.promises.access instead of synchronous existsSync
- Verify file exists on disk before emitting download:complete (#110)

Docker image size: 28.4 GB -> 12.2 GB
- Removed all CUDA/NVIDIA dependencies; switched to CPU-only PyTorch/TensorFlow
- tensorflow-cpu + essentia-tensorflow --no-deps (avoids GPU TF transitive dep)
- Fixed .dockerignore: **/node_modules and **/.next now excluded from build context

PWA / mobile
- Background audio session loss on iOS/Android: SilenceKeepalive singleton,
  tryResume() in MediaSession play handler, direct track load on 'ended' event,
  visibilitychange/pageshow foreground recovery
- Lock orientation to portrait for Android device lock (#117)

Discovery
- Retry All re-importing albums already in library: apply same three-level filter
  as GET /current before creating download jobs; delete stale UnavailableAlbum
  records for already-present albums. Closes #34

CI / release
- linux/arm64 added to release and nightly Docker builds (#87)
- Isolated release CI from nightly GHA cache (cache-from/cache-to removed from
  docker-publish.yml to guarantee clean release builds)
- Redis vm.overcommit_memory=1 sysctl added to prod and server compose files

Other fixes
- Cross-artist album fallback by title+year prevents library splitting (#50)
- Retry temp-MBID artists after 24h not 7 days; hide temp MBIDs from API (#112)
- 3-attempt ECONNRESET retry on all Deezer getPlaylist call sites (#119)
- check response.ok on health probe — fetch does not throw on 5xx (#104)
- Z-index stacking hierarchy established (MiniPlayer through OverlayPlayer)
- API token display overflow on iPhone (min-w-0/overflow-hidden on flex container)
2026-02-23 17:19:46 -06:00
Your Name 9d9ca9fc12 fix: complete remaining Kima rebrand across all source files
Covers: README docker examples, metric prefixes, User-Agent URLs,
env vars (LIDIFY_* -> KIMA_*), test env vars, image asset rename
(LIDIFY.webp -> kima.webp), frontend component constants, and
code review docs. Only lidify-discovery Lidarr tag and webhook
detection string intentionally preserved for backward compatibility.
2026-02-16 10:10:30 -06:00
Your Name 569ed5ecbe chore: rebrand Docker infrastructure to Kima 2026-02-16 09:41:11 -06:00
Your Name db758d07d1 v1.4.2: GPU support, analyzer lifecycle, search overhaul
- GPU acceleration for CLAP vibe embeddings (NVIDIA Container Toolkit)
- Immediate model unload + malloc_trim (6.5GB -> 2.0GB idle)
- tsvector full-text search with ILIKE fallback (fixes #64)
- Discovery returns musically similar artists separately
- Circuit breaker, DB reconciliation race, enrichment completion fixes
- Worker resize debounce, queue batch size reduction
- README GPU docs, CHANGELOG v1.4.2 entry
2026-02-07 19:01:30 -06:00
Your Name 39af30f699 v1.4.2: search overhaul, similar artists fix, analyzer idle optimization
Search:
- Full-text search with DB triggers for Artist/Album/Track searchVector
- Harden queryToTsquery for special chars, fix NaN LIMIT propagation
- Extract ILIKE fallback methods, normalize cache keys
- Parallelize discovery endpoint (Last.fm + iTunes concurrent)
- Remove double debounce in frontend search
- Separate similar artists endpoint (musically similar, not name-similar)
- Alias resolution banner ("Showing results for X, searched Y")
- Soulseek polling interval leak fix (useRef + AbortController)
- Typed API responses for discover and similar artists
- "/" keyboard shortcut to focus search bar

Streaming:
- Fix HTTP Range suffix parsing for Firefox/Safari (#84)
- Extract parseRangeHeader utility, use in audioStreaming + podcasts
- Clamp range end to file boundary per RFC 7233

Library:
- Server-side sorting for artists, albums, tracks endpoints
- Case-insensitive artist matching in playlists and discovery (#64)

Audio Analyzer:
- Replace 5s poll loop with Redis BRPOP (zero CPU while idle)
- Remove TensorFlow import from main process (~300MB RAM saved)
- Lazy worker pool creation (starts on first job, not at boot)
- Configurable MODEL_IDLE_TIMEOUT to unload models after idle period
- DB reconciliation on BRPOP timeout for missed queue items
- Lighter Dockerfile healthcheck (pgrep instead of TF import)

Cleanup:
- Delete dead useDebouncedValue hook, enrichment worker, mood bucket worker
- Move sort maps to module scope
- Bump version to 1.4.2

Thanks to @Allram for identifying and fixing the Range parsing issue (#84)

Closes #84, closes #64
2026-02-07 14:57:19 -06:00
Your Name b6abfd0830 v1.4.1: bug fixes, enrichment resilience, frontend lint cleanup
Audio & Playback:
- Fix doubled audio on track change (destroy old Howl before creating new)
- Fix play/pause visual desync by using Howler state as source of truth

Soulseek & Downloads:
- Fix Soulseek download 400 error (closes #101)
- Expand Soulseek documentation (closes #27)

Enrichment & Analysis:
- Fix CLAP analyzer clobbering Essentia analysisStatus (root cause of #79)
- Add embedding check to both Python analyzers before resetting tracks
- Set analysisStartedAt when marking tracks as processing
- Clear analysisStartedAt on successful completion
- Include vibe embeddings in isFullyComplete check
- Add keepPreviousData to enrichment progress query for UI resilience
- Shut down idle worker pool to free ~5.6 GB when no work pending
- Fix compilation matching for multi-disc albums (closes #70)
- Add podcast auto-refresh in enrichment cycle (closes #81)

Admin & Auth:
- Add admin password reset via env var (closes #97)
- Add retry failed analysis button in settings (closes #79)
- Add requireAdmin to onboarding config and cleanup routes
- Remove userId from 2FA challenge response

Queue & UI:
- Fix cancelJob/refreshJobMatches not persisting state
- Fix discovery polling leak on batch failure
- Fix withTimeout timer leak in enrichment worker
- Fix useAlbumData infinite re-render loop
- Fix unhandled audio.play() promise rejection

Performance:
- Eliminate N+1 queries in recommendation endpoints
- Idle Essentia worker pool shutdown (8 processes, ~5.6 GB freed)

Frontend Quality:
- Fix all 377 ESLint errors and warnings (0 remaining)
- Fix Rules of Hooks, setState-in-effect, exhaustive-deps
- Type api.ts and 50+ files (remove explicit any)
- Remove 1664 lines of dead code and duplicates
- Extract shared utilities from duplicated patterns
2026-02-06 18:30:40 -06:00
Your Name 5b20c4207d refactor(docker): remove profiles, add lite mode override
Changes the opt-in model to opt-out:
- Analyzers now run by default with `docker compose up -d`
- Users who want lite mode copy docker-compose.override.yml.lite
  to docker-compose.override.yml (saves ~3-4GB RAM)

This is more user-friendly for an open source project where
most users want the full experience out of the box.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 11:36:33 -06:00
Your Name c7758f8417 feat(docker): add analyzer profiles for optional services
Profiles:
- none: Minimal, metadata only (~2GB RAM)
- analysis: MusicCNN for BPM/key/mood (~5GB RAM)
- vibe: Both analyzers for similarity search (~7GB RAM)
- full: Alias for vibe

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:58:09 -06:00
Your Name ee56104be8 security(api): add internal auth to vibe failure endpoint
Add shared secret authentication to the /api/analysis/vibe/failure
endpoint to prevent external abuse. The CLAP analyzer now sends
X-Internal-Secret header which the backend validates against
INTERNAL_API_SECRET environment variable.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 10:53:33 -06:00
Your Name 85abbb61bc perf(clap): always extract middle 60s for efficient embedding
- Apply chunking universally, not just for large files
- 60s from the middle captures the vibe while avoiding intros/outros
- Reduces memory requirement from 6GB to 3GB
- Faster processing for all tracks regardless of length

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 22:31:19 -06:00
Your Name 85880f5204 fix(clap): handle large audio files by chunking
- Add chunked audio loading for files >50MB - extracts middle 60 seconds
  instead of loading entire file into memory
- Use get_audio_embedding_from_data for pre-loaded audio control
- Increase CLAP container memory limit from 4GB to 6GB
- Add librosa for audio loading with offset/duration support

Large lossless FLAC files (e.g., 97MB) now process successfully
without causing container OOM crashes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 22:12:55 -06:00
Your Name 32cddf223b feat(docker): add CLAP analyzer service to compose
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 19:08:54 -06:00
Your Name 56ec293386 feat(db): add pgvector extension and track_embeddings table
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 19:01:39 -06:00
Your Name 7f228fb76f perf(library): optimize grid performance and add nightly version support
- Use CachedImage (memoized) instead of raw Image in library grids
- Add GPU acceleration hints (translateZ) to card containers
- Remove expensive shadow-lg from library card image containers
- Add hover scale transform to match homepage cards
- Fix pagination scroll to use correct scroll container (#main-content)
- Scroll after page change, not on click
- Remove standalone /artists and /albums pages (use /library tabs)
- Add NEXT_PUBLIC_BUILD_TYPE env var for nightly vs release builds
- Bump version to 1.3.6

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-23 17:29:54 -06:00
Your Name 26bfc0e35a Hotfix v1.3.3: Critical bug fixes and regressions
- Fixed regression in Soulseek search where general queries returned "No tracks found" due to trailing spaces.
- Fixed ranking logic where empty track titles incorrectly boosted scores for all results.
- Fixed "Skip Track" fallback setting not working (Fixes #68).
- Fixed login "Internal Server Error" on NAS devices (Fixes #75).
- Fixed Wikimedia Commons image proxy 429 errors by updating User-Agent.
- Added selective enrichment controls for Artists, Mood Tags, and Audio Analysis.
2026-01-11 21:17:25 -06:00
Your Name cc8d0f6969 Release v1.3.0: Multi-source downloads, audio analyzer resilience, mobile improvements
Major Features:
- Multi-source download system (Soulseek/Lidarr with fallback)
- Configurable enrichment speed control (1-5x)
- Mobile touch drag support for seek sliders
- iOS PWA media controls (Control Center, Lock Screen)
- Artist name alias resolution via Last.fm
- Circuit breaker pattern for audio analysis

Critical Fixes:
- Audio analyzer stability (non-ASCII, BrokenProcessPool, OOM)
- Discovery system race conditions and import failures
- Radio decade categorization using originalYear
- LastFM API response normalization
- Mood bucket infinite loop prevention

Security:
- Bull Board admin authentication
- Lidarr webhook signature verification
- JWT token expiration and refresh
- Encryption key validation on startup

Closes #2, #6, #9, #13, #21, #26, #31, #34, #35, #37, #40, #43
2026-01-06 20:07:33 -06:00
Kevin O'Neill 021aec7a63 Initial release v1.0.0 2025-12-25 18:58:06 -06:00