Skill Tracer
Skills › HyperFrames › hyperframes-cli › cloud.md

cloud.md

165 lines · skills/hyperframes-cli/references/cloud.md at a595755

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# cloud — HeyGen-hosted rendering (zero-infra)
2
3`hyperframes cloud render` renders a composition on HeyGen's managed cloud. The CLI zips the project, uploads it, runs the render on HeyGen's infrastructure (Chromium + FFmpeg), and downloads the finished video. Nothing to deploy, and no Chrome/FFmpeg/AWS to manage; the server applies the selected credential's render allowance or billing.
4
5```bash
6npx hyperframes auth login # one-time sign-in
7npx hyperframes cloud render # zip, upload, render, download
8```
9

cloud — HeyGen-hosted rendering (zero-infra)

hyperframes cloud render renders a composition on HeyGen's managed cloud. The CLI zips the project, uploads it, runs the render on HeyGen's infrastructure (Chromium + FFmpeg), and downloads the finished video. Nothing to deploy, and no Chrome/FFmpeg/AWS to manage; the server applies the selected credential's render allowance or billing.

npx hyperframes auth login            # one-time sign-in
npx hyperframes cloud render          # zip, upload, render, download
Raw lines 1 to 9
10## When to use managed cloud, Lambda, Cloud Run, or local
12- **`hyperframes render`** (local): fastest iteration loop, use while authoring. Previews, snapshots and draft checks stay local.
13- **`hyperframes cloud render`**: zero-infra. HeyGen runs the render under the selected credential's allowance or billing. This is the default answer to "render in the cloud" when you don't want to manage Chrome/FFmpeg/AWS.
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`).
17**Final renders on a paid plan.** When `npx hyperframes auth status` shows `Billing: HyperFrames` and a paid plan on its `HyperFrames:` line (not `Free`), the render the person receives, final or shareable, is `cloud render --fps <data-fps> --quality high -o <path>`: the root's `data-fps` (cloud defaults to 30) and `high` (local `delivery`'s equivalent; cloud defaults to `standard`). On Free, render locally unless the person asks for cloud. A fractional rate, or a frame that is not 16:9, 9:16 or 1:1, renders locally. If the cloud render is refused or fails (network, quota), render locally and tell the person why.

When to use managed cloud, Lambda, Cloud Run, or local

  • **hyperframes render** (local): fastest iteration loop, use while authoring. Previews, snapshots and draft checks stay local.
  • **hyperframes cloud render**: zero-infra. HeyGen runs the render under the selected credential's allowance or billing. This is the default answer to "render in the cloud" when you don't want to manage Chrome/FFmpeg/AWS.
  • **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).
  • **hyperframes cloudrun render**: bring-your-own-GCP distributed rendering through Cloud Run and Workflows. Use only when GCP ownership is explicit (see cloudrun.md).

Final renders on a paid plan. When npx hyperframes auth status shows Billing: HyperFrames and a paid plan on its HyperFrames: line (not Free), the render the person receives, final or shareable, is cloud render --fps <data-fps> --quality high -o <path>: the root's data-fps (cloud defaults to 30) and high (local delivery's equivalent; cloud defaults to standard). On Free, render locally unless the person asks for cloud. A fractional rate, or a frame that is not 16:9, 9:16 or 1:1, renders locally. If the cloud render is refused or fails (network, quota), render locally and tell the person why.

Raw lines 10 to 18
19## Authentication
21Cloud rendering uses the dedicated HyperFrames OAuth client and isolated `~/.hyperframes/credentials` store. A previous shared HeyGen login requires a fresh `hyperframes auth login`; the separate `heygen` CLI keeps its own login. An explicit API key uses API billing.
23```bash
24npx hyperframes auth login # OAuth 2.0 + PKCE, opens the browser
25npx hyperframes auth login --api-key # CI/headless: hidden prompt, or pipe: echo "$HEYGEN_API_KEY" | ... --api-key
26npx hyperframes auth status # active credential source, identity, billing snapshot
27 # exit 0 = signed in and verified; exit 1 = not signed in,
28 # or the credential was rejected — signed-out exit 1 is the
29 # normal offline state (scripts: `auth status || echo offline`),
30 # not a command failure
31npx hyperframes auth refresh # force-refresh an OAuth token before a long job
32npx hyperframes auth logout # clear the stored credential
33```
35Credential resolution order (first match wins): `HEYGEN_ACCESS_TOKEN` (an OAuth token a host app injects; never refreshed or saved), then the `hyperframes auth login` session in `~/.hyperframes/credentials` (refreshed when expired), then `HEYGEN_API_KEY`, then `HYPERFRAMES_API_KEY`, then a key saved with `auth login --api-key`. A signed-in session wins over an env key; the env key is used if HeyGen refuses to refresh the session or `HEYGEN_API_URL` points at a host app's gateway. `auth status` shows which one is in use; `auth logout` makes the env key win. `HYPERFRAMES_ENV=dev` selects the dev client, OAuth/API hosts and `~/.hyperframes/dev/credentials` together. `HYPERFRAMES_CONFIG_DIR` overrides the credentials root. `HEYGEN_API_URL` overrides the API host.

Authentication

Cloud rendering uses the dedicated HyperFrames OAuth client and isolated ~/.hyperframes/credentials store. A previous shared HeyGen login requires a fresh hyperframes auth login; the separate heygen CLI keeps its own login. An explicit API key uses API billing.

npx hyperframes auth login              # OAuth 2.0 + PKCE, opens the browser
npx hyperframes auth login --api-key    # CI/headless: hidden prompt, or pipe: echo "$HEYGEN_API_KEY" | ... --api-key
npx hyperframes auth status             # active credential source, identity, billing snapshot
                                        #   exit 0 = signed in and verified; exit 1 = not signed in,
                                        #   or the credential was rejected — signed-out exit 1 is the
                                        #   normal offline state (scripts: `auth status || echo offline`),
                                        #   not a command failure
npx hyperframes auth refresh            # force-refresh an OAuth token before a long job
npx hyperframes auth logout             # clear the stored credential

Credential resolution order (first match wins): HEYGEN_ACCESS_TOKEN (an OAuth token a host app injects; never refreshed or saved), then the hyperframes auth login session in ~/.hyperframes/credentials (refreshed when expired), then HEYGEN_API_KEY, then HYPERFRAMES_API_KEY, then a key saved with auth login --api-key. A signed-in session wins over an env key; the env key is used if HeyGen refuses to refresh the session or HEYGEN_API_URL points at a host app's gateway. auth status shows which one is in use; auth logout makes the env key win. HYPERFRAMES_ENV=dev selects the dev client, OAuth/API hosts and ~/.hyperframes/dev/credentials together. HYPERFRAMES_CONFIG_DIR overrides the credentials root. HEYGEN_API_URL overrides the API host.

Raw lines 19 to 36
37## The render pipeline
39`cloud render` runs end-to-end:
411. **Resolve the project**: a local directory (default `.`), or skip the upload with `--asset-id` / `--url`.
422. **Auto-detect aspect ratio** from the entry HTML's `data-width`/`data-height`.
433. **Zip** the project (same ignore set as `hyperframes publish`, including `.hyperframesignore`).
444. **Upload** the zip through the direct-to-S3 asset flow, yielding an `asset_id`.
455. **Submit** the render to `POST /v3/hyperframes/renders`, yielding a `render_id`.
466. **Poll** `GET /v3/hyperframes/renders/{id}` until it completes or fails (skip with `--no-wait`).
477. **Download** the signed video URL to disk.

The render pipeline

cloud render runs end-to-end:

  1. Resolve the project: a local directory (default .), or skip the upload with --asset-id / --url.
  2. Auto-detect aspect ratio from the entry HTML's data-width/data-height.
  3. Zip the project (same ignore set as hyperframes publish, including .hyperframesignore).
  4. Upload the zip through the direct-to-S3 asset flow, yielding an asset_id.
  5. Submit the render to POST /v3/hyperframes/renders, yielding a render_id.
  6. Poll GET /v3/hyperframes/renders/{id} until it completes or fails (skip with --no-wait).
  7. Download the signed video URL to disk.
Raw lines 37 to 48
49## Archive size and `.hyperframesignore`
51The direct-upload limit is 200 MB. HyperFrames automatically excludes root-level `renders/` and `snapshots/`, along with its existing development exclusions such as `.git`, `node_modules`, `dist`, `.next`, `coverage`, and dotfiles. Add project-specific gitignore-style rules to `<project>/.hyperframesignore` when other generated or intermediate assets are not required at render time. The same rules affect `hyperframes publish`.
53Inspect the exact archive without authenticating, uploading, spending credits, or starting a render:
55```bash
56npx hyperframes cloud render <project> --dry-run --json
57```
59The result reports compressed `size_bytes`, `file_count`, the 200 MB limit, and the ten largest included files.
61When a cloud upload reports a size-limit error, agents must use this workflow:
631. Run the dry-run command and inspect the largest included files and directories.
642. Classify obvious generated outputs first: old renders, extra snapshot/contact-sheet directories, caches, exported previews, and source media used only to produce final assets.
653. Before excluding anything else, search `src`, `href`, `url()`, `data-composition-src`, JavaScript strings, manifests, and variable-driven paths across every HTML, CSS, and JavaScript entry.
664. Preserve existing `.hyperframesignore` comments and rules. Add the narrowest verified-unneeded root-relative paths; prefer an exact directory or file over a broad wildcard.
675. Never ignore `index.html`, the selected composition, mounted sub-compositions, fonts, images, audio, video, scripts, or manifests merely because they are large. Never ignore all of `assets/`.
686. Rerun dry-run until the archive is below the limit, then run `npx hyperframes check`. Remember that `check` sees the source directory, so it cannot prove a dynamically computed asset path remains in the filtered archive; the reference audit is still required.
70Example:
72```gitignore
73# Additional generated verification passes
74/snapshots2/
75/snapshots3/
77# Master used only to produce the final background clips
78/assets/bg-pattern.mp4
79```
81Rules support comments, globs, and negation. A later rule can override a default, for example `!/snapshots/` when that directory intentionally contains render inputs.

Archive size and .hyperframesignore

The direct-upload limit is 200 MB. HyperFrames automatically excludes root-level renders/ and snapshots/, along with its existing development exclusions such as .git, node_modules, dist, .next, coverage, and dotfiles. Add project-specific gitignore-style rules to <project>/.hyperframesignore when other generated or intermediate assets are not required at render time. The same rules affect hyperframes publish.

Inspect the exact archive without authenticating, uploading, spending credits, or starting a render:

npx hyperframes cloud render <project> --dry-run --json

The result reports compressed size_bytes, file_count, the 200 MB limit, and the ten largest included files.

When a cloud upload reports a size-limit error, agents must use this workflow:

  1. Run the dry-run command and inspect the largest included files and directories.
  2. Classify obvious generated outputs first: old renders, extra snapshot/contact-sheet directories, caches, exported previews, and source media used only to produce final assets.
  3. Before excluding anything else, search src, href, url(), data-composition-src, JavaScript strings, manifests, and variable-driven paths across every HTML, CSS, and JavaScript entry.
  4. Preserve existing .hyperframesignore comments and rules. Add the narrowest verified-unneeded root-relative paths; prefer an exact directory or file over a broad wildcard.
  5. Never ignore index.html, the selected composition, mounted sub-compositions, fonts, images, audio, video, scripts, or manifests merely because they are large. Never ignore all of assets/.
  6. Rerun dry-run until the archive is below the limit, then run npx hyperframes check. Remember that check sees the source directory, so it cannot prove a dynamically computed asset path remains in the filtered archive; the reference audit is still required.

Example:

# Additional generated verification passes
/snapshots2/
/snapshots3/

# Master used only to produce the final background clips
/assets/bg-pattern.mp4

Rules support comments, globs, and negation. A later rule can override a default, for example !/snapshots/ when that directory intentionally contains render inputs.

Raw lines 49 to 82
83## Render options
85| Flag | Default | Meaning |
86| ---------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
87| `--fps` | `30` | Frames per second, 1–240. |
88| `--quality` | `standard` | `draft`, `standard`, or `high`. |
89| `--format` | `mp4` | `mp4`, `webm`, or `mov` (webm/mov carry alpha). |
90| `--resolution` | `1080p` | `1080p` or `4k` (4k billed at 1.5×). |
91| `--aspect-ratio` | auto | Any `W:H`, auto from a local project's `data-width`/`data-height`. At `1080p` the output keeps the composition's size at any ratio (2:1 stays 2:1); `4k` takes only `16:9`, `9:16`, `1:1`. |
92| `--composition` / `-c` | `index.html` | Entry HTML file inside the zip. |
93| `--output` / `-o` | `renders/<render_id>.<ext>` | Local download destination. |
94| `--dry-run` | off | Build and inspect a local project zip without authenticating, uploading, or rendering. |
96```bash
97npx hyperframes cloud render . \
98 --composition compositions/intro.html \
99 --output ./renders/intro.mp4
101npx hyperframes cloud render --quality high --fps 60
102```
104`--resolution 4k` cannot combine with `--format webm`/`mov`: the 4k supersampling path has no alpha channel. Render 4k as mp4, or render alpha at native resolution.

Render options

FlagDefaultMeaning
--fps30Frames per second, 1–240.
--qualitystandarddraft, standard, or high.
--formatmp4mp4, webm, or mov (webm/mov carry alpha).
--resolution1080p1080p or 4k (4k billed at 1.5×).
--aspect-ratioautoAny W:H, auto from a local project's data-width/data-height. At 1080p the output keeps the composition's size at any ratio (2:1 stays 2:1); 4k takes only 16:9, 9:16, 1:1.
--composition / -cindex.htmlEntry HTML file inside the zip.
--output / -orenders/<render_id>.<ext>Local download destination.
--dry-runoffBuild and inspect a local project zip without authenticating, uploading, or rendering.
npx hyperframes cloud render . \
  --composition compositions/intro.html \
  --output ./renders/intro.mp4

npx hyperframes cloud render --quality high --fps 60

--resolution 4k cannot combine with --format webm/mov: the 4k supersampling path has no alpha channel. Render 4k as mp4, or render alpha at native resolution.

Raw lines 83 to 105
106## Templates and variables
108Cloud rendering supports [composition variables](../../hyperframes/references/format.md#variables): declare `data-composition-variables` on the composition, then fill them at render time.
110```bash
111npx hyperframes cloud render --variables '{"title":"Q4 Recap","theme":"dark"}'
112npx hyperframes cloud render --variables-file ./vars.json
113npx hyperframes cloud render --variables '{"title":"Q4 Recap"}' --strict-variables
114```
116For a **local project** the CLI validates `--variables` against the declared schema _before_ uploading. For `--asset-id`/`--url` the schema lives server-side, so mismatches surface as a `hyperframes_project_invalid` API error.
118**Upload once, re-render many** is the idiomatic template loop: render a local project to get its `asset_id`, then re-submit against that asset with new values (no re-zip, no re-upload).
120```bash
121npx hyperframes cloud render ./card-template # note the asset_id printed on upload
122npx hyperframes cloud render --asset-id asst_abc123 --variables '{"name":"Ada"}'
123npx hyperframes cloud render --asset-id asst_abc123 --variables '{"name":"Linus"}'
124```
126For 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 [`/hyperframes` format.md](../../hyperframes/references/format.md#variables).

Templates and variables

Cloud rendering supports composition variables: declare data-composition-variables on the composition, then fill them at render time.

npx hyperframes cloud render --variables '{"title":"Q4 Recap","theme":"dark"}'
npx hyperframes cloud render --variables-file ./vars.json
npx hyperframes cloud render --variables '{"title":"Q4 Recap"}' --strict-variables

For a local project the CLI validates --variables against the declared schema before uploading. For --asset-id/--url the schema lives server-side, so mismatches surface as a hyperframes_project_invalid API error.

Upload once, re-render many is the idiomatic template loop: render a local project to get its asset_id, then re-submit against that asset with new values (no re-zip, no re-upload).

npx hyperframes cloud render ./card-template                              # note the asset_id printed on upload
npx hyperframes cloud render --asset-id asst_abc123 --variables '{"name":"Ada"}'
npx hyperframes cloud render --asset-id asst_abc123 --variables '{"name":"Linus"}'

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 [/hyperframes format.md](../../hyperframes/references/format.md#variables).

Raw lines 106 to 127
Names a skill hyperframes :126
128## Fire-and-forget and webhooks
130By default the CLI blocks, polls, and downloads. Combine `--no-wait` (submit and exit with just the `render_id`) with `--callback-url` (HTTPS webhook on terminal status) for true fire-and-forget:
132```bash
133npx hyperframes cloud render --callback-url https://example.com/hf-hook --no-wait
134# Poll later with: hyperframes cloud get hfr_def456
135```
137| Flag | Meaning |
138| ----------------- | --------------------------------------------------- |
139| `--no-wait` | Submit and exit immediately; print the `render_id`. |
140| `--callback-url` | HTTPS webhook fired when the render terminates. |
141| `--callback-id` | Opaque tracking ID echoed in webhook payloads. |
142| `--poll-interval` | Poll cadence in seconds (default `2`). |
143| `--max-wait` | Max poll duration in minutes (default `60`). |

Fire-and-forget and webhooks

By default the CLI blocks, polls, and downloads. Combine --no-wait (submit and exit with just the render_id) with --callback-url (HTTPS webhook on terminal status) for true fire-and-forget:

npx hyperframes cloud render --callback-url https://example.com/hf-hook --no-wait
#    Poll later with: hyperframes cloud get hfr_def456
FlagMeaning
--no-waitSubmit and exit immediately; print the render_id.
--callback-urlHTTPS webhook fired when the render terminates.
--callback-idOpaque tracking ID echoed in webhook payloads.
--poll-intervalPoll cadence in seconds (default 2).
--max-waitMax poll duration in minutes (default 60).
Raw lines 128 to 144
145## Managing renders
147```bash
148npx hyperframes cloud list # recent renders (--limit, --token, --all)
149npx hyperframes cloud get hfr_def456 # full detail + short-lived signed video_url
150npx hyperframes cloud delete hfr_def456 # soft-delete (--no-confirm to skip the prompt)
151```
153`video_url` and `thumbnail_url` are short-lived presigned URLs, so re-fetch with `cloud get` rather than caching them.

Managing renders

npx hyperframes cloud list                 # recent renders (--limit, --token, --all)
npx hyperframes cloud get hfr_def456       # full detail + short-lived signed video_url
npx hyperframes cloud delete hfr_def456    # soft-delete (--no-confirm to skip the prompt)

video_url and thumbnail_url are short-lived presigned URLs, so re-fetch with cloud get rather than caching them.

Raw lines 145 to 154
155## Safe retries
157The CLI transparently retries a `401` by force-refreshing the OAuth token and replaying. That's harmless for reads, but the zip upload (`POST /v3/assets`) is **not** idempotent: a blind retry creates a duplicate asset and bills twice. Pass `--idempotency-key` so retries are safe:
159```bash
160npx hyperframes cloud render . --idempotency-key "$(uuidgen)"
161```
163The key is forwarded to both upload and submit (the server scopes idempotency per-endpoint, so reusing one value is safe). Use any opaque string in `[A-Za-z0-9_:.-]`, 1–255 chars.
165Full flag reference: docs `/deploy/cloud` and `/packages/cli#hyperframes-cloud`.

Safe retries

The CLI transparently retries a 401 by force-refreshing the OAuth token and replaying. That's harmless for reads, but the zip upload (POST /v3/assets) is not idempotent: a blind retry creates a duplicate asset and bills twice. Pass --idempotency-key so retries are safe:

npx hyperframes cloud render . --idempotency-key "$(uuidgen)"

The key is forwarded to both upload and submit (the server scopes idempotency per-endpoint, so reusing one value is safe). Use any opaque string in [A-Za-z0-9_:.-], 1–255 chars.

Full flag reference: docs /deploy/cloud and /packages/cli#hyperframes-cloud.

Raw lines 155 to 165