From 009345a5591b3aac004ee089e205c7c65f529202 Mon Sep 17 00:00:00 2001 From: ishan pandey Date: Mon, 27 Apr 2026 21:30:59 +0530 Subject: [PATCH] feat: per-scene sfx via elevenlabs (milestone a of #25) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first audio-bed retention lever from the SFX/Music + Gemini plan (#25). Per-scene generated sound effects landing on the existing SFX lane that PR #20 placeholders wired. **Backend** (`packages/core`) - `elevenlabs/sfx.ts` — `generateSoundEffect(apiKey, prompt, opts)` mirrors the existing `synthesize()` shape: returns mp3 bytes + format. Clamps duration to 0.5..22, prompt influence to 0..1. Surfaces ElevenLabsError with the raw HTTP detail so the studio can show a meaningful 502. - `script/sfx/manifest.ts` — append-only manifest at `assets/sfx/sfx.manifest.json`. Three anchors (scene-start / accent-word / scene-end). Pure-helper `resolveSfxStart` does the anchor → absolute-time math; `resolveSfxStartForScene` wraps it with scene + cursor lookup so the assembler can call it directly. - `assemble.ts` reads the manifest once per assemble, groups by sceneId, and emits `