Skip to content

feat(mobile): improve cross-device agent Live Activities - #4978

Closed
zortos293 wants to merge 11 commits into
pingdotgg:mainfrom
zortos293:feat/mobile-agent-activity-t3notch
Closed

feat(mobile): improve cross-device agent Live Activities#4978
zortos293 wants to merge 11 commits into
pingdotgg:mainfrom
zortos293:feat/mobile-agent-activity-t3notch

Conversation

@zortos293

@zortos293 zortos293 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Restyles the agent Live Activity across the iPhone and iPad Lock Screens, Dynamic Island, and Apple Watch Smart Stack with attention-first ordering, provider marks, phase colors, compact status dots, and overflow handling.
  • Fixes Live Activity regions that silently dropped rows when nested layout children were not serialized by the native runtime.
  • Adds a dedicated compact hierarchy for Apple Watch so task, project, status, and overflow information remain readable in the narrow Smart Stack surface.
  • Generates native provider-mark assets from the existing web icons so branding stays in sync across surfaces.

Why

The existing Live Activity rendered as a flat list and could omit agent rows entirely. It also reused the wider Lock Screen hierarchy on Apple Watch, which truncated the useful task and status information.

UI Changes

Before After
Before: previous T3 Code agent Live Activity After: updated T3 Code agent Live Activity

Verification

  • Mobile test suite: 595 tests passed across 98 test files.
  • Mobile TypeScript typecheck passed.
  • Provider-mark asset drift check passed.
  • Exercised the Lock Screen and Dynamic Island layouts on iPhone, the Lock Screen layout on iPad, and the Smart Stack layout on a paired Apple Watch simulator.

Notes

  • Provider branding is currently derived from the model name because the aggregate does not yet carry the provider instance ID.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for the UI changes
  • A video is not applicable because this change does not add animation or interaction

Note

Medium Risk
Large Live Activity layout and iOS prebuild widget asset changes affect a user-visible surface, but behavior is heavily covered by tests and the asset sync is deterministic with a CI check.

Overview
Restyles agent Live Activities on Lock Screen, Dynamic Island, and Apple Watch with attention-first ordering, Apple system phase colors, provider marks on each row, neutral card slabs, phase dots, and +N more overflow instead of silently hiding agents.

Fixes a native serialization bug where nested JSX children ([strip, [cards]]) caused agent rows to never render on the lock screen; banner regions now use flat child arrays.

Adds a dedicated Watch Smart Stack layout (bannerSmall) with a solid background, compact headline, two-line hero card, and overflow line so narrow surfaces stay readable.

Syncs provider branding by generating widget SVG assets from apps/web Icons.tsx via sync-provider-marks.mjs, shipping them through withWidgetLogoAsset.cjs, with check:provider-marks for CI drift detection. Brand on each card is inferred from modelTitle until the aggregate carries provider IDs.

Reviewed by Cursor Bugbot for commit 861c328. Configure here.

Note

Add provider branding and per-thread serialization to agent Live Activities

  • Live Activity cards now show provider marks (Claude, Codex, Cursor, Grok, OpenCode) with phase dots and status instead of model text; SVGs are synced from apps/web/src/components/Icons.tsx via a new sync-provider-marks.mjs script.
  • All Live Activity regions are overhauled: banner shows up to 4 provider-branded cards plus a '+N more' overflow, compact trailing shows a concise phase word and count badge when >1 agent, minimal shows a phase glyph only when attention or all-done.
  • providerName is propagated end-to-end: from projectThreadAwareness through RelayAgentActivityState/RelayAgentActivityAggregateRow to the mobile widget renderer.
  • AgentAwarenessRelay now serializes publishes per thread (up to concurrency 4 across threads) using makeKeyedCoalescingWorker, and republishes active threads when the provider registry changes.
  • AgentActivityPublisher gains keyed per-thread and per-user locking to prevent older publishes from completing after newer ones for the same thread.

Macroscope summarized 8e3d1ba.

@coderabbitai

