v2.4.0
One coordinate space across every tool, and tap no longer taps through overlays.
Found while driving a third-party in-app devtool whose sheet is an ordinary absolutely-positioned view rather than a Modal.
One coordinate space
get_screen_state emitted raw points while the screenshot tools and tap() spoke delivered-image pixels — a 2.19× disagreement on a 3x device. Coordinates taken from the tool the descriptions pointed agents at landed nowhere near the element.
Delivered-image pixels are now the single contract. get_screen_state, get_screen_layout, inspect_at_point (output and input) and measure all convert through a shared per-device scale. tap, swipe and ocr_screenshot are unchanged — the space they already used is the one everything else moved onto.
When the device scale can't be read, the tools now say so instead of silently reverting to points.
Overlay detection
Overlays were only recognised if they could be named (Modal, BottomSheet, native presentations). Anything under an undeclared sheet was reported reachable, and a tap on it was swallowed while reporting success: true.
Detection is now geometric, judged on measured frames. Route containers and off-screen drawers are excluded, and a candidate must actually occlude a foreign, earlier-painted element to count as an overlay.
tap refuses covered targets
tap now declines before dispatch when the resolved target is covered, naming the overlay, rather than firing a touch that the OS will hand to something else. Previously such a tap mutated app state the caller never asked to change and was never told about.
The check runs in target resolution, so it covers fiber, accessibility, OCR and raw coordinates alike. It is bounded and failure-open: a slow or inconclusive read dispatches as before, and it declines to judge when nothing on screen reads as reachable — a misclassification cannot disable tapping. Where an overlay's own control sits over a covered element the tap still fires, and the response names what actually received it.
Truthful verification
verification.explanation no longer claims "the screen updated as expected" — a pixel diff cannot identify which element responded, which is how the original mis-tap read as a success.
diagnoseCoordinateMiss also loses a scale heuristic that carried no safe-area term and could offset its probe onto a neighbouring element, producing confident "check your onPress handler" advice about elements that were in fact covered.