You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
record-video --format gif (top-level, ios record-video, and android record-video): record an animated GIF on both platforms. The format is also inferred from a .gif--output extension (explicit --format wins, with a stderr note on mismatch). Capture still runs through the existing H.264 pipelines into an intermediate MP4; on stop, the recording is transcoded into a looping GIF — sampled at --fps (GIF default 10) and scaled at --scale (GIF default 0.5), with per-frame delays derived from source timestamps so Android's variable frame rate keeps wall-clock pacing. A failed transcode preserves the intermediate MP4 and reports its path. (#84 — thanks @kws0210!)
Fixed
type "" (empty input) no longer runs the framework preflight: the empty-input short-circuit now returns before the Xcode check and private-framework load, not just before HID session creation. type "$VAR" with an empty variable is now a strict no-op even on hosts without a usable xcode-select path, and the preflight's subprocess no longer makes the empty-input unit test flake on loaded CI runners. (#92)
iOS hit-test probes no longer inherit the HID metric scale on display-downscaled devices (iPhone 12/13 mini, the 6/6s/7/8 Plus family). The AX point hit-test shares HID's native-portrait axes but consumes points in the UI point metric — verified live on iPhone 12 mini / iOS 26.4: querying the un-scaled UI point returns the element at that point, while the pixels/scale-shrunk point lands ~4% off. The UIPointScale introduced for HID dispatch was also applied to the orientation calibrator's discriminator probes, the quadtree recovery probes, and describe-ui --point's re-issued query, shifting every probe ~4% off target on those devices: small discriminators (a 17x22 toolbar button) missed outright, wasting the probe budget and degrading collapsed-children recovery. Probe transforms now rotate on the UI-sized canvas (OrientationCalibration.probeCGPoint) and only HID dispatch carries the metric scale. The remote-content retry's sampling grid (issue #64) also moves to the UI-sized canvas — recovering the scale from the shell root's own display frame — so the right/bottom ~4% of a downscaled screen (where a picker's bottom bar tends to live) is actually probed. Portrait probes are the identity everywhere — which is what keeps the single-probe --point fast path valid on downscaled panels — and devices that render 1:1 are untouched (the two canvases coincide). (#92)
iOS taps, swipes and point hit-tests now land on the right element on display-downscaled devices (iPhone 12/13 mini, the 6/6s/7/8 Plus family). Those models lay out a larger point space than they display — the mini renders 375x812 points into a 1125x2436 buffer and downsamples onto its 1080x2340 panel — while NativePortraitSize, the space HID normalizes against, is pixels / scale and therefore reads 360x780. The two spaces were treated as one (the portrait mapping is the identity), so every AX-derived coordinate was dispatched 4.1% away from the origin: measured live on iPhone 12 mini / iOS 26.3.1, tapping a Settings row whose frame spans y 648...700 opened the row below it, and a 48pt-tall button could only be hit by hand-dividing its center by 1.041. Calibration now carries a UIPointScale — the metric ratio between the UI point space and the framebuffer point space, recovered from the AX-reported screen size — and applies it in both directions, so the gesture canvas, the stale-snapshot advisory and the quadtree's UI-space probes agree with HID again. Identity on every device that renders at its panel resolution; a UI size that is a window rather than the display (a resized iPad scene) is rejected by an axis-skew guard rather than turned into a bogus scale. (#90 — thanks @subdiox!)
The iOS describe-ui text outline now renders value="…" for TextArea (UITextView / SwiftUI TextEditor — the shape of chat message inputs), Slider, and Button, not only TextField/SecureTextField/Switch. Text typed into a labeled multi-line editor was previously invisible in the outline — present only in --jsonentries[].value — so an agent could not confirm a type or a clear landed without falling back to JSON. A value that merely echoes the label slot is suppressed: this removes the pre-existing double print on label-less inputs (TextField "query" value="query") and keeps page controls and picker wheels (which the AX bridge reports as Slider with value == label) quiet. The whitelist additions are grounded in a live probe of the AX bridge's actual role vocabulary — see the playground's new Value Roles screen (UISearchBar → TextField, UIPageControl → Slider, UIProgressView → GenericElement, UISwitch → CheckBox); GenericElement stays excluded so status-bar values don't flood the outline. Android already rendered these correctly (EditText classifies as TextField regardless of textMultiLine); it gains a labeled multi-line fixture and a parity regression test. (#87)
JPEG frame scaling now produces the requested pixel dimensions on Retina displays instead of multiplying the result by the screen backing scale (#83, #85 — thanks @EuanTop!).
The SIM_USE_VERSION build-time override actually reaches the version stamp now. VersionPlugin registered its generator command with an empty environment, so the documented "environment variable first" priority was dead code and every build fell back to git describe — release builds happened to be correct only because they build on the tagged commit, while scripts/dev-install.sh builds stamped a stale describe string. The override is now resolved in the plugin process and baked into the command's argv, which also makes a changed override invalidate SPM's command cache without requiring a source-file edit.