A clean-room composition substrate for agent-authored video. Two groups under one umbrella:
-
runtime/(@work.books/gamut-runtime) — HTML Web Components that schedule and composite a video timeline. Authors write a single.htmlfile with<gm-doc>/<gm-timeline>/<gm-track>/<gm-clip>/<gm-scene>/<gm-audio>/<gm-shader>/<gm-adjustment>/<gm-include>elements. Animation lives inside<gm-scene>via the agent's HTML/CSS/JS (GSAP or anything else). The runtime registers the custom-element family with the browser; the DOM is the IR. -
cli/(@work.books/gamut-cli, binarygamut) — Imperative editing operations the agent can use without touching the composition HTML:gamut trim,gamut split,gamut cut,gamut concat,gamut move,gamut inspect,gamut lint,gamut verify,gamut preview,gamut transcribe,gamut render. -
hyperframes/(@work.books/gamut-hyperframes) — Vendored HyperFrames authoring docs + a tiny scene-side helper (onReady, canvas constants) for scripts inside<gm-scene>.
The previous CW XML format (vendored at vendor/workbooks/packages/cw-xml/) baked in enum-driven templates that substituted behavior for missing fields — intent="reveal" selected a tween recipe, kind="fade" selected a transition, mode="word-highlight" selected a caption renderer. The agent thought it specified motion; the runtime invented it. Every "reveal" looked the same. The format had no honest server-side counterpart.
gamut is the rebuild. No recipes. No enums. No fallbacks. The XML carries schedule + composition; the HTML scene carries animation. Guardrails come from a linter (structural checks) and a render-query verifier (RVST-style; loads the comp in a headless browser and reports what's actually visible). Every required attribute is required — missing fields are errors, never substituted defaults.
<!doctype html>
<html>
<head>
<script type="module" src="https://unpkg.com/@work.books/gamut-runtime"></script>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<gm-doc fps="30" resolution="1920x1080" aspect="16:9">
<gm-asset id="hero-vid" kind="video" src="footage/hero.mp4" />
<gm-asset id="vo" kind="audio" src="audio/vo.mp3" />
<gm-asset id="vo-words" kind="transcript" src="audio/vo.words.json" />
<gm-timeline duration="12s">
<gm-track id="base" z="0">
<gm-clip asset="hero-vid" in="2s" out="9s" start="0s" />
</gm-track>
<gm-track id="overlays" z="10">
<gm-scene start="0.5s" duration="3s">
<h1 class="title">Cut from evidence.</h1>
<script type="module">
import { onReady } from "@work.books/gamut-hyperframes/ready";
onReady(() => {
gsap.from(".title", { y: 60, opacity: 0, duration: 0.6, ease: "back.out(1.6)" });
});
</script>
</gm-scene>
</gm-track>
<gm-track id="grading" z="20">
<gm-adjustment start="0s" duration="12s" filter="contrast(1.05) saturate(1.08)" />
</gm-track>
<gm-track id="audio-vo" z="0">
<gm-audio asset="vo" start="0.5s" duration="11s" volume="1.0" />
</gm-track>
</gm-timeline>
</gm-doc>
</body>
</html>See the plan file for the full architecture and phase plan.