Skip to content

release: v0.4.10 — fix silent --device failures, real physical-device support - #189

Merged
justrach merged 1 commit into
mainfrom
release/0.4.10
Jul 25, 2026
Merged

release: v0.4.10 — fix silent --device failures, real physical-device support#189
justrach merged 1 commit into
mainfrom
release/0.4.10

Conversation

@justrach

Copy link
Copy Markdown
Owner

The bug

Every --device command silently did nothing and reported success.

devicectl.zig shelled out to bare xcrun devicectl. xcrun resolves through xcode-select, which on this machine points at CommandLineTools — where devicectl does not exist. Combined with io.runCommand not checking exit status, the failure was swallowed entirely.

# before
$ kuri-mobile ios launch --device --udid FAKEUDID com.foo.bar
$ echo $?
0        # did nothing whatsoever

# after
$ kuri-mobile ios launch --device --udid FAKEUDID com.foo.bar
devicectl failed (exit 1): ERROR: The specified device was not found. (Name: FAKEUDID)
error: the Xcode tool reported a failure (see the message above).
$ echo $?
1

This is the same bug class fixed for simctl in 0.4.6 — devicectl was missed. It now goes through the Xcode resolver by absolute path with a checked exit status.

A second latent bug: listDevicesJson passed --json-output -, but devicectl states that writing JSON to a file on disk is the only supported machine interface — it never writes JSON to stdout. That call would have created a file literally named -.

Physical device support

With the plumbing fixed, real devices gain genuine support:

Command Before After
install / uninstall simulator only ✅ devicectl
list-apps errored on --device ✅ devicectl
launch / terminate silently no-op ✅ works
device-info, device-processes, lock-state, displays, reboot ✅ new

lock-state is worth calling out: automation that appears to do nothing because the screen is locked is a common and confusing failure, and this makes it checkable.

Verified against a real paired iPhone (iPhone 16 Pro Max) — device-info returns actual hardware properties.

Scope, stated honestly

devicectl exposes no screenshot and no UI hierarchy. So tap/swipe/type/uitree/screenshot remain simulator-only no matter what is plugged in — those genuinely need XCUITest. The registry's scope field now reflects reality exactly:

41 tools | {'simulator': 29, 'simulator+device': 7, 'device': 5}

An agent reading ios tools --json can now tell "won't work on your phone" from "not set up yet" without trying it.

Verification

All four release targets build; test, test-fetch, test-browse, kuri-mobile's suite all exit 0; e2e-ios SKIPs cleanly with no simulator booted.

Not verified: no iOS device is currently connected (all three paired devices report unavailable), so the write paths — install --device, uninstall --device, reboot — are exercised only through the error path. device-info against a paired-but-disconnected device does return real data.

🤖 Generated with Claude Code

https://claude.ai/code/session_012gzdKWXk7UbHm5TtSGqYBJ

… support

Every `--device` command silently did nothing and reported success.
devicectl.zig shelled out to bare `xcrun devicectl`, which resolves through
xcode-select; when that points at CommandLineTools, devicectl is not there.
With an unchecked exit status on top, `ios launch --device` exited 0 having
done nothing. Same bug class fixed for simctl in 0.4.6 — devicectl was missed.

It now goes through the Xcode resolver by absolute path with a checked exit
status, so failures surface devicectl's own diagnostic. Verified: a bogus
udid used to exit 0, now exits 1 with "The specified device was not found".

listDevicesJson also passed `--json-output -`, but devicectl only writes JSON
to a file on disk, so that would have created a file named `-`.

With the plumbing correct, physical devices gain real support: install,
uninstall and list-apps now route to devicectl, plus new device-info,
device-processes, lock-state, displays and reboot. lock-state addresses a
common silent failure — automation that appears to do nothing because the
screen is locked.

devicectl exposes no screenshot and no UI hierarchy, so tap/swipe/type/
uitree/screenshot stay simulator-only regardless of what is attached; those
need XCUITest. The registry's scope field now says so exactly: 29
simulator-only, 7 simulator+device, 5 device-only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012gzdKWXk7UbHm5TtSGqYBJ
@justrach
justrach merged commit a363c22 into main Jul 25, 2026
@justrach
justrach deleted the release/0.4.10 branch July 25, 2026 06:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant