Repository Turn Document

Fix Electron Codex Bridge Regression

Repaired the Electron desktop ChatGPT/Codex bridge after the Settings screen fell back to the browser-only “Desktop Required” state. The desktop shell now loads its preload bridge from a CommonJS file, exposes an explicit desktop runtime marker, and stamps the renderer with an Islandflow desktop user-agent marker.

Issueislandflow-sc6
ScopeElectron desktop bridge loading
ValidationDesktop build and focused tests passed; web build hit tracked shared-types blocker

Summary

The Electron app was presenting the same fallback shown in a regular browser, which blocked managed ChatGPT login, Codex model loading, and native Copilot controls. The fix makes the preload file unambiguously runnable by Electron and gives the web runtime reliable desktop shell signals while the bridge is coming online.

Changes Made

Context

The visible failure mode was the Settings page labeling the session as browser-only even though it was running inside Islandflow Desktop. That meant the renderer saw neither the native preload bridge nor a desktop-shell signal it trusted. The previous bridge code was emitted as preload.js inside an ESM package, which is fragile for Electron preload loading because the script is intended to run as classic CommonJS. The follow-up patch also protects against Electron user-agent stripping by using a dedicated preload marker.

Important Implementation Details

Relevant Diff Snippets

Snippets are formatted as unified patch text for Diffs-style review. Reference: https://diffs.com/docs.

diff --git a/apps/desktop/package.json b/apps/desktop/package.json
@@
-    "build": "tsc -p tsconfig.json",
+    "build": "tsc -p tsconfig.json && cp src/preload.cjs dist/preload.cjs",

diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts
@@
-const PRELOAD_PATH = fileURLToPath(new URL("./preload.js", import.meta.url));
+const PRELOAD_PATH = fileURLToPath(new URL("./preload.cjs", import.meta.url));
@@
   installNavigationGuards(window);
+  window.webContents.setUserAgent(
+    `${window.webContents.getUserAgent()} IslandflowDesktop/${app.getVersion()} Electron/${process.versions.electron}`
+  );

diff --git a/apps/desktop/src/preload.cjs b/apps/desktop/src/preload.cjs
+const { contextBridge, ipcRenderer } = require("electron");
+...
+contextBridge.exposeInMainWorld("islandflowDesktopRuntime", {
+  shell: "electron",
+  app: "islandflow"
+});
+contextBridge.exposeInMainWorld("islandflowDesktop", bridge);

Expected Impact for End-Users

Opening Settings inside Islandflow Desktop should no longer show the browser-only fallback. If the native bridge itself is unavailable, users should see bridge recovery guidance instead of being told they are not in the desktop app. When the bridge is available, users should be able to connect ChatGPT or Codex, load managed models, and use native Copilot controls from the desktop app again.

Validation

Buildbun --cwd=apps/desktop run build passed.
Desktop Testsbun --cwd=apps/desktop run test passed, 12 tests.
Web Bridge Testsbun test apps/web/app/desktop-ai.test.ts passed, 19 tests.
Web Buildbun --cwd=apps/web run build compiled, then failed on tracked issue islandflow-c8f: shared packages/types imports still use explicit .ts extensions.

Issues, Limitations, and Mitigations

Follow-up Work