Commit Graph
757 Commits
Author SHA1 Message Date
Miguel ÁngelandClaude Opus 4.6 082e19df22 fix(skills): tighten trigger surface and add dimension/duration comments
- Narrow description to disambiguate from hyperframes-registry (install)
  and hyperframes (in-project authoring) skills
- Add "adjust" comments on dimensions/duration defaults so agents don't
  blindly copy 1920x1080/10s for all composition shapes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 23:45:35 +00:00
Miguel ÁngelandClaude Opus 4.6 6b3beffb24 fix(skills): address review feedback on contribute skill
- Remove `stability` field from templates.md registry-item.json template
- Fix S3 path to match canonical `docs/images/catalog/{kind}/{name}.png`
- Split internal vs external contributor upload flow
- Parameterize `{kind}` in Step 6 (format, stage, commit paths)
- Fix component target path to flat `compositions/components/{name}.html`
- Add component template to templates.md
- Add `npx hyperframes publish` step for contributor preview

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 23:43:01 +00:00
Miguel Ángel 15d8b6a998 feat(skills): add contribute skill for registry block authoring
New skill that guides users through the full workflow of contributing
caption styles, VFX blocks, transitions, and other components to the
HyperFrames registry.

Covers: scaffolding, proven patterns (seeded PRNG, paused timelines,
hard kills, unique ID prefixes), validation, rendering, and PR prep.

Includes copy-paste HTML templates for caption and Three.js components
with all the non-negotiable rules baked in.

