fix(desktop): render the offline page and server picker in packaged builds

Merged
IC
2mo ago
+689-58

Summary

  • Packaged builds since v0.8.13 open the offline page and the Server picker as blank windows. The grantFileProtocolExtraPrivileges fuse is off, and with it Electron no longer routes file: navigations through its asar-aware loader, so loadFile on a page inside app.asar fails with ERR_FILE_NOT_FOUND and the window shows only its background colour. The picker is a modal sheet whose only Cancel button lives in that page, so it could not be closed either. Unpackaged runs never hit this (no asar, default fuses), which is why the e2e suite stayed green
  • Serve both pages over a privileged sim-shell: scheme handled in the main process (exact-file allowlist, per-session handler), which is what Electron's fuse docs prescribe instead of file:
  • Gate the server:/offline: IPC family on that scheme's URLs. The old gate resolved static/*.html against the process cwd, which is / for a Finder-launched app, so packaged builds refused every shell-control call even when the page loaded
  • Close the picker on Escape from the main process and on a main-frame load failure (with a native error), so a sheet can never strand the user again
  • A bundled offline page that failed to load is never navigated to again, while the origin keeps being retried on the usual cadence so the window still recovers on its own
  • Unpackaged runs serve the brand font from the web app's public fonts through the same handler, so nothing generated needs to exist in the tree; packaged builds keep electron-builder's copy in static/ as the only root

Type of Change

  • Bug fix

Testing

  • Unit tests for the scheme handler (allowlist, ordered roots) and URL predicate, the IPC gate, the picker (Escape, failed load), and the load-health retry behaviour
  • Unpackaged e2e asserts the offline page is on sim-shell: with its font loaded, and a new test opens the picker from the offline page, checks the pre-filled value crosses the IPC gate, and closes it with Escape
  • New packaged e2e connects over --remote-debugging-port to the fused build and asserts the offline page renders and the picker opens pre-filled. Passes against a local electron-builder --mac dir build of this branch; fails against the shipped v0.8.19
  • bun run lint, type-check, check:audits, and the desktop unit suite pass

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)