Skip to content

fix(agent): support Chromium 137 side panel APIs - #2245

Open
Felarof (felarof99) wants to merge 1 commit into
mainfrom
feat/ext-on-137
Open

fix(agent): support Chromium 137 side panel APIs#2245
Felarof (felarof99) wants to merge 1 commit into
mainfrom
feat/ext-on-137

Conversation

@felarof99

Copy link
Copy Markdown
Contributor

Summary

  • feature-detect BrowserOS-only side panel lifecycle and action APIs absent from Chromium 137
  • fall back to standard chrome.sidePanel.open for tab open/toggle behavior
  • preserve known-open window state when Chromium lacks sidePanel.close
  • add mutation-killing tests for each partial API shape

Design

The compatibility boundary remains in toggleSidePanel.ts. Newer BrowserOS builds retain the richer browserosIsOpen, browserosToggle, close, onOpened, and onClosed paths. Chromium 137 uses only its standard supported API surface.

Test plan

  • 18 focused side-panel tests
  • root lint
  • root typecheck
  • full test suite
  • WXT development extension build
  • audited all 32 direct extension API calls against Chromium 137 schemas
  • live headed Chrome 137.0.7187.69 service worker remains alive with all five guarded side-panel members undefined
  • app.html#/home mounts with no JavaScript exceptions
  • headless Chromium 137 camera capture of the same bundle: /Users/felarof01/Workspaces/build/CHROME/nightwork/shots/ext-on-137.png

Root Fallow remains baseline-red on 320 pre-existing repository findings; none references the changed files.

@felarof99

Copy link
Copy Markdown
Contributor Author

Greptile (@greptileai) review

@felarof99

Copy link
Copy Markdown
Contributor Author

Claude (@claude) review

@github-actions github-actions Bot added the fix label Aug 13, 2026
@claude

claude Bot commented Aug 13, 2026

Copy link
Copy Markdown

Claude finished Felarof (@felarof99)'s task in 2m 32s —— View job


Review: Chromium 137 side panel API fallback

Tasks

  • Gather context (diff, changed files, CLAUDE.md)
  • Understand the request (@claude review)
  • Review toggleSidePanel.ts changes
  • Review new/updated tests
  • Post review feedback

Summary

The compatibility boundary is cleanly contained to toggleSidePanel.ts — no other file touches browserosToggle/browserosIsOpen/sidePanel.close/onOpened/onClosed directly, so the feature-detection logic can't be bypassed elsewhere. I traced each guarded branch against the new tests:

  • openTabSidePanel (toggleSidePanel.ts:126-141): falls back to chrome.sidePanel.open({ tabId }) when either browserosIsOpen or browserosToggle is missing — covered by the "falls back... BrowserOS tab open APIs are unavailable" test (deletes browserosIsOpen).
  • toggleTabSidePanel (:143-151): falls back when browserosToggle is missing — covered.
  • toggleWindowSidePanel (:163-175): when sidePanel.close is missing, preserves the "open" state instead of erroring — covered by "keeps an open window panel open when Chromium cannot close it".
  • registerSidePanelOpenStateListeners (:178-193): onOpened?.addListener / onClosed?.addListener correctly no-op when either event is absent — covered by both .no-on-opened and .no-on-closed test files.

Logic is sound and matches the PR's stated design (graceful degradation to standard Chrome APIs, best-effort state preservation when Chromium can't close programmatically).

Minor findings

  1. Test coverage gap in openTabSidePanel's OR condition (toggleSidePanel.ts:129-132). The guard is:

    if (
      typeof chrome.sidePanel.browserosIsOpen !== 'function' ||
      typeof chrome.sidePanel.browserosToggle !== 'function'
    )

    Existing tests delete browserosIsOpen (exercising the first operand) and separately delete browserosToggle only for toggleTabSidePanel's single-condition guard — but no test deletes only browserosToggle while calling openSidePanel/openTabSidePanel with browserosIsOpen still present. That leaves the ||&& mutant on this specific line unkilled: if only browserosToggle is missing, the mutated && version would skip the fallback, call browserosIsOpen successfully, then throw calling undefined browserosToggle. Given the PR explicitly calls out "mutation-killing tests for each partial API shape," this one partial shape (browserosToggle absent, browserosIsOpen present, via openSidePanel) looks like the one gap. Low real-world risk since BrowserOS ships both APIs together, but easy to close with one more test case mirroring the existing "falls back... tab toggle is unavailable" test but calling openSidePanel instead of toggleSidePanel.

  2. Ambient types still declare these as always-present (chrome-browser-os.d.ts:70-88): browserosToggle, browserosIsOpen, close, and onClosed are typed as non-optional, so the new typeof x !== 'function' runtime guards aren't reflected in the type system. Not a functional bug (feature-detection via typeof works regardless of the declared type), but it means TypeScript can't warn a future caller who accesses these members without the guard. Worth considering marking them optional (browserosToggle?: etc.) if/when convenient, purely for defense-in-depth — not blocking.

Nothing else stood out — fallback behavior, state caching, and the ?. guards for onOpened/onClosed all look correct and are well covered by the new focused tests.

