Commit Graph
132 Commits
Author SHA1 Message Date
Miguel Ángel 4237165517 chore: release v0.6.27 2026-05-19 17:12:32 -04:00
James f4e96a58ed chore: release v0.6.26 2026-05-19 18:16:54 +00:00
James 2dc2531cf7 chore: release v0.6.25 2026-05-19 02:33:31 +00:00
Miguel Ángel 7354d61371 chore: release v0.6.24 2026-05-18 22:00:56 -04:00
Miguel Ángel ffbc18ad31 feat(studio): full Blocks panel — browse, search, add, drag-and-drop registry items
Adds a Blocks tab to the Studio left sidebar with the full 78-item registry
catalog (58 blocks + 20 components). Users can browse by category, search by
title/description, preview CDN-hosted poster thumbnails with video-on-hover,
and install items on-demand with one click or drag-to-timeline.

Core changes:
- BlockCategory type + resolveBlockCategory() for 7 categories (Captions, VFX,
  Transitions, Effects, Social, Data, Scenes)
- Registry API routes: GET /api/registry/blocks (catalog) + POST install
- StudioApiAdapter extended with listRegistryCatalog + installRegistryBlock
- Vite adapter reads from disk; CLI adapter fetches from GitHub (24h cache)
- BlockParam interface + params on 6 blocks for future parameter controls

Studio UI:
- 4th sidebar tab "Blocks" with responsive grid, category pills, search bar
- BlockCard: CDN poster thumbnail, video autoplay on hover, duration + WebGL badges
- On-demand install: blocks append as sub-compositions on timeline; components
  overlay at start=0 spanning full duration with transparent background patching
- TIMELINE_BLOCK_MIME drag-and-drop to timeline
- BlockParamsPanel (Phase 3 scaffold) auto-opens for parameterized blocks

Registry manifests:
- All 58 blocks backfilled with preview: { video, poster } CDN URLs
- All 20 components normalized to object format + poster URLs added
- 6 blocks annotated with params (Liquid Glass/Background, Portal, Chart,
  Logo Outro, Magnetic)
- flowchart-vertical preview generated and uploaded to CDN
2026-05-18 21:15:15 -04:00
James 2087d5dab2 chore: add fallow config and fix high-signal findings
Configure fallow via .fallowrc.jsonc so its analysis reflects this repo's
real entry surface, then fix the genuine issues it found.

Fallow noise reduction (601 → 276 dead-code findings):
- Ignore docs/, test fixtures, skill test-corpora, registry/, examples/
- Declare worker entry points loaded dynamically by file path
  (pngDecodeBlitWorker.ts, shaderTransitionWorker.ts)
- Declare runtime IIFE entry (core/src/runtime/entry.ts) built outside the
  import graph by build-hyperframes-runtime-artifact.ts
