Skip to content

Commit 9f30a28

Browse files
committed
Auto-merge upstream openclaw/openclaw
2 parents eb17a81 + f0537e9 commit 9f30a28

276 files changed

Lines changed: 9148 additions & 1180 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/openclaw-parallels-smoke/SKILL.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ Use this skill for Parallels guest workflows and smoke interpretation. Do not lo
7272
- For full beta validation after a tag is published, prefer one command:
7373
- `timeout --foreground 150m pnpm test:parallels:npm-update -- --beta-validation beta3 --json`
7474
This resolves `beta3` to the latest `*-beta.3` version, runs latest->that-version same-guest update coverage, and then runs fresh install smoke for that exact published target on the same selected OS matrix. Use `--platform macos|windows|linux` to narrow reruns.
75+
- For beta 4 npm validation with agent turns, the known-good shape is:
76+
- `gtimeout --foreground 150m pnpm test:parallels:npm-update -- --beta-validation beta4 --model openai/gpt-5.4 --json`
77+
Prefer the explicit `beta4` alias over `openclaw@beta` when validating a specific prerelease number; npm tags can move.
7578
- If the wrapper fails a lane, read the auto-dumped tail first, then the full nested lane log under `.artifacts/parallels/openclaw-parallels-npm-update.*`.
7679
- Current known macOS update-lane transport signature when the fallback is missing or bypassed: `Unable to authenticate the user. Make sure that the specified credentials are correct and try again.` Treat that as Parallels current-user authentication before blaming npm or OpenClaw.
7780
- A macOS packaged fresh install with global package directories or bundled files mode `0777` usually means the harness used the root `prlctl exec` fallback under a permissive umask. The POSIX guest transports should prepend `umask 022`; verify the phase preflight line before blaming npm.

.agents/skills/openclaw-qa-testing/SKILL.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,20 @@ pnpm test:docker:npm-telegram-live
139139
- `OPENCLAW_QA_CONVEX_SITE_URL`
140140
- `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`
141141
- `OPENCLAW_NPM_TELEGRAM_PROVIDER_MODE=mock-openai`
142+
- If direct Telegram env is missing locally and `op signin` blocks, prefer dispatching the manual GitHub lane because the `qa-live-shared` environment already has Convex CI credentials:
143+
144+
```bash
145+
gh workflow run "NPM Telegram Beta E2E" --repo openclaw/openclaw --ref main \
146+
-f package_spec=openclaw@YYYY.M.D-beta.N \
147+
-f package_label=openclaw@YYYY.M.D-beta.N \
148+
-f provider_mode=mock-openai
149+
```
150+
151+
- Poll the exact run id from the dispatch URL. `gh run view --json artifacts` is not supported; list artifacts with:
152+
153+
```bash
154+
gh api repos/openclaw/openclaw/actions/runs/<run-id>/artifacts
155+
```
142156

143157
## Character evals
144158

CHANGELOG.md

Lines changed: 54 additions & 1 deletion
Large diffs are not rendered by default.

apps/ios/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# OpenClaw iOS Changelog
22

3+
## 2026.5.4 - 2026-05-04
4+
5+
Maintenance update for the current OpenClaw development release.
6+
7+
- Gateway pairing now supports scanning QR codes from Settings and accepts full copied setup-code messages while keeping non-loopback `ws://` setup links blocked.
8+
39
## 2026.5.3 - 2026-05-03
410

511
Maintenance update for the current OpenClaw development release.

apps/ios/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ gateway can only send pushes for iOS devices that paired with that gateway.
241241

242242
## What Works Now (Concrete)
243243

244-
- Pairing via setup code flow (`/pair` then `/pair approve` in Telegram).
244+
- Pairing via QR or setup code flow (`/pair qr` or `/pair`, then `/pair approve` in Telegram).
245245
- Gateway connection via discovery or manual host/port with TLS fingerprint trust prompt.
246246
- Chat + Talk surfaces through the operator gateway session.
247247
- iPhone node commands in foreground: camera snap/clip, canvas present/navigate/eval/snapshot, screen record, location, contacts, calendar, reminders, photos, motion, local notifications.

apps/ios/Sources/Gateway/GatewaySetupCode.swift

Lines changed: 0 additions & 42 deletions
This file was deleted.

apps/ios/Sources/Onboarding/GatewayOnboardingView.swift

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -248,69 +248,36 @@ private struct ManualEntryStep: View {
248248
return
249249
}
250250

