When building a Windows Electron app on Apple Silicon macOS, packaging defaults to the host unless you pin the target. In @opencode/desktop, set OPENCODE_TARGET (preferred) so both the Electron build and electron-builder agree on windows-x64 — including native bindings such as @lydell/node-pty-win32-x64.
bun run pack alone does not emit the one-click NSIS .exe. For Windows it uses --dir and copies an unpacked app to the repo-root dist/desktop/app. The NSIS installer is a second pack that wraps a prepackaged app via OPENCODE_DESKTOP_APP (same split the release workflow uses after signing).
Build Windows x64 (unpacked, then NSIS)
From packages/desktop, with the SigmaAgents tab extension selected:
|
Result (repo root):
|
electron-builder also writes the same file under packages/desktop/dist/ during the run; pack copies the single .exe into dist/desktop/. Artifact naming comes from artifactName: "SigmaAgents-${os}-${arch}-${version}.${ext}" (${os} → win).
Pin a stamped version with OPENCODE_VERSION on both build and pack. Channel / icons use OPENCODE_CHANNEL (dev default, beta, or prod / latest).
For Windows ARM64, use OPENCODE_TARGET=windows-arm64 on the same sequence (OPENCODE_DESKTOP_APP still required for the .exe).
RUST_TARGET=x86_64-pc-windows-msvc still works as a fallback for target resolution, but OPENCODE_TARGET=windows-x64 is what the desktop README and release jobs use.
Why two pack steps
script/pack.ts branches on Windows:
- Without
OPENCODE_DESKTOP_APP:electron-builder --dir→ unpackedwin-unpacked→ copy todist/desktop/app. - With
OPENCODE_DESKTOP_APP: strip dangling symlinks in the prepackaged tree, thenelectron-builder --prepackaged <app>→ NSIS (oneClick: true) → copy the.exetodist/desktop/.
Do not point OPENCODE_DESKTOP_APP at packages/desktop/dist/win-unpacked or ../../dist/desktop/app. pack deletes both at startup. Use a copy outside those trees (CI uses $RUNNER_TEMP/app/app).
Caveat: dangling .bin symlinks and 7-Zip
On macOS, packaging used to copy thape-config/node_modules/.bin/* as absolute symlinks into packages/desktop/dist/win-unpacked/.... When the NSIS pack deletes dist/, those links dangle. 7-Zip then exits with warnings (errno=2), and electron-builder treats exit code 1 as failure while building @opencodedesktop-…-x64.nsis.7z.
That is handled in-tree now:
electron-builder.config.tsexcludesnode_modules/.binfrom the bundledthape-config(Unix package-manager shims are unused at runtime).script/pack.tsremoves any remaining dangling symlinks underOPENCODE_DESKTOP_APPbefore--prepackaged.
You no longer need a manual find … -delete before step 4. Old /tmp/sigma-agents-win-app copies from before that fix still work once step 4 runs, because pack strips the dangling links itself.
Verify native bindings
After build, confirm the main bundle targets Windows x64:
|
After the first (unpacked) pack:
|
Without OPENCODE_TARGET (or an equivalent target), you can get an installer that launches but crashes with Cannot find module './windowsTerminal' because the host darwin-arm64 binding was baked in.
Caveat: Code Signing
The .exe built on macOS is not a release-signed Windows artifact. CI packs an unpacked app, signs it on Windows, then runs OPENCODE_DESKTOP_APP=<signed-app> bun run pack, and signs the installer afterward. Local macOS builds skip that pipeline.
CLI build
|