Store-readiness release: fixes from a Chrome Web Store-style review — permission minimization, a hardened page↔extension bridge, and four real extension-lifecycle bugs the happy path had been hiding.
- Removed the unusedthe extension never needed it (every
tabspermissionchrome.tabs.*call ridesactiveTabor host permissions), and it added a "Read your browsing history" install warning for nothing. - Page→extension bridge is now allowlistedpage scripts can only relay the six
tb:rec:*recording verbs; previously a page could relay arbitrary message types (includingCAPTURE_SCREENSHOT, reading the tab's pixels back without a consent prompt). - it was broadcast via
tb:rec:startednow actually reaches the pageruntime.sendMessage, which never delivers to content scripts, so the HUD-mount fallback, the mic-missing toast, and the slow-picker recovery (2-min cap + DOM replay re-arm) were dead code end-to-end. Background now fans it out per-tab like the auto-stop broadcast. - Service-worker hydration racea mutating event that *woke* the worker (tab close, toolbar ✕, auto-stop) could persist blank state over every tab's saved state, and the in-flight hydration read could then resurrect the stale snapshot. All mutating paths now await hydration, and a dirty flag makes fresh writes win.
- Firefox recorder-window id survives event-page restartspreviously a restart mid-recording meant closing the popup never ended the recording on-page, passive probes reported "not recording", and the next start opened a second window.
- The recorder host is closed after every recording on both browsersChrome's offscreen document (exempt from auto-teardown) used to hold the full base64 recording in memory until browser close; recovery is served from
chrome.storage.localinstead. - declared — Chrome ≤108 used to install the extension and silently fail to record.
minimum_chrome_version: 116