* feat(cli): add hyperframes clean to find and remove what HyperFrames left on disk
`hyperframes clean` lists leftover render work dirs, debug renders, the history of projects
that no longer exist, idle video proxies and extracted video frames, with sizes, and removes
them. `--dry-run` removes nothing, `--json` is for agents, `--snapshots` also removes
snapshot folders (otherwise listed as reclaimable). It never touches outputs, sources or
anything a running render or preview still owns.
* docs(cli): say that clean does not search a project's subfolders
* fix(cli): clean test compares folder names on Windows and the skills manifest is regenerated
* fix(studio-server): the proxy cache sweep removes only files the transcoder named
It removed any idle .mp4 or .webm in .transcode-cache, so a user file placed there, or reached through
a symlinked cache folder, could go. Proxies are always <sha256>.<ext> and their temp files
.tmp-<uuid>-<proxy name>; nothing else is swept.
* style(producer): keep a renderDirOwner doc comment within 120 columns
* fix(cli): --yes in an unattended run no longer overrides a no saved by another process
* fix(cli): every settings writer takes the lock, and --yes needs a real terminal to reverse a no
* fix(cli): the thin-results download offer also needs a real terminal
* fix(cli): one owner-checked settings lock, and an unreadable settings file never counts as a yes
* fix(cli): settings lock removals go through a reaper, and a non-boolean answer counts as a no
* fix(cli): a settings lock that cannot be released no longer fails a write that landed
* fix(cli): a leftover settings lock is never taken over, and doctor names it
* fix(cli): a background update that cannot be recorded is not launched again every run
* fix(cli): every on-device install re-reads the saved answer first, and an unsaved yes installs nothing
* fix(cli): the thin-results offer stops when a yes cannot be saved
* fix(cli): only the consent-checked step installs the on-device runtime, and a leftover lock warns once
* fix(cli): the leftover-lock warning follows the attended-terminal rule
* docs(cli): explain how catalog search works and which model it downloads
* docs(cli): name the model catalog search was chosen against
* docs(cli): keep only live rules in the word-search header comment
* docs(cli): correct the hosted vector size in the local vector build comment
* feat(cli): hyperframes timeline prints a project's tracks and clips
* docs(cli): list the timeline command
* feat(cli): timeline command reports unreadable lanes; add skill docs
* fix(cli): timeline stays inside the project, shares one start cache, keeps small volumes
* fix(cli): timeline resolves symlinks before the project containment check
* fix(cli): timeline accepts project folders whose name starts with two dots
* refactor(cli): timeline and compositions share the engine's start resolver
* docs(skills): point agents at the timeline command where they decide how to read a project
* fix(cli): timeline prints absolute main-timeline times and the owning file for nested clips
Nested rows carry absStart/absEnd on the main timeline and their owning
file, alongside existing local start/end. Text prints absolute time first,
local time in parentheses. Adds jq/node one-liners for common queries,
tested against a fixture.
* fix(cli): timeline places nested media at the runtime start and tests its query one-liners
A nested media clip with a negative literal data-start was reported later than it plays,
because the raw start was clamped before the host offset was added. The skill's jq and node
one-liners now run against the fixture in the test suite.
* fix(cli): timeline clamps a negative media start to 0 when its host starts at 0
The runtime skips the host-offset formula for a host at t=0 and clamps the start, so the
timeline command now does the same.
* refactor(core): one media-start rule shared by the runtime and the timeline command
The runtime and the CLI each carried a copy of the rule for when a nested media clip's
start takes the host offset, and the copies had drifted. Both now call
resolveMediaStartSeconds.
* test(cli): timeline fixture for a media start written as an expression
parseNumeric and the runtime's parseStrictFiniteTimingNumber are the same function, so the
two callers cannot disagree on what counts as a literal; this pins the expression case.
The "One project, open end to end" section on Examples was four cards linking into
a GitHub folder. A reader on the docs site does not want to leave for a repo tree
to read a BRIEF.md. The section is gone, and so is the examples/docs-reference-project
folder it pointed at.
Also removed the prose references that leaned on it: the Reference Project
paragraph on Go further, the two GitHub-inspect links on Developers, and the
mention on the Studio landing. Each was reworded to talk about "a project"
generally rather than that specific folder.
Examples is now purely the nineteen finished films plus Start from a template.
The changelog entry recording #2977 is left as history. 0 broken links.
`npx hyperframes compare` was shown with no arguments. The command needs two or
more paths ("pass 2+ paths" in its own help), so a reader copying that line gets
an error on their first try. It now shows two.
The closing section was six bullets joined by semicolons — a sentence pretending
to be a list. It is a sentence now.
While writing that sentence I claimed every command can print JSON. It cannot:
`snapshot` and bare `skills` have no --json, though `skills check` does. Changed
to "most commands", which is true. Checked twelve commands against their own
--help rather than against the page.
Thirty-two published videos were the raw render output. One 20-second catalog
preview was 60 MB at 25 Mbps — Blu-ray bitrate for a screen capture in a docs
page. Nothing autoplays, so no page shipped that silently, but a reader who
pressed play paid for it.
Re-encoded at 1280 wide, CRF 28, faststart, keeping audio where it existed.
Measured PSNR against the originals at ~38.5 dB, which is visually identical —
the first check I ran returned nothing and I mistook that for a pass, so this
number comes from a filter that actually worked.
Worth correcting one thing I said earlier: the catalog is not systemically
over-encoded. 190 videos, 0.36 GB, about 1.9 MB each. Six were over 10 MB. I
found two monsters and generalised from them.
Pages carrying more than 8 MB of video: 26 before, and the heaviest went from
140 MB to under 15 MB.
The durable fix is in generate-catalog-previews.ts, which had no delivery encode
at all — it published the render master directly. It has a web pass now, so the
next preview is born small instead of being cleaned up later.
Adds the pages the rebuilt navigation is organised around, and moves the sidebar
onto that structure. Every entry points at a file that exists after this commit;
nothing is rewritten or removed yet, and no redirect is claimed yet.
- Studio (13 pages) — the editor had no section of its own
- One guide per creation workflow, matching the shipped agent skills
- Section hubs: Concepts, Catalog, Developers, Deploy, Workflows, Help,
Go further, Product updates, 30 Days of HyperFrames
Pages a later commit retires drop out of the sidebar here but still exist and
still resolve, so the site stays navigable at this commit.
Incidentally fixes a link to /concepts from the Lambda migration guide that is
broken on main today — the destination did not exist.