Skip to content

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

Merged
icecrasher321 merged 2 commits into
stagingfrom
staging-v103
Sep 4, 2026
Merged

fix(desktop): render the offline page and server picker in packaged builds#7464
icecrasher321 merged 2 commits into
stagingfrom
staging-v103

Conversation

@icecrasher321

@icecrasher321 icecrasher321 commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

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)

@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Sep 4, 2026 12:10am UTC

Request Review

@greptile-apps

greptile-apps Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR replaces packaged desktop recovery-page file: navigations with an allowlisted sim-shell: protocol and updates the IPC gate accordingly. It also makes the server picker independently dismissible and preserves origin retries after a bundled offline-page failure.

  • Registers and attaches a session-scoped handler for the offline page, server picker, and bundled font.
  • Loads both local pages through sim-shell://pages and restricts shell-control IPC to those exact document URLs.
  • Marks a failed offline page as broken without disabling the normal origin retry loop.
  • Adds packaged and unpackaged coverage for page rendering, picker IPC, Escape handling, and retry behavior.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains.

The previously reported retry issue is fixed: once the bundled page fails, later timer cycles continue loading the configured origin without navigating to the broken offline page again.

Important Files Changed

Filename Overview
apps/desktop/src/main/local-pages.ts Introduces the privileged, session-scoped sim-shell: handler with exact host and filename allowlists and ordered asset roots.
apps/desktop/src/main/load-health.ts Prevents repeat navigation to a bundled offline page after that page fails while retaining the origin recovery timer.
apps/desktop/src/main/server-window.ts Migrates the server picker to sim-shell: and adds main-process Escape and load-failure dismissal paths.
apps/desktop/src/main/ipc.ts Replaces cwd-dependent local-file sender checks with exact bundled-page URL validation.
apps/desktop/e2e/packaged-smoke.spec.ts Adds fused packaged-build coverage proving the offline page and server picker render and cross the local-page IPC gate.

Sequence Diagram

sequenceDiagram
  participant Main as Electron main process
  participant Protocol as sim-shell handler
  participant Page as Recovery page
  participant Origin as Configured server
  Main->>Protocol: load sim-shell://pages/offline.html
  Protocol-->>Page: Serve allowlisted bundled HTML/font
  Page->>Main: Gated shell-control IPC
  Main->>Origin: Retry configured HTTP(S) origin
  alt Origin recovers
    Origin-->>Main: Successful main-frame load
  else Origin remains unavailable
    Main->>Protocol: Show offline page unless marked broken
  end
Loading

Reviews (2): Last reviewed commit: "fix(desktop): keep retrying the origin p..." | Re-trigger Greptile

Comment thread apps/desktop/src/main/load-health.ts
Comment thread apps/desktop/scripts/build.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 18 files

Confidence score: 4/5

  • In apps/desktop/scripts/build.ts, a Turbo cache hit after a clean checkout skips the copy step because only dist/** is cached, leaving the generated font unavailable to bundled pages; include the generated font in cached outputs or ensure the copy runs on cache hits.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/desktop/scripts/build.ts">

<violation number="1" location="apps/desktop/scripts/build.ts:39">
P2: When the desktop build runs through Turbo and hits its cache after a clean checkout, this copy does not run and the generated font is not restored because Turbo only caches `dist/**`. The bundled pages then load with a missing brand font; add the font to the desktop build outputs or make it a tracked/input-derived artifact that Turbo restores.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread apps/desktop/src/main/local-pages.ts
Comment thread apps/desktop/scripts/build.ts Outdated
Comment thread apps/desktop/src/main/load-health.ts
@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@greptile

@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@icecrasher321 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 16 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@icecrasher321
icecrasher321 merged commit 8ddba9a into staging Sep 4, 2026
35 checks passed
@icecrasher321
icecrasher321 deleted the staging-v103 branch September 4, 2026 00:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant