Skip to content

fix(web): offer Update client when the app is behind the server - #5254

Open
matheustimbo wants to merge 7 commits into
pingdotgg:mainfrom
matheustimbo:fix/version-skew-update-direction
Open

fix(web): offer Update client when the app is behind the server#5254
matheustimbo wants to merge 7 commits into
pingdotgg:mainfrom
matheustimbo:fix/version-skew-update-direction

Conversation

@matheustimbo

@matheustimbo matheustimbo commented Aug 3, 2026

Copy link
Copy Markdown

What Changed

  • Fixes [Bug]: Version drift banner says Update server when the macOS client is behind #5253
  • Compare client/server versions with semver and expose outdatedSide from resolveVersionMismatch
  • When the client is behind, show Update client and drive the desktop updater (checkForUpdatedownloadUpdateinstallUpdate)
  • When the server is behind, keep the existing Update server / copy-command paths
  • Update docs/user/updating.md for the client-behind case

Why

The version-drift UI treated the client as canonical and always offered a server update targeting the client version. When a newer server connected to an older macOS/desktop client, that CTA was inverted and could downgrade the server. Direction-aware skew fixes the CTA and routes client-behind cases through the existing Electron updater.

UI Changes

Before

Client behind server, but the banner still offers Update server:

Before: Update server CTA

After

Same mismatch offers Update client, which drives the desktop updater:

After: Update client CTA

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes (N/A — no motion/interaction choreography)

Test plan

  • vp test run apps/web/src/versionSkew.test.ts
  • macOS desktop on an older nightly connected to a newer server: banner says update this client; Update client checks/downloads/installs
  • Newer client connected to an older self-updating server: still shows Update server
  • Web (non-Electron) client behind a server: guidance text only, no Update server button

Note

Medium Risk
Changes version-mismatch CTAs and desktop update orchestration; fixes a prior path that could push server updates toward the client version when the client was actually behind.

Overview
Version mismatch handling now compares client and server with semver and records which side is behind (outdatedSide), instead of always treating the client version as the update target.

When the client is older, the chat banner and Connections show Update client and clientUpdateGuidance() text. On Electron, the new ClientUpdateAction runs the desktop updater (check → download → install) with in-flight state kept outside React so dismiss/navigation does not cancel checks. Non-desktop clients get guidance only—no server update button.

When the server is older, behavior stays on Update server / copy-command paths. Server update progress and failure UI are hidden when the client is the outdated side. Reconnect banners no longer fold into “server restarting” messaging when skew is client-behind.

User docs in docs/user/updating.md describe client-behind vs server-behind actions.

Reviewed by Cursor Bugbot for commit caff1ce. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Show client update controls in chat banner and settings when client is behind the server

  • Adds a new ClientUpdateAction component (ClientUpdateAction.tsx) that on Electron can check, download, and install updates with progress feedback via toasts; on non-Electron it renders static guidance text.
  • Extends versionSkew.ts with resolveVersionOutdatedSide and an outdatedSide field on VersionMismatch, so the UI can distinguish whether the client or server needs updating.
  • Updates the chat banner (ChatView.tsx) and connections settings (ConnectionsSettings.tsx) to show client-focused guidance and ClientUpdateAction when the client is behind, suppressing server update controls and progress in that case.
  • Reconnect-folding in the chat banner no longer applies when the version skew is due to an outdated client.

Macroscope summarized caff1ce.

Detect which side of a client/server version mismatch is outdated so the
banner offers Update client via the desktop updater instead of downgrading
a newer server.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: effe6349-1df4-430b-86c6-7105db87b2e9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 3, 2026
@matheustimbo

Copy link
Copy Markdown
Author

UI before / after

Before (bug)

Client behind server, but CTA says Update server:

Before: Update server CTA

After (fix)

Same mismatch, CTA says Update client and updates this app:

After: Update client CTA

Comment thread apps/web/src/components/ClientUpdateAction.tsx Outdated
Comment thread apps/web/src/components/ClientUpdateAction.tsx
@macroscopeapp

macroscopeapp Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature that offers client updates when the app is behind the server version. The new ClientUpdateAction component (300+ lines) includes non-trivial async update checking, polling logic, and desktop bridge integration. Changes to the version mismatch workflow warrant human review.

You can customize Macroscope's approvability policy. Learn more.

Address Bugbot findings on ClientUpdateAction: continue after check via
subscribed update state instead of the async check return value, and show
guidance when desktop auto-updates are disabled.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/web/src/components/ClientUpdateAction.tsx Outdated
Comment thread apps/web/src/components/ClientUpdateAction.tsx Outdated
Arm the Update client follow-up on checkedAt advancing so a pre-check
idle/up-to-date snapshot cannot clear the pending download path.

Co-authored-by: Cursor <cursoragent@cursor.com>
@matheustimbo

Copy link
Copy Markdown
Author

Babysit note

  • Addressed Bugbot + Macroscope findings on ClientUpdateAction (async check settle + disabled-updates guidance).
  • Fork CI is currently action_required (first-time contributor workflows need maintainer approval): https://github.com/pingdotgg/t3code/actions/runs/30781304061
  • Vercel marketing deploy also needs org authorization for fork PRs — unrelated to this change.

Once CI is approved/run, happy to chase any remaining failures.

Move check-then-download into a module-scoped async flow that polls
settled desktop update state, so dismissing the banner cannot drop the
continuation.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/web/src/components/ClientUpdateAction.tsx Outdated
Avoid clearing local pending state when a second click hits the in-flight
guard; wait for the module-scoped check to finish instead.

Co-authored-by: Cursor <cursoragent@cursor.com>

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit db5f85b. Configure here.

Comment thread apps/web/src/components/ClientUpdateAction.tsx Outdated
Replace localCheckPending/useEffect with useSyncExternalStore over the
module in-flight flag so remounts cannot leave the button stuck disabled.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/web/src/components/ClientUpdateAction.tsx
When checkForUpdate returns checked:false because a concurrent check is
already running, wait for that check to settle (or act on the busy state)
instead of showing a misleading failure toast.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Version drift banner says Update server when the macOS client is behind

1 participant