feat(mobile): show agent activity in an Android home screen widget #35965
OpenGarberchov(GitHub profile, opens in a new tab)wants to merge 2 commits into
main fromrefs/pull/35965/headopened View on GitHubtanstack-source added labelsfeature
github-actions[bot](GitHub profile, opens in a new tab) added labelsvouch:unvouched
github-actions[bot](GitHub profile, opens in a new tab) added labelssize:L
github-actions[bot](GitHub profile, opens in a new tab) added labels📱 Native Change
- apps/mobile/src/widgets/AgentActivityWidget.android.tsx lines 67 to 70Outdated@@ -0,0 +50,21 @@50+ const summary =51+ attentionCount > 052+ ? `${attentionCount} need${attentionCount === 1 ? "s" : ""} attention`53+ : workingCount > 054+ ? `${workingCount} active`55+ : rows.some((row) => row.phase === "stale")56+ ? "Out of date"57+ : rows.some((row) => row.phase === "failed")58+ ? "Failed"59+ : rows.length > 060+ ? "Done"61+ : "T3 Code";62+ const limit = 4;63+ const hidden = rows.length - limit;64+65+ return (66+ // Android lacks widgetURL; one card Button routes taps to the app listener.67+ <Button68+ colors={{ containerColor: colors.surface }}69+ modifiers={[fillMaxSize()]}70+ onClick={() => {}}apps/mobile/src/widgets/publishAgentActivityWidget.android.ts lines 24 to 25Outdated@@ -0,0 +5,21 @@5+ agentActivityWidgetSnapshot,6+ type AgentActivityWidgetSource,7+} from "./agentActivityWidgetTimeline";8+9+let tapUrl: string | undefined;10+let listening = false;11+12+export async function publishAgentActivityWidget(source: AgentActivityWidgetSource) {13+ if (!requireOptionalNativeModule("ExpoWidgets")) return;14+ const [{ default: widget }, { addUserInteractionListener }] = await Promise.all([15+ import("./AgentActivityWidget"),16+ import("expo-widgets"),17+ ]);18+ const snapshot = agentActivityWidgetSnapshot(source, Date.now());19+ const deepLink = snapshot.activities[0]?.deepLink;20+ tapUrl = Linking.createURL(deepLink?.startsWith("/") ? deepLink.slice(1) : "");21+ if (!listening) {22+ // expo-widgets lacks Android widgetURL. Button events need a live JS runtime to open the app.23+ listening = true;24+ addUserInteractionListener((event) => {25+ if (event.source === "AgentActivity" && tapUrl) void Linking.openURL(tapUrl);
- apps/mobile/src/widgets/AgentActivityWidget.android.tsx line 22@@ -0,0 +2,21 @@2+import { fillMaxSize, fillMaxWidth, padding, paddingAll } from "@expo/ui/jetpack-compose/modifiers";3+import { createWidget, type WidgetEnvironment } from "expo-widgets";4+5+import type { AgentActivityPhase } from "./AgentActivity";6+import type { AgentActivityWidgetSnapshot } from "./agentActivityWidgetTimeline";7+8+// Android counterpart of the iOS Agent Activity widget, with the same header,9+// row layout, and phase colors. The publisher sorts the rows, so the first one10+// is the thread that most needs the user.11+export function AgentActivityWidget(12+ publishedProps: Partial<AgentActivityWidgetSnapshot> | undefined,13+ environment: WidgetEnvironment,14+) {15+ "widget";16+ // The widget runtime evaluates this function without the app's module scope.17+ // Before the app's first publish, the embedded layout renders with no props.18+ const props = publishedProps ?? {};19+ const light = environment.colorScheme !== "dark";20+ const background = light ? "#ffffff" : "#1c1c1e";21+ const primary = light ? "#000000" : "#ffffff";22+ const secondary = light ? "#8e8e93" : "#98989f";
Sign in to join this conversation.




Walkthrough
The pull request adds an Android Agent Activity widget. It builds and publishes ordered activity snapshots, renders activity status and rows, and enables Android remote registration without Live Activity reconciliation.
Changes: Android Agent Activity widget
apps/mobile/src/widgets/agentActivityWidgetTimeline.ts,apps/mobile/src/widgets/agentActivityWidgetTimeline.test.tsapps/mobile/src/widgets/AgentActivityWidget.android.tsxapps/mobile/src/features/agent-awareness/remoteRegistration.ts,apps/mobile/src/features/agent-awareness/remoteRegistration.test.ts,apps/mobile/src/widgets/publishAgentActivityWidget.android.ts,apps/mobile/app.config.ts,docs/user/mobile-notifications.mdEstimated code review effort: 3 (Moderate) | ~20 minutes
Change: Feature
Sequence Diagram(s)#
Suggested reviewers:
macroscopeappMerge Risk:
Moderate · up to
b85fdTapping any agent row on the Android widget opens the first thread. Taps may also do nothing if Android has reclaimed the app process. Fix thread navigation before merge or explicitly accept the limitation.
Pre-merge checks:
4
android: null) and gives a clear change breakdown per file. It links a …Full details: Title check
Explanation
The title "feat(mobile): show agent activity in an Android home screen widget" matches the main change: a new Android home screen widget for Agent Activity, which previously existed only on iOS. It is a conventional commit title in plain language, and it names the platform and the feature. The title does not mention the snapshot publishing, the foreground refresh change, or the docs update, but those are supporting details and the title does not need to cover them.
Full details: Description check
Explanation
The description follows the repository template closely. It states the problem (Agent Activity widget is iOS-only, Android has
android: null) and gives a clear change breakdown per file. It links a related idea (#36045) and notes that background refresh is out of scope with a link to#35318. The Verification section lists concrete commands, test counts, the APK run on an Android 16 emulator, and screenshots for picker, signed-out, signed-in, and post-tap states. The Scope section does not link a bug issue. It cites an Ideas discussion and does not explain why this is a bug fix rather than a feature, which the template asks for, since the repo says it accepts bug fixes, not features. The template also asks for the model and harness used if an agent was used; the description says it was generated with Claude Code but does not name the model. Most required sections are complete, so the check passes, but the scope rationale and the agent model/harness line are missing.Finishing Touches
Generate unit tests (beta)