hyperframes 0.7.57 → 0.7.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/cli.js +4218 -2643
  2. package/dist/commands/contrast-audit.browser.js +69 -19
  3. package/dist/commands/layout-audit.browser.js +168 -35
  4. package/dist/hyperframe-runtime.js +27 -27
  5. package/dist/hyperframe.manifest.json +1 -1
  6. package/dist/hyperframe.runtime.iife.js +27 -27
  7. package/dist/hyperframes-player.global.js +1 -1
  8. package/dist/skills/hyperframes/SKILL.md +103 -124
  9. package/dist/skills/hyperframes/references/capability-menu.md +47 -0
  10. package/dist/skills/hyperframes/references/pitch-round.md +40 -0
  11. package/dist/skills/hyperframes/references/route-briefs.md +85 -0
  12. package/dist/skills/hyperframes/references/skill-lifecycle.md +33 -0
  13. package/dist/skills/hyperframes/references/workflow-catalog.md +70 -0
  14. package/dist/skills/hyperframes-cli/SKILL.md +99 -109
  15. package/dist/skills/hyperframes-cli/references/beats.md +19 -0
  16. package/dist/skills/hyperframes-cli/references/cloud.md +8 -3
  17. package/dist/skills/hyperframes-cli/references/cloudrun.md +62 -0
  18. package/dist/skills/hyperframes-cli/references/compare-and-batch.md +105 -0
  19. package/dist/skills/hyperframes-cli/references/lambda.md +77 -24
  20. package/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +3 -3
  21. package/dist/skills/hyperframes-cli/references/preview-render.md +7 -3
  22. package/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +2 -0
  23. package/dist/studio/assets/{hyperframes-player--Z69cEkE.js → hyperframes-player-Bm07FLkl.js} +1 -1
  24. package/dist/studio/assets/{index-KsfE1bUu.js → index-B995FG46.js} +1 -1
  25. package/dist/studio/assets/index-CrkAdJkb.js +426 -0
  26. package/dist/studio/assets/index-Dj5p8U_A.css +1 -0
  27. package/dist/studio/assets/{index-Bf1x1y8H.js → index-FvzmPhfG.js} +1 -1
  28. package/dist/studio/{chunk-5QSIMBEJ.js → chunk-OBAG3GWK.js} +33 -21
  29. package/dist/studio/chunk-OBAG3GWK.js.map +1 -0
  30. package/dist/studio/{domEditingLayers-6LQGKPOI.js → domEditingLayers-2CKWGEHS.js} +2 -2
  31. package/dist/studio/index.d.ts +27 -7
  32. package/dist/studio/index.html +2 -2
  33. package/dist/studio/index.js +18029 -11563
  34. package/dist/studio/index.js.map +1 -1
  35. package/dist/studio/styles/tailwind-preset.d.ts +5 -0
  36. package/dist/studio/styles/tailwind-preset.js +8 -1
  37. package/dist/studio/styles/tailwind-preset.js.map +1 -1
  38. package/dist/templates/_shared/AGENTS.md +5 -4
  39. package/dist/templates/_shared/CLAUDE.md +5 -4
  40. package/package.json +2 -2
  41. package/dist/studio/assets/index-DfmYkU44.js +0 -423
  42. package/dist/studio/assets/index-_pqzyxB1.css +0 -1
  43. package/dist/studio/chunk-5QSIMBEJ.js.map +0 -1
  44. /package/dist/studio/{domEditingLayers-6LQGKPOI.js.map → domEditingLayers-2CKWGEHS.js.map} +0 -0
