Skip to content

Commit 7026c7b

Browse files
committed
docs(snapshot): name the producers that actually answer the viewport question (#3182)
The contract and user docs claimed a web producer that does not exist: platform-web hands over a tree and never reads a screen, and neither does Linux. They now name the two surfaces that answer and the absences that are real, including raw, which validates no box. The Node client page gains the field, following how readiness was documented.
1 parent f8b6cfe commit 7026c7b

5 files changed

Lines changed: 20 additions & 14 deletions

File tree

‎packages/capture-kit/src/snapshot-state.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export function buildSnapshotState(
5252
targetActivation?: IosTargetActivation;
5353
/** The keyboard band the producer measured, carried to the state the tap guards read (#2660). */
5454
keyboard?: SnapshotKeyboardBandFact;
55-
/** The box the producer measured the rects in (#3182), carried to the response and the find path. */
55+
/** The box the producer measured the rects in (#3182), carried to the response that reads this state. */
5656
viewport?: SnapshotViewportSize;
5757
} & SnapshotCaptureProvenance,
5858
flags:

‎packages/contracts/src/client-capture.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ export type CaptureSnapshotResult = {
7272
*
7373
* Which surface it names is the producer's answer, not always the physical panel: the app window
7474
* for iOS (so iPad Split View and a foldable panel do not inflate it), the screen the bounds were
75-
* measured on for Android and Apple TV, the browser viewport on web. Absent means the producer
76-
* measured no box — a provider handing over a bare tree, or a desktop capture with no single
77-
* window behind it — and never a zero. This is the full screen size only; content-safe gesture
78-
* bounds stay with #1821.
75+
* measured on for Android and Apple TV. Absent means the producer measured no box — a desktop
76+
* capture whose rects are absolute in window space, a backend that reads a tree without reading a
77+
* screen, or a raw projection nothing validated a box against — and never a zero. This is the full
78+
* screen size only; content-safe gesture bounds stay with #1821.
7979
*/
8080
viewport?: SnapshotViewportSize;
8181
/**

‎packages/kernel/src/snapshot.ts‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,11 @@ export type SnapshotKeyboardBandFact =
347347
* It is the box of the surface the producer read, which is not always the physical panel. iOS
348348
* reports the app window in the app's orientation space (ADR 0004), which is smaller than the panel
349349
* under iPad Split View and is never the foldable panel `fold` reports (ADR 0025); Android and the
350-
* Apple TV runner report the screen the bounds were measured on; web reports the browser viewport
351-
* the box model is relative to. A consumer that needs a *gesture* band inside those bounds still
352-
* reads `keyboard` and the app window, which is #1821's remaining scope.
350+
* Apple TV runner report the screen the bounds were measured on. A producer that has no box of its
351+
* own to answer with leaves the field off: the macOS desktop, whose rects are absolute in window
352+
* space and answer to no single frame, and the web and Linux backends, which read a tree without
353+
* reading a screen. A consumer that needs a *gesture* band inside those bounds still reads `keyboard`
354+
* and the app window, which is #1821's remaining scope.
353355
*
354356
* Absent means the producer measured no box. Absence is never `0`: `snapshotViewportSizeFrom` from
355357
* `@agent-device/kernel/rect` is the sole construction path and refuses a box
@@ -665,9 +667,10 @@ export type SnapshotState = {
665667
*/
666668
keyboard?: SnapshotKeyboardBandFact;
667669
/**
668-
* The box these rects are measured in, as the producer measured it (#3182). The session keeps it so
669-
* a consumer of the stored tree — the find-path viewport, a later diff — reads the same box the
670-
* response published instead of inferring one from the largest rect still on screen.
670+
* The box these rects are measured in, as the producer measured it (#3182). The state is the carrier
671+
* the response reads, so the stored tree and the published `viewport` are one fact rather than two:
672+
* a consumer of a stored capture — a later diff, a re-read of the session's tree — gets the box the
673+
* producer measured instead of inferring one from the largest rect still on screen.
671674
*/
672675
viewport?: SnapshotViewportSize;
673676
/**

‎website/docs/docs/client-api.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ The complete domain-client method map is:
346346

347347
`client.devices.list()` returns `AgentDeviceDevice` entries. Their optional `model` and `osVersion` fields describe the hardware and OS when discovery reports them; see [Device discovery](/docs/commands#device-discovery) for the sources.
348348

349+
`client.capture.snapshot()` carries an optional `viewport: { width, height }` beside `nodes`: the box those rects are measured in, in the same coordinate space and orientation, so a consumer scales and clips against the screen it was shown instead of inferring one from the largest rect on screen. It is absent when the producer measured no box and never reported as a zero; see [`snapshot`](/docs/commands) for what each producer answers with.
350+
349351
`client.observability.events({ cursor, limit })` reads the session event timeline as paged JSON entries. Use `nextCursor` from the previous page to continue from the daemon-owned `events.ndjson` file without replaying already uploaded/displayed events. Cursors are absolute and survive the file's size rotation; a cursor older than the retained window rejects with `COMMAND_FAILED`, `details.reason: "EVENT_LOG_CURSOR_EXPIRED"`, and `details.earliestCursor` to resume from.
350352
The event timeline keeps operational context such as command/status/timing, paths, session/device/app identifiers, refs/selectors, and coordinates. Typed text, clipboard writes, push/event payloads, raw unknown command arguments, and matching raw message fragments are replaced with length-only placeholders.
351353

‎website/docs/docs/commands.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,10 @@ agent-device get attrs @e1
415415
space and orientation as the rects beside it, so a consumer scales and clips against the screen it
416416
was shown instead of inferring one from the largest rect on screen. Which surface it names is the
417417
producer's answer: the app window on iOS (so iPad Split View and a foldable panel do not inflate
418-
it), the measured screen on Android and Apple TV, the browser viewport on web. It is absent when
419-
the producer measured no box — a bare provider tree, a desktop capture with no single window —
420-
and never reported as a zero. It is the full size only; content-safe gesture bounds are separate.
418+
it), the measured screen on Android and Apple TV. It is absent when the producer measured no box —
419+
a macOS capture whose rects are absolute in window space, a web or Linux capture that reads a tree
420+
without reading a screen, or `--raw`, which validates no box — and never reported as a zero. It is
421+
the full size only; content-safe gesture bounds are separate.
421422
- `--scope <text|@ref>` returns the subtree of the first node in document order whose label, value,
422423
or identifier contains the scope text (case-insensitive) and whose subtree still has content in
423424
the requested projection, re-rooted at depth 0; no match returns an empty snapshot rather than the

0 commit comments

Comments
 (0)