fix(settings): re-render Extensions section once chrome extensions finish loading
Settings → Extensions stopped showing per-extension Settings/Popup
buttons (third regression — previously fixed 2026-04-23 and
2026-04-17).
Root cause is a load-order race: renderPrivacySettings() runs once at
Settings page load, but loadEnabledChromeExtensions() in
backend/electron/entry.ts is async and fire-and-forget. If the
Settings window opens before extensions finish loading, the
loadedExtensions Map is empty, getChromeExtensionUiEntries() returns
[], and no buttons render. The Features pane already had a
feature:all-loaded refresh signal; the Extensions pane had nothing
equivalent.
Fix:
- backend/electron/entry.ts publishes a chrome-extensions:loaded
pubsub event after loadEnabledChromeExtensions() completes.
- app/settings/settings.js subscribes once, clears the Privacy section
contents, and re-appends the freshly-rendered tree on receipt.
Refactor for testability:
- Extracted computeUiEntries() into chrome-extensions-helpers.ts as a
pure dependency-injected function (UiEntryManifest /
UiEntryDiscovered / UiEntryLoaded / ComputedUiEntry types). The
Electron-coupled getChromeExtensionUiEntries() in
chrome-extensions.ts delegates to it.
- New chrome-extensions-ui-entries.test.ts: 12 unit tests across
empty-state, MV3 (action + options_ui), MV2 (browser_action +
options_page), and extensionId key-matching. The key regression
guard asserts exactly 2 openable entries for the proton-pass
fixture — if this drops to 0, Settings → Extensions buttons are
missing again, and the test fails immediately instead of after a
release.