## What
Adds an `isBrowserExtensionNoise` predicate to the frontend Sentry
`beforeSend` chain that drops errors originating from injected
browser-extension scripts.
## Why
Triaging Sentry surfaced recurring, unactionable issues caused entirely
by users' browser extensions, not our code:
- **PHP-LARAVEL-21** — `i: Failed to connect to MetaMask`
(`chrome-extension://…/inpage.js`)
- **PHP-LARAVEL-3M** — `Cannot read properties of undefined (reading
'sendMessage')` (`chrome-extension://…/injectedScript.bundle.js`)
These recur for every user who has the offending extension installed, so
resolving-and-waiting just re-pages us forever. This follows the
existing pattern of named noise predicates with vitest coverage
(`isChunkLoadErrorEvent`, `isSafariCashbackExtensionNoise`, …).
## How
The predicate inspects the **crashing (innermost) frame** of each
exception and drops the event only when that frame's URL uses a
browser-extension scheme (`chrome-extension://`, `moz-extension://`,
`safari-web-extension://`, `safari-extension://`,
`ms-browser-extension://`).
Matching only the crashing frame — not *any* frame — avoids
over-filtering legitimate app errors that merely pass through an
extension-wrapped handler.
### Not filtered on purpose
`AxiosError: Network Error` (PHP-LARAVEL-28 / -38) is left untouched: it
has no extension frames and a full backend outage produces the same
error, so we want it to keep alerting.
## Tests
`resources/js/lib/sentry.test.ts` — 4 new cases (drops the two real
extension shapes; keeps the network error and an app error where the
extension frame is not the crash site). `vitest run` green (12/12).