Skip to content

feat: improve extensions support#250

Merged
iamEvanYT merged 17 commits intomainfrom
evan/improve-extensions-support
Apr 5, 2026
Merged

feat: improve extensions support#250
iamEvanYT merged 17 commits intomainfrom
evan/improve-extensions-support

Conversation

@iamEvanYT
Copy link
Copy Markdown
Member

@iamEvanYT iamEvanYT commented Apr 5, 2026

  • Fixed several glitchy extensions, including Bitwarden & Proton Pass
  • Fixed extension pages favicons not loading
  • Bump Extension Packages
  • Fixed Service Workers of extensions sometimes not loading
  • Added Chrome Validation Headers to prevent disruptive banner from showing on Extension Store
  • Dispatch chrome.runtime.onInstalled to extensions for installation setup
  • Removed deprecated electron extension methods from being used

fixes #101

Summary by CodeRabbit

  • Chores

    • Updated extension and web-store integration dependencies.
  • Improvements

    • More reliable extension installation and startup, with better handling of failures.
    • Improved loading and serving of extension assets (including favicons).
    • Requests to some Chrome services now include enhanced browser-validation headers.
    • Better manifest localization and normalized extension metadata for display.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 5, 2026

Build artifacts for all platforms are ready! 🚀

Download the artifacts for:

One-line installer (Unstable):
bunx flow-debug-build@1.2.1 --open 24008846717

(execution 24008846717 / attempt 1)

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 5, 2026

Walkthrough

Refactors extension handling and user-agent interception: updates dependencies, delegates CRX handling to the electron-chrome-extensions library, adds extension asset loading and service-worker startup helpers, changes user-agent transformer to return browser-header flags, and adjusts tab/favicons flows to use new extension APIs.

Changes

Cohort / File(s) Summary
Dependency Updates
package.json
Bumped electron-chrome-extensions to 4.9.4 and electron-chrome-web-store to 0.13.3.
Loaded Profiles & Tabs
src/main/controllers/loaded-profiles-controller/index.ts, src/main/controllers/tabs-controller/tab.ts
Made tab creation sequential (awaited), reworked afterInstall to persist and initialize extensions with startSWPromise, dispatch runtime “installed” event; replaced direct extensions.tabUpdated call with "tab-updated" webContents event.
User-Agent / Interceptor
src/main/controllers/sessions-controller/intercept-rules/user-agent-transformer.ts, src/main/modules/user-agent.ts
transformUserAgentHeader now returns { userAgent, includeChromeBrowserHeaders }; interceptor injects x-browser-* headers when flagged; added helper to generate those headers.
Chrome Validation
src/main/modules/chrome.ts
New module: platform API keys and generateChromeValidationHeader(userAgent, apiKey?) producing SHA-1-based Base64 validation header.
Extension Assets & Locales
src/main/modules/extensions/assets.ts, src/main/modules/extensions/locales.ts
Added getExtensionAsset(...) with path sanitization, containment checks, web_accessible_resources enforcement; added translateManifestString(...) to resolve __MSG_*__ manifest placeholders.
Extension Service Worker Startup
src/main/modules/extensions/helpers.ts, src/main/modules/extensions/management.ts
Added startExtensionServiceWorker(session, extension) with retry loop; replaced inline MV3 service worker startup with delegated startup returning a startSWPromise; exposed initializeLoadedExtension.
CRX Protocol Integration
src/main/modules/extensions/main.ts
Removed custom protocol handler; registered partitionSessionResolver via setSessionPartitionResolver and delegated CRX handling to ElectronChromeExtensions.handleCRXProtocol(session.defaultSession).
IPC / Favicon
src/main/ipc/app/extensions.ts, src/main/controllers/sessions-controller/protocols/.../active-favicon.ts
Replaced local manifest translation with translateManifestString import; favicon fetch now handles chrome-extension:// URLs by resolving assets via getExtensionAsset.

Sequence Diagram(s)

