Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 31 additions & 20 deletions packages/cli/src/cloud/_gen/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,15 @@ export interface CreateHyperframesRenderRequest {
*/
format?: "mp4" | "webm" | "mov";
/**
* Optional resolution preset. If omitted, the composition's own declared
* dimensions are used.
*/
resolution?:
| "landscape"
| "portrait"
| "landscape-4k"
| "portrait-4k"
| "square"
| "square-4k"
| null;
* Output resolution tier. Defaults to '1080p'. Pass '4k' for 4K renders
* (billed at 1.5x).
*/
resolution?: HyperframesResolution;
/**
* Output aspect ratio. Defaults to '16:9' (landscape). Pass '9:16' for
* portrait or '1:1' for square.
*/
aspect_ratio?: HyperframesAspectRatio;
/**
* Entry HTML file relative to the project root (e.g. compositions/intro.html).
* Defaults to index.html when omitted.
Expand Down Expand Up @@ -135,6 +133,15 @@ export interface DeleteHyperframesRenderResponse {
render_id: string;
}

/**
* Output aspect ratio. Only the three ratios already supported end-to-end by
* the render pipeline are exposed today: ``16:9`` (landscape), ``9:16``
* (portrait), ``1:1`` (square). ``auto`` and other social-media ratios (4:5,
* 5:4) are reserved for a follow-up PR that wires composition-dim inference at
* the controller boundary.
*/
export type HyperframesAspectRatio = "16:9" | "9:16" | "1:1";

/**
* Detailed HyperFrames render resource.
*/
Expand Down Expand Up @@ -181,16 +188,13 @@ export interface HyperframesRenderDetail {
*/
format: "mp4" | "webm" | "mov";
/**
* Resolution preset, if one was set.
* Resolution tier, if one was set.
*/
resolution?:
| "landscape"
| "portrait"
| "landscape-4k"
| "portrait-4k"
| "square"
| "square-4k"
| null;
resolution?: HyperframesResolution | null;
/**
* Aspect ratio, if one was set.
*/
aspect_ratio?: HyperframesAspectRatio | null;
/**
* Composition entry file path.
*/
Expand All @@ -215,6 +219,13 @@ export interface HyperframesRenderDetail {
*/
export type HyperframesRenderStatus = "queued" | "rendering" | "completed" | "failed";

/**
* Output resolution tier. Pricing diverges only at 4K (1.5x multiplier). The
* render-pipeline value set is intentionally narrow at launch; 720p and other
* tiers will follow once the producer/CLI surface catches up.
*/
export type HyperframesResolution = "1080p" | "4k";

export interface StandardAPIError {
/**
* Machine-readable error code
Expand Down
23 changes: 13 additions & 10 deletions packages/cli/src/commands/cloud/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,8 @@ import { isAbsolute, resolve as resolvePath } from "node:path";

const VALID_QUALITY = ["draft", "standard", "high"] as const;
const VALID_FORMAT = ["mp4", "webm", "mov"] as const;
const VALID_RESOLUTION = [
"landscape",
"portrait",
"landscape-4k",
"portrait-4k",
"square",
"square-4k",
] as const;
const VALID_RESOLUTION = ["1080p", "4k"] as const;
const VALID_ASPECT_RATIO = ["16:9", "9:16", "1:1"] as const;

const FORMAT_EXT: Record<string, string> = { mp4: ".mp4", webm: ".webm", mov: ".mov" };

Expand Down Expand Up @@ -96,8 +90,11 @@ export default defineCommand({
format: { type: "string", description: "mp4 | webm | mov (default: mp4)" },
resolution: {
type: "string",
description:
"Resolution preset: landscape | portrait | landscape-4k | portrait-4k | square | square-4k",
description: "Resolution tier: 1080p | 4k (default: 1080p; 4k is billed at 1.5x)",
},
"aspect-ratio": {
type: "string",
description: "Aspect ratio: 16:9 | 9:16 | 1:1 (default: 16:9)",
},
composition: {
type: "string",
Expand Down Expand Up @@ -185,6 +182,9 @@ export default defineCommand({
const resolution = parseEnumFlag(args.resolution, VALID_RESOLUTION, {
flag: "--resolution",
});
const aspectRatio = parseEnumFlag(args["aspect-ratio"], VALID_ASPECT_RATIO, {
flag: "--aspect-ratio",
});
const pollIntervalMs = parsePollIntervalMs(args["poll-interval"]);
const maxWaitMs = parseMaxWaitMs(args["max-wait"]);
validateIdempotencyKey(args["idempotency-key"]);
Expand Down Expand Up @@ -214,6 +214,7 @@ export default defineCommand({
quality,
format,
resolution,
aspectRatio,
composition: args.composition,
variables,
title: args.title,
Expand Down Expand Up @@ -443,6 +444,7 @@ interface SubmitOptions {
quality: "draft" | "standard" | "high" | undefined;
format: "mp4" | "webm" | "mov" | undefined;
resolution: CreateHyperframesRenderRequest["resolution"] | undefined;
aspectRatio: CreateHyperframesRenderRequest["aspect_ratio"] | undefined;
composition: string | undefined;
variables: Record<string, unknown> | undefined;
title: string | undefined;
Expand Down Expand Up @@ -470,6 +472,7 @@ function buildRenderBody(opts: SubmitOptions): CreateHyperframesRenderRequest {
if (opts.quality !== undefined) body.quality = opts.quality;
if (opts.format !== undefined) body.format = opts.format;
if (opts.resolution !== undefined) body.resolution = opts.resolution;
if (opts.aspectRatio !== undefined) body.aspect_ratio = opts.aspectRatio;
if (opts.composition !== undefined) body.composition = opts.composition;
if (opts.variables !== undefined) body.variables = opts.variables;
if (opts.title !== undefined) body.title = opts.title;
Expand Down
Loading