Skip to content

[codex] Restore T3 Connect account controls#3492

Merged
juliusmarminge merged 2 commits into
mainfrom
codex/investigate-account-mobile-relay
Jun 22, 2026
Merged

[codex] Restore T3 Connect account controls#3492
juliusmarminge merged 2 commits into
mainfrom
codex/investigate-account-mobile-relay

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Jun 21, 2026

Copy link
Copy Markdown
Member

Summary

  • add a Clerk UserButton.UserProfilePage for account-level mobile clients
  • show each registered client's push notification, Live Activity, app version, and notification-event status
  • restore Publish agent activity as a nested setting under the local environment's T3 Connect exposure switch
  • serialize preference changes with link/unlink operations and restore stale T3 Connect naming

Root cause

The dedicated cloud settings page originally owned both notification-device status and the activity publication preference. The T3 Connect rebrand removed that page without moving the device view into Clerk. A later connection architecture rewrite also replaced the T3 Connect exposure row and dropped its nested publication toggle, while leaving the relay device APIs and server preference endpoint intact.

Impact

Signed-in users can inspect registered mobile clients from the Clerk account component again. Linked server environments can explicitly opt into publishing agent activity so mobile push notifications and Live Activities receive updates.

Validation

  • vp test run apps/web/src/components/clerk/MobileClientsUserProfilePage.logic.test.ts apps/web/src/cloud/linkEnvironment.test.ts
  • vp check
  • vp run typecheck
  • vp run --filter @t3tools/web build

Note

Restore T3 Connect account controls with mobile client management and agent activity toggle

  • Renames all user-facing copy from "T3 Cloud" to "T3 Connect" across ConnectionsSettings.tsx and related components.
  • Adds a new toggle in the T3 Connect settings row to enable/disable publishing agent activity to mobile clients via the new updatePrimaryEnvironmentPreferences atom command.
  • Adds a "Mobile clients" page to the Clerk user profile (avatar menu) that lists managed relay devices with platform, notification, and Live Activities status using new formatting helpers in MobileClientsUserProfilePage.logic.ts.

Macroscope summarized fddeca8.


Note

Medium Risk
Touches cloud link preferences and what activity is published to mobile clients, but reuses existing connect APIs and serializes preference updates with link/unlink operations.

Overview
Restores T3 Connect account and connection settings that were dropped during the rebrand and connection UI rewrite.

User-facing copy in Connections is updated from “T3 Cloud” to T3 Connect. When a local environment is linked, a nested Publish agent activity switch calls updatePrimaryEnvironmentPreferences (serialized with link/unlink) so the primary environment can opt in or out of sending activity to mobile push and Live Activities.

A Mobile clients tab is added to the Clerk UserButton profile. It lists relay-registered iOS devices (push/Live Activity badges, notification detail, refresh and error retry) via useManagedRelayDevices, with small presentation helpers and unit tests.

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

@coderabbitai

coderabbitai Bot commented Jun 21, 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

Run ID: 06dcfcca-3a77-4fae-934f-5c5ca131fb1f

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
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/investigate-account-mobile-relay

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

@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Jun 21, 2026
@juliusmarminge
juliusmarminge marked this pull request as ready for review June 21, 2026 21:11

@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 3 potential issues.

Fix All in Cursor

Bugbot Autofix prepared fixes for all 3 issues found in the latest run.

  • ✅ Fixed: Error shows empty clients state
    • Added a hasErrorWithoutData guard that renders nothing in place of EmptyMobileClients when an error is present but no cached data exists, so only the error banner is shown.
  • ✅ Fixed: Preference switch stale after update
    • Added optimistic local state (optimisticPublishActivity) that is set immediately on successful update and used as the switch's checked value until the async refresh catches up, preventing the stale display.
  • ✅ Fixed: False empty before relay session
    • Extended the isInitialLoad condition to also be true when devicesState.accountId is falsy (relay session not yet established), showing the loading skeleton instead of the false empty state.

Create PR

Or push these changes by commenting:

