fix(apple): refuse captures whose window or panel identity is unknown

TH
2h ago
+275-25

Summary

  • ADR 0031: a native macOS app screenshot now captures the front window or refuses. Before, it captured the largest window when ScreenCaptureKit did not offer the front window. New typed reasons: window-not-found and front-window-not-shareable. A shared fixture pins them for Swift and TypeScript, and the host adds a hint.
  • ADR 0025: a foldable capture refuses with COMMAND_FAILED, reason capture-panel-unidentified, when no panel is primary and power does not identify one lit panel. Before, it picked a panel by list order. The sole-lit-panel and primary-panel paths are unchanged. Simulator video recording uses the same resolver.

10 files. Help and user docs are updated. ADR text is unchanged. Part of #3744.

Validation

  • Head dec7c9ba41: pnpm check:affected --run passed with exactCommit=true (format, lint, typecheck, layering, fallow, build, vitest-related, docs). pnpm test:macos-helper: 11 passed.
  • Regression proof, with the base production code or a planted fallback to another window:
    • display-inventory.test.ts: 2 failed, 35 passed, then 37 passed.
    • helper.test.ts: 1 failed, 10 passed, then 11 passed.
    • Swift helper tests: 1 failed of 11, then 11 passed.
  • Device evidence:
    • macOS: not obtained. The live TextEdit capture failed with the Screen Recording permission refusal. CGPreflightScreenCaptureAccess() is false in the agent host and in Ghostty. The case where the front window is missing could not be provoked live.
    • iPhone Duo: no live run. This Mac lacks the iOS 27.1 simulator runtime.
  • The macOS / Smoke Tests CI job covers the Swift helper build.

Live checks before merge

An independent Codex review found no code findings. These live checks are still open, because this agent host has no Screen Recording permission and no iOS 27.1 simulator runtime:

  • macOS, with Screen Recording permission: take native app screenshots with two windows of different sizes, a sheet or popover or panel, a menu-bar extra, and a fullscreen Space. Each capture is the front window or a typed refusal, never another window. Also run overlays and a live screenshot diff.
  • iOS 27.1 iPhone Duo: take a screenshot and a recording in the closed and open poses. Confirm the named panel, its point size, and a tap on a fresh ref. Confirm that a rotated single-panel iPhone or iPad keeps its capture behavior.