Commit Graph
6715 Commits
Author SHA1 Message Date
Miguel Angel Simon Sierra 62916ad7ac fix(lint): the nested-video hint keeps timing on the video, and docs and hint are pinned 2026-11-03 18:47:02 -05:00
Miguel Angel Simon Sierra a06f04e87c fix(skills): say a video carries its own data-start, not its wrapper 2026-11-03 18:33:12 -05:00
Miguel Ángel e2edc93f5f fix(producer): a laptop that sleeps mid-render no longer counts the sleep as a capture stall (#7096)
* fix(producer): a laptop that sleeps mid-render no longer counts the sleep as a capture stall

* style(producer): format the stall watchdog timers
2026-11-03 23:11:32 +00:00
Miguel Ángel 3dc82f18e3 fix(producer): a stalled capture resumes at the first unwritten frame, not frame 0 (#7104)
* fix(producer): a stalled capture resumes at the first unwritten frame instead of frame 0

* fix(producer): a page that keeps stalling falls back after three resumes instead of resuming forever
2026-11-03 22:25:52 +00:00
Miguel Ángel 9304d73ec8 test(skills): core-skills test matches the reverse start wording (#7114) 2026-11-03 22:14:13 +00:00
WaterrrForever 341fdd353c docs(skills): reverse-any-video runs sign-in and payment itself and opens the result (#7101)
* docs(skills): reverse-any-video runs sign-in and payment itself and opens the result

From Wenbo's end-to-end reverse test (F1, F2, F8, F9, F12, F13):
- the person types nothing: the agent runs auth login, billing subscribe and
  billing top-up itself and gives each page as a clickable link
- never sign in with an API key to get past Pro
- reverse start's plan is final; auth status is read only for a null plan,
  and its hyperframes field, never user.subscription
- an old CLI without reverse start: run this run as npx -y hyperframes@latest
- hand over: side by side from diff --sbs, Studio preview, Framey line
- animated shots: cut the guide inside a dissolve, retime each generated shot

* docs(skills): reverse sign-in names --device, reads auth status --json, trims dissolve frames

Rames's three wording notes on #7101, and the old-CLI subscribe line now
applies only to a plugin's pinned CLI, beside main's null upgrade_url rule.

* docs(skills): a plugin whose CLI can't reverse stops before payment

Jerrai on #7101: the plugin fallback sent the person to subscribe when the
pinned CLI has no reverse start, so the run could not go on after paying.
It now stops and says the plugin needs updating.
2026-11-03 20:05:22 +00:00
Miguel Ángel 3aaed65ef6 fix(check): the analysis restarts the idle window with every call it makes (#6919)
* fix(check): the analysis restarts the idle window with every call it makes

* test(check): runAuditGrid's analysis must use the progress-reporting driver
2026-11-03 19:47:13 +00:00
Miguel Ángel 3a28ef41ae perf(studio): a long film's media durations write the store once per file, not once per clip (#6745)
* fix(studio): a film that cuts one file into many clips plays smoothly while their durations load

* test(studio): the metadata test counts one store write per file
2026-11-03 18:54:17 +00:00
Wenbo ZhuandClaude Opus 5.5 a5a6121332 fix(cli): don't invent a purchase link when the server withholds upgrade_url (#7031)
reverse/start answers upgrade_url: null when no plan can be bought right
now. The CLI treated that like a missing field and built its own plans
link, so a Free account under gate "block" was sent to a page where it
can't buy. Now null means no link anywhere: the JSON prints
upgrade_url: null and subscribe_command: null (billing subscribe would
open that same plans page), the refusal says a plan can't be purchased
right now instead of naming the subscribe command, and the skill runs
nothing and passes on no link. Only an absent field (an older server)
falls back to the plans page; a string is used as is.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 16:47:05 +00:00
WaterrrForeverandClaude Opus 5.5 faae6017dd refactor(cli): templates pull unpacks the verified pack from memory (#7084)
The pack was written to a temporary file before tar read it. tar now
reads the checked bytes on stdin, so nothing downloaded is written to
disk before it is unpacked.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 16:25:14 +00:00
WaterrrForever 12ce8c2ffd chore: release v0.9.9 (#7095) v0.9.9 2026-11-03 11:28:41 -05:00
Miguel Ángel 1071ff35a7 docs: point the Discord links at the new community server (#7097) 2026-11-03 10:44:08 -05:00
Miguel Ángel 67d11c0a5c fix(engine): a script the page cancelled is not a failed load (#7093) 2026-11-03 15:00:39 +00:00
Miguel Ángel fc006f713b fix(studio-server): a render that ran over 5 minutes can still be read after it finishes (#7087)
* fix(studio-server): a render that ran over 5 minutes can still be read after it finishes

* fix(studio-server): keep the finished-jobs helper's reasoning in its names
2026-11-03 14:22:36 +00:00
Miguel Ángel 4ceec0171f perf(studio-server): preview steps skip the page parse when a tag scan answers (#7092)
* test(studio-server): a stamped preview build parses its page once

* perf(studio-server): preview steps skip the page parse when a tag scan answers
2026-11-03 14:16:22 +00:00
Miguel Ángel dec465949b feat(engine): a script-load failure names where the script came from and why it failed (#7088)
* feat(engine): a script-load failure names where the script came from and why it failed

* fix(engine): keep the script-load cause helpers private and within the engine size budget
2026-11-03 13:54:20 +00:00
Wenbo ZhuandClaude Opus 5.5 b2acef5869 fix(cli): no auto-update across 0.x minors; install skills at the CLI's release tag (#7013)
* fix(cli): no auto-update across 0.x minors; install skills at the CLI's release tag

- autoUpdate: before 1.0 a minor bump counts as a major one, so 0.8.x -> 0.9.x
  is a notice, not a silent background install. From 1.0 on, the major alone.
- skills: `skills update` / bare `skills` / `init` install from
  heygen-com/hyperframes#v<VERSION>, and `skills check` plus the background
  freshness nudge read the manifest at the same tag. A build the repo has no
  tag for (dev build) falls back to main, as before.
- skills: run the upstream installer as `npx skills@1.7.4` instead of an
  unpinned `npx skills`.

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

* fix(cli): keep the comment share of the touched files from rising

Comment ratchet: trim the comments added in the previous commit. No code change.

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

* fix(cli): pass the CLI version into the skills check instead of importing it

scripts/clawhub-unlist-retired.mjs loads skillsManifest.ts from source under
plain node, which cannot resolve a relative `../version.js` import. Callers now
pass `cliVersion` (and skillsSourceRef takes it as an argument), so the module
keeps importing only node builtins.

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

* fix(cli): read skills at the CLI's tag without a probe; pin skills@1.5.13

- A release build reads the manifest at its own tag directly (publish pushes
  the tag before npm publish). Only a 404 for that manifest falls back to main;
  a timeout, missing git or proxy error now surfaces instead of quietly
  comparing against main, so the background nudge can't cache a false
  "outdated" count.
- checkSkills returns the ref it read, and skills update installs from that
  same ref, so check and install can't disagree within one run.
- Pin skills@1.5.13 (it parses `#<ref>` too) so the pin matches the version
  agentDirs.generated.ts and the lock-path notes were checked against.

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

* refactor(cli): split the tag and main manifest fetches

Fallow flagged fetchRemoteManifest's CRAP score (31.6 > 30). The tag fetch
(404 is the only fallback to main) and the SHA-pinned main fetch are now their
own functions. No behaviour change.

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

* fix(cli): never auto-upgrade a Homebrew install

`brew upgrade hyperframes` installs whatever formula the tap holds, so a
background run scheduled for an allowed patch could still cross a 0.x minor.
Homebrew installs now only get the update notice naming `brew upgrade`.
A new test drives the scheduler through the real installer detection and
installer script: no spawn on Homebrew, a versioned npm install for a patch.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 13:21:39 +00:00
Miguel Ángel 35753f3821 perf(parsers): ensureHfIds skips the parse when every element already has its id (#7069)
* test(parsers): a stamped document needs no parse to keep its ids

* perf(parsers): ensureHfIds skips the parse when every element already has its id

* fix(parsers): a fragment checks every tag, a stray body tag included

* fix(parsers): keep the parse for a page not opening head then body

* refactor(parsers): split the head check out of the page shape check

* fix(parsers): find the head end tag without stripping comments
2026-11-03 13:16:44 +00:00
Miguel Ángel 47dddedd6c fix(core): Safari audio frozen after its cut is pulled onto the playhead at 0.5 s behind, not 1 s (#7082)
* fix(core): Safari audio that sits frozen after its cut is pulled onto the playhead in 0.4 s, not 1 s

* fix(core): shorten the frozen-audio comment

* fix(core): leave a WebKit audio element that is still filling data out of the frozen rule
2026-11-03 11:17:40 +00:00
WaterrrForeverandClaude Opus 5.5 2daedcdafc feat(skills): style templates on the HyperFrames plan (#6842)
* fix(cli,skills): say a step's credits are its total, and keep cost out of retries

An out-of-credits refusal named what the step needs, and an agent read
that as the shortfall. It now says the number is the step's total.

After its last try, an agent told the person what was spent and what
another try would cost. The HeyGen reference now says not to.

* fix(cli): plan avatar credits from the HyperFrames price rows

An avatar's credits came from its old API price, about five times what
the plan charges, so --max-credits refused calls that fit and a top-up
asked for too much. They now use the Avatar IV photo row plus the
general avatar video row, 950 credits a minute.

* fix(cli): pin the avatar price test and keep pricing under the comment share

* fix(cli): plan avatar seconds on the Avatar IV row alone

The general avatar row is only checked at admission and billed on
seconds left after Avatar IV, so adding it to every second made a 15 s
script plan at 238 instead of 200 and a 220 limit refuse a call that fits.

* feat(skills): creator templates on the HyperFrames plan

A Pro account asks for a video in a creator's format and the agent pulls that
template on demand. The packs sit in the private bucket behind the plan-gated
bundle route, so a Free account gets a 402 and the upgrade step. A pull costs
no credits; making the film spends them as Reverse does.

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

* feat(skills): make creator-remix the one template skill

SKILL.md holds the catalog, the Pro openings, the pull and the credit
rules. references/remix.md is how to make the episode, from Desktop's
creator-remix with only what the app alone has swapped for the CLI.
The packs now hold only the template, so their hashes change.

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

* feat(skills): the creator-remix skill and its packs

SKILL.md holds the catalog, the Pro openings, the pull and the credit
rules. references/remix.md is how to make the episode, from Desktop's
creator-remix with only what the app alone has swapped for the CLI.
The packs now hold only the template, so their hashes change.

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

* fix(skills): word creator-remix's sign-in steps the way media-use does

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

* feat(skills): a creator-remix presenter runs on the plan by default

The person's own HeyGen avatar is recommended, not required: without
one, 小Lin's presenter is made with HeyGen Video 1 from their photo.

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

* feat(cli): pin template packs whose voice bills the plan first

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

* fix(cli): offload media named inside template tags

References in a composition's <template> were never rewritten, because the DOM
query stops at the tag and template.content does not serialize, so the file stayed
in the zip. A stem matched as a plain word and a same-named file elsewhere counted
as a mention too. A 5-minute presented film went from 196 MB to 71 MB.

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

* feat(cli): lipsync, and avatars that speak a finished voice

Video 1 takes audio as a reference and re-paces it, so a shot's lips follow its
own track and drift up to a second from the voice. generate --type lipsync redoes
the mouth to the exact voice. generate --type avatar takes --audio, and --avatar
for the person's own look, so the lips land on the voice from one job.

Also moves the plan rows to the 2026-10-30 price book, estimates a voice's credits
so --max-credits can hold it, logs jobs from a folder with no project, and describes
the resolve flags.

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

* feat(skills): presenters go avatar first, and a voice can be stock

The person's own avatar, then Avatar IV from their photo, then Video 1 with
lipsync. With no clone or recording, a stock voice named in the credits. Pins the
five rebuilt packs. The archive test keeps its ../ under GNU tar with -P.

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

* test(cli): fix avatar price and sfx provider tests, trim comments

A wav gives the avatar price test an exact length on every platform. The
sfx tests now expect HeyGen first. Comment share is back under the base.

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

* fix(core): read a font shorthand whose size nests parentheses

`font: calc(var(--size) * 1px)/1 "X"` cut at the first closing parenthesis, so a
bad family name failed the render.

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

* fix(cli): one ledger row per job, and search skips a template's own pictures

A job done at once logs one row, transcribe logs to the project, and resolve no
longer offers a component's file for a search. --reuse and --provider get help text.

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

* feat(skills): pin the tested template packs, and a board needs no voice

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

* test(cli): read the transcribe ledger row as JSON, for Windows paths

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

* chore(cli): pin the Big Questions pack without the film length check

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

* docs(skills): call them style templates, and the docs example pulls a real slug

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

* chore(cli): pin the cleaned template packs

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

* docs(skills): drop the stock-presenter ban and the no-spend-before-storyboard rule

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

* chore(cli): pin the Paper Trail and Long Story Short packs without the stock-presenter ban

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

* feat(skills): rename creator-remix to style-remix, and the five templates to names that say the look

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

* feat(skills): style-remix lists the five templates when none is named

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

* chore(cli): pin the Finance Explainer pack that varies its motion graphics

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

* feat(cli): media-use generate --type cutout takes a shot out of its background on the plan

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

* chore(cli): pin the Finance Explainer pack without the provisional variety rule

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

* chore(cli): pin the five style packs with variety rules measured on real films

Animated Science gets a worlds-and-boards budget, 3D True Crime a main board and a
brief corner note, 3D Brand caps by measured rate, Finance and Collage set pieces and
more than one look.

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

* docs(skills): media-use names the on-plan cutout and lipsync commands, not the heygen CLI ones

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

* fix(cli): cutout retries dedupe on request_id, uploads carry their real type; style-remix is public

The background-removal route dedupes on the body's request_id and ignores the Idempotency-Key
header, so a retry after a lost answer started a second job: runJob now also sends the key in the
body for such a route. Uploads typed every non-MP4 file as audio, so WebM and MOV inputs were
refused: they now take their type from the extension. Fails without the fix: the new cutout test
in generate.test.ts sees audio/mpeg for WebM and MOV.

style-remix drops metadata.internal and is listed with the other published skills.

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

* chore(cli): keep the comment share of the touched files at main's

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

* docs: count style-remix in the README and CLAUDE.md skill lists

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

* feat(skills): rename style-remix to style-sampling

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 11:07:02 +00:00
Jerrai 3f42dc1c73 feat(cli): diff --offset compares the original at t with yours at t + offset (#7057)
* feat(cli): diff --offset compares the original at t with yours at t + offset

Every per-frame measure (SSIM per frame and per cell, frames.tsv, cuts,
missing content) reads yours offset seconds later, and a project folder is
captured at the shifted times. The window keeps to where both sides have
frames and says so in warnings; an offset with no overlap, or one that is
not a number, is refused with a fix. Sound keeps its own offset reading,
duration is reported as not measured, and the result echoes offset.

* refactor(cli): trim diff offset comments under the file's comment share

* fix(cli): rebase full-length diff offsets and reject overflow

Keep offset streams on a zero-based clock even when every frame is selected. Cover an untrimmed delayed render and reject non-finite offsets before file or project processing.

— Jerrai

* refactor(cli): remove redundant offset filter comment

— Jerrai
2026-11-03 10:48:47 +00:00
WaterrrForever 7ae108005a fix(cli): measure cuts reads a zoom that speeds up as a move, not a cut (#7075)
* fix(cli): measure cuts reads a zoom that speeds up as a move, not a cut

Bug bash (Stripe "pay", 0.9.6): the app window's zoom-in at 0.2 s changes
3, 9, 12, 5 grey levels a frame, and the 12 crossed a cut's level, so
measure cuts listed a cut there and diff failed the rebuild (pass: false at
0.93 similarity) for missing it.

A single-frame cut is now a fast move when the frames either side move too
(30% of its change) and the frame before, zoomed 0.8-1.25x and shifted a few
pixels, comes within 40% of its change of the frame after. A punch-in also
zooms, but out of a still picture, so it stays a cut.

* fix(cli): a zoom is a move only when the picture moves on both sides

Review (hf-review): motion on one side hid a real punch-in out of a still
picture next to a moving shot, and the mirrored punch-out. isMove now needs
both neighbours moving (min, not max). The 33-film check now changes only
Stripe's 0.2 s zoom; league-promo 95.93 s and M1000 5.43 s are cuts again.
2026-11-03 10:20:03 +00:00
WaterrrForever e9de593fe9 fix(cli): measure picks more than 100 frames on ffmpeg 8 (#7071)
* fix(cli): measure picks more than 100 frames on ffmpeg 8

ffmpeg 8 refuses a flat sum of more than 100 terms ("Error while parsing
expression"), and every frame pick in measure, diff and snapshot was one flat
sum of eq(n,k). The ffmpeg HyperFrames downloads is 8.1.2, so measure frames,
diff, face, person, drawn boxes and snapshot all failed past 100 frames.
PostHog: every such cli_error since 0.9.3 came from Windows agents on ffmpeg 8.

sumOf keeps a sum of up to 100 terms flat and nests a longer one in halves.

* fix(cli): sums nest from 51 terms, so ffmpeg 8 takes every pick count

Review (hf-review): 100-term leaves still failed on ffmpeg 8.1.2 once nested,
at 199-201 eq() picks, and snapshot's deeper terms failed at 97-100 times.
ffmpeg 8 limits how deep an expression nests, and a flat sum counts a level
a term. Leaves of 50 pass every count from 1 to 1000 in both shapes, and
1500-5000. Tests decode 199/200/237/401 picks and 97/100/199 snapshot times.
2026-11-03 10:14:37 +00:00
James RussoandClaude Opus 5.5 d89bf35b1d fix(core): keep overflowing content and SVG clip paths in motion-blurred frames (#7080)
* fix(core): keep overflowing content and SVG clip paths in motion-blurred frames

A blurred mover was copied only within its own layout box, so text wider
than the box (a one-line wordmark in a fixed-width container) was cut in
blurred frames. The movers-alone capture also hid every non-mover, including
the SVG clipPath a mover references, which empties the clip and makes the
mover vanish. Both showed as flicker during playback and in full renders.

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

* fix(core): keep the motion-blur fix within each file's comment share

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

* fix(core): measure overflowing text with a Range, ignore rects inside the mover

A block child is as wide as its mover however long its no-wrap text, so
reading child boxes missed the common overflow layout. Read the text's own
rects through a Range. On a rotated mover each child's upright client rect
covers the mover's corners, which doubled the box at 45 degrees and could
pull a neighbouring mover into the trail; only rects that leave the
mover's own client rect now grow it.

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

* fix(core): measure a rotated mover's overflow unrotated

The upright client rect of a rotated mover has empty corners, so overflow
that landed there passed the "stays inside" check and was still cropped.
Measure a rotated mover with its own transform off and map the rects back
through its layout pose, then restore its style.

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

* fix(core): keep a rotated mover the containing block while measured

With only transform: none, a mover with no position stops being the
containing block of its absolute and fixed children, so they jump to an
outer ancestor while measured and their real overflow is cropped. Add
will-change: transform during the swap, and skip the swap when the mover
has no transform of its own.

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

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-03 09:59:56 +00:00
WaterrrForever 91e7f4d48f fix(cli): measure and diff tell an agent what to type after a wrong call (#7072)
The top measure and diff errors since 0.9.4 (PostHog, CLI project) were
agents' calls, not bad videos:

- A flag from another command: --from/--to on ops that take --start/--end
  (extract is the other way round), -o for --out. The unknown-flag error now
  names the flag that means the same here.
- measure sync without --roi stopped at citty's bare "Missing required
  argument"; diff with one video at "Missing required positional argument:
  YOURS". Both now reach their own message with the command to run.
- A Windows path whose backslashes bash dropped (D:videoclip.mp4) was only
  "no file at". The fix line now says to quote it or write it with /.
2026-11-03 09:59:39 +00:00
WaterrrForever 95a86a19cc docs(skills): reverse checks the plan before downloading a linked video (#7076)
Bug bash (Miguel's #2): given a link, the agent downloaded the video before
reverse start could tell it the account was Free. The skill now runs auth
status first. To stay in budget, the no-reverse-start fallback lives only in
start.md (it was in both), and two lines are shorter.
2026-11-03 09:55:43 +00:00
Miguel Ángel ce9830fece fix(studio-server): a project's signature no longer freezes the host while it walks the files (#7073)
* fix(studio-server): a project's signature no longer freezes the host while it walks the files

* style(studio-server): format the signature changes

* fix(studio-server): keep the adapter for the preview's early-error script
2026-11-03 09:16:40 +00:00
Miguel Ángel 9ceced05e2 chore: release v0.9.8 (#7077) v0.9.8 2026-11-03 09:15:54 +00:00
James RussoandClaude Opus 5.5 10bc426e32 feat(cli): call HeyGen's v3 media routes through the generated client (#7063)
* feat(cli): call HeyGen's v3 media routes through the generated client

The media-use generate routes (image, video, avatar, voice, music), HeyGen
transcription and the public voice list called fetch by hand. They now go
through the generated cloud client, regenerated with the create and status
methods for those routes.

runJob takes a job route (its path, how it starts, how its status is read)
in place of a path and a poll-path function. Keys, retries, timeouts,
polling and error messages are unchanged. Speech answers in the request and
the API takes no Idempotency-Key there, so it has no status to poll and no
key header is sent.

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

* chore(cli): keep v3.ts comment share at the base

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

* chore(cli): regenerate the cloud client without API description text

The generated client and types now carry names and types only, with no
JSDoc taken from the API spec's summaries and descriptions. The source
contract test checks that no method carries generated description text,
in place of checking the uploadAsset description.

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

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-03 08:59:27 +00:00
Miguel Ángel b84835c413 feat(studio-server): the preview records the kind and origin of each early error (#7041)
* feat(studio-server): the preview records the kind and origin of each early error

* fix(studio-server): write preview script values with U+2028/2029 and < escaped
2026-11-03 07:47:49 +00:00
Miguel Ángel 9a2cd9e61b fix(producer): a BeginFrame capture failure re-renders on a screenshot session (#7070) 2026-11-03 07:45:44 +00:00
Miguel Ángel 79b6af9b48 feat(producer): a render request can force screenshot capture for that render (#7066)
* feat(producer): a render request can force screenshot capture for that render

A retried render can ask for the slower, safer capture mode without changing the pod's environment.

* fix(producer): drop the comment line the comment ratchet flags
2026-11-03 07:32:17 +00:00
Miguel Ángel 3eead5432d fix(core): audio no longer plays fast for a moment after Play (#7067)
* fix(core): audio no longer plays fast for a moment after Play

* refactor(core): split the audio start wait out of the clock read
2026-11-03 07:30:57 +00:00
Miguel Ángel 3baf81f9a9 fix(cli): reverse on Free runs billing subscribe credited to the run (#7046)
* fix(skills): reverse on Free opens the upgrade page for the person

* docs(skills): reverse on Free opens the upgrade page with a quoted link

* fix(cli): reverse on Free runs billing subscribe credited to the run

* fix(cli): trim the reverse skill and drop a doc comment for lint budgets
2026-11-03 05:46:34 +00:00
James RussoandClaude Opus 5.5 8c799ebd1b chore: release v0.9.7 (#7064)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
v0.9.7
2026-11-03 05:21:25 +00:00
Miguel Ángel bc9f33488b docs(skills): media-use voiceover is free only on the Free plan (#7065) 2026-11-03 05:15:09 +00:00
heygen-rui-botandJames Russo 58a01f1692 chore(codegen): resync cloud client from EF 59dfee8c (#7058)
Co-authored-by: James Russo <james.russo@heygen.com>
2026-11-03 04:55:22 +00:00
James RussoandClaude Opus 5.5 dffc640e85 fix(cli): drop --page-motion-blur from cloud render (#7062)
* fix(cli): drop --page-motion-blur from cloud render

The flag sent page_motion_blur to the hosted render API, which never
accepted that field and rejects unknown fields. Motion blur is set in
the composition with data-motion-blur, and the runtime turns it off on
its own when it cannot render correctly, so the cloud flag is removed
with its request plumbing, test and docs row.

Local render keeps its own --page-motion-blur flag.

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

* chore(ci): allow deleting the cloud render page motion blur test

The deletion guard blocks removed files unless they are listed. The
test file only covered the cloud render --page-motion-blur flag that
this branch removes.

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

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-03 04:21:08 +00:00
Miguel Ángel 0f85af7c7f fix(core): preview playback lands where a seek does when a set interrupts a tween (#7061)
* fix(core): preview playback lands where a seek does when a set interrupts a tween

* test(core): the preview overlap fix holds under a nested time scale and fires each callback once

* style(core): shorten the overlap comment

* refactor(core): the overlap span names its fields and carries no comments
2026-11-03 04:16:09 +00:00
James RussoandClaude Opus 5.5 112ba53302 fix(studio): motion blur falls back for a WebGL canvas Studio reaches first (#7060)
* fix(core): motion blur notices a WebGL canvas the Studio page touched first

When a same-origin host page (Studio) reaches a preview element before the
scene does, for example through a MutationObserver record, Chrome gives that
element the host's prototype. The scene's getContext("webgl") then ran the
host's unpatched getContext, so the canvas never reached the accelerated
canvas set, capture motion blur stayed on, and the WebGL canvas froze during
preview playback.

The tracker now records a canvas in the set of the canvas's own window, and
installs itself in a same-origin parent too, compiled with the parent's own
Function. Cross-origin parents are skipped.

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

* fix(studio): track accelerated canvases in Studio's window, not the embedder's

The preview runtime no longer installs the canvas tracker in its parent
window. That ran on every preview boot, so any same-origin page embedding
the player got its getContext wrapped, and a host CSP without
unsafe-eval reported a violation on each load. Studio now installs the
tracker in its own window when its Player module loads, and core
exposes it at @hyperframes/core/page-motion-blur.

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

* chore: keep the comment share of the touched files from rising

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

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-03 03:59:23 +00:00
Miguel Ángel 05ddddbbf0 docs(skills): reverse tops up once for the run's total and inits with --video (#7048)
* docs(skills): reverse asks to top up once for the run's total

* docs(skills): reverse builds the project with init --video

* test(skills): pin reverse's init --video and top-up-once wording

* docs(skills): a refusal with no amount runs a plain top-up
2026-11-03 03:13:11 +00:00
Miguel Ángel 5e30bbdbe1 feat(lint): flag a set that fires inside a running tween on the same property (#7059)
* feat(lint): flag a set that fires inside a running tween on the same property

* fix(lint): shorten a comment line in the tween overlap helper
2026-11-03 02:47:18 +00:00
James RussoandClaude Opus 5.5 d03bdeae9d fix(cli): prefer OAuth session over HEYGEN_API_KEY (#7051)
* fix(cli): prefer OAuth session over HEYGEN_API_KEY

A signed-in `hyperframes auth login` session now wins over an API key in
the environment, so a paid plan on the login is used even when the shell
also exports HEYGEN_API_KEY.

New order: HEYGEN_ACCESS_TOKEN (host app), the stored login (refreshed
when expired), HEYGEN_API_KEY, HYPERFRAMES_API_KEY, the saved API key.
The env key still comes first when HEYGEN_API_URL or HEYGEN_API_BASE
names a host app's gateway, and takes over for the rest of the process
when the login cannot be refreshed. The media-use audio helper follows
the same order.

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

* fix(cli): fall back to the env key only when HeyGen refuses the refresh

A 503, a network error or an overlapping refresh no longer switches the
process to HEYGEN_API_KEY. The fallback now needs a refused grant or an
expired login with no refresh token. A login another process stored since
is re-read first, and refreshes that overlap in one process share one
request. The media-use helper no longer treats HeyGen's own API base as a
gateway.

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

* fix(cli): keep the login when the refresh reply can't be read

Only a 400/401 from the token endpoint marks the grant as refused and
switches to the env key. A 200 whose body can't be parsed now throws and
leaves the login in place, so the next call refreshes again.

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

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-03 01:52:30 +00:00
Miguel Ángel 92943d99f0 fix(studio-server): two exports in the same second get separate jobs (#7053)
* fix(studio-server): two exports in the same second get separate jobs

* fix(studio-server): name the same-second job id helper instead of commenting it
2026-11-03 01:15:11 +00:00
Miguel Ángel 81b93cf055 fix(cli): snapshot stops Chrome decoding videos it already replaces with extracted frames (#6949)
* fix(cli): snapshot stops Chrome decoding videos it already replaces with extracted frames

* fix(cli): a held video keeps its intrinsic size in snapshot, as in render

* fix(cli): shorten a comment line in the held-video hints
2026-11-03 01:14:27 +00:00
Miguel Ángel 8a6636efe3 fix(cli): the latest version in _meta is never older than the running CLI (#7049)
* fix(cli): the latest version in _meta is never older than the running CLI

* fix(cli): keep the daily recheck cadence when the cached latest is older than the running CLI
2026-11-03 01:13:02 +00:00
Miguel Ángel eb3562966f feat(preview): an unplayable video shows its own frame while its copy is made (#6589)
* feat(preview): an unplayable video shows its own frame while its copy is made

* fix(preview): drop the comment on the copy's light flag

* fix(preview): shorten the still helper's doc comment

* test(preview): each proxy-wait test starts with no copy report left over

* fix(preview): cached still frames are swept with the proxy copies
2026-11-03 00:23:50 +00:00
Miguel Ángel b22af8f25c chore(studio-server): raise the package size budget for the preview features (#7044) 2026-11-02 23:48:00 +00:00
Miguel Ángel de2603e637 fix(cli): auth login --device works without a terminal (#7045) 2026-11-02 23:46:36 +00:00
James RussoandClaude Opus 5.5 6feb4bec7a docs(changelog): weekly digest 2026-10-26-2026-11-02 (#7032)
* docs(changelog): weekly digest 2026-10-26-2026-11-02

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

* docs(changelog): embed the Oct 26-Nov 2 weekly video

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

* docs(changelog): tighten two claims from review

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

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-02 22:24:40 +00:00