Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
b59aac4
feat(limrun): serve iOS alert get/wait/accept/dismiss from tree capture
thymikee Oct 15, 2026
791519a
fix(limrun): harden iOS alert detection against ambiguous sheets
thymikee Oct 15, 2026
85ca5ca
refactor(alert): drive every tree-based alert backend through one sha…
thymikee Oct 16, 2026
2fb88ff
refactor(alert): ride main's deadline primitive with no sleep seam
thymikee Oct 16, 2026
61a270e
test(limrun): pin the accept-once/second-get-none timeline and satisf…
thymikee Oct 16, 2026
2a68d16
fix(alerts): resolve multi-grant sheets by a declared preference table
thymikee Oct 16, 2026
9bf80e2
fix(alerts): type the undecided state and bound the seams each budget…
thymikee Oct 16, 2026
0aadaab
fix(alerts): close the window holes the review found and cap the budget
thymikee Oct 16, 2026
2313a1a
fix(alerts): scope alert captures to the warm helper and split the un…
thymikee Oct 16, 2026
83b6129
fix(alerts): let only the latest answered capture claim a visible dialog
thymikee Oct 16, 2026
71087fb
fix(alerts): a deadline-straddling confirm capture cannot erase an an…
thymikee Oct 16, 2026
be48a28
test(alerts): pin the press cutoff's dispatched disclosure; review nits
thymikee Oct 16, 2026
5cfe029
fix(alerts): let started probes finish, rank Android grants by id
thymikee Oct 17, 2026
51b4941
fix(alerts): keep the mechanics façade lazy, honor cancel at every po…
thymikee Oct 17, 2026
3e1e3ae
docs(alerts): state the real lazy-load constraint, cancel truth, and …
thymikee Oct 17, 2026
5fc2322
fix(alerts): type the transport-death cancel as pre-press, and make t…
thymikee Oct 17, 2026
92df16a
docs(capture-kit): scope the transport-death cancel comment to the ro…
thymikee Oct 17, 2026
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
- 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 sessions now serve `alert get/wait/accept/dismiss` instead of refusing with `unsupported-provider-mode`. System alerts are read from the same element-tree capture snapshots ride — a blank-label, process-exclusive application root hosting a text-and-buttons sheet — and accepted or dismissed by tapping the button whose English label states the asked-for action; a capture that is alert-shaped but unresolvable (degraded buttons, competing sheets, an unverifiable owner) is reported as undecided and never pressed or counted as dismissed. The one shape no capture fact separates is an app dialog under a blanked root shared by no other process; the label-only acting legs answer it with a refusal, never a guess.
- The tree-based alert backends (Android and Limrun iOS) now share one alert driver and one button vocabulary. The vocabulary is a per-role preference table over English labels — `alert accept/dismiss` classify the same label the same way on both platforms, so Android now recognizes iOS variant grants (`Allow Once`, `Allow All the Time`, `Allow While Using App`, `Allow Notifications`) and `Ask App Not to Track` as acting choices — and Android layers its own grant-id rank on top of it: the permissioncontroller ids order the sheet's grants (foreground-only, then always, then one-time) wherever an id exists, so a localized Android 11+ sheet ("Mientras la app está en uso"/"Solo esta vez") and the Android 10 "Allow only while using the app" resolve to the lasting grant instead of refusing. A choice refuses only when the ranks name no single physical button for the action — the same label or the same grant id at two points, or a candidate no rank reaches — and each backend's own policy answers then (Android's neutral-button/Back fallback, Limrun's typed refusal). `alert not found` and the no-matching-button refusal now carry the same typed `details.reason` on both platforms. `alert get` reports its outcome as a typed `status` (`visible`/`none`/`undecided`) so clients switch on states instead of parsing the message. An alert budget bounds only how long a leg polls: every capture that started inside the budget finishes and its answer counts, and only the caller's cancellation stops a capture or press from being acted on (Android's adb child is killed; Limrun's client exposes no abort, so a call already in flight runs to its answer while the leg itself ends at the next seam the caller's cancellation can reach). A quiet-screen `alert accept|dismiss` therefore always answers `alert-not-found` with `dispatched: no`, never a reason that depends on which capture crossed the deadline. An `alert wait` budget above 2147483647 ms is refused as `INVALID_ARGS` rather than misfiring a timer.
- 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
4 changes: 4 additions & 0 deletions packages/capture-kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
"types": "./src/snapshot/android-replacement-surface-occlusion.ts",
"default": "./src/snapshot/android-replacement-surface-occlusion.ts"
},
"./alert-tree-driver": {
"types": "./src/alert-tree-driver.ts",
"default": "./src/alert-tree-driver.ts"
},
"./app-log-durable-resource": {
"types": "./src/capture-admission/app-log-durable-resource.ts",
"default": "./src/capture-admission/app-log-durable-resource.ts"
Expand Down
Loading
Loading