feat(screenshot): add a per-request iOS simulator screen mask
Summary
Adds request-scoped --screen-mask black for iOS/iPadOS simulator outlines and deterministic visual baselines. Apple declares support for handheld simctl captures; other capture bindings refuse masks. Masked requests cannot fall back to runner.
agent-device screenshot baseline.png --screen-mask black
agent-device diff screenshot --baseline baseline.png --screen-mask black
Node/MCP: screenMask: "black". Saved-image diffs reject it; defaults and thresholds stay unchanged. tvOS/visionOS are unsupported.
31 files. Scope expanded to per-request APIs, live diffs, and capture-owner enforcement following review. No dedicated issue; related #4184 addresses runner capture.
Validation
Head: 71739389ed2b21d7188d11a7055fdcea797e58cc.
Main: 035c2b6cae0b5a2d6b769c36f63daa1e99f92420.
pnpm check:affected --run --head 71739389ed2b21d7188d11a7055fdcea797e58cc (Node 24.13): failed, exactCommit:true. Identical related-suite command on unchanged main: 1,256 passed/4 failed on both, all Apple-runner symlink-removal failures.
Same regression command: prior head 0bbe8a6f1148daa7bb743c85d739c2c273d6946b plus tests 11 failed/33 passed; head 44 passed. Eager-loading/capture suites: 936 passed. Separate unit diagnosis reproduced host-kit failures and Android line 117 on main; Android line 143 remains inconclusive.
Live at da8b7036d8874d7322e07026d50ab7c4a18b759f (production unchanged): iPhone 12 mini, iOS 18.6, 360×780. Black/default/black confirms request isolation. Same-screen diff matched: 0/280,800 pixels; changed screen differed: 40,549 (14.44%). Overlay preserves the outline; its red annotation crosses the top-left corner.
| Black | Default | Black again | Changed-screen overlay |
|---|---|---|---|
![]() | ![]() | ![]() | ![]() |
Ready for CI as requested by @thymikee; local gate remains base-blocked. CI/native/provider lanes remain required. Vercel needs maintainer authorization.



