Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Add `settings mobile-data on|off` for adb-backed Android targets. It switches mobile data through `svc data` and reports the `mobileData` state stored in the global `mobile_data` row; multi-SIM read-back is not covered yet. Every other target refuses it before anything runs, and `--app` is refused because the switch is device-wide.
- On iOS, a `fill` that runs under a degraded XCTest snapshot channel now aims at a point, including ref, selector and replay fills. When the runner identifies no text input under that point, it refuses with `NO_TEXT_INPUT_AT_POINT` (`error.details.reason: no_text_input_at_point`, `dispatched: no`) before dispatching its focus tap, and no field changes; when the input lookup itself cannot answer, it refuses with `TEXT_INPUT_PROBE_UNAVAILABLE` (`error.details.reason: text_input_probe_unavailable`). Previously such a fill cleared and typed through the app-level first responder, so it could rewrite a field the caller never named, or report a clear failure after emptying it. A ref or selector fill whose rect centre misses the real field (an outer container, a non-input node) now needs a point inside the input's own rect.
- Opening a macOS app by bundle identifier now waits briefly when the app is already running but not yet registered with LaunchServices — the case when a supervisor or dev script started it directly — and if registration arrives within that bounded window the open attaches to the running copy, so the session drives the app the caller started, with its arguments. A copy still unlisted when the window closes gets the plain `open` as before, which can still duplicate; the wait only bounds the race, it does not close it. Launching an app that is not running costs one extra LaunchServices lookup and one process-table read, plus one bundle-identifier read when app-shaped processes exist.
- Limrun iOS snapshots no longer fail when the instance reports a numeric or boolean accessibility value (the system photo picker's tabs report `1`/`0`): the provider seam normalizes variant scalars to text, the way the Apple tree does. Limrun nodes now also publish `selected: true` for nodes carrying the `Selected` trait, so snapshot output and `selected:` selectors can tell a picked photo from an unpicked one.
- `settings` refuses a setting the target does not serve before anything changes, with `UNSUPPORTED_OPERATION`, `settings <setting> is not supported on this device`, and the target's `error.details.reason` (such as `unsupported-platform-leaf`). This replaces the macOS `INVALID_ARGS` refusal and the Apple `setting-unsupported-on-leaf` reason, and now also covers settings that used to reach the device first, such as Android `reset-keychain` or Apple `animations`.
- `settings` refuses, before touching the device, a state its setting does not accept (`Invalid <setting> state: …`), a permission action or mode its target does not take (such as `permission deny accessibility`), and a stray extra argument (such as `clear-app-state <app> <extra>`). The CLI and the daemon accept the same state spellings, in any casing or surrounding whitespace.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@ test('local Apple tool provider exposes macOS host operations as semantic method
const calls: Array<[string, string[], string | undefined]> = [];
const provider = createLocalAppleToolProvider({
runCommand: async (cmd, args, options) => {
// The bundle open's LaunchServices registration probe is the seam's own read, asserted in
// launch-services-registration.test.ts; this routing test only reports it as listing the bundle.
if (cmd === '/usr/bin/lsappinfo') {
return { exitCode: 0, stdout: 'ASN:0x0-0x1234-"Demo":\n', stderr: '' };
}
calls.push([cmd, args, typeof options?.stdin === 'string' ? options.stdin : undefined]);
if (cmd === 'pbpaste') {
return { exitCode: 0, stdout: 'copied\r\n', stderr: '' };
Expand Down
6 changes: 6 additions & 0 deletions packages/platform-apple/src/os/macos/host-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ export function createLocalAppleMacOsHostProvider(
): AppleMacOsHostProvider {
return {
openBundle: async (bundleId, url) => {
// Loaded on the first bundle open, not when this provider is constructed: the probe's host-kit
// reads stay off the Apple façades' eager closure (ADR 0019), and an open of an already-listed
// app is the common path that never needs them until `open` actually runs.
const { waitForLaunchServicesRegistration } =
await import('./launch-services-registration.ts');
await waitForLaunchServicesRegistration(runCommand, bundleId);
await runCommand('open', buildMacOpenArgs(bundleId, url));
},
openTarget: async (target) => {
Expand Down
Loading
Loading