sequenceDiagram
  participant LoadedProfiles as LoadedProfilesController
  participant ExtensionsMgr as ExtensionManager
  participant ExtModule as extensions module
  participant Session as Electron.Session
  participant FS as Filesystem

  LoadedProfiles->>ExtensionsMgr: persist installed extension
  ExtensionsMgr->>ExtModule: initializeLoadedExtension(extension)
  ExtModule->>Session: session.extensions.getExtension(id)
  ExtModule->>Session: startExtensionServiceWorker(scope) (startSWPromise)
  note right of Session: attempts to start service worker\n(retries internally)
  ExtModule->>FS: resolve & read manifest/icons when needed (getExtensionAsset)
  ExtModule-->>ExtensionsMgr: return { startSWPromise }
  ExtensionsMgr-->>LoadedProfiles: dispatch runtime "installed" event after startSWPromise resolves
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰
I hopped through manifests, keys, and streams,
I fetched the assets and chased the dreams,
A service worker took a leap,
Headers whispered secrets deep,
Extensions bloom — the rabbit beams!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: improve extensions support' directly summarizes the main objective: improving extension functionality across multiple areas (Bitwarden/Proton Pass fixes, favicon loading, service workers, validation headers, onInstalled events).
Linked Issues check ✅ Passed The PR addresses issue #101 by fixing extension functionality including context menu behavior, service worker initialization, and proper event dispatching for extension setup.
Out of Scope Changes check ✅ Passed All changes are directly related to improving extension support: dependency updates, CRX protocol handling refactoring, extension asset loading, service worker initialization, Chrome validation headers, manifest translation, and user-agent header transformation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch evan/improve-extensions-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 5, 2026

Greptile Summary

This PR improves extension support in the Flow browser by upgrading electron-chrome-extensions (4.7.5 → 4.9.4) and electron-chrome-web-store (0.11.2 → 0.13.3), removing deprecated Electron extension APIs, and introducing several complementary features: a retry loop for MV3 service worker startup, Chrome validation headers for the Web Store, chrome.runtime.onInstalled dispatch on install, and proper handling of chrome-extension:// favicons.

Key changes:

  • extensions/main.ts: Removes the manual crx: protocol handler and replaces setPartitionSessionGrabber with the new setSessionPartitionResolver + ElectronChromeExtensions.handleCRXProtocol API.
  • extensions/helpers.ts (new): Implements a bounded retry loop (up to ~600 attempts over 10 s) to start MV3 service workers, fixing intermittent extension startup failures.
  • extensions/management.ts: _afterLoadExtension is now public so loaded-profiles-controller can await the service-worker promise before dispatching onInstalled.
  • chrome.ts (new): Generates Chrome's x-browser-validation HMAC-SHA1 header using platform-specific API keys.
  • user-agent-transformer.ts / user-agent.ts: Injects Chrome browser identification headers (x-browser-*) for requests to chromewebstore.google.com, suppressing the disruptive "not Chrome" banner.
  • active-favicon.ts: Falls back to reading extension assets directly when session.fetch() cannot resolve chrome-extension:// favicon URLs.
  • locales.ts: Adds translateManifestString to resolve __MSG_key__ placeholders in manifest strings.

Issues found:

  • generateChromeValidationHeader throws an unguarded Error for unrecognised OS strings, which can crash request handling when visiting the Chrome Web Store.
  • x-browser-validation is set twice in user-agent-transformer.ts (once inside generateBrowserClientHeaders, once explicitly), resulting in redundant work.
  • translateManifestString has a mixed string | Promise<string> return type; making it consistently async would clarify intent.
  • _afterLoadExtension is now public despite its underscore-private naming convention."

Confidence Score: 4/5

Mostly safe to merge; one P1 issue (unguarded throw in Chrome validation header generation) could break Chrome Web Store access on non-standard platforms or after aggressive UA stripping.

The P1 finding in chrome.ts means a missing OS match in the user agent throws synchronously inside a web-request interceptor, which would prevent the Chrome Web Store from loading rather than gracefully degrading. All other findings are P2 style or cleanup items that do not block merge.

