feat(android): implement T3 Connect end to end#3926
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
…ew env Android push (T3 Connect) requires FCM: without google-services.json in the APK, expo-notifications cannot mint an Expo push token and device registration silently degrades. Wire android.googleServicesFile from the T3CODE_ANDROID_GOOGLE_SERVICES_FILE EAS file variable (sensitive visibility so preview CI can pull it for the native fingerprint), validate the file registers the variant's Android package, and fail Android EAS preview builds fast when the variable is missing so a broken-notifications APK can never build again. Delivery stays app -> Expo push token -> relay -> Expo Push Service -> FCM; no firebase SDK is added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
preferences.test.ts and linkEnvironment.test.ts import modules that transitively reach expo-crypto, whose expo-modules-core import reads the React Native __DEV__ global that does not exist under the node test runner. Mock the native modules like the sibling suites already do. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ApprovabilityVerdict: Needs human review This PR introduces a complete new feature (Android push notifications) with database schema migrations, new Expo push delivery infrastructure, contract changes, and cross-cutting modifications. New features with schema impact and significant runtime behavior warrant human review. You can customize Macroscope's approvability policy. Learn more. |
- Android alerts now mirror the iOS transition rules: they ring only when a thread newly enters an attention phase or freshly finishes relative to the per-device last-delivered aggregate, so republishes, reconnect replays, and stale completions stay silent. The shared transition logic moves to agentActivityTransitions.ts and ApnsDeliveries delegates to it. - An alert-eligible publish also repaints the quiet status notification when live updates are enabled, so the shade never shows stale running content beside a completion alert. Expo deliveries persist the delivered aggregate via LiveActivities.markDelivery (and advance it silently on drift when the status channel is off) so transitions have a baseline. - Android device registrations are authoritative for expoPushToken: a re-registration without a token (permission revoked) clears the stored one instead of coalescing it back. - Android FCM token rotations carry a monotonic marker so they are never coalesced into an in-flight registration that already read the pre-rotation token. - The mobile clients profile page treats an omitted androidApiLevel like null instead of rendering 'Android API undefined'. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f2a839b. Configure here.
Advancing the transition baseline on any accepted delivery meant a successful quiet status could consume an attention/terminal transition whose high-priority alert failed, and the missed ring would never retry. The baseline now only advances when the alert (if one was due) was accepted, so the next publish recomputes and retries the transition. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The claims null the unique push-token columns on whichever rows own them before the upsert re-inserts them on the registering device. Running them as separate statements meant a failed upsert stranded the token — cleared from its old row, owned by none — silently disabling push delivery until the next successful registration. The claims and upsert now commit atomically so a failure rolls the claims back. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Summary
Implements T3 Connect end to end for Android using the existing Expo Push Service. No direct Firebase integration or new push provider is introduced.
Root cause
Android preview builds could authenticate, but first-run mobile identity creation could fail before environment bootstrap. The mobile registration and agent-awareness delivery paths were also iOS-only, so Android could not register an Expo push token or receive T3 Connect status and actionable updates.
What changed
Validation
vp check(0 errors; 9 pre-existing React warnings)vp run typecheckvp run lint:mobile(native source scan passed; optional local SwiftLint/ktlint/detekt tools were unavailable)com.t3tools.t3code.previewTesting note
End-to-end push testing requires a preview/dev-client build produced with the existing Expo/EAS Android push credentials and a relay deployment containing this migration and worker code. The repository does not add or configure Firebase.
Note
High Risk
Touches relay push delivery, DB migration with a unique
expo_push_tokenindex, and device registration transactions; mis-deployed migration or missing EAS credentials can break preview builds or silently disable Android push until a new native build.Overview
End-to-end Android T3 Connect now registers devices with Expo push tokens, embeds Firebase via
google-services.json, and delivers agent status and alerts through the relay’s Expo Push Service path while iOS APNs / Live Activities stay unchanged.On mobile, Android joins agent-awareness registration:
expo-notificationsplugin and notification channels, permission flow,expoPushTokenin relay payloads, FCM rotation handling, settings copy for Android, and more resilient device ID creation and connection when identity load fails.On relay, a migration adds
expo_push_token,android_api_level, and delivery-provider fields; device registration is transactional with Expo token claim/invalidate rules;ExpoPushClient/ExpoPushDeliveriessend quiet status vs high-priority alerts (shared transition logic with APNs); receipts reconcile and bad tokens are cleared.CI/docs require
T3CODE_ANDROID_GOOGLE_SERVICES_FILEfor EAS preview fingerprinting; credentials are gitignored.Reviewed by Cursor Bugbot for commit cf7ea38. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Implement Android push notifications end-to-end via Expo push delivery
platform: 'android',androidApiLevel, andexpoPushTokento the relay; iOS registration behavior is unchanged.ExpoPushClientandExpoPushDeliveriesrelay services that send Expo push messages for Android targets and periodically reconcile Expo receipts via a new cron step in the relay worker.expo_push_token,android_api_level, and provider metadata columns (delivery_provider,provider_status,provider_id) on delivery attempts and mobile devices.configureAgentAwarenessNotificationChannelsto create two Android notification channels (t3-connect-activityandt3-connect-alerts) and gates these on Android at runtime; notification permission and settings UI now supports Android.newlyAttentionRows,freshNewlyTerminalRows,shouldUpdateLiveActivity) intoagentActivityTransitions.tsandagentAwarenessPreferences.ts, consumed by both APNs and Expo delivery paths.resolveAndroidGoogleServicesFilebuild-time validation forgoogle-services.jsonand fails the EAS preview CI job early if the file is missing.expo_push_tokenwill reject duplicate tokens at the DB level;ios_major_versionis now nullable, requiring any code that assumed it was non-null to handle null.Macroscope summarized cf7ea38.