Commit Graph
12 Commits
Author SHA1 Message Date
Neil fe0f2f9be7 perf(dev): share one Electron dist per repo instead of per worktree (#17664)
* 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
2026-08-31 20:35:54 -07:00
Jinjing d2aab68ae7 Automations ux improvement (#17626)
* Add keyboard navigation to automations UI

Improves workflow efficiency by enabling keyboard-driven navigation
across automations list, run history, and detail pane tabs.

* Add Escape key support to automations detail pane

Pressing Escape now clears external and automation run page views,
then returns to the automations list. Also improves cross-browser
compatibility of keyboard event handling by using Element checks and
getAttribute instead of dataset access.

* Fix keyboard navigation to let Enter key reach focused controls

- Enter key now passes through to focused buttons, links, and other interactive controls
- Arrow key navigation through automation run history still works
- Prevents intercepting native keyboard behavior of interactive elements

* improve test

* Move keyboard focus to follow row selection

When navigating automation runs with arrow keys, focus must follow the selection so Enter key acts on the newly selected row rather than the previously focused one.
2026-08-31 18:37:19 -07:00
OrcaWin 1ec13cbda2 Speed up CI dependency and computer E2E setup (#17513) 2026-08-30 18:19:08 -07:00
Neil b261f4005c fix(build): preserve Electron during binary repair (#17334)
* 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.
2026-08-29 23:12:25 -07:00
Jinjing e4c278eb52 Extract AutomationTimeField component with improved digit input (#13975)
* 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.
2026-08-12 14:40:39 -07:00
Neil 0f91af821d ci: parallelize PR checks and accelerate Vite builds (#10989)
* ci: parallelize and accelerate PR checks

* fix(ci): make accelerated checks runtime-safe

* fix(ci): address review findings

* fix(ci): retry transient Electron downloads

* test(ci): cover Electron download retry limits
2026-07-27 13:32:29 -07:00
Neil 1009ac9083 chore: update Electron to 42 (#3919) 2026-05-30 13:26:48 -07:00
Neil 77f5b2ad9d Preserve Electron framework symlinks (#2958)
Preserve Electron framework symlinks
2026-05-27 18:13:25 -07:00
Neil a76b7b764c Extract Electron package with host unzip (#2957)
Extract Electron package with host unzip
2026-05-27 18:03:55 -07:00
Neil 82b6ccb1a9 Await Electron package installer (#2956)
Await Electron package installer
2026-05-27 17:54:41 -07:00
Neil 4df9d32da3 Verify Electron archive before package install
Extract Electron downloads out-of-tree and verify the expected executable before replacing node_modules/electron/dist.
2026-05-27 17:41:18 -07:00
Jinwoo HongandOrca f0fbe5be7f Align incoming git graph boundary lanes (#2934)
Co-authored-by: Orca <help@stably.ai>
2026-05-27 17:04:36 -07:00