fix(mobile): an expired Live Activity no longer leaves a second card - #15254
Conversation
iOS ends every Live Activity 8 hours after it starts but keeps the ended card on the Lock Screen for up to 4 more hours. expo-widgets' getInstances() hides ended cards, so the app thought none was showing and started a new one, leaving a frozen "Agent status out of date" card next to the live one. LiveActivityFactory.start() now dismisses this factory's ended activities before requesting a new one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a focused iOS Live Activity bug fix that dismisses matching ended cards before starting a replacement, while the lockfile change only activates the updated dependency patch. The change is small, isolated, and has no product-default, schema, security, or deployment-infrastructure impact. You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review. 📝 WalkthroughWalkthroughThe patch updates Live Activity environment properties and view construction, adds cleanup of matching ended activities before a new activity starts, and changes the layout-registry script’s direct-execution check to compare resolved paths. ChangesLive Activity Updates
Layout Registry Execution Check
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~15 minutes Change: Bug fix Merge Risk: 🔵 Low · up to Starting a replacement may briefly show two cards, but the old card should be removed. This is a bounded risk rather than a merge blocker. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
## What's Changed * fix(mobile): iOS threads no longer jump to the top by @znoraka in pingdotgg/t3code#14808 * fix(web): reduce the gap above the draft composer by @Bil0000 in pingdotgg/t3code#15196 * fix(mobile): a dev server left running no longer shows the waiting bolt by @jakeleventhal in pingdotgg/t3code#15194 * fix(server): a Claude command you stop shows as interrupted by @SunkenInTime in pingdotgg/t3code#14896 * fix(server): editors appear once a slow discovery scan finishes by @bfowler in pingdotgg/t3code#13917 * fix(server): Claude threads no longer stay stuck in plan mode Claude entered itself by @juliusmarminge in pingdotgg/t3code#15224 * fix(mobile): show complete subagent details by @jakeleventhal in pingdotgg/t3code#15189 * fix(mobile): an expired Live Activity no longer leaves a second card by @juliusmarminge in pingdotgg/t3code#15254 * test(web): remove redundant thread sort fallback tests by @t3-code[bot] in pingdotgg/t3code#15095 * fix(web): thinking row after a failed tool expands the run's tool calls by @maria-rcks in pingdotgg/t3code#15056 * perf(web): DOM changes no longer restyle the whole page by @flamboh in pingdotgg/t3code#15265 * perf(usage): cut warm usage scans from seconds to milliseconds on large histories by @t3dotgg in pingdotgg/t3code#15149 * perf(web): virtualize command palette results by @flamboh in pingdotgg/t3code#15266 * chore(lint): flag :has() variants that restyle the whole page by @flamboh in pingdotgg/t3code#15274 * fix(web): workspace card docks beside chat when the window is narrow by @t3dotgg in pingdotgg/t3code#14992 * feat(web): render mermaid code blocks as diagrams by @maria-rcks in pingdotgg/t3code#15067 ## New Contributors * @znoraka made their first contribution in pingdotgg/t3code#14808 **Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261003.2632...v0.0.46-nightly.20261003.2638 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261003.2638
## What's Changed * fix(mobile): iOS threads no longer jump to the top by @znoraka in pingdotgg/t3code#14808 * fix(web): reduce the gap above the draft composer by @Bil0000 in pingdotgg/t3code#15196 * fix(mobile): a dev server left running no longer shows the waiting bolt by @jakeleventhal in pingdotgg/t3code#15194 * fix(server): a Claude command you stop shows as interrupted by @SunkenInTime in pingdotgg/t3code#14896 * fix(server): editors appear once a slow discovery scan finishes by @bfowler in pingdotgg/t3code#13917 * fix(server): Claude threads no longer stay stuck in plan mode Claude entered itself by @juliusmarminge in pingdotgg/t3code#15224 * fix(mobile): show complete subagent details by @jakeleventhal in pingdotgg/t3code#15189 * fix(mobile): an expired Live Activity no longer leaves a second card by @juliusmarminge in pingdotgg/t3code#15254 * test(web): remove redundant thread sort fallback tests by @t3-code[bot] in pingdotgg/t3code#15095 * fix(web): thinking row after a failed tool expands the run's tool calls by @maria-rcks in pingdotgg/t3code#15056 * perf(web): DOM changes no longer restyle the whole page by @flamboh in pingdotgg/t3code#15265 * perf(usage): cut warm usage scans from seconds to milliseconds on large histories by @t3dotgg in pingdotgg/t3code#15149 * perf(web): virtualize command palette results by @flamboh in pingdotgg/t3code#15266 * chore(lint): flag :has() variants that restyle the whole page by @flamboh in pingdotgg/t3code#15274 * fix(web): workspace card docks beside chat when the window is narrow by @t3dotgg in pingdotgg/t3code#14992 * feat(web): render mermaid code blocks as diagrams by @maria-rcks in pingdotgg/t3code#15067 ## New Contributors * @znoraka made their first contribution in pingdotgg/t3code#14808 **Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261003.2632...v0.0.46-nightly.20261003.2638 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261003.2638
iOS ends a Live Activity 8 hours after it starts but keeps the ended card on the Lock Screen for up to 4 more hours. expo-widgets'
getInstances()only returns active and stale cards (expo/expo#48489), so our app thought no card was showing and started a fresh one. That left two cards stacked: a frozen "Agent status out of date" card and the live one.The fix extends our existing
expo-widgets@58.0.11patch:LiveActivityFactory.start()now dismisses this factory's ended activities (end(nil, dismissalPolicy: .immediate)) before requesting a new one. Every way the app starts a card (sending from the phone, foreground priming, showcase) goes throughstart(), so this one change covers all of them. The relay and the widget layout are unchanged, and Android doesn't use this code.Verification
iOS 27 simulator, T3 Code Dev built from this patch. I started card A and ended it with default dismissal, which leaves it ended but still on screen with
getInstances()returning 0, like a card after the 8-hour limit. Then I started card B.In the
liveactivitiesdlog, card A sat ended ("zombie") for about 45 seconds, then was ended by our app and removed ("discarded") at the same moment card B started. I didn't wait for a real 8-hour expiry.Shipping: this needs a store build, and OTAs won't know
Expo's fingerprint doesn't include our root
patches/directory. It only hashesapps/mobile/patchesplus each package'spackage.json. This change leaves the production fingerprint unchanged (509325fd…, the same as iOS 2.0.0 build 104), so:versionbump (or a manual dispatch).Fixing fingerprint coverage of root patches is a separate change.
🤖 Generated with Claude Code, Claude Opus 5.5 in T3 Code