src/main/modules/chrome.ts (unguarded throw) and src/main/controllers/sessions-controller/intercept-rules/user-agent-transformer.ts (duplicate header).

Important Files Changed

Filename Overview
src/main/modules/chrome.ts New file generating Chrome's x-browser-validation header; throws on unrecognised OS instead of gracefully degrading
src/main/controllers/sessions-controller/intercept-rules/user-agent-transformer.ts Injects Chrome browser headers for Web Store requests; x-browser-validation is redundantly set twice
src/main/modules/extensions/helpers.ts New bounded retry loop (~600 attempts / 10 s) for MV3 service worker startup; logic is sound
src/main/modules/extensions/management.ts _afterLoadExtension changed to public (underscore convention mismatch); service worker startup delegated to helpers.ts
src/main/modules/extensions/main.ts Removes deprecated manual crx: protocol handler; uses new ElectronChromeExtensions.handleCRXProtocol API cleanly
src/main/modules/extensions/locales.ts New translateManifestString helper has mixed string
src/main/controllers/loaded-profiles-controller/index.ts Wires service worker await + dispatchRuntimeInstalled on install; translateManifestString correctly called with await
src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts Handles chrome-extension:// favicon URLs by reading extension assets directly; deduplication and caching logic is correct
src/main/modules/user-agent.ts Adds chromewebstore.google.com detection to strip app UA and set includeChromeBrowserHeaders flag
src/main/modules/extensions/assets.ts No functional changes; isWebAccessibleForOrigin correctly grants same-extension-origin access for favicons

Sequence Diagram

sequenceDiagram
    participant CWS as Chrome Web Store
    participant UAT as UserAgentTransformer
    participant Chrome as chrome.ts
    participant ECE as ElectronChromeExtensions
    participant SW as ServiceWorkers
    participant ECW as electron-chrome-web-store

    Note over ECE: App ready
    ECE->>ECE: handleCRXProtocol(defaultSession)

    CWS->>UAT: onBeforeSendHeaders (chromewebstore.google.com)
    UAT->>Chrome: generateChromeValidationHeader(ua)
    Chrome-->>UAT: x-browser-validation hash
    UAT-->>CWS: inject x-browser-* headers

    ECW->>ECW: afterInstall(details)
    ECW->>SW: startExtensionServiceWorker() [retry up to 600x]
    SW-->>ECW: success
    ECW->>ECE: dispatchRuntimeInstalled(extensionId, install)
Loading

Reviews (1): Last reviewed commit: "chore: bump extension packages" | Re-trigger Greptile

Comment thread src/main/modules/chrome.ts Outdated
Comment thread src/main/modules/extensions/management.ts Outdated
Comment thread src/main/modules/extensions/locales.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/controllers/loaded-profiles-controller/index.ts (1)

186-196: 🧹 Nitpick | 🔵 Trivial

Prefer const tab = await ... over mixing await with .then().

The current pattern works but is less idiomatic. Consider separating the await and the callback for clarity.

Suggested refactor
           for (const url of urls) {
             const currentTabIndex = tabIndex;
 
-            await tabsController.createTab(window.id, profileId, undefined, undefined, { url }).then((tab) => {
-              if (currentTabIndex === 0) {
-                tabsController.activateTab(tab);
-              }
-            });
+            const tab = await tabsController.createTab(window.id, profileId, undefined, undefined, { url });
+            if (currentTabIndex === 0) {
+              tabsController.activateTab(tab);
+            }
 
             tabIndex++;
           }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/controllers/loaded-profiles-controller/index.ts` around lines 186 -
196, Replace the mixed await/.then pattern in the loop by awaiting the promise
directly: call tabsController.createTab(...) with await into a const (e.g.,
const tab = await tabsController.createTab(window.id, profileId, undefined,
undefined, { url })), then run the activation logic (if (currentTabIndex === 0)
tabsController.activateTab(tab)); keep the currentTabIndex const and tabIndex++
logic intact and remove the .then() callback to improve clarity.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/main/controllers/sessions-controller/intercept-rules/user-agent-transformer.ts`:
- Around line 36-47: The x-browser-validation header is being assigned twice:
once when spreading the result of generateBrowserClientHeaders(newValue) into
newHeaders and again explicitly via generateChromeValidationHeader(newValue);
remove the redundant explicit assignment. In the block gated by
includeChromeBrowserHeaders, keep the loop that merges
generateBrowserClientHeaders(newValue) into newHeaders and delete the separate
call that computes and sets newHeaders["x-browser-validation"] =
validationHeader (you may also remove the const validationHeader assignment).
Ensure updated = true remains.