251-
guard let payload = GatewaySetupCode.decode(raw: raw) else {
252-
self.setupStatusText = "Setup code not recognized."
251+
guard let link = GatewayConnectDeepLink.fromSetupInput(raw) else {
252+
self.setupStatusText = "Setup code not recognized or uses an insecure ws:// gateway URL."
253253
return
254254
}
255255

256-
if let urlString = payload.url, let url = URL(string: urlString) {
257-
self.applyURL(url)
258-
} else if let host = payload.host, !host.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
259-
self.manualHost = host.trimmingCharacters(in: .whitespacesAndNewlines)
260-
if let port = payload.port {
261-
self.manualPortText = String(port)
262-
} else {
263-
self.manualPortText = ""
264-
}
265-
if let tls = payload.tls {
266-
self.manualUseTLS = tls
267-
}
268-
} else if let url = URL(string: raw), url.scheme != nil {
269-
self.applyURL(url)
270-
} else {
271-
self.setupStatusText = "Setup code missing URL or host."
272-
return
273-
}
256+
self.manualHost = link.host
257+
self.manualPortText = String(link.port)
258+
self.manualUseTLS = link.tls
274259

275-
if let token = payload.token, !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
260+
if let token = link.token, !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
276261
self.manualToken = token.trimmingCharacters(in: .whitespacesAndNewlines)
277-
} else if payload.bootstrapToken?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false {
262+
} else if link.bootstrapToken?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false {
278263
self.manualToken = ""
279264
}
280-
if let password = payload.password, !password.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
265+
if let password = link.password, !password.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
281266
self.manualPassword = password.trimmingCharacters(in: .whitespacesAndNewlines)
282-
} else if payload.bootstrapToken?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false {
267+
} else if link.bootstrapToken?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false {
283268
self.manualPassword = ""
284269
}
285270

286271
let trimmedInstanceId = UserDefaults.standard.string(forKey: "node.instanceId")?
287272
.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
288273
if !trimmedInstanceId.isEmpty {
289274
let trimmedBootstrapToken =
290-
payload.bootstrapToken?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
275+
link.bootstrapToken?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
291276
GatewaySettingsStore.saveGatewayBootstrapToken(trimmedBootstrapToken, instanceId: trimmedInstanceId)
292277
}
293278

294279
self.setupStatusText = "Setup code applied."
295280
}
296-
297-
private func applyURL(_ url: URL) {
298-
guard let host = url.host, !host.isEmpty else { return }
299-
self.manualHost = host
300-
if let port = url.port {
301-
self.manualPortText = String(port)
302-
} else {
303-
self.manualPortText = ""
304-
}
305-
let scheme = (url.scheme ?? "").lowercased()
306-
if scheme == "wss" || scheme == "https" {
307-
self.manualUseTLS = true
308-
} else if scheme == "ws" || scheme == "http" {
309-
self.manualUseTLS = false
310-
}
311-
}
312-
313-
// (GatewaySetupCode) decode raw setup codes.
314281
}
315282

316283
@MainActor

apps/ios/Sources/Onboarding/OnboardingWizardView.swift

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -203,14 +203,7 @@ struct OnboardingWizardView: View {
203203
return
204204
}
205205
if let message = self.detectQRCode(from: data) {
206-
if let link = GatewayConnectDeepLink.fromSetupCode(message) {
207-
self.handleScannedLink(link)
208-
return
209-
}
210-
if let url = URL(string: message),
211-
let route = DeepLinkParser.parse(url),
212-
case let .gateway(link) = route
213-
{
206+
if let link = GatewayConnectDeepLink.fromSetupInput(message) {
214207
self.handleScannedLink(link)
215208
return
216209
}

apps/ios/Sources/Onboarding/QRScannerView.swift

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,11 @@ struct QRScannerView: UIViewControllerRepresentable {
6565
let payload = barcode.payloadStringValue
6666
else { continue }
6767

68-
// Try setup code format first (base64url JSON from /pair qr).
69-
if let link = GatewayConnectDeepLink.fromSetupCode(payload) {
68+
if let link = GatewayConnectDeepLink.fromSetupInput(payload) {
7069
self.handled = true
71-
self.parent.onGatewayLink(link)
72-
return
73-
}
74-
75-
// Fall back to deep link URL format (openclaw://gateway?...).
76-
if let url = URL(string: payload),
77-
let route = DeepLinkParser.parse(url),
78-
case let .gateway(link) = route
79-
{
80-
self.handled = true
81-
self.parent.onGatewayLink(link)
70+
Task { @MainActor in
71+
self.parent.onGatewayLink(link)
72+
}
8273
return
8374
}
8475
}

0 commit comments

Comments
 (0)