31 Commits
Author SHA1 Message Date
James bc956bb6da chore: release v0.1.15 2026-03-31 03:34:27 +00:00
James 25767fd8dd chore: release v0.1.14 2026-03-31 03:15:36 +00:00
ef6225da1d feat(core): add fitTextFontSize utility for pixel-accurate text measurement (#152)
Add @chenglou/pretext dependency and fitTextFontSize() utility that uses
canvas measureText to compute the largest font size that fits text within
a given width. Replaces character-count heuristics with actual font-aware
measurement.

- New fitTextFontSize() in @hyperframes/core/text, exposed on window.__hyperframes
- Generalized for all text elements (captions, titles, etc.), not just captions
- Unit tests (mocked pretext) + browser integration test (real Chromium canvas)
- Updated captions skill docs with usage, exit guarantee, and self-lint patterns

Co-authored-by: James <james.russo@heygen.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 20:14:13 -07:00
James cf0ec5d27d chore: release v0.1.13 2026-03-30 22:21:18 +00:00
Miguel Ángel 1230657ed0 fix(studio,runtime,engine,compiler): 8 bug fixes — audio, render, timeline, Lottie, thumbnails, video render (#133)
## Summary

**Original 5 bugs fixed:**

- **Bug 1 — Audio silent after seek**: Added `Accept-Ranges` / `Content-Length` + `206 Partial Content` to the static asset server for byte-range seeking.
- **Bug 2 — Download 404 after restart**: Render list endpoint now registers on-disk renders into the in-memory job map.
- **Bug 3 — Timeline stops at GSAP end**: `resolveRootTimelineFromDocument` pads the GSAP timeline to match `data-duration` when the composition declares longer.
- **Bug 4 — Render stuck at 0%**: Store `jobState` reference (not spread copy) so async progress mutations reach the SSE stream.
- **Bug 5 — Lottie missing in preview/render**: Two fixes — (a) moved Lottie adapter before GSAP so `onUpdate` wins; (b) fixed bundler silently dropping external CDN `\<script src>` tags from sub-compositions (root cause: `$content(s).html()` returns `""` for external scripts).

**3 additional bugs fixed:**

- **Bug 6 — Blank thumbnails outside monorepo**: Implemented `generateThumbnail` in the CLI adapter using Puppeteer.
- **Bug 7 — Video empty in rendered sub-compositions**: Fixed `parseVideoElements` selector from `video[id][src]` to `video[src][data-start]` + auto-assign IDs.
- **Render errors**: Failed renders now show their error message in the renders panel.

## Commits

| Commit | Description |
| --- | --- |
| `3951c6f` | fix(studio): store render job reference instead of snapshot copy |
| `f331c30` | fix(studio): make previously-completed renders downloadable after restart |
| `a5e2d04` | fix(studio): add range request support for audio/video seeking in preview |
| `f24317a` | fix(runtime): pad GSAP timeline to data-duration when composition declares longer duration |
| `7cf38ca` | fix(runtime): fix Lottie adapter conflicting with GSAP-driven animations |
| `bc99209` | fix(studio): surface render error messages in the renders panel |
| `8fc9e8b` | fix(cli): implement generateThumbnail in studio adapter |
| `90277ea` | fix(engine): render videos inside sub-compositions that lack an explicit id |
| `f5bb579` | fix(compiler): preserve external CDN scripts from sub-compositions in bundle |

## Test plan

- [x] `golden-lyric-video`: seek → audio plays from seeked position
- [x] Any project: render → progress advances past 0%, reaches 100%
- [x] Any project: complete render, restart `hyperframes dev`, Download → works
- [x] `intro-vid`: play → runs full 5s (not stopping at 3s)
- [x] `hyperframe-build-up-demo`: play → rocket Lottie visible during 0-2s  verified
- [x] Outside monorepo: Compositions sidebar shows thumbnail images (not blank)
- [x] `bug.zip` project: render → video in polaroid sub-composition appears in output
- [x] Trigger a failed render → error message shown
2026-03-30 23:58:08 +02:00
Vance Ingalls 229538c622 fix: add media rendering guardrails to prevent silent failures (#112)
## Summary

- **Lint rules** catch media elements missing `id` (renderer silently skips them), missing `src`, `preload="none"` (blocks renderer), and video nested in timed divs (freezes playback). Upgraded `video_nested_in_timed_element` from warning to error.
- **Compiler** strips `preload="none"` from media during compilation. Runs parallel, cached keyframe interval analysis via ffprobe — warns on sparse keyframes (>2s) that cause seek failures and audio/video desync. Suggested ffmpeg command preserves audio (`-c:a copy`).
- **Pre-render lint** lints `index.html` + all `compositions/*.html` sub-compositions before render via shared `lintProject()` helper. Warns by default; `--strict` blocks on errors, `--strict-all` blocks on errors + warnings.
- **Render orchestrator** logs a hint to retry with `--workers 1` when parallel capture times out on video-heavy compositions.
- **Refactor**: extracted `runFfprobe()` + `parseProbeJson()` helpers to deduplicate ~80 lines of spawn boilerplate across 3 ffprobe functions. Extracted `shouldBlockRender()` so strict flag tests exercise production code. Shared `lintProject()` used by both `lint` and `render` commands.

## Context

Discovered during a real composition build session where:
1. `<audio>` without `id` rendered silently (preview worked fine because runtime queries `[data-start]`, but renderer queries `[id][src]`)
2. `<video>` inside timed `<div>` froze on first frame
3. `preload="none"` caused 45s renderer timeout
4. YouTube clips with sparse keyframes from `yt-dlp --download-sections` caused audio/video desync
5. Parallel workers timed out on video-heavy compositions

## Test plan

- [x] Core: 365/365 tests passing (5 new lint tests)
- [x] Engine: 24/24 tests passing
- [x] CLI: 14/14 tests passing (7 lintProject + 7 shouldBlockRender)
- [x] Lint + format hooks pass
- [ ] Manual: create a composition with `<audio data-start="0" src="test.wav">` (no id) — verify `npx hyperframes lint` catches it
- [ ] Manual: run `npx hyperframes render --strict` with lint errors — verify it blocks
- [ ] Manual: run `npx hyperframes render --strict-all` with lint warnings — verify it blocks
2026-03-30 11:07:19 -07:00
Miguel ÁngelandClaude Opus 4.6 808d196fe0 chore: bump to v0.1.12
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 10:10:03 +00:00
Miguel ÁngelandClaude Sonnet 4.6 6d105a3e64 chore: bump to v0.1.11
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:39:38 -04:00
James 7d7af7902b chore: release v0.1.10 2026-03-28 03:59:00 +00:00
James b6e2d74cb7 chore: release v0.1.9 2026-03-27 22:16:04 +00:00
James 8b784cca3d chore: release v0.1.8 2026-03-27 22:09:23 +00:00
James 8d7c33a4aa fix(publish): add repository.url to all packages for npm provenance
npm's sigstore provenance verification requires package.json
repository.url to match the GitHub repo. Without it, publish
fails with E422 "expected to match https://github.com/heygen-com/hyperframes".
2026-03-27 22:07:55 +00:00
James 4a49d461df chore: release v0.1.7 2026-03-27 22:03:09 +00:00
github-actions[bot] 55ff721552 chore: release v0.1.6 2026-03-27 06:04:18 +00:00
JamesandClaude Opus 4.6 83d11ac595 refactor: simplify review fixes for WebM PR
- Use static import for copyFileSync (was unnecessary dynamic import)
- Shallow-copy config before mutating forceScreenshot (prevents
  caller-provided config from being permanently modified)
- Consolidate isWebm/isWebmRender/outputFormat into single early
  declaration in renderOrchestrator
- Fix debug output extension for WebM (was hardcoded .mp4)
- Log unexpected audio extraction errors instead of silently swallowing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 03:40:35 +00:00
JamesandClaude Opus 4.6 efc7b82755 fix(render): fix WebM transparency — use screenshot mode + proper CDP setup
- Force screenshot capture mode for WebM (beginFrame doesn't support
  alpha channel in chrome-headless-shell)
- Set Emulation.setDefaultBackgroundColorOverride once during session
  creation (matching experiment-framework's approach)
- Fix acquireBrowser to pass executable path in screenshot mode on
  Linux (was setting undefined, causing puppeteer-core to fail)
- Add Page.captureScreenshot params: fromSurface, captureBeyondViewport,
  optimizeForSpeed (matching experiment-framework)
- Fix regression harness extractMonoPcm16 for videos without audio
- Add getEncoderPreset unit tests
- Add webm-transparency regression test with golden baseline

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 02:35:03 +00:00
JamesandClaude Opus 4.6 a146c9e527 test(render): add WebM regression test and getEncoderPreset unit tests
- New regression test `webm-transparency`: minimal transparent composition
  rendered to WebM, validates VP9 codec and visual quality at 100
  checkpoints against golden baseline
- Extend regression harness: `renderConfig.format` field ("mp4" | "webm"),
  format-aware output paths and snapshot filenames
- Fix `extractMonoPcm16` to gracefully handle videos without audio
  streams (WebM without audio was throwing instead of returning empty)
- Unit tests for `getEncoderPreset()`: VP9/yuva420p for WebM,
  h264/yuv420p for MP4, preset mapping, quality preservation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 02:19:43 +00:00
JamesandClaude Opus 4.6 15f6b86ac0 feat(render): add WebM output with VP9 alpha transparency
Support rendering compositions with transparent backgrounds via
`--format webm`. VP9+alpha is the standard format for overlayable
video (captions, lower thirds, overlays).

Changes by layer:
- CLI: `--format mp4|webm` flag on render command
- Producer: threads format through RenderConfig, switches to PNG
  capture and VP9 encoding when webm
- Engine: getEncoderPreset() returns VP9 config with yuva420p;
  transparent page background via CDP when capturing PNG;
  mux uses Opus audio for WebM; VP9 flags from production:
  -row-mt 1, -auto-alt-ref 0, alpha_mode=1 metadata
- Frame capture: Emulation.setDefaultBackgroundColorOverride a=0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 02:12:39 +00:00
github-actions[bot]andgithub-actions[bot] ffd0fb678f chore: release v0.1.5 (#77)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-27 01:50:05 +01:00
github-actions[bot] 87fc3e3d8f chore: release v0.1.4 2026-03-26 22:09:12 +00:00
Miguel Ángel 36c91cecbb chore: release v0.1.3 (#60)
## Release v0.1.3

Bumps all packages to v0.1.3.

### Changes since v0.1.2
- fix(producer): resolve manifest from sibling dist/ directory
- fix(producer): add margin reset when wrapping HTML fragments
- fix(producer): exclude test files from tsc build
- feat(cli): add opt-out anonymous telemetry via PostHog
- feat: add HyperFrames skills for AI coding tools
- fix(cli): resolve npx hyperframes from inside monorepo
- fix(ci): publish workflow fixes (remove provenance, idempotent steps, remove prepublishOnly)

After merging, the release tag is created automatically, which triggers npm publish.
2026-03-26 19:17:09 +01:00
Miguel Ángel f84df64e64 chore: release v0.1.2 (#32)
## Release v0.1.2

Bumps all packages to v0.1.2.

**After merging**, the release tag is created automatically, which triggers npm publish.
2026-03-24 06:06:12 +01:00
JamesandClaude Opus 4.6 065de441b3 style: apply oxfmt formatting to markdown files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 04:54:24 +00:00
JamesandClaude Opus 4.6 98113c2447 docs: add per-package READMEs and polish root docs for OSS launch
- Add READMEs for all 5 packages (core, engine, producer, cli, studio)
  with install, overview, basic usage, and links to full docs
- Rewrite core README from internal doc to OSS-facing format
- Polish root README: add badges, packages table, docs link, requirements
- Add AI usage policy and BDFL governance statement to CONTRIBUTING.md
- Genericize license references (pending final license decision)
- Docs URL set to hyperframes.heygen.com

Addresses VA-850.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 04:53:00 +00:00
github-actions[bot] 7d75ba30db chore: release v0.1.2 2026-03-24 04:32:13 +00:00
Vance Ingalls 20be2ea1c2 style: apply oxfmt baseline formatting across all source files (#25)
## Summary
- Run `oxfmt .` across the entire codebase to establish formatted baseline
- 299 files changed — mechanical formatting only, no logic changes
- Double quotes, semicolons, 2-space indent, trailing commas, 100 print width

Part 3/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits)

## Test plan
- [x] `pnpm format:check` — all 426 files pass
- [x] `pnpm -r typecheck` — all packages pass
- [x] `pnpm build` — all packages build
- [x] All 348 tests pass
2026-03-23 17:15:14 -07:00
Vance Ingalls 323ff8f860 fix: resolve oxlint errors across codebase (#24)
## Summary
- Remove 5 unused `beforeEach` imports from test files
- Remove unused imports (`existsSync`, `TimelineCompositionElement`)
- Remove unused destructured variables (`options`, `width`, `height`, `goldenEl`)
- Remove dead `formatDuration` function
- Fix unused catch parameters (`catch (err)` → `catch`)
- Prefix unused `renderError` state with `_`
- Add `eslint-disable-next-line` for 2 React exhaustive-deps false positives (stable ref + zustand setter)

Part 2/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits)

## Test plan
- [x] `pnpm lint` — 0 errors on 193 files
- [x] All 348 tests pass (core + engine)
2026-03-23 16:41:41 -07:00
James 4fa627d36a chore: release v0.1.1 2026-03-23 03:24:59 +00:00
Vance IngallsandClaude Opus 4.6 1a713b37b9 fix: change workspace:* to workspace:^ for npm publish compatibility (#12)
pnpm converts workspace:^ to ^X.Y.Z during publish, but workspace:*
was left unconverted in the registry. This caused install failures
for external consumers.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 20:15:54 -07:00
James fac39541f5 fix: resolve build and typecheck failures across packages 2026-03-23 01:29:53 +00:00
Vance IngallsandClaude Opus 4.6 9f8e5ba5a1 initial code (#2)
* feat: initial code port from hyperframes-internal

Port all OSS-ready packages from the internal monorepo:
- @hyperframes/core — shared types, HTML generation, GSAP utilities, runtime
- @hyperframes/cli — CLI for creating, previewing, and rendering compositions
- @hyperframes/engine — framework-agnostic rendering engine (BeginFrame + FFmpeg)
- @hyperframes/producer — video rendering pipeline (Puppeteer + FFmpeg)
- @hyperframes/ui-player — browser-based video player component
- @hyperframes/studio — composition editor (React frontend + Hono backend)

Includes regression test suite with Docker-based test harness.

All HeyGen-internal references, deployment infrastructure, and
proprietary assets have been removed. Package names migrated
from @app/* to @hyperframes/*.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: scrub internal codenames and stale references from OSS port

- Replace static.heygen.ai runtime URLs in test fixtures
- Remove internal CDN publish script (publish-hyperframe-runtime.ts)
- Replace sandbox-studio, sandbox-interceptor, __magicEditRuntime
  with neutral names (studio, hyperframe-runtime, __hyperframeRuntime)
- Fix stale Vault API / localhost references in docs
- Remove broken deprecated_studio link

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove remaining internal codenames and stale references

- Delete stale producer README.md and PIPELINE.md (referenced nonexistent files)
- Replace "Cerberus" codename with "HyperFrames" in test design reviews
- Replace magic-edit postMessage identifiers with hf-preview/hf-parent
- Rename debug-magic-edit-timeline.ts to debug-timeline.ts
- Replace "Motion Cut" with "HyperFrames" in Timeline comments
- Fix studio/CLI references to nonexistent archive package
  (use local data/projects/ dir, stub render proxy)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 22:43:56 -07:00