Skip to content

Fix browser multi-tab controls and menu occlusion#119

Merged
yaacovcorcos merged 18 commits into
mainfrom
agent/browser-multitab-ui-reliability
Jul 24, 2026
Merged

Fix browser multi-tab controls and menu occlusion#119
yaacovcorcos merged 18 commits into
mainfrom
agent/browser-multitab-ui-reliability

Conversation

@yaacovcorcos

@yaacovcorcos yaacovcorcos commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a dedicated, always-visible New browser tab control and serialize rapid/deferred tab creation so sleeping panes wake once without dropped or duplicate tabs
  • keep renderer-adopted browser sessions alive under transient overlays: the guest is CSS-occluded and bounds IPC is suppressed, while real pane hide/zero-size/local-home states still send null bounds and retain the existing suspend lifecycle
  • cover app menus, dialogs, sheets, selects, comboboxes, autocomplete, popovers, previews, tooltips, toasts/Undo, and recent-view overlays through the shared overlay marker; sheet ownership prevents a Browser panel from treating its own backdrop as an external obstruction
  • make tab interaction predictable and accessible: tablist/tab semantics, roving focus, Arrow/Home/End/Delete controls, adjacent-tab selection after close, and focus recovery without stealing focus from a newer interaction
  • keep Browser a singleton dock pane and remove already-open singleton kinds from Add panel, while the Browser panel's own plus creates additional browser tabs
  • add a real Electron regression that adopts an actual renderer <webview>, holds an overlay for 31.25 seconds, and proves the same web contents/tab session survives without null bounds or a suspend timer before geometry recovers
  • make that Electron proof hermetic across success, failure, timeout, and interruption: isolated profile/session paths, bounded process-tree cleanup, dynamic Electron sandbox resolution, a disposable macOS app identity, and deterministic earliest-setup signal cleanup

Root causes

The native tab model and IPC already supported multiple tabs, but the renderer's visible creation path was ambiguous and could drop or race requests while a deferred pane woke. The dock header plus means Add panel; because Browser is a singleton, choosing Browser there only focused the existing pane.

For overlays, the renderer sent null bounds whenever the guest was visually obscured. Native main correctly interpreted null as an actual hide, started its suspend timer, and destroyed the adopted runtime after 30 seconds. The renderer's attach key then suppressed re-adoption, leaving a dead/frozen Browser panel. Transient visual occlusion is now distinct from lifecycle hide.

Validation

Exact head: 0dbdb174ae7c87d60b7901200d63ce324d03fb97 on origin/main fffd9e7797b8df34d19ac2bb4439740fb29f11f6. This merge head composes reviewed #119 fe51e9fef01be5f5364d21f414ecc244d53b87af with merged #112 without conflict-resolution hunks.

  • bun run fmt:check
  • bun run lint — 0 errors; 217 existing repository warnings
  • bun run typecheck — 9/9 tasks
  • bun run test — 12/12 tasks; web 3,037/3,037; server/CLI 2,178 passed with 7 platform skips; deterministic early-interruption regression included
  • bun run --cwd apps/web test:browser:stable
    • keybindings: 3 passed
    • chat view: 62 passed, 11 skipped
    • event router: 10 passed
    • remaining: 225 passed, 1 skipped
  • browser geometry suite: 12 passed
  • focused Browser accessibility/focus/overlay suite: 28 passed
  • dock logic: 29 passed
  • desktop browser-manager reliability: 4 passed
  • Electron sandbox policy: 11 passed
  • bun run build:desktop — 5/5 tasks
  • bun run test:desktop-browser-overlay-lifecycle
    • held occluded: 31,250 ms
    • same adopted web contents and active tab
    • open mode suppress, close mode send
    • no null bounds or suspend timer
    • recovered width: 700 px
    • temporary profile, app clone, probe, and saved-state paths removed
  • earliest-setup SIGTERM regression: 1/1; handler acknowledged the signal and removed the harness directory before builds or Electron launch

Exactly three independent read-only reviews examined this exact final SHA for:

  1. correctness, reliability, concurrency, lifecycle, and performance
  2. security, privacy, data loss, cleanup/process ownership, CI privilege, and release safety
  3. architecture, maintainability, product design, accessibility, cross-platform behavior, and test proof

All three reported no actionable P0–P3 findings.