coderabbitai Bot commented Jul 30, 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: 55487b74-8a83-4ce5-81e1-2d1b0f687cb0

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:XXL 1,000+ changed lines (additions + deletions). labels Jul 30, 2026
Comment thread apps/mobile/scripts/sync-provider-marks.mjs
Comment thread apps/mobile/src/features/agent-awareness/remoteRegistration.ts Outdated
Comment thread apps/mobile/src/features/agent-awareness/remoteRegistration.ts Outdated
Comment thread apps/mobile/src/widgets/AgentActivity.tsx Outdated
Comment thread apps/mobile/src/widgets/AgentActivityHome.tsx Outdated

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

Reviewed the changed TypeScript against the Effect service conventions. The widget layout modules (AgentActivity.tsx, AgentActivityHome.tsx) contain no Effect services and look fine; one finding in remoteRegistration.ts where an Effect now depends on the imperative persistence bridge.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/mobile/src/features/agent-awareness/remoteRegistration.ts Outdated
Comment thread apps/mobile/src/widgets/AgentActivity.tsx
@zortos293
zortos293 force-pushed the feat/mobile-agent-activity-t3notch branch from 730ee3c to 861c328 Compare July 30, 2026 23:18
@zortos293 zortos293 changed the title feat(mobile): restyle the agent Live Activity and implement the home-screen widget feat(mobile): improve cross-device agent Live Activities Jul 30, 2026
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:XXL 1,000+ changed lines (additions + deletions). labels Jul 30, 2026
@zortos293
zortos293 marked this pull request as ready for review July 30, 2026 23:20

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

Fix All in Cursor

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

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 861c328. Configure here.

Comment thread apps/mobile/src/widgets/AgentActivity.tsx Outdated
Comment thread apps/mobile/src/widgets/AgentActivity.tsx
@macroscopeapp

macroscopeapp Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces new user-facing functionality (provider branding in Live Activities) with cross-cutting changes across mobile, server, and shared packages. Additionally, there is an unresolved review comment identifying a potential concurrency ordering issue in the publisher code.

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

Comment thread apps/mobile/src/widgets/AgentActivity.tsx Outdated
Comment thread infra/relay/src/agentActivity/AgentActivityPublisher.ts Outdated
nowMs: now.epochMilliseconds,
});
}),
publish: Effect.fn("relay.agent_activity_publisher.publish")(function* (input) {

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.

🟡 Medium agentActivity/AgentActivityPublisher.ts:174

A stale delivery can still be queued after a newer one. publishForDeliveryUser acquires the per-user lock only after rows.upsert/rows.remove and links.listDeliveryUsersForEnvironment have already run. An older publish call can pause before publishForDeliveryUser enters the lock, while a newer publish for the same user acquires the lock, delivers, and releases it. The older call then enters the lock and delivers an aggregate built from its now-stale input.state (including the terminal-state and notification-only aggregates). This lets an outdated terminal/push update land after a newer one — the exact ordering violation the lock is meant to prevent. Consider moving the row mutation and delivery-user lookup inside withDeliveryLock, or acquiring the lock before those reads, so the entire per-user snapshot-and-deliver sequence is serialized.

🤖 Copy this AI Prompt to have your agent fix this:
In file @infra/relay/src/agentActivity/AgentActivityPublisher.ts around line 174:

A stale delivery can still be queued after a newer one. `publishForDeliveryUser` acquires the per-user lock only after `rows.upsert`/`rows.remove` and `links.listDeliveryUsersForEnvironment` have already run. An older `publish` call can pause before `publishForDeliveryUser` enters the lock, while a newer `publish` for the same user acquires the lock, delivers, and releases it. The older call then enters the lock and delivers an aggregate built from its now-stale `input.state` (including the terminal-state and notification-only aggregates). This lets an outdated terminal/push update land after a newer one — the exact ordering violation the lock is meant to prevent. Consider moving the row mutation and delivery-user lookup inside `withDeliveryLock`, or acquiring the lock before those reads, so the entire per-user snapshot-and-deliver sequence is serialized.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as part of the open-PR backlog sweep (wave 1).

Reason: Jul conflicted Live Activities rewrite; #6325 later fixed stale Live Activities.
Related: #6325

Reopen if this is still wanted and you’re willing to rebase onto current main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 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.

2 participants