Fix Aiden Live screen-capture lifecycle before 0.41.4 - #135
Conversation
There was a problem hiding this comment.
Caution
This PR still exposes an unintended camera-permission path, and it can leave a replacement capture binding active after a concurrent start/source-change race.
Reviewed changes
This review covers the complete 13-file, one-commit screen-capture lifecycle fix.
- Authority fencing — Replaces document-key-only display release with opaque binding tokens and invalidation-aware service ownership.
- Electron policy — Installs temporary exact-document permission/display handlers and clears them when the final binding closes.
- Renderer teardown — Fences picker continuations, stops late streams and rejected frame pumps, and propagates exact tokens through IPC.
- Regression coverage — Adds parser, service, guard, and renderer tests for stale releases and adversarial teardown paths.
GPT Luna | 𝕏
There was a problem hiding this comment.
Important
The new startup cleanup can still leave the screen-share setup permanently busy when a picker is already pending; see the inline comment.
Reviewed changes The incremental review covered the changes after 95af884b, focusing on media permission narrowing and screen-capture startup fencing.
- Restricted media admission — Limited Electron
mediapermission grants to audio-only checks and requests, with camera denial coverage. - Locked source replacement — Blocked screen-source changes while provider startup is pending.
- Released startup authority — Released the exact display binding during start-failure cleanup.
- Expanded regression coverage — Added coverage for pending-start replacement attempts and audio/video permission paths.
GPT Luna | 𝕏
| await dependencies.api.stop().catch(() => undefined); | ||
| sessionRef.current = null; | ||
| await teardownMedia(); | ||
| releaseDisplayAuthority(); |
There was a problem hiding this comment.
releaseDisplayAuthority() advances screenPickerGeneration, but chooseScreenSource clears screenBusy only when its own generation is still current. Since the setup dialog still allows Start Live while screenBusy is true, a failed start can invalidate a pending picker and leave screenBusy permanently true, preventing the user from choosing a screen again.
Technical details
# Clear the stale picker busy state after startup cancellation
## Affected sites
- `renderer/components/assistant/use-assistant-live.ts:1212` — start failure invalidates a pending picker through `releaseDisplayAuthority()`.
- `renderer/components/assistant/use-assistant-live.ts:929-930` — the superseded picker skips `setScreenBusy(false)` after its generation changes.
- `renderer/components/assistant/assistant-live.tsx:129` — the Start control is not gated by `screenBusy`.
## Required outcome
- Any path that cancels or supersedes the only pending screen picker must eventually clear `screenBusy` without allowing an older picker to clear a newer operation's busy state.
- Add a regression that starts a picker, starts Live, forces start failure, settles the picker, and verifies another source choice is accepted.
Summary
Validation
npm run type-checknpm run lintnpm run buildnpm run test:gemini-live(179 Live + 48 Computer Use)npm testRelease coordination
The original 0.41.4 release run was cancelled before publication after Pullfrog reported these issues. Merge this exact head, then restart the notarized 0.41.4 release from corrected
main.Closes the unresolved Pullfrog findings on #134.