This PR is Ready for Review and no longer on hold. It remains unmerged until exact-head hosted CI is green.

@github-actions github-actions Bot added size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Jul 24, 2026
@yaacovcorcos yaacovcorcos added the on-hold Work intentionally paused; do not merge until explicitly resumed. label Jul 24, 2026
@github-actions github-actions Bot added size:XXL and removed size:L labels Jul 24, 2026
@yaacovcorcos
yaacovcorcos marked this pull request as ready for review July 24, 2026 17:07
@yaacovcorcos yaacovcorcos removed the on-hold Work intentionally paused; do not merge until explicitly resumed. label Jul 24, 2026
@yaacovcorcos
yaacovcorcos merged commit 4144022 into main Jul 24, 2026
14 of 15 checks passed
@yaacovcorcos
yaacovcorcos deleted the agent/browser-multitab-ui-reliability branch July 24, 2026 17:32
yaacovcorcos added a commit that referenced this pull request Jul 24, 2026
* Route telemetry through ScientFactory gateway (#43)

* Fix unsigned macOS release signatures (#44)

* Add consent-aware desktop analytics (#47)

* Fix Claude terminal auth and connection recovery (#52)

* fix provider status refresh invariants

* fix Claude auth recovery

* Use direct OAuth for Grok sign-in (#53)

* Use direct OAuth for Grok sign-in

* Expose safe Grok OAuth browser fallback

* Secure Scient state initialization (#48)

* Secure Scient state initialization

* Allow legacy migration state test

* fix(security): harden private state files

* test(security): lock private file boundaries

* fix(security): reject unsafe private file nodes

* Supervise the desktop backend lifecycle (#49)

* Supervise the desktop backend lifecycle

* fix(desktop): preserve backend lifecycle ownership

* fix(desktop): replace semantically unready backends

* fix(desktop): close backend lifecycle races

* Supervise desktop connection recovery (#50)

* Supervise desktop connection recovery

* Isolate provider dialog browser fixtures

* fix(desktop): bind activation readiness generation

* fix(web): enforce single-owner connection recovery

* style(web): format connection recovery

* fix(web): satisfy connection transport types

* fix(web): harden stream and terminal recovery

* fix(web): fail closed on stuck stream cancellation

* fix(web): preserve terminal recovery ordering

* fix(web): clamp reconnect jitter ceilings

* fix(desktop): preserve connection wake after restack

* Define safe RPC recovery policies (#51)

* Define safe RPC recovery policies

* test(web): cover RPC recovery integration

* fix(web): recover after uncertain mutation failures

* test(web): type RPC recovery harness precisely

* fix(web): recover a failed replay generation

* Surface connection recovery diagnostics (#55)

* Surface connection recovery diagnostics

* test(web): cover connection recovery experience

* style(web): format recovery browser coverage

* fix(web): keep recovery diagnostics current

* Recover Codex sessions after authentication loss (#56)

* fix: recover Codex sessions after auth loss

* fix(codex): gate auth recovery by provider mode

* fix: harden Codex authentication recovery

* Support Linux desktop development launch (#57)

* Secure Scient state initialization

* Allow legacy migration state test

* Supervise the desktop backend lifecycle

* Supervise desktop connection recovery

* Define safe RPC recovery policies

* Surface connection recovery diagnostics

* Support Linux desktop development launch

* Isolate provider dialog browser fixtures

* fix(desktop): fail closed on unsafe Linux sandbox

* style(desktop): format Linux launcher hardening

* fix(release): preserve AppImage sandbox

* revert(release): keep AppImage migration out of launcher hardening

* fix(desktop): honor Linux user namespace sandbox

* Fix Antigravity browser authentication (#59)

* Fix Antigravity browser authentication

* Harden Antigravity authentication lifecycle

* Close Antigravity code window deterministically

* Keep Antigravity code submission cancellable

* Scope desktop signing credentials by platform (#60)

* Fix managed Antigravity updates, authentication, and dialog UX (#62)

* Fix trusted Antigravity install and update routing

* Fix Antigravity browser authentication and models

* Refine provider connection dialog actions

* Harden managed provider update recovery

* Stabilize macOS release identity (#63)

* Reduce unintended macOS permission prompts (#64)

* Stabilize macOS release identity

* Reduce unintended macOS permission prompts

* Apply repository formatting

* Control macOS notarization lifecycle (#65)

* Add Evidence to Note as a latent built-in (#70)

* Harden bidirectional chat rendering (#71)

* feat(web): harden bidirectional chat rendering

* fix(web): close bidi review gaps

* Add Medical Exam Study built-in (#72)

* Fix YAML frontmatter in Markdown previews (#69)

* Add T3-inspired project source dialog (#76)

* Add project source dialog

* Harden project source cloning

* Add T3-style right dock surfaces (#77)

* Add T3-style right dock surfaces

* Fix right dock test formatting

* fix: remove AppSnap startup announcement (#80)

* Add artifact preview cards to chat (#81)

* fix: select providers after connection (#82)

* Add message-level conversation forks (#78)

* Add message-level conversation forks

* Stabilize hosted fork browser test

* Close message fork boundary gaps

* Close final fork review gaps

* Resolve final fork recertification blockers

* Avoid replaying completed fork bootstrap

* Harden fork lineage and restart recovery

* Stabilize cold browser geometry startup

* Repair legacy fork title families

* Preserve unrecorded fork rename boundaries

* Clear drifted fork title lineage

* Improve desktop contribution workflow (#75)

* Set default base font to 15px and fix numeric editing (#79)

* Increase default base font size to 15px

* Fix manual font size editing

* Preserve external font setting updates

* Use recommended provider model defaults (#83)

* Use recommended provider model defaults

* Apply repository formatting

* Update browser expectation for Codex default

* Preserve explicit drafts before model discovery

* Respect live provider model availability

* Align desktop approval policy (#85)

* Fix release-candidate regressions (#86)

* Fix release candidate regressions

* Fix long transcript fork validation

* fix(release): preserve Linux sandbox (#87)

* fix(release): preserve Linux sandbox

* test(release): resolve nested builder package

* test(release): follow Bun package symlinks

* fix: preserve whitespace in folder browsing (#90)

* Collapse long assistant artifact shelves (#91)

* Remove project setup confirmation card (#93)

* Build unified notification system (#96)

* Hide provider setup banner on empty chats (#94)

* Hide provider setup banner on empty chats

* Stabilize empty provider banner coverage

* Harden provider banner browser readiness

* Fix Droid model discovery lifecycle (#95)

* Add ChatGPT-first voice transcription with local Whisper fallback (#97)

* feat(voice): define transcription backend contract

* feat(voice): add verified local transcription core

* Fix ChatGPT voice account context

* feat(voice): add ChatGPT-first local Whisper fallback

* Default Git writing to GPT-5.6 Luna (#99)

* Apply updated settings defaults once (#101)

* Apply updated settings defaults once

* Enable Studio in its browser fixture

* Improve voice dictation and active-turn composer controls (#102)

* Improve voice recording controls

* Add live local voice previews

* Keep voice send locked through completion

* Keep active-turn composer actions available

* Pin Whisper runtime source revision

* Fix voice transition regressions

* Fix folder picker navigation and project opening (#98)

* Fix folder picker navigation and project opening

* Tighten project setup choices

* Prevent duplicate folder picker submissions

* Fix Whisper runtime packaging on Windows (#104)

* fix: make Whisper packaging cross-platform safe

* fix: verify signed Windows Whisper runtime

* Secure HTML artifact previews with isolated execution (#100)

* feat: add secure HTML artifact previews

* fix: enforce HTML preview ownership boundaries

* Document cross-platform manual verification

* Use trash icon for voice cancel action (#106)

* Fix browser pane close and runtime recovery (#113)

* Isolate temporary Claude discovery from MCP servers (#116)

* Respect reduced motion in thread spinner (#84)

Adapt the upstream accessibility concept while retaining Scient-owned spinner geometry.

* Harden upstream-derived release tooling (#109)

* Salvage safe PR 61 interaction improvements (#107)

* Salvage safe PR 61 interaction improvements

* Harden terminal selection copy handling

* Adapt Studio Git gating and folder access (#108)

* Adapt Studio folder controls from Synara

* Gate Studio review command on repository detection

* Improve changed-file accessibility and density (#110)

* Add compact previews for bulky changed-file cards (#117)

* Improve changed-file accessibility and density

* Add compact changed-file previews

* Ensure changed-file previews show every file

* feat: add curated in-app release notes (#112)

* feat: add curated release notes workflow

* fix: harden release note experience

* refactor: share release note footer layout

* test: keep release note diagnostics concise

* Reject developer-facing release note copy

* Revert "Reject developer-facing release note copy"

This reverts commit 1006003.

* Harden release note structural validation

* Harden release note asset validation

* Resolve release note certification findings

* Bound release note PNG chunk parsing

* Validate all release note PNG chunk CRCs

* Fix browser multi-tab controls and menu occlusion (#119)

* Fix browser multi-tab controls and menu occlusion

* Keep browser sessions alive under overlays

* Harden browser overlay lifecycle coverage

* Complete browser tab and overlay semantics

* Restore focus after final browser tab closes

* Synchronize split-pane browser focus

* Harden Electron overlay lifecycle runner

* Isolate macOS Electron test bundle state

* Keep Electron lifecycle tests fully hermetic

* Resolve Electron sandbox from workspace package

* Guarantee Electron test harness cleanup

* Register Electron fixture cleanup immediately

* Restore focus after browser close controls

* Complete browser close focus recovery

* Handle early Electron test interruptions

* Cover earliest Electron setup interruption

* Refine branch and automation workflow affordances (#111)

* Refine upstream-derived workflow affordances

* Respect resolved automation triage state

* Fix native branch clipboard acceptance

* Document native workflow UX acceptance

* Add universal local file viewer (#114)

* Add universal local file viewer

* Harden local HTML preview capabilities

* Resolve HTML preview review blockers

* Close final HTML preview review gaps

* Fail closed on truncated active HTML

* Preserve complex HTML preview dependencies

* Fail closed on SVG runtime link mutation

* Block alternate network egress in HTML previews

* Recover HTML preview network setup

* Serialize HTML preview retries

* Occlude native HTML previews under overlays

* Harden provider installation and sign-in (#103)

* Harden provider installation and sign-in

* Fix Windows provider runtime test fixtures

* Make Windows PATH test path-stable

* Close provider onboarding reliability gaps

* Keep post-install sign-in recovery on the correct path

* Canonicalize Windows runtime discovery test paths

* Harden provider device-code recovery

* Harden OpenCode and Kilo turn completion (#120)

* Harden OpenCode and Kilo turn completion

* fix(provider): isolate OpenCode turn completion ownership

* fix(provider): close OpenCode completion review races

* fix(provider): fence OpenCode reply and replay races

* fix(provider): clean interrupted OpenCode replies

* fix(provider): harden OpenCode interaction ownership

* fix(provider): fail closed on ambiguous replies

* Harden OpenCode lifecycle retirement

* Serialize OpenCode session retirement

* Make OpenCode retirement interruption safe

* Finalize confirmed OpenCode process exits

* Add native folder drop to Add Project (#115)

* feat(projects): add native folder drop intake

* fix(projects): harden folder drop feedback

* fix(projects): keep folder errors visible

* fix(projects): preserve compact folder dialog footer

* fix(projects): harden native folder intake

* docs(qa): align folder intake evidence

* fix(projects): scope folder drop to dialog

* test(projects): cover platform folder labels

* docs: correct folder drop verification evidence

* docs: qualify native drag evidence

* docs: refresh folder drop verification evidence

* docs: refresh folder drop certification evidence

* docs: recertify folder drop on latest main

* Neutralize project drops outside dialog

* Update folder drop acceptance evidence

* Make new thread workspace intent explicit (#118)

* fix(web): make new thread workspace intent explicit

* fix(web): serialize distinct new thread intents

* test(web): type exact workspace branch mocks

* fix(web): preserve new thread request ordering

* fix(web): preserve latest new thread intent

* fix(web): coordinate all new thread navigation

* fix(web): preserve latest navigation across preparation

* fix(web): close remaining navigation races

* chore: clean merged sidebar imports

* fix(web): close terminal and route ownership gaps

* fix(web): coordinate every new-thread route intent

* fix(web): enforce route ownership before history commits

* test(web): use typed routes in navigation guard proof

* fix(web): release committed navigation ownership

* docs: add Scient 0.5.13 release notes

* chore: keep promotion tree aligned with main

* chore: restore test cleanup in promotion tree

* chore: align promotion test tree
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant