Repository navigation
feat(cli): audio --read --layer reads a one-layer file whole, no separation - #7345
Conversation
…e whole A caller that knows a file holds a single layer can declare it: the file is read whole as that layer with no stem separation and nothing uploaded. Without the flag the read is unchanged. An unknown layer is rejected. Consumer: heygen-com/experiment-framework#66322. Proposal OK'd by Rory (C0BEH487Q7R, 2026-11-07). Co-Authored-By: Jerrai
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
Co-Authored-By: Jerrai
There was a problem hiding this comment.
Verdict: APPROVE · 0 blocker · 0 important · 2 nits · head 3a756902
No-flag path is unchanged (base() adds no layer, cache check entry.analysis.layer === layer holds for old entries), and analyzeLayer never reaches stemsFor/describeStems, so nothing uploads at any --quality. CI ran the new suites with ffmpeg (read.test.ts 17 tests, flake gate 10/10 on both files).
- nit: the text header for a layered read is still
<file> · N s · not separated(format.tsheader); only--jsonshows the declared layer. A· read as <layer>suffix would make text-mode output say why nothing was separated.
Scope
Read in full: audio/read/read.ts, commands/audio.ts, types.ts, both tests, docs hunk. Checked format.ts against null voice/effects/music. No prior reviews on the PR.
| return { analysis: entry.analysis, textPath, jsonPath, cached: true }; | ||
| } | ||
| const analysis = await analyze(path, file, sha, transcript, stemDir, quality, options.cacheDir); | ||
| const analysis = layer |
There was a problem hiding this comment.
nit: layered and mix reads share one cache slot (jsonPath/textPath are keyed only on name + sha, line 465), so they are never confused but they do overwrite each other: reading the same file alternately with and without --layer (or with two different layers) re-analyses every time, and a textPath handed out by the earlier read now holds the other read. Harmless for the Cut Room consumer, which only reads its own single-layer takes with the flag; adding the layer to stem (e.g. ${stem}-${layer}) would keep both. Stems on disk are untouched either way, so no re-upload.
…-com#7336-heygen-com#7358 Adopt heygen-com#7304 (without CLI renderDiagnostic, needs heygen-com#6725), heygen-com#7331, heygen-com#7332, heygen-com#7334, heygen-com#7337, heygen-com#7336, heygen-com#7339, heygen-com#7289, heygen-com#5594, heygen-com#6900, heygen-com#7322, heygen-com#7342, heygen-com#7343, heygen-com#7350 (onProgress only), heygen-com#7352, heygen-com#7348, heygen-com#7344, heygen-com#7353, heygen-com#7356 and heygen-com#7355. Defer heygen-com#5708 (needs heygen-com#6911) and heygen-com#7345 (READ_VERSION 4 vs 7); heygen-com#7307 not applicable. Re-read 14 moved pins, pin 6 new PRs (monitored 126). Make checkReportFile module-private and suppress the cross-package closeTestChrome duplicate for fallow. Co-authored-by: Miguel Ángel <miguel.sierra@heygen.com> Co-authored-by: SophiaHuangCc <129631224+SophiaHuangCc@users.noreply.github.com> Co-authored-by: Dante <duanjl.china@gmail.com> Co-authored-by: Muzzy5150 <muzzy5150yt@gmail.com> Co-authored-by: ump45nose <52391318+ump45nose@users.noreply.github.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What
hyperframes audio <file> --read --layer music|sfx|voice: a file the caller declares holds one layer is read whole as that layer, with no stem separation and nothing uploaded.Why
audio --readreads music only from separated stems, so a file known to be a single music, effect or voice take still pays for separation. Rory OK'd this proposal (C0BEH487Q7R, 2026-11-07). The consumer is heygen-com/experiment-framework#66322, held until this ships; it callshyperframes audio <file> --read --quality local --layer <voice|sfx|music> [--range a,b] [--transcript words]onceaudio --helplists--layer.Related work
Consumer: experiment-framework#66322.
How
commands/audio.ts:--layerparsed byparseLayer; unknown values fail with--layer is music, sfx, voice; got <value>;--layerwithout--readis rejected.--helptext added.audio/read/read.ts:analyzeLayerdecodes the whole file and runs the existing analysis on it:musicthroughreadMusic(sections, tempo, levels),voicethroughvoiceFromWords/voiceFromActivity(words and pauses),sfxthroughfindEffects. Other layers are null.types.ts:ReadAudio.layer?records the declared layer, present only when declared. The cache entry must match the declared layer, so a layered read never reuses a mix read and vice versa.docs/packages/cli.mdx.Test plan
audio/read/read.test.ts(music, voice and sfx read whole with zero stem requests, cache kept apart from a mix read, nolayerfield when undeclared);commands/audio.command.test.ts(each layer passed through, absent flag, bad value,--layerwithout--read).vitest runon those two files: 23 passed. oxfmt and oxlint clean on changed files.— Jerrai