Repository navigation
feat(mobile): approve the front waiting agent from the Apple Watch and Wear OS - #6199
Conversation
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (13 files)
Previous Review Summary (commit e751df3)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit e751df3)Status: 4 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (42 files)
Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0 Review guidance: REVIEW.md from base branch |
e751df3 to
47e5680
Compare
|
bot: Cross-platform fix. Pushed 86c00ef (kwf What changed:
|
86c00ef to
c40943e
Compare
|
(bot) ## Live proof (proof-only request; no code change) Ran on android; the request asked for any platform. This request asked for live proof of existing behaviour. There is no diff; the verify round ran the must-run scenarios and recorded the evidence below.
|
|
(bot) kwf reopened its section for this PR: verification restarted (phase verify) The proof in the body came from an earlier round and can be stale. This PR is human-ready, so nothing here was changed. |
Changelog for users
Changelog for maintainers
apps/mobile/src/lib/glanceable/approve-front-agent.ts:291— accepted: a rejecting manager factory no longer strands the retainedUserWebConnection. The factory destroys the connection before rethrowing, andrunApprovalcatches the rejection, republishes the surfaces from fresh rows, and returnsfailed, retryable.apps/mobile/modules/active-agents-live-update/android/src/main/java/com/kilocode/activeagentsliveupdate/ActiveAgentsApproveReceiver.kt:20— accepted:startServicesits in a try/catch that logs and returns, and the wake lock is taken only after the start is accepted, so the API 26+ background refusal cannot strand it. A new test reads the Kotlin source and pins that order.apps/mobile/src/lib/glanceable/approve-front-agent.ts:301— accepted: teardown deletes theheadlessConnectionsentry and destroys the connection beforemanager.destroy(), and the approval'sfinallyswallows a throwing teardown, so the connection, outcome, and surface refresh all survive.apps/mobile/src/glanceable-ios/approve-action.ts:95— accepted: a registration id guards the unsubscribe, so an earlier registration that a later one replaced returns without clearing the shared callback or removing the listener.needsApprovalis a new optional count on the glanceable snapshot and push schemas: it countspermissionrows only, and every reader treats an absent value as 0, so an older server still parses. The Live Activity content state forwards the count; the Home Screen widget and complication props stay read-only and carry no Approve affordance.Button(literaltarget="approve") rides the count block, gated onhasCounts && needsApproval > 0, so the expired frame draws no control. A newbannerSmallsection serves the.smallfamily (Apple Watch, CarPlay) with one count row plus the control, and the combined accessibility label sits on the count block alone so VoiceOver can focus the button.approve-action.tsmatches the interaction event ontargetalone, because the nativesourceis the ActivityKit instance UUID, andlayout-copy.test.tspins the layout literal toAPPROVE_TARGET.PendingIntentstarts a non-exported receiver and aHeadlessJsTaskService(ActiveAgentsApprove, 60 s); the task registered at app entry applies the stored widget language, then calls the shared approval service. The newapproveFrontAgentservice picks the longest-waiting permission row, reuses the open chat screen's manager through the newlive-session-manager-registry(the relay allows one owner per session) or attaches a headless connection, waits up to 15 s for the replayed ask, respondsonce, acks attention, and republishes the surfaces from fresh rows.notifications.tsnow shares its SecureStore scope reads throughlib/glanceable/scope.ts; no file underapps/mobile/src/**/kiloclaw/**changed.targetcontract between layout and handler, the deliberately swallowed teardown in the approvalfinally, the receiver's start-then-lock order that its test reads from the Kotlin source, and the swallowed approval failure that leaves the wrist with no error state.E2E proof
The iOS half of this change ran live on a Mac simulator in PR #6232, which stacks on this branch and pins the behaviour with tests. That round installed the CI build on an iOS simulator and drove the scenarios; its verdict is
iOS verification passed.The Apple Watch wrist tap is an owner-manual scope: the simulator cannot deliver it. It is NOT claimed as proved here.
This section's own earlier line read
-> pass :: owner-manual: ..., which the harness now refuses to count as a pass (a scenario naming an owner-manual scope is excluded whatever its result field says).