diff --git a/src/servers/sidecar/music/indexer.ts b/src/servers/sidecar/music/indexer.ts index 63b7ad5f..e53a64d4 100644 --- a/src/servers/sidecar/music/indexer.ts +++ b/src/servers/sidecar/music/indexer.ts @@ -34,6 +34,11 @@ const COVER_FILES = ['folder.jpg', 'cover.jpg', 'folder.png', 'cover.png']; const DISCO_FILE = '_discography.md'; const TRACK_CONCURRENCY = 6; const COVER_MAX_PX = 600; +// Cache-format version. Bump when the build produces NEW per-album outputs (so far: v2 added video +// posters + lyrics). A manifest written by an older CACHE_VERSION forces a one-time FULL rebuild — the +// per-album `v` skip only applies once the cache is already at the current format. +// v1 → initial (meta + cover) v2 → + posters/ + lyrics/ +const CACHE_VERSION = 2; // ── Types (meta.json matches the app's IndexMeta/IndexTrack) ── @@ -445,7 +450,7 @@ export async function buildMusicIndex(): Promise { console.log('[music] resync started'); const prev = await loadManifest(); - const next: Manifest = { version: 1, generatedAt: status.startedAt!, albums: {} }; + const next: Manifest = { version: CACHE_VERSION, generatedAt: status.startedAt!, albums: {} }; try { await mkdir(CACHE_ROOT, { recursive: true }); @@ -584,7 +589,10 @@ async function walk(dirAbs: string, prev: Manifest, next: Manifest): Promise f !== null); const outputsExist = expected.every((f) => existsSync(join(cacheDir, f))); - if (prev.albums[rel]?.v === v && outputsExist) { + // Only trust the per-album `v` skip once the cache is already at the current format — an older + // CACHE_VERSION means new outputs (posters/lyrics) may be missing, so rebuild every folder once. + const formatCurrent = prev.version === CACHE_VERSION; + if (formatCurrent && prev.albums[rel]?.v === v && outputsExist) { status.albumsSkipped += 1; } else { await mkdir(cacheDir, { recursive: true });