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 and stamps the renderer with an explicit Islandflow desktop user-agent marker.
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 a reliable desktop shell signal while
the bridge is coming online.
Changes Made
- Added
apps/desktop/src/preload.cjs, a CommonJS preload that exposes window.islandflowDesktop.ai.
- Updated the desktop build script to copy
src/preload.cjs into dist/preload.cjs.
- Pointed the Electron
BrowserWindow preload path at preload.cjs instead of preload.js.
- Added an explicit
IslandflowDesktop/<version> Electron/<version> user-agent token before loading the app URL.
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
an Electron user-agent signature. 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.
Important Implementation Details
- The preload bridge still exposes the same IPC methods, so the web UI contract did not change.
- The user-agent marker is a fallback signal, not the primary bridge. When the preload is healthy,
window.islandflowDesktop remains the source of truth for native controls.
- The app and Electron versions are read at runtime with
app.getVersion() and process.versions.electron.
- The older TypeScript preload source remains in place for now, but Electron no longer depends on its emitted
.js file.
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("islandflowDesktop", bridge);
Expected Impact for End-Users
Opening Settings inside Islandflow Desktop should no longer show the browser-only fallback. Users should
see the managed auth surface, 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, 17 tests.
Issues, Limitations, and Mitigations
- The live GUI was not fully re-driven in this turn; validation focused on the build artifact and bridge detection tests.
- The old
src/preload.ts still exists. A later cleanup can remove or consolidate it after confirming no packaging path still references it.
- An unrelated dirty file,
apps/web/next-env.d.ts, was already present and was not touched by this fix.
Follow-up Work
- Close
islandflow-sc6 after the commit lands.
- Consider adding a lightweight Electron smoke test that asserts
window.islandflowDesktop exists after launch.
- Remove the unused TypeScript preload path once the CommonJS preload has been verified in packaged and dev runs.