@@ -0,0 +1,33 @@
1
+ # Skill installation and freshness
2
+
3
+ Read this reference when installing or updating skills, diagnosing unexpected workflow behavior, or running HyperFrames setup in CI.
4
+
5
+ HyperFrames installs the core set eagerly and workflow skills lazily.
6
+
7
+ - **Core set:** `/hyperframes`, the `hyperframes-*` domain skills, and `/media-use`.
8
+ - **Workflow skills:** installed when routing selects them through `npx hyperframes skills update <workflow-name>`.
9
+
10
+ ## What `init` does
11
+
12
+ `npx hyperframes init` checks GitHub and refreshes the core set plus other skills already installed. It does not install workflows that have never been used. A current install is a no-op. Offline or rate-limited checks degrade gracefully and do not fail project scaffolding.
13
+
14
+ The `--skip-skills` CLI flag is temporarily ignored. CI and tests may opt out with `HYPERFRAMES_SKIP_SKILLS=1`.
15
+
16
+ ## Diagnose and update
17
+
18
+ ```bash
19
+ npx hyperframes skills check
20
+ npx hyperframes skills check --json
21
+ npx hyperframes skills update
22
+ npx hyperframes skills update <workflow-name>
23
+ npx hyperframes skills
24
+ ```
25
+
26
+ - `skills check` exits non-zero when an installed skill is stale or the core set is incomplete. Workflows available on demand but not installed are not failures.
27
+ - Bare `skills update` refreshes the core set and everything already installed, prunes unpublished skills, and does not expand the workflow set.
28
+ - Named `skills update <name...>` also installs those named workflows or domain skills.
29
+ - Bare `skills` installs the full published set explicitly.
30
+
31
+ If the HyperFrames CLI is unavailable, use `npx skills add heygen-com/hyperframes --skill <workflow-name>` for one workflow or `npx skills add heygen-com/hyperframes --all` for the full published set.
32
+
33
+ The CLI may print a one-line stale-skill reminder during `render`, `lint`, or `check`. Treat a failed update as a visible tool failure; do not continue from a remembered workflow contract.
@@ -0,0 +1,70 @@
1
+ # Workflow catalog
2
+
3
+ Use this catalog while routing, before the selected workflow is lazy-installed. After the routing table in `../SKILL.md` yields a candidate, read that candidate's section and confirm that its input and output match the request.
4
+
5
+ ## Sections
6
+
7
+ - [`/product-launch-video`](#product-launch-video), [`/faceless-explainer`](#faceless-explainer), [`/pr-to-video`](#pr-to-video)
8
+ - [`/embedded-captions`](#embedded-captions), [`/talking-head-recut`](#talking-head-recut)
9
+ - [`/motion-graphics`](#motion-graphics), [`/music-to-video`](#music-to-video), [`/slideshow`](#slideshow)
10
+ - [`/general-video`](#general-video), [`/remotion-to-hyperframes`](#remotion-to-hyperframes)
11
+
12
+ ## `/product-launch-video`
13
+
14
+ - **Input:** A website URL; a script or brief that names a site; or a product-launch script with no derivable site or an explicit “do not scrape” instruction. Capture website assets and brand tokens unless the brief selects no-capture mode. Ask whether supplied script copy is verbatim voice-over or may be restructured.
15
+ - **Output:** A product promo, launch video, site tour, or showcase MP4. Sweet spot 30–90s; hard cap about 3 minutes. A show-it-as-is brief features captured screens rather than inventing a separate route.
16
+ - **Triggers:** “launch video for X”, “promo for our site”, “turn this script into a 60s promo”, “text-only launch video”, “turn this website into a video”, “site tour from this URL”.
17
+
18
+ ## `/faceless-explainer`
19
+
20
+ - **Input:** A topic, article, notes, or arbitrary text being explained, with no product being marketed and no website to capture.
21
+ - **Output:** A faceless explainer MP4 with invented typography, abstract graphics, diagrams, or data visualization. Sweet spot 30–90s; hard cap about 3 minutes.
22
+ - **Triggers:** “faceless explainer about X”, “explain how DNS works as a video”, “turn this article into an explainer”.
23
+
24
+ ## `/pr-to-video`
25
+
26
+ - **Input:** A GitHub PR URL, `owner/repo#N`, or “this PR”, read through `gh`; it is not a website capture request.
27
+ - **Output:** A changelog, feature reveal, fix explainer, or refactor walkthrough with diff, before/after, file-tree, and impact scenes. Hard cap about 3 minutes; duration follows change size.
28
+ - **Triggers:** “make a video about this PR”, “turn PR #1187 into a changelog video”, “release-notes video from this pull request”.
29
+
30
+ ## `/embedded-captions`
31
+
32
+ - **Input:** Existing talking-head footage to caption. It is an actual media file, not a URL or creative brief.
33
+ - **Output:** The same footage, untouched, with a caption layer and selected caption identity. The subject may occlude embedded captions. Any length.
34
+ - **Triggers:** “add captions”, “add subtitles”, “captions behind the subject”, “cinematic captions for my clip”.
35
+
36
+ ## `/talking-head-recut`
37
+
38
+ - **Input:** Existing talking-head, interview, or podcast footage to package. The underlying clip plays unchanged.
39
+ - **Output:** The same footage with transcript-synced graphic-overlay cards: kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, or picture-in-picture. Any length.
40
+ - **Triggers:** “package this video”, “add graphic overlays to my talk”, “add lower-thirds or data callouts to this interview”.
41
+
42
+ ## `/motion-graphics`
43
+
44
+ - **Input:** A short design-led unit, typically under 10s, with no narration, where motion is the message: kinetic type, stat/count-up, chart hit, logo sting, animated title, lower-third, map, tweet/headline/page highlight, or asset-fusion shot.
45
+ - **Output:** A short MP4 or transparent alpha WebM/MOV overlay.
46
+ - **Triggers:** “an 8s logo sting”, “animate this stat”, “kinetic-type intro”, “animate this title”, “transparent lower-third overlay”.
47
+
48
+ ## `/music-to-video`
49
+
50
+ - **Input:** A music track, or a video whose audio becomes the track, with no narration or website capture. User images or videos are optional.
51
+ - **Output:** A beat-synced MP4 driven by a deterministic beat/energy map (`audiomap.json`). It may become a lyric video, slideshow, visualizer, or kinetic promo without changing pipelines.
52
+ - **Triggers:** “make a video for this song”, “beat-synced video”, “lyric video”, “music visualizer”, “kinetic promo to this beat”.
53
+
54
+ ## `/slideshow`
55
+
56
+ - **Input:** A brief, outline, or existing page to author as a presentation, pitch deck, or interactive deck. If “slides”, “deck”, or “convert this page” is ambiguous, confirm that the user wants a HyperFrames slideshow before authoring.
57
+ - **Output:** A runnable HyperFrames composition plus the JSON island used by `SlideshowController`: discrete slides, fragment reveals, branching, hotspots, presenter mode, and speaker notes. The deliverable is a navigable deck, not an MP4.
58
+ - **Triggers:** “make a pitch deck”, “interactive presentation”, “convert this page into slides”, “slideshow with presenter mode”.
59
+
60
+ ## `/general-video`
61
+
62
+ - **Input:** Any custom creation or edit not covered above: a static title card, longer brand or sizzle reel, multi-scene montage, static loop/poster, NLE-like footage remix, or freeform composition. It also executes every `flow: companion` brief.
63
+ - **Output:** A HyperFrames composition of any length or format through design → plan → static layout → animation → check → approval → render.
64
+ - **Triggers:** “make a static title card”, “longer brand reel”, “multi-scene composition”, “static loop”, “custom video”, or any unmatched video request.
65
+
66
+ ## `/remotion-to-hyperframes`
67
+
68
+ - **Input:** Existing Remotion React source, only when the user explicitly asks to port, convert, or migrate it. A passing Remotion mention is not a trigger.
69
+ - **Output:** A HyperFrames HTML composition translated from the source and compared with the Remotion render through the migration evaluation harness.
70
+ - **Triggers:** “port my Remotion project”, “convert this Remotion composition”, “migrate from Remotion”.
@@ -1,146 +1,136 @@
1
1
  ---
2
2
  name: hyperframes-cli
3
- description: HyperFrames CLI dev loop. Use when running npx hyperframes init, add, catalog, capture, lint, check, snapshot, compare, grade-compare, preview, play, render, publish, cloud, feedback, lambda, doctor, browser, info, upgrade, skills, compositions, docs, benchmark, telemetry, transcribe, tts, or remove-background (validate/inspect/layout are deprecated aliases covered by check), or when troubleshooting the HyperFrames build/render environment. Entry point for HeyGen-hosted cloud rendering (`hyperframes cloud render / list / get / delete`) and self-managed AWS Lambda rendering (`hyperframes lambda deploy / render / progress / destroy / policies / sites`).
3
+ description: >
4
+ Use the HyperFrames CLI development loop: init, add, catalog, capture, lint, check, snapshot,
5
+ compare, grade-compare, preview, play, present, beats, keyframes, single or batch render, publish,
6
+ cloud, cloudrun, feedback, lambda, doctor, browser, info, upgrade, skills, compositions, docs,
7
+ benchmark, telemetry, transcribe, auth, tts, and remove-background. Also use when diagnosing build
8
+ or render failures. validate, inspect, and layout are deprecated aliases; use check. Covers local,
9
+ HeyGen-hosted cloud, AWS Lambda, and Google Cloud Run rendering.
4
10
  ---
5
11
 
6
12
  # HyperFrames CLI
7
13
 
8
- Everything runs through `npx hyperframes` unless project instructions specify a local wrapper. Obey the local wrapper exactly. Requires Node.js >= 22 and FFmpeg.
9
-
10
- ## Workflow
11
-
12
- 1. **Scaffold** `npx hyperframes init my-video` (or `capture` from a URL). `init` also checks the installed skills against the latest on GitHub and updates the global set if any are out of date. The `--skip-skills` flag is currently neutered (temporary, while the skills.sh registry catches up), so every `init` runs this check and pulls our latest skills regardless.
13
- 2. **Write** author HTML composition (see the `hyperframes-core` skill)
14
- 3. **Lint** `npx hyperframes lint` (static, fast run it early while iterating)
15
- 4. **Check** `npx hyperframes check` (the browser gate; add `--snapshots` for annotated frames + per-finding crops)
16
- 5. **Preview / edit** `npx hyperframes preview` opens **Studio**, the timeline editor where the user can manually edit anything (not just watch). Review there, then ask before rendering.
17
- 6. **Render** pick the variant:
18
- - Iterate: `npx hyperframes render --quality draft`
19
- - Deliver: `npx hyperframes render --quality high --output out.mp4`
20
- - CI / cross-host repro: `npx hyperframes render --docker --strict --output out.mp4`
21
- - Cloud, zero-infra: `npx hyperframes cloud render` (HeyGen hosts the render; no local Chrome/FFmpeg/AWS, see Cloud below)
22
- - Cloud, bring-your-own-AWS: `npx hyperframes lambda render ./my-project --width 1920 --height 1080 --wait` (see Lambda below)
23
- 7. **Report feedback** — after verifying the output, `npx hyperframes feedback --rating <1-5> --comment "..."` once per task (see Agent Conventions).
24
-
25
- Run `check` before preview. It runs the linter first (and skips the browser entirely on lint errors), then does everything the old validate → inspect → snapshot sequence did in **one** browser session and one seek pass: runtime console errors and failed requests, layout defects (text spilling out of bubbles/containers or off canvas, held overlaps, occlusion), motion-sidecar verification (`*.motion.json` — entrances under seek, stagger order, in-frame, liveness), and WCAG contrast. Contrast failures are errors and carry the sampled fg/bg colors, measured vs required ratio, and a suggested compliant color, so most contrast fixes need no screenshot. Every finding carries a selector, `data-*` identity, composition source file, bbox, and sample time — jump straight to the HTML. Single-sample transients demote to info; findings held across samples gate the exit code (`--strict` gates warnings too). `validate`, `inspect`, and `layout` still work but are deprecated aliases of parts of `check`.
26
-
27
- For motion-heavy work, prefer snapshot-driven iteration and a `*.motion.json` sidecar — see `references/lint-validate-inspect.md` for the discipline and motion-verification spec. To compare agent-authored candidate variants, use `npx hyperframes compare <path...> [--at <sec>] [--labels a,b,c] [--out compare.png] [--cols n] [--json]` to render each composition through its own runtime, assemble one labeled sheet, inspect it side by side, and choose. For color-grade selection, use the color-specific sibling `npx hyperframes grade-compare --for <frame> --grades grades.json` (or `--luts a.cube,b.cube`) to render every grading candidate through the real WebGL grading runtime into one labeled PNG before choosing the winner.
28
-
29
- ## Agent Conventions
30
-
31
- Cross-cutting rules that hold for every command:
32
-
33
- - **`--json` is available on every command except `render`, `preview`, and `play` server modes.** Use it for any agent / CI invocation of the supported commands; output includes a `_meta` envelope (cli version, latest available, update advice). `render` reports status via stdout + exit code only — verify success with the post-render check below. `preview --selection --json` and `preview --context --json` are the preview exceptions: they do not start a server, they query the user's running Studio session and exit.
34
- - **`doctor --json` always exits 0**, even when the environment is broken. Gate on the payload's `ok` field: `npx hyperframes doctor --json | jq -e '.ok' > /dev/null`. This insulates pipelines from CLI release churn.
35
- - **Non-TTY mode is auto-detected.** When `stdout` is not a TTY (CI, agents, piped output) the CLI auto-switches to non-interactive; `init` then **requires `--example`**. Pass `--non-interactive` to force this mode even on a TTY.
36
- - **CI gating on render**: `--strict` fails on lint errors, `--strict-all` fails on warnings too, `--strict-variables` fails on undeclared `--variables` keys.
37
- - **Correlate a verify loop with `HYPERFRAMES_RUN_ID`.** Orchestrators driving the CLI per task/design element should set this env var once per unit of work; every command invocation attaches it to telemetry, and `check` emits a per-gate breakdown, making roundtrips-per-task measurable.
38
- - **Paths in `--json` are redacted** — `$HOME` becomes the literal `$HOME` so output is safe to paste into bug reports and agent contexts.
39
- - **Render is user-gated.** Never auto-render once the checks pass. Pause at `preview`, tell the user the video is editable in Studio, and render only after they approve.
40
- - **Use Studio context for user-directed edits.** When the user says "this selected element", "the thing I clicked", "current selection", or similar, ask them to select it in Studio, then run `npx hyperframes preview --context --json --context-fields selection`. Use the returned `selection.target.hfId` / `selector`, `selection.sourceFile`, `selection.currentTime`, and `selection.thumbnailUrl` to anchor the edit. If `selection` is `null` and `errors.selection.code` is `no-selection`, ask the user to click the element and rerun; do not guess from screenshots.
41
- - **Keep Studio context compact.** `preview --context --json` returns compact selection by default. Add `--context-fields selection`, `--context-fields selection,lint`, or `--context-fields lint` to avoid bloating agent context. Use `--context-detail full` only when you need heavy fields like computed styles, inline styles, or text-field metadata.
42
- - **Post-render verification.** After `render` returns exit 0, confirm the output file exists and has plausible size before reporting success: `[ -s "$OUTPUT" ] || echo "render produced no output"`. The CLI prints `◇ <path>` on success; for long renders also sanity-check duration with `ffprobe -i "$OUTPUT" -show_format -v error`.
43
- - **Report feedback after a successful render.** Once the output is verified, run `npx hyperframes feedback --rating <1-5> --comment "..."` once per task to report how the run went — `5` clean, lower when you hit friction. Put any bug, workaround, missing feature, or confusing behaviour you encountered in `--comment`. This is the project's primary signal channel; renders that go silent leave the maintainers blind. Skip only when telemetry is disabled or the user opted out.
44
- - **For a reproducible bug, add `--file-issue`** — it publishes a minimal repro of the project to a public URL and opens a pre-filled GitHub issue with your comment + environment. A comment alone almost never lets a maintainer reproduce; the published composition is what makes the report actionable. Point `--dir <project>` at the failing composition if it isn't the current directory.
45
- - **Write bug comments a maintainer can reproduce from — a paraphrase they can't act on wastes the report.** The CLI already attaches os/arch/mem/ffmpeg/CLI-version, so don't repeat those; spend the comment on what only you saw. For a bug, include every one of these that applies:
46
- - **Exact error string, verbatim** (copy it, don't summarise) — and whether the render still produced an output file, silently fell back (look for a `[Render] … re-rendering via screenshot` / `falling back` log line), or the process hard-exited with no error (`Killed: 9`, `FATAL … heap`, `Target closed`). "Which timeout / which failure mode" is the single most useful fact.
47
- - **A minimal repro**: the smallest composition (or just the offending element + its CSS) that still shows it — inline it in the comment or note the file. Name the trigger you isolated (e.g. "only when the text node uses `font-family: 苹方`", "only at 4K", "only with a `<video>` present").
48
- - **The exact command + flags** you ran, and any env vars set (`HF_*` / `PRODUCER_*`).
49
- - **What's wrong and where**: the frame number or timestamp, and the visual defect (blank text, black band at the bottom, wrong glyphs, frozen canvas) vs. what you expected. A screenshot path if you saved one.
50
- - If it reproduces only sometimes, say so and give the hit rate.
51
-
52
- ## Routing
53
-
54
- | Want to… | Read |
55
- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
56
- | Scaffold a project (`init`, `capture`, `skills`) | `references/init-and-scaffold.md` |
57
- | Check correctness (`lint`, `check`, `snapshot`, deprecated `validate`/`inspect`) | `references/lint-validate-inspect.md` |
58
- | Preview or render (`preview`, `play`, `render`, `publish`) | `references/preview-render.md` |
59
- | Diagnose the environment (`doctor`, `browser`) | `references/doctor-browser.md` |
60
- | Cloud render, zero-infra HeyGen-hosted (`cloud render / list / get / delete`, `auth`) | `references/cloud.md` |
61
- | Cloud render on your own AWS Lambda (`lambda deploy / sites / render / progress / destroy / policies`) | `references/lambda.md` |
62
- | Parametrize / template renders (`--variables`, `--variables-file`, `--strict-variables`, `--batch`) | `references/cloud.md` + `hyperframes-core` (`variables-and-media.md`) |
63
- | Everything else (`info`, `upgrade`, `compositions`, `docs`, `benchmark`, `telemetry`, asset preprocessing) | `references/upgrade-info-misc.md` |
64
-
65
- ## Cross-Skill Hand-Offs
66
-
67
- - **Tailwind projects** (`init --tailwind`) → use `hyperframes-core` (Tailwind reference) before editing classes or theme tokens.
68
- - **Registry blocks/components** (`hyperframes add`, `hyperframes catalog`) → use `hyperframes-registry` for install paths, sub-composition wiring, and snippet merging.
69
- - **Asset preprocessing** (`tts`, `transcribe`, `remove-background`) → use `media-use` for voice selection, Whisper model rules, captions, and TTS-to-captions chain.
70
- - **Parametrized renders** (`--variables`) → declared via `data-composition-variables` on `<html>`; see `hyperframes-core` for the full schema.
71
-
72
- ## Cloud (HeyGen-hosted rendering)
73
-
74
- `hyperframes cloud render` is the **zero-infra** render path: the CLI zips your project, uploads it, renders on HeyGen's cloud, and downloads the mp4. No Chrome, no FFmpeg, no AWS, and you pay per credit. This is the default answer to "render this in the cloud"; reach for Lambda only when you already own AWS and need distributed/chunked rendering.
14
+ Run commands as `npx hyperframes ...` unless project instructions provide a wrapper. Obey the wrapper when present. The CLI requires Node.js 22 or newer and FFmpeg.
15
+
16
+ ## Development loop
17
+
18
+ 1. **Scaffold:** `npx hyperframes init <project>` or capture a site. In non-TTY mode, pass `--non-interactive --example=<name>`.
19
+ 2. **Author:** write the composition using `/hyperframes-core`.
20
+ 3. **Get fast feedback while editing:** run `npx hyperframes lint` after the first HTML pass and after structural changes.
21
+ 4. **Run the final gate:** run `npx hyperframes check`; it reruns lint before opening the browser. Do not prepend a redundant standalone lint invocation. Add `--snapshots` for annotated overview frames and finding crops.
22
+ 5. **Inspect sub-compositions:** when `index.html` mounts `data-composition-src`, capture midpoint snapshots and inspect each mounted scene.
23
+ 6. **Open the final Studio preview:** run `npx hyperframes preview`, hand the timeline project URL to the user, and ask whether to revise or render.
24
+ 7. **Render only after approval:** use draft quality for iteration and high quality for delivery.
25
+ 8. **Verify the output:** confirm the file exists, is non-empty, and has a plausible duration.
75
26
 
76
27
  ```bash
77
- npx hyperframes auth login # one-time sign-in (shared with the `heygen` CLI)
78
- npx hyperframes cloud render # zip, upload, render, download to renders/<id>.mp4
28
+ # Fast iteration check; repeat while authoring as needed.
29
+ npx hyperframes lint
30
+
31
+ # Required final gate; includes lint.
32
+ npx hyperframes check
33
+ npx hyperframes preview
34
+ npx hyperframes render --quality high --output out.mp4
35
+ test -s out.mp4
36
+ ffprobe -v error -show_format out.mp4
79
37
  ```
80
38
 
81
- Common flags: `--composition <html>`, `--output <path>`, `--quality draft|standard|high`, `--fps`, `--resolution 1080p|4k`, `--format mp4|webm|mov`, `--aspect-ratio` (auto-detected from `data-width`/`data-height`). Fire-and-forget with `--no-wait` + `--callback-url`; make retries safe with `--idempotency-key "$(uuidgen)"`. Manage jobs with `cloud list` / `cloud get <id>` / `cloud delete <id>`.
39
+ `check` runs lint first, then uses one browser session and one seek pass to audit runtime errors, failed requests, layout, `*.motion.json` assertions, and WCAG contrast. Persistent findings gate the exit code; transient entrance or exit findings are informational. Use `--strict` to gate warnings. `validate`, `inspect`, and `layout` remain aliases for compatibility but must not appear in new instructions or scripts.
40
+
41
+ ## Two different preview surfaces
82
42
 
83
- The idiomatic **template workflow is upload-once, re-render-many**: render a local project once to get its `asset_id`, then re-submit against that asset with different `--variables` (skips zip + upload). See `references/cloud.md` for the full flag set, the auth model, webhooks, and the template loop.
43
+ Do not confuse these states:
84
44
 
85
- ## Variables (parametrized / template renders)
45
+ | Surface | When it may open | Purpose |
46
+ | ------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------- |
47
+ | Storyboard board | Before composition checks, only when `storyboard: yes` | Review plan cards and wireframe sketches. Open `?view=storyboard#project/<name>`. |
48
+ | Final composition preview | After `check` passes | Review the assembled timeline before render. Open `#project/<name>`. |
86
49
 
87
- Any render (local, cloud, or Lambda) can fill declared template slots at render time. Declarations live on the composition (`data-composition-variables`); the CLI surface is:
50
+ The early board is not approval of the final video. Rendering always requires the final approval defined by `hyperframes-core/references/review-loop.md`.
51
+
52
+ ## Sub-composition smoke test
53
+
54
+ Static audits cannot catch every mount failure. When the project uses sub-compositions, capture at least one visible midpoint for each host slot:
88
55
 
89
56
  ```bash
90
- npx hyperframes render --variables '{"title":"Q4 Recap","theme":"dark"}' --output q4.mp4
91
- npx hyperframes render --variables-file ./vars.json --output out.mp4
92
- npx hyperframes render --batch rows.json --output "renders/{name}.mp4" --strict-variables
93
- npx hyperframes cloud render --asset-id asst_abc123 --variables '{"name":"Ada"}'
57
+ npx hyperframes snapshot --at <t1>,<t2>,<t3>
94
58
  ```
95
59
 
96
- `--strict-variables` fails the render on any undeclared key or type mismatch (use it in CI). `--batch <rows.json>` renders one output per data row with `{key}`/`{index}` path placeholders and writes a `manifest.json`. For the **full schema** (declaring types, `data-var-src`/`data-var-text` declarative bindings, per-instance `data-variable-values` for sub-compositions, and precedence) use the `hyperframes-core` skill (`references/variables-and-media.md`). The cloud template loop lives in `references/cloud.md`.
60
+ Treat tiny unstyled content, canvas-sized icons, missing hero elements, or timeline-registration timeouts as render-blocking mount defects. See `hyperframes-core/references/sub-compositions.md` for the corresponding fixes.
97
61
 
98
- ## Lambda (Cloud Rendering)
62
+ ## Agent conventions
99
63
 
100
- `hyperframes lambda` deploys distributed rendering to AWS Lambda and drives renders from your laptop or CI. End-to-end is three commands:
64
+ - Prefer `--json` for agent and CI calls. Server-mode `render`, `preview`, and `play` do not provide ordinary JSON output; `preview --selection --json` and `preview --context --json` are query-mode exceptions.
65
+ - `doctor --json` always exits zero. Gate on its payload:
101
66
 
102
- ```bash
103
- npx hyperframes lambda deploy # provision SAM stack (Lambda + Step Functions + S3)
104
- npx hyperframes lambda render ./my-project --width 1920 --height 1080 --wait
105
- npx hyperframes lambda destroy # tear down (S3 bucket is retained)
106
- ```
67
+ ```bash
68
+ npx hyperframes doctor --json | jq -e '.ok' >/dev/null
69
+ ```
107
70
 
108
- Use Lambda when a render is too long / too large for one host (multi-minute videos, 4K, large parallel batches) and you have AWS credentials configured. For dev-loop iteration stay on local `render`.
71
+ - Non-TTY mode is automatic. `init` requires `--example` there; use `--non-interactive` to force deterministic behavior on a TTY.
72
+ - Use one `HYPERFRAMES_RUN_ID` for all commands in the same verification loop.
73
+ - Use `--strict`, `--strict-all`, and `--strict-variables` when the corresponding warnings, variables, or CI conditions must gate the render.
74
+ - JSON paths redact the home directory as `$HOME`; do not try to reverse the redaction.
75
+ - Never render merely because checks pass. Pause at the final preview and wait for approval.
109
76
 
110
- See `references/lambda.md` for prerequisites, all 6 subcommands (`deploy`, `sites create`, `render`, `progress`, `destroy`, `policies`), IAM policy validation, state files, and cost / cleanup rules.
77
+ ## Studio-directed edits
111
78
 
112
- ## Minimum Completion Gate
79
+ When the user refers to “this element” or the current selection, query Studio instead of guessing:
113
80
 
114
81
  ```bash
115
- npx hyperframes check
82
+ npx hyperframes preview --context --json --context-fields selection
116
83
  ```
117
84
 
118
- One command covers the old lint + validate + inspect sequence in one browser session. Add `--strict` to gate warnings and `render --strict` in CI to fail on lint errors. `--caption-zone "<x0=..;y0=..;x1=..;y1=..>"` and `--frame-check` add opt-in band/bounds gates for pipelines that need them.
85
+ Use `selection.target.hfId` when available, otherwise its selector and source file. If the result reports `no-selection`, ask the user to click the element and rerun. Request only the context slices you need; use `--context-detail full` only for computed styles or editable text metadata. Full behavior and failure codes live in `references/preview-render.md`.
119
86
 
120
- ### Visual smoke test — required when the project uses sub-compositions
87
+ ## Render choices
121
88
 
122
- The audits evaluate the bundled composition; they cannot catch every cross-file mount failure when `index.html` mounts sub-compositions via `data-composition-src` (see `hyperframes-core` → `references/sub-compositions.md`, "Common pitfalls"). The gate that catches those is one that actually loads `index.html` the way `render` does and seeks the timeline.
89
+ | Need | Command |
90
+ | ---------------------------------------- | ----------------------------------------------------------------------------- |
91
+ | Fast local iteration | `npx hyperframes render --quality draft` |
92
+ | Final local delivery | `npx hyperframes render --quality high --output out.mp4` |
93
+ | Reproducible container render | `npx hyperframes render --docker --strict --output out.mp4` |
94
+ | Local variable-driven batch render | `npx hyperframes render --batch rows.json --output "renders/{name}.mp4"` |
95
+ | HeyGen-hosted zero-infrastructure render | `npx hyperframes cloud render` |
96
+ | Self-managed distributed AWS render | `npx hyperframes lambda render <project> --width 1920 --height 1080 --wait` |
97
+ | Self-managed distributed GCP render | `npx hyperframes cloudrun render <project> --width 1920 --height 1080 --wait` |
123
98
 
124
- Use `hyperframes snapshot` it loads the project the same way `render` does (so it exercises the same mount path) but only captures the timestamps you request, so it's seconds instead of a full render:
99
+ Use cloud rendering when the user wants hosted rendering without local Chrome, FFmpeg, or AWS. Use Lambda only when AWS ownership is a requirement. Use Cloud Run only when GCP ownership is a requirement. Read the matching reference before running any cloud path.
125
100
 
126
- ```bash
127
- # Capture one frame at the midpoint of every sub-composition.
128
- # Midpoints = data-start + data-duration/2 for each host slot in index.html.
129
- npx hyperframes snapshot --at <t1>,<t2>,<t3>,...
101
+ After verifying a successful render, send one feedback report unless telemetry is disabled or the user opted out:
130
102
 
131
- # Or, if you don't need per-scene targeting, an evenly-spaced sample:
132
- npx hyperframes snapshot --frames 9
103
+ ```bash
104
+ npx hyperframes feedback --rating <0-10> --comment "<specific result or friction>"
133
105
  ```
134
106
 
135
- Output lands in `snapshots/frame-NN-at-Xs.png`. Eyeball each frame against the scene plan.
107
+ Use `--file-issue` only with consent: it publishes a minimal reproduction to a public URL. The bug report format and privacy warning live in `references/preview-render.md`.
108
+
109
+ ## Read the matching reference before running a command
110
+
111
+ The following references and owning skills are mandatory command contracts, not optional background reading. Before running a command in the table, read its matching row.
136
112
 
137
- Per-frame red flags (each maps to a specific failure mode the static gates miss):
113
+ | Need | Reference |
114
+ | -------------------------------------------------------------------------------------- | ------------------------------------- |
115
+ | `init`, `capture`, `skills` | `references/init-and-scaffold.md` |
116
+ | `lint`, `check`, motion sidecars, `snapshot` | `references/lint-validate-inspect.md` |
117
+ | `compare`, `grade-compare`, variable-driven `render --batch` | `references/compare-and-batch.md` |
118
+ | `beats` for an existing project's Studio beat grid | `references/beats.md` |
119
+ | `preview`, `play`, `render`, `publish`, Studio context, feedback | `references/preview-render.md` |
120
+ | `doctor`, browser management | `references/doctor-browser.md` |
121
+ | `auth`, HeyGen-hosted cloud rendering, and template variables | `references/cloud.md` |
122
+ | AWS Lambda deployment and rendering | `references/lambda.md` |
123
+ | Google Cloud Run deployment and rendering | `references/cloudrun.md` |
124
+ | `info`, `upgrade`, `compositions`, `docs`, `benchmark`, telemetry, media preprocessing | `references/upgrade-info-misc.md` |
138
125
 
139
- | What you see | Root cause |
140
- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
141
- | Text shows up tiny + unstyled in the top-left corner | `<style>` block left in `<head>` outside `<template>` (Pitfall 1) — no CSS reached live DOM |
142
- | SVG/icon elements blown up to canvas-size | Same as above — no width/height constraints applied |
143
- | Hero element of the scene is missing entirely; only background + watermark visible | Host-id ≠ template id (Pitfall 2) — timeline never ran, frame captured at initial state |
144
- | Snapshot command logs `Sub-composition timelines not registered after 45000ms` | Pitfall 2 — direct confirmation |
126
+ For composition variables, also read `/hyperframes-core` → `references/variables-and-media.md`. For `hyperframes add` and `hyperframes catalog`, use `/hyperframes-registry`. Before `hyperframes present`, read `/slideshow`; before `hyperframes keyframes`, read `/hyperframes-keyframes`. For TTS, transcription, captions, or background removal choices, use `/media-use`.
127
+
128
+ The specialized commands are deliberately documented by their owning workflows:
129
+
130
+ ```bash
131
+ npx hyperframes present <project-dir> --port 3004 --no-open
132
+ npx hyperframes beats <project-dir> --json
133
+ npx hyperframes keyframes <project-dir> --json
134
+ ```
145
135
 
146
- `snapshots/` can be deleted after eyeballing; the user-facing final render is a separate pass with `npx hyperframes render`.
136
+ `present` serves a navigable deck with presenter and audience synchronization. `beats` is the standalone Studio beat-grid utility defined in `references/beats.md`. `keyframes` surfaces seek-safe animation and motion-path diagnostics.
@@ -0,0 +1,19 @@
1
+ # Generate a project beat grid
2
+
3
+ Use `hyperframes beats` when an existing HyperFrames project needs the Studio-compatible beat file for its music track. This is a CLI utility, not a complete video workflow.
4
+
5
+ ```bash
6
+ npx hyperframes beats
7
+ npx hyperframes beats ./my-video
8
+ npx hyperframes beats ./my-video --json
9
+ ```
10
+
11
+ The project must contain a local music `<audio>` source. Mark it with `data-timeline-role="music"`; an id containing `music`, `bgm`, or `soundtrack` is also recognized. The command analyzes that file in headless Chrome and writes `beats/<audio-relative-path>.json`.
12
+
13
+ If no beats are detected, the command fails and writes nothing. If Chrome is unavailable, run:
14
+
15
+ ```bash
16
+ npx hyperframes browser ensure
17
+ ```
18
+
19
+ For a complete beat-synced video, route through `/music-to-video`. That workflow owns a different audio-driven pipeline and its `audiomap.json`; do not replace its analyzer with this Studio utility.
@@ -7,11 +7,12 @@ npx hyperframes auth login # one-time sign-in
7
7
  npx hyperframes cloud render # zip, upload, render, download
8
8
  ```
9
9
 
10
- ## When to use cloud vs lambda vs local
10
+ ## When to use managed cloud, Lambda, Cloud Run, or local
11
11
 
12
12
  - **`hyperframes render`** (local): fastest iteration loop, use while authoring.
13
13
  - **`hyperframes cloud render`**: zero-infra. HeyGen runs the render and you pay per credit. This is the default answer to "render in the cloud" when you don't want to manage Chrome/FFmpeg/AWS.
14
14
  - **`hyperframes lambda render`**: bring-your-own-AWS distributed rendering with chunked parallelism. Only worth it when you've already invested in AWS (see `lambda.md`).
15
+ - **`hyperframes cloudrun render`**: bring-your-own-GCP distributed rendering through Cloud Run and Workflows. Use only when GCP ownership is explicit (see `cloudrun.md`).
15
16
 
16
17
  ## Authentication
17
18
 
@@ -21,6 +22,10 @@ Cloud rendering needs a HeyGen credential, stored at `~/.heygen/credentials` (`0
21
22
  npx hyperframes auth login # OAuth 2.0 + PKCE, opens the browser
22
23
  npx hyperframes auth login --api-key # CI/headless: hidden prompt, or pipe: echo "$HEYGEN_API_KEY" | ... --api-key
23
24
  npx hyperframes auth status # active credential source, identity, billing snapshot
25
+ # exit 0 = signed in and verified; exit 1 = not signed in,
26
+ # or the credential was rejected — signed-out exit 1 is the
27
+ # normal offline state (scripts: `auth status || echo offline`),
28
+ # not a command failure
24
29
  npx hyperframes auth refresh # force-refresh an OAuth token before a long job
25
30
  npx hyperframes auth logout # clear the stored credential
26
31
  ```
@@ -63,7 +68,7 @@ npx hyperframes cloud render --quality high --fps 60
63
68
 
64
69
  ## Templates and variables
65
70
 
66
- Cloud rendering supports [variables](../SKILL.md#variables-parametrized--template-renders): declare `data-composition-variables` on the composition, then fill them at render time.
71
+ Cloud rendering supports [composition variables](../../hyperframes-core/references/variables-and-media.md#variables): declare `data-composition-variables` on the composition, then fill them at render time.
67
72
 
68
73
  ```bash
69
74
  npx hyperframes cloud render --variables '{"title":"Q4 Recap","theme":"dark"}'
@@ -81,7 +86,7 @@ npx hyperframes cloud render --asset-id asst_abc123 --variables '{"name":"Ada"}'
81
86
  npx hyperframes cloud render --asset-id asst_abc123 --variables '{"name":"Linus"}'
82
87
  ```
83
88
 
84
- For high-volume personalized batches, the Lambda path adds a JSONL fan-out (see `lambda.md`). The full variables schema (types, declarative bindings, sub-composition overrides, precedence) lives in the `hyperframes-core` skill.
89
+ For high-volume personalized batches, both self-managed paths provide JSONL fan-out: AWS Lambda (`lambda.md`) and Google Cloud Run (`cloudrun.md`). The full variables schema (types, declarative bindings, sub-composition overrides, precedence) lives in the `hyperframes-core` skill.
85
90
 
86
91
  ## Fire-and-forget and webhooks
87
92
 
@@ -0,0 +1,62 @@
1
+ # Cloud Run rendering on Google Cloud
2
+
3
+ Use `hyperframes cloudrun` only when the user explicitly wants self-managed Google Cloud infrastructure. It deploys Cloud Run, Workflows, and Cloud Storage. For a managed default use `hyperframes cloud`; for AWS use `hyperframes lambda`.
4
+
5
+ ## Prerequisites
6
+
7
+ - `gcloud` is authenticated and the target project has billing enabled.
8
+ - Terraform 1.5 or newer is on `PATH`.
9
+ - Docker or permission to use Cloud Build is available.
10
+
11
+ ## Lifecycle
12
+
13
+ ```bash
14
+ npx hyperframes cloudrun deploy --project <gcp-project> --region us-central1
15
+ npx hyperframes cloudrun sites create ./project
16
+ npx hyperframes cloudrun render ./project --width 1920 --height 1080 --wait
17
+ npx hyperframes cloudrun progress <execution-name>
18
+ npx hyperframes cloudrun destroy --project <gcp-project>
19
+ ```
20
+
21
+ `deploy` enables the required Google APIs, builds or accepts a container image, applies the bundled Terraform module, and stores the resulting coordinates in `~/.hyperframes/cloudrun-state.json`. Use deploy flags such as `--image`, `--repo`, `--cpu`, `--memory`, `--max-instances`, and `--timeout` only when the infrastructure needs those overrides.
22
+
23
+ `sites create` uploads a content-addressed project archive for reuse by `render-batch`; pass its `--site-id` to that command to skip the batch upload. Single `cloudrun render` currently resolves the project from its directory and does not consume `--site-id`. Both render commands require `--width` and `--height`; supported output formats are `mp4`, `mov`, `png-sequence`, and `webm`. Use `--output-resolution 4k` to supersample an authored composition without changing its layout dimensions.
24
+
25
+ Common render flags are `--fps 24|30|60`, `--quality draft|standard|high`, `--codec h264|h265` for MP4, `--chunk-size`, `--max-parallel-chunks`, `--target-chunk-frames`, `--render-id`, `--output-key`, `--wait`, and `--wait-interval-ms`. Use `--json` for machine-readable output.
26
+
27
+ For a variable-driven single render:
28
+
29
+ ```bash
30
+ npx hyperframes cloudrun render ./template \
31
+ --width 1920 --height 1080 \
32
+ --variables-file ./alice.json \
33
+ --strict-variables \
34
+ --wait
35
+ ```
36
+
37
+ Use exactly one of `--variables` and `--variables-file`. Read [`variables-and-media.md`](../../hyperframes-core/references/variables-and-media.md#variables) for the composition-side contract.
38
+
39
+ ## JSONL batches
40
+
41
+ ```bash
42
+ npx hyperframes cloudrun render-batch ./template \
43
+ --batch ./users.jsonl \
44
+ --width 1920 --height 1080 \
45
+ --max-concurrent 10 \
46
+ --site-id <site-id> \
47
+ --json
48
+ ```
49
+
50
+ Each nonblank line must contain an `outputKey`; `variables` is optional:
51
+
52
+ ```json
53
+ { "outputKey": "renders/alice.mp4", "variables": { "name": "Alice" } }
54
+ ```
55
+
56
+ - `--max-concurrent` defaults to `50` and limits in-flight executions. `--max-parallel-chunks` separately limits chunks inside one render.
57
+ - `--dry-run` parses the file and prints `would-start` rows without starting executions.
58
+ - The template uploads once unless `--site-id` is supplied.
59
+ - Per-entry start errors remain visible and make the command exit nonzero.
60
+ - Do not rely on `--strict-variables` for `cloudrun render-batch`: the current command accepts the flag but does not validate batch rows. Validate the JSONL variable objects against the composition schema before dispatch. The strict gate does work for single `cloudrun render`.
61
+
62
+ `render` without `--wait` returns an execution name. Use `cloudrun progress <execution-name>` until it succeeds, then verify the reported GCS output. `destroy` removes the Terraform-managed stack and its scratch bucket; preserve any deliverables that must outlive the stack.
@@ -0,0 +1,105 @@
1
+ # Compare and batch rendering
2
+
3
+ Use these commands for deliberate visual comparison or variable-driven template output. They do not replace `lint`, `check`, final preview approval, or output verification.
4
+
5
+ ## Contents
6
+
7
+ - [Compare projects or variants](#compare-projects-or-variants)
8
+ - [Compare color grades](#compare-color-grades)
9
+ - [Batch template renders](#batch-template-renders)
10
+
11
+ ## Compare projects or variants
12
+
13
+ Render the same timestamp from two or more project directories or HTML files into one labeled contact sheet:
14
+
15
+ ```bash
16
+ npx hyperframes compare <path-a> <path-b> [<path-c> ...] \
17
+ --at <seconds> \
18
+ --labels baseline,candidate \
19
+ --out compare.png \
20
+ --cols 2
21
+ ```
22
+
23
+ Useful options:
24
+
25
+ - `--at <seconds>` selects the shared comparison time.
26
+ - `--labels <a,b,...>` labels cells in input order.
27
+ - `--out <file>` chooses the sheet path.
28
+ - `--cols <n>` controls its grid.
29
+ - `--json` returns machine-readable results.
30
+ - `--timeout <ms>` changes the per-variant render-ready timeout.
31
+
32
+ One sheet accepts at most 16 variants. Extra inputs are truncated with a warning; split larger comparisons into several runs.
33
+
34
+ `compare` is a visual review surface, not a quality gate. Run it when checking a baseline against a candidate, comparing implementation variants, or verifying that a repair preserves the intended look. Inspect the generated image; do not treat command success as visual approval.
35
+
36
+ ## Compare color grades
37
+
38
+ Create grade candidates from a source frame:
39
+
40
+ ```bash
41
+ npx hyperframes grade-compare \
42
+ --for frame.png \
43
+ --grades grades.json \
44
+ --project . \
45
+ --out grade-compare.png
46
+ ```
47
+
48
+ `grades.json` is an array of labeled HyperFrames grading blocks:
49
+
50
+ ```json
51
+ [{ "label": "warm", "grading": { "temperature": 0.2, "contrast": 0.1 } }]
52
+ ```
53
+
54
+ Or compare explicit LUT files:
55
+
56
+ ```bash
57
+ npx hyperframes grade-compare \
58
+ --for source.mp4 \
59
+ --luts warm.cube,cool.cube \
60
+ --out grade-compare.png
61
+ ```
62
+
63
+ - `--for` accepts an image or a video. For video input, the command extracts the first frame.
64
+ - Supply exactly one candidate source: `--grades <json>` or `--luts <a.cube,b.cube>`.
65
+ - A neutral baseline is included by default; pass `--no-baseline` only when the baseline is not a useful reference.
66
+ - The command accepts at most 16 candidate grades. With the default neutral baseline, the sheet may contain 17 cells. Extra candidates are truncated with a warning; split larger sets into several runs.
67
+ - `--timeout <ms>` changes the render-ready timeout for the generated comparison composition.
68
+ - Use `--json` for machine-readable output.
69
+
70
+ This command helps select a grade. It does not apply the selected grade to the composition or replace `/media-use` provenance and LUT validation.
71
+
72
+ ## Batch template renders
73
+
74
+ `render --batch` accepts either a JSON array of variable objects or an object with a `rows` array:
75
+
76
+ ```json
77
+ {
78
+ "rows": [
79
+ { "name": "alpha", "headline": "Hello" },
80
+ { "name": "beta", "headline": "Welcome" }
81
+ ]
82
+ }
83
+ ```
84
+
85
+ Declare the variables in the composition, then run:
86
+
87
+ ```bash
88
+ npx hyperframes render \
89
+ --batch rows.json \
90
+ --output "renders/{name}.mp4" \
91
+ --batch-concurrency 1 \
92
+ --strict-variables
93
+ ```
94
+
95
+ Batch rules:
96
+
97
+ - Do not combine `--batch` with `--variables` or `--variables-file`; each row is the variable set for one render.
98
+ - If `--output` is omitted, the generated filename includes `{index}` so rows remain unique.
99
+ - Output templates support `{index}` and row keys containing letters, numbers, `_`, `.`, or `-`. A placeholder value must be a string, number, or boolean; `null`, objects, and arrays are invalid. Missing placeholders and output collisions are errors.
100
+ - `--batch-concurrency` defaults to `1`. Raise it conservatively because each render already uses workers.
101
+ - `--batch-fail-fast` stops scheduling after the first failure. Without it, independent rows keep running and failures remain visible in the manifest.
102
+ - `--strict-variables` validates every row before rendering and aborts before output when the declared variable contract is violated.
103
+ - `--json` emits progress events suitable for agents and CI.
104
+
105
+ The command writes `manifest.json` in the common output directory and updates it throughout the run. It records each row's variables, status, output, error, and timing. Completion means the manifest has no failed rows and every completed output exists, is non-empty, and has a plausible duration.