Note: I wasn't able to execute bun run check/bun run test in this sandbox (network/shell command approval unavailable), so this review is based on static tracing of the diff against the test file's assertions rather than a live test run. The PR description states the full suite, lint, and typecheck were already run locally.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Tests passed: 294/294

Ran 1 of 15 suites (14 not affected by this change).

Suite Passed Failed Skipped
server-agent n/a n/a not affected
server-api n/a n/a not affected
server-tools n/a n/a not affected
server-browser n/a n/a not affected
server-integration n/a n/a not affected
server-lib n/a n/a not affected
server-root n/a n/a not affected
agent 294/294 0 0
claw-app n/a n/a not affected
claw-onboard n/a n/a not affected
build n/a n/a not affected
release n/a n/a not affected
claw-server-rust n/a n/a not affected
claw-server-rust-quality n/a n/a not affected
claw-mcp n/a n/a not affected

View workflow run

@greptile-apps

greptile-apps Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR feature-detects BrowserOS-specific side-panel APIs so the extension can run against Chromium 137, falling back to the standard open operation and independently registering available lifecycle listeners.

  • Adds guarded tab open/toggle behavior for partial side-panel API surfaces.
  • Avoids calling unsupported window-close and lifecycle APIs.
  • Adds focused tests for missing action and event APIs.

Confidence Score: 4/5

The stale window-open cache should be fixed before merging because it can prevent users from reopening a manually dismissed side panel on Chromium’s reduced API surface.

The compatibility branch suppresses sidePanel.open based on state that cannot be invalidated after a manual dismissal when onClosed is unavailable, leaving the toolbar action unable to restore the panel.

Files Needing Attention: packages/browseros-agent/apps/app/lib/browseros/toggleSidePanel.ts

Important Files Changed

Filename Overview
packages/browseros-agent/apps/app/lib/browseros/toggleSidePanel.ts Adds API feature detection and standard fallbacks, but the missing-close path can strand stale window-open state after manual dismissal.
packages/browseros-agent/apps/app/lib/browseros/toggleSidePanel.test.ts Adds focused fallback coverage, including the intended preservation of cached open state when close is unavailable, but does not cover manual dismissal followed by reopening.
packages/browseros-agent/apps/app/lib/browseros/toggleSidePanel.no-on-closed.test.ts Verifies that onOpened registration remains independent when onClosed is absent.
packages/browseros-agent/apps/app/lib/browseros/toggleSidePanel.no-on-opened.test.ts Verifies that onClosed registration remains independent when onOpened is absent.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Click[Toolbar click] --> Scope{Window-scoped?}
  Scope -- No --> TabAPI{browserosToggle available?}
  TabAPI -- Yes --> NativeToggle[browserosToggle]
  TabAPI -- No --> StandardOpen[sidePanel.open by tab]
  Scope -- Yes --> Cached{Window ID cached open?}
  Cached -- No --> WindowOpen[sidePanel.open by window and cache ID]
  Cached -- Yes --> CloseAPI{sidePanel.close available?}
  CloseAPI -- Yes --> WindowClose[Close panel and clear ID]
  CloseAPI -- No --> Preserve[Return opened true]
  ManualClose[User manually dismisses panel] --> MissingEvent{onClosed available?}
  MissingEvent -- No --> Stale[Cached ID remains stale]
  Stale --> Cached
Loading
Prompt To Fix All With AI
### Issue 1
packages/browseros-agent/apps/app/lib/browseros/toggleSidePanel.ts:166-169
**Stale window-open state blocks reopening**

When a window-scoped panel is manually dismissed on Chromium without `sidePanel.close` and `sidePanel.onClosed`, its cached window ID cannot be cleared. The next toolbar click takes this branch and returns `{ opened: true }` without calling `sidePanel.open`, leaving the panel closed for that window.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(agent): support Chromium 137 side pa..." | Re-trigger Greptile

Comment on lines 166 to +169
if (openWindowSidePanelIds.has(target.windowId)) {
if (typeof chrome.sidePanel.close !== 'function') {
return { opened: true }
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Stale window-open state blocks reopening

When a window-scoped panel is manually dismissed on Chromium without sidePanel.close and sidePanel.onClosed, its cached window ID cannot be cleared. The next toolbar click takes this branch and returns { opened: true } without calling sidePanel.open, leaving the panel closed for that window.

Knowledge Base Used: Extension App (packages/browseros-agent/apps/app)

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/browseros-agent/apps/app/lib/browseros/toggleSidePanel.ts
Line: 166-169

Comment:
**Stale window-open state blocks reopening**

When a window-scoped panel is manually dismissed on Chromium without `sidePanel.close` and `sidePanel.onClosed`, its cached window ID cannot be cleared. The next toolbar click takes this branch and returns `{ opened: true }` without calling `sidePanel.open`, leaving the panel closed for that window.

**Knowledge Base Used:** [Extension App (packages/browseros-agent/apps/app)](https://app.greptile.com/browseros-org-2/-/custom-context/knowledge-base/browseros-ai/browseros/-/docs/extension-app.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant