Commit Graph
2091 Commits
Author SHA1 Message Date
x 8bf6fd3684 fix(cli): check's render-ready warning advises a --timeout above the new default 2026-11-01 17:03:40 -05:00
x e276b27061 fix(cli): check waits for the composition as long as snapshot and render do 2026-11-01 17:01:02 -05:00
x 4d98ee0b0c test(cli): check waits as long as snapshot for the composition by default 2026-11-01 17:01:01 -05:00
Miguel Ángel 9284e69fff fix(core): accept 65-point .cube LUTs, the size grading apps export (#6921)
* fix(core): accept 65-point .cube LUTs, the size grading apps export

* fix(core): shrink LUTs wider than the GPU texture limit instead of rendering black
2026-11-01 20:46:08 +00:00
Vance Ingalls 5540f49121 chore: release v0.8.229 (#6951) 2026-11-01 12:42:11 -08:00
Vance IngallsandClaude Opus 5.5 34ddced2d0 fix(cli): keep browser sign-in open through checkout (#6879)
* fix(cli): keep browser sign-in open through checkout

The loopback listener timed out after 5 minutes, but plan checkout runs
inside the OAuth flow. A slower purchase ended on ERR_CONNECTION_REFUSED.
Raise the default to 60 minutes, matching pacific's plan-checkout handoff.

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

* fix(cli): show the sign-in limit and how to recover

The waiting line now states the 60-minute limit and Ctrl+C. After a
timed-out browser login the CLI says to run auth login again.

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

* fix(cli): drop unverified purchase claim, harden timer test, document limit

Review fixes: the timeout hint no longer says purchases stay on the account
(the CLI cannot observe billing); the no-timer-left test now asserts before
any explicit close() and uses node:http so undici timers cannot pollute the
count; docs mention the 60-minute window and Ctrl+C.

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

* fix(cli): close the sign-in listener on every path and record Ctrl+C

Ctrl+C is now the advertised exit, but events only flush on exit, which a
default SIGINT skips, so an abandoned login vanished from telemetry. Record
it as aborted and exit 130 through requestCliExit. Close the listener on any
throw, so a failure before the wait can't hold the process for the full
window. Derive the waiting line and timeout message from the listener's own
limit, and name the constant for why it is long, which clears the comment
ratchet.

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

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 12:29:35 -08:00
WaterrrForever 6b0abb4eb5 fix(cli): a stale mask takes its frame's colours instead of delogo's streaks (#6950)
* fix(cli): a stale mask takes its frame's colours instead of delogo's streaks

Delogo drew the box's edges across large boxes, and HeyGen painted the streaks into the shot.

Shrink the box to 3x3 and blur it back, so no letter or streak survives.

fails without the fix: leaves no streaks in a box filled while the picture changes

* fix(cli): the stale mask fill drops gblur, which blacked out light boxes

On a 3x3 picture gblur turned light fills black on an FFmpeg 8 build.

Bicubic from 3x3 is already smooth.
2026-11-01 19:41:17 +00:00
WaterrrForever 7f8ae5b4b6 fix(cli): a masked box follows the frame while the camera moves (#6948)
* fix(cli): a masked box follows the frame while the camera moves

A temporal median under a moving camera froze older frames in the box, and HeyGen painted them in.

Fill from the box's own edges on each frame when the picture round it changes.

fails without the fix: fills a masked box from the current frame while the picture changes

* fix(cli): the mask scan stops where the guide does, and small boxes still blur

A long guide overflowed the decode buffer.

A narrow box asked for more blur than its chroma plane holds.
2026-11-01 18:52:06 +00:00
Miguel Ángel 3179348d9a chore: release v0.8.228 (#6943)
* chore: release v0.8.228

* docs(release): the v0.8.228 notes say what limiting a mix far over the ceiling costs
2026-11-01 18:14:51 +00:00
Miguel Ángel f9e8cab67d fix(cli): a render says when it lowered the whole mix, and how to keep the level (#6938) 2026-11-01 16:35:35 +00:00
Miguel Ángel 7aa3a447e2 chore: release v0.8.227 (#6936) 2026-11-01 16:16:13 +00:00
Miguel Ángel ef250cc9d0 feat(cli): the api exports offloadHeavyMedia and every offloaded file reports its asset_id (#6932)
* feat(cli): the api exports offloadHeavyMedia and every offloaded file reports its asset_id

* fix(cli): drop the asset_id doc comment that raised the file's comment share
2026-11-01 15:46:18 +00:00
WaterrrForever 69400df276 fix(cli): the cut detector keeps real cuts in live footage (#6923)
* fix(cli): the cut detector keeps real cuts in live footage

#6894 left held frames out of every baseline and called any run over 3 frames a fast
move. On live footage that raised the baseline past real jump cuts and dropped blur
transitions between shots. Only animation that moves and holds in turn gets the moving
baseline now, and a run stays a cut when its tones change.

* fix(cli): a wipe through black is a cut, and a cut near a guide's edge is refused

A whip keeps its tones through every frame of the run, so that is the test, not only
the two ends: johnny's wipes between two views of one map match at the ends alone.
foldShort folds pieces of a few frames now. At 0.5 s it let a real cut through to a
paid shot, and the classifier already handles the flashes it was there for. --allow-cuts
is in the skills.

* refactor(cli): name the whip check instead of commenting it
2026-11-01 15:30:29 +00:00
Miguel Ángel 6b3e7a7a95 fix(cli): check and snapshot free video clips the playhead left, halving memory on cut films (#6929)
* fix(cli): check and snapshot free video clips the playhead left, halving memory on cut films

* fix(core): drop the releaseMedia doc comment that raised the file's comment share
2026-11-01 14:50:41 +00:00
WaterrrForever 439d01784c fix(cli): a shot from --first-frame comes back in that frame's shape (#6924)
* fix(cli): a shot from --first-frame comes back in that frame's shape

HeyGen can answer 1344x768 for a 16:9 first frame. The crop only ran with --aspect or
with no first frame, so these shots kept its size. Without --aspect the first frame now
sets the shape.

* refactor(cli): drop a comment the function name already says

* fix(cli): the first frame's shape is the one sent, not the one stored

A phone JPEG with Orientation=6 uploads as portrait but stores landscape pixels, so a correct
portrait answer was cropped to 90x50. The shape now comes from the same conversion the upload uses.

fails without the fix: keeps a portrait shot from a phone photo stored sideways
2026-11-01 14:44:27 +00:00
Miguel Ángel 8c22ddba0f fix(cli): snapshot warns when self-closed audio or video clips have swallowed the page (#6915) 2026-11-01 06:16:39 +00:00
Miguel Ángel f08f07ab64 chore: release v0.8.226 (#6917) 2026-11-01 06:04:20 +00:00
Miguel Ángel bbd487c6f8 fix(cli): snapshot ends the process once its stills are saved, like render (#6916)
* fix(cli): snapshot ends the process once its stills are saved, like render

* fix(cli): diff ends the process once its result is out, like snapshot
2026-11-01 05:36:49 +00:00
Miguel Ángel 52a42983db fix(cli): snapshot gives a seek that will not settle its own --timeout, not three minutes (#6910)
* fix(cli): snapshot gives a seek that will not settle its own --timeout, not three minutes

* fix(cli): a seek budget never outlives the protocol timeout; say so in --timeout help
2026-11-01 02:46:55 +00:00
Miguel Ángel 5ce6b30bdb fix(cli): billing and Desktop handoff read their hosts from settings (#6897)
* fix(cli): billing and Desktop handoff read their hosts from settings

* fix(cli): OAuth client and API hosts read from settings

* test(cli): host and client settings tests run the same on any machine

* chore(cli): format and refresh the skills manifest

* chore(cli): trim a comment

* chore(cli): keep the stylesheet as it was
2026-10-31 22:49:12 +00:00
Miguel Ángel 8a0b8a9c22 fix(cli): measure ink, one output-folder flag spelling, logo wordmark variant (#6891)
* feat(cli): measure ink reads text size, --out and --output both work, logo --variant wordmark

measure ink reports the bounds, size and lines of text in a region of one frame, so a rebuild can be sized without a script. measure and snapshot take --out and --output for the same folder. media-use resolve --type logo --variant wordmark returns the brand's wordmark when theSVG has one.

* fix(cli): measure ink stays under the complexity and comment limits, one projectOf

* fix(cli): snapshot and measure also accept --output-dir

* fix(cli): projectOf moves without adding comment lines

* fix(cli): measure output alias list type-checks as an argument

* fix(cli): a logo variant never answers a default logo request; test output flags

* style(cli): format the new tests
2026-10-31 22:26:35 +00:00
Miguel Ángel 5259097261 fix(cli): one cut detector that tells real cuts from flashes and fast moves (#6894)
* fix(cli): one cut detector that tells real cuts from flashes and fast moves

* fix(cli): a flash must come back within a few frames; trim comments, format

* test(cli): the cut fixture gets a 60 s timeout; format

* test(cli): drop a history comment
2026-10-31 21:40:38 +00:00
Miguel Ángel ee50cd2fc0 fix(cli): cloud render uses the composition's data-fps and skips unused heavy files (#6895)
* fix(cli): cloud render uses the composition's data-fps and skips unused heavy files

* fix(cli): satisfy typecheck and comment ratchet for cloud render fps
2026-10-31 21:04:00 +00:00
Miguel Ángel b687d06235 chore: release v0.8.225 (#6898) 2026-10-31 20:58:04 +00:00
Miguel Ángel 4d44c0d0ab fix(cli): billing top-up opens the pricing page (#6887)
* fix(cli): billing top-up opens the pricing page

* test(cli): pin the top-up link's query fields on every environment
2026-10-31 19:59:49 +00:00
Miguel Ángel 919e138fc2 fix(cli): fill --mask boxes from the picture behind and crop generated clips to the requested aspect (#6892)
* fix(cli): fill --mask boxes from the picture behind and crop generated clips to the requested aspect

* fix(cli): shorten the mask fill comment
2026-10-31 19:48:28 +00:00
Miguel Ángel 2239771efd chore: release v0.8.224 (#6885) 2026-10-31 15:13:39 -04:00
Miguel Ángel ea7d43c616 fix(cli): stopping remove-background on a Mac no longer aborts the process (#6848)
* fix(cli): stopping remove-background on a Mac no longer aborts the process

* fix(cli): a quit after background removal released its session exits at once

* Revert "fix(cli): a quit after background removal released its session exits at once"

This reverts commit 3b9d6ffc24.
2026-10-31 17:08:22 +00:00
Miguel Ángel 1e5413f34c fix(core): a stuck seek in check or snapshot fails named before the protocol timeout (#6596)
* fix(core): a seek that never settles ends after 30 s and names what it waits on

* fix(core): keep the seek-wait comments within the comment limits

* fix(core): only a caller's limit ends a seek wait; check and snapshot end it before their timeout
2026-10-31 16:48:36 +00:00
Miguel Ángel 4d6d38519d refactor(cli): proxy failure wording without added comments or a try/catch (#6715) 2026-10-31 16:18:33 +00:00
Miguel Ángel 60f711686c fix(producer): auto renders with color-graded media stay SDR instead of promoting to HDR (#6671)
* fix(producer): auto renders with color-graded media stay SDR instead of promoting to HDR

* fix(producer): keep auto renders SDR when a graded canvas is present
2026-10-31 16:16:06 +00:00
Miguel Ángel 2439b62acd chore: release v0.8.223 (#6869) 2026-10-30 19:11:14 -07:00
WaterrrForeverandMiguel Angel Simon Sierra f2358315e5 feat(skills): re-land reverse any video on the HyperFrames plan, with clearer credit wording (#6833)
* 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.

* fix(cli): the credits link opens the web plan page, which is live

* test(cli): pin the production credits link too

* chore(skills): regenerate the skills manifest after merging main

* docs(cli): keep the person measure's doc comments to four lines

* docs(cli): keep the measure doc comments to four lines

* docs(cli): keep the measure comment lines to 120 characters

---------

Co-authored-by: Miguel Angel Simon Sierra <miguel.sierra@heygen.com>
2026-10-31 00:47:54 +00:00
Vance IngallsandClaude Opus 5.5 5169422a8a fix(lint): the podcast-lanes.html page Desktop writes is not a second root composition (#6809)
* fix(lint): the podcast-lanes.html page Desktop writes is not a second root composition

HyperFrames Desktop's podcast edit writes its camera lanes page, podcast-lanes.html,
at the project root beside index.html: Studio reads no composition inside a dot
folder, and Desktop opens the page directly as its own view. index.html never mounts
it and no render plays it, but multiple_root_compositions fails lint and check on
every podcast project, and its fix hint tells an agent to remove the file. Exempt it
the way caption-skin.html already is.

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

* refactor(lint): name the pages opened beside index.html instead of commenting them

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 17:36:28 -07:00
Miguel Ángel ef9155fee1 fix(cli): say stdin was empty when a JSON flag reads - and nothing is piped (#6852) 2026-10-30 18:29:50 +00:00
Miguel Ángel 80f9350da2 fix(cli): remove-background gathers each decoded frame in linear time (#6850) 2026-10-30 18:29:31 +00:00
Miguel Ángel 6aa9c78bd8 fix(cli): exit-time telemetry no longer loses a render's events on Windows (#6847)
* fix(cli): exit-time telemetry no longer loses a render's events on Windows

* fix(cli): telemetry smoke stand-in reads the batch file; format the warning
2026-10-30 18:29:19 +00:00
Miguel Ángel 16e2e4c6b5 fix(cli): read BOM-prefixed JSON files for timeline plans, grades and motion specs (#6845)
* fix(cli): read BOM-prefixed JSON files for timeline plans, grades and motion specs

* fix(cli): read BOM-prefixed files for render --batch, lambda policy and transcripts

* test(cli): drop the batch BOM test #6605 already covers

* fix(cli): decodeJsonText is only used inside jsonFlag.ts

* fix(cli): drop a fallow suppression the export no longer needs
2026-10-30 18:29:08 +00:00
Miguel Ángel e28dbe4ce4 chore: release v0.8.222 (#6846) 2026-10-30 18:04:36 +00:00
Jerrai 1116077dab fix(cli): capture treats only 192.0.0.0/24 and 192.0.2.0/24 as reserved, via one shared list (#6853)
* fix(cli): capture's public-address check uses the engine's list; 192.0/16 is not all reserved

Only 192.0.0.0/24 and 192.0.2.0/24 are special-use. The capture proxy blocked all of
192.0.0.0/16, so sites on WordPress VIP (192.0.64.0/18, e.g. nasa.gov at 192.0.66.108)
failed every capture with net::ERR_TUNNEL_CONNECTION_FAILED. isPublicIPv4 now reads the
engine's isBlockedNetworkHost, so capture and asset downloads share one list.

— Jerrai (cutroom-debug)

* refactor(engine): one special-use network list, in a light subpath capture imports

Importing all of @hyperframes/engine into capture's publicNetwork slowed the lookup child's
start-up past publicNetwork.process.test's 6 s mid-lookup exit. The list and
isBlockedNetworkHost move to engine/src/utils/networkPolicy.ts, exported as
@hyperframes/engine/network-policy; urlDownloader and the engine index read it there.

— Jerrai (cutroom-debug)

* test(engine): pin 192.0.0.0/24 and 192.0.2.0/24 blocked, the rest of 192.0/16 public

— Jerrai (cutroom-debug)

* fix(cli): alias the engine's network-policy subpath in the CLI bundle

esbuild's root alias rewrote @hyperframes/engine/network-policy to src/index.ts/network-policy;
the exact-subpath list now carries it. The publicNetwork docstring is cut to keep the file's
comment share under its base.

— Jerrai (cutroom-debug)
2026-10-30 16:21:34 +00:00
Akshar Patel 4cabfd18a2 fix(cli): render batches read PowerShell JSON files (#6605) 2026-10-30 16:03:54 +00:00
kevin 0a304f2aa6 fix(cli): read a comment after an empty .env value as no value (#6497) 2026-10-30 16:03:46 +00:00
NavpreetSSidhu f64b028223 fix(cli): count line_unread words from the block's rendered text (#6456) 2026-10-30 16:03:41 +00:00
Miguel Ángel 4da50e2218 feat(telemetry): render_complete splits capture time into seek, page, screenshot and encoder wait (#6839) 2026-10-30 14:55:06 +00:00
Miguel Ángel 5a164fb369 feat(cli): render --start and --end render only that span of the film as its own MP4 (#6834)
* feat(cli): render --start and --end render only that span of the film as its own MP4

The span reuses the chunked render path, so frames are captured at their absolute times and sub-composition timing matches a full render.

* chore(producer): shorten the renderSpan comment

* fix(producer): a cancelled span render stops, and its real-render test runs in the integration lane

renderSpan checks the abort signal before each chunk part and before the stitch. The real-render tests move to their own file listed in the integration lane.

* chore(producer): put the renderSpan doc comment back above renderSpan
2026-10-30 14:45:43 +00:00
James RussoandClaude Opus 5.5 b45e602faa revert: feat(skills): reverse any video (#6754) (#6840)
* revert: feat(skills): reverse any video (#6754)

Keep the reverse-any-video skill and its CLI billing commands out of main until
web subscriptions are live (/pricing and /account/plan return 404 today).
Re-land together with #6833 once those pages ship.

This reverts commit cb2389cf35.

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

* chore(scripts): allow the #6754 revert deletions

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-10-30 14:32:26 +00:00
Miguel Ángel 4ba01be151 fix(cli): history show --diff names a changed video or audio file instead of refusing (#6836)
* fix(cli): history show --diff names a changed video or audio file instead of refusing

* fix(cli): history show --diff names a changed video or audio file instead of refusing
2026-10-30 14:11:35 +00:00
Miguel Ángel 3ebf888fb6 fix(cli): point a brace-stripped JSON flag value at the file and stdin forms (#6838)
* fix(cli): point a brace-stripped JSON flag value at the file and stdin forms

* fix(cli): share the brace-stripped JSON hint with --variables and skip drive paths
2026-10-30 14:07:40 +00:00
Miguel Ángel 6f2b072275 fix(cli): --variables-file and --variables <path> read the file again (#6831)
* fix(cli): --variables-file and --variables <path> read the file again

* fix(cli): drop the comment the typed merge already says
2026-10-30 13:39:35 +00:00
cb2389cf35 feat(skills): reverse any video on the HyperFrames plan (#6754)
* feat(skills): reverse any video on the HyperFrames plan

Reverse rebuilds a video as an editable HyperFrames project and re-shoots its
people with HeyGen. It runs for a person signed in on HyperFrames Pro; Free is
told it is a Pro feature and given the upgrade step.

- skills: reverse-any-video; media-use is the one gate for HeyGen calls
  (sign-in, credits, refusals)
- cli: media-use generate (image, video shot, avatar, voice, music) with --plan
  pricing and --max-credits; measure, diff and analyze for the rebuild; the
  HyperFrames plan in auth status; billing subscribe and top-up wait on the
  plans or credits page
- remotion-to-hyperframes compares with `hyperframes diff` instead of its own
  shell scripts

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

* chore(skills): satisfy CI gates for reverse-any-video

- docs: list diff, measure, analyze and billing in "Find your command" in
  docs/packages/cli.mdx, each with its own section.
- skills: bring media-use/SKILL.md under its 5120 B budget by pointing setup,
  direct-recipe and treatment detail at the references that already hold it;
  the sign-in, credits, --max-credits and billing rules stay in SKILL.md.
- comments: register transcript.json and REVERSE.md as project files for the
  citation checker, and drop a history note from face.test.ts.
- comments: cut restating prose or move it into names so every changed file is
  at or under its comment share. Allowlist the two deleted remotion scripts in
  check-no-main-deletions.

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

* fix(cli): terminate measure's ffprobe options with --

probeVideo passed the input path straight after its options, so a path
starting with "-" would be read as a flag; the producer's ffprobe argv
contract test failed on it. runFfmpeg's fixed flags move to a constant
so the contract no longer mistakes that ffmpeg wrapper for a probe.

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

* test(cli): split diff's video tests into three files under CI's per-file limit

The file took ~131 s on CI against the flake gate's 120 s, and its heaviest test (four
comparisons) hit the 20 s per-test limit. The video tests now live in three files sharing
diff.test-helpers.ts, and that test is two tests of two comparisons each.

analyze reads each part once and checks the bytes it read, instead of a stat then a read
(CodeQL js/file-system-race).

* fix(skills,cli): one credits rule; ask before dropping a step that won't fit

On dev with a 100-credit limit the agent priced a re-shoot with --plan and dropped it without
asking (J5), and in J6 it told the person a price. SKILL.md's Credits rule now covers both:
--plan is for the agent, and when a step won't fit (a --plan over what is left, or a refused
call) the agent says what doesn't fit and asks before dropping or shrinking it.
setup-providers.md's older confirm-before-paying rule points to it.

--plan now runs the same checks as the real call (checkRequest), so it no longer prices a
request that would be refused. The re-shoot recipe in people.md gains the --prompt it needs.
heygen.md: a sign-in also makes images, and --plan's usd is the API charge rounded to $1/60
while its credits come from the list price.

* fix(cli): auth status drops 'balance unavailable' above the plan's credits; sign-in page title

* test(cli): keep diff's video tests inside the flake gate's limits

Under the gate's CPU contention every diff test needing face detection or
optical flow paid opencv.js's 11 MB download and WebAssembly start-up, and
every diffVideos call wrote four worst-moment pictures (about 28 ffmpeg runs)
no assertion read. Tests ran 21-28 s against the 20 s limit.

- loadOpenCvFirst() stages opencv.js in a beforeAll (from this machine's
  cache, a temp copy kept between runs, else the network).
- diffVerdicts() runs diffVideos with worst: 0 for tests that only read
  verdicts; the worst-moment tests keep the pictures.
- The carried-text test is split into its dirty and clean halves.

Locally with 8 CPU burners on 8 cores: slowest test 7.7 s, files 24-30 s.

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

* fix(cli): generate --plan refuses what the real call refuses

checkRequest now holds every pre-send check (the --out extension and
--mask without --motion joined the route body and guide checks), and
generate() runs it first, so --plan and the real call share one function.

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

* fix(cli): plans link uses from=cli and follows HYPERFRAMES_ENV; no balance notice beside the plan

- pageUrl sets from=cli, the parameter the pricing page reads to send a
  CLI buyer back to the terminal.
- The plans and credits pages are on dev.hyperframes.dev with
  HYPERFRAMES_ENV=dev, hyperframes.studio otherwise.
- auth status --json omits the 'HyperFrames balance is unavailable' notice
  when the plan was read.

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

* fix(skills): reverse-any-video re-checks sign-in on resume; REVERSE.md holds no prices

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

* test(cli): split diff-people's whole-frame reuse test into three

It ran five diff comparisons in one test and took 20.2-20.6 s under the flake
gate's contention, over the 20 s limit. Each piece now runs at most two
comparisons against a shared ledger: copy and burned-in title, footage cut
whole, and cuts that only fed a generation. Under 24 CPU burners locally the
slowest of the three takes 3.0 s, where the combined test took 4.9 s under 8.

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

* fix(cli,skills): reverse resume asks after one failed retry; out-of-credits names the step's price

- media-use generate: when HeyGen refuses for credits without saying how many, the refusal
  names the CLI's own price for the call (what --plan prints) as "needs about N" and
  "billing top-up --needed N", instead of "needs more".
- reverse-any-video: never repeat auth status's plan/credits line; a step an earlier session
  gave up on gets one more try, then ask; a command stored in REVERSE.md is a note, rebuilt
  from its recipe and checked with --plan, never run as written.
- people.md / heygen.md: a refused or failed job gets one more try, test calls included,
  then stop and ask.

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

* fix(cli,skills): send a failed HeyGen job again as new; resume asks if the limit still applies

- runJob: a key whose job failed or was refused is recorded in the config dir
  (heygen-failed-keys); the next run with the same inputs sends key-1, key-2, ... so HeyGen
  starts a new job. A finished or still-running job keeps its key and is picked up, so
  nothing is paid twice. "fix the request it names, then run again" now holds.
- reverse-any-video: on resume after a run under a credit limit, just ask whether it still
  applies, naming no costs or numbers.

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

* refactor(cli,skills): drop what reverse-any-video no longer uses

The skill rebuilds from measure probe, cuts, frames, events and face, and checks with
diff. analyze, diff --explain and eight measure commands (trail, box, ink, rhythm,
objects, track, flow, continuity) have no caller, so they go, with their tests and docs.
Examples now use original.mp4 instead of the old .reverse/source.mp4 evidence folder,
and diff's --segments is described as a file rather than REVERSE.md.

* fix(cli): check no longer copies VP9 and AV1 videos before it starts

Chrome plays both, alpha included, and the proxy is made on demand if a browser ever
asks. Copying remove-background's VP9 cutouts took minutes on projects that have them.

* fix(cli,skills): keep paid retries, credit limits and lip sync honest

Retries keep their key after 401, 403, 408, 409, 425 and 429, which say
nothing about the job, and failed keys are scoped to the API and payer.

Credits come from the plan's video rows instead of list dollars, and
reference pictures past the first two count toward --max-credits.

Lip sync reads sound on its own timestamps, so a delayed track fails
the gate. Look and energy call two near-zero values the same.

--plan refuses a missing input as the real call does. The skills teach
the direct sign-in, its credential path and the billing commands.

* chore(cli): keep the new pricing and energy files under the comment share

* fix(cli): scope failed HeyGen keys to the signed-in account

Failed keys were scoped by the local user block, which is absent for a
host's token and display-only otherwise, so two accounts could share a
scope and one could start a second paid job.

The scope now comes from the account /v3/users/me reports for the token
in use. When that cannot be told, no failure is recorded and the key
stays the same.

* fix(cli): fix a job's sender when it starts

Failure scope was looked up again after polling, so a sign-in during a
job could record one account's failure under another and rotate its
finished key. The credential is now read once per job: it signs the POST
and owns any failure, even if someone else signs in meanwhile.

Prefer username to email, since /v3/users/me returns no user id.

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: James <james.russo@heygen.com>
2026-10-30 13:24:02 +00:00