* fix: cover SVS text template rendering
* fix: detect the SVS sheet close between recipes
parseSvs searched the raw text for </sheet> before parsing, so a quoted
recipe value containing that text was either taken as the close or, with
lastIndexOf, guessed at. Check for the close tag only between recipes
instead, since closingBrace already skips quoted text. A missing close now
reports SVS_ROOT_UNCLOSED and a second close SVS_TRAILING, as on main.
Co-authored-by: Sharky Wang <65097782+rponeawa@users.noreply.github.com>
---------
Co-authored-by: Sharky Wang <65097782+rponeawa@users.noreply.github.com>
evaluateProducerPlan records every Producer failure keyed by its step, but
build-planning.ts read that map only inside the plannedNeeds loop. A Producer
that failed in a step carrying no request, such as assemble-timeline, had its
failure recorded and never surfaced: plan reported "Build plan is valid" and
exited 0 for builds that deterministically fail at Build.
Keep the failures no planned need reports, count them into the verdict and the
exit code, and print each failing step with its message.
render-still-video converted authored sRGB pictures to yuv420p with
FFmpeg's default BT.601 matrix and wrote no color metadata. Players and
Chromium decode untagged HD video as BT.709, so an HD still clip shifted
color, e.g. #20C040 came back as (20,169,62) in a Chrome <video>, which
is also how HyperFrames composites these clips.
Use the same encode tail as the HyperFrames local renderer (#342) for
the single-picture and the multi-picture paths, and add a test that
checks the stream tags and the decoded color of both paths.
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Since 089c39a01 the frame animation runtime kept each CSS animation live
and paused, and set its currentTime to Present-relative time on hf-seek.
HyperFrames' own css and waapi adapters also seek every live document
animation, to absolute composition time, and the last writer wins. A
Present that starts after frame 0 therefore rendered the pose at absolute
time: a media-track Item with a fade disappeared for most of its window.
Read the authored keyframes and timing once, then cancel the CSS animation
and set animation-name to none, as 0.2.13 did, so the engine never
discovers it. On each seek, evaluate the active poses with transient
Animations built from the constructor, which the waapi adapter does not
patch, read the computed values, cancel them and write the pose inline.
This still avoids tabulating every Present frame.
Fixes#372
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
TikTok rejects the TLS fingerprint of the locked Python environment, so
hypit media fetch failed with "Unexpected response from webpage request".
The curl-cffi extra lets yt-dlp impersonate a browser. Existing prepared
environments need hypit media prepare-fetch again to pick it up.
Reported in #381.