feat(ios): add watch action surface#93387
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 15, 2026, 4:28 PM ET / 20:28 UTC. Summary PR surface: Other +2811. Total +2811 across 18 files. Reproducibility: not applicable. this is a feature PR, not a current-main bug report. The reviewed evidence is after-fix behavior proof for a paired watch/iPhone simulator flow against a live local gateway. Review metrics: 2 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land after iOS/watch owner sign-off on the new command contract, keeping physical-device or TestFlight proof as a pre-release validation item if maintainers want that bar. Do we have a high-confidence way to reproduce the issue? Not applicable: this is a feature PR, not a current-main bug report. The reviewed evidence is after-fix behavior proof for a paired watch/iPhone simulator flow against a live local gateway. Is this the best way to solve the issue? Yes: the implementation extends the existing NodeAppModel, WatchConnectivity, and shared OpenClawKit watch payload seams instead of creating a parallel transport. The remaining question is maintainer acceptance of the new watch command and queued-chat contract. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 32af1c069727. Label changesLabel justifications:
Evidence reviewedPR surface: Other +2811. Total +2811 across 18 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR expands the watch/iOS WatchConnectivity protocol to support “app snapshot” syncing and watch-driven app commands (refresh/open chat/send chat/start/stop talk), and updates the watch UI to a multi-page control surface that shows live status, approvals, and chat.
Changes:
- Extend the Swift protocol generator to emit Swift string enums from
oneOf/anyOfliteral unions (not justenum). - Add watch payload types/models for app snapshots + commands, plus encode/decode and transport wiring on both iOS and watch.
- Replace the watch inbox UI with a tabbed “control surface” including snapshot-driven status and a watch chat composer; add watch assets and iOS tests for new watch flows.
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/protocol-gen-swift.ts | Enhances Swift codegen to detect string-enum cases from more schema shapes. |
| apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift | Adds newly generated protocol enums. |
| apps/shared/OpenClawKit/Sources/OpenClawKit/WatchCommands.swift | Adds shared watch payload/command models for snapshot + commands. |
| apps/ios/project.yml | Includes WatchExtension asset catalog in build sources. |
| apps/ios/WatchExtension/Sources/WatchInboxView.swift | Implements new watch control-surface UI (status/inbox/approvals + chat). |
| apps/ios/WatchExtension/Sources/WatchInboxStore.swift | Stores new snapshot state and composes app commands/replies. |
| apps/ios/WatchExtension/Sources/WatchConnectivityReceiver.swift | Adds request/parse/send for snapshot + commands; consumes app context on activation. |
| apps/ios/WatchExtension/Sources/OpenClawWatchApp.swift | Triggers snapshot refresh and sends app commands/chat from watch UI. |
| apps/ios/WatchExtension/Assets.xcassets/** | Adds the watch icon asset used by the new UI. |
| apps/ios/Tests/NodeAppModelInvokeTests.swift | Adds tests covering watch snapshot requests and app commands (talk/open chat/send chat + queueing). |
| apps/ios/Sources/Services/WatchMessagingService.swift | Wires new callbacks and adds syncAppSnapshot. |
| apps/ios/Sources/Services/WatchMessagingPayloadCodec.swift | Encodes app snapshots; parses snapshot requests and app commands. |
| apps/ios/Sources/Services/WatchConnectivityTransport.swift | Routes new payload types and adds application-context sender helper. |
| apps/ios/Sources/Services/NodeServiceProtocols.swift | Adds new watch event types + protocol surface. |
| apps/ios/Sources/Model/WatchReplyCoordinator.swift | Adds WatchChatCoordinator for queuing/deduping watch chat commands. |
| apps/ios/Sources/Model/NodeAppModel.swift | Implements snapshot creation, chat preview fetch, watch command handling, and queued chat flushing. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2b1fda6620
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
* feat(ios): add watch action surface * fix: harden watch action surface * fix: clean watch codegen lint * fix(ios): scope watch chat commands to gateway --------- Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
* feat(ios): add watch action surface * fix: harden watch action surface * fix: clean watch codegen lint * fix(ios): scope watch chat commands to gateway --------- Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
Real behavior proof
Connected gateway watch chat delivery
9C50FB20-5231-42F7-ADCD-4CEBED3FB31A, both installed from the built OpenClaw iOS/watch schemes, paired to a live local OpenClaw gateway atws://127.0.0.1:18789.pnpm openclaw qr --setup-code-only --url ws://127.0.0.1:18789, entered it in the iPhone simulator Gateway setup UI, and connected the iPhone simulator as a gateway node/operator device.iPhone 17 Prohad rolesnode, operator, operator scopes, and freshlastSeenReason=connect.Message OpenClawpill, enteredHithrough the native watch keyboard, tappedDone, and captured watch/iPhone/gateway logs.operator gateway connected host=127.0.0.1 scheme=wsbefore the watch send.watch.app.command command=send-chat,chat.send start sessionKey=main len=2,chat.send ok,agent.wait completed ... status=ok, andwatch_chat_completedfor the same watch command id.kNoErr.Hi, the phone forwarded it to the connected gateway chat session, the agent run completed, and the phone pushed the completed chat snapshot back to the watch.Connected watch snapshot after final reviewed build
Watch chat page with bottom message pill and sent status
Before/after visual comparison
Swipe and scroll proof
OpenClawWatchAppafter review-comment fixes through XcodeBuildMCP profilewatch-proof; result:SUCCEEDEDwith no build errors.xcodebuild test -project apps/ios/OpenClaw.xcodeproj -scheme OpenClaw -destination 'platform=iOS Simulator,name=iPhone 17 Pro' -only-testing:OpenClawTests/NodeAppModelInvokeTests -derivedDataPath /tmp/openclaw-watch-proof/ios-test-derived -skipPackagePluginValidation -skipMacroValidation; result:66 tests in 1 suite passed..agents/skills/autoreview/scripts/autoreview --mode localafter the final fixes; result:autoreview clean: no accepted/actionable findings reported.OpenClawWatchAppwith Xcode against the paired watch simulator.xcrun simctl install.7921672da6NodeAppModelInvokeTestspassed with 66 tests.OpenClawWatchAppsimulator build succeeded on watchOS simulator9C50FB20-5231-42F7-ADCD-4CEBED3FB31A./tmp/openclaw-watch-proof/logs/openclaw-gateway-final-reviewed.log/tmp/openclaw-watch-proof/logs/openclaw-gateway-chat-final-reviewed.log/tmp/openclaw-watch-proof/logs/phone-openclaw-gateway.log/tmp/openclaw-watch-proofReconnect on iPhone,Offline,Ready for quick actions.paired=true appInstalled=true reachable=trueandwatch.app.snapshotRequesthandling.Talk to Claw; native watch input accepted text and showedChat: sent.Summary
Linked context
Requested by maintainer in the watch action-surface iteration.
Tests and validation
git diff --checkxcodebuild build -project apps/ios/OpenClaw.xcodeproj -scheme OpenClawWatchApp -destination 'platform=watchOS Simulator,id=9C50FB20-5231-42F7-ADCD-4CEBED3FB31A' -derivedDataPath /tmp/openclaw-watch-proof/current-derived -skipPackagePluginValidation -skipMacroValidationxcodebuild test -project apps/ios/OpenClaw.xcodeproj -scheme OpenClaw -destination 'platform=iOS Simulator,name=iPhone 17 Pro' -only-testing:OpenClawTests/NodeAppModelInvokeTests -skipPackagePluginValidation -skipMacroValidationws://127.0.0.1:18789; proof excerpt asset linked above..agents/skills/autoreview/scripts/autoreview --mode localclean after addressing two accepted findings.Risk checklist
Current review state
Ready for maintainer review. Proof media is hosted as fork release assets so screenshots/GIFs/log excerpts are not committed into the OpenClaw branch.