@cursor push 85a49a0654
Preview (85a49a0654)
diff --git a/apps/web/src/components/clerk/MobileClientsUserProfilePage.tsx b/apps/web/src/components/clerk/MobileClientsUserProfilePage.tsx
--- a/apps/web/src/components/clerk/MobileClientsUserProfilePage.tsx
+++ b/apps/web/src/components/clerk/MobileClientsUserProfilePage.tsx
@@ -107,7 +107,9 @@
 export function MobileClientsUserProfilePage() {
   const devicesState = useManagedRelayDevices();
   const devices = devicesState.data ?? [];
-  const isInitialLoad = devicesState.data === null && !devicesState.error;
+  const isInitialLoad =
+    !devicesState.accountId || (devicesState.data === null && !devicesState.error);
+  const hasErrorWithoutData = devicesState.error !== null && devicesState.data === null;
 
   return (
     <div className="flex min-h-[30rem] w-full flex-col bg-background text-foreground">
@@ -149,7 +151,7 @@
 
         {isInitialLoad ? (
           <MobileClientsSkeleton />
-        ) : devices.length > 0 ? (
+        ) : hasErrorWithoutData ? null : devices.length > 0 ? (
           <ul className="space-y-3">
             {devices.map((device) => (
               <MobileClientRow key={device.deviceId} device={device} />

diff --git a/apps/web/src/components/settings/ConnectionsSettings.tsx b/apps/web/src/components/settings/ConnectionsSettings.tsx
--- a/apps/web/src/components/settings/ConnectionsSettings.tsx
+++ b/apps/web/src/components/settings/ConnectionsSettings.tsx
@@ -1586,7 +1586,15 @@
   const [operationError, setOperationError] = useState<string | null>(null);
   const [isUpdating, setIsUpdating] = useState(false);
   const [isUpdatingPreference, setIsUpdatingPreference] = useState(false);
+  const [optimisticPublishActivity, setOptimisticPublishActivity] = useState<boolean | null>(null);
 
+  const serverPublishActivity = primaryCloudLinkState.data?.publishAgentActivity ?? null;
+  useEffect(() => {
+    if (optimisticPublishActivity !== null && serverPublishActivity === optimisticPublishActivity) {
+      setOptimisticPublishActivity(null);
+    }
+  }, [serverPublishActivity, optimisticPublishActivity]);
+
   const reportUpdateFailure = (cause: unknown) => {
     const message = cause instanceof Error ? cause.message : "Could not update T3 Connect access.";
     const traceId = findErrorTraceId(cause);
@@ -1689,6 +1697,7 @@
     }
 
     primaryCloudLinkState.refresh();
+    setOptimisticPublishActivity(enabled);
     toastManager.add({
       type: "success",
       title: enabled ? "Agent activity enabled" : "Agent activity disabled",
@@ -1734,7 +1743,11 @@
           control={
             <Switch
               aria-label="Publish agent activity to mobile clients"
-              checked={primaryCloudLinkState.data?.publishAgentActivity ?? false}
+              checked={
+                optimisticPublishActivity ??
+                primaryCloudLinkState.data?.publishAgentActivity ??
+                false
+              }
               disabled={
                 !canManageRelay ||
                 !isSignedIn ||

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 5c536c8. Configure here.

Comment thread apps/web/src/components/clerk/MobileClientsUserProfilePage.tsx
? "This environment can publish agent activity to your mobile clients."
: "This environment will stop publishing agent activity.",
});
setIsUpdatingPreference(false);

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.

Preference switch stale after update

Medium Severity

The "Publish agent activity" switch can display an incorrect state immediately after a successful update. The UI relies on primaryCloudLinkState which updates asynchronously, discarding the updatePrimaryEnvironmentPreferences command's immediate return value. This causes a brief mismatch between the UI and the actual state, even after a success toast.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5c536c8. Configure here.

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

macroscopeapp Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new user-facing features including a mobile clients management page and an agent activity publishing toggle. New feature introductions with user-facing behavior changes warrant human review, and there's an unresolved comment about potential UI state issues.

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

- Treat missing account IDs as initial load state
- Suppress empty list when device fetch errors with no data
@juliusmarminge
juliusmarminge merged commit 8cc9a6f into main Jun 22, 2026
16 checks passed
@juliusmarminge
juliusmarminge deleted the codex/investigate-account-mobile-relay branch June 22, 2026 22:58
simonbetton pushed a commit to simonbetton/reviewer that referenced this pull request Jun 29, 2026
Co-authored-by: Julius Marminge <julius@mac.lan>
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:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant