Commit Graph
5871 Commits
Author SHA1 Message Date
Miguel Ángel bd4cae7e35 fix(engine): an opaque ProRes clip extracts to jpg frames, only ProRes with alpha stays png (#6130)
* fix(engine): an opaque ProRes clip extracts to jpg frames, only ProRes with alpha stays png

ProRes was always cached as lossless PNG in case a missed tag hid alpha. ProRes alpha shows in its pixel format (yuva444p), so the guess only costs size: a 4K 4:2:2 clip wrote about 17 MB a frame, 18 GB for 36 s. VP8 and VP9 keep PNG because their alpha rides a side channel ffprobe can miss.

* test(engine): ProRes extraction format follows the alpha plane

* chore(engine): format the ProRes extraction change
2026-10-23 14:14:06 +00:00
Miguel Ángel 132a504b69 fix(engine): encode with the same x264 and x265 thread count on any host size (#6127)
* fix(engine): encode with the same x264 and x265 thread count on any host size

libx264 and libx265 pick their thread count from the host core count when
ffmpeg is not told one, and the bitstream depends on it, so the same frames
encoded to different bytes on 8, 16 and 32 vCPU nodes and chunks of one
render could differ. Both encoders now pass the thread count from the CPU
quota (Node reads the container limit), which is fixed per pod.

* chore(engine): raise the packed size budget for the encoder thread module
2026-10-23 14:13:57 +00:00
Miguel Ángel 2ed882ccf2 fix(studio-server): the history lock works on drives without hard links (#6125)
* fix(studio-server): the history lock works on drives without hard links

Taking the owner lock links a prepared file into place. exFAT and some network drives refuse hard links (ENOTSUP, EPERM), so the claim threw and the project history could not open. A refused link now falls back to creating the lock exclusively. A reader treats a just-created empty lock as being taken, and clears one a crashed claimant left behind after two seconds.

* test(studio-server): run the owner lock tests where node:fs can be stubbed

* fix(studio-server): the evict lock also waits out a claimant's empty file

The evict lock takes the same exclusive-create fallback as the owner lock, so it can be empty for a moment too. One deadHolder check now decides a holder is gone at all three sites: owner, evictor and the lock itself.

* chore(studio-server): trim comments on the owner lock

* test(studio-server): an empty lock is taken over once it is old, not while being written

* chore(studio-server): shorten the claim comment
2026-10-23 12:32:47 +00:00
Miguel Ángel 3cdae3804e fix(engine): mix any number of audio clips by summing them in stages (#6120)
One ffmpeg graph held every clip of a group (or of the whole film) as its own
input, so a long project ran into the open-file and input limits and the
export failed. Past 96 clips the mixer now folds slices into one running
float sum, with no cap on the total; mixes of 96 clips or fewer take the same
single-graph path as before.

A mix process now also gets a deadline that grows with the film length, and a
failed ffmpeg run keeps how long it ran and the last lines of its stderr.
2026-10-23 12:09:39 +00:00
Miguel Ángel 3badc9bfa5 chore: release v0.8.188 (#6122) v0.8.188 2026-10-23 09:53:45 +00:00
Miguel Ángel c4c1e621d4 fix(producer): a blank media src is no source instead of the page itself (#6121)
* fix(producer): a blank media src is no source instead of the page itself

A video with src="" reads back from the browser as the composition page URL. The probe then treated index.html as its media file and failed the whole render with 'media sources are text documents'. A blank own src with no <source> child now reports no source.

* style(producer): format the blank-src test
2026-10-23 09:12:40 +00:00
Miguel Ángel 401d0655fb fix(aws-lambda): keep the arm64 image staging script out of the published package (#6118)
* fix(aws-lambda): keep the arm64 image staging script out of the published package

stage-arm64-image.ts is run from a checkout by the image workflow and the publish job, and nothing in dist or the CLI imports it. With the release's prebuilt/ files added, aws-lambda measured 73484 bytes packed and 267013 unpacked in the publish job, over its budgets of 73369 and 266805, so v0.8.187 did not publish.

* ci: the packed-manifest check pins stand-in Lambda assets, like the publish job

The publish job adds prebuilt/handler-zip.json and prebuilt/video-image.json before verify:packed-manifests; the PR check did not, so a package could pass on the PR and fail at publish. The verifier now runs the same pin script on sparse stand-ins of release size when no pins exist, and removes them afterwards. It lives in the verifier, not a Build step, so the edit-accuracy input closure stays unchanged.
2026-10-23 08:52:34 +00:00
Miguel Ángel b6de25391a fix(runtime): a composition script that shadows console no longer breaks the render runtime (#6119)
A script with a top-level const console = ... hides the global from every runtime call to console.info/warn. The runtime build now maps console to globalThis.console.
2026-10-23 07:53:26 +00:00
Miguel Ángel aeecf38345 fix(producer): long renders with small frames no longer fail the up-front disk estimate (#6117)
* fix(producer): long renders with small frames no longer fail the up-front disk estimate

The pre-capture check priced PNG frames as raw RGBA, so a long, mostly transparent overlay was refused for needing hundreds of GB it would never write. The measured projection after the first frames already stops a render that cannot fit, using real frame sizes, so the estimate no longer throws.

* fix(producer): drop the comment the ratchet counts

* fix(producer): trim comments so the file's comment share does not rise
2026-10-23 07:52:35 +00:00
Miguel Ángel 69738b7ce4 fix(engine): render into a folder whose name holds a percent sign (#6116)
* fix(engine): render into a folder whose name holds a percent sign

ffmpeg reads an image sequence path as a printf template, so a folder like
"12% Up" was parsed as a format code and every video render failed. The
folder part of each frame-sequence path now goes through one helper that
doubles the percent sign.

* fix(engine): drop the helper doc line the comment ratchet rejects
2026-10-23 07:33:25 +00:00
Miguel Ángel d1aeb31bf4 fix(lint): tell an agent where to move a video nested in a timed wrapper (#6113)
* fix(lint): tell an agent where to move a video nested in a timed wrapper

The missing-start hint said to add data-start="0" even when the video sat
inside a timed wrapper, which then trips the never-both rule. The hint now
names the wrapper and its start, and following it lints clean.

* fix(lint): hint the innermost timed wrapper of a nested video

The hint used the outermost timed ancestor, so scene > clip > video told the
agent the scene timing. It now takes the innermost enclosing timed element,
counts nesting depth so a closed sibling no longer hides its parent, omits the
duration when the wrapper has none, and leaves audio on the plain hint.

* fix(lint): a closed timed sibling no longer counts as a wrapper of the next video

The nesting check compared how many closing tags sat between a timed element
and a video with how many same-name opening tags did, ignoring order, so an
unrelated later sibling cancelled the close. It now walks them in document
order and stops when the element closes.
2026-10-23 06:42:06 +00:00
Miguel Ángel 6fe83060d9 chore: release v0.8.187 (#6115) v0.8.187 2026-10-23 06:32:30 +00:00
Miguel Ángel 504ec2b307 feat(cli): lambda deploy renders on arm64 by default; --video-arch x86_64 keeps x86 (#6073)
* 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
2026-10-23 05:45:49 +00:00
Vance IngallsandClaude Sonnet 5.5 e85f56e86c fix(core): capture blur strobing, backdrop box, glow drop-out and callback motion (#6106)
* fix(core): capture blur sizes its taps to the smear and weights them exactly

A fast move strobed at the default 16 taps (8 px steps on a 1560 px whip). With no
data-motion-blur-samples set, taps are now about one per 2 px of travel (2 to 128); an
explicit samples count still wins.

Canvas quantizes image globalAlpha to 1/255, so 1/n weights left coverage short (n = 104
summed to 0.81, a lighter card body). Each tap now carries a whole number of 1/255 units
that sum to exactly 255.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* feat(core): capture blur draws the movers from their own transparent layer

The crop came from a capture of the whole scene, so the backdrop under a see-through mover
smeared with it (a lighter box with the dotted background erased) and a glow or shadow
outside the mover's box was cut off, leaving a hard-edged box.

Each frame now captures the movers alone, everything else visibility:hidden, so a mover's
pixels carry their true alpha and no backdrop; the background capture is unchanged. The crop
grows by the mover's ink reach (box-shadow, text-shadow, filter, outline, measured during the
scan), so glows travel with it. Two paints per frame, as before.

The output is cleared on wrap instead of showing the previous wrap's last frame, since the
first paint is no longer a drawable sharp frame. Core's unpacked size budget goes to 3,950,000
for the new module.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(core): capture blur finds callback-driven movers when events are on

The mover scan seeked with callbacks suppressed even where the root allows them, so a
composition whose motion lives in a timeline callback (a render(t) driven from onUpdate)
reported 0 movers and rendered sharp. With data-motion-blur-events="on" the scan now seeks
the way the frame reads do. Without it nothing changes: callbacks stay suppressed.

The no-movers finding in hyperframes check now names the attribute.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 22:40:57 -07:00
Miguel Ángel 784e1d01d9 test(cli): process tests stop owning old processes that carry a reused parent pid on Windows (#6111)
* test(cli): process tests stop owning old processes that carry a reused parent pid on Windows

* test(cli): split the process listing parser out of the table builder
2026-10-23 04:37:09 +00:00
Miguel Ángel 0df088926e feat(aws-lambda): push a prebuilt image to ECR without Docker (#6063)
* feat(aws-lambda): push a prebuilt image to ECR without Docker

Adds pushImageToEcr and ensureEcrRepository to the SDK subpath. The push
reads a single-platform OCI image layout, verifies every blob against its
descriptor before any ECR call, uploads only the blobs ECR lacks through
the layer-upload API, and puts the manifest under a tag, returning the
digest-pinned image URI.

* fix(aws-lambda): keep the ECR client out of the SDK bundle

Like the other AWS SDK clients, @aws-sdk/client-ecr is a dependency the consumer
resolves. Bundled into the ESM SDK it hits a dynamic require of node:https and
the packed package fails to import.

* feat(aws-lambda): build the ECR client from a region like the other SDK calls

* build(aws-lambda): add only the ECR client to the lockfile

* fix(aws-lambda): adopt an existing ECR repository only when it carries the caller's tags

* chore(aws-lambda): raise the size budget for pushing an image to ECR

pushImageToEcr ships in dist (unminified chunk plus its .d.ts); no source maps, tests or release-only files are involved. Built dist, npm pack --dry-run, main versus main plus this branch: +2486 B packed, +8846 B unpacked. The merge-group run measured 73369 packed and 266805 unpacked, which are the new budgets (were 70874 and 258166).
2026-10-23 04:35:25 +00:00
Miguel Ángel 0255493913 fix(core): a scene paints no filter output from an HTML layer before its start or after its end (#6097)
* fix(core): a scene paints no filter output from an HTML layer before its start or after its end

* fix(core): a scene paints no filter output from its pseudo-element layers outside its window
2026-10-23 04:12:55 +00:00
Miguel Ángel 8d562a3d91 feat(aws-lambda): attach the arm64 video image to releases and pin it (#6070)
* feat(aws-lambda): attach the arm64 video image to releases and pin it

The release builds the arm64 video function image from the handler ZIP it
attaches, attaches it as an OCI layout tarball with its sha256, and pins it
in prebuilt/video-image.json, read through prebuiltVideoImage(). A retried
release reuses the image already attached.

* fix(aws-lambda): keep the release pin script out of the published package

pin-handler-zip.ts is run from a checkout by publish.yml; nothing in dist or the CLI imports it. Leaving it out keeps aws-lambda under its size budget with the video image reader added.
2026-10-23 03:52:35 +00:00
Miguel Ángel f6cbf87cdd feat(aws-lambda): arm64 video function image from the handler ZIP (#6064)
* feat(aws-lambda): arm64 video function image from the handler ZIP

The image is the release handler ZIP with its x86 ffmpeg and Chrome swapped for
the native ffmpeg tree and the sha256-pinned Sparticuz arm64 Chrome pack, so the
x86 and arm64 functions run the same handler code. The image stage only copies,
so any host builds it. CI builds it and runs ffmpeg, a real Chrome render and the
Lambda runtime on an ARM runner.

* fix(aws-lambda): launch Chrome in the image smoke the way Lambda does

@sparticuz/chromium inflates its AL2023 libraries only when AWS_EXECUTION_ENV
names a Node runtime; Lambda sets it, a bare docker run does not. The workflow
also runs on @sparticuz/chromium bumps and handler ZIP layout changes, which
re-stage the image.

* fix(aws-lambda): smoke the arm64 image through its own Lambda runtime

The smoke is now a handler invoked through the image's entrypoint, whose
bootstrap sets AWS_EXECUTION_ENV the way Lambda does, so @sparticuz/chromium
takes its Lambda branch with nothing set by hand. It returns the value it saw.

* fix(aws-lambda): agree the move of the ffmpeg build workflow into the image workflow

* fix(aws-lambda): build the Chrome pack URL from the pin and hand the checked pack to tar in memory
2026-10-23 02:41:18 +00:00
Miguel Ángel 821003b112 test(studio): retain Chrome launch diagnostics (#6077)
* test(studio): retain Chrome launch diagnostics

* fix(studio): read Chrome's version from the file on Windows instead of running it

* fix(studio): shorten the Chrome version probe
2026-10-23 01:55:52 +00:00
Miguel Ángel 1accb709ff fix(engine): hundreds of effects in one audio group mix in time, and a mix timeout is named (#6101)
* fix(engine): hundreds of effects in one audio group mix in time, and a mix timeout is named

* refactor(engine): name the group mix's single pad instead of commenting it
2026-10-23 01:55:23 +00:00
Miguel Ángel f5f884e33d fix(aws-lambda): make webm and mov audio in the separate audio task like mp4 (#6098)
* fix(aws-lambda): make webm and mov audio in the separate audio task like mp4

A WebM or MOV plan mixed and encoded its own audio, so on a stack whose plan runs on an arm64 function the audio came out of a different ffmpeg build than an x86 render's. The plan now leaves that audio to the separate audio task, as mp4 already does, and the assembler joins the chunks with that file. Only mp4 chunks stitch; cfr and png-sequence keep their audio in the plan.

* test(aws-lambda): join mov chunks with the audio task's track too

* refactor(producer): keep the separate-audio gate's one-line doc comment
2026-10-23 01:55:02 +00:00
Miguel Ángel 03ed14615a feat(aws-lambda): run chunks on an optional arm64 image function (#6065)
* feat(aws-lambda): run chunks on an optional arm64 image function

A new VideoImageUri parameter adds an arm64 container-image function that only
renders chunks. Plan, audio and assemble stay on the x86 ZIP function, so audio
encodes are unchanged. Empty (the default) deploys exactly as before. The
reserved concurrency moves to whichever function renders the chunks.

* docs(aws-lambda): the template tags both render functions

* fix(aws-lambda): nest the arm64 video function so sam deploy needs no image repository

sam deploy refuses a template with any top-level image function unless it is given an image
repository, even when that function's Condition is false, so every deploy of the template failed.
The video function now lives in video-function.yaml, a nested stack created only when
VideoImageUri is set. The release ships it beside template.yaml and the CLI stages both.

A new workflow runs the CLI's sam deploy argv against the template with fake credentials and
requires it to reach the first upload.

* fix(aws-lambda): run the plan on the arm64 video function with the chunks it plans

* refactor(cli): name the staged template directory instead of commenting it

* docs(aws-lambda): say the arm64 image runs the plan as well as the chunks
2026-10-23 00:40:55 +00:00
Miguel Ángel 1d0a18c814 ci(windows): fail a hung engine-cli test step at its deadline and name the stuck process (#6100)
* ci(windows): fail a hung test step at its deadline and name the process that hung

* ci(windows): upload the test step log even when the step is killed
2026-10-23 00:36:08 +00:00
Miguel Ángel bb19f342d3 build(aws-lambda): pinned native ffmpeg build for an arm64 Lambda image (#6062)
* build(aws-lambda): pinned native ffmpeg build for an arm64 Lambda image

One recipe, run per architecture on the Lambda Node 22 base it ships on. Codec
libraries link statically; glibc and GnuTLS stay dynamic, with the two libraries
the bare base lacks bundled beside the binaries. A check stage on the bare base
proves every encoder, decoder, filter and protocol the engine calls, and the
artifact cannot be produced without it. CI builds it on two ARM runners and
requires byte-identical tarballs.

* fix(aws-lambda): link GnuTLS dynamically in the arm64 ffmpeg build

With --static pkg-config flags, gnutls.pc names a libgmp.a from its own RPM build
tree and configure rejected GnuTLS. The codec libraries exist only as static
archives, so they still link statically. The recipe moves to image/, which will
also hold the video function image stage.

* fix(aws-lambda): build x265 for arm64 with the base image compiler

x265 builds its SVE2 kernels with -march=armv9-a, which gcc 11 rejects. Turn
them off, and stop a failed x265 build from reaching ffmpeg configure as a
misleading "x265 not found".

* fix(aws-lambda): pin x264 to the revision the x86 ffmpeg uses

The x86 ffmpeg-static 7.0.2 encodes with x264 r3191 (4613ac3); match it.

* fix(aws-lambda): 10-bit x265 in the arm64 ffmpeg, checked by output format

x265 now builds the 10-bit library and links it into the 8-bit one, so HDR
renders get yuv420p10le instead of a silent 8-bit fallback. The check asserts
the encoded pixel format rather than a successful command, and its ffprobe calls
terminate options with -- like every other caller.
2026-10-23 00:13:50 +00:00
Miguel Ángel 6225271173 fix: preserve motion blur off through cloud render requests (#6087)
* fix: preserve motion blur off through cloud render requests

* fix: keep generated blur docs concise and format examples

* fix: freeze motion blur intent for distributed render workers
2026-10-22 23:54:54 +00:00
Miguel Ángel da6b77bd84 fix(cli): preserve video frames when scenes reuse element IDs (#6095)
* 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
2026-10-22 23:23:17 +00:00
Miguel Ángel 9da107aef5 fix(audio): fit PCM to video frames before AAC delivery (#6089)
* fix(audio): fit PCM to video frames before AAC delivery

* fix(audio): migrate the CLI diagnostic stage fixture

* fix(test): measure the whole unscaled audio residual

* test(audio): refresh the speed-ramp delivery golden
2026-10-22 23:12:56 +00:00
Miguel Ángel aa4b535334 fix(engine): publish video frames only after decoding (#6092) 2026-10-22 22:35:17 +00:00
Vance IngallsandClaude Sonnet 5.5 4a788583f6 docs: guide and skill note for opt-in capture motion blur (#6049)
* 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>
2026-10-22 22:20:21 +00:00
James Russo 1cf4975d2f fix(parsers): preserve Unicode offsets when stamping IDs (#6079) 2026-10-22 21:31:43 +00:00
Miguel Ángel 36c4a9fd80 fix: exclude base-marked generated files from comment checks (#6091) 2026-10-22 21:18:17 +00:00
Miguel Ángel 807803a452 chore: mark cloud SDK output as generated (#6088) 2026-10-22 20:28:52 +00:00
Miguel Ángel 77394fe9e5 fix(aws-lambda): retry a file upload after a dropped connection (#6082)
* fix(aws-lambda): retry a file upload after a dropped connection

* fix(aws-lambda): keep retrying an S3 request timeout
2026-10-22 20:21:55 +00:00
Miguel Ángel a8ac55dc30 fix: data-volume multiplies the volume lane in preview and render (#6068)
* 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
2026-10-22 20:12:49 +00:00
Miguel Ángel 27b9f68506 fix(ci): pin and reuse the docs validation CLI (#6080)
* fix(ci): pin and reuse the docs validation CLI

* fix(ci): pin and reuse the docs validation CLI
2026-10-22 19:43:26 +00:00
Miguel Ángel 10c724bf55 feat(cli): preserve page motion blur off in local renders (#6081) 2026-10-22 19:30:16 +00:00
Ular KimsanovandClaude Opus 5.5 3d67fb9d10 chore: help agents find hyperframes on npm and context7 (#5937)
* 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>
2026-10-22 19:04:48 +00:00
Miguel Ángel b3f5869035 fix(hooks): run the checkout's own oxfmt, oxlint and tsc instead of bunx (#5751) 2026-10-22 18:53:34 +00:00
Ular KimsanovandClaude Opus 5.5 1b1a576d52 docs(cli): document every command, and check it in CI (#5938)
* 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>
2026-10-22 18:45:53 +00:00
Miguel Ángel 3dd9f51785 test(studio): sample gesture replay from one preview state (#6076) 2026-10-22 18:32:51 +00:00
Ular KimsanovandClaude Opus 5.5 29643c7c8a docs: install the Studio app on Linux from the .deb (#5946)
* 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>
2026-10-22 17:34:13 +00:00
Miguel Ángel 609ff5a7c0 fix(studio): the edit-accuracy gate says the shards did not run, not that accuracy fell (#6069)
With no shard results, ratchet.mjs threw, wrote no report, and the workflow
printed "Edit accuracy fell against the base branch" for what was a build or
shard failure. A shard that did not report was also counted as a drop. The
gate now exits 2 with "Edit accuracy did not run: N of M shards reported
results" when nothing that ran fell, writes its comment and report in that
case too, and the workflow prints the gate's own verdict.
2026-10-22 17:24:43 +00:00
Ular KimsanovandClaude Opus 5.5 32ab255f61 docs: send docs pageviews to the HyperFrames PostHog project (#5948)
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>
2026-10-22 17:11:15 +00:00
Miguel Ángel bbf9f8ffd0 chore: release v0.8.186 (#6072) v0.8.186 2026-10-22 16:54:16 +00:00
Miguel Ángel a93271df78 test(cli): run skill one-liner tests without a shell per line (#6071) 2026-10-22 16:54:03 +00:00
Miguel Ángel 934c88bac8 fix(cli): history lists its entries even when this run cannot write the history (#6061)
* fix(cli): history lists its entries even when this run cannot write the history

history --json, show and the other read-only subcommands open the history as
its owner, which writes a lock and files pending changes. On a full disk or an
unwritable cache folder that write failed the whole read. A read now falls back
to the history as last recorded and says why on stderr; undo, restore and other
writes still fail.

* fix(cli): history falls back only when it could not write, not when it could not read

* fix(cli): history reads past a log it may read but not append to
2026-10-22 15:34:37 +00:00
Miguel Ángel 86b90bb424 fix(cli): init --video frames the project to the clip's shape, so nothing is cropped (#5984)
* fix(cli): a portrait clip passed to init --video makes a portrait project

* fix(cli): keep init's comment share and the skill's citations within the checks

* feat(cli): init --video snaps the frame to 9:16, 4:5 or 1:1 so a phone clip shows whole

* fix(cli): init --video frames a non-square-pixel clip by the shape it plays at

* fix(cli): init --video frames the project to the clip's own shape, so the whole picture shows

* fix(cli): keep init's comment share at its base

* test(cli): drop the ratio check of the retired talking-head skill
2026-10-22 15:28:24 +00:00
Miguel Ángel cfff4493df fix(core): a clip's volume lane stays smooth in preview while the page is busy (#6057)
* fix(core): a clip's volume lane stays smooth in preview while the page is busy

A clip with a volume automation lane had two writers on one gain in
preview: the Web Audio transport scheduled the lane as ramps on the
clip's gain, and the per-tick media sync wrote the same lane's value onto
that gain about 60 times a second. Each write landed whenever the main
thread got to it, so a busy page stepped the gain and the clip sounded
choppy. The lane now has its own gain node, like a group's fader beside
its mute gain, and the per-tick volume of a routed clip no longer folds
the lane in.

* fix(core): name the transport's ownership of a routed clip's lane instead of commenting it

* chore(core): raise the unpacked size budget for the volume lane's own gain

The preview fix gives a clip's volume lane its own gain node and tears it
down with the clip, which takes core to 3935950 bytes unpacked, 283 over
the budget main set at its exact size.

* fix(core): volume lanes follow rate changes and edits mid-play

* fix(core): shorten the clip stages comment

* fix(core): point the volume lane comments at the code they name
2026-10-22 15:12:46 +00:00
Miguel Ángel 2ef60f3f26 fix(cli): a check that runs out of time says which step it was in and how long each took (#6060)
* fix(cli): a check that runs out of time says which step it was in and how long each took

When check hits its 120 s deadline, the error now names the step it was in
(loading the page, waiting for it to be ready, checking samples, the overlap
pass, finding crops) and the seconds each step took, including the video
copies and Chrome start that happen before the deadline starts.

* fix(cli): drop two comments the names already say
2026-10-22 14:22:01 +00:00