* 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(studio-server): a copy another process holds without progress ends in a named error
* fix(studio-server): a long source's in-progress piece counts as the owner's progress
* test(history): the write-timing test no longer depends on how late its timers fire
* test(history): the write-timing test gives its turn a wide idle limit
* 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
* fix(studio): a split at a clip's edge leaves the file unchanged
* fix(studio): keep the split margin's doc within the comment width
* chore(studio-server): keep the split margin's comments within the file's share
* fix(cli): normalize-audio never cuts a clip that is quieter than the target
* fix(cli): carry the boost-hold rule in a name, not a comment
* fix(cli): normalize-audio no longer says a clip is matched when a limit holds it short of the target
* fix(cli): format normalize-audio, drop the extra comment, and say a held clip is held
* fix(studio-server): the render route passes a MOV ProRes profile to the render
* fix(studio-server): drop the added comment line so the comment share does not rise
* fix(studio-server): undo and redo on Windows restore a file something holds open
* fix(studio-server): a restore waits for the preview's reads to close before replacing the file
* fix(studio-server): a restore checks the project folder after the preview's reads close
* fix(preview): the proxy copy for the video at the playhead is made ahead of the rest
* test(preview): the resolveProxy assertions carry the priority option
* fix(preview): the proxy copy asked for last goes first, and a repeat ask moves it to the front
* refactor(preview): the proxy wait loop moves its header and progress handling into helpers
* fix(studio-server): a history lock whose start cannot be recorded is given back
claim() took owner.pid and then wrote the start record; if that write threw, the error left owner.pid held by this process, so later opens waited on and then named their own pid as the busy owner. Creation and recording now release the file together.
* refactor(studio-server): drop the comment the ratchet counts against ownerLock.ts
* fix: phone videos with an undecodable first audio track check, preview and render
* fix(engine): a rate-lane clip bakes its ramp from the decodable audio track
* test: phone-clip tests end ffprobe options before the input
* 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.
* 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
* 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
* 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
* feat(engine): encoders cap peak bitrate and place keyframes on a set interval
* style(engine): shorten the rate-cap comment
* style(engine): drop the doc lines the comment ratchet flagged
* feat(producer): mp4 renders honour a keyframe interval and a peak bitrate cap on every encoder path
* style(producer): shorten the delivery encoder file headers
* style(producer): drop a comment line from the segment manifest
* style(producer): shorten the integration test header
* test: delivery encoder tests follow the ffprobe argv contract and run in the integration lane
* feat: the render request, server and Lambda plan carry the keyframe interval and peak bitrate cap
* fix(studio): the Studio render route passes the keyframe interval and bitrate cap to the encoder
* chore(studio-server): drop a comment the helper's name already says
* feat(cli): render and lambda render take --keyframe-interval, --max-bitrate and --buffer-size