Three coordinated polish changes: 1. PlayerBar cover bumps from h-20 (80px) to h-24 (96px) and the bar's vertical padding tightens from py-4 to py-1.5. Bar height stays ~108px but the cover now fills ~89% of it (was ~74%) — reads as the substantial primary content the operator wanted, not a thumbnail. 2. InfiniteScrollSentinel default rootMargin moves from 300px to 800px so the next page fetches well before the user reaches the bottom of the rendered set. Empirically that's ~3-4 rows of cards on a typical library grid — loading feels seamless rather than catching up. 3. HorizontalScrollRow takes rows: T[][] instead of items: T[]. Multiple rows of items now render inside one shared overflow-x-auto container, so the rows scroll together as a single coupled section. Recently added (2 album rows) and Most played (3 track rows) on the home page now scroll as one unit. Rediscover keeps two separate scrollers because its rows are different card types (square albums vs circular artists) — coupling those would interleave shapes awkwardly. The item snippet's second arg is now the global flat index so consumers like CompactTrackCard (which needs sectionTracks + index for play actions) work without per-row re-indexing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Minstrel
Self-hosted music server with OpenSubsonic compatibility plus an extended API for server-side smart shuffle, a dual-like model (general + contextual), session-aware radio, ListenBrainz scrobble/similarity, and Lidarr integration. Go + Postgres, packaged as a Docker container.
State and intelligence belong on the server, not the client.
Specs
Authoritative v1 scope lives under docs/:
- Server spec — current implementation focus.
- Client spec — Flutter companion app; work starts once the server reaches its Subsonic-compatible baseline.
Development workflow
- Day-to-day work happens on the
devbranch (or feature branches merged intodev). mainis protected — changes land only via pull request fromdev.- Production builds are cut by tagging a release (
v*) offmain.
CI / container image
Forgejo Actions handles:
- Tests on push to
devand on PRs intomain. - Container image build + push to the Forgejo registry on merge to
main(:main) and onv*tags (:<version>).
Task and milestone tracking: Fable (Minstrel project, id 12).
Development
Minstrel has two concurrent dev processes:
- Backend:
docker compose up— starts Postgres and Minstrel on:4533. - Frontend:
cd web && npm install && npm run dev— Vite dev server on:5173with HMR.
The Vite dev server proxies /api/* and /rest/* to the backend on :4533,
so session cookies work correctly when the SPA is loaded from the Vite origin.
Production build
docker build -t minstrel . runs the SvelteKit build inside a node stage,
copies the output into the golang stage, and //go:embeds it into the
final binary. The resulting container serves the SPA from / alongside the
API surfaces. No separate static-file server is required.