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
27 changes: 25 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -467,17 +467,40 @@ jobs:
timeout-minutes: 1
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
- name: Check file sizes (max 500 lines)
# Scoped to files THIS PR changed under packages/studio. Walking the
# whole tree blamed every unrelated PR for pre-existing offenders.
# Falls back to a full scan on push events (no base ref available)
# so the rule still guards main.
run: |
set -e
if [ -n "${{ github.base_ref }}" ]; then
mapfile -t files < <(
git diff --name-only --diff-filter=ACMR \
"origin/${{ github.base_ref }}...HEAD" -- \
'packages/studio/**/*.ts' 'packages/studio/**/*.tsx' \
| grep -vE '\.(test|spec)\.(ts|tsx)$|\.generated\.' || true
)
else
mapfile -t files < <(
find packages/studio -path '*/node_modules' -prune -o \
\( -name '*.ts' -o -name '*.tsx' \) -print \
| grep -vE '\.(test|spec)\.(ts|tsx)$|\.generated\.'
)
fi
EXIT=0
while IFS= read -r f; do
for f in "${files[@]}"; do
[ -z "$f" ] && continue
[ -f "$f" ] || continue # skip files deleted in this PR
if grep -qxF "$f" .filesize-allowlist 2>/dev/null; then continue; fi
lines=$(wc -l < "$f")
if [ "$lines" -gt 500 ]; then
echo "::error file=$f::$f has $lines lines (max 500)"
EXIT=1
fi
done < <(find packages/studio -path '*/node_modules' -prune -o \( -name '*.ts' -o -name '*.tsx' \) -print | grep -vE '\.(test|spec)\.(ts|tsx)$|\.generated\.')
done
exit $EXIT

semantic-pr-title:
Expand Down
26 changes: 26 additions & 0 deletions packages/cli/src/commands/lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@

import { defineCommand } from "citty";
import type { DistributedFormat } from "@hyperframes/aws-lambda/sdk";
import {
type CanvasResolution,
VALID_CANVAS_RESOLUTIONS,
normalizeResolutionFlag,
} from "@hyperframes/core";
import type { Example } from "./_examples.js";
import { c } from "../ui/colors.js";

Expand All @@ -23,6 +28,10 @@ export const examples: Example[] = [
"Render and stream progress until done",
"hyperframes lambda render ./my-project --width 1920 --height 1080 --wait",
],
[
"Supersample a 1080p composition to 4K via Chrome deviceScaleFactor",
"hyperframes lambda render ./my-project --width 1920 --height 1080 --output-resolution 4k --wait",
],
[
"Render with composition variables (personalised template)",
'hyperframes lambda render ./my-template --site-id abc1234deadbeef0 --width 1920 --height 1080 --variables \'{"title":"Hello Alice","accent":"#ff0000"}\'',
Expand Down Expand Up @@ -113,6 +122,11 @@ export default defineCommand({
"site-id": { type: "string", description: "Explicit site id (overrides content hash)" },
width: { type: "string", description: "Render width in pixels" },
height: { type: "string", description: "Render height in pixels" },
"output-resolution": {
type: "string",
description:
"Output resolution preset that engages Chrome deviceScaleFactor supersampling. Accepts canonical names (landscape, landscape-4k, portrait, portrait-4k, square, square-4k) and aliases (1080p, 4k, uhd, hd). When set, the composition's authored data-width/data-height is supersampled to the target preset without changing the layout.",
},
fps: { type: "string", description: "Render fps (24 | 30 | 60)" },
format: { type: "string", description: "mp4 | mov | png-sequence | webm (default: mp4)" },
codec: { type: "string", description: "h264 | h265 (mp4 only)" },
Expand Down Expand Up @@ -291,6 +305,7 @@ export default defineCommand({
fps: fpsRaw,
width,
height,
outputResolution: parseOutputResolution(args["output-resolution"]),
format: parseFormat(args.format),
codec: parseCodec(args.codec),
quality: parseQuality(args.quality),
Expand Down Expand Up @@ -342,6 +357,7 @@ export default defineCommand({
fps: fpsRaw,
width,
height,
outputResolution: parseOutputResolution(args["output-resolution"]),
format: parseFormat(args.format),
codec: parseCodec(args.codec),
quality: parseQuality(args.quality),
Expand Down Expand Up @@ -450,3 +466,13 @@ const parseQuality = (raw: unknown): (typeof QUALITIES)[number] | undefined =>
parseEnum(raw, QUALITIES, "[lambda render] --quality", undefined);
const parseChromeSource = (raw: unknown): (typeof CHROME_SOURCES)[number] =>
parseEnum(raw, CHROME_SOURCES, "[lambda deploy] --chrome-source", "sparticuz")!;

function parseOutputResolution(raw: unknown): CanvasResolution | undefined {
if (raw == null || raw === "") return undefined;
const normalized = normalizeResolutionFlag(String(raw));
if (normalized) return normalized;
throw new Error(
`[lambda render] --output-resolution must be one of ${VALID_CANVAS_RESOLUTIONS.join("|")} ` +
`(or an alias: 1080p, 4k, uhd, hd, 1080p-portrait, portrait-1080p, 4k-portrait, 1080p-square, square-1080p, 4k-square); got ${String(raw)}`,
);
}
4 changes: 4 additions & 0 deletions packages/cli/src/commands/lambda/render-batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import type {
SerializableDistributedRenderConfig,
SiteHandle,
} from "@hyperframes/aws-lambda/sdk";
import type { CanvasResolution } from "@hyperframes/core";
import { c } from "../../ui/colors.js";
import { errorBox } from "../../ui/format.js";
import {
Expand Down Expand Up @@ -60,6 +61,8 @@ export interface RenderBatchArgs {
fps: 24 | 30 | 60;
width: number;
height: number;
/** See {@link RenderArgs.outputResolution}. */
outputResolution?: CanvasResolution;
format: DistributedFormat;
codec?: "h264" | "h265";
quality?: "draft" | "standard" | "high";
Expand Down Expand Up @@ -199,6 +202,7 @@ export async function runRenderBatch(args: RenderBatchArgs): Promise<void> {
fps: args.fps,
width: args.width,
height: args.height,
outputResolution: args.outputResolution,
format: args.format,
codec: args.codec,
quality: args.quality,
Expand Down
10 changes: 10 additions & 0 deletions packages/cli/src/commands/lambda/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
DistributedFormat,
SerializableDistributedRenderConfig,
} from "@hyperframes/aws-lambda/sdk";
import type { CanvasResolution } from "@hyperframes/core";
import { c } from "../../ui/colors.js";
import {
reportVariableIssues,
Expand All @@ -32,6 +33,14 @@ export interface RenderArgs {
fps: 24 | 30 | 60;
width: number;
height: number;
/**
* Optional output resolution preset that engages Chrome `deviceScaleFactor`
* supersampling. When set, the composition is laid out at the canvas size
* declared by `data-width`/`data-height` (or `--width`/`--height`) and
* supersampled to the preset's dimensions — `landscape-4k` (3840×2160)
* from a 1920×1080 layout uses DPR 2, etc.
*/
outputResolution?: CanvasResolution;
format: DistributedFormat;
codec?: "h264" | "h265";
quality?: "draft" | "standard" | "high";
Expand Down Expand Up @@ -99,6 +108,7 @@ export async function runRender(args: RenderArgs): Promise<void> {
fps: args.fps,
width: args.width,
height: args.height,
outputResolution: args.outputResolution,
format: args.format,
codec: args.codec,
quality: args.quality,
Expand Down
Loading