In `@src/main/modules/chrome.ts`:
- Around line 18-29: The code in chrome.ts that maps userAgent -> apiKey (using
PLATFORM_API_KEYS and the local apiKey variable) must not throw on unknown UAs;
change the branch that currently throws ("Unknown OS in user agent. Supply
apiKey manually.") to instead return a null/undefined apiKey (or simply leave
apiKey unset) so header generation is best-effort. Update
setupUserAgentTransformer() callers (specifically the user-agent transformer in
sessions-controller/intercept-rules/user-agent-transformer.ts) to only set the
x-browser-validation header when the transformer returns a non-null value.
Ensure no exception is thrown from the request-header generation path and that
x-browser-validation is added conditionally.

In `@src/main/modules/extensions/assets.ts`:
- Around line 71-78: matchesWildcardPattern can exhibit ReDoS risks with many
wildcards; update it to mitigate by collapsing consecutive '*' into a single '*'
(normalize pattern), enforce a safe maximum pattern length and a max number of
wildcards (e.g., reject or return false when limits exceeded), then call
escapePattern and build the RegExp as before; reference matchesWildcardPattern
and escapePattern when locating the code and add configurable constants like
MAX_PATTERN_LENGTH and MAX_WILDCARDS to centralize limits.

In `@src/main/modules/extensions/helpers.ts`:
- Around line 7-12: The scope string for starting the service worker is missing
a trailing slash so startWorkerForScope() won't match; update the scope
construction (where scope is defined from extensionId in the block that checks
extension.manifest.manifest_version === 3 &&
extension.manifest.background?.service_worker) to include a trailing slash
(i.e., chrome-extension://${extensionId}/) before calling
session.serviceWorkers.startWorkerForScope(scope) so the retry loop can
successfully find the scope.

In `@src/main/modules/extensions/locales.ts`:
- Around line 115-121: The function translateManifestString currently returns a
plain string for non-__MSG_ values and a Promise<string> when using
transformStringToLocale, producing a string | Promise<string> API; make
translateManifestString consistently async by declaring it async and always
returning a Promise<string> (i.e., await or return the result of
transformStringToLocale for the __MSG_ path and wrap the plain string in a
resolved Promise for the non-match path), updating the function signature and
callers as needed; locate translateManifestString and transformStringToLocale to
implement this change.

In `@src/main/modules/extensions/management.ts`:
- Around line 308-310: The code calls _afterLoadExtension(...) which now returns
an object containing startSWPromise but currently ignores it, causing
loadExtensionWithData to resolve before the MV3 service worker is running;
modify both branches in loadExtensionWithData (the branch using
session.extensions.getExtension(extensionId) and the branch that creates/loads a
new extension) to capture the returned { startSWPromise } from
this._afterLoadExtension(loadedExtensionOrNew) and await startSWPromise before
returning so the method only resolves once the service-worker startup completes.

---

Outside diff comments:
In `@src/main/controllers/loaded-profiles-controller/index.ts`:
- Around line 186-196: Replace the mixed await/.then pattern in the loop by
awaiting the promise directly: call tabsController.createTab(...) with await
into a const (e.g., const tab = await tabsController.createTab(window.id,
profileId, undefined, undefined, { url })), then run the activation logic (if
(currentTabIndex === 0) tabsController.activateTab(tab)); keep the
currentTabIndex const and tabIndex++ logic intact and remove the .then()
callback to improve clarity.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2edc4082-6b41-4e6f-b09c-bb2d4d4e0e93

📥 Commits

Reviewing files that changed from the base of the PR and between cb7e97f and 7218393.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • package.json
  • src/main/controllers/loaded-profiles-controller/index.ts
  • src/main/controllers/sessions-controller/intercept-rules/user-agent-transformer.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts
  • src/main/controllers/tabs-controller/tab.ts
  • src/main/ipc/app/extensions.ts
  • src/main/modules/chrome.ts
  • src/main/modules/extensions/assets.ts
  • src/main/modules/extensions/helpers.ts
  • src/main/modules/extensions/locales.ts
  • src/main/modules/extensions/main.ts
  • src/main/modules/extensions/management.ts
  • src/main/modules/user-agent.ts

Comment thread src/main/modules/chrome.ts
Comment thread src/main/modules/extensions/assets.ts
Comment thread src/main/modules/extensions/helpers.ts
Comment thread src/main/modules/extensions/locales.ts Outdated
Comment thread src/main/modules/extensions/management.ts
@iamEvanYT iamEvanYT changed the title feat: improve-extensions-support feat: improve extensions support Apr 5, 2026
@iamEvanYT iamEvanYT added the enhancement New feature or request label Apr 5, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/main/controllers/loaded-profiles-controller/index.ts (1)

189-193: 🧹 Nitpick | 🔵 Trivial

Redundant await with .then() chain.

Using await before .then() is an antipattern. The await resolves the promise, then .then() wraps it in another promise. Simplify by using the resolved value directly:

♻️ Proposed fix
-            await tabsController.createTab(window.id, profileId, undefined, undefined, { url }).then((tab) => {
-              if (currentTabIndex === 0) {
-                tabsController.activateTab(tab);
-              }
-            });
+            const tab = await tabsController.createTab(window.id, profileId, undefined, undefined, { url });
+            if (currentTabIndex === 0) {
+              tabsController.activateTab(tab);
+            }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/controllers/loaded-profiles-controller/index.ts` around lines 189 -
193, The code uses await together with a .then() chain on
tabsController.createTab which is redundant; replace the await + .then with a
single awaited assignment: call tabsController.createTab(...) with the same args
and assign its resolved value to a const (e.g., const tab = await
tabsController.createTab(window.id, profileId, undefined, undefined, { url })),
then use the existing currentTabIndex check to call
tabsController.activateTab(tab); remove the .then() wrapper entirely while
keeping the same activation logic.
src/main/modules/extensions/management.ts (1)

314-335: ⚠️ Potential issue | 🟡 Minor

Service worker may not be ready when loadExtensionWithData resolves.

Both branches call _afterLoadExtension() but don't await the returned startSWPromise. This means the method resolves before the MV3 background service worker is running. While the comment on line 284 indicates this is intentional ("Runs asynchronously, so we don't block the main thread"), callers expecting the extension to be fully operational may encounter race conditions.

The afterInstall handler in loaded-profiles-controller correctly awaits startSWPromise, but bulk loading via loadExtensions() won't wait for service workers. If this is intentional for startup performance, consider documenting this behavior in the method's JSDoc.

📝 Proposed documentation addition
   /**
    * Load an extension with data
    * `@param` extensionId - The ID of the extension
    * `@param` extensionData - The data of the extension
    * `@returns` The loaded extension
+   * `@remarks` Service worker startup is not awaited. Use `initializeLoadedExtension`
+   *          and await `startSWPromise` if immediate SW readiness is required.
    */
   private async loadExtensionWithData(extensionId: string, extensionData: ExtensionData) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/modules/extensions/management.ts` around lines 314 - 335,
loadExtensionWithData currently calls _afterLoadExtension but does not await the
service-worker startup promise (startSWPromise), so callers can get an extension
object before the MV3 background service worker is running; either await the
startSWPromise inside _afterLoadExtension or update loadExtensionWithData to
await the service-worker startup before returning (ensure both the
"loadedExtension" and newly loaded branches wait), or if the non-blocking
behavior is intentional, add a JSDoc to loadExtensionWithData explaining that it
does not wait for startSWPromise and callers that need a running service worker
must await startSWPromise themselves (reference methods: loadExtensionWithData,
_afterLoadExtension, startSWPromise, and callers like loadExtensions and
afterInstall).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/controllers/loaded-profiles-controller/index.ts`:
- Around line 300-354: The getAllExtensions handler currently reads
manifest.options_url which may be absent for Manifest V3; update
getAllExtensions to prefer manifest.options_url but fall back to
manifest.options_page and then manifest.options_ui (or options_ui.page when
applicable) when building the optionsUrl field so extensions using
options_page/options_ui are supported; locate the optionsUrl assignment in the
returned object inside getAllExtensions and modify it to check
manifest.options_url || manifest.options_page || (manifest.options_ui &&
manifest.options_ui.page) (preserving existing translateManifestString usage
where needed).

In `@src/main/modules/extensions/assets.ts`:
- Around line 177-187: There is a TOCTOU risk between getFsStat ->
isPathInsideRoot -> fs.readFile on resolvedAssetPath; to fix, open the file
first (using fs.open with O_NOFOLLOW if available) and perform your
stat/containment checks against the open file descriptor or its realpath, then
read from the handle instead of calling fs.readFile after the checks; update the
logic around getFsStat, isPathInsideRoot and the final fs.readFile usage (and
handle errors from fs.open) so the containment and file-type checks are done on
the opened file to eliminate the check-then-use window.

---

Outside diff comments:
In `@src/main/controllers/loaded-profiles-controller/index.ts`:
- Around line 189-193: The code uses await together with a .then() chain on
tabsController.createTab which is redundant; replace the await + .then with a
single awaited assignment: call tabsController.createTab(...) with the same args
and assign its resolved value to a const (e.g., const tab = await
tabsController.createTab(window.id, profileId, undefined, undefined, { url })),
then use the existing currentTabIndex check to call
tabsController.activateTab(tab); remove the .then() wrapper entirely while
keeping the same activation logic.

In `@src/main/modules/extensions/management.ts`:
- Around line 314-335: loadExtensionWithData currently calls _afterLoadExtension
but does not await the service-worker startup promise (startSWPromise), so
callers can get an extension object before the MV3 background service worker is
running; either await the startSWPromise inside _afterLoadExtension or update
loadExtensionWithData to await the service-worker startup before returning
(ensure both the "loadedExtension" and newly loaded branches wait), or if the
non-blocking behavior is intentional, add a JSDoc to loadExtensionWithData
explaining that it does not wait for startSWPromise and callers that need a
running service worker must await startSWPromise themselves (reference methods:
loadExtensionWithData, _afterLoadExtension, startSWPromise, and callers like
loadExtensions and afterInstall).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 353eedaf-ffe7-4195-9ed1-2f2d1de7dadd

📥 Commits

Reviewing files that changed from the base of the PR and between 7218393 and affc4a2.

📒 Files selected for processing (6)
  • src/main/controllers/loaded-profiles-controller/index.ts
  • src/main/controllers/sessions-controller/intercept-rules/user-agent-transformer.ts
  • src/main/modules/chrome.ts
  • src/main/modules/extensions/assets.ts
  • src/main/modules/extensions/locales.ts
  • src/main/modules/extensions/management.ts

Comment thread src/main/controllers/loaded-profiles-controller/index.ts
Comment thread src/main/modules/extensions/assets.ts
@iamEvanYT iamEvanYT merged commit ed1330f into main Apr 5, 2026
12 checks passed
@iamEvanYT iamEvanYT deleted the evan/improve-extensions-support branch April 5, 2026 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bitwarden extension does not work as expected

1 participant