feat: pair mobile devices from the Control UI#94672
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 4, 2026, 12:37 PM ET / 16:37 UTC. Summary Reproducibility: not applicable. as a feature PR: current main lacks the Control UI/RPC path, and the PR adds it rather than fixing a reproducible broken existing contract. Review metrics: 1 noteworthy metric.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the admin-scoped Control UI pairing flow only after a maintainer accepts the setup-code security boundary and the PR includes redacted live proof against a real Gateway/mobile pairing path. Do we have a high-confidence way to reproduce the issue? Not applicable as a feature PR: current main lacks the Control UI/RPC path, and the PR adds it rather than fixing a reproducible broken existing contract. Is this the best way to solve the issue? Yes, the shape is the maintainable layer: reuse the existing setup-code helper through a hidden admin-scoped Gateway RPC and keep the browser as a renderer, but the merge still needs live proof and security acceptance. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 280e8d487627. Label changesLabel changes:
Label justifications:
Evidence reviewedWhat 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
Review history (2 earlier review cycles) |
a02aadf to
1945f20
Compare
|
Adversarial review (GPT-5.5) pass — addressed two real findings on this PR:
Unchanged guarantees: Re-validated on latest |
1945f20 to
96f1b0f
Compare
The OpenClaw mobile/companion app scans a pairing setup code to connect to the gateway, but that code + QR could only be produced by the openclaw qr CLI (ASCII to stdout). Non-terminal clients driving onboarding had no way to display the connect QR.
Add a device.pair.setupCode gateway method that reuses resolvePairingSetupFromConfig + encodePairingSetupCode + renderQrPngDataUrl to return { setupCode, qrDataUrl?, gatewayUrl, auth, urlSource }. The embedded setup code mints a short-lived bootstrap token that hands off broad operator scopes (read/write/approvals/talk.secrets), so the method requires operator.admin (matching the wizard methods a companion already uses) and is not advertised. auth is a label only; the gateway credential is never returned, and an oversized QR is omitted so the response always satisfies the result schema.
Refs openclaw#94661.
Co-authored-by: Copilot <[email protected]>
96f1b0f to
cf313b1
Compare
|
Maintainer follow-up complete on What changed:
Focused proof: Broad proof: Blacksmith Testbox Known gap: no physical-iPhone scan. Mocked Control UI E2E covers the route, Gateway request, PNG QR, copy/replacement flow, and auto-connect guidance. Before/after screenshots plus a short recording are captured locally; attachment publishing is blocked because this checkout has no configured Crabbox artifact broker and the existing-Chrome bridge is offline. CI follow-up: the first Initial final-head CI reached 68 passes, then exposed two unrelated broad-shard failures: a current- |
Dependency GuardThis PR changes dependency-related files. Maintainers should confirm these changes are intentional. Changed files:
Maintainer follow-up:
|
Dependency graph change authorizedThis PR includes dependency graph changes. A repository admin or member of
A later push changes the PR head SHA and requires a fresh security approval. |
|
/allow-dependencies-change Maintainer-prepared cross-repo sync; dependency files match current main exactly and add no dependency graph delta. |
|
Merged via squash.
|
* feat(gateway): add device.pair.setupCode RPC for connect QR
The OpenClaw mobile/companion app scans a pairing setup code to connect to the gateway, but that code + QR could only be produced by the openclaw qr CLI (ASCII to stdout). Non-terminal clients driving onboarding had no way to display the connect QR.
Add a device.pair.setupCode gateway method that reuses resolvePairingSetupFromConfig + encodePairingSetupCode + renderQrPngDataUrl to return { setupCode, qrDataUrl?, gatewayUrl, auth, urlSource }. The embedded setup code mints a short-lived bootstrap token that hands off broad operator scopes (read/write/approvals/talk.secrets), so the method requires operator.admin (matching the wizard methods a companion already uses) and is not advertised. auth is a label only; the gateway credential is never returned, and an oversized QR is omitted so the response always satisfies the result schema.
Refs openclaw#94661.
Co-authored-by: Copilot <[email protected]>
* feat(ui): pair mobile devices from Control UI
* docs: refresh generated docs map
* docs: clarify mobile QR auto-connect
* docs: clarify mobile QR auto-connect
* docs: clarify mobile QR auto-connect
---------
Co-authored-by: Barbara Kudiess <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>


Related: #94661
What Problem This Solves
The OpenClaw iOS/Android apps can scan a Gateway setup QR, but the Control UI could not create one. Operators had to leave the browser and use
openclaw qror the optional Telegramdevice-pairplugin; the UI exposed only the separate device-management surface.Why This Change Was Made
This adds the hidden,
operator.admin-scopeddevice.pair.setupCodeRPC from the original contribution and uses it for a guided Nodes → Pair mobile device flow. The RPC reuses the canonical pairing/setup-code helpers; the Control UI adds no second token or QR format. The Devices card now appears at the top of Nodes, the dialog handles scan/copy/retry states, and the docs lead with the browser flow.The setup code contains a short-lived bootstrap credential. The RPC returns only the opaque setup code plus non-secret connection metadata, is not advertised, and keeps the configured
device-pairpublic URL fallback used by the existing CLI/plugin flow.User Impact
An already paired administrator can now connect a phone without opening a terminal:
Sessions without
operator.admincannot create setup codes. Remote pairing still requires a secure/reachable Gateway URL (wss://, such as Tailscale Serve/Funnel); private LAN and loopback retain their existing allowances.Evidence
node scripts/run-vitest.mjs src/gateway/server-methods/device-pair-setup.test.ts ui/src/ui/views/nodes.devices.test.tsnode scripts/run-vitest.mjs run --config test/vitest/vitest.ui-e2e.config.ts --configLoader runner ui/src/ui/e2e/mobile-pairing.e2e.test.tspnpm ui:i18n:checkcheck:changedpassed on Blacksmith Testboxtbx_01kwp7yb60j5eqj6te8fyzmf76(workflow run)pnpm buildpassed in the same Testbox runNot tested: a physical iPhone scan. The E2E verifies the actual Control UI route, Gateway request, PNG QR rendering, and replacement-code action against the deterministic mocked Gateway.