From 578f0f1bb1f0817ca89a8551cc267c466cc5c7b6 Mon Sep 17 00:00:00 2001 From: calesthio Date: Sat, 27 Jun 2026 10:32:07 -0700 Subject: [PATCH] feat(compose): add atelier (bespoke) composition mode + doctrine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a hand-authored, project-local Remotion render path that bypasses the cut-schema and the stock scene-type registry, for hero/bespoke videos that must look distinct from one another. - video_compose: composition_mode="atelier" (or renderer_family="bespoke") routes to _render_via_atelier, which renders a project-local entry under remotion-composer/projects// with an optional per-project public_dir (skips copying the bloated shared public/). No cut-schema, no stock registry. - skills/meta/bespoke-composition.md: routing skill — art direction (visual-style) -> motion principles (Disney 12) -> engine mechanics (remotion-best-practices + stock components read only as a mechanics codex) -> atelier render. Doctrine: reuse engine knowledge, never creative components. - AGENT_GUIDE: "Composition Authoring Mode" (templated vs atelier); default atelier for hero work; scene-type catalog reframed as a mechanics codex. - animation-runtime-selector + INDEX: authoring-mode-first pointers. - base_tool.run_command: decode subprocess output as UTF-8/replace (Windows cp1252 crashed the reader thread on Remotion's Unicode progress output). - .gitignore: remotion-composer/projects/ (throwaway bespoke compositions). --- .gitignore | 3 + AGENT_GUIDE.md | 11 ++ skills/INDEX.md | 2 + skills/meta/animation-runtime-selector.md | 7 ++ skills/meta/bespoke-composition.md | 133 ++++++++++++++++++++ tools/base_tool.py | 6 + tools/video/video_compose.py | 147 ++++++++++++++++++++++ 7 files changed, 309 insertions(+) create mode 100644 skills/meta/bespoke-composition.md diff --git a/.gitignore b/.gitignore index b6a5e0d..ddff2fe 100644 --- a/.gitignore +++ b/.gitignore @@ -81,6 +81,9 @@ node_modules/ # Remotion build output and copied project assets (regenerable at render time) remotion-composer/out/ +# Project-local bespoke ("atelier") compositions — hand-authored per video, +# throwaway and regenerable. Keeps the shared src/ free of one-off scenes. +remotion-composer/projects/ remotion-composer/public/* # But keep demo props (shipped with the project for zero-key demos) !remotion-composer/public/demo-props/ diff --git a/AGENT_GUIDE.md b/AGENT_GUIDE.md index 7cdf3a8..a94016b 100644 --- a/AGENT_GUIDE.md +++ b/AGENT_GUIDE.md @@ -130,6 +130,15 @@ Exception: if only one runtime is available on the machine, the agent proceeds w This rule applies to every pipeline that invokes `video_compose` — not just Wave 1. A pipeline's director skill may recommend a runtime, but that recommendation is input to the conversation with the user, not a decision. +### Composition Authoring Mode — Templated vs Atelier + +Orthogonal to *runtime* is *authoring mode*: **how** the composition is built. Present it as its own proposal decision and log it in `decision_log` (`category: "composition_mode"`). + +- **Templated** — assemble the stock `cut.type` scene-types (`text_card`, `stat_card`, `bar_chart`, …) into the `Explainer`/`CinematicRenderer` compositions. Fast, cheap, reliable — and the reason most videos look alike. Right for batch output, localization variants, quick drafts, and low-stakes internal clips. +- **Atelier** — **hand-author the composition from scratch**: bespoke scenes, a one-off theme, and motion written for this piece, rendered via `composition_mode: "atelier"` (see `video_compose` → `_render_via_atelier`). No reusable creative components; a fresh visual language every time. + +**Default to atelier for hero work** — marketing, launches, brand pieces, any single-deliverable explainer that must impress. The deciding rule: *reuse engine knowledge, never creative components.* In atelier mode the stock scene-type catalog, `hyperframes-registry` blocks, fixtures, and finished components are **off-limits** — they are frozen looks that reintroduce sameness. Before building, route through **`skills/meta/bespoke-composition.md`**, which sequences: art direction (`visual-style`) → motion principles (Disney 12 via `framer-motion`/`lottie-bodymovin`) → engine mechanics (`remotion-best-practices` + the stock components read *only as a mechanics codex*) → render via the atelier path. Close with a **distinctness review**: *could this be any other product's video? does it reuse a look I've made before?* — the inverse of "does it match the reference." Atelier costs more tokens and iteration than templated; say so at proposal so the user opts in knowingly. + ### Escalate Blockers Explicitly When a blocker occurs, the agent must surface it immediately using this structure: @@ -396,6 +405,8 @@ For these requests: See `remotion-composer/SCENE_TYPES.md` for the authoritative list and their cut schemas. Current scene types usable via `cut.type`: `text_card`, `stat_card`, `callout`, `comparison`, `hero_title`, `terminal_scene`, `anime_scene`, `bar_chart`, `line_chart`, `pie_chart`, `kpi_grid`, `progress_bar`. Overlay types include `section_title`, `stat_reveal`, `hero_title`, `provider_chip`. +These stock scene-types are the **templated** path — fast and reliable, but they are why videos look alike. For **hero work, prefer atelier mode** (hand-authored composition) over this catalog; read those types as a *mechanics codex*, not a menu to assemble. See "Composition Authoring Mode" above and `skills/meta/bespoke-composition.md`. + **When Remotion is NOT available** and `render_runtime="remotion"` was NOT locked, `video_compose` may use FFmpeg Ken Burns motion on still images. This still works but produces less engaging visuals. Mention this tradeoff in the proposal. When `render_runtime="remotion"` IS locked and Remotion is unavailable, that's a blocker — escalate, don't silently swap. When `render_runtime="hyperframes"` is locked and HyperFrames is unavailable (Node < 22, missing `ffmpeg`/`npx`, or `hyperframes doctor` reports issues), that's also a blocker. Do not substitute Remotion or FFmpeg without user approval + a logged `render_runtime_selection` decision. diff --git a/skills/INDEX.md b/skills/INDEX.md index 59ab925..d6dd1b4 100644 --- a/skills/INDEX.md +++ b/skills/INDEX.md @@ -280,6 +280,8 @@ Cross-cutting skills that apply to all pipelines: | Reviewer | `meta/reviewer.md` | Self-review protocol after every stage | | Checkpoint Protocol | `meta/checkpoint-protocol.md` | When/how to checkpoint and request human approval | | Skill Creator | `meta/skill-creator.md` | Dynamically create new skills during pipeline runs | +| Animation Runtime Selector | `meta/animation-runtime-selector.md` | Choose render runtime + animation library per scene | +| Bespoke Composition (Atelier) | `meta/bespoke-composition.md` | Hand-author a composition from scratch (hero work) — no stock scene-types; routes art-direction → motion principles → engine mechanics → atelier render | ## Style Playbooks diff --git a/skills/meta/animation-runtime-selector.md b/skills/meta/animation-runtime-selector.md index 030db9c..5e65d55 100644 --- a/skills/meta/animation-runtime-selector.md +++ b/skills/meta/animation-runtime-selector.md @@ -7,6 +7,13 @@ Meta-skill that answers two questions: Read this before authoring any animated component or composition, and whenever you're choosing `render_runtime` at proposal time. It routes you to the right Layer 3 skill so you don't waste time hand-rolling what a plugin already solves. +> **Authoring mode comes first.** Before runtime or library, decide *how* the composition is +> built: **templated** (assemble stock `cut.type` scenes) vs **atelier** (hand-author from +> scratch). Default to atelier for hero work and follow `skills/meta/bespoke-composition.md`. +> The routing below applies within either mode — but in atelier mode the stock scene-types and +> registry blocks are off-limits; you write your own. "Does a stock cut-type fit?" is **not** a +> valid shortcut for a hero piece. See `AGENT_GUIDE.md` → "Composition Authoring Mode". + ## When to use this skill Apply when: diff --git a/skills/meta/bespoke-composition.md b/skills/meta/bespoke-composition.md new file mode 100644 index 0000000..083ce76 --- /dev/null +++ b/skills/meta/bespoke-composition.md @@ -0,0 +1,133 @@ +# Bespoke Composition (Atelier Mode) + +Meta-skill for **hand-authoring a composition from scratch** instead of assembling stock +scene-types. This is the "hand-stitched every time" path: for hero pieces, every pixel of the +look is written fresh so no two videos share a visual language. + +Read this whenever you've chosen **atelier mode** for a piece (see "When to use"). It does not +hand you components — it routes you to the *principles, engine mechanics, and tool wiring* you +need so that what you build is correct, and distinct. + +> The single rule that governs everything below: **reuse engine knowledge, never creative +> components.** How Remotion resolves an asset is engine knowledge — reuse it freely. How a +> previous video looked is a creative decision — never reuse it. + +## When to use this skill (authoring mode is a proposal decision) + +OpenMontage now separates three orthogonal axes, all locked at proposal: + +- `renderer_family` — creative grammar +- `render_runtime` — technical engine (remotion / hyperframes / ffmpeg) +- **`composition_mode`** — **templated** (assemble stock `cut.type` scenes) **vs. atelier** (hand-author) + +Pick **atelier** by default for: marketing, launches, explainers that must impress, brand +pieces, anything single-deliverable where quality is the point. Pick **templated** for: batch +output, localization variants, quick drafts, low-stakes internal clips — places where reliable +sameness is fine and bespoke cost is unjustified. Present the choice to the user at proposal and +log it in `decision_log` (`category: "composition_mode"`), the same way you present runtime. + +If atelier is chosen, the stock scene-type catalog, the `hyperframes-registry` blocks, fixtures, +and any finished component are **off-limits** — they are frozen looks and reintroduce sameness. + +## The construction route + +Author in this order. Each step routes you to existing knowledge — do not skip the first one. + +### 1. Commit to an art direction *for this subject* — the divergence engine +Before writing any component, decide a visual language that fits **this** topic and no other. +Use the **`visual-style`** Layer 3 skill (CREATE mode) to lock: palette, type personality, +motion character, layout system, and **one signature device** unique to this piece. Difference +between videos is guaranteed here — not by withholding components, but by forcing a fresh +direction each time. Write it down (a short `art-direction.md` in the project) and build to it. + +Ask yourself: *what visual metaphor belongs to this subject that I have not used before?* If the +answer resembles a past piece, you haven't found the direction yet. + +### 2. Decide the motion language — principles, not presets +Reach for **principle** skills, never finished animations: +- **`framer-motion`** and **`lottie-bodymovin`** — Disney's 12 principles (anticipation, staging, + follow-through, slow-in/out, arc, timing, exaggeration, appeal). Runtime-agnostic; apply the + *principles* in your own Remotion `spring()`/`interpolate()` code. +- The HyperFrames `references/motion-principles.md` — easing as emotion, timing as weight. + +### 3. Reach for a richer vocabulary only when the concept demands it +Most scenes are Remotion primitives. Escalate when the *idea* needs it, not by default: +`gsap-*` (kinetic typography via SplitText, shape morph via MorphSVG, curved motion via +MotionPath, line-draw via DrawSVG, custom easing), `threejs-*` (3D), `d3-viz` (data-driven +custom charts — build the chart by hand; do **not** drop in the stock `bar_chart`/`line_chart`), +`manim-*` (math), `canvas-procedural-animation` (particles/weather). + +### 4. Get the engine mechanics right — the gotcha codex +This is the only place you "reuse": the engine's solved problems. These are facts about how +Remotion works, not looks. Study `.agents/skills/remotion-best-practices` (19 rule files: +timing, transitions, text-animations, transparent video, fonts, audio, sequencing, measuring +text). You may also read the stock components in `remotion-composer/src/components/` **as a +mechanics codex — to learn idioms, never to import or imitate a look.** + +Recurring mechanics that bite if you don't know them: +- **Determinism**: no `Math.random()` / `Date.now()` per frame — use Remotion `random(seed)` or a + seeded helper, or particles/easing flicker across the render. +- **Per-scene duration**: `useVideoConfig().durationInFrames` returns the *composition* length, not + your scene's. Drive scene-local timing from a passed `durationInFrames`/`Sequence`, not the global. +- **Asset paths**: URLs and `staticFile()` (public/) work everywhere; **`