31446 Commits
Author SHA1 Message Date
claude[bot]andClaude 2954493d46 docs: fix incorrect heading levels (#55407)
Several API entries were one heading level too deep relative to their
sibling events and methods, or skipped a level under their section.


Claude-Session: https://claude.ai/code/session_01KX1hkKfxeSmmXK7rv1wNCE

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-27 17:47:53 -07:00
Zhong Lufan (钟路帆) 3dfc698827 fix: silently ignore legacy --no-stdio-init switch (#55397)
Removing --no-stdio-init also removed the filtering that kept the switch
out of Node.js argument parsing. Existing launchers using ELECTRON_RUN_AS_NODE
therefore fail at startup with a bad option error.

Restore silent filtering to ease migration without restoring the switch's
stdio initialization behavior. Keep automatic Windows NUL detection unchanged
and update the command-line and breaking-change documentation.

Follow up on #53459 and the review feedback in #55366.

Assisted-By: GPT 6 Astra
2026-10-27 13:27:21 -04:00
708d5fe414 chore: bump chromium to 158.0.8127.0 (main) (#55378)
* chore: bump chromium in DEPS to 158.0.8126.0

* chore: update siso revision

* chore: update patches

* build: rebase siso patches onto siso dfc32e4

Upstream https://chromium-review.googlesource.com/c/build/+/8609448
(146ec3de) passes grpc.WaitForHandlers(true) to the reapitest fake
server, conflicting with our UnaryInterceptor plumbing on the same
grpc.NewServer() call. Seed our server options with upstream's.

Skip-Lint: siso patch rebase; siso CLs don't map to Chromium versions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: bump chromium in DEPS to 158.0.8127.0

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: electron-claude[bot] <279139701+electron-claude[bot]@users.noreply.github.com>
Co-authored-by: clavin <clavin@electronjs.org>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 12:28:28 -04:00
David Babenko-Sanders 4fb65e91de ci: bump dsanders11/project-actions to 2.1.0 (#55386) v47.0.0-nightly.20261027 2026-10-26 17:14:49 -07:00
dependabot[bot] e66fd3f5e2 build(deps): bump github/codeql-action/upload-sarif from 4.38.3 to 4.39.0 (#55383)
build(deps): bump github/codeql-action/upload-sarif

Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 4.38.3 to 4.39.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/24c54180a607b1449ed407dd24f251e4e9147c8d...6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee)

---
updated-dependencies:
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-26 17:14:01 -07:00
claude[bot]andClaude Opus 5.5 27e39e926c fix: use upstream's File System Access path matcher (#55328)
* fix: use upstream's File System Access path matcher

Electron kept its own copy of ShouldBlockAccessToPath() and the Windows
MaybeIsLocalUNCPath() helpers. That copy never evaluated the suffix block
rules, so the kBlockWrite rules for .git/hooks, .git/config and .git/modules
were not enforced, and it lacked the hypervisor host-share servers (mac, psf,
vmware-host, .host, vboxsvr, vboxsrv) and trailing-dot handling that upstream
added in 158.0.8120.0.

Extend refactor_expose_file_system_access_blocklist.patch to move upstream's
ShouldBlockAccessToPath() and its UNC helpers verbatim into
chrome_file_system_access_blocklist.cc, exposed as a static member of
ChromeFileSystemAccessPermissionContext, and call it from Electron with the
access trigger so kBlockWrite rules only apply to save and programmatic write
operations, matching Chrome. Future upstream changes to the matcher now
conflict on roll instead of drifting.

This replaces Electron's stricter UNC checks with upstream's: '_' is now
allowed in UNC server names, and only drive (X$) and ADMIN$/IPC$/PRINT$/FAX$
admin shares are blocked rather than every '$'-suffixed share.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* test: cover Windows UNC classification in the File System Access blocklist

Shares a fixture directory over loopback SMB and pastes it under different
UNC server and share names, checking that local server names (localhost,
127.0.0.1, and a trailing-dot localhost when it resolves) and drive admin
shares are blocked while other servers and non-admin hidden shares are not.
The hidden share and trailing-dot cases pin down the intentional changes
from Electron's previous matcher.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* test: fix the UNC spec's localhost case and share names

A file URL drops a "localhost" host, so pasting \\localhost\share reached
Chromium as a path with no server. Drop that case; 127.0.0.1 and the
trailing-dot localhost still cover local server names.

Keep share names to 12 characters so net share doesn't stop to ask about
MS-DOS clients, and answer that prompt anyway in case it appears.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-26 16:57:02 -04:00
ece4214c22 chore: bump chromium to 158.0.8125.0 (main) (#55311)
* chore: bump chromium in DEPS to 158.0.8121.0

* 8561777: [device] Make DeviceMonitorMessageWindow a NoDestructor

Upstreamed; remove the patch.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8561777

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: update patches

* chore: bump chromium in DEPS to 158.0.8123.0

* chore: update patches

* chore: bump chromium in DEPS to 158.0.8125.0

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: electron-claude[bot] <279139701+electron-claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-26 12:22:45 -07:00
Zhong Lufan (钟路帆) baf7eaf5b4 fix: automatically skip stdio initialization when NUL is unavailable (#53459)
Automatically set kNoStdioInitialization on Windows when the NUL device
cannot be opened, rather than aborting startup. Apply this to both
embedded Node.js and ELECTRON_RUN_AS_NODE initialization.

Remove the --no-stdio-init switch and its child-process forwarding, and
update the command-line and breaking changes documentation. Preserve
normal stdio initialization when NUL is available and on other platforms.

Closes #52677

Assisted-By: GPT 6.1 Sol
2026-10-26 11:46:29 -04:00
electron-roller[bot]andClaude Opus 5.5 e9bc0b2292 build: update build-images to 22fded7 (#55200)
* chore: bump build image tag in .devcontainer/docker-compose.yml to 22fded7

* chore: bump build image sha in build-image-sha action

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmMk2yWrVE76u5SLy2QaJk

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-26 11:43:12 -04:00
claude[bot]andClaude 15980f8024 build: don't hardcode the Python 3.11 path on Windows runners (#55308)
install-build-tools copied C:\Python311\python.exe to python3.exe, which
ties every Windows build to the runner image's Python 3.11 install path.
Only create python3.exe when python3 doesn't already run, and take the
directory from the Python 3 on PATH.


Claude-Session: https://claude.ai/code/session_01CFb55iGpm94Xhee9mSX3eV

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-26 11:41:52 -04:00
time1043 02f35ce992 docs: remove redundant shell requires in application menu tutorial (#55312) 2026-10-26 11:35:40 -04:00
claude[bot]andClaude Opus 5.5 6ffeb62f95 test: fix seven specs that relied on in-suite retries (#55359)
* test: read the download item inside will-download in api-session spec

`will-download event > identifies the frame and origin that started the
download` called preventDefault() in its will-download listener and only
read item.getInitiatorOrigin() after awaiting the event. preventDefault()
cancels the download, which destroys the item, and that can happen before
the awaiting code runs, so the read threw "DownloadItem used after being
destroyed". Read the origin inside the listener, while the item is alive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: wait for the page to see clearData() in api-session spec

`ses.clearData() > clears all data when no options supplied` (and its
"called twice in parallel" twin) read localStorage.length right after
clearData() resolved. The page answers from its own cached copy of
localStorage, which the storage backend updates over a separate pipe, so
the page could still report the old item. Wait until the page sees the
clear, as the clearStorageData() spec already does.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: enable Network capture before navigating in debugger valid unicode spec

"handles valid unicode characters in message" started loadURL() on a
fresh window and only then attached the debugger and sent Network.enable
without waiting for it. Network.enable reaches the renderer only once it
exists, so when the tiny response won that race Network.responseReceived
was never emitted and the test hung until its 30s timeout.

Load about:blank first, attach, await Network.enable, then start
listening and navigate, matching the neighbouring invalid unicode spec.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: drop the 5s timeout on contentTracing recording specs

startRecording() resolves only once every child process acks the start,
or after the tracing service's 10s ack timeout, and stopRecording() then
waits up to 5s for the stop acks. A child that is slow to get scheduled on
a busy CI host therefore stretches a single record() past the 5s
per-suite timeout whatever the trace categories are, and the test only
passed on the in-suite retry.

Use the default spec timeout instead. Stopping the network service for
25s while a recording runs makes the slowest record() take about 15s,
which matches that bound and stays well inside the default.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: listen for the PDF viewer download's done event before it can fire

The asar PDF viewer download test attached its 'done' listener only after
the click loop noticed that the download had started. When the click's
executeJavaScript() round trip came back late, the small download could
start and finish inside that window, and the test then waited for a
'done' event that had already fired until the spec timed out.

Start listening for 'done' in the synchronous will-download handler that
accepts the first download, so the event cannot be missed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: isolate the custom protocol extension fixtures' profiles

runFixture() started the custom-protocol fixture apps on the default
profile (they have no package.json, so userData is the stock Electron
directory other fixture apps use too) and never stopped them. When
another browser process holds that profile, the fixture's MV3 service
worker never answers the content script, the page title never changes
and the app hangs until the test times out. Because the hung app was not
killed it kept the profile open, so every in-job retry hung the same way.

Give each run its own --user-data-dir, and kill the app and remove the
directory when the test ends.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: follow links without synthesized clicks in navigation ordering specs

The "navigation events > ordering" specs for a second navigation, a
redirect and an in-page navigation clicked a link in a window that was
never shown, by sending CDP mouse events after a fixed 2s wait. On
Wayland a hidden window presents no frames, and the click can be lost
before it reaches the page: the browser forwards mouseDown and mouseUp,
but the page sees no pointer, mouse or click event, so the navigation
never starts and the test times out.

These specs check the order of navigation events, not input delivery.
Follow the link with a renderer-side click() once the page has loaded
instead; it is the same renderer-initiated navigation, and it no longer
depends on frames being presented or on the 2s wait.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-26 11:33:06 -04:00
RoboandSamuel Maddock a4b0cc65a5 refactor: generate PreloadRealmGlobalScope IDL bindings in //electron (#55165)
* refactor: use PreloadRealmGlobalScope for service worker preloads

Service worker preload scripts ran in Blink's ShadowRealmGlobalScope.
The ShadowRealm proposal has stalled, so Chromium may remove that class.

A new Chromium patch adds PreloadRealmGlobalScope, a global scope that
exposes the same interfaces without depending on any ShadowRealm code,
and Electron now creates the preload context with it.

Uncaught errors and unhandled rejections in a service worker preload
script are now reported through the worker's console. Before, they hit
NOTREACHED() in ShadowRealmGlobalScope.

Calling getEventListeners() from the DevTools console in the preload
context no longer crashes the renderer.

* refactor: generate PreloadRealmGlobalScope IDL bindings in //electron

* ci: normalize include paths in Windows gen headers for clang-tidy

The Windows clang-tidy job runs in a Linux container using generated
headers downloaded from out_gen_artifacts_win_x64. On Windows, Python
code generators such as inspector_protocol/code_generator.py use
os.path.join() and emit backslashes in #include directives, causing
Linux Siso scandeps and clang-tidy on RBE workers to fail with:

gen/third_party/blink/renderer/core/inspector/protocol/forward.h:15:10: error: 'third_party/inspector_protocol\crdtp/error_support.h' file not found [clang-diagnostic-error]
   15 | #include "third_party/inspector_protocol\crdtp/error_support.h"
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* fixup! normalize include paths in Windows gen headers for clang-tidy

* fix: resolve root worker context for ShadowRealms nested in preload realms

When a ShadowRealm is created inside a service worker preload realm
(e.g. with --harmony-shadow-realm), its initiator ExecutionContext is
PreloadRealmGlobalScope rather than a WorkerOrWorkletGlobalScope or
ShadowRealmGlobalScope. Previously, GetRootInitiatorExecutionContext()
only walked initiators via To<ShadowRealmGlobalScope>(), which either
stopped at PreloadRealmGlobalScope (failing the subsequent
To<WorkerOrWorkletGlobalScope>() cast on unhandled rejections or console
messages) or performed an invalid downcast to ShadowRealmGlobalScope.

Delegate GetRootInitiatorExecutionContext() to
initiator_execution_context_->GetRootExecutionContext() so nested
ShadowRealms walk through PreloadRealmGlobalScope to the underlying
ServiceWorkerGlobalScope.

* fix: use Supplement<ExecutionContext> for PreloadRealmLifetimeController

Replace V8 embedder data slot storage in PreloadRealmLifetimeController with
blink::Supplement<ExecutionContext> so it cannot collide with NodeBindings
storing node::IsolateData* in kElectronContextEmbedderDataIndex
or require a persistent self root.

* build: track blink pydeps

* chore: update patches

---------

Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>
2026-10-26 08:26:03 -07:00
Sam Maddockanddeepak1556 8c691a4ffb refactor: use PreloadRealmGlobalScope for service worker preloads (#55142)
* refactor: use PreloadRealmGlobalScope for service worker preloads

Service worker preload scripts ran in Blink's ShadowRealmGlobalScope.
The ShadowRealm proposal has stalled, so Chromium may remove that class.

A new Chromium patch adds PreloadRealmGlobalScope, a global scope that
exposes the same interfaces without depending on any ShadowRealm code,
and Electron now creates the preload context with it.

Uncaught errors and unhandled rejections in a service worker preload
script are now reported through the worker's console. Before, they hit
NOTREACHED() in ShadowRealmGlobalScope.

Calling getEventListeners() from the DevTools console in the preload
context no longer crashes the renderer.

* chore: update patchs

* chore: update patches

---------

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2026-10-26 08:26:02 -07:00
Charles KerrandClaude Opus 5.5 79594d98e6 test: wait for an active window before sending menu shortcuts (#55287)
* test: wait for an active window before sending menu shortcuts

On Windows and Linux, views hands accelerators only to the active
window (View::CanHandleAccelerators). The setIgnoreMenuShortcuts specs
waited for page or DevTools focus, which can be set inside an inactive
window, or for no focus at all, so an honored F13 could miss the menu
and the spec timed out waiting for it. Focus the window and wait for
isFocused() before each press.

The CDP keyUp's answer is what orders the count after the keyDown's
menu dispatch: the widget acks the events in order, and the browser
offers an unhandled keyDown to the menu while it handles that ack.
This only holds when both events reach the same widget, but the keyDown
went through sendInputEvent to the main widget, while CDP targets the
focused frame. Send the keyDown through CDP as well, with a native key
code so that it isn't marked skip_if_unhandled. Read the count as soon
as the keyUp is answered instead of polling for it, and wait for the
webview guest to have focus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: keep menu shortcut windows visible and active

The browser doesn't offer keys from a hidden widget to the menu
(RenderWidgetHostImpl::OnKeyboardEventAck checks IsHidden()). On
Windows, native occlusion marks a covered window hidden and shows it
again only after a timer and a posted task, so a press sent right after
window.focus() raises a covered window could be dropped. Keep the shown
windows always on top on Windows, as the visibility specs do, and wait
for the page to report that it is visible before each press.

On macOS, window.focus() activates the app only when no other app is
frontmost, so the isFocused() wait could time out. Take activation with
app.focus({ steal: true }) first, as the webview specs do.

Also correct the comment on the native key code: off macOS, any
non-zero code works.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: simplify the menu shortcut specs

The webview spec activated the window before each press, and then
sendShortcut() activated it again under a different condition. Focus
the guest inside sendShortcut() instead, once the window is active, so
activation happens in one place. Set the Windows alwaysOnTop option
from one describe-level const, next to the reason for it.

The docked DevTools spec waited for devtools-focused and passed
activate: true, which is the default and which docked DevTools ignore.
Neither the CDP target nor the menu depends on DevTools focus, and
sendShortcut() already waits for an active window and a visible page
before each press, so drop both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
v47.0.0-nightly.20261026
2026-10-26 01:26:56 -07:00
d34d52969b test: isolate File System API permission state (#54862)
* test: isolate File System API permission state

The writable-handle allow and deny specs shared the default session, the
file:// origin and test.txt. If the allow spec's write grant is still
active when the deny spec gets its handle, GetWritePermissionGrant()
hands back that grant, and the handle's DoRequestPermission() returns at
once because its status is no longer 'ask', so the grant's
RequestPermission() is never reached. The deny spec then starts at
'granted', createWritable() succeeds and the denying handler is never
called. Resetting the handlers in afterEach doesn't revoke the grant.

Give each File System API spec its own in-memory session, reset that
session's handlers afterwards, and assert that the deny spec starts at
'prompt'. The NotAllowedError check and the check for exactly one
correctly populated request are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: simplify the File System API permission specs

Each File System API spec now has its own session, so:

- Install permission handlers with ses.setPermission*Handler(), as the
  File System Access permission scope specs do. It is the same session
  the window uses, but a spec that forgets `session: ses` can no longer
  leave a handler on the default session.
- Use afterEach(closeAllWindows). Resetting the handlers of a session
  that no later spec uses did nothing.
- Drop the deny spec's trace of the initial permission. The 'prompt'
  assertion right after it reports the same value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 01:26:52 -07:00
dffa6661cc test: improve reliability of menu cpp-heap specs (#55297)
* test: use precise GC and live menu counts in the menu rebuild spec

The spec measured the whole C++ heap after collecting with
v8Util.requestGarbageCollectionForTesting(), a synchronous GC that scans
the native stack conservatively. A replaced menu, its submenus and its
items all reference each other, so a stale pointer to any one of them
keeps the whole menu alive: about 75 KB, several times the spec's 10%
allowance. In 100 local Linux runs, that GC kept one or two replaced
menus alive in 3 runs, while precise GC kept none. A single Windows
failure grew by 75,680 bytes, close to the size of one menu.

Collect with gc({ type: 'major', execution: 'async' }), which does not
scan the stack, and check what the regression is about: every replaced
menu's WeakRef is cleared, the live Menu and MenuItem counts are equal
after identical rounds, and the current application menu stays alive.
The whole-heap growth check stays as a secondary check with the same
allowance; with precise GC the heap size was identical across rounds.

Only synchronous helpers hold the menus: a suspended async function
keeps its registers, and a menu left in one stayed alive after being
replaced. The failure message also said 100 rebuilds per round instead
of 50.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: use precise GC in the other cpp-heap growth specs

The download, chunked upload and utilityProcess leak specs measured the
whole C++ heap after the synchronous v8Util GC, which scans the native
stack conservatively. The check also could not see a leak of the
objects these specs are about. In local runs, keeping every
DownloadItem, every request with its URL loader, or every exited child
alive stayed within the 10% allowance and the old specs passed; only
retained UtilityProcess wrappers went over it, and only just.

Collect with gc({ type: 'major', execution: 'async' }) and check those
objects: a WeakRef to every download item, request and child is cleared
after each round, and no DownloadItem, SimpleURLLoaderWrapper,
JSChunkedDataPipeGetter or UtilityProcess wrapper is left alive. A
count taken while an object is still in use must see it, so a renamed
type cannot pass the zero check. The whole-heap check stays as a
secondary check with the same allowance; it did not change between
rounds.

The per-operation helpers are synchronous and resolve with numbers, so
no suspended async frame holds a download item, request or child.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: share the cpp-heap object-count and precise-GC helpers

The menu, download, chunked upload, utilityProcess and PromiseHandle
specs each carried a copy of the code that counts C++ heap objects by
cppgc type name and of the precise collection with
gc({ type: 'major', execution: 'async' }). Move both into
spec/lib/cpp-heap-helpers.js as countCppHeapObjects() and
collectGarbagePrecisely(), which the remotely() bodies require the way
they require heapsnapshot-helpers.js. The specs' assertions are
unchanged. The menu spec now reads the heap size from brief statistics,
like the others.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: address review notes on the cpp-heap growth specs

On macOS, Menu.setApplicationMenu() installs the menu on a later
run-loop pass, and until then the previously installed menu stays
alive. If that pass had not run before the last collection, the menu
spec would see one replaced menu still alive. Yield one macrotask
before collecting.

The utilityProcess spec takes its in-use count right after fork(),
before the child runs, so say that, and fail if a child exits with a
nonzero code, so the spec cannot pass when every launch fails. The
comments on the whole-heap checks now call them what they are: a
coarse secondary check for growth in other types.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: simplify the cpp-heap growth specs

The downloads, uploads, menu and utilityProcess growth specs each
counted their uncollected WeakRefs with the same filter. Export it from
cpp-heap-helpers.js as countAlive(), the name the menu spec gave its
local copy.

Once the helper took over the counting, the menu spec's measure() was a
one-use wrapper around an object literal, and its name meant something
different from measure() in the other specs. Return the literal from
rebuildAndMeasure() instead. The Menu and MenuItem counts now sit under
`live`, as in the uploads spec, so one toEqual() compares both across
rounds; it fails whenever either of the two toBe() checks would have.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Revert "test: use precise GC and live menu counts in the menu rebuild spec"

This reverts commit 116ecfe671.

* test: extract synchronous rebuild helper in menu heap spec

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2026-10-26 01:26:35 -07:00
claude[bot]andClaude Opus 5.5 f11c314b8d test: fix retry-reliant clearData IndexedDB spec (#55232)
* test: read clearData() results from a new document

`ses.clearData() > only clears specified data categories` hung until
the spec timeout on sanitizer runs. Clearing IndexedDB force-closes the
bucket and disconnects the page's IndexedDB factory pipe, but the page
learns about that separately from the `get-indexeddb` IPC that follows.
If it handles the IPC first, `indexedDB.open()` goes down the dead pipe
and fails with "AbortError: The connection was closed.". The fixture
only logged the error, so the test waited forever. Every main run that
needed the retry logged that error from the fixture.

Read the data back from a fresh load of the fixture (with ?readOnly, so
it does not seed it again), and have the fixture report open failures
instead of only logging them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: report how cookie-app exited in the app restart spec

`ses.cookies > should survive an app restart for persistent partition`
needs a retry in about one in six linux-x64-ubsan runs and in no other
lane, and its failures leave nothing to go on: the test dropped the
app's stderr and exit status. Run the app with spawnAndWait(), require
a clean exit, and attach the app's stdout and stderr to both
assertions, so the next failure shows what the app printed, e.g. a
UBSan report.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-26 08:01:58 +00:00
claude[bot]andClaude 4ba52efe38 test: fix retry-reliant spellchecker and OOM crash-key specs (#55226)
The macOS spellchecker specs relied on retries because the system spelling
server starts on first use, which took 30 to 60 seconds on fresh CI
machines. Until then AppKit times every request out and Blink never asks
again about the text it already checked, so the first context menu spec
never saw its misspelling. Wait once, in a beforeAll, until the spell
checker answers with suggestions for a misspelled word, and have the
context menu waits require the suggestions as well as the misspelled word.

The renderer OOM crash-key specs filled the heap with arrays of pointers,
so each of the ~20 full GCs V8 runs near the heap limit traced the whole
heap. On the Intel macOS runners that took long enough for the crash
fixture's 30 second exit timer to end the app before the renderer crashed.
Fill the heap with arrays of doubles instead, which the GC does not trace.


Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-26 08:01:54 +00:00
claude[bot]andClaude 74141f73b9 test: fix retry-reliant macOS UI specs (#55223)
app sandbox options: the mixed-sandbox fixture credited each window's
argv to whichever window it had created last, so a sandboxed window
that reported after its DevTools opened left argv.sandbox unset and the
spec hung until the timeout. Take each window's argv from its own
webContents.ipc, open both windows at once, read the report until the
app ends the connection, and fail as soon as the app exits early.

shell.openExternal: the 'removes focus' spec read isFocused() only after
openExternal() resolved, by which time the activation requests made to
take focus beforehand, or the browser finishing its launch, can have
given focus back. Read the state when 'blur' arrives instead.

Notification remove*: wait for the notifications to drop out of
getHistory() instead of sleeping 100 or 500 ms, since Notification
Center applies removals asynchronously.


Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-26 08:01:50 +00:00
claude[bot]andClaude 0187553fce test: fix retry-reliant webview and debugger specs (#55227)
debugger.sendCommand "does not crash for invalid unicode characters in
message" attached to a window that had never loaded anything and sent
Network.enable without waiting for it. With no renderer yet, the command
only reached the renderer during the first navigation, and
Network.loadingFinished was sometimes never reported. Load about:blank
first, attach, await Network.enable, then navigate.

<webview>.reload() "should emit beforeunload handler": the guest has no
user gesture, so Chromium skips the beforeunload confirmation and the
reload goes ahead. The fixture's IPC, deferred with setTimeout(0) in the
hidden window, could be dropped when the document unloaded. Send it
synchronously from the handler.

<webview> "follows the embedder window when it is hidden and shown
again" took the guest's next visibility report as the state to check, but
the guest can report 'hidden' before the embedder has shown it. Wait for
each expected state instead, and run the suite serially like the
BrowserWindow visibilityState specs, since on macOS a window from another
spec worker can occlude the embedder.


Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-26 08:01:47 +00:00
claude[bot]andClaude 6408a0c6bb test: fix retry-reliant macOS fullscreen BrowserWindow specs (#55230)
"should be able to load a URL while transitioning to fullscreen" and
"transparent option > correctly returns isMaximized() when the window is
maximized then minimized" time out on their first attempt on macOS and
pass on retry. Each runs right after a test that ends with two windows
sharing fullscreen (a borderless child of a fullscreen parent, and
"multiple windows inherit correct fullscreen state"). Those tests'
reported durations, which include the afterEach hook, are too short to
contain a fullscreen exit in the failing runs, so closeAllWindows()
destroyed a window that was still animating out of fullscreen, and AppKit
ignored the next test's first window request.

closeWindow() only waited when isFullScreen() was true, which it no
longer is while a window is being taken out of fullscreen along with
another one. Track which BrowserWindows have entered fullscreen and not
yet left it, wait for their 'leave-full-screen' too, and warn when that
does not arrive within the existing 5s bound.

"does not exit simpleFullScreen when requestFullscreen is called" still
spent its first attempt's whole 10s focus wait without the page getting
focus on macOS arm64, and passed on the retry, which requested app
activation again. Request activation on every poll instead of once.


Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-26 08:01:43 +00:00
0240841b24 refactor: compile upstream FSA blocklist helpers instead of copying them (#54751)
* fix: carry upstream macOS firmlink blocklist fix into exposed FSA blocklist

Chromium 156.0.8078.3 already contains upstream 64c8e2a1ceda ("[FSA] Block
macOS firmlink alias paths to sensitive directories"), but
refactor_expose_file_system_access_blocklist.patch re-adds
NormalizeFilePath()/GenerateBlockPaths() as static members in the header
without the new pieces, so Electron's copy of the blocklist does not carry
the fix.

Update the patch's header copy to match upstream: add the
MaybeStripMacDataVolumePrefix() and NormalizeFilePathForBlocklist() static
helpers, the /System/Volumes kBlockAllChildren rule, and normalize
generated rules through NormalizeFilePathForBlocklist().

Refs https://chromium-review.googlesource.com/c/chromium/src/+/8410087 (upstream commit 64c8e2a1cedafdbcc750abc423ad9b389537c223)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* fix: fold macOS Data volume firmlink paths in file system access blocklist checks

Switches Electron's copy of ShouldBlockAccessToPath() to the
NormalizeFilePathForBlocklist() helper (from upstream 64c8e2a1ceda, exposed
in the header by the companion refactor_expose_file_system_access_blocklist
patch update), so paths spelled via /System/Volumes/Data are matched
against the root-namespace blocklist rules the same way Chrome does.

Refs https://chromium-review.googlesource.com/c/chromium/src/+/8410087 (upstream commit 64c8e2a1cedafdbcc750abc423ad9b389537c223)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* test: cover /System/Volumes/Data alias paths in FSA blocklist

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* refactor: compile upstream FSA blocklist helpers instead of copying them

refactor_expose_file_system_access_blocklist.patch used to hand-copy
upstream's NormalizeFilePath(), NormalizeFilePathForBlocklist() and
GenerateBlockPaths() into the header as inline static members. Since #53634
dropped the .cc hunks, upstream edits to the originals no longer conflict on
roll, so the copy goes stale silently (this is how the firmlink fix
64c8e2a1ceda was lost on the M156 roll; main's copy also still keeps the
.git/hooks rule Windows-only, while upstream applies it on all platforms).

Instead, declare NormalizeFilePathForBlocklist() and GenerateBlockPaths() as
static members in the header and move upstream's definitions verbatim out of
chrome_file_system_access_permission_context.cc into a new
chrome_file_system_access_blocklist.cc, which Electron now compiles as part
of //electron/chromium_src:chrome. Upstream changes to the blocklist now
conflict loudly on the removal hunk instead of being dropped.

Electron's call sites are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* chore: update patches

Regenerate the index line for chrome_file_system_access_permission_context.cc
in refactor_expose_file_system_access_blocklist.patch so the patch round-trips
through `e patches chromium` against 156.0.8078.3 (fixes "needs update" in the
checkout jobs).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* chore: update patches

Regenerate the index line for chrome_file_system_access_permission_context.cc
in refactor_expose_file_system_access_blocklist.patch against
157.0.8085.0 after merging main (Chromium roll #54590), matching the
update-patches.patch artifact from the failed apply-patches check.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* test: resolve home dir symlinks and cover /System/Volumes rule in FSA firmlink spec

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* chore: update patches

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* chore: update patches

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* chore: update patches

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* chore: update patches

Rebase refactor_expose_file_system_access_blocklist.patch onto 158.0.8118.0
and carry the upstream kBlockPaths additions from that version into
chrome_file_system_access_blocklist.cc.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

* chore: update patches

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtuMgvwAcw7t9Q6HEB31Vx

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2026-10-25 15:00:26 -07:00
claude[bot]andClaude Opus 5.5 316685ba12 fix: show macOS context menus reliably after a previous one is cancelled (#55235)
* fix: show macOS context menus reliably after a previous one is cancelled

-[ElectronMenuController cancel] dismissed the menu with -cancelTracking,
which plays a fade-out animation. While that animation runs, a following
-popUpMenuPositioningItem:atLocation:inView: returns without showing the
menu or calling -menuWillOpen:, so a Menu.popup() made right after
Menu.closePopup() (or after a cancelled popup on another window) showed
nothing, and neither 'menu-will-show', 'menu-will-close' nor the popup
callback ever fired.

Use -cancelTrackingWithoutAnimation instead, and clear isMenuOpen_ before
calling it so that a -menuDidClose: delivered during the cancel is ignored
and 'menu-will-close' and the close callback are still reported exactly
once, from -cancel.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: cover reopening a macOS popup menu from a closed popup's callback

Pops a menu up, closes it with closePopup() once it shows, and pops it
up again from the first popup's callback. Both popups must emit exactly
one menu-will-show, one menu-will-close and one callback, in order.
With the animated -cancelTracking the second popup showed nothing, so
the test timed out. It runs with retry: 0 because every attempt repeats
the same sequence, so a retry could only hide a regression.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-25 22:00:04 +00:00
electron-pgo-updater[bot] 863cbdd57d build: update PGO profiles (#55317)
* build: update linux-arm64 PGO profile

* build: update linux-x64 PGO profile

* build: update macos-arm64 PGO profile

* build: update macos-x64 PGO profile

* build: update v8-builtins PGO profile

* build: update win-arm64 PGO profile

* build: update win-x64 PGO profile

---------

Co-authored-by: electron-pgo-updater[bot] <290827142+electron-pgo-updater[bot]@users.noreply.github.com>
2026-10-25 21:06:27 +00:00
claude[bot]andClaude 96a2dc1f28 ci: print TCC diagnostics when macOS runner lacks capture/input access (#55237)
ci: print TCC diagnostics when the macOS runner lacks capture/input access

On a small share of hosted macOS VMs (about 0.5% of macos-x64 and 0.2%
of macos-arm64 test jobs since late September, on the same runner image
as the passing jobs) TCC denies the job screen capture, posting events
and Accessibility from the first spec on. desktopCapturer.getSources
then rejects with "Failed to get sources.", getUserMedia/getDisplayMedia
with "Could not start video source", and the real-input specs time out
with postEventAccess:false and accessibilityTrusted:false.

Add a preflight before the specs that checks
CGPreflightScreenCaptureAccess() and CGPreflightPostEventAccess() from
the job's process chain. When access is missing it prints the process
chain, the TCC.db rows for these services and tccd's attribution of the
request, and emits a warning naming the runner host problem. It does not
change TCC state or fail the step; that can follow once the attribution
shows which process TCC holds responsible.


Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-24 07:16:37 +00:00
electron-roller[bot]andelectron-claude[bot] e5c444e395 chore: bump chromium to 158.0.8120.0 (main) (#55295)
* chore: bump chromium in DEPS to 158.0.8120.0

* chore: update patches

* chore: update libc++ filenames

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: electron-claude[bot] <279139701+electron-claude[bot]@users.noreply.github.com>
2026-10-23 18:38:32 -07:00
claude[bot]andClaude 7d44215c46 ci: label PGO profile update PRs with their target branch (#55298)
Profile update PRs opened against a release branch now also get that
branch's label (e.g. 46-x-y), added in the same additive labels call as
semver/none. main PRs are unchanged; they already receive the current
major's label on merge from pull-request-merged.yml.


Claude-Session: https://claude.ai/code/session_019kGNYv837tKLbJDSHsECro

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-24 10:18:33 +09:00
claude[bot]andClaude eb6db76aee test: poll the window server without blocking the app shim specs (#55231)
The app shim specs ask osascript which windows are on screen, and did so
with spawnSync, every 10ms, on the main process's UI thread. A window in a
shim is drawn by AppKit in the shim's process, which asks the host
synchronously through remote_cocoa whether the window can become key, has
the key appearance or shows its title whenever it orders, lays out or draws
it. While the host sat in spawnSync those calls went unanswered, so the shim
advanced roughly one call per osascript run. On the slower Intel macOS
runners that starved the tab merge in "tabs two windows of one shim
together" past waitUntil's 10s, on every in-suite retry.

Run osascript with an async execFile so the host keeps answering the shim
while the window server is queried.


Claude-Session: https://claude.ai/code/session_01Xomb9LeAiuTMvaEtSsauvb

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 17:02:00 -07:00
0e7bb2dc18 chore: bump chromium to 158.0.8118.0 (main) (#55210)
* chore: bump chromium in DEPS to 158.0.8117.0

* chore: update patches

* chore: bump chromium in DEPS to 158.0.8118.0

* 8527748: [Linux] Remember declined GlobalShortcuts portal shortcuts

Upstream now marks cancelled shortcuts as declined on a failed
BindShortcuts response and re-binds the remaining ones without them.
Keep that logic, resolve the groups of the failed bind request as
unbound before it runs, and close the session instead of recording the
failed IDs as bound so that a later registration attempts a fresh bind.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8527748

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: update patches

* 8604729: [UI] Rename `WindowOpenDisposition` enumerators to kCamelCase

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8604729

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8567537: Enable BackupRefPtr in PartitionAlloc default dispatch shim

BackupRefPtr now covers allocations made before FeatureList
initialization, including the ContentClient and per-process clients
created by ElectronMainDelegate. ElectronMainDelegate declared
content_client_ before gpu_client_, renderer_client_ and
utility_client_, so at process exit those were freed first and the
base content::ContentClient destructor then released dangling raw_ptrs
to them. In dcheck_always_on builds the dangling pointer detector turns
that into a crash on exit of every renderer, GPU and utility process,
which made the crashReporter "ensure linux child process args are not
modified" spec receive a minidump from a utility process exiting
instead of a clean exit. Declare content_client_ last, matching
content_shell's ShellMainDelegate, so it is destroyed first.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8567537

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: electron-claude[bot] <279139701+electron-claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: David Babenko-Sanders <dsanders11@ucsbalum.com>
2026-10-23 15:17:00 -07:00
David Babenko-SandersandClaude Opus 5.5 6431970d8b build: enable more performance-* clang-tidy checks (#54024)
* build: enable more performance-* clang-tidy checks

* chore: performance-prefer-single-char-overloads

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: performance-unnecessary-copy-initialization

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: performance-use-std-move

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: performance-move-const-arg

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: performance-no-automatic-move

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: address review feedback

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MC6nEgyED2MtseZ9KdGMpt

* chore: fix new clang-tidy performance findings

Address performance-use-std-move, performance-move-const-arg, and
performance-prefer-single-char-overloads findings in code that landed
on main since the previous base.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MC6nEgyED2MtseZ9KdGMpt

* chore: fix new clang-tidy performance findings on macOS

Silence performance-unnecessary-copy-initialization for task runners
captured by Objective-C blocks in the macOS file and message box
dialogs, matching the existing pattern: the copy is needed since a
block would otherwise capture the reference by reference.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MC6nEgyED2MtseZ9KdGMpt

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-23 14:53:40 -07:00
claude[bot]andClaude bea5390a06 build: update build-tools to f3e78a8 (#55285)
Claude-Session: https://claude.ai/code/session_01VtzqDnnQUTDMMgM2SxviUT

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 20:49:15 +00:00
claude[bot]andClaude Opus 5.5 a6d4549ee9 fix: handle a null pending call in dbus::ObjectProxy (#55236)
* fix: handle a null pending call in dbus::ObjectProxy

dbus_connection_send_with_reply() can succeed with a null
DBusPendingCall when the connection is already disconnected.
ObjectProxy::StartAsyncMethodCall() then passes it to
dbus_pending_call_set_notify(), which fails a libdbus argument check and
aborts the process. This made the app spec "when a D-Bus bus goes away >
exits cleanly instead of crashing" end in SIGABRT on Linux.

Add a Chromium patch that runs the callback with a null response, as the
function already does for its other failures.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: add a regression test for the null D-Bus pending call

Extend the dbus::ObjectProxy patch with a dbus_unittests case,
ObjectProxyMockBusTest.NullPendingCallRunsCallbackWithNull, in
dbus/object_proxy_unittest.cc. It uses a MockBus whose SendWithReply()
leaves the pending call null, and checks that the callback runs
asynchronously, exactly once, with a null response and a null error
response. Unlike the Linux bus-loss spec, it does not depend on shutdown
timing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: cover a D-Bus method call made after the bus is lost

Add "app module > when a D-Bus bus goes away > fails a method call made
after the bus is lost instead of crashing". The test runs separate
private session and system dbus-daemons, waits until the app's
org.freedesktop.login1 proxy has connected to the system bus, then
kills the system daemon. Electron quits when Chromium handles the
disconnect, and the fixture's 'quit' handler then starts a login1
method call on the lost system bus. Right after that, it sends a badge
update signal on the session bus. Both buses use the same D-Bus thread,
so the signal reaching the session bus proves the call has run. The
test waits for that signal, lets the app exit, and expects exit code 0.

Without the null pending call fix, the login1 call aborts the app with
SIGABRT. The test waits only on D-Bus traffic and app output, not on
timeouts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 19:57:26 +00:00
Sam MaddockandClaude bc658b2924 fix: extension code drift (#55155)
* fix: report tab ids to extension webRequest and declarativeNetRequest

ElectronExtensionsBrowserClient did not override
GetTabAndWindowIdForWebContents, so the default of -1 reached every
caller: chrome.webRequest reported details.tabId as -1 and
declarativeNetRequest rules with a tabIds condition never matched.
Return the WebContents id, the same id chrome.tabs uses.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: keep extension service workers registered when clearing storage

Chrome's embedder refuses to delete or web-update the registration of
an extension's background service worker and only lets the manifest's
worker script register at the extension's root scope. Electron used
the content defaults, so session.clearStorageData() deleted the
registration and the extension stopped receiving events until it was
reloaded.

Override MayDeleteServiceWorkerRegistration,
ShouldTryToUpdateServiceWorkerRegistration and AllowServiceWorker to
match.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: crash in chrome.cookies.getAllCookieStores

The cookies API now lives in //extensions, so extensions with the
"cookies" permission can call it in Electron. Core code dereferences
ExtensionsAPIClient::GetCookiesApiDelegate(), which Electron did not
provide, crashing the browser process, and the CookiesAPI factory that
dispatches cookies.onChanged is only built by embedders.

Provide a delegate that lists the session as its own cookie store and
build the factory.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: restore the management permission feature

The "management" entry was dropped from Electron's permission features
when the file was resynced with Chrome's in #44653. The management API
feature depends on it, so a manifest requesting the permission lost it
and chrome.management.getAll, get, onEnabled and onDisabled were
unavailable.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: localize messages in extension stylesheets

Chromium substitutes __MSG_*__ placeholders in extension CSS with a
renderer URL loader throttle that only Chrome's throttle provider
installs. Electron had no provider, so placeholders such as
__MSG_@@extension_id__ were left as literal text. Install the throttle
from RendererClientBase.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: let WebSocket activity keep extension service workers alive

Chrome forwards ShouldNotifyServiceWorkerOnWebSocketActivity to the
extensions dispatcher so traffic on a WebSocket resets an extension
service worker's idle timer. Electron did not, so a worker holding an
open socket was still stopped after 30 seconds.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: keep sandboxed extension frames out of the extension process map

Chrome isolates only manifest-sandboxed extension pages (and sandboxed
about:srcdoc and data: documents) in a separate process and leaves that
process out of the extension ProcessMap, so it cannot be granted
extension API access. Electron isolated every sandboxed extension frame
and recorded each of those processes as a privileged extension process.

Override ShouldAllowCrossProcessSandboxedFrameForPrecursor and skip
sandboxed principals in SiteInstanceGotProcessAndSite to match.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: support navigator.clipboard in extension service workers

Chromium exposes navigator.clipboard to extension service workers, but
every piece that enables it lives in Chrome's embedder. Register
chrome-extension as an extension scheme with Blink, pass
--extension-process to extension renderers and turn the runtime feature
on there, and answer IsClipboardAllowedForServiceWorker and
AllowWorkerWriteToClipboard in the browser. Writes still require the
clipboardWrite permission.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: run the extension service worker script on disk after a restart

A service worker registration outlives the app, and Chromium trusts a
stored registration as current while the extension's version is
unchanged. Electron loads unpacked extensions on every launch, so an
extension whose files changed without a version bump kept running the
worker script from the launch that first registered it.

Unregister a worker left by a previous launch before adding the
extension so it is registered again from the files being loaded.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: persist extension alarms and dynamic content scripts

ElectronExtensionSystem returned null for the state, rules and dynamic
user scripts stores, so chrome.alarms and content scripts registered
with persistAcrossSessions were forgotten when the app quit. Create the
three StateStores as Chrome's extension system does.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: report webRequest proxying to the service worker loader

content asks HasWebRequestAPIProxy before starting a service worker
AutoPreload request, because a preload that is raced and dropped is
reported to webRequest listeners as a failed request. Answer for both
Electron's webRequest module and extensions that proxy requests.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: use the app name in extension warnings

ElectronExtensionsClient::GetProductName still returned "app_shell",
the name of the Chromium embedder it was copied from, which extension
warning messages interpolate.

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove stale extension feature entries

These keys name permissions, manifest keys and API functions that
Chromium has removed or that Electron's schemas do not define, so they
matched nothing.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: update extension support notes

The background key is supported for Manifest V3 service workers too,
and chrome.management needs the management permission.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 13:41:53 -04:00
claude[bot]andClaude Opus 5.5 ab1a105caa fix: make DeviceMonitorMessageWindow a NoDestructor (#54809)
* fix: mark leaked serial device observation as dangling on Windows

With dangling raw_ptr checks enabled, the Windows browser process fails
the dangling-pointer check at exit after a page uses navigator.serial.
DeviceService is destroyed after the ThreadPool has shut down, so the
serial enumerator's UI-thread helper is leaked with its observation of
the COM-port DeviceMonitorWin still active when an AtExit callback frees
the monitor. Mark that observation LeakedDanglingUntriaged, as was done
for ElectronUsbDelegate.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xn1qtQBJvK9weVCmD9tLkv

* chore: reference upstream CL in serial dangling patch

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xn1qtQBJvK9weVCmD9tLkv

* fix: notify DeviceMonitorWin observers before destruction

Replace the LeakedDanglingUntriaged annotation with the approach from
upstream CL 8561777: ~DeviceMonitorWin notifies observers, and the
serial enumerator's UI thread helper resets its observation there, so
no raw_ptr dangles when the monitor is freed at exit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xn1qtQBJvK9weVCmD9tLkv

* fix: update DeviceMonitorWin patch to upstream CL 8561777 PS7

Upstream review moved the fix to making DeviceMonitorMessageWindow a
base::NoDestructor instead of notifying observers before destruction.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xn1qtQBJvK9weVCmD9tLkv

* fix: update DeviceMonitorWin patch to upstream CL 8561777 PS8

Adds the DeviceMonitorWin SEQUENCE_CHECKER from patchset 8.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWqmuJ7QaqrgrGccdfquWX

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 17:39:46 +00:00
claude[bot]andClaude ac6b2966ad test: run copyVideoFrameAt specs serially (#55257)
The webFrameMain.copyVideoFrameAt specs clear the system clipboard,
assert it holds no image, and then wait for one to appear. While they
run in the parallel phase, a spec file in another Electron process can
write or clear the clipboard between those steps. Tag the suite serial,
as spec/CLAUDE.md requires for tests that use the system clipboard.


Claude-Session: https://claude.ai/code/session_01AnikcZrheSxnwN9HdN9p3E

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 15:40:33 +00:00
claude[bot]andClaude Opus 5.5 d8cc3947bb test: fix retry-reliant network and utility process specs (#55228)
* test: fix retry-reliant network and utility process specs

- startRemoteControlApp(): the remote-control app quits itself after 30s,
  but sanitizer builds give each test 180s. Slow ASan tests that were still
  talking to the app after 30s failed with "socket hang up" or hung. Pass
  the configured spec timeout as --remote-app-timeout.
- utilityProcess child-process-gone "with default serviceName": every
  unnamed utility process shares this name, and the event for a child that
  exited via process.exit() can land in the next test (as 'killed' on
  Windows). Match this child's event by its exit code.
- webRequest "requests that no blocking listener can match": replace the
  elapsed-time thresholds with a server-side log of served paths that the
  busy main process reads, so the tests check whether the request reached
  the network while the main process was blocked, not how fast it was.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: keep webRequest busy-main checks independent across retries

The served-path log lives for the whole describe block and a vitest
retry re-runs only the test body, so a retried attempt found the
earlier attempt's entries: the precedence check failed on every retry
and the round-trip checks could pass without testing anything. Give
every request that these checks look for its own path.

Also register the forked child in the utilityProcess
'with default serviceName' test with deferKillUtilityProcess, as
spec/CLAUDE.md requires.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: fail fast when the remote-control app exits before it listens

startRemoteControlApp() waited only for the "Listening" line, so when
the app exited or failed to spawn first, the test hung until its
timeout (180s on sanitizer builds). Reject as soon as the child exits
or errors before reporting its port, with its exit code, signal and
stderr, and drop these listeners once the port arrives so that a later
normal exit rejects nothing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: run the default-serviceName child-process-gone test in its own app

Every utility process forked without a serviceName is called "Node
Utility Process", so in the spec runner the child-process-gone event
of an earlier test's child could reach this test's listener. Matching
by exit code only made a collision less likely. Fork the crashing child
inside a remote-control app of its own, where it is the only process
with that name, and read the event there.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 10:35:00 -04:00
claude[bot]andClaude Opus 5.5 45084688a7 fix: close the utilityProcess port before its descriptor is destroyed (#55233)
* fix: close the utilityProcess port before its descriptor is destroyed

A UtilityProcessWrapper that is still alive when the heap is torn down at
exit, for example one whose child had not finished launching when
ElectronBrowserMainParts shut the others down, was destroyed with its
postMessage port still lent to the mojo::Connector. Debug and sanitizer
builds then hit DCHECK(handle_.is_valid()) in MessagePortDescriptor::Reset().

Move the connector and port descriptor onto a NativePeer. Its
TearDownNative() takes the handle back and resets the descriptor, so the
port is closed at MicrotasksRunner shutdown or after collection, never
during cppgc sweeping. The exit-time order (dispatch pending messages,
close the port, emit 'exit') is unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* fix: close the utilityProcess port in the destructor and shut down launching wrappers

Per review, replace the PortLifecycle native peer with a smaller fix:

- ~UtilityProcessWrapper closes the connector port and any stdio read fds
  not yet handed to JS. Both are non-GC members, so this is allowed during
  cppgc sweeping, and it fixes the DCHECK in MessagePortDescriptor::Reset()
  for a wrapper still alive at heap teardown.
- Bind the connector error handler with base::Unretained: the connector is
  owned by the wrapper and destroying it cancels the handler.
- Drop the connector_->is_valid() check in CloseConnectorPort();
  GiveDisentangledHandle() replaces an invalid handle with a dangling one, so
  the port is always reset.
- Track wrappers from construction instead of from launch, and add
  UtilityProcessWrapper::ShutdownAll(), so PostMainMessageLoopRun() also
  shuts down wrappers whose child is still launching before Node.js stops.
  FromProcessId() ignores a null pid.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 10:33:32 -04:00
claude[bot]andClaude e3790be1a2 fix: bind WebRequestHost so blocking chrome.webRequest listeners can finish (#55234)
fix: bind extensions::mojom::WebRequestHost for renderers and service workers

Chromium enables kWebRequestPerContextEventDispatch by default. With it,
the browser keeps a request blocked on a blocking chrome.webRequest
listener until the renderer calls WebRequestHost.EventHandlingDone.
Electron never registered a binder for that channel-associated
interface, so the call was dropped ("Request for unknown
Channel-associated interface: extensions.mojom.WebRequestHost") and the
request could stay blocked.

Register WebRequestEventRouter::BindForRenderer in
ExposeInterfacesToRenderer and
RegisterAssociatedInterfaceBindersForServiceWorker, matching
ChromeContentBrowserClientExtensionsPart.


Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 10:28:27 -04:00
claude[bot]andClaude 6d9ae6c112 test: fix retry-reliant misc specs (#55224)
GDK_BACKEND: wait for the fixture app to exit instead of polling its
output for up to 10s. The old wait let the next launch (the second test
or a retry) overlap the previous copy's shutdown, which on the ASAN lane
pushed the second launch past the 10s limit.

long-animation-frame: check only the long frame that ran the fixture's
busy-loop requestAnimationFrame callback. A slow host can report other
long frames in the same batch with no script or with an unattributed
one, which made the every-entry check resolve false.


Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 10:19:46 -04:00
claude[bot]andClaude 4d38eab74e test: migrate cpp-heap specs to v8 heap snapshot helpers (#55243)
Split out of #55229 and extended per review there.

- heapsnapshot-helpers.js reads V8's flat snapshot arrays:
  takeHeapSnapshot()/parseHeapSnapshot(), countHeapSnapshotNodes(),
  snapshotContainsRetainingPath() and countRetainingPathNodes(). Path
  steps skip weak edges and can also match edge type, edge name, node
  type and detachedness; each node counts once however many paths reach
  it. The old object-graph containsRetainingPath() is removed.
- Every recordState() + containsRetainingPath() check in cpp-heap.spec.ts
  uses the new helpers, and --expose-internals is dropped.
- The node-counting checks (powerMonitor, autoUpdater, the two
  webContents before/after counts and api-ipc's ObjectTemplateInfo count)
  use countHeapSnapshotNodes() over the node array; the occurrences
  checks (three Session roots, one WebFrameMain root) count distinct nodes.
- The renderer cached-templates test keeps webContents.takeHeapSnapshot()
  and counts its markers with countHeapSnapshotNodes() instead of
  createJSHeapSnapshot().
- Tests that make the remote app quit inside remotely() register their
  exit/close listener first, so a fast exit is not missed (19 tests).
- 'should settle an in-flight call stack reply after frame disposal'
  keeps the page running script so the V8 interrupt is serviced, and
  awaits the result instead of racing a 5 s timeout.
- 'should release the root for a detached frame after navigation' runs
  its app with --disable-renderer-backgrounding so the old page's unload
  IPC is not dropped.


Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 10:06:26 -04:00
claude[bot]andClaude Opus 5.5 59227614a2 test: fix retry-reliant gc-lifecycle specs (#55229)
* test: fix retry-reliant gc-lifecycle specs

Replace races with waits on the real event or state in cpp-heap,
webFrameMain and webContents specs that needed vitest's in-suite retry
on main:

- cpp-heap: register exit/close listeners before remotely() triggers
  app.quit(); keep the renderer running script while a call stack is
  collected; keep renderers at foreground priority for the unload-IPC
  test; read heap snapshots as flat arrays for the slow WebFrameMain,
  DevTools and UtilityProcess snapshot tests.
- webFrameMain: foreground priority for the detached-frame test, a fixed
  video box measured after it can play for copyVideoFrameAt, and a
  running page for collectJavaScriptCallStack.
- webContents: wait for 'destroyed' in clone(), for did-stop-loading
  before an in-page loadURL(), and for restore() before executeJavaScript;
  wait for visibilityState in the background throttling specs; parse PDFs
  with pdf.js in-process; and hold the unresponsive-event page in a sync
  XHR the test releases instead of a fixed 40 s spin.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: wait for visibilityState in the first hidden-page throttling spec

'stops producing frames again once re-enabled' checked
document.visibilityState immediately after frames stopped or started,
but the page learns its visibility separately from its widget being
shown or hidden and can still report the old state for a moment. Use
the becomes() helper like the other specs in this describe.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

* test: run detached-frame unload spec in its own app, split out cpp-heap work

'disposes detached frame after cross-origin navigation' needs the old
renderer at foreground priority so its unload IPC is not dropped. Instead
of appending --disable-renderer-backgrounding to the spec runner's own
command line at test time, run the scenario in the remote-control app
launched with that switch. The assertions are unchanged.

The cpp-heap.spec.ts changes and the new heap snapshot helpers move to a
separate PR, as requested in review.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPMvJBQiyP6b7QjatACmnS

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 09:22:47 -04:00
claude[bot]andClaude Opus 5.5 2fb6c26db6 feat: support chrome.storage.sync in extensions (#54088)
* feat: support chrome.storage.sync in extensions

Register a ValueStoreCache for the SYNC settings namespace from
ElectronExtensionsAPIClient::AddAdditionalValueStoreCaches. Until now
Electron never overrode that hook, so StorageFrontend only knew about
LOCAL (and the in-memory SESSION area) and every chrome.storage.sync
call failed with '"sync" is not available in this instance of Chrome'.

ElectronSyncValueStoreCache mirrors Chromium's LocalValueStoreCache but
uses settings_namespace::SYNC, which gives it its own LevelDB directory
under the partition path (kSyncExtensionSettingsDirectoryName), so sync
and local never alias. It enforces the chrome.storage.sync quotas from
extensions/common/api/storage.json (QUOTA_BYTES 102400,
QUOTA_BYTES_PER_ITEM 8192, MAX_ITEMS 512); the per-minute and per-hour
write limits are already applied to kSync by storage_api.cc. There is
no sync service in Electron, so the area behaves like Chrome with sync
disabled: a second local store with no cross-device sync.
chrome.storage.managed stays unsupported because there is no policy
source to back it.

This answers the question raised on #53995 about supporting
chrome.storage instead of dropping sync from the test fixture.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AFucMLGyVVqSUAKXrqbaUT

* fix: include value_store_factory.h in ElectronExtensionsAPIClient

The linux-x64 and linux-x64-ubsan builds failed compiling
electron_extensions_api_client.cc:

  ../../base/memory/scoped_refptr.h:398:6: error: member access into
  incomplete type 'value_store::ValueStoreFactory'
  ../../base/memory/scoped_refptr.h:405:6: error: member access into
  incomplete type 'value_store::ValueStoreFactory'
  note: in instantiation of ... requested here
    electron_extensions_api_client.cc:97:39:
      new ElectronSyncValueStoreCache(factory);

AddAdditionalValueStoreCaches copies the
scoped_refptr<value_store::ValueStoreFactory> into the new
ElectronSyncValueStoreCache, which instantiates AddRef/Release on the
pointee. extensions_api_client.h and electron_sync_value_store_cache.h
only forward-declare ValueStoreFactory, so the translation unit needs
the full definition. Include components/value_store/value_store_factory.h
the same way chrome_extensions_api_client.cc does.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AFucMLGyVVqSUAKXrqbaUT

* test: use vitest matchers in chrome.storage.sync spec

main dropped chai in favour of vitest's own matchers and now lints
against chai-style chains, so convert the chrome.storage.sync spec's
assertions to the equivalent vitest matchers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AFucMLGyVVqSUAKXrqbaUT

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-23 09:16:18 -04:00
claude[bot]andClaude 0e77ca92cd test: wait for GDK_BACKEND fixture exit instead of a fixed 10s poll (#55222)
The GDK_BACKEND specs polled the fixture's stdout with waitUntil's fixed
10s default while ignoring its stderr, and the fixture launched a second
Electron (ELECTRON_RUN_AS_NODE) through a blocking execFileSync. On ASan
builds the two Electron launches can take longer than 10s under load, so
the test has been passing only on retry there and failed all four
attempts on main's ASan shard after the 158.0.8116.0 roll, with no output
to say why.

Wait for the fixture to exit with spawnAndWait, bounded by the per-test
timeout (which sanitizer builds raise), and put the exit code, signal,
stdout and stderr in the assertion message. Have the fixture read the
inherited variable through /bin/sh instead of a second Electron, with a
timeout on execFileSync, and exit with an error instead of hanging if
that fails.


Claude-Session: https://claude.ai/code/session_011SCvSB39Bwi5Fiyo8eAsgn

Co-authored-by: Claude <noreply@anthropic.com>
v47.0.0-nightly.20261023
2026-10-23 12:50:01 +09:00
Sam MaddockandClaude 2dcce8748f docs: ? in preload script globs matches zero or one character (#55209)
The URL filter docs said `?` matches any single character, but globs are
matched with base::MatchPattern, where `?` is optional. Correct the docs
and add a spec for the behavior.

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-22 21:09:20 -04:00
claude[bot]andClaude 16ac8dadf2 build: bump secret-service-action to v1.1.0 (#55216)
Claude-Session: https://claude.ai/code/session_01ELojQikqpZ2KVGqjEeNwUe

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-22 22:47:39 +00:00
claude[bot]andClaude 4d07e30770 build: exclude build-tool PDBs from pdb.zip (#55212)
The win32-x64 pdb.zip has grown past GitHub's 2 GiB per-asset limit, so
release upload fails with a 422. Drop the PDBs of the natives codecache
generators and node_mksnapshot, host build tools that never ship.


Claude-Session: https://claude.ai/code/session_01CNVT3t9ytyoJ9SVMv3pu3z

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-22 21:46:45 +00:00
claude[bot]andClaude 35ac258e35 ci: pre-seed node-gyp headers on Linux too (#55202)
The Linux build/test images ship a node-gyp header cache built with the
image builder's host Node (currently 22.23.3), but the containers run
the nodesource Node (22.23.4), so the cache never matches. Every
native-addon fixture then downloads the headers itself and copies them
into the shared devdir in parallel, truncating headers that an
already-configured fixture is compiling against.

Run the pre-seed on every platform and pass --ensure so it is a no-op
when the cache already matches.


Claude-Session: https://claude.ai/code/session_01Xtmcutqr2Yx3gWuQ7LyDad

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-22 14:26:21 -07:00
a89731b06c chore: bump chromium to 158.0.8116.0 (main) (#55174)
* chore: bump chromium in DEPS to 158.0.8116.0

* 8527713: [Linux] Persist offered GlobalShortcuts portal shortcuts

Upstream BindShortcuts() now looks commands up with find() and falls
back to persisted offered shortcuts whose owner isn't loaded. Moved the
pending bind group tracking into the found branch so unloaded shortcuts
don't resolve a registration.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8527713

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8618876: Add compromised eMudhra intermediates to blocklist.

Upstream now ships the same eight SPKI hashes in
cert_verify_proc_blocklist.inc, so the Electron patch carrying them is
no longer needed.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8618876

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: update patches

* 8615507: Use ChildProcessId in ContentBrowserClient::SelectClientCertificate()

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8615507

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8617940: Roll hunspell_dictionaries and update dictionary versions

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8617940

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8581764: DynamicPatching: Decouple //content from ChildModule

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8581764

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: electron-claude[bot] <279139701+electron-claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-10-22 15:03:40 -04:00
Shelley Vohr 3b24d8f7f6 feat: add app.setActivationToken() on Linux (#54989)
* feat: add app.setActivationToken() on Linux

A Wayland compositor only raises a window when the request carries an XDG
activation token. Electron forwards the tokens it receives at launch and from
its own notifications, but an app that gets one another way, for example from
a notification it sent over D-Bus itself, had no way to hand it over. The new
method sets the token that the next window activation uses.

* fix: document the X11 behavior of app.setActivationToken() and harden its spec

X11 uses the same token as the startup notification ID of the next window that
is created or activated, so the method is not a no-op there. The spec now sets
the token before its window is shown, reads the activation request as it
appears and fails if the child exits instead of skipping.

* docs: say what the token is on X11 in the parameter description
2026-10-22 17:42:23 +00:00