Commit Graph
5091 Commits
Author SHA1 Message Date
Miguel Ángel 404e8254e6 fix(studio-server): an HDR clip previews and snapshots the way the SDR export renders it (#6537)
* fix(studio-server): an HDR clip previews and snapshots the way the SDR export renders it

Footage tagged HLG or PQ played raw in the preview, where the browser tone-maps it its
own way, while the SDR export tone-maps it with zscale and hable: the same clip came
out lighter and with different reds and blues. HDR video now takes the tone-mapped
preview copy (the filter the export uses), and a snapshot still of HDR footage runs
the same tone map. Without an ffmpeg that has zscale and tonemap the clip plays
natively, with a warning that names the missing library.

* fix(studio-server): an HDR clip is never playable for preview, whatever its codec

Only HDR H.264 and ProRes took the tone-mapped copy: an HDR HEVC, VP9 or AV1 clip kept
its codec's test type, so a browser that can decode it was judged able to play it and
the original played with the browser's own mapping. An HDR clip now has no test type, so
the swap always fires. The missing-library warning no longer names the file.

* test(cli): the HDR still test ends ffprobe's options before its input

The repo's ffprobe argv contract requires "--" immediately before the input path; the new
test passed the still's path without it.
2026-10-27 12:49:04 +00:00
Miguel Ángel 6092785348 fix(studio-server): preview loads root-path media, images and CSS from the project, as render does (#6552)
* fix(studio-server): preview loads root-path media, images and CSS from the project, as render does

* fix(studio-server): preview writes root paths project-relative, the form Studio reads back
2026-10-27 12:29:17 +00:00
Miguel Ángel 58552ede4b test(studio): record each edit-accuracy shard's file writes and reloads when HF_WRITE_TRACE is set (#6532)
* test(studio): record each edit-accuracy shard's file writes and reloads when HF_WRITE_TRACE is set

* style(studio): format the write trace

* fix(core): hash the write trace with sha256

* style(studio): wrap the trace hash helper

* style(studio): format the trace hash helper

* fix(studio): turn the reload log on in the Studio page the trace watches
2026-10-27 11:50:20 +00:00
Miguel Ángel 7053aa90dd fix(core): text a script splits into letters shows once and carries the variable's value (#6543)
* fix(core): text a script splits into letters shows once and carries the variable's value

* fix(core): Studio's mounted and swapped scenes read bound text, and instance values load first

* test(core): the scoped variables table is emitted compact in head
2026-10-27 11:29:02 +00:00
Miguel Ángel f04be0f7ce fix(cli): check waits 10 s for a scene to become ready and says what a timeout means (#6539)
check gave a scene 3 s to signal it was ready, then warned "checking the current page
state" and sampled whatever was on screen. Scenes that build procedural textures or
WebGL canvases routinely need longer, so a pass could miss late content with a warning
nobody could act on. The default wait is now 10 s (it ends the moment the page is
ready), the warning says the scene may still be building and to raise --timeout, and
check_report records render_ready_timed_out so the cases can be counted.
2026-10-27 11:28:23 +00:00
Miguel Ángel f007882ca7 chore: release v0.8.208 (#6529) 2026-10-27 11:12:48 +00:00
Miguel Ángel 2634a343dd fix(engine): a Chrome shell that ignores SIGTERM can no longer freeze the CLI at launch (#6547)
The start probe waited for the shell to exit after SIGTERM, so a shell that stalled under load blocked the whole process. Kill it outright at the timeout.
2026-10-27 11:09:05 +00:00
Miguel Ángel 4f1e66d2d0 fix(cli): orphaned Chrome helpers no longer keep a finished snapshot from exiting (#6545)
* fix(cli): a browser's orphaned helpers no longer keep a finished snapshot from exiting

The CDP pipe sockets stayed open after Chrome exited whenever a helper process outlived it, so the CLI never reached natural exit. Destroy them when the browser process exits.

* refactor(cli): name the pipe close so launch.ts carries no new comment

* fix(cli): a browser stand-in without stdio no longer throws from the exit listener

* fix(cli): close every pipe of an exited browser, not only the CDP pair
2026-10-27 11:08:59 +00:00
Miguel Ángel b428ea92be fix(cli): closing the managed Chrome also ends the helper processes it leaves behind (#6542)
* fix(cli): closing the managed Chrome also ends the helper processes it leaves behind

The close waited a second for Chrome to exit and then killed only Chrome's own process.
Under load that second is often not enough, and the helpers (the GPU and renderer
processes, crashpad_handler) were reparented to init and kept running after a finished
run. The close now records the processes under Chrome before it starts, and ends any of
them still running (under the same command) once Chrome is gone.

* test(cli): the helper-reaping test polls for the helper's exit instead of waiting 200 ms

* fix(cli): the Chrome process listing is bounded and no longer runs at import

The ps call that records Chrome's helpers ran with no time limit before the
bounded browser close, so a stalled ps made the close unbounded. It now has a
2 s limit, and a timeout records no helpers.

execFile is resolved when ps runs, not when the module loads, so tests that
mock node:child_process without execFile import it again.
2026-10-27 11:08:53 +00:00
Xuanru LiandJerrai cf04452c0d fix(cli): audio --read reads music onsets, effect peaks, pauses and voice against music (#6546)
* fix(cli): audio --read starts music where its sound is sustained

A run of the bed is split where sound fills less than half of the surrounding
2 s, so a short tone and scattered clicks that bridge into the music no longer
pull its start earlier. Sparse stretches are left to effects.

* fix(cli): audio --read finds effects in each stem and levels them from the mix

A sound ends where the next one starts, so a run of kicks is not one long
riser. Effects are searched in the drums and in the bed outside music, each on
its own, so a click inside a tone is still found. Each effect's peak is read
from the decoded mix in dBFS, and the music reference is taken next to the
effect rather than under it, where its own leakage sits.

* fix(cli): audio --read measures the recording through each pause

Pauses carry the whole recording's level so the read can say what keeps
playing while the voice stops.

* feat(cli): audio --read prints peaks, what plays in pauses, voice vs music

Effect lines print the absolute peak and name the reference of the relative
figure; pause lines keep the pause kind and list the effects, music and
ambience under them; sentences over music print voice and music loudness and
which is louder. Read schema version 4.

* fix(cli): audio --read finds bed effects on the whole bed, not a blanked one

Blanking the bed wherever music or ambience played made every blanked
stretch that ended while sound was still audible look like a sound rising
out of silence. Fades and quiet bridges then printed as dings, hits and
whooshes. The bed is now searched whole, and each source carries the
spans it plays music or ambience in. A sound whose onset-to-peak overlaps
one of those spans belongs to it, so it is not an effect. The drums and
the bare mix carry no spans.

— Jerrai

---------

Co-authored-by: Jerrai <jerrai@heygen.com>
2026-10-27 11:08:00 +00:00
Miguel Ángel 24d49637d3 fix(cli): a negative number after a flag is its value, not an unknown flag (#6549) 2026-10-27 10:49:32 +00:00
Miguel Ángel 5a92fe7e5e fix(cli): beats given a media file points to hyperframes audio instead of a folder error (#6544)
* fix(cli): beats given a media file points to hyperframes audio instead of a folder error

* fix(cli): beats names the folder for a composition file and syncs the skills manifest
2026-10-27 10:49:26 +00:00
Miguel Ángel c2b68fbe07 fix(cli): snapshot's auto end frame stays within 250 ms of a long composition's end (#6538)
* fix(cli): snapshot's auto end frame stays within 250 ms of a long composition's end

* test(cli): the end-frame test comment states the cap, not the history

* chore(cli): shorten the snapshot end-frame comment
2026-10-27 10:28:44 +00:00
Miguel Ángel ae2c4b3942 fix(engine): a GPU probe cancelled by its caller no longer sets software mode for the process (#6541)
The GPU probe's answer is kept for the whole process and the first caller's probe is the
one every later caller waits on. When that first caller cancelled it (a prelaunched
browser dropped, a stopping check), the probe died with "This operation was aborted",
and that cancellation was kept as the answer: every browser the process launched after
it ran in software mode, with a log line blaming the GPU probe. A cancelled probe is now
forgotten and the next caller probes again.
2026-10-27 10:08:51 +00:00
Miguel Ángel 859281a60d fix(studio-server): preview resolves root-path module imports to the project (#6534)
* fix(studio-server): preview resolves root-path module imports to the project

* test(studio-server): preview's own scripts make no module import; lint flags a broken import map
2026-10-27 09:48:42 +00:00
Xuanru Li 87baff8842 fix(cli): audio --read reports noise beds as ambience, not music (#6536)
* fix(cli): audio --read reports noise beds as ambience, not music

A stretch of the non-voice stems counted as music whenever it was above
-55 dB, so room tone and engine rumble separated into "other" printed as
a music piece. A stretch is now music only with a beat, clear tonal chroma
or more than one leading instrument; otherwise it is ambience with its
level in dBFS, called quiet under -45 dBFS, and breaks lie only between
two runs of music. The header lists only stems that carry sound, with
their level, instead of the separator's six fixed names.

* refactor(cli): audio --read gate carries its meaning in names, not comments

* fix(cli): keep ambience out of downstream music measurements

* fix(cli): measure music beat evidence within each stretch
2026-10-27 09:44:40 +00:00
Miguel Ángel 6989271600 perf(producer): a parallel chunk checks BeginFrame on its first worker, with no separate browser (#6500)
* perf(producer): a parallel chunk checks BeginFrame on its first worker, with no separate browser

* style(producer): format

* fix(producer): a chunk whose first worker dies before its check settles instead of hanging
2026-10-27 09:08:54 +00:00
Miguel Ángel eba78b4ad3 fix(cli): audio accepts several files, as its help says (#6535) 2026-10-27 09:08:48 +00:00
Miguel Ángel 5d7cbc2171 feat(lint): warn when a sub-composition's linked stylesheet names its root id (#6533)
* feat(lint): warn when a sub-composition's linked stylesheet names its root id

* chore(skills): regenerate the skills manifest

* fix(lint): the linked-stylesheet hint names fixes that lint clean
2026-10-27 08:48:57 +00:00
Miguel Ángel 1bc4bd9ca4 fix(cli): a check or snapshot that times out says which step it was on (#6531)
* fix(cli): a check or snapshot that times out says which step it was on

check's idle deadline named only the phase ("while checking samples") and snapshot's
CDP timeout named nothing. check now adds the sample, craft frame or overlap probe it
was on, and snapshot adds the seek or capture of the frame it was on, with its time.

* fix(cli): a snapshot timeout no longer tells the user to raise a setting they do not have

Puppeteer's protocol timeout message ends "Increase the 'protocolTimeout' setting in
launch/connect calls". snapshot has no such option, so the step it was on is now the
last thing the message says.
2026-10-27 08:16:01 +00:00
Miguel Ángel 8560812fae feat(cli): check reports where its seek loop spends its time (#6526)
* feat(cli): check reports where its seek loop spends its time

check_report carried one seek_loop_ms, which lumps the layout grid, the craft pass
(up to 600 frames) and the overlap pass with its hold probes. It now also carries
grid_ms, craft_ms, overlap_ms and composition_s, so a slow check can be tied to a
pass. Nothing about what check does or prints changes.

* chore(cli): drop the pass-timings doc comment so the comment share does not rise
2026-10-27 07:49:27 +00:00
Miguel Ángel 9e5da67409 fix(cli): a Chrome that fails to start says how it ended, and a slow start says so (#6516)
* fix(cli): a Chrome that fails to start says how it ended, and a slow start says so

A failed launch only reported "Protocol error (Target.setDiscoverTargets): Target closed". It now
runs the browser once more on its own with the same flags and reports its exit code (Windows
codes named: missing runtime, out of memory, security software), its last stderr lines, or that
it stayed up. The CLI and the engine's render launch both use it. A start slower than 5 s prints
"Chrome is still starting...", and a --timeout that looks like seconds says it is milliseconds.

* chore(cli): cut the Chrome launch diagnosis comments to the comment limit

* fix(cli): the Chrome startup check runs Chrome as puppeteer does and can be cancelled

The check started the browser with only the caller's flags, so a full Chrome ran headful and
was blamed for a missing X server. It now uses puppeteer's default arguments (headless
included). The check is stopped when the CLI is stopped, and the GPU probe, whose failure
falls back to software anyway, skips it.

* fix(cli): a Chrome launch error is never replaced by a failure to explain it

The startup diagnosis asks puppeteer for its default arguments before re-running
Chrome. If that call fails, its error used to replace the launch error the caller
needed. The launch error is now reported as it was. The core package size budget
rises to cover the new chromeStartup module (about 4.7 KB unpacked).

* refactor(engine): the Chrome startup diagnosis lives in the engine, not core

Both callers launch Chrome through the engine (the CLI already imports it), so the
engine owns the diagnosis. Core's package size budget is back to its old value.
2026-10-27 07:49:04 +00:00
Miguel Ángel 019b17b4b7 fix(engine): a failed video extraction says what ffmpeg reported, without paths or URLs (#6527) 2026-10-27 07:29:03 +00:00
Miguel Ángel c9377e28ff test(cli): the studio server test reads the asset body it fetches before moving the folder (#6528)
The file-change test fetches an asset and never reads the response, so the file stays
open and Windows fails the later folder move with EPERM (it failed a merge-queue run).
The helper now reads each body to its end.
2026-10-27 07:28:55 +00:00
Miguel Ángel 592ca3daf1 fix(studio-server): history lock retries a busy url write and releases on failure (#6525)
* fix(studio-server): history lock retries a busy url write and releases on failure

* style(studio-server): wrap the fs mock

* style(studio-server): format the owner lock test
2026-10-27 07:09:09 +00:00
Miguel Ángel a669316bf2 fix(cli): --timeout on check and snapshot takes units like 45s (#6521)
* fix(cli): check stops making video copies after 10 minutes, and --timeout takes units

The copy phase of check had no overall limit: a source that kept moving was never
stopped, and stdout stays silent the whole time. It now ends after 10 minutes with
an error naming the files still unfinished and the elapsed seconds; finished copies
are reused on the next run. The stderr progress lines are unchanged.

--timeout on check and snapshot is milliseconds, so "--timeout 45" waited 45 ms.
It now accepts 45s, 2m and 45000ms, and a bare number under 1000 warns on stderr
that it is milliseconds. Output on stdout is unchanged.

* chore(cli): cut the --timeout parser comment to the comment limit

* fix(cli): drop the 10 minute wall clock on check's video copies

A copy that keeps making progress must not be cut by a clock, and a re-run would
only start it over. The copy already ends when ffmpeg stops reporting progress
for 3 minutes (finished pieces are kept for the next run), so the phase is
bounded on no progress. The --timeout warning now names the value actually used
when check raises a small value to its 500 ms floor.
2026-10-27 06:55:05 +00:00
Miguel Ángel 808d642bce fix(cli): take JSON flags from a file or stdin so PowerShell can pass them (#6518)
* fix(cli): take JSON flags from a file or stdin so PowerShell can pass them

* fix(cli): read BOM-prefixed and UTF-16 JSON from a file or stdin

* style(cli): format the JSON flag reader

* test(cli): feed the bytes PowerShell pipes to the JSON reader

* style(cli): shorten the JSON flag reader's comments

* style(cli): one line for the JSON flag reader's comment
2026-10-27 06:33:50 +00:00
Miguel Ángel 859cd2fb9c fix(core): retiming a parked scene in the preview takes effect without a reload (#6522)
* fix(core): retiming a parked scene in the preview takes effect without a reload

* fix(core): an edit that leaves a parked scene without a start or length in seconds reloads instead
2026-10-27 06:15:38 +00:00
Miguel Ángel 33e0ba550b fix(core): an audio clip that never gets data no longer freezes the playhead (#6523) 2026-10-27 06:10:26 +00:00
Miguel Ángel 594df21537 fix(core): a video after a cut plays in sync instead of about 70 ms behind (#6494)
* fix(core): a video after a cut starts early by its measured start delay, so it plays in sync

* test(player): playbench reports how far the picture after a cut runs behind the playhead

* fix(core): a looping video no longer skews the learned video start delay

* fix(core): the video start delay is learned in less code and capped at 100 ms under test
2026-10-27 06:09:05 +00:00
0fb9a50a63 fix(docker): Node 22.23.4 and Bun 1.4.4 for CVE-2026-111497 (Brotli) (#6440)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: Joel Gallardo <joel.gallardo@heygen.com>

Co-authored-by: heygengenesis[bot] <262951085+heygengenesis[bot]@users.noreply.github.com>
2026-10-27 05:41:56 +00:00
Miguel Ángel 527ab66905 test(engine): Chrome-driving tests run in their own project after the rest (#6517)
* test(engine): Chrome-driving tests run in their own project after the rest

* ci: test reachability understands inline vitest projects
2026-10-27 05:38:33 +00:00
Akshar Patel 2d207cb3a5 fix(cli): validate cloud variables against the selected composition (#6520) 2026-10-27 05:20:00 +00:00
Miguel Ángel bd9b134cbb fix(core): the npm package no longer ships the unminified media sync runtime (#6515)
* fix(core): the npm package no longer ships the unminified media sync runtime

* style(core): a two-line comment for the media clip's volume keyframes

* style(core): the moved media clip type keeps only the comments its names do not say
2026-10-27 05:03:45 +00:00
Xuanru LiandJerrai a779206430 feat(cli): capture accepts a local HTML file again (#6498)
* feat(cli): capture accepts a local HTML file again

Adds an explicit --local-file mode. The file's directory (or --local-root) is served
on a loopback port that only Chrome may reach outside the capture proxy; all other
traffic keeps the public-address policy. The URL argument stays public HTTP(S) only.

* fix(cli): local capture output names the file, not the loopback server

In --local-file mode, meta.json, AGENTS.md, extracted files and the returned result
used the temporary 127.0.0.1 origin. One rewriter maps that origin to file:// URLs
under the root, and meta.json records the file as its source. Root and served paths
now resolve with the same native realpath, which Windows needs.

* fix(cli): local capture reads its files from disk and resolves real paths natively

The asset downloader read the local page server with Node's fetch, which an environment proxy
(NODE_USE_ENV_PROXY with HTTP_PROXY) intercepts, so local images and fonts were dropped. It now
reads the file from disk under the server's own checks.

Root and served paths both use the native realpath. The JS realpath kept Windows 8.3 short names
while fs/promises expanded them, so every file answered 404 on Windows.

The default root is the directory the file was named in, so a symlinked entry can no longer widen
it to wherever the link points.

The local-file docs move below the capture policy text so their heading does not swallow it.

* refactor(cli): capture settles a watchdog outcome in one place

* fix(cli): escape every RegExp metacharacter in the local origin rewriter

---------

Co-authored-by: Jerrai <jerrai@heygen.com>
2026-10-27 04:45:32 +00:00
Miguel Ángel 619b8bc4d7 chore: release v0.8.207 (#6510) 2026-10-27 04:33:06 +00:00
Miguel Ángel eb6b2c9de9 fix(cli): snapshot counts and lists the stills that are on disk, and fails when some are not (#6511)
* fix(cli): snapshot counts and lists the stills that are on disk, and fails when some are not

The summary counted frames the run had captured, not files that exist, and printed paths
relative to the project. It now checks every still on disk, prints absolute paths, says
"N of M" when some are missing or empty, names them, and exits non-zero.

* fix(cli): snapshot says when it clears an earlier run's stills from the folder

Without --keep, a run removes the stills an earlier run left in the folder before it captures,
so two runs into one -o folder silently erased the first. The behaviour stays; the console
and --json now say "cleared N stills from an earlier run in <folder>". The on-disk comment is
also cut to the comment limit.

* fix(cli): snapshot judges the stills it wrote, not the frames it was asked for

A --zoom target that is not visible skips a frame on purpose, with a warning, and that frame never
reaches the written list. Comparing the files on disk with the requested count turned that into a
failed run. Only a written still that is missing or empty fails now.
2026-10-27 04:29:40 +00:00
Miguel Ángel ac90833cc6 fix(player): fade the controls when idle and copy crossorigin to the audio it plays (#6509)
* fix(player): fade the controls when idle and copy crossorigin to the audio it plays

* fix(player): only keyboard focus keeps the controls on screen
2026-10-27 04:09:05 +00:00
Miguel Ángel 202bed36c9 test(producer): the stall tests jump fake time to the next timer instead of a second at a time (#6508)
* test(producer): the stall tests jump fake time to the next timer instead of a second at a time

A 400 s scenario took 400 steps of 50 real event-loop turns plus file IO, which crept
past the unit timeout on a loaded runner. Idle windows now cost one step.

* test(producer): stub the memory sampler so the stall tests' timer jumps skip the idle windows

The sampler is a faked 250 ms interval, so it was the next timer on every jump and the
jump was never longer than 250 ms.
2026-10-27 03:51:58 +00:00
Miguel Ángel be036160fe fix(cli): Kokoro speech works when its espeak data path passes 260 characters (#6507)
* fix(cli): Kokoro speech works when its espeak data folder path passes 260 characters on Windows

* test(cli): cache test follows the synth script version
2026-10-27 03:22:49 +00:00
Miguel Ángel 142f246d7c fix(cli): a finished capture no longer fails when Windows refuses to delete its Chrome profile (#6505)
Chrome's profile lockfile is held for a moment after the browser exits, so removing the
capture profile threw EBUSY and a finished capture exited 1. The profile and staging
removals now go through a core helper that retries transient locks and, for cleanup of
finished work, warns instead of failing.
2026-10-27 03:10:11 +00:00
Miguel Ángel c618724a5f fix(producer): a clip bound by its mount's variable values plays the bound file (#6501)
* test(producer): probe a variable-bound clip under a host with values

* fix(producer): probe a variable-bound clip its mount or defaults rebind

* style(producer): variable media fixtures in small steps

* test(producer): list the real-render variable mount test in the integration lane

* style(producer): keep probeStage's comment share at the base
2026-10-27 03:09:31 +00:00
Xuanru LiandJerrai 53d3caeac5 feat(cli): capture can route its traffic through an opt-in upstream proxy (#6499)
* feat(cli): capture can route its traffic through an opt-in upstream proxy

HYPERFRAMES_CAPTURE_PROXY=http://host:port sends the capture browser proxy's
forwarded requests and CONNECT tunnels, and every publicRequest download,
to that proxy by hostname instead of dialing a checked public IPv4. Unset,
behaviour is unchanged.

* fix(cli): keep capture comment share flat and close the new CodeQL findings

Test fixtures record what they receive instead of echoing request data, and
capture --video strips line breaks from a failed download's message before
logging it.

* fix(cli): proxied HTTP downloads send no URL fragment, and a malformed proxy credential is refused

The absolute-form request to the upstream used the URL's href, so a fragment such as
sprite.svg#icon went on the request line, which the pinned path never sends and strict proxies
refuse. A malformed percent-escape in the proxy credentials threw a bare URIError instead of the
usual "not a valid proxy URL" error. The test servers label their echoes text/plain.

* fix(cli): strip line breaks from capture --video errors in the form CodeQL recognizes

* fix(cli): capture --video logs errors through a recognized newline sanitizer

---------

Co-authored-by: Jerrai <jerrai@heygen.com>
2026-10-27 02:52:52 +00:00
Miguel Ángel 3ec054ab6f fix(engine): renders on a Mac decode a clip in software when the media engine refuses it (#6488)
* fix(engine): renders on a Mac decode a clip in software when the media engine refuses it

* refactor(engine): name the software decode retry condition instead of commenting it
2026-10-27 02:52:25 +00:00
Xuanru Li 725f069cb9 feat(cli): skip the preview-server scan when HYPERFRAMES_NO_PREVIEW_DISCOVERY=1 (#6503)
render, check and snapshot open project history, which looks for a running
preview by probing 100 loopback ports and 5190. Behind an egress fence every
probe is refused and reported. Setting HYPERFRAMES_NO_PREVIEW_DISCOVERY=1 makes
historyDeps.findServer return null without a request, so history opens directly.

Refs #6204
2026-10-27 02:34:19 +00:00
Miguel Ángel 736f38ff4a fix(player): each take plays its own audio when the browser blocks autoplay (#6417)
* fix(player): each take plays its own audio when the browser blocks autoplay

* fix(player): a parent audio proxy of a video clip is seeked when its lag holds, not rate-chased

* style(core): keep the steering policy's comment share where it was
2026-10-27 01:49:09 +00:00
Miguel Ángel 63d9435625 test(cli): install-lock concurrency test uses fake timers (#6504) 2026-10-27 01:48:48 +00:00
Miguel Ángel 6b5d068e4a fix(core): a video no longer runs ahead of the playhead or past its out-point (#6438)
* fix(core): a video no longer runs ahead of the playhead or past its out-point

* fix(core): keep a looping video playing when the playhead wraps before it
2026-10-27 01:45:05 +00:00
Miguel Ángel 7aac5c763b perf(aws-lambda): each chunk logs where its seconds went (#6391)
* perf(aws-lambda): each chunk logs where its seconds went

The chunk_capture event now carries the handler's setup time and the renderer's own stage timings (plan check, browser boot, capture, encode, total), which the renderer already measured but the logs dropped. Lets a fleet run be split into start-up, capture and tail per chunk.

* perf(aws-lambda): chunk logs also time the Chrome path resolution

On the container image the compressed Chrome may be unpacked on every cold chunk; chromeMs separates that from the plan download in setupMs.
2026-10-27 01:24:48 +00:00
Miguel Ángel 4539f35170 feat(cli): write one diagnostic report when a command stays silent for 60 s (#6480)
* feat(cli): write one diagnostic report when a command stays silent for 60 s

* feat(cli): load the hang report only when it is asked for

* fix(cli): the hang report is written without announcing itself on stderr

* fix(cli): the hang report leaves out environment values or is not written, and is written once

* refactor(cli): shorten the hang report comment to the line limit
2026-10-27 01:23:43 +00:00