With ${arch} in artifactName and both x64 and arm64 NSIS targets,
electron-builder also publishes per-arch installers. The arm64-only one
installs nothing on x64 machines but still creates shortcuts and an
uninstaller, leaving a broken install.
Give nsis its own artifactName without ${arch} so only the universal
installer is built, and abort an arm64-only installer on non-ARM64
Windows as a safeguard.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Pin Linux ARM jobs to ubuntu-24.04
ubuntu-latest is now Ubuntu 26.04, which no longer packages
qemu-user-static. Both the workflow's QEMU setup step and
arm-runner-action install it, so the ARM builds fail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Support scroll on linux
* Close tab on middle-click of the X button too
The X icon only had onClick, which browsers never fire for the middle
button. Wire it to the same middle-click handler already used on the
tab body so middle-clicking the X closes the tab like clicking
anywhere else on it does.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Spawn shell via flatpak-spawn --host on Flatpak builds
The Flatpak build sandboxes the shell inside the app's mount namespace,
so PATH ends up as whatever the runtime provides (/app/bin:/usr/bin)
with no access to /usr/local or /home/linuxbrew, unlike an unsandboxed
terminal like Konsole. Route the pty through flatpak-spawn --host so
the shell actually runs on the host and its --login profile computes a
normal host PATH, and grant the org.freedesktop.Flatpak talk-name the
portal needs for this.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Document Flatpak shell-spawning fix and bare-shell-name limitation
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Fix prettier lint in session.ts and tabs.tsx
Both fit within the 120-column print width, so prettier wants them on
one line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Writes Casks/quine-hyper.rb in quine-global/homebrew-tap (canonical on
Forgejo, over SSH on port 2200) using the release's dmg digests. Needs a
HOMEBREW_TAP_SSH_KEY secret whose public key is a write deploy key on
the tap.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
windows-latest now ships Visual Studio 2026 (18.x). electron-builder's
bundled @electron/rebuild@4.0.3 (used by `electron-builder install-app-deps`)
pins node-gyp@^11.2.0, which doesn't know about VS 2026 and fails with
"Could not find any Visual Studio installation to use" when rebuilding
native modules like native-process-working-directory.
Add a pnpm override (and matching yarn-style resolution) pinning
node-gyp to ^12.3.0 everywhere, including nested copies, since 12.1.0+
added VS 2026 detection.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Flatpak is the primary app delivery mechanism on immutable Fedora
Atomic desktops like Silverblue and Aurora, which don't support
traditional deb/rpm installs well. This wires up electron-builder's
built-in flatpak target, pinned to the current org.electronjs.Electron2.BaseApp
runtime (25.08) with Wayland-first sandbox permissions, and installs
flatpak-builder plus the Flathub remote in CI so the bundle builds
and ships alongside the other Linux artifacts.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Guard validate-tag and upload-release behind github.ref_type == 'tag'
so manual workflow dispatches from non-tag branches don't fail the
tag-version check or attempt to create a GitHub release.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add explicit `if` to upload-release job so it isn't skipped when
validate-tag is skipped (canary branch triggers workflow_dispatch)
- Bust pnpm cache key prefix (pnpm- → pnpm-store-) to avoid
deserialization failures from old actions/cache v3/v4 entries
- Allow cache saves on workflow_dispatch in addition to push
- Add missing cache/save step to build-linux-arm action
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore(updater): switch auto-update feed to Quine Global endpoint using query parameters
The client now calls https://hyper.quineglobal.com/update (and /api/update-check)
with query params instead of the old releases.hyper.is / releases-canary.hyper.is
subdomain paths.
- Uses platform, arch, version, and channel parameters.
- Supports explicit channel=canary so users on stable builds can still opt into
canary updates via config.
- Pairs with corresponding server-side changes in hyper-quineglobal-com.
* Fix prettier
Duplicate @types/react TypeScript error (package.json, pnpm-lock.yaml)
What: Added "pnpm": { "overrides": { "@types/react": "18.3.12" } } to the root package.json.
Why: @types/react-dom@18.3.1, @types/hoist-non-react-statics, and @types/styled-jsx all declare @types/react:
"" as a plain dependency. With yarn this was resolved by the resolutions field. With pnpm, resolutions is
ignored — pnpm only reads pnpm.overrides. Without the override, each of those packages resolved "" to the
latest @types/react@19.1.2 and nested it under their own node_modules/. TypeScript then saw two incompatible
definitions for the same React types simultaneously, producing the TS2344: Type 'C' does not satisfy the
constraint 'ComponentType' error in react-redux/es/types.d.ts.
The nested @types/react@19.1.2 directories were also stale artifacts from pre-override installs — pnpm's
--force flag reinstalls packages but does not scrub orphaned nested node_modules subdirectories. They were
removed manually, and the pnpm.overrides prevents them from reappearing on future installs.
Cannot find module 'execa' crash at app startup (app/package.json, app/session.ts)
What: Upgraded shell-env from 3.0.1 to 4.0.3, added execa@5.1.1 as a direct app dependency, removed
os-locale@5.0.0, replaced its one usage with Intl.DateTimeFormat().resolvedOptions().locale, and updated the
shellEnv.sync() call to the new named export shellEnvSync.
Why: This was a layered problem rooted in how electron-builder packages the app when using pnpm.
electron-builder builds the asar by walking pnpm's flat (hoisted) node_modules dependency tree. When two
packages need incompatible major versions of the same dependency, pnpm cannot hoist both — it puts the
minority version in a nested node_modules/ inside the requiring package's directory. electron-builder's pnpm
integration only scans the flat level; it emits "dependency not found on disk" for anything nested, and those
nested packages are silently excluded from the asar.
shell-env@3.0.1 needed execa@^1.0.0. The hoisted top-level was execa@4.1.0. So pnpm nested execa@1.0.0 under
node_modules/shell-env/node_modules/execa/. electron-builder missed it. At runtime, require('shell-env') →
require('execa') → crash, even on macOS where the shellEnv.sync() call is never actually reached (the import
itself triggers the error).
Upgrading shell-env to 4.0.3 alone would have just shifted the nesting from execa@1 to execa@5 (since 4.0.3
uses ^5.1.1). And os-locale@5.0.0 used ^4.0.0, which would then become the nested one instead. There is no
version of either package where both use the same execa major, so they can't both be hoisted simultaneously.
The fix makes execa@5.1.1 the explicit top-level dependency. shell-env@4.0.3 (needs ^5.1.1) is satisfied
without nesting. os-locale is removed entirely and its one call site replaced with
Intl.DateTimeFormat().resolvedOptions().locale, which returns the same locale string from a V8 built-in — no
execa chain at all.
CI frozen-lockfile failure inside electron-builder install-app-deps (app/.npmrc)
What: Added frozen-lockfile=false to app/.npmrc.
Why: target/ is the electron-builder app directory and is fully gitignored. That means target/pnpm-lock.yaml
is never committed. In CI, pnpm automatically enables frozen-lockfile=true when it detects CI=true in the
environment — this applies to every pnpm invocation in the process tree, including child processes.
The postinstall sequence is: webpack copies app/ to target/ → electron-builder install-app-deps runs pnpm
install inside target/. Because app/.npmrc contains ignore-workspace=true, pnpm treats target/ as a standalone
project rather than part of the workspace, and looks for a target/-local lockfile. On a fresh CI checkout
there is none. With frozen-lockfile=true inherited from the CI environment, pnpm refuses to generate one and
exits with ERR_PNPM_OUTDATED_LOCKFILE.
Locally this was invisible because target/pnpm-lock.yaml accumulated from previous runs and was simply reused.
Adding frozen-lockfile=false to app/.npmrc (which webpack copies to target/.npmrc) overrides the CI
environment default specifically for the target/ context, allowing pnpm to generate a fresh lockfile on each
CI run.
app/session.ts locale — removal of os-locale
Already covered under point 2, but worth noting separately: osLocale.sync() was the only call site.
Intl.DateTimeFormat().resolvedOptions().locale is a direct replacement — it returns the OS locale (e.g. en-US)
in the same format, available in all modern Node/Electron versions with no external dependencies. The
.replace(/-/, '_') transforms it to POSIX LANG format (en_US) exactly as before.
Restores RPM generation that was dropped in #98 to fix CI. Also adds
*.rpm to the artifact upload list in the build action.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add troubleshooting
* fix(cli-install): lazy-require native-reg to fix TS error on non-Windows
native-reg is a Windows-only optional dependency that can't be resolved
at compile time on macOS/Linux. Move the require() inside addBinToUserPath
and add an explicit platform guard that rejects early before the Promise
is constructed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore(deps): pin electron-link to quine-global v0.7.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix devtools patch
* Fix type error
* fix(snapshot): avoid npm_config_arch polluting node-gyp-build on cross-arch builds
electron-link depends on classic-level (via node-gyp-build), which reads
npm_config_arch to select its native prebuild. Setting npm_config_arch=arm64
on an x64 host caused it to dlopen the arm64 .node binary, crashing the
v8 snapshot build. Switch to a dedicated SNAPSHOT_TARGET_ARCH env var that
only mk-snapshot.js and cp-snapshot.js read, keeping npm_config_arch unset.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix type error
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>