Re-sign electrobun's CLI binary so the app actually launches
`bun run start` printed nothing and exited 0 without ever opening a window. electrobun's prebuilt CLI is a Bun single-file executable whose payload is appended after the linker ad-hoc signed it, so `codesign -v` reports "code or signature have been modified" and the macOS kernel SIGKILLs it at exec. The failure was invisible because bin/electrobun.cjs spawns the real binary and forwards `process.exit(code || 0)` — a signal death has `code === null`. Confirmed upstream, not local corruption: a fresh download from the GitHub release hashes identical to the shipped copy and fails the same check. Both the darwin-arm64 and darwin-x64 CLI tarballs are affected. scripts/fix-electrobun-cli.ts re-seals the binary with `codesign --force --sign -`. It runs from postinstall AND ahead of every electrobun invocation, because the wrapper downloads the CLI lazily on first use rather than at install time — postinstall alone would no-op on a fresh checkout. When the binary is missing it provokes that download first, so a clean tree self-heals. It also fixes .cache/electrobun, which the wrapper restores bin/ from, and release.ts re-signs the Rosetta x64 CLI on download and on cache reuse. Idempotent (~0.3s when already valid) and a no-op off macOS. Verified from a deleted-binary state: `bun run start` downloads, re-signs and launches. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -22,12 +22,20 @@ semver-shaped (`0.1.<n>`) for electrobun's config/updater; `BRANDING.buildLabel`
|
||||
- `scripts/node-version-shim.ts` (preloaded via `bunfig.toml`, root AND ui/)
|
||||
fakes a Node version the Angular CLI accepts under Bun. Both preloads are
|
||||
load-bearing.
|
||||
- `scripts/fix-electrobun-cli.ts` re-signs electrobun's prebuilt CLI binary,
|
||||
whose upstream ad-hoc signature is invalid — macOS SIGKILLs it and the app
|
||||
silently never launches, with exit code 0 (see [gotchas.md](gotchas.md)). It
|
||||
runs from `postinstall` **and** at the start of `dev`/`start`/`build`/
|
||||
`release`, because the CLI is downloaded lazily on first use rather than at
|
||||
install time; when the binary is missing it provokes that download first, so
|
||||
a fresh checkout self-heals. Equally load-bearing — removing it means
|
||||
`bun run start` does nothing at all.
|
||||
|
||||
## Release builds
|
||||
|
||||
`bun scripts/release.ts [--target mac-arm64|mac-x64|win-x64]` (default: host).
|
||||
Steps: gen-version → gen-icons → Angular build → `electrobun build
|
||||
--env=stable` → copy/rename artifacts into
|
||||
Steps: gen-version → fix-electrobun-cli → gen-icons → Angular build →
|
||||
`electrobun build --env=stable` → copy/rename artifacts into
|
||||
`release/<target>/miniSCP-Build<n>-<target>.*`.
|
||||
|
||||
Facts the script encodes:
|
||||
@@ -46,6 +54,10 @@ Facts the script encodes:
|
||||
`dist-macos-x64` core into the electrobun package dir on first use, and
|
||||
packages a genuine x64 app. Note: Bun's `fetch`→`Bun.write` streaming hung
|
||||
on the GitHub redirect chain; the script uses `curl -fsSL` deliberately.
|
||||
- **Both CLI binaries need re-signing.** The x64 CLI fetched for the Rosetta
|
||||
path carries the same broken upstream signature as the arm64 one, so
|
||||
`x64Cli()` re-signs it after download *and* on cache reuse; the native path
|
||||
is covered by the `fix-electrobun-cli.ts` step up front.
|
||||
- **Core binary downloads**: the installed npm package ships mac-arm64
|
||||
binaries only; other `dist-<os>-<arch>` cores are fetched from
|
||||
`github.com/blackboardsh/electrobun/releases` at build time — network to
|
||||
|
||||
@@ -31,6 +31,21 @@ touching the adjacent code.
|
||||
|
||||
## Electrobun
|
||||
|
||||
- **The prebuilt CLI binary ships with a broken ad-hoc signature**, so macOS
|
||||
SIGKILLs it at exec and `bun run start` prints nothing and exits **0** —
|
||||
`bin/electrobun.cjs` spawns the real binary and forwards
|
||||
`process.exit(code || 0)`, and a signal death has `code === null`. The binary
|
||||
is a Bun single-file executable whose payload is appended *after* the linker
|
||||
signed it, so `codesign -v` reports "code or signature have been modified";
|
||||
the arm64 and x64 CLI tarballs are both affected upstream (confirmed by
|
||||
hashing a fresh download against the shipped copy — it is not local
|
||||
corruption, and re-installing does not help). `scripts/fix-electrobun-cli.ts`
|
||||
re-seals it with `codesign --force --sign -`. It runs from `postinstall`
|
||||
**and** ahead of every electrobun invocation, because the wrapper downloads
|
||||
the binary **lazily on first use**, not at install time — postinstall alone
|
||||
would no-op on a fresh checkout. It also fixes `.cache/electrobun`, which the
|
||||
wrapper restores `bin/` from. Never read a silent `exit 0` from the
|
||||
electrobun CLI as "nothing happened": run `codesign -v` on it first.
|
||||
- **Window `close` is not cancellable** (response type `{}`; only the
|
||||
app-level `before-quit` supports `event.response = {allow:false}`). All
|
||||
unsaved-state guards must either intercept app-controlled close paths
|
||||
|
||||
Reference in New Issue
Block a user