From cf64b786118f89c3a0df32fd5d1e5d133af04946 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 6 May 2026 13:18:04 +0000 Subject: [PATCH] fix(deps): fetch electron binary via @electron/get, drop ^41 pin The hotfix in #586 pinned electron to ^41 because electron@42.0.0 removed the postinstall that fetches the prebuilt binary into node_modules/electron/dist/. That left us tethered to electron 41.x and would re-break whenever 41 ages out of npm or the upstream behavior shifts again. This change does the binary fetch ourselves so we no longer depend on electron's postinstall: * New scripts/setup/fetch-electron-binary.js uses @electron/get to download the matching prebuilt binary for the host platform/arch and extract-zip to unpack it into dist/. Reads the version from the installed electron's package.json so it always matches what npm resolved. * setup_electron_asar runs the helper only when npm install leaves dist/ missing. If electron later restores the postinstall, this is a no-op. * Drops the 'electron@^41' pin so we follow latest electron again. * @electron/get honors ELECTRON_MIRROR / ELECTRON_CACHE, so users behind proxies/mirrors keep working without further changes. Refs #584 Co-Authored-By: Claude --- scripts/setup/dependencies.sh | 19 +++++-- scripts/setup/fetch-electron-binary.js | 69 ++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 scripts/setup/fetch-electron-binary.js diff --git a/scripts/setup/dependencies.sh b/scripts/setup/dependencies.sh index 659db05..1b58bdd 100644 --- a/scripts/setup/dependencies.sh +++ b/scripts/setup/dependencies.sh @@ -215,16 +215,25 @@ setup_electron_asar() { if [[ $install_needed == true ]]; then echo "Installing Electron and Asar locally into $work_dir..." - # Pin to electron 41.x: electron@42.0.0 (2026-05-06) dropped the - # postinstall that fetches the prebuilt binary into dist/, leaving - # node_modules/electron/dist absent and the build aborting (#584). - # A durable fix using @electron/get is tracked separately. - if ! npm install --no-save 'electron@^41' @electron/asar; then + if ! npm install --no-save \ + electron @electron/asar @electron/get extract-zip; then echo 'Failed to install Electron and/or Asar locally.' >&2 cd "$project_root" || exit 1 exit 1 fi echo 'Electron and Asar installation command finished.' + + # electron@42+ no longer ships a postinstall script that fetches + # the prebuilt binary into dist/. If npm didn't populate it, fetch + # the matching binary explicitly via @electron/get. See #584. + if [[ ! -d $electron_dist_path ]]; then + echo 'Electron postinstall did not populate dist/; fetching binary explicitly...' + if ! node "$project_root/scripts/setup/fetch-electron-binary.js"; then + echo 'Failed to fetch Electron binary via @electron/get.' >&2 + cd "$project_root" || exit 1 + exit 1 + fi + fi else echo 'Local Electron distribution and Asar binary already present.' fi diff --git a/scripts/setup/fetch-electron-binary.js b/scripts/setup/fetch-electron-binary.js new file mode 100644 index 0000000..b9e8c30 --- /dev/null +++ b/scripts/setup/fetch-electron-binary.js @@ -0,0 +1,69 @@ +#!/usr/bin/env node +// Fetches the Electron prebuilt binary into node_modules/electron/dist/. +// +// electron@42.0.0 (2026-05-06) removed the postinstall script that +// historically populated dist/ during `npm install`. This helper restores +// that behavior using @electron/get + extract-zip, so the rest of the +// build pipeline (which depends on the dist/ layout) keeps working. +// +// Run from the directory containing node_modules/electron. Reads the +// installed electron version from its package.json and downloads the +// matching binary for the host platform/arch. +// +// See: https://github.com/aaddrick/claude-desktop-debian/issues/584 + +'use strict'; + +const fs = require('node:fs'); +const path = require('node:path'); + +async function main() { + const cwd = process.cwd(); + const electronModuleDir = path.join(cwd, 'node_modules', 'electron'); + const distDir = path.join(electronModuleDir, 'dist'); + + if (!fs.existsSync(electronModuleDir)) { + throw new Error( + `Electron module not found at ${electronModuleDir}; ` + + "run 'npm install electron' first.", + ); + } + + const pkgPath = path.join(electronModuleDir, 'package.json'); + const { version } = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); + if (!version) { + throw new Error(`Could not read version from ${pkgPath}`); + } + + const platform = 'linux'; + // node's process.arch values map cleanly to electron release archs, + // except 'arm' which electron publishes as 'armv7l'. + const arch = process.arch === 'arm' ? 'armv7l' : process.arch; + + const { downloadArtifact } = require('@electron/get'); + const extractZip = require('extract-zip'); + + console.log(`Fetching electron@${version} for ${platform}-${arch}...`); + const zipPath = await downloadArtifact({ + version, + platform, + arch, + artifactName: 'electron', + }); + + console.log(`Extracting ${zipPath} into ${distDir}`); + fs.mkdirSync(distDir, { recursive: true }); + await extractZip(zipPath, { dir: distDir }); + + const electronBin = path.join(distDir, 'electron'); + if (fs.existsSync(electronBin)) { + fs.chmodSync(electronBin, 0o755); + } + + console.log('Electron binary fetched and extracted successfully.'); +} + +main().catch((err) => { + console.error(err && err.stack ? err.stack : err); + process.exit(1); +});