Commit Graph
5091 Commits
Author SHA1 Message Date
Miguel Ángel d8398c9da7 fix(engine): a video held past its media end keeps following its animation (#6424)
* fix(engine): a video held past its media end keeps following its animation

Fixes #4049.

* fix(engine): drop two comments the names already carry
2026-10-26 16:12:30 +00:00
9ecb13ed69 fix(producer): deduplicate scene font faces before embedding (#6395)
* fix(producer): deduplicate scene font faces before embedding

* fix(producer): address font deduplication review

* docs(help): document render font-face deduplication

The troubleshooting guide this section originally targeted was folded
into docs/help.mdx on main, so the section now lives under the render
troubleshooting entries there.

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

---------

Co-authored-by: James <james.russo@heygen.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 16:06:29 +00:00
Muzzy5150 803655a67e fix(cli): isolate benchmark render files (#6403) 2026-10-26 15:32:27 +00:00
kape acd0bc361f fix(producer): honor disabled looping for finite-loop GIF inputs (#3943) 2026-10-26 15:31:13 +00:00
Abdullah M. Nazif dfb7e5a4de fix(media-use): serialize concurrent preference records (#5366)
* fix(media-use): serialize concurrent preference records

* chore: prepare conflict resolution against current main

* fix(media-use): serialize concurrent preference records

* docs(media-use): clarify project preference file guidance

* chore: prepare conflict resolution against current main

* fix(media-use): refresh preference records against main

* chore: prepare conflict resolution against current main

* chore: merge main and refresh preferences skill manifest

* chore: prepare conflict resolution against current main

* chore: merge main and refresh preferences skill manifest

* chore: prepare conflict resolution against current main

* chore: merge main and refresh preferences skill manifest
2026-10-26 15:30:18 +00:00
Miguel Ángel 7d6c02f85a test(player): playbench measures first play, audio joins, automation, cuts and the autoplay fallback (#6418)
* test(player): playbench measures first play, audio joins, automation, cuts and the autoplay fallback

* fix(player): playbench takes-heard windows follow the composition playhead

The host page has no player, so its samples carry no playhead.

The windows fell back to nominal cut times.
2026-10-26 15:15:20 +00:00
Abdullah M. Nazif 2be8bc2b9e fix(cli): preserve UTF-8 across subprocess output chunks (#5273)
* fix(cli): preserve UTF-8 across subprocess output chunks

* chore: prepare conflict resolution against current main

* fix(cli): retain UTF-8 output handling with current main

* chore: prepare conflict resolution against current main

* fix(cli): retain UTF-8 decoding with process teardown updates

* chore: prepare conflict resolution against current main

* fix(cli): preserve decoded subprocess progress on current main

* docs(cli): scope Unicode output guarantees to cancellable workers

* docs(cli): name commands with Unicode-safe diagnostics
2026-10-26 14:58:57 +00:00
Abdullah M. Nazif d1b3471325 fix(cli): describe the restored skip-skills option (#6245)
* fix(cli): describe the restored skip-skills option

* docs(ci): describe the current skills opt-out
2026-10-26 14:58:35 +00:00
SophiaHuangCc 2d695a8436 feat(studio): support GIF export with loop count (#5593)
* feat(studio): support GIF export with loop count

* fix(studio): cap GIF exports at 30 fps

* fix(studio): complete GIF export review follow-ups
2026-10-26 14:57:55 +00:00
Muhtasim Munif Fahim 64cb6556ef fix(lint): add fix hints to the variables-entry and CSS parse findings (#5447)
Closes #5392
2026-10-26 14:57:23 +00:00
jbernard077andClaude Fable 5.1 36a24aeb85 fix(core): the fonts gate starts loading declared faces no laid-out text uses yet (#6415)
* fix(core): the fonts gate starts loading declared faces no laid-out text uses yet

Before composition scripts run, waitForFonts forces one layout and awaits
document.fonts.ready. A face that only script-built text uses has not started
loading at that point, so ready does not wait for it and the script measures
the fallback face. Start every face still unloaded after the forced layout,
under the existing timeout; a load that rejects falls through to the same
timeout warning instead of stopping the scripts.

Refs #5112

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(core): keep the fonts gate's comment share level; cover a face that never settles

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-26 14:56:59 +00:00
Akshar Patel d507323ef9 fix(player): keep new controls in sync with playback (#6373) 2026-10-26 14:53:06 +00:00
Akshar Patel ec866ed1c5 fix(cli): keep audio timings when trimming long recordings (#6375) 2026-10-26 14:52:41 +00:00
Muhtasim Munif Fahim 85dcc193d5 fix(cli): list the examples init --example accepts in docs examples (#5446)
The examples topic listed title-card and video-edit, which do not exist,
and none of the eight examples in registry/examples. List blank plus the
registry examples with their registry-item descriptions, and add a test
that fails when the topic and registry/examples disagree.

Fixes #5393
2026-10-26 14:22:09 +00:00
Miguel Ángel 2d1b5cfbd2 chore: release v0.8.204 (#6423) 2026-10-26 10:16:23 -04:00
Miguel Ángel f6c26141d8 fix(producer): a media src that resolves to the page itself is no source (#6421)
* fix(producer): a media src that resolves to the page itself is no source

A src of '#', '#t=1', '?' or '?x=1' reads back from the browser as the page URL
plus a suffix. decodedUrlPath strips the suffix, so the probe opened index.html as
a media file and failed the render with 'media sources are text documents'.
Discovery now drops any src whose URL without query and hash equals the page URL,
which also covers the blank and whitespace forms from the earlier fix.

* fix(producer): name the page-itself check instead of commenting it
2026-10-26 13:50:50 +00:00
Miguel Ángel f16c23cd99 fix(engine): a slow first Chrome start no longer drops a render to screenshot capture (#6420)
The beginFrame probe now tells a timeout from a real rejection.

A timeout relaunches Chrome and probes once more with a longer budget.

An unsupported answer still falls back at once.
2026-10-26 13:49:57 +00:00
Miguel Ángel dc56b3d20a perf(studio): the layer walk skips clips the runtime hid, so scrubbing a long film stays smooth (#6416)
The off-canvas indicators (always mounted) and the Layers panel rebuild their layer list every
100 ms while a scrub mutates the preview, and each rebuild read the computed style of every element
of every scene, on screen or not. The runtime already hides everything inside a clip its visibility
pass hid, so those subtrees hold no layer: the walk now skips a clip marked data-hf-clip-hidden
with an inline visibility of hidden. The marker constant moves to studio-preview-mark so the runtime
and Studio share one owner.
2026-10-26 13:22:09 +00:00
Miguel Ángel 575f68cf5b fix(producer): a render whose capture stops advancing fails within minutes (#6413)
* fix(producer): a render whose capture stops advancing fails within minutes

* fix(producer): keep the bounded probe read the stall change dropped

* chore(producer): shorten a test comment

* fix(producer): every retry batch gets its own first-frame window; the stall test waits for the render to settle

A retry that runs as several batches opened one stall window for the whole attempt, so a later batch whose browsers take longer than the no-progress window to land a frame was killed where main would have finished. The window now opens per batch. The stall tests also waited a fixed number of turns for real file IO after the last frame, which failed about 3 runs in 10 on a loaded machine; they now wait for the render to settle.

* fix(producer): a test reads the stall error fields instead of suppressions; size budget follows

* test(producer): split the scripted capture attempt into small helpers

* test(producer): the stall test advances fake time only while the scripted capture waits
2026-10-26 12:20:19 +00:00
Miguel Ángel ff0a56340b chore: release v0.8.203 (#6412) 2026-10-26 07:20:07 -04:00
Miguel Ángel 52b3d32114 fix(studio-server): a failed preview copy reports its causes and what its source is (#6350)
* fix(studio-server): a failed preview copy says why its output could not open

* fix(studio-server): a failed preview copy reports its causes and what its source is

* fix(studio-server): failure reports hide spaced paths and survive a vanished source

* refactor(studio-server): read a probe's result in its own function for the complexity gate

* fix(studio-server): close the source facts function the rebase left open

* fix(studio-server): a failure report reads the source size through one open descriptor
2026-10-26 10:54:09 +00:00
Miguel Ángel 6a977e8db1 fix(producer): chunk capture round-robins only for callers that bill wall time (#6405)
* fix(producer): chunk capture round-robins only for callers that bill wall time

* fix(engine): worker, extraction and encoder sizing read the CPU quota, not the host core count

* Revert "fix(engine): worker, extraction and encoder sizing read the CPU quota, not the host core count"

This reverts commit cdd4d858c8.

* chore(producer): drop the doc comments the comment ratchet rejects
2026-10-26 10:20:08 +00:00
Xuanru Li a39f7b37d9 feat(cli): check-review inspect attaches the inspector's report to each framed finding (#6409)
* feat(cli): skipContrastInMotion moves to HF_TOOL_CONTEXT check-review

The --skip-contrast-in-motion flag and HYPERFRAMES_CHECK_SKIP_CONTRAST_IN_MOTION
env give way to a check-review capability in HF_TOOL_CONTEXT, so only a harness
turns it on. The skill text and manifest go back to main.

* feat(cli): check-review findingFrames saves one plain frame per finding time

With HF_TOOL_CONTEXT check-review.findingFrames, every error/warning finding in
layout or contrast with a real bbox gets frameTime (the middle sample of its
longest held run, by the heldMs gap rule) and frame (the absolute path of an
unannotated full frame shared by every finding at that time). One seek and
screenshot per distinct time, capped at 60 times with errors first, into the
run's snapshot folder; not listed in snapshots, history or events. Without the
capability, output is unchanged.

* docs(cli): finding-frame comments name the check-review capability, not a flag

* fix(cli): validate finding frame times and preserve cancellation

* fix(cli): count finding frame progress toward the check deadline

* feat(cli): check-review inspect attaches the inspector's report to each framed finding

With findingFrames on, the finding-frames page is served with the
inspector's GSAP hooks. After each frame is captured, every finding framed
at that time is inspected by its data-hf-id, else its selector, and the
inspector's own report is attached as the finding's inspect field. A failed
inspection becomes that finding's { error } and never fails the check.
Without the capability nothing changes.

Drops the unused @types/mime-types devDependency that the dependency audit
flags once packages/cli/package.json is touched.

* fix(cli): stop finding inspections after cancellation

* fix(cli): reject ambiguous finding inspection targets

* fix(ci): build inspector before Windows CLI smoke

* fix(cli): parse viewport HTML with explicit server parser
2026-10-26 10:02:49 +00:00
Miguel Ángel 84fd701daa feat(studio): preview copy progress, retry and a remembered quality (#6366)
* feat(studio-server): a copy being made says how far it has got, and can be retried

* feat(core): the preview reports its lighter copies' progress and retries failed ones

* feat(studio): the preview quality and its lighter copies' progress live in the player store

* feat(studio): every host forwards the preview quality, and the choice is kept per computer

* feat(studio): the preview quality knows if a person or the app chose it

* fix(core): the first report of the lighter copies is not held back by the throttle

* test(studio): the preview quality preference test writes under the real key

* fix(core): a quality change reports its copies at once, not after the throttle

* style: format the preview quality files

* feat(core): report how playback is going, and what the preview holds, to the host

* fix(studio): the preview quality levels come from a browser-safe core entry

* style: format the new entry's files

* style: drop two comments the file's ratchet and the citation check refuse

* feat(core): tell which lower levels would give a video a lighter copy

* fix(studio): drop the old level's playback health when the level changes

* feat(studio-server): preview facts carry the probed codec of every video

* refactor(studio): route the preview's reports through a table for the complexity gate

* fix(core): a copy's retry flag is sent on the first ask only, not on every poll

* fix(core): type the health report and restore the player hook's complexity directive

* style: cut four comments the comment ratchet refuses

* fix(studio): keep playerStore.ts within its 600-line cap

* fix(core): a scene mounting does not restart the playback health window

* fix(core): the playback health window restarts only when the display scale changes

* fix(core): a repeated display scale no longer restarts the playback health window

* fix(studio): route the preview's reports by an explicit list of message types
2026-10-26 09:20:07 +00:00
Xuanru Li 12ae82aa8a feat(cli): check-review findingFrames saves one plain frame per finding time (#6401)
* feat(cli): skipContrastInMotion moves to HF_TOOL_CONTEXT check-review

The --skip-contrast-in-motion flag and HYPERFRAMES_CHECK_SKIP_CONTRAST_IN_MOTION
env give way to a check-review capability in HF_TOOL_CONTEXT, so only a harness
turns it on. The skill text and manifest go back to main.

* feat(cli): check-review findingFrames saves one plain frame per finding time

With HF_TOOL_CONTEXT check-review.findingFrames, every error/warning finding in
layout or contrast with a real bbox gets frameTime (the middle sample of its
longest held run, by the heldMs gap rule) and frame (the absolute path of an
unannotated full frame shared by every finding at that time). One seek and
screenshot per distinct time, capped at 60 times with errors first, into the
run's snapshot folder; not listed in snapshots, history or events. Without the
capability, output is unchanged.

* docs(cli): finding-frame comments name the check-review capability, not a flag

* fix(cli): validate finding frame times and preserve cancellation

* fix(cli): count finding frame progress toward the check deadline
2026-10-26 08:28:38 +00:00
Miguel Ángel 1819276fc3 test: real-Chrome and CI smoke pages inline GSAP so they wait on no CDN (#6406)
* test(studio): real-Chrome tests inline GSAP so their page waits on no request

* test(ci): smoke projects inline GSAP so required checks wait on no CDN
2026-10-26 08:20:55 +00:00
Vance Ingalls f8d51f3146 chore: release v0.8.202 (#6404) 2026-10-26 07:55:04 +00:00
Xuanru Li 257bf285ff feat(cli): skipContrastInMotion moves to HF_TOOL_CONTEXT check-review (#6400)
* feat(cli): skipContrastInMotion moves to HF_TOOL_CONTEXT check-review

The --skip-contrast-in-motion flag and HYPERFRAMES_CHECK_SKIP_CONTRAST_IN_MOTION
env give way to a check-review capability in HF_TOOL_CONTEXT, so only a harness
turns it on. The skill text and manifest go back to main.

* fix(cli): satisfy comment ratchet for check capability
2026-10-26 07:42:50 +00:00
Miguel Ángel 603f4214ff fix: Remotion ports keep box sizes, the manifest hook runs after format, a drag test stops flaking (#6392)
* feat(skills): a Remotion port carries Remotion's box-sizing rule so bordered boxes keep their size

* chore(skills): regenerate the skills manifest after the format pass

* fix(hooks): the skills manifest is hashed after the formatter has run

* test(studio): a drag is measured against the box the preview shows

* test(studio): another element is read bare until it is selected
2026-10-26 07:20:03 +00:00
Vance IngallsandClaude Opus 5.5 07a126d80f fix(core): preview audio fades play as ramps on the audio clock, so cuts no longer click (#6397)
* fix(core): preview audio fades play as ramps on the audio clock, so cuts no longer click

data-fade-in / data-fade-out were folded into one volume per 50 ms sync tick and applied as
a step (el.volume, or gain.value in the Web Audio transport), so a 20 ms fade never played
and each clip started and stopped at near full level: a click at every cut. The export
applies the fades (ffmpeg afade) and does not click.

The transport now books each clip's fades on a gain of its own when it schedules the
clip, for both decoded buffers and captured media elements: a linear ramp from where the
clip starts sounding up to its fade-in, and down to silence at its end. The sync tick hands
the transport the level without the fade (onElementVolume's new fifth argument, sent only
where a fade applies), so a booked fade is not applied twice. The plain el.volume fallback
keeps its stepped fade.

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

* fix(core): one doc block on setElementVolume

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

* fix(core): keep the comment share where it was

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

* fix(core): booked fades hold through pre-roll, follow rate changes, skip unbounded ends

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

* chore: raise the producer unpacked budget to the measured size plus 1%

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 06:25:24 +00:00
Xuanru Li afdad4ea38 feat(cli): opt-in check flag that leaves out contrast measured mid-animation (#6396)
* feat(cli): opt-in check flag that leaves out contrast measured mid-animation

`hyperframes check --skip-contrast-in-motion`, or
HYPERFRAMES_CHECK_SKIP_CONTRAST_IN_MOTION=1, leaves out a contrast failure
measured while a GSAP tween on the text or an ancestor is running, or while
the text's cumulative opacity is below 1. Repeating tweens and tweens of 4 s
or longer (camera drifts) do not count as motion. Text no GSAP tween targets
is reported as before. With neither set, check is unchanged.

The motion state is read at the same contrast sample, with no extra seek or
screenshot.

* fix(cli): read contrast motion on current GSAP clocks

* fix(cli): keep infinite timeline motion ambient
2026-10-26 06:22:46 +00:00
Miguel Ángel 2e23b7e434 fix(studio-server): copies are found by content and made by one process at a time (#6358)
* perf(studio-server): a preview copy is keyed by the file's content, so copied projects reuse it

* fix(studio-server): copies are keyed by content and made by one process at a time

* docs(studio-server): shorten the copy lock comment

* fix(studio-server): find a copy by place and time first, by whole-file content when that misses

* fix(studio-server): hash small sources in one read; wait longer in tests for the hash

* test(studio-server): cache folder listings ignore the copy index files

* style(studio-server): format the copy lookup files

* docs(studio-server): shorten the copy lookup comment

* fix(studio-server): hash a source through one open handle, not a check then a read

* fix(studio-server): hash through one descriptor, keeping the small-file path synchronous

* style(studio-server): format the cache key file
2026-10-26 06:20:03 +00:00
Miguel Ángel a11280eef0 perf(cli): lambda deploy warms the video function so the first render does not wait for its image (#6376)
* perf(cli): lambda deploy warms the video function so the first render does not wait for its image

A freshly deployed container-image function loads its image on first use, which added about 12 s to the first render's plan on some deploys. Deploy now invokes the function's warm action once after the stack is up (default on, --no-warm skips it). A failed warm-up prints a warning and the deploy still succeeds.

* chore(cli): move the deploy warm-up to its own file, regenerate the skills manifest

Regenerates skills-manifest.json for the lambda reference change, keeps runDeploy under the complexity gate by pulling the warm step into a helper, and leaves sam.ts untouched.

* fix(cli): the deploy warm-up asks the aws CLI for JSON output whatever the profile sets

A profile configured for text or yaml output made the reply unparseable, which printed a spurious warm-up warning.

* refactor(cli): split the reserved-concurrency notice and warm-up gate out of runDeploy
2026-10-26 05:32:53 +00:00
Miguel Ángel 8d773fc68a feat(cli): lambda render --width/--height at a whole-number multiple renders at that scale (#6390) 2026-10-26 04:56:01 +00:00
Miguel Ángel 3ff8cd8683 chore: release v0.8.201 (#6377) 2026-10-26 04:50:26 +00:00
James RussoandYi-111-a 9096aab8c8 fix(studio): still placeholder while a video frame thumbnail loads (#6389)
Co-authored-by: Yi-111-a <153097222+Yi-111-a@users.noreply.github.com>
2026-10-26 03:56:16 +00:00
Miguel Ángel 38d9aeb5ea feat(core): lighter preview copies of heavy videos below full quality (#6365)
* feat(core): tell which video files deserve a lighter preview copy, and at which size

* feat(studio-server): serve lighter copies of heavy playable files, a keyframe every second

* feat(core): the preview plays lighter copies of heavy videos below full quality

* style: shorten two comments

* style: shorten a comment

* style: shorten a comment

* fix(core): format the preview quality files and split the copy sizing for the complexity gate

* style: format the studio-server preview files

* fix(core): type the copy job's level as a preview quality

* chore(producer): raise the package size budget for the preview runtime growth
2026-10-26 03:53:21 +00:00
Hill Patel c0ddd3228d fix(cli): preserve quoted multiline .env values (#6124)
* fix(cli): preserve quoted multiline .env values

applyDotEnv parsed .env content line by line: a quoted value's closing
quote was only ever looked for on the same physical line, so a value
like HYPERFRAMES_VERTEX_SERVICE_ACCOUNT='{...}' spread across several
lines got truncated to the leftover text on its opening line, and the
continuation lines were silently dropped (no "=" to parse as entries).

Join physical lines into logical ones before parsing: when a line
opens a quote that isn't closed on that same line, keep appending
following lines until one contains the closing quote character. This
matches how Node's util.parseEnv treats quoted multiline values.

Fixes #6075

* fix(cli): do not let a commented or unclosed quote swallow later .env lines

logicalLines looked for an open quote on every physical line before
entryOf had a chance to classify it as blank or a comment, so a
commented-out example like `# KEY="sk-old` (an unclosed quote inside
a comment) opened a quote that never closed, joining every line below
it into one value and dropping the real keys that followed.

A genuinely stray unclosed quote with no later closing line had the
same failure mode: the join ran to EOF and swallowed the rest of the
file instead of leaving the malformed line on its own, so a later
file like A='x / B=2 lost B entirely.

Skip blank/comment lines before checking for an open quote (matching
entryOf's own skip), and if the closing-quote search reaches EOF
without finding one, fall back to the opening line on its own and
resume parsing from the next line. Also strip a trailing \r per line
so a CRLF multiline value doesn't carry it into the joined string.

* fix(cli): trim comments on dotEnv.ts to stay within the comment-ratchet budget

Dropped the comments on openQuoteOf and closingLineIndex (their names
already say what they do) and cut the logicalLines comment down to
two lines, bringing the file back to 6/93 comment lines against the
base's 4/57.
2026-10-26 03:49:23 +00:00
Miguel Ángel badb61aa99 fix(studio-server): take over a history lock whose pid now runs another process (#6386)
* fix(studio-server): take over a history lock whose pid now runs another process

* style(studio-server): drop two comments from the history lock
2026-10-26 03:21:37 +00:00
Miguel Ángel a058cde725 fix(cli): cloud render --dry-run stops reading media it cannot match and logs progress to stderr (#6371)
A dry run hashed every referenced media file in full to look for an earlier upload, strictly one at a time, and printed nothing under --json until the end. It now hashes only files the local upload cache could hold (a file whose size matches no cached asset, or any file when nothing was uploaded, cannot hit), and --json writes one progress line per file to stderr.
2026-10-26 02:16:39 +00:00
Miguel Ángel f32e2a6fbe fix(core): pressing play puts a sped-up or looping video at the right moment in one seek (#5800)
* fix(core): pressing play puts a sped-up or looping video at the right moment in one seek

Pressing play, or seeking while playing, placed every video as if it played at 1x from its start and never looped. The media sync that runs right after knew better, saw a gap of seconds on a 2x or looping clip, and seeked again: two decoder resets per press. Both now read one function for where a media element belongs in its source at a given time, so the first placement is the only seek.

* fix(core): play keeps a video's own speed and skips seeking a video already in place

Setting the transport rate wrote that rate onto every media element, so a 1.15x clip played at 1x until the next media sync put it back; Studio sends a rate on every Play. The media sync already sets each element to its own rate times the transport rate, so the rate change now leaves elements alone and lets that sync apply it. Pressing Play also no longer seeks a video that is already at its source time, since every seek flushes the decoder.

* fix(core): pause and play leave media alone that another feature or the slideshow is driving

Play and pause placed every in-window video at the playhead, including a video the grading preview or a Studio scrub holds while paused, and slide media while the slideshow drives media itself. They now ask the media sync which clips are the runtime's to move.

* refactor(core): trim comments the comment-share check rejects
2026-10-26 02:15:41 +00:00
Miguel Ángel e4bdf8c51c perf(studio-server): copy alpha cut-outs several pieces at a time (#6342) 2026-10-26 02:14:49 +00:00
Miguel Ángel 9cd2dc3a85 fix(cli): media-treatment and normalize-audio find clips inside mounted scenes (#6362)
* fix(cli): media-treatment and normalize-audio find clips inside mounted scenes

* fix(cli): report the scene file with forward slashes and drop added comments

* fix(cli): normalize-audio reads a scene's audio relative to the scene file
2026-10-26 02:13:56 +00:00
Miguel Ángel e48c8a0614 perf(studio): a settled timeline's composition check scans only its hosts, not the whole preview (#5880) 2026-10-26 01:35:00 +00:00
Miguel Ángel e51ec11caa perf(engine): on a Mac, video frames for a render decode on the media engine (#5878)
Frame extraction decoded every source in software, so a long 4K60 HEVC clip
spent much of its CPU on decoding. On macOS, extraction now asks ffmpeg for
VideoToolbox when this ffmpeg has it and the source cannot carry alpha; ffmpeg
falls back to software for a stream VideoToolbox cannot decode, and the frames
written are byte-identical.
2026-10-26 01:33:24 +00:00
Miguel Ángel 924da50637 perf(producer): chunks capture frames round-robin so the encoder runs during capture (#6364)
* perf(producer): chunks capture frames round-robin so the encoder runs during capture

The overlapped encoder takes frames in order, but workers captured contiguous ranges, so it sat idle until worker 0 finished and then encoded the other workers' frames after capture. With the encoder on, workers now take frames round-robin and it keeps pace.

* chore(producer): drop a doc comment to keep the comment ratchet flat

* fix(producer): interleaved capture retries a dead worker as one stride task and keeps static-frame reuse

A worker that dies during round-robin capture leaves every Nth frame missing; the missing-frame retry turned each into its own one-frame batch. It now retries one stride task per dead worker. Screenshot-mode static reuse also required the previous frame to be exactly one back, which never holds at stride above 1; it now reuses when every frame in the gap is static, like the worker path.
2026-10-26 01:32:12 +00:00
James RussoandClaude Opus 5.5 cbf1176cf0 fix(cli): stop shipping an env var name that endpoint scanners flag (#6369)
* fix(cli): stop shipping an env var name that endpoint scanners flag

Cisco Secure Endpoint ships an IoC signature that matches the literal
name of the openclaw state-dir env var. Any file containing it is
quarantined, which deletes a CLI dist chunk (the CLI then fails on its
second run) and the Studio app.asar.

Key the openclaw agent-runtime rule on OPENCLAW_CONFIG_PATH only. openclaw
sets both variables on the subprocesses it spawns, so detection is
unchanged. Drop the state-dir name from the comments and from the test,
which now covers detection through the config-path variable.

Fixes #5245

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

* fix(cli): keep the openclaw comment under the comment-share ratchet

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

* fix(cli): drop the external-repo citation from the openclaw comment

The comment-citations check resolves file:line references against this
repo, and that path lives in the openclaw repo.

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-26 01:11:17 +00:00
James RussoandClaude Opus 5.5 f4a48ad3e0 fix(cli): make snapshot --describe opt-in (#6368)
snapshot uploaded every frame to Gemini whenever GEMINI_API_KEY or
GOOGLE_API_KEY was set, even with no flag. Frames now stay local unless
--describe is passed. A bare --describe uses the default prompt (it used
to send an empty one), --describe "question" asks a custom one, and
--describe false still works.

Fixes #6138

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 01:06:29 +00:00
Miguel Ángel 84b6319346 perf(core): keep long-media analysis responsive and sample the whole clip (#5793)
* perf(studio): music beat analysis no longer freezes the page or runs during playback

* fix(core): media-treatment --analyze finishes on long HDR clips

Grade analysis decoded the clip from the start and kept every frame until the
fps filter had emitted five samples. Past 50 s the filter rate floors at 0.1
fps, so it always decoded the first 40 s at full rate and resolution: a
3-minute 4K60 10-bit HLG clip timed out at 15 s, and every long clip was
graded from its first 40 s only.

Each sample now seeks to the middle of one fifth of the clip and decodes one
frame. The timeout applies per sample and its error names the sample time and
HYPERFRAMES_ANALYZE_TIMEOUT_MS.

* refactor(core): name the keyframe seek instead of commenting it

* fix(core): count one frame per grade sample on ffmpeg 8
2026-10-26 00:15:51 +00:00
Miguel Ángel 3ad80aa82e fix(core): a script's hidden clip stays hidden after a jump or a re-entry (#6355)
* fix(core): a script's hidden clip stays hidden after a jump or a re-entry

* fix(core): re-hide an ended clip unless the tween hid it
2026-10-26 00:13:12 +00:00