feat(meetings): capture system audio in Electron - #7196
Conversation
Adds a recording package that owns an audio session: a state machine per session, a WAV writer, a transcript persister, and recovery for a session whose process died mid-recording. The dashboard exposes it at /api/ws/recording, and the Meetings app records what a session produced through its own recording store. The frontend captures both the microphone and the system output, mixes them through the PCM worklet's two inputs, and shows input level in a meter so a user can see the capture is live before the meeting starts.
A browser tab can only offer system audio through a display-capture prompt, and on some platforms not at all. Electron can grant it directly, so the display-media handler resolves a loopback audio track and the frontend probes which capture tier it actually received. The tier is reported rather than assumed, so a platform that cannot provide system audio degrades to microphone-only instead of recording silence.
Audit note — this PR and #5738 are one branch stack, not duplicatesA duplicate-detection sweep flagged these two as near-identical because they share a large block of added lines. They are not duplicates: one branch contains the other's commits, so the shared lines are inherited, and the review diff overstates what this PR actually authored. This is the textbook stacked-branch artifact, provable by SHA rather than by reading code: What is genuinely each PR's ownIf #5738 merges, #7196 still carries all of its own work and loses nothing: 6 files #5738 never touches ( Suggested actionLand #5738 first, then rebase #7196 onto From a repository-wide duplicate/overlap audit of every pull request open against |
Open PR relationship auditThis is a consolidated, point-in-time code-level audit note. It compares complete merge-base diffs and current/merged code; it does not treat a shared topic as duplication or partial coverage as completion. Relationship findings
No PR, Issue, label, branch, or review state was changed by the relationship-note portion of this audit. |
|
🤖 Kiro Crew [operator: NicholasRBowers#a942f9ca]: This PR has been inactive for 7+ days. I reviewed the blockers but they require your input:
When you've addressed these, the pipeline will re-assess on its next cycle. |
|
Attempted a rebase onto main They land in the parent commit (
Also pending on this PR's own commit: merged #7532 moved Suggested order: land #5738 first, then rebase this branch so its diff is just its own 22 files. |
Problem / Motivation
In a browser tab, system audio (the remote side of a Zoom/Chime call) is only reachable through a display-capture prompt, and on some platforms not at all. So in the desktop app — the place most likely to be running next to a call — a meeting records only what the microphone picks up.
What changed
website/electron/display-media.jsgrants the request with system audio where the platform can provide it, andpreload.jsexposes the capability to the renderer behind the existing bridge.audio/captureTier.ts): the frontend inspects the track it actually received and reports which tier it got. A platform that cannot provide system audio degrades to microphone-only instead of recording silence — the failure a hardcoded assumption would produce.Tests
website/src/test/MeetingsCaptureTier.test.ts(16 tests) — the tier probe and each degradation path.website/electron/test/display-media.test.js(17 node:test cases) — the main-process handler's grant/refuse branches.Both suites run green on the branch (Linux, node 22).
tsc -bdoes not pass on this branch's checkout because the stack's base predates the main-branch repair in #5522 (useDialogFocusTrap.ts) — untouched by this change and resolved by the rebase onto #5738's post-rebase head.Manual verification
Not yet performed on a real desktop build; loopback capture availability differs per OS and needs a hands-on pass (macOS in particular) before merge sign-off.
Related Issues
Part of the meetings feature stack split from the
feat/meetnotebranch; depends on #5738, independent of #5741/#2190/#7194.no linked issue: feature work from the meetings stack; no tracked issue exists for it.