Tested by an unbiased agent with zero prior HyperFrames knowledge —
built a working cap-typewriter component that passed lint and validate
on the first attempt. Feedback incorporated: per-character animation
guidance, monospace font size exceptions, positioning variants, and
PREFIX naming convention table.
2026-05-08 15:59:15 -07:00
Miguel Ángel 21794e698e feat(claude-code-plugin): add Claude Code marketplace manifest (#676)
Added a Claude Code marketplace manifest as announced here https://github.com/heygen-com/hyperframes/pull/528#issuecomment-4406797097
2026-05-09 00:16:55 +02:00
James Russo b58e447305 Merge pull request #681 from heygen-com/readme-demo-video
docs: replace README demo GIF with higher-quality MP4
2026-05-08 13:58:38 -07:00
JamesandClaude Opus 4.7 50c8a66114 docs: switch README hero to animated WebP for autoplay + higher quality
GitHub strips autoplay/loop from <video> tags in markdown, so the MP4
required a click to play. WebP autoplays via <img> while preserving full
HD source quality (1280x720 vs the previous GIF's 400x225).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 12:17:37 -07:00
JamesandClaude Opus 4.7 67901349eb docs: replace README demo GIF with higher-quality MP4
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 12:01:49 -07:00
Jo Weiser 3c33860bf9 feat(claude-code-plugin): add Claude Code marketplace manifest 2026-05-08 17:36:49 +02:00
Miguel ÁngelandClaude Opus 4.6 ae343bfdc8 chore: release v0.5.5
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.5.5
2026-05-08 15:00:29 +00:00
Miguel Ángel 75dcfd98cf Merge pull request #675 from heygen-com/fix/webaudio-future-clip-scheduling 2026-05-08 16:59:17 +02:00
Miguel ÁngelandClaude Opus 4.6 38522f996e fix(runtime): schedule future WebAudio clips with delay instead of playing immediately
Clips whose compositionStart is ahead of the current timeline position
were starting immediately because sourceNode.start() always received
when=0. Use the AudioContext scheduling API to defer future clips:
sourceNode.start(ctx.currentTime + delay, mediaStart).

Closes #674

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 14:56:33 +00:00
Miguel Ángel 8de7ad7f61 chore: release v0.5.4 v0.5.4 2026-05-07 23:22:15 -07:00
Miguel Ángel f761ee2624 fix(player): drive src URL timelines without runtime (#673)
* fix(player): drive src URL timelines without runtime

* fix(player): pause direct timeline after seek
2026-05-08 08:19:29 +02:00
Miguel Ángel b009288df7 feat(runtime): single-clock transport — eliminate pause/play audio drift (#671)
Replace the two-clock architecture (GSAP rAF ticker + HTMLMediaElement
pipeline reconciled by a 50ms polling loop) with a single TransportClock.
GSAP is always paused and seeked to clock.now() on each rAF tick.
Drift between visual timeline and audio is structurally impossible.

Architecture:

  TransportClock.now() ──rAF──▶ timeline.seek(t) + el.currentTime
       ▲
  AudioContext.currentTime (~21µs)  ← WebAudio active
       OR
  audio.currentTime (~33ms)         ← HTMLMediaElement fallback
       OR
  performance.now() (~1ms)          ← no audio

Key changes:
- TransportClock class with monotonic + audio-master clock sources
- WebAudioTransport: routes audio through AudioBufferSourceNode for
  sample-accurate scheduling, falls back gracefully to HTMLMediaElement
- rAF tick loop replaces 50ms setInterval poll; GSAP always paused
- Strict sync (40ms threshold, consecutive-sample gated) + forceSync
  on play/pause/seek transitions for sub-frame media accuracy
- Buffer-stall: visuals freeze when audio is buffering instead of
  running ahead
- Frame quantization preserved in seek/renderSeek (parity contract)

Browser-verified: 0.0ms drift after 40 pause/play cycles (was 400ms+).

Also fixes: CDN script HTML error responses in validate (pre-existing).

54 tests across clock, clock-drift, webAudioTransport, and media.

Closes #668
2026-05-08 07:53:46 +02:00
James Russo 7bf30d5423 Merge pull request #666 from heygen-com/05-07-fix_engine_supersample_screenshot_capture_to_honor_devicescalefactor
fix(engine): supersample screenshot capture to honor deviceScaleFactor
2026-05-07 12:08:42 -07:00
James Russo 65727e33d9 Merge pull request #665 from heygen-com/05-07-refactor_dedupe_resolution_presets_and_clean_up_4k_stack
refactor: dedupe resolution presets and clean up 4k stack
2026-05-07 11:47:46 -07:00
James Russo ef13841fa3 Merge pull request #664 from heygen-com/05-07-feat_studio_add_resolution_selector_to_render_export_bar
feat(studio): add resolution selector to render export bar
2026-05-07 10:56:57 -07:00
James Russo 441640813a Merge pull request #663 from heygen-com/05-07-feat_cli_add_--resolution_flag_to_hyperframes_render_for_one-line_4k
feat(cli): add --resolution flag to hyperframes render for one-line 4k
2026-05-07 10:40:59 -07:00
James 453bd6e313 fix(engine,producer): reject alpha+supersample, unit-test clip plumbing 2026-05-07 16:58:26 +00:00
James 0eaa54e000 fix(core,engine): derive CanvasResolution from CANVAS_DIMENSIONS, snapshot eviction value 2026-05-07 16:58:26 +00:00
James bc02b8810c fix(studio): exhaustively type RESOLUTION_OPTIONS and document layout coupling 2026-05-07 16:58:26 +00:00
James 385917ea59 fix(engine): supersample screenshot capture to honor deviceScaleFactor 2026-05-07 16:58:26 +00:00
James 2b2281d490 refactor: dedupe resolution presets and clean up 4k stack 2026-05-07 16:58:26 +00:00
James 0c026bb0f6 fix(studio): forward outputResolution from vite dev adapter to producer 2026-05-07 16:58:26 +00:00
James 25edba803a feat(studio): add resolution selector to render export bar 2026-05-07 16:58:26 +00:00
James 2d3ad953ee ci: bump pinned BtbN ffmpeg release to 2026-04-30 monthly snapshot
The autobuild-2026-04-23-13-16 release was rotated out of BtbN's
recent-dailies window, returning 404 on the Windows test/render jobs.
Switch to the 2026-04-30 month-end snapshot, which BtbN keeps long-term
(visible in the persistent monthly-snapshot history).
2026-05-07 16:58:25 +00:00
James 1545763ea3 fix(cli,producer): cross-multiply aspect check, CLI HDR guard, honest banner 2026-05-07 16:58:25 +00:00
James 5260429dd9 docs(4k): add asset-scaling reality check and reflect Studio dropdown 2026-05-07 16:58:25 +00:00
James e07aeba213 feat(cli): add --resolution flag to hyperframes render for one-line 4k 2026-05-07 16:58:25 +00:00
James Russo c1c7ba999a Merge pull request #661 from heygen-com/05-07-feat_cli_add_--resolution_flag_to_hyperframes_init_for_4k_scaffolding
feat(cli): add --resolution flag to hyperframes init for 4k scaffolding
2026-05-07 07:55:13 -07:00
James Russo a50aaa55cb Merge pull request #662 from heygen-com/05-07-fix_engine_byte-budget_the_frame_data_uri_cache_to_bound_memory_at_4k
fix(engine): byte-budget the frame data uri cache to bound memory at 4k
2026-05-07 07:31:06 -07:00
Vance Ingalls edac92b431 docs: add texture mask text catalog entry (#650)
* feat(registry): add texture mask PNGs for texture-mask-text component

* feat(registry): add texture-mask-text CSS snippet

* feat(registry): add registry-item.json for texture-mask-text

* feat(registry): add texture-mask-text demo composition

* feat(registry): register texture-mask-text component in manifest

* style: format texture-mask-text files with oxfmt

* fix: set mask-image directly on texture classes instead of via CSS custom property

url() inside CSS custom properties doesn't resolve correctly with mask-image
in some browsers. Move mask-image declarations to each texture class directly.

* docs: add texture mask text catalog entry

* test: lint texture mask text usage

* fix: harden texture mask text docs and lint

* fix: stabilize texture mask asset paths

* fix: address texture catalog review feedback

* fix: harden texture mask text instructions

* docs: remove texture catalog intro copy

* docs: use canonical texture preview URL

* docs: use cdn texture mask assets

* fix: escape catalog frontmatter safely

* test: stabilize windows render cli test

* test: pin texture catalog instructions
2026-05-07 00:23:36 -07:00
James 8355b39ffc fix(engine): skip caching oversized frames + add eviction telemetry 2026-05-07 06:10:26 +00:00
James 8203005488 fix(engine): byte-budget the frame data uri cache to bound memory at 4k 2026-05-07 06:10:26 +00:00
James 9f0074e44a fix(cli): handle reverse-order CSS in applyResolutionPreset and document scope 2026-05-07 06:10:22 +00:00
James a4eea984d9 feat(cli): add --resolution flag to hyperframes init for 4k scaffolding 2026-05-07 06:09:44 +00:00
James Russo 73966cd53b feat(core): add 4k canvas resolution presets (#660)
## What

Adds `landscape-4k` (3840×2160) and `portrait-4k` (2160×3840) presets to `CanvasResolution` and `CANVAS_DIMENSIONS` in `@hyperframes/core`. Foundation for end-to-end 4K rendering support.

## Why

There is no codified way today to mark a composition as 4K. The string union `CanvasResolution = "landscape" | "portrait"` is the only enum used by templates, generators, and stage-zoom math; without 4K members, scaffolds and helpers always emit 1080p dimensions even when the underlying engine + encoder pipeline can already handle larger viewports (Chrome `setViewport`, ffmpeg `libx264`/`libvpx-vp9`/`prores_ks` all scale fine).

This is PR 1 of a 3-PR stack making 4K a first-class option:

1. **PR #660 (this)** — core types/constants + parser detection.
2. **PR #661** — `hyperframes init --resolution 4k` flag to scaffold 4K projects.
3. **PR #662** — byte-budget the frame data-URI cache so 4K renders don't OOM.

## How

- `CanvasResolution` extended additively (no breaking change).
- `CANVAS_DIMENSIONS` gains `landscape-4k` / `portrait-4k` entries.
- `parseResolutionFromHtml` accepts `data-resolution="landscape-4k|portrait-4k"` and infers 4K from `data-composition-width`/`data-composition-height` (long side ≥ 2560 → UHD variant).
- `parseResolutionFromCss` reuses the same dimension-aware classifier so inline `#stage { width/height }` styles are detected too.
- Helper extracted: `resolveResolutionFromDimensions(w, h)`.
- `cli/info.ts` cleanup: replaces a nested `parsed.resolution === "portrait" ? 1080 : 1920` ternary with a `CANVAS_DIMENSIONS[parsed.resolution]` lookup so it stays correct for 4K.

Stage-CSS generators (`templates/base.ts`, `generators/hyperframes.ts`) already index `CANVAS_DIMENSIONS[resolution]`, so they pick up the new presets automatically.

## Test plan

- [x] Unit tests added/updated — 4 new parser tests, 1 expanded constants test
- [x] Manual testing performed — `bun run --cwd packages/core test` (679 pass), `bun run --cwd packages/cli test` (277 pass)
- [ ] Documentation updated (deferred to PR #661 where the user-facing flag lands)
2026-05-06 23:09:12 -07:00
James 20f8318ee2 fix(core): tighten 4K threshold to 3840 and pin square=portrait convention 2026-05-07 05:08:12 +00:00
James 555c51fcf6 feat(core): add 4k canvas resolution presets 2026-05-07 02:36:16 +00:00
James Russo f385181d66 Merge pull request #659 from heygen-com/fix/cli-render-windows-cold-import-v2
fix(cli): preload render.js once in renderLocal test suite (Windows CI)
2026-05-06 19:35:17 -07:00
James a739be58b1 fix(cli): preload render.js once in renderLocal test suite to fix Windows CI
The first dynamic `await import("./render.js")` cold-load takes >5 s on
Windows runners — long enough to blow vitest's default 5 s timeout in
whichever test ran it first. Subsequent imports are <10 ms because the
module is now cached, so only test #1 ever times out.

The downstream failure is more subtle: when test #1 times out, vitest
moves on, but its leaked async function eventually hits the synchronous
`producer.createRenderJob(...)` line and pushes a stale config to
`producerState.createdJobs`. That push lands AFTER test #2's `beforeEach`
clears the array, so test #2's `createdJobs[0]` is the leaked test #1
entry instead of its own. That's why test #2 saw `browserGpuMode: 'software'`
when it expected `'auto'`.

Hoist the import into `beforeAll` (matching the pattern the existing
`parseVariablesArg` and `validateVariablesAgainstProject` describe blocks
in this file already use). Cold-load happens once outside any test's
timeout window, every test stays fast, no leaked promise can corrupt
state.

Failing run: https://github.com/heygen-com/hyperframes/actions/runs/25470257972/job/74732502915
Started failing on main with the merge of #642 (auto-detect-browser-gpu),
which added the "forwards browserGpuMode='auto'" test as test #2.
2026-05-07 02:06:03 +00:00
James Russo 31acf7fdec Merge pull request #654 from TheodorKleynhans/feat/cli-png-sequence-format
feat(cli): expose png-sequence format
2026-05-06 18:12:18 -07:00
James Russo 588639fc1a Merge pull request #657 from heygen-com/fix/runtime-swallow-helper
fix(runtime): swallow() helper replaces empty catches in inlined runtime
2026-05-06 18:11:38 -07:00
Miguel Ángel ea3f7273e7 fix(core): scope duplicate getElementById lookups (#655) 2026-05-07 02:49:30 +02:00
James Russo a327e13a1e Merge pull request #632 from kiyeonjeon21/fix/cli-bun-command-hints
fix(cli): use bun in command hints
2026-05-06 17:22:02 -07:00
James Russo 5212ed49c9 Merge pull request #320 from Dylanwooo/feat/doctor-json-output
feat(cli): add --json output to doctor
2026-05-06 17:21:33 -07:00
James f33000dd1f fix(cli): rename browserGpu → browserGpuMode in render.test.ts
Drive-by fix: hf#631 (composition flag) merged with two test calls
using `browserGpu: false`, but hf#642 (browserGpuMode auto) merged
shortly after and removed that field from RenderOptions in favour of
the tri-state `browserGpuMode`. Main has been failing typecheck since
hf#642 landed (every PR inherits the failure).

Renaming `browserGpu: false` → `browserGpuMode: "software"` matches
the new shape; both tests still verify what they were written for
(forwards entryFile / omits entryFile to createRenderJob).
2026-05-07 00:00:49 +00:00
Theodor Kleynhans 4e28658173 feat(cli): expose png-sequence format
The producer already supports `format: "png-sequence"` end-to-end (see
RenderConfig in renderOrchestrator.ts), but the CLI's VALID_FORMAT
validator rejects it before the flag reaches the producer. Surface it
the same way `mov` and `webm` are surfaced.

Behaviour:
- `--format png-sequence` accepted alongside mp4/webm/mov.
- Auto-output path uses no extension (FORMAT_EXT["png-sequence"] = "")
  since the producer treats outputPath as a directory of frame_NNNNNN.png.
- `printRenderComplete` sums the contained file sizes when outputPath
  is a directory, instead of reporting the platform-dependent inode
  size.
- DockerRenderOptions.format type extended; existing buildDockerRunArgs
  is unchanged because it forwards the string verbatim.

Tests:
- renderLocal forwards `format: "png-sequence"` to createRenderJob.
- buildDockerRunArgs propagates `--format png-sequence` to the
  container.

Docs:
- Rendering guide: format flag table, format comparison table, new
  "PNG sequence (no encoding)" section, "How it works" extended.
- CLI package docs: format flag table updated.
2026-05-07 01:56:06 +02:00
James e87196456b feat(runtime): swallow() helper replaces empty catches in inlined runtime
After hf#641 inlined the runtime IIFE into every bundle, lint tools
inspecting bundled output (including Abhay's c2v eval) started flagging
empty `catch {}` blocks across the runtime. The source had explanatory
comments inside, but esbuild's minifier strips them — the IIFE ships
~10 visible patterns of `}catch{}` and consumers' linters fire on each.

Each empty catch is intentional best-effort error swallowing —
postMessage to a parent frame that may not exist, `media.play()` /
`pause()` that throw under autoplay restrictions, timeline `seek()` on
a disposed timeline, anime.js / lottie feature detection on hosts that
don't load those libraries, etc. The right behaviour stays "tried,
didn't work, move on", but doing it visibly improves three things:

  - lint clean: helper call is a real statement; no `no-empty` warnings
    survive minification
  - debuggable: flip `window.__hfDebug = true` in DevTools to see every
    swallow site with `console.debug` (silent in prod by default)
  - observable: studio / embeddings can install
    `window.__hf.onSwallowed = handler` to collect runtime swallow
    events without polluting the page console

Implementation: `packages/core/src/runtime/diagnostics.ts` exports
`swallow(label, err?)`. 41 catch sites across 12 runtime files
converted via mechanical pass (auto-generated `runtime.<module>.siteN`
labels — labels can be tightened site-by-site as a follow-up; the
shape of the change is what matters here).

Verification:
- core 674/674 (incl. 6 new diagnostics tests covering silent default,
  __hfDebug logging, legacy __HYPERFRAMES_DEBUG flag, handler hook,
  handler-throws-doesn't-recurse, both-active)
- typecheck clean
- format / lint clean
- runtime IIFE rebuilds successfully (`bun run build:hyperframes-runtime`)

Refs Abhay's c2v eval — bundler artefacts now lint-clean with the
runtime body inlined.
2026-05-06 23:53:21 +00:00
James Russo 0e7e33cf7d docs: add deployment guide for Vercel and Cloudflare templates (#653)
## What

Adds a new guide at `docs/guides/deploy.mdx` covering the two official one-click deployment templates:

- [heygen-com/hyperframes-vercel-template](https://github.com/heygen-com/hyperframes-vercel-template) (Vercel Sandbox + Vercel Blob)
- [heygen-com/hyperframes-cloudflare-template](https://github.com/heygen-com/hyperframes-cloudflare-template) (Cloudflare Containers + R2)

Wires the new page into `docs.json` under Guides, slotted right after `guides/rendering` (logical follow-on: render locally → deploy to the cloud).

## Why

The two templates currently only exist as GitHub READMEs, so they're invisible to anyone reading the docs site. New users who want a hosted preview + render endpoint have no entry point in the docs to discover them.

## How

Single guide with:

- A comparison table (compute / storage / deploy button) so readers can pick at a glance.
- `<Tabs>` for per-platform details (deploy button, what you get, performance, pricing, "why this primitive").
- Shared architecture diagram and the common "pre-baked renderer" cost pattern.
- "Swapping the composition" steps that work for both templates.
- "When to use a template vs. roll your own" framing for queues, multi-tenant, self-hosted.

Single-page approach (vs. one page per template) chosen because content overlaps heavily — easier to discover and lower maintenance until more templates land.

## Test plan

- [x] No code changes — docs only
- [x] `bunx oxfmt --check` and `bunx oxlint` pass on changed files (no rules apply to `.mdx` / `.json` here)
- [ ] Render the docs site locally to verify nav placement and Mintlify components (`<Tabs>`, `<Steps>`, `<CardGroup>`, `<Note>`) render correctly
- [ ] Verify the Vercel and Cloudflare deploy buttons in the page open the correct template URLs
2026-05-06 16:18:49 -07:00