fix(ios): book every surface on the lit panel, not the first window

TH
6h ago
+1459-55

Problem

On a foldable iPhone, gestures, reads, the snapshot viewport, and capture used SpringBoard's first window, which is the outer status bar even when the inner panel is lit.

Change

  • The host names the lit panel per surface command, within timeoutMs, and gives the runner the remaining budget. A known multi-panel device whose panel table is unread is refused (panel-table-unreadable).
  • The runner books one lit window per request before acting, keyed to its app, and refuses with typed APP_SCREEN_* codes. Element reads search only windows that report the lit display. The panel is written in main-queue order.
  • Snapshots run the tree tier only, keep proven lit windows (raw too), and use the booked frame as root.
  • Without litPanel, routes match main.

Net production lines: 1,164 → 622.

Duo evidence

  • Runner screenshot: unfolded lit=3 … frame=(0,0 951x669), SCREEN_CAPTURE display=3, home and Settings. Folded lit=1, display=1. Each PNG shows the lit panel.
  • Unfolded get text: Search field via runner readText (lit=3, 2 windows) returned "Search". Icon and row labels come from the tree ("Settings", "General").
  • Unfolded snapshot: nodes[0].rect = (0,0,951,669). find Safari (x=871) tapped it.
  • Tap: reference=(0,-0,951,669), displayID=3. Folded reference=(0,0,466,678), displayID=1.
  • iPhone 17 Pro: no lit-panel lines, reference=(0,0,402,874).

Tests: iOS 42/42, macOS 32/0 (method-level).

šŸ¤– Generated with Claude Code