You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
extension: fixes and improvements for the Chrome extension #356
Fixes and improvements from a code audit of the chrome extension, done in October 2026. Roadmap work lives in #340, #341, #342 and #343. Items marked (to confirm) were not reproduced; check them before fixing.
Problems
Medium
Only one trusted extension ID: the server trusts a single ID (packages/devtools/src/extension-origin.ts:5) and the panel pins a single origin string (extension/panel-bridge.js:21). Edge Add-ons does not keep the manifest key, so a published Edge build gets a 403 from every hub until each user adds allowedOrigins. Add the Edge ID to PANGULAR_EXTENSION_IDS once the listing exists, and generate PINNED_ORIGIN from the same list so both sides change together.
Low
Server search runs one probe at a time:findConnection awaits each fetch in turn, with a 1.5 s timeout each. With 7 candidates after dedupe, a missing or hung server shows "Detecting Angular app…" for about 10 s, plus a fixed 500 ms delay at start and 1000 ms after each navigation. Fire the probes together with Promise.allSettled and pick the first success in PATHS order, and drop the fixed delays (extension/panel-bridge.js:133-159, 219, 224).
Angular inside iframes is never found: detection, the page id lookup and $0 lookups call inspectedWindow.eval without frameURL, and the server is searched on the top frame's origin. Storybook, micro-frontend shells and embedded previews never connect. When the top frame has no Angular, find the frames and pass frameURL (extension/devtools.js:28, extension/panel-bridge.js:53-58, 72).
Worker tab map is lost when Chrome stops the worker:angularTabs lives in memory, so the fast path in devtools.js usually misses (its own comment says so), and the is-angular-page handler returns true after a synchronous sendResponse. Once the content scripts go (phase 1 of 4: safe by default and wired into your workflow #340), remove the worker; if it stays, keep the map in chrome.storage.session and drop return true (extension/background.js:2, 26, extension/devtools.js:9).
Granted hosts cannot be seen or removed: there is no options_ui and no chrome.permissions.remove call, and the privacy policy sends users to Chrome's site settings. Add a small options page, or a link in the status view, that lists granted origins outside the loopback set with a Remove button (extension/manifest.json, extension/panel-bridge.js).
Extension version is bumped by hand:extension/manifest.json and packages/devtools/package.json:3 are both 0.0.7, but nothing keeps them in sync and scripts/extension-zip.mjs does not check it. Make the zip script set or verify the manifest version from the package version.
No end-to-end test loads the real extension: the packages/devtools/src/__tests__/extension-*.test.ts tests all stub chrome.*, and ci.yml only checks that extension/ui is not stale. A manifest mistake or a Chrome API change would ship unnoticed. Add a Playwright job that runs Chromium with --load-extension=extension against the demo SSR app and checks that the panel loads ui/index.html with a pageId.
Improvements
Toolbar icon (chrome.action) that turns colored on Angular pages, with a small popup showing the Angular version, dev or prod mode and whether a Pangular server answered. Use activeTab so it adds no install warning (extension/manifest.json, new popup files).
Elements sidebar pane through chrome.devtools.panels.elements.createSidebarPane that shows the selected element's component inputs and signals (extension/devtools.js, extension/panel-bridge.js).
Keep the UI iframe across navigations: today every network.onNavigated reloads the whole panel. Only search for the server again when the origin changes, so the tab, filter and selection survive a reload (extension/panel-bridge.js:221-225, 182-190).
Remember the last base path that worked for each origin (sessionStorage in the panel) and try it first, so reconnecting is close to instant (extension/panel-bridge.js).
Standalone mode: when no Pangular server answers, read the page directly through inspectedWindow.eval and the in-page collectors, giving read-only component, signal and DI views with no server setup (extension/panel-bridge.js, app/src/extension-bridge.ts).
Audit the extension panel with axe: extend scripts/panel-axe.mjs to load extension/panel.html with a stubbed chrome object, so the status view is checked too. test:axe only audits dist/panel-axe today (package.json:19).
CI release job that runs extension:zip on tags and attaches the zip to the GitHub release, so users can load a downloaded build without cloning (.github/workflows, scripts/extension-zip.mjs).
Context
Fixes and improvements from a code audit of the chrome extension, done in October 2026. Roadmap work lives in #340, #341, #342 and #343. Items marked (to confirm) were not reproduced; check them before fixing.
Problems
Medium
packages/devtools/src/extension-origin.ts:5) and the panel pins a single origin string (extension/panel-bridge.js:21). Edge Add-ons does not keep the manifestkey, so a published Edge build gets a 403 from every hub until each user addsallowedOrigins. Add the Edge ID toPANGULAR_EXTENSION_IDSonce the listing exists, and generatePINNED_ORIGINfrom the same list so both sides change together.Low
findConnectionawaits each fetch in turn, with a 1.5 s timeout each. With 7 candidates after dedupe, a missing or hung server shows "Detecting Angular app…" for about 10 s, plus a fixed 500 ms delay at start and 1000 ms after each navigation. Fire the probes together withPromise.allSettledand pick the first success inPATHSorder, and drop the fixed delays (extension/panel-bridge.js:133-159,219,224).$0lookups callinspectedWindow.evalwithoutframeURL, and the server is searched on the top frame's origin. Storybook, micro-frontend shells and embedded previews never connect. When the top frame has no Angular, find the frames and passframeURL(extension/devtools.js:28,extension/panel-bridge.js:53-58,72).angularTabslives in memory, so the fast path indevtools.jsusually misses (its own comment says so), and theis-angular-pagehandler returnstrueafter a synchronoussendResponse. Once the content scripts go (phase 1 of 4: safe by default and wired into your workflow #340), remove the worker; if it stays, keep the map inchrome.storage.sessionand dropreturn true(extension/background.js:2,26,extension/devtools.js:9).options_uiand nochrome.permissions.removecall, and the privacy policy sends users to Chrome's site settings. Add a small options page, or a link in the status view, that lists granted origins outside the loopback set with a Remove button (extension/manifest.json,extension/panel-bridge.js).extension/manifest.jsonandpackages/devtools/package.json:3are both0.0.7, but nothing keeps them in sync andscripts/extension-zip.mjsdoes not check it. Make the zip script set or verify the manifest version from the package version.packages/devtools/src/__tests__/extension-*.test.tstests all stubchrome.*, andci.ymlonly checks thatextension/uiis not stale. A manifest mistake or a Chrome API change would ship unnoticed. Add a Playwright job that runs Chromium with--load-extension=extensionagainst the demo SSR app and checks that the panel loadsui/index.htmlwith apageId.Improvements
chrome.action) that turns colored on Angular pages, with a small popup showing the Angular version, dev or prod mode and whether a Pangular server answered. UseactiveTabso it adds no install warning (extension/manifest.json, new popup files).chrome.devtools.panels.elements.createSidebarPanethat shows the selected element's component inputs and signals (extension/devtools.js,extension/panel-bridge.js).network.onNavigatedreloads the whole panel. Only search for the server again when the origin changes, so the tab, filter and selection survive a reload (extension/panel-bridge.js:221-225,182-190).sessionStoragein the panel) and try it first, so reconnecting is close to instant (extension/panel-bridge.js).inspectedWindow.evaland the in-page collectors, giving read-only component, signal and DI views with no server setup (extension/panel-bridge.js,app/src/extension-bridge.ts).scripts/panel-axe.mjsto loadextension/panel.htmlwith a stubbedchromeobject, so the status view is checked too.test:axeonly auditsdist/panel-axetoday (package.json:19).extension:zipon tags and attaches the zip to the GitHub release, so users can load a downloaded build without cloning (.github/workflows,scripts/extension-zip.mjs).Already tracked elsewhere
<all_urls>content scripts and the install warning: phase 1 of 4: safe by default and wired into your workflow #340.__PANGULAR_ANGULAR_DETECTED__message (goes away with the content scripts): phase 1 of 4: safe by default and wired into your workflow #340.title(axeframe-title): phase 1 of 4: safe by default and wired into your workflow #340.background.scripts, gecko id,moz-extension:checks): phase 3 of 4: a shell you live in #342.Generated by Claude Code