* fix(sdk): keep added elements when reopening saved overrides
* fix(sdk): replay saved overrides in latest edit order
* fix(sdk): preserve saved positions after sibling edits
* test(sdk): cover child edits after base parent restoration
* fix(producer): report unavailable frame checks in debug logs
* chore: prepare conflict resolution against current main
* fix(producer): retain scoped diagnostics with current artifact handling
* fix(render): align container Chrome with the CLI
* chore: prepare conflict resolution against current main
* fix(render): retain Chrome visuals and current audio baselines
* fix(cli): preserve ducking gain when music starts later
* test(cli): keep ducking regressions standalone
* chore: prepare conflict resolution against current main
* chore: preserve reviewed fix on current main
* chore: prepare conflict resolution against current main
* fix(cli): refresh delayed music ducking against main
* fix(cli): include external video posters in project archives
* chore: prepare conflict resolution against current main
* fix(cli): retain poster localization with shared archive resolvers
* fix(cli): reap only orphaned browsers HyperFrames launched
Orphan cleanup on preview and render killed every PPID-1 process of the
current user whose args named chrome-headless-shell or a Puppeteer temp
profile, which included detached browsers started by other tools.
Every HyperFrames Chrome launch now passes an inert
--hyperframes-owned-browser switch, and the reaper only kills PPID-1
processes that carry it as a whole argument.
Fixes#6203
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(core): serve the browser marker from its own subpath
The GCP image's BeginFrame contract step imports the engine's
browserManager straight from source before core's generated runtime
exists, so pulling the marker from the core root entry broke it.
A dependency-free @hyperframes/core/browser-marker subpath keeps that
import chain as light as it was.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(cli): expect the browser marker in the capture fallback launches
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* docs(cli): say orphan cleanup runs before preview and render
The cleanup only stops browsers HyperFrames launched, so the opt-out is
no longer needed to protect other tools' browsers.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Blur finds movers by seeking, and only runs timeline callbacks while it
scans when data-motion-blur-events is on, so motion set from a render(t)
function (k3-promo's rods and pills) showed no blur. Subtle and Strong
now write the attribute and Off removes it.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* docs(studio-app): show the app working, three new pages, today's UI
* docs(studio-app): correct what the app does today (fact-checked against both repos' main)
Script: audio goes to HeyGen to transcribe; cuts wait in Pending video edits until Send; today's toolbar; suggested
cuts. Continue from Claude Code: Mac only, inside an agent session, catch-up after that hand-off, real output.
GitHub Copilot added. 4K price, 10-minute sign-in, Auto as the default, real sign-in errors, motion-guide limit,
the right-panel row. Looping clips pause and respect reduced motion.
* docs(studio-app): hold the Share page until Share launches (desktop-share is at 0%)
* docs(studio-app): Home screenshot from a regular account on b467 (Make, Reference, Script)
* Revert "docs(studio-app): hold the Share page until Share launches (desktop-share is at 0%)"
This reverts commit 201070ac7b7a551c5515c1a770be4a5e8ab36ab9.
* docs(studio-app): Export link label names its page
* docs(studio-app): where-is-it clips re-recorded on a regular account, b467
Staff-only items are gone (Pit Crew Academy, View as a user, the HyperFrames agent, Learn). # opens tools by typing;
the tools list and the @ menu match a regular account; the import clip ends before the folder list.
* docs(studio-app): new Script clip on a regular account: Cut, Pending video edits, Send 1 edit, 0:22 to 0:17
* docs(studio-app): Draw clip re-recorded on a regular account (Send 1 edit to Claude Code, 1 min 52 s edit)
* docs(studio-app): Export clip re-recorded on a regular account (1080p, 16 s); cloud rendering as the app shows it
* docs(studio-app): Video 1 change-a-clip demo re-recorded on a regular account (Up to $1.09 shown before Make)
* docs(studio-app): Share clips re-recorded on a regular account; the page mentions HeyGen's Checking step
* docs(studio-app): first-video demo re-recorded on a regular account (question cards, Send answer, 29 min storyboard, 10 min build)
* docs(studio-app): Reference page follows today's flow (the app reads the video, then Copy editing style or Video brief; What to swap); demo re-recorded on a regular account
* docs(studio-app): autoplaying demos start muted so browsers play them; Automatic updates in troubleshooting
* docs(studio-app): update home.jpg in place instead of replacing it
* docs(snippets): DocsVideo stops an autoplaying loop when Reduce Motion turns on mid-visit; play loads it again
* docs(studio-app): motion guides need the person's picture; drop a pending cut by deleting its row; remove two unused stills
* fix(cli): init and skills update only touch HyperFrames skills; --skip-skills works
* fix(cli): init never touches installed skills and no command removes one
* fix(cli): shorten the init skills comment
* fix(cli): shorten the init skills comment
* fix(cli): the stale-skills notice reaches agents that run without a terminal
* test(cli): a run without a terminal now checks skills in the background
* fix(cli): the stale-skills notice also prints on --json runs
* docs: align render, fps and transcribe docs with the CLI
- docs/guides/rendering.mdx: default render quality is `looks` (CRF 16),
not `standard`.
- docs/packages/cli.mdx, render --help (render.ts): default --output is the
timestamped `renders/<project>_<YYYY-MM-DD>_<HH-MM-SS>.<ext>`.
- skills/hyperframes-cli/references/preview-render.md: local --fps accepts
1-240 or a rational and defaults to the root data-fps, else 30; only
lambda and cloudrun are limited to 24, 30, 60.
- skills/hyperframes-cli/references/lint-validate-inspect.md: snapshot
--range is documented as START,END like every other reference.
- skills/media-use/references/audio.md, skills/media-use/audio/references/
transcribe.md, skills/hyperframes/references/captions.md: name the entry
point for each transcription default (transcribe.mjs prefers Parakeet;
`hyperframes transcribe` uses Parakeet when installed, else the small.en
whisper model).
- transcribe --model help text and docs/packages/cli.mdx: list `small` and
`medium`, which the CLI already accepts.
- skills-manifest.json: regenerated hashes for the three skills touched.
— Jerrai
* docs: lambda and cloud run also accept 25 fps
Distributed renders accept 24, 25, 30 and 60 fps (DISTRIBUTED_FPS in
packages/core/src/distributedFps.ts).
- skills/hyperframes-cli/references/preview-render.md: the --fps note
lists 24, 25, 30, 60 for lambda and cloudrun.
- skills/hyperframes-cli/references/lambda.md, cloudrun.md: --fps lists
include 25.
- packages/cli/src/docs/rendering.md (`hyperframes docs rendering`): --fps
said 24, 30 or 60 and --quality defaulted to standard; local render takes
1-240 or a rational, default root data-fps else 30, and the default
quality is looks.
- skills-manifest.json: regenerated hyperframes-cli hash.
— Jerrai
* chore(skills): regenerate skills manifest after formatting
The format hook rewrote skill markdown after the manifest hook had hashed
it, leaving the hyperframes-cli hash stale.
— Jerrai
Note that the desktop hand-off in `open` is macOS-only for now, that
`timeline apply --plan` prints only a count without --json, and what
`history undo --who` reverts.
Refs #5386
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* feat(studio): motion blur panel with Off / Subtle / Strong
One three-way control in the right dock. Subtle is the default blur
(240 deg shutter, samples sized to the smear); Strong is 720 deg and 64
samples. Writes the root data-motion-blur attributes through the SDK so
renders match and undo works; reads live attributes from the preview.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* fix(studio): motion blur panel edits the file's own root
The edits were worked out against the preview DOM but written to the file,
so a stale preview (undo inside the hold, a slow reload) could save a level
other than the one picked. They are now computed inside the mutation from
the candidate's root. While locked to a sub-composition no level is shown.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* fix(studio): shorten the motion blur tab so the dock strip fits
Five tabs overflowed the default dock width by 10px and clipped a label
(Studio: load smoke). The tab is now titled Blur.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* feat: check names the filter fallback, the render log names the tier, Studio stops opting out
hyperframes check reports motion_blur_filter_fallback (info) with the reason capture could not
run and the way back to it. The engine's per-session log line gains tier=, and its pixel test
covers the fallback over a WebGL page. Studio no longer sends previewMotionBlur: every Chrome
can preview blur now, through the fallback where it lacks html-in-canvas; the server still
accepts false from an older Studio.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* feat(core): blur picks the cheaper filter tier when every mover only translates
The scan now notes whether any mover turns or scales (the linear part of its transform chain
changes) and whether it already forms a stacking context while it moves. When every mover only
translates, the filter tier draws as well as capture and costs about what no blur costs: on an
8 s bench shot a render took 7.0 s against 9.9 s with capture and 7.3 s with no blur. Anything
that turns or scales, or moves without a transform, stays on capture.
data-motion-blur-tier="capture" or "filter" forces a tier. The report says which one drew
and why (translation-only, tier-attribute); hyperframes check stays quiet for those two, which
are choices, not fallbacks. The pixel tests run the shared assertions through both tiers.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* docs(motion-blur): the two tiers, the tier attribute, and what changed in limits
The guide described blur turning off for WebGL, a root transform and similar. It now says the
filter tier draws instead, how the tier is chosen and forced, what each does with a turn or a
zoom, the measured cost of each, and which findings check emits. The skill note drops the
off-for-WebGL advice and the 1.7x figure.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* feat(core): blur defaults match a 240 degree shutter and at least 32 samples
The shutter opens 240 degrees by default (was 180) and each mover gets at least 32 taps (was
sized to the smear alone, down to 2), growing with the smear as before. These are the settings
the shutter blur Jake built uses; on the card whip the default render is now 51 dB from his
(34.6 dB at the old defaults). The guide's attribute table says so.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* chore(core): trim tier.ts comments to the ratchet
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* chore: allow deleting the Studio previewMotionBlur render test
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* feat(studio): add a preview seek bar
* fix(studio): preserve preview height with the seek bar
* fix(studio): keep the preview seek thumb fully visible
* fix(cli): check copies hostile videos at the composition size, not the source size
* fix(cli): the check server serves the copy the page names with hf-proxy-box
* feat(cli): check --prepare-media makes the video copies alone, and a stopped copy resumes
A long source is copied in one-minute pieces that stay in the cache, so a copy
that is killed or runs out of time continues from its finished pieces.
check --prepare-media runs only that step: no browser, no report, a per-file
result as JSON, and exit 1 when a copy failed.
* fix(studio-server): keep finished copy pieces while their copy runs
The short limit for dead partial copies would delete the first pieces of a
long copy that is still encoding. Finished pieces now follow their own
one-hour limit and are never swept while their copy is in flight.
* refactor(studio-server): shorten two comments
The comment gate limits a comment line to 120 characters and a run to four lines.
* refactor(studio-server): drop comments the names already carry
The comment ratchet lets a file's comment share only go down.
* fix(cli): the check server pre-warms the copy the page asks for, not the source-size one
The server started a source-size copy of every hostile video next to Chrome on
each check, because its pre-warm passed no box while the page and the up-front
copy use the composition's box. The pre-warm now takes the same box, found by
the one helper the up-front copy uses.
* fix(cli): end a check on no progress, not on a 120 s wall clock
The check ended 120 s after Chrome was ready no matter what it was doing, so a
long project whose sampling and overlap pass each kept working still failed
(the overlap pass was one page call that reported nothing for its whole run).
The deadline is now an idle clock: every phase entered, every sample finished,
every overlap batch of eight times and every operation that settles restarts it,
and the check ends only after 120 s with none. The overlap grid is asked for in
batches so it can report between them.
* refactor(cli): shorten the idle deadline comment
The comment gate allows 120 characters on a comment line.
* test(cli): check's overlap grid runs in page tasks of at most 8 samples
* fix(cli): check test types for the cli lib, studio-server size budget for resumable copies
* feat(aws-lambda): price arm64 chunk invocations at the arm64 rate
getRenderProgress takes chunkArchitecture, the architecture of the function
that renders chunks. RenderChunk invocations are priced at its per GB-second
rate, both inline and from a Distributed Map's output; plan, audio and
assemble stay at the x86 rate.
* feat(cli): render chunks on an arm64 function with lambda deploy --video-arch
--video-arch arm64 pushes the arm64 video function image to the stack's own
ECR repository and deploys the template with VideoImageUri set to its digest.
Outside a checkout the image is the one the installed adapter pins; inside a
checkout it must come from HYPERFRAMES_LAMBDA_VIDEO_IMAGE, built from that
checkout. The default stays x86_64, which always sends an empty VideoImageUri
so a redeploy drops a video function rather than keeping it.
destroy deletes the repository, render and progress price chunks at the arm64
rate, and policies lists the ECR actions.
* fix(cli): push the video image only to an ECR repository this stack tagged
* fix(cli): price the plan at the video function's rate now that it runs there
* feat(cli): lambda deploy renders on arm64 by default; --video-arch x86_64 keeps x86
* refactor(cli): drop two doc comments the names already carry
* fix(cli): preserve video frames when scenes reuse element IDs
* chore(core): keep media identity comments within the ratchet
* test(core): update page-build goldens for distinct media ids across repeated scenes
* docs: guide and skill note for opt-in capture motion blur
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* docs(motion-blur): scope the first-frame guarantee and the Chrome no-flag claim
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* fix: data-volume multiplies the volume lane in preview and render
* fix: a clip's data-volume plays ahead of its audio effects, in preview and render
* feat(studio): the media panel shows a clip's Gain beside its Volume level
* fix(audio): cap gain times volume lanes through each ramp
* chore(core): account for shared volume envelopes in package budget
* fix(core): restore static gain when a playing lane is removed
* feat(cli): open scaffolded agent instructions with what hyperframes is
Agents asked to make a video choose from what is on disk. The AGENTS.md and
CLAUDE.md that init writes now open with a plain statement of what the project
is and that `hyperframes render` replaces a hand-built headless-browser and
ffmpeg pipeline, and list `snapshot` beside preview, check, render and docs.
A test pins that init writes both files from the template, and the CLI docs
now say init creates them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: describe the npm packages in plain words
npm search ranks on description and keywords. The hyperframes package now says
what it does ("Make videos with code and AI agents: write HTML, render MP4.
Open source.") and lists the words people and agents search for. Core and
studio had empty descriptions; producer and player gain keywords too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(readme): give coding agents a one-line start
The opening paragraph said what HyperFrames is but not how an agent starts.
Add one line: install the skills, then ask the agent for a video.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cli): keep the scaffolded agent intro to what the folder is
Inside a scaffolded project the agent already uses the CLI, so telling it not to build its own
capture pipeline there adds nothing. The intro now only says what the folder is.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: keep npm metadata to the CLI package
Internal packages are not searched on npm, and the init test only
re-checked the template's own text.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: context7.json so agents get the docs and the composition rules
Indexes docs, skills, registry and examples only (no test fixtures),
and hands agents five rules from AGENTS.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* docs(cli): document media-use and usage commands
Both command groups are registered and visible but had no section in the CLI reference.
- media-use: subcommands, resolve flags, the per-type source order, where files land,
which sources need a HeyGen sign-in or can cost money, and telemetry.
- usage: flags, the known and unknown result shapes, which logins it reads, and that it
sends no telemetry.
- Add both to the "Find your command" table.
The from, reuse, and params subcommands cannot take their value in this release, so the
page points to the working resolve --from, --reuse, and --params forms instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(cli): drop the media-use bug workaround note
The bugs go to the media-use owner instead of living in the docs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(cli): list every command in the finder, and check it in CI
A ~20-line check fails the docs workflow when a CLI command is missing
from "Find your command". On main it finds media-use, usage, models,
clean and events. AGENTS.md and CLAUDE.md ask agents to ship docs with
the change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: format the docs command check
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* docs: install the Studio app on Linux from the .deb, list models and clean
The download page hands Linux browsers the .deb by default
(demo-next studio/download/route.ts), so the steps now match it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: leave the finder rows to the media-use docs PR
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: use the file names the linux download actually gives
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The landing page and hyperframes.dev are tracked; the docs are not, so
AI-chat referrals and docs-to-download paths are invisible. Session
recording stays off.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>