Skip to content

🤖 feat: show a Restarting screen immediately on Install & restart - #4244

Merged
ibetitsmike merged 4 commits into
mainfrom
mike/update-restarting-screen
Sep 16, 2026
Merged

ibetitsmike merged 4 commits into
mainfrom
mike/update-restarting-screen

Conversation

@ibetitsmike

@ibetitsmike ibetitsmike commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Pressing Install & restart now swaps the whole UI to a full-screen "Restarting Xum…" screen the moment the install is confirmed, instead of leaving the old UI on screen until the process abruptly restarts.

Background

Both updaters went straight from downloaded to the restart with no status change. On desktop, autoUpdater.quitAndInstall() can block for seconds (Squirrel on macOS fetching the update from electron-updater's local proxy) while the window stays visible; on the npm server the graceful restart (abort streams, close terminals, dispose services) can take up to the teardown budget. The only feedback was a transient "Installing…" button label, cleared by the next status event.

Implementation

  • New restarting variant in UpdateStatusSchema ({ type: "restarting", info: { version } }).
  • src/desktop/updater.ts: emits restarting synchronously before markUpdateInstallInProgress() / quitAndInstall() (real path only; the DEBUG_UPDATER fake path is unchanged so developers are not trapped behind the cover). Retries after an install error reuse the remembered downloaded UpdateInfo. setChannel now refuses while restarting, since resetting to idle there would tear the screen down mid-quit, and updater errors reported through the error event while restarting map to the install phase so the retry stays available.
  • serverUpdater.ts: emits restarting right after the blocker gate passes (also on the forced path), before activateUpdate + restart. Still no await between the idle snapshot, the broadcast, the atomic swap, and the shutdown latch.
  • New self-contained UpdateRestartOverlay (mounted in AppLoaderInner next to <App />, portaled to <body> so an open modal's aria-hidden on the app root cannot hide the status from assistive technology): subscribes to update.onStatus itself, covers the viewport above dialogs/toasts/menus, and deliberately keeps the cover up while api is null during the server reconnect gap; the relaunched server's first status (or an install error) clears it. pointer-events-auto so Radix's modal body lock (About dialog open) cannot let clicks fall through.
  • About dialog closes itself when restarting lands (releasing Radix's focus trap and the aria-hidden it put on the app root) and, if reopened, shows "Restarting to install …" with update actions disabled; title bar badge spins.
  • Storybook: .storybook/main.ts lifts the inline .boot-loader CSS from index.html into the preview head so LoadingScreen-based stories render as they do in the app (they were unstyled before).

Validation

  • Unit tests: restarting is emitted before quitAndInstall / before activate + restart, never while blocked, followed by error/install when activation throws; the overlay appears on restarting, survives api === null, and clears on the next status; setChannel refuses while restarting (red/green checked).
  • Storybook plays for the overlay (desktop + phone-pinned) and the About Restarting story.
  • Remote dogfood UAT (Coder Agents, Storybook + dev-server sandbox against the pushed head) passed: overlay coverage verified at 320 to 1900 px and under scroll/resize, About dialog states, no dev-app regression. Its one finding (the setChannel guard gap) is fixed here.

Risks

  • Low. The new status only flows through the existing update.onStatus stream, and every other consumer ignores unknown-to-them states by falling through to no-ops. If a relaunched server never comes back, the browser client keeps showing the restart screen (no timeout/escape hatch yet); today it would show a reconnect banner over a dead UI instead.
  • The real desktop restart (Squirrel handshake) could not be exercised in the remote UAT; the desktop path is covered by unit tests only.

Xum acted for Mike on this pull request.


Generated with xum • Model: anthropic:claude-fable-5-1 • Thinking: xhigh • Cost: $66.69

Both updaters jumped from "downloaded" straight to the process restart, so
"Install & restart" left the old UI on screen for seconds (Squirrel handshake
on macOS, graceful server teardown on npm) and then the app vanished.

- Add a "restarting" UpdateStatus emitted synchronously once the install is
  going ahead: the desktop updater before quitAndInstall(), the server updater
  after the blocker gate and before activation (also on the forced path).
- New UpdateRestartOverlay covers the whole app the moment that status
  arrives and stays up through the reconnect gap until the relaunched server
  reports another status, or an install error clears it.
- About dialog shows the restarting state and disables update actions; the
  title bar badge spins.
…clicks

- desktop UpdaterService.setChannel now refuses while an install is restarting,
  so the status cannot be reset to idle mid-quitAndInstall (found in UAT)
- UpdateRestartOverlay opts back into pointer events under Radix's modal body lock
LoadingScreen (and the restart overlay) rely on .boot-loader rules that only
exist inline in index.html, so their stories rendered unstyled (top-left, no
sizing). Lift those rules into the preview head from index.html itself.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 13, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-13T21:21:33.903159Z 50dbb7b Manual request
🔒 Security Review Completed 2026-09-13T21:21:32.129778Z 50dbb7b Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 494e51c9ab

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/desktop/updater.ts
Comment thread src/browser/components/AppLoader/AppLoader.tsx
…rrors

- updater errors reported through electron-updater's error event while
  restarting now map to the install phase (retry stays available)
- UpdateRestartOverlay portals to <body> so an open Radix modal's aria-hidden
  on the app root cannot hide the status from assistive technology
- the About dialog closes itself when restarting lands, releasing its focus
  trap and aria-hidden so the restart screen is what keyboard/AT land on
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 50dbb7bf27

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 50dbb7bf27

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
ibetitsmike added this pull request to the merge queue Sep 16, 2026
Merged via the queue into main with commit 643acb9 Sep 16, 2026
35 of 38 checks passed
@ibetitsmike
ibetitsmike deleted the mike/update-restarting-screen branch September 16, 2026 19:24
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