feat(snapshot): measure Android Appium viewport
Summary
Android Appium snapshots publish a validated display viewport independently of source-tree extent. Measurements before and after capture must agree. Each optional /window/rect probe bounds client waiting to 500ms with no retry; unavailable/disagreeing measurements are omitted. Caller cancellation rejects the snapshot.
Example: agent-device snapshot --json can return viewport: { "width": 1080, "height": 2400 } for a sparse tree. Keyboard content resizing does not determine viewport dimensions.
Six files: client/interactor code and tests, owning help, and snapshot docs. No scope expansion.
Closes #3528
Validation
Head: 77705524132640bf9ded9acafe15ce8b104301bc (unchanged).
| Regression checks | base 1a328cc46 | head 777055241 |
|---|---|---|
| Before/after viewport mismatch cases | 3 failed | 3 passed |
Focused client/interactor tests: 63 passed. pnpm check:affected --run: passed on this exact head, 209 files / 1,732 tests.
Live evidence and exact commands: API 35 emulator-5564, Appium portrait 1080×2400, landscape 2400×1080, keyboard 1080×2400, sparse five-node 420×320 window still 1080×2400 viewport. All matched Appium window rectangle and Android logical display bounds; source extent was never substituted. Sparse-tree variant tested. No fix needed.
Disposable emulator/AVD and our Appium server cleaned up; emulator-5554 untouched.
CI green, including Coverage, Integration Tests, and platform smoke; zero unresolved threads. Client abort cannot cancel Appium execution or release its command lock. No remaining requested live-check gap.