You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(cli): declarative motion verification in inspect (#1437)
Extend `inspect` to verify motion intent against the same seeked timeline
the renderer uses, catching render-≠-preview bugs that layout sampling can't:
entrance reveals the seek skips, broken stagger order, off-frame drift, and
frozen shots.
A `*.motion.json` sidecar next to the composition opts in (auto-discovered,
no flag, no authoring-framework changes); without one, inspect is unchanged.
inspect seeks a dense grid over the asserted selectors, builds an
element × time matrix of {rect, opacity, visible} plus per-scope liveness
signatures, and evaluates four assertions in Node:
appearsBy -> motion_appears_late
before -> motion_out_of_order
staysInFrame -> motion_off_frame
keepsMoving -> motion_frozen
A selector matching nothing is reported as motion_selector_missing rather
than silently passing. Findings reuse the LayoutIssue shape and flow through
the existing dedupe/collapse/limit/format pipeline and JSON envelope; they
are errors by default, so a failed assertion fails the run.
The motion pass runs in the same Chrome session as the layout audit (no extra
launch) and only when a sidecar is present.
Copy file name to clipboardExpand all lines: docs/packages/cli.mdx
+26-1Lines changed: 26 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ npx hyperframes <command>
19
19
- Preview compositions with live hot reload (`preview`)
20
20
- Render compositions to MP4 locally or in Docker (`render`)
21
21
- Lint compositions for structural issues (`lint`)
22
-
- Inspect rendered visual layout for text overflow, clipped containers, and overlapping text (`inspect`)
22
+
- Inspect rendered visual layout for text overflow, clipped containers, and overlapping text, plus verify motion intent against the seeked timeline (`inspect`)
23
23
- Capture key frames as PNG screenshots (`snapshot`)
24
24
- Check your environment for missing dependencies (`doctor`)
25
25
@@ -580,6 +580,31 @@ This is suppressed in CI environments, non-TTY shells, and when `HYPERFRAMES_NO_
580
580
npx hyperframes layout [dir] --json
581
581
```
582
582
583
+
#### Motion verification
584
+
585
+
`inspect` also checks **motion intent** against the same seeked timeline the renderer uses — catching the render-≠-preview bugs that layout sampling can't, like an entrance reveal the seek skips, a broken stagger order, an element that drifts off-frame mid-tween, or a shot that freezes. Drop a `*.motion.json` sidecar next to the composition and `inspect` evaluates it automatically (no flag, no authoring changes); without a sidecar, `inspect` behaves exactly as before.
|`appearsBy(selector, bySec)`| the element is visible (opacity ≥ 0.5) no later than `bySec` — catches reveals the seek lands past (`motion_appears_late`) |
602
+
|`before(a, b)`|`a` first appears strictly before `b` — catches broken stagger order (`motion_out_of_order`) |
603
+
|`staysInFrame(selector)`| once visible, the element's box never leaves the canvas — catches off-frame drift (`motion_off_frame`) |
604
+
|`keepsMoving(withinSelector?)`| no fully-static window longer than `maxStaticSec` (default 2s) — catches frozen shots (`motion_frozen`) |
605
+
606
+
`duration`, `keepsMoving.withinSelector`, and `keepsMoving.maxStaticSec` are optional. Findings are reported in the same shape and JSON envelope as layout findings, are **errors by default** (a failed assertion fails the run), and a selector that matches nothing is reported as `motion_selector_missing` rather than silently passing.
607
+
583
608
### `snapshot`
584
609
585
610
Capture key frames from a composition as PNG screenshots — verify visual output without a full render:
0 commit comments