A regenerated shot never lines up with a whip frame by frame, so diff listed every fast move.
A jump now counts only above the original's own motion around it.
fails without the fix: reads a change no stronger than the original's motion as the same fast move
* fix(cli): snapshot shoots a frame again when Chrome drops the screenshot mid-paint
* fix(cli): keep the first screenshot error when the retry fails differently
* fix: cache paths follow HYPERFRAMES_CACHE_DIR
Every place HyperFrames keeps downloaded or built files now takes its
folder from one helper, hyperframesCacheDir() in @hyperframes/core. The
default stays ~/.cache/hyperframes; HYPERFRAMES_CACHE_DIR moves it.
* fix: register the cache-dir subpath for bun and node, and build inspector from core source
* test: the cache-dir override test uses a folder that is absolute on every platform
* fix: the opencv cache follows HYPERFRAMES_CACHE_DIR
* fix(cli): npm installs run in their staging dir, so no cache path reaches a command line
* fix(cli): whisper.cpp is cloned inside its build dir, so no cache path is a git argument
* test(cli): the whisper clone test finds no system whisper on Windows either
* fix(cli): say a font or image URL is a download, not a page, when capture is given one
* fix(cli): word the capture download hint as a likely cause, not a fact
* 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
* 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>
* 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.
* 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.
* 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
* 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
* 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
* 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
* 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
* 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
* 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
* 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
* 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
* 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.
* 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
* 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
* 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>
* 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>
* 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
* 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
* 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)