Skip to content

feat(cli): add --output-resolution to lambda render#1020

Open
jrusso1020 wants to merge 1 commit into
mainfrom
feat/lambda-output-resolution
Open

feat(cli): add --output-resolution to lambda render#1020
jrusso1020 wants to merge 1 commit into
mainfrom
feat/lambda-output-resolution

Conversation

@jrusso1020
Copy link
Copy Markdown
Collaborator

@jrusso1020 jrusso1020 commented May 21, 2026

What

Add --output-resolution to hyperframes lambda render (and render-batch). Renders an authored-at-1080p composition at 4K/2K via Chrome deviceScaleFactor supersampling without changing the composition layout.

Why

Plain --width 3840 --height 2160 against a composition with data-width="1920" silently produces a 1080p output because the runtime lays out the page at the composition's authored dimensions — Config.width is effectively ignored. There was no supported way through the CLI to render at a higher resolution than the composition was authored at.

The new flag is the supported supersampling path: composition lays out at its authored canvas size and Chrome supersamples to the target preset. PR #1022 (next in stack) adds a warning when the user passes mismatched --width/--height and points them here.

How

  • Accepts canonical CanvasResolution names (landscape, landscape-4k, portrait, portrait-4k, square, square-4k) and the aliases the local hyperframes render already accepts (1080p, 4k, uhd, hd, 1080p-portrait, 4k-portrait, 1080p-square, 4k-square).
  • Delegates parsing to the existing normalizeResolutionFlag exported from @hyperframes/core — same alias table the local renderer uses, no duplication.
  • Threads the value into SerializableDistributedRenderConfig.outputResolution (already supported by the SDK + producer); no SDK or runtime changes.
  • Wired through both lambda render and lambda render-batch so batch personalisation flows can also target 4K.

Test plan

  • Typecheck + format + lint
  • Manual: bun run --cwd packages/cli dev lambda render … --output-resolution bogus rejects with the canonical-names list
  • Manual: --output-resolution 4k on a 1080p composition produces a 4K output (verified end-to-end on inspector-launch — 196 MB vs the 77 MB 1080p output)
  • Unit tests for parseOutputResolution — delegated to existing normalizeResolutionFlag coverage in core

Copy link
Copy Markdown
Collaborator

@miguel-heygen miguel-heygen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean, well-scoped addition. Threading outputResolution through the existing normalizeResolutionFlag from core avoids duplicating the alias table, and wiring it into both render and render-batch covers the two code paths. The types line up end-to-end: CanvasResolution -> RenderArgs / RenderBatchArgs -> SerializableDistributedRenderConfig -> DistributedRenderConfig (which the producer already handles).

Two minor nits, neither blocking:

  1. Unnecessary lint suppressionfallow-ignore-next-line complexity on parseOutputResolution is overkill for a 7-line function with two branches. The rest of the file uses it on genuinely complex functions (100+ line handlers). Not worth a re-push, just worth knowing.

  2. Error message alias list is incomplete — The throw mentions 1080p-portrait, 4k-portrait, 1080p-square, 4k-square but the core alias table also accepts portrait-1080p and square-1080p. Again, minor — users hitting this error get pointed at the canonical names anyway.

CI: the File size check failure is pre-existing (BlocksTab.tsx, NLELayout.tsx) and unrelated to this PR.

@jrusso1020 jrusso1020 force-pushed the feat/lambda-output-resolution branch from c1fd891 to f3b9b1f Compare May 22, 2026 18:02
@jrusso1020
Copy link
Copy Markdown
Collaborator Author

Thanks Miguel — both nits addressed in the latest push:

  1. Fallow suppression dropped. I simplified the guard from raw === undefined || raw === null || raw === "" to raw == null || raw === "" (one branch shorter), which brings the function under fallow's CRAP threshold organically. No suppression needed.

  2. Error-message alias list expanded. Added portrait-1080p and square-1080p (the two reverse-order aliases the core table accepts). The error now lists: 1080p, 4k, uhd, hd, 1080p-portrait, portrait-1080p, 4k-portrait, 1080p-square, square-1080p, 4k-square.

Re: the pre-existing File size check CI failure — confirmed unrelated.

Copy link
Copy Markdown
Collaborator

@vanceingalls vanceingalls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers. Clean CLI extension pattern — delegates parsing to normalizeResolutionFlag, threads through SerializableDistributedRenderConfig.outputResolution, wires both lambda render and render-batch correctly.

Nits

  • parseOutputResolution's error message lists portrait-1080p and square-1080p as valid aliases. Verify those are actually accepted by normalizeResolutionFlag. If the alias table doesn't include them, the error text is misleading.
  • Help text shows --width 1920 --height 1080 --output-resolution 4k together — confirm whether --width/--height are still required when --output-resolution is passed (the supersampling scenario the PR targets), or can be omitted.

The pre-existing File size check failure on BlocksTab.tsx/NLELayout.tsx is unrelated to this PR.

— Vai

Allows authored-at-1080p compositions to render at 4K/2K via Chrome
deviceScaleFactor supersampling without re-laying-out the composition.
Plain --width 3840 silently lays out at 1920×1080 because data-width/
data-height attrs override Config.width — this flag is the supported
way to ask the renderer to supersample.

Accepts canonical CanvasResolution names (landscape, landscape-4k,
portrait, portrait-4k, square, square-4k) and aliases (1080p, 4k, uhd,
hd, 1080p-portrait, 4k-portrait, 1080p-square, 4k-square). Wired
through render + render-batch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jrusso1020 jrusso1020 force-pushed the feat/lambda-output-resolution branch from f3b9b1f to 1bca6ec Compare May 22, 2026 18:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants