- Electron desktop app with sidecar CLI binary bundling - Setup page on marketing site with OS-detected download buttons - GitHub Actions workflow for building desktop distributables - Re-enable keychain secrets plugin - Fix React production build (resolve.dedupe) - Support EXECUTOR_SCOPE_DIR env var for scope selection
Showing the changes to apps/desktop/scripts/bundle-cli.js (1 of 13 files). Show all
Unified · Split
| @@ -0,0 +1,58 @@ | ||
| 1 | +/** | |
| 2 | + * Builds the executor CLI binary and copies it into the desktop app's | |
| 3 | + * resources/ folder so electron-builder can bundle it as a sidecar. | |
| 4 | + */ | |
| 5 | +const { execSync, spawnSync } = require("node:child_process"); | |
| 6 | +const { existsSync, mkdirSync, cpSync, chmodSync } = require("node:fs"); | |
| 7 | +const { resolve, join } = require("node:path"); | |
| 8 | + | |
| 9 | +const root = resolve(__dirname, ".."); | |
| 10 | +const repoRoot = resolve(root, "../.."); | |
| 11 | +const cliRoot = resolve(repoRoot, "apps/cli"); | |
| 12 | +const resourcesDir = resolve(root, "resources"); | |
| 13 | + | |
| 14 | +// Build CLI for current platform | |
| 15 | +console.log("Building executor CLI binary..."); | |
| 16 | + | |
| 17 | +// Resolve bun binary path explicitly | |
| 18 | +const { homedir } = require("node:os"); | |
| 19 | +const bunBin = resolve(process.env.BUN_INSTALL || join(homedir(), ".bun"), "bin", "bun"); | |
| 20 | + | |
| 21 | +const result = spawnSync(bunBin, ["run", "src/build.ts", "binary", "--single"], { | |
| 22 | + cwd: cliRoot, | |
| 23 | + stdio: "inherit", | |
| 24 | +}); | |
| 25 | + | |
| 26 | +if (result.error) { | |
| 27 | + console.error("CLI build spawn error:", result.error.message); | |
| 28 | + process.exit(1); | |
| 29 | +} | |
| 30 | + | |
| 31 | +if (result.status !== 0) { | |
| 32 | + console.error(`CLI build failed with exit code ${result.status}`); | |
| 33 | + process.exit(1); | |
| 34 | +} | |
| 35 | + | |
| 36 | +// Find the built binary | |
| 37 | +const platform = process.platform === "win32" ? "windows" : process.platform; | |
| 38 | +const arch = process.arch === "arm64" ? "arm64" : "x64"; | |
| 39 | +const binaryName = process.platform === "win32" ? "executor.exe" : "executor"; | |
| 40 | +const targetDir = join(cliRoot, "dist", `executor-${platform}-${arch}`, "bin"); | |
| 41 | + | |
| 42 | +if (!existsSync(join(targetDir, binaryName))) { | |
| 43 | + console.error(`Binary not found at ${join(targetDir, binaryName)}`); | |
| 44 | + process.exit(1); | |
| 45 | +} | |
| 46 | + | |
| 47 | +// Copy to resources/ | |
| 48 | +mkdirSync(resourcesDir, { recursive: true }); | |
| 49 | +cpSync(join(targetDir, binaryName), join(resourcesDir, binaryName)); | |
| 50 | +chmodSync(join(resourcesDir, binaryName), 0o755); | |
| 51 | + | |
| 52 | +// Copy QuickJS WASM if present | |
| 53 | +const wasmPath = join(targetDir, "emscripten-module.wasm"); | |
| 54 | +if (existsSync(wasmPath)) { | |
| 55 | + cpSync(wasmPath, join(resourcesDir, "emscripten-module.wasm")); | |
| 56 | +} | |
| 57 | + | |
| 58 | +console.log(`Sidecar binary copied to ${resourcesDir}`); | |