From b1d1221ba64f056ee1c4a491597c86bd96a54379 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sun, 17 May 2026 23:18:30 -0700 Subject: [PATCH] fix(desktop): build preload as CJS so contextBridge actually fires MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit esbuild was emitting preload.js as ESM (format:"esm"), but Electron loads preload scripts via its sandboxed Node context, which is CJS. With an ESM preload, the contextBridge.exposeInMainWorld calls silently no-op, leaving window.fusionShell / window.fusionAPI undefined in the renderer — which is why the dashboard always fell through to "Can't reach the Fusion backend" and DesktopLaunchGate always logged "window.fusionShell unavailable; bypassing". Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/desktop/scripts/build.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/desktop/scripts/build.ts b/packages/desktop/scripts/build.ts index e3dbf1094..728b875ac 100644 --- a/packages/desktop/scripts/build.ts +++ b/packages/desktop/scripts/build.ts @@ -44,7 +44,13 @@ async function buildElectronEntrypoints(): Promise { entryPoints: [join(packageRoot, "src", "preload.ts")], outfile: join(desktopDistDir, "preload.js"), bundle: true, - format: "esm", + // Preload scripts must be CommonJS — Electron loads them via the + // sandboxed Node context, not as ESM. With format:"esm" the + // contextBridge calls silently no-op and window.fusionShell / + // window.fusionAPI stay undefined, which made the dashboard fall + // through to "can't reach the Fusion backend" and the launch gate + // always bypass. + format: "cjs", platform: "node", target: "node22", sourcemap: true,