* perf(dev): clone one Electron dist per repo instead of per worktree
Every worktree extracted its own ~295MB node_modules/electron/dist, measured
at 69GB across 241 worktrees on one machine.
Extract once per repository into <git-common-dir>/orca-cache/electron, then
APFS-clone it into each worktree: copy-on-write, so the second worktree
allocates ~0 bytes and still gets a real, private, writable directory.
Hangs off install-electron-package-binary.mjs, inside the transaction it
already uses to swap dist. Every cache path returns a boolean and false means
"install normally", so non-APFS, cross-volume, corrupt entry, no Git, folder
workspace and CI all keep today's behavior. No symlinks, no lifecycle changes.
out/electron-dev's per-branch Electron.app copy clones too, via the same helper.
Refs #13709
* perf(dev): share the Electron dist on Linux and Windows too
Extends the shared dist cache beyond macOS APFS. Three mechanisms, strongest
isolation first:
macOS APFS cp -c private copy-on-write
Linux btrfs cp --reflink private copy-on-write
ext4 / NTFS hardlink + 0555 shared inodes, forced read-only
Reflinks cover btrfs/XFS/bcachefs/ZFS but not ext4, and Windows block cloning
is ReFS-only, so most Linux and effectively all Windows developers need
hardlinks to get any saving at all. Extracted dist is 327MB on linux-x64 and
374MB on win32-x64, both larger than macOS.
Hardlinks share inodes, so a write through one worktree would rewrite every
sibling and the cache. Nothing in this repo writes inside dist -- every
mutation replaces the directory via rename -- but Electron's own install.js
extracts over an existing dist with O_TRUNC, and is reachable through
`pnpm rebuild electron`. Publishing the entry read-only turns that from silent
cross-worktree corruption into EPERM. Directories stay writable so the install
transaction's renames and unlinks still work.
out/electron-dev's per-branch Electron.app is patched and codesigned after it
is copied, so it uses copyPrivateTree, which never hardlinks.
Refs #13709
* test(dev): keep shared-dist tests honest across ext4 and NTFS
Verified on real hardware: Ubuntu 24.04/ext4 (no reflink support, so the
hardlink tier is the only thing that helps there) and Windows/NTFS.
Three tests faked platform: 'darwin' while invoking the real mechanism, so
they failed on Linux where /bin/cp -c does not exist. Mechanism selection is
now asserted with injected stubs; real filesystem behavior is asserted against
whatever the host actually supports.
Windows maps chmod onto the read-only attribute alone, so a directory never
reports 0o755 and a read-only file reports 0o444. Mode-bit assertions that
encoded POSIX semantics are now behavioral (the tree stays removable), and the
executable-bit assertion is POSIX-only -- confirmed on NTFS that a read-only
hardlinked .exe still runs.
* fix(dev): stop a losing publisher from discarding a good cache entry
Greptile caught a TOCTOU in the shared Electron dist cache. Quarantining an
invalid entry happened before sharing the replacement tree, which takes
seconds -- long enough for a sibling worktree to publish a good entry that this
one would then rename away. If the follow-up publish also failed, the cache was
left empty and every worktree re-downloaded.
Stage first, then re-validate immediately before the destructive rename, so an
entry that became good during the share is kept. On a failed swap, restore the
quarantined entry instead of leaving no entry at all: a stale entry still beats
an empty cache, because the next publisher re-validates and replaces it. An
entry that cannot be validated is never displaced, matching the pre-staging rule.
Also covers the Electron upgrade path end to end: a version bump gets its own
cache entry and leaves the previous one for worktrees still on the old branch.
* feat(dev): add a script to share existing worktrees' Electron dists
An install only shares when Electron is (re)installed, and rebuild-native-deps
returns early when the package is already usable -- so a worktree that already
has a working dist never reaches the sharing path and keeps its own copy until
the next Electron upgrade.
pnpm reclaim:electron-dists reports what it would share; --apply does it.
Each worktree is converted behind a rename, so an interrupted run leaves a
working dist either way, and any worktree that fails is left untouched.
Measured on one machine: 677 worktrees, ~195 GiB reclaimable.
* fix(dev): keep the reclaim script's error formatting type-safe
* fix(build): preserve Electron during binary repair
* refactor(build): split native dependency fixtures
* fix(build): resolve one Electron install target for child and check
runElectronPackageBinaryInstall forced ELECTRON_INSTALL_PLATFORM/ARCH to the
host-derived rebuild target, clobbering inherited installer env, while the
parent usability check still honored the inherited value. A bare
`node config/scripts/rebuild-native-deps.mjs` under ELECTRON_INSTALL_PLATFORM=win32
on Linux therefore installed the Linux binary and then rejected it as
unavailable. Resolve the target once (CLI, ELECTRON_INSTALL_*, npm config, host)
and use it for both the child env and getElectronPlatformPath.
* fix(build): keep Electron install transaction cleanup best-effort
The finally-block rmSync could throw after a fully successful publish (Windows
EPERM when another process still holds the discarded old electron.exe open),
turning a correct install into exit 1. On the rollback path it could also
replace the in-flight publishError with an unrelated temp-dir error. Retry the
removal and downgrade a persistent failure to a warning.
* Extract AutomationTimeField component with improved digit input
Moves time parsing and selection logic into a reusable component
with enhanced UX: arrow key stepping, auto-commit on 2-digit entry,
and improved validation. Refactors AutomationSchedulePicker to use
the new component, reducing code duplication.
* fix(renderer): stop mutating clockRef during AutomationTimeField render
Move the prop→ref sync into useEffect so React Doctor no longer fails static analysis on ref writes during render. patchTime still updates the ref immediately for concurrent digit commits.
* fix(renderer): improve AM/PM toggle accessibility in AutomationTimeField
- Aria-label now includes current period (AM/PM) so screen readers announce which is selected
- Add aria-pressed attribute to communicate toggle button state
- Move translation keys to AutomationTimeField namespace reflecting component extraction
* fix(ci): retry Electron install on HTTP/2 stream and Fetch 503 errors
CI shards failed before tests when GitHub release downloads refused HTTP/2
streams or returned Fetch Response.status 503, which were not classified as
transient and skipped retries.
* fix(ci): give Electron package downloads more retry headroom
GitHub release CDN still returned 503 after the short 3-attempt budget under
CI fan-out; extend the default backoff so install can recover.
Migrate fileURLToPath(import.meta.url) / dirname(...) boilerplate to the
native import.meta.dirname / import.meta.filename, then enable the rule
at error so new code stays on the native form.
The oxlint autofix rewrites the expression but leaves the now-unused
node:url / node:path imports behind (which the already-enabled
no-unused-vars=error would then flag), so this commit also removes those
34 orphaned imports — trimming the named import where other names are
still used, deleting the line where it was the sole import.
Scope is build scripts + Node-env tests only (config/scripts, tools/
benchmarks, *.test.{ts,mjs}, vitest configs); zero shipped runtime code.
The native properties are exact equivalents (Node >= 20.11; repo is on
24), so behavior is unchanged.
Verified: oxlint 0 errors tree-wide (root + mobile), oxfmt clean,
typecheck (node+cli+web) + mobile tsc pass, root vitest 22825 passed /
0 failed, mobile vitest 1018 passed. Exercised the rewritten scripts
directly: build:relay (6 targets), ensure-native-runtime,
verify-macos-entitlements all run correctly with import.meta.dirname.