- Declare bun:test files in producer + aws-lambda as test entries
- Ignore dynamically-resolved deps: tsup external (puppeteer-core, esbuild,
  giget), peer/static-file (gsap in player perf tests), workspace deps
  hoisted by bun (happy-dom, @hyperframes/*), and @fontsource/* packages
  read via readFileSync in generate-font-data.ts

Extract inline build:fonts scripts:
- packages/{cli,producer}/package.json had multi-line `node -e ...` blobs
  containing braces that fallow mis-parsed as glob alternate groups. Moved
  to dedicated build-fonts.mjs scripts.

Fix duplicate exports:
- Remove dead FileIcon alias in studio/SystemIcons.tsx (FileTreeIcons.tsx
  has the real, used one)
- Consolidate ValidationResult: drop the identical duplicate in
  gsapParser.ts; both parsers now import from core.types
- Suppress intentional namespace patterns (per-namespace ML manager
  exports; CLI per-command 'examples' convention; fileServer.ts test-only
  isPathInside which has different symlink semantics from utils/paths.ts)

Break circular dep (studio/components/editor):
- manualEditsDom.ts re-exported clearStudioPathOffset / clearStudioRotation
  / clearStudioBoxSize from manualEditsSnapshot.ts, which imports four
  helpers from manualEditsDom.ts — back-edge cycle
- Re-export moved to manualEdits.ts (the package-public barrel) where the
  rest of the snapshot re-exports already live; underlying files now form
  a clean DAG

Remove genuinely unused deps:
- studio: motion (no imports anywhere), codemirror (umbrella package; the
  @codemirror/* sub-packages are used directly)
- cli: mime-types (plus its only consumer src/utils/mime.ts, which was a
  hardcoded mime table that didn't use the package), and its now-stale
  tsup external entry

Verified: typecheck across core/cli/producer/studio is clean, oxlint
+ oxfmt pass, manualEdits.test.ts (18 tests) and core parser tests (69
tests) still pass.

Deferred follow-ups (real findings, separate PRs):
- 8 circular deps in producer/services/render/stages/ — renderOrchestrator
  ↔ captureHdr* / captureStage / extractVideosStage form a hub cycle
- ~14 unused files in producer/src/services/ that look like dead
  re-export shims to @hyperframes/engine, but aren't in the public
  exports map — need to confirm no deep-import consumers before deletion
- waveform.ts complexity hotspot
2026-05-18 18:57:21 +00:00
Miguel Ángel 27efcd0f80 chore: release v0.6.22 2026-05-18 14:23:43 -04:00
Miguel Ángel 8163f38077 chore: release v0.6.21 2026-05-18 11:29:01 -04:00
Miguel Ángel 6c533c0b0f chore: release v0.6.20 2026-05-17 18:07:59 -04:00
Miguel Ángel 04aa6a644f chore: release v0.6.19 2026-05-17 17:55:32 -04:00
James Russo b05a22e69e feat(producer): add --mode=lambda-local to the regression harness (#913)
* feat(producer): add --mode=lambda-local to the regression harness

Third harness mode that drives the OSS @hyperframes/aws-lambda handler
through the exact event sequence Step Functions produces in
production:

  handler({Action: "plan"})             → planDir tarball on fake S3
  handler({Action: "renderChunk"}) × N  → chunk artifacts on fake S3
  handler({Action: "assemble"})         → final mp4/mov/png-sequence

The S3 client is a filesystem-backed fake (every s3://<bucket>/<key>
URI maps to <tempRoot>/s3/<key>), so the harness exercises the
handler's event-parsing + tar/S3 conventions + dispatch logic on top
of the underlying producer primitives. Regressions in event JSON
shape, S3 key layout, or plan-hash boundary checks now surface in
the same CI run as the in-process and distributed-simulated modes
without paying for a real AWS round-trip.

Deliberately NOT a Docker/RIE invocation — that would gate the
producer test suite on Docker-in-Docker support which most CI
runners lack. Real-ZIP-via-RIE tests live in
packages/aws-lambda/scripts/ (probe:beginframe) and the
maintainer-run smoke.sh.

Wired up via:
  - HarnessMode union extended to include "lambda-local"
  - parseHarnessModeFlag accepts --mode=lambda-local
  - regression-harness.ts dispatches to runLambdaLocalRender for
    the new mode, sharing the distributed-support gate +
    pathology-floor threshold with distributed-simulated mode
  - package.json scripts: test:lambda-local + docker:test:lambda-local
  - producer.devDependencies += @hyperframes/aws-lambda (workspace)
  - producer/tsconfig.json gains path mappings to self so the type
    cycle through aws-lambda's source resolves at typecheck time
    without needing producer to be pre-built

Tests: 3 new unit tests on parseHarnessModeFlag + resolveMinPsnrForMode
cover the new mode. End-to-end PSNR contract still runs through
Dockerfile.test (manual + CI).

* refactor(producer): /simplify pass on lambda-local harness imports

Three small cleanups on top of the lambda-local harness:

  - Drop the unused createReadStream import + its `void` workaround
    comment. The aws-lambda handler's tar / S3 transport pulls
    createReadStream from its own imports; this file never references
    it directly.

  - Hoist the dynamic `await import("node:fs")` calls for
    writeFileSync out of FilesystemBackedFakeS3.send into the static
    import block. Repeated PutObject calls don't need to repay the
    dynamic-import cost.

  - Hoist the dynamic `await import("@hyperframes/aws-lambda")` call
    for untarDirectory similarly. Drops the now-redundant duplicate
    aws-lambda import statement.

The PutObject body branch also collapses: `body instanceof Buffer`
and `typeof body === "string"` both call writeFileSync identically,
so they share one branch.

No behavior changes.

* fix(producer): lazy-import lambda-local harness module

The static import of regression-harness-lambda-local.ts pulled
@hyperframes/aws-lambda (and its @aws-sdk/* + @sparticuz/chromium
transitive deps) at module-load time. Dockerfile.test only copies
the producer's own files into the container, so aws-lambda's src
isn't present at runtime — and even `--mode=in-process` failed:

  Error [ERR_MODULE_NOT_FOUND]: Cannot find module
  '/app/packages/producer/node_modules/@hyperframes/aws-lambda/src/index.ts'
  imported from /app/packages/producer/src/regression-harness-lambda-local.ts

Load the module on demand instead. `--mode=lambda-local` callers
pay the import cost; the existing in-process and distributed-
simulated modes don't.

* fix(producer): address PR review on lambda-local harness

Three review items from Vai:

  - `Config.width`/`Config.height` are now plumbed through
    RunLambdaLocalInput rather than hardcoded inside
    runLambdaLocalRender. Lambda-local's whole point is to catch
    event-shape drift; if the handler ever starts honouring
    Config.width/height (e.g. for canvas sizing), having those
    values flow from the caller means the harness sees what the
    fixture authored. The interface change makes the eventual
    upgrade-to-real-fixture-resolution a one-line dispatch swap.

  - Drop the dead `export type { Fps }` and its unused import
    from @hyperframes/core. The module never re-exports it.

  - The dispatch site in regression-harness.ts now passes 1920×1080
    explicitly with a comment marking it as a placeholder until
    the harness compiles the composition HTML up-front to surface
    the authored data-width/data-height. distributed-simulated
    mode uses the same placeholder internally, kept for parity.

No behavior change in the existing modes; lambda-local now has a
clear extension point for honouring fixture dimensions.
2026-05-17 14:04:49 -04:00
Miguel ÁngelandClaude Sonnet 4.6 78fce8bd8a chore: release v0.6.18
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 15:32:53 +00:00
Miguel ÁngelandClaude Sonnet 4.6 3f976d454c chore: release v0.6.17
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 15:15:54 +00:00
James b30fd29695 chore: release v0.6.16 2026-05-17 08:20:08 +00:00
James 5f8391bd96 chore: release v0.6.15 2026-05-16 23:30:38 +00:00
Miguel Ángel 1fca35b625 chore: release v0.6.14 2026-05-16 13:02:23 -07:00
Miguel ÁngelandClaude Sonnet 4.6 883260aae3 chore: release v0.6.13
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:35:46 +00:00
Miguel Ángel 2355d505e1 chore: release v0.6.12 2026-05-16 00:48:57 -07:00
Miguel Ángel 4212a28312 chore: release v0.6.11 2026-05-15 23:43:21 -07:00
Miguel Ángel d3c32a0b4d chore: release v0.6.10 2026-05-15 21:25:26 -07:00
Miguel Ángel 82c9b6b5ea chore: release v0.6.9 2026-05-15 19:45:01 -07:00
Miguel Ángel 4b501762e4 chore: release v0.6.8 2026-05-15 19:20:28 -07:00
Miguel Ángel e8e2e81730 chore: release v0.6.7 2026-05-14 21:54:56 -07:00
James 415ad8b5a6 feat(producer): add harness mode --mode=distributed-simulated 2026-05-14 04:27:12 +00:00
James 91a91f66ba feat(producer): export distributed render primitives 2026-05-14 03:40:44 +00:00
terencecho 27ae55a5c7 chore: release v0.6.6 (#818) 2026-05-13 17:01:15 -07:00
Miguel Ángel 7703122a4d chore: release v0.6.5 2026-05-13 13:40:37 -07:00
Miguel Ángel 9fe356be14 chore: bump version to 0.6.4 2026-05-13 00:49:09 -07:00
Miguel Ángel 636db23197 chore: bump version to 0.6.3 2026-05-13 00:46:36 -07:00
James 067bc722e3 fix(deps): align @types/node + esbuild + tsx across workspace
The Windows install failures (`ENOENT: failed copying files from cache to
destination for package @types/node` / `esbuild`) are caused by bun creating
workspace-scoped nested installs under
`node_modules/@hyperframes/<pkg>/node_modules/...`. Those nested paths only
exist because each workspace package pinned a different `@types/node` /
`esbuild` major:

- root: `@types/node ^25.0.10`, core: `^24.10.13`, cli/engine/producer: `^22`
- core/cli: `esbuild ^0.25.x`, producer: `^0.27.2`

Each major-version gap forces bun to install a workspace-scoped copy in a
deep `node_modules/@hyperframes/<pkg>/node_modules/<dep>/node_modules/...`
tree that bun can't reliably materialize on Windows GHA runners. Aligning
versions lets bun dedup to a single root-hoisted install per dep, and the
nested workspace block disappears from `bun.lock` entirely.

## Alignment

- `@types/node` → `^25.0.10` across root, core, cli, engine, producer
- `esbuild` → `^0.25.12` across cli, core, producer
- `tsx` → `^4.21.0` across producer (matches root + core)

## Source-level v25 compat (already in this PR)

@types/node v25 declares `File` as an interface (not a class) and exposes a
conditional global where `FormData.entries()` narrows to `[string, string]`
when an `onmessage` global is in scope. `packages/core/src/studio-api/routes/files.ts`'s
`value instanceof File` check was relying on the v24 class declaration —
already cast the iterator to `Iterable<[string, FileLike | string]>` in the
prior commit.

Two more v25 source fixes here:
- `packages/cli/src/commands/init.ts`
- `packages/cli/src/whisper/normalize.ts`

`Dirent.path` was removed in @types/node v25 (deprecated alias for
`parentPath` since Node 20.12). Drop the `?? e.path` fallback.

## Verification

Both install layouts now build clean end-to-end:

- `bun install` (isolated, default): full build green, 853 core tests pass,
  typecheck green across all 7 packages
- `bun install --linker=hoisted` (Windows CI): same result
- `bun.lock` no longer contains any `@hyperframes/<pkg>/<dep>` nested
  workspace entries — 70+ lines of nested install blocks gone
2026-05-13 03:35:47 +00:00
Miguel ÁngelandClaude Opus 4.6 86c5fd28e8 chore: release v0.6.2
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-13 01:35:21 +00:00
Miguel ÁngelandClaude Opus 4.6 82fd2967c4 chore: release v0.6.1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-13 00:27:13 +00:00
Miguel Ángel 91bdffffe6 fix(ci): scope LOC check to studio, split useTimelinePlayer + hyperframes-player under 500 LOC (#750)
* refactor: split useTimelinePlayer.ts and hyperframes-player.ts into focused modules (<500 LOC each)

* fix(ci): scope 500 LOC check to packages/studio, add allowlist for grandfathered files

* feat(cli): Linux ARM64 support — auto-install Chromium on DGX Spark / GB10 / Jetson

Chrome Headless Shell has no Linux ARM64 binary. On arm64 Linux:
- Detects the platform automatically
- Tries to auto-install system Chromium via apt-get (works on Ubuntu/Debian ARM)
- Falls back to clear manual instructions with exact commands
- 'hyperframes browser ensure' guides through the setup interactively
- After setup, all render commands work without any flags

* fix(ci): disable Windows Defender real-time monitoring to prevent EPERM builds

Path exclusions are insufficient — Defender re-scans new files created
during bun install before the exclusion takes effect. Disable real-time
monitoring for the entire job duration instead (standard CI practice).

* refactor(studio): split all files >500 LOC + extract useToast, delete allowlist

All 11 large files split into focused modules under 500 LOC.
App.tsx extracted toast logic into useToast hook (493 LOC now).
.filesize-allowlist deleted — no longer needed.

* fix: remove unused imports from split files, extract useToast from App.tsx

App.tsx: 504 → 493 lines (toast logic extracted to useToast hook)
timelineDOM.ts: remove unused imports from re-export pattern
MotionPanel.tsx: remove unused clampStudioCustomEasePoints import
studioMotionOps.ts: remove unused StudioGsapMotionDirection import

* fix(ci): use Set-MpPreference to fully disable Windows Defender (both jobs)

* fix(producer): use node --experimental-strip-types instead of tsx for build:fonts

Eliminates the tsx binary dependency that Windows Defender locks during
bun install, causing EPERM errors. Node 22.6+ strips TypeScript types
natively with no external binary.

* chore: remove .filesize-allowlist — App.tsx is now 493 lines (<500)

* fix(ci): disable Windows Defender before checkout to prevent all EPERM races

* fix(producer): skip build:fonts if fontData.generated.ts already exists

The generated file is tracked in git, so CI doesn't need to regenerate
it. This avoids @fontsource/inter node_modules access on Windows which
triggers EPERM from Defender scanning during bun install.
2026-05-13 01:48:12 +02:00
Miguel Ángel e25a3b3a4b chore: release v0.6.0 2026-05-12 11:28:30 -07:00
Miguel Ángel 57ea5641fe chore: release v0.5.7 2026-05-10 18:34:43 +00:00
Miguel Ángel bd7bbae42d chore: release v0.5.6 2026-05-10 05:40:30 +00:00
Miguel ÁngelandClaude Opus 4.6 ae343bfdc8 chore: release v0.5.5
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 15:00:29 +00:00
Miguel Ángel 8de7ad7f61 chore: release v0.5.4 2026-05-07 23:22:15 -07:00
Miguel Ángel aa524f43c9 chore: release v0.5.3 2026-05-06 11:45:59 -07:00
Miguel Ángel 7174c4cdcd chore: release v0.5.2 2026-05-06 10:27:07 -07:00
Miguel Ángel 64f3a4ed5f chore: release v0.5.1 2026-05-06 10:14:00 -07:00
James 94b8acf3b0 chore: release v0.5.0 2026-05-06 16:12:18 +00:00
James 584627546a chore: release v0.4.45 2026-05-05 04:41:23 +00:00
Miguel Ángel 20895eecdd chore: release v0.4.44 2026-05-04 14:37:16 -07:00
Miguel Ángel 1d15845a13 chore: release v0.4.43 2026-05-03 22:53:04 -07:00
Miguel Ángel db9cffb203 chore: release v0.4.42 2026-05-01 21:35:29 -07:00
Miguel Ángel 8b8dcf543e chore: release v0.4.41 2026-04-30 22:52:55 -04:00
Miguel Ángel 4fa2633e82 chore: release v0.4.40 2026-04-30 13:04:39 -04:00
Miguel Ángel 2045e21f70 chore: release v0.4.39 2026-04-30 01:18:15 -04:00
Miguel Ángel 4ab304e22f chore: release v0.4.38 2026-04-29 21:10:23 -04:00