Imported from mouse-lin/frame-smith (
AGENTS.md). Install upstream withnpx skills add mouse-lin/frame-smith. Copyright stays with the author.
frame-smith — Agent Instructions
For OpenAI Codex and other agent runtimes that read
AGENTS.md. The full skill is atskills/frame-smith/SKILL.md. Deep reference material lives inskills/frame-smith/references/. Load what you need per phase — do not inline everything at once.
What frame-smith does
frame-smith is a director, not a renderer. It reads a brief, decides what the video is, writes a Remotion composition (.tsx), and registers it — but it does not own the runtime. It builds two registers:
- cinematic — a landscape clip,
1920×1080 · 30fps, ~12–24s, pure visual, no voiceover (music + SFX still apply), ending on a wordmark/logo payoff. - short — a vertical clip,
1080×1920, for 抖音/小红书/视频号, may carry subtitles + voiceover, hook by ~1.5s. Obeys theS = width/720scale system and 抖音 safe zones.
The through-line both share: high motion craft, zero motion-slop — the motion craft floor and the anti-slop blacklist.
0. ENVIRONMENT GATE — hard requirement, run FIRST
frame-smith cannot render on its own. At least one of the hyperframe or remotion skills (or a Remotion project on disk) must be present — see skills/frame-smith/references/environment.md, or run bash skills/frame-smith/scripts/check-runtime.sh.
- Neither present → STOP. Write no
.tsx. Report it and offer install (hyperframepreferred — carries the effect templates;remotion= leaner runtime). Ask for a path before assuming any; never hardcode one. - One present → record which (it decides where the composition lands + how to register/preview), then proceed.
Commands (targeted iteration)
A full build runs the whole workflow below. For iterating on an existing composition, route the request through one verb instead of rebuilding — Codex has no slash commands, so map the user's intent to the verb and load only that reference. The env gate (§0) still runs first for any verb that writes or renders.
| Verb | Intent it matches | Load |
|---|---|---|
craft |
"make me a promo video / a片头 / HyperFrame clip" (default) | full workflow |
env |
"is the runtime set up?" — report runtime or install path, read-only | references/environment.md |
engine |
"wrong effect / this vibe is off" → swap the effect engine, keep beats | references/effect-catalog.md |
beats |
"timing's off / drags in the middle" → re-cut the timeline | references/beat-structure.md |
reveals |
"text all comes in the same way / entrances are boring" → re-choreograph entrances/exits | references/reveals.md |
sound |
"wrong music / 换配乐 / 音效不对 / 音画不同步" → re-score audio | references/sound-design.md |
slower / faster |
"too frantic" / "too flat, dead" → re-time, ENERGY ∓ | references/motion-floor.md |
register |
"make it vertical / 竖屏 / 抖音" → re-orient landscape↔vertical | references/motion-floor.md |
restage |
"improve / fix this clip" → audit-first, never full-rebuild | references/anti-cheap-motion.md + references/preflight.md |
audit |
"is this any good?", "review it" — read-only, never edits | references/anti-cheap-motion.md + references/preflight.md + references/showcraft.md |
For a single complaint, change one thing, keep the engine + beats, then re-run the relevant pre-flight gates.
Mandatory workflow (execute in order)
1. Frame Read — before any code
After the env gate passes, read the brief and determine the register. Output exactly:
Lazy default (rejected): {the obvious motion cliché for this brief}
Frame Read: {subject} · {mood in 2–3 words} · register={cinematic|short} · engine={the one effect engine} · duration={n}s · ENERGY={n} SPECTACLE={n} DENSITY={n}
Beats: {H0 hook} → … → {Hn payoff}
Then stop for confirmation. Do not generate code yet. Assert the direction, invite a veto — never a menu of adjectives.
2. Set the three dials
- ENERGY (1–10): tempo & attack of the motion.
- SPECTACLE (1–10): how technically-ambitious the effect engine is.
- DENSITY (1–10): information on screen per beat.
If SPECTACLE ≥ 7 you MUST ship a working engine (a real CSS-3D solid / particle burst / mask theme-flip / counters), not a gradient pulse. Can't ship it in scope? Drop to 4–5 and ship an impeccably-timed simpler clip.
3. Lay the motion craft floor (both registers)
Non-negotiables — see references/motion-floor.md:
const FPS = 30; const f = (s) => Math.round(s*FPS);— time authored in seconds, never raw frames.const clampOpts = { extrapolateLeft:'clamp', extrapolateRight:'clamp' };on everyinterpolateover a time range.- Easing over
linear(Easing.out(cubic/exp/back),spring); holds are flat segments in a piecewiseinterpolate. - Animate
transform/opacityonly — nevertop/left/width/height. - The export三件套:
X,XCover(a still),X_FRAMES(duration const). - short only:
S = width/720on every pixel; keep content inside 抖音 safe zones (top 160 / bottom 220 / left 44 / right 120 @1080p).
4. Pick ONE effect engine
One load-bearing engine, done at 100% — from references/effect-catalog.md:
- Poster-cube tumble — CSS-3D poster cube + editorial overlay (many small visuals / design brand).
- Capsule theme-flip — stadium/pill mask sweeping light→dark (a transform / before-after / playful).
- Architecture data-pulse — trapezoid envelopes + counters + network lines + gallery wipes (data / metrics / real photos).
- Particle-burst album — SVG stroke-writing + particle burst + 3D ring carousel + spring-explode (photos / memories / emotional).
Sub-effects (counters, wipes, overlay grid) may garnish; there is one load-bearing engine. transform/opacity only; simplify if it janks; design the terminal frame for XCover.
5. Lay the beat timeline
references/beat-structure.md: fix H0…Hn in seconds, one job per beat, the first beat earns the next second (short: hook by ~1.5s), the last beat lands a designed payoff (also the XCover still), no dead air. export const X_FRAMES = HEND;.
6. Choreograph the reveals
references/reveals.md: how text/elements enter & exit is the readable surface. Vary the vector, stagger siblings (~f(0.04–0.08)), mask the edge (masked line rise), match granularity to text length (per-char only on short wordmarks), give the hero its own move, resolve elements out (enter × (1−exit)). The #1 slop is everything fading-up together.
7. Score it — sound design
references/sound-design.md. Sound is half the craft; not optional on cinematic either. BGM matched to ENERGY + genre with head/tail fades; 3–6 SFX accenting the key beats (whoosh/impact/click/riser); duck BGM under voiceover (short); and lock audio-visual sync — every SFX <Sequence from={Hn}> and the BGM drop land on the same beat frame as their picture. Reads-silent is mandatory (muted autoplay).
8. Write & register
references/registration.md: export三件套; register the <Composition> + …Cover pair in the runtime's Root with durationInFrames = X_FRAMES, fps={30}, and the register's width/height. An unregistered composition is invisible and unrenderable.
9. Pre-flight before declaring done
references/anti-cheap-motion.md + references/preflight.md, then the quality rubric in references/showcraft.md. Mandatory gates:
- Env gate passed before writing; composition in the right runtime dir.
- 30fps,
f(sec), everyinterpolateclamped,transform/opacityonly. - One engine, shown (SPECTACLE claimed = shown); no jank / cut-off.
- One job per beat; hook fast; last beat lands a payoff; no dead air.
- Reveals varied + staggered; hero has its own move; not everything-fades-up.
- Sound present + matched + synced (SFX on beat constants, BGM drop on peak); reads silent.
- Export三件套 +
<Composition>pair registered;durationInFrames === X_FRAMES. - short: inside 抖音 safe zones; subtitles split by punctuation.
- Proved it moves (Studio preview or a still render at the peak frame).
If any gate fails: fix it. Do not ship and note it as a known issue.
Reference files
| File | Load when |
|---|---|
references/environment.md |
§0, first — detect the runtime, install/bootstrap when neither is present, on-disk fallback (ask for the path, never hardcode) |
references/motion-floor.md |
Every build — the craft floor: 30fps, f(sec), clampOpts, easing library, trapezoid, S-scale + 抖音 safe zones (vertical), export三件套, terminal-frame discipline |
references/effect-catalog.md |
Picking the engine — the four archetypes + reusable sub-effects (3D solids, mask theme-flip, trapezoid counters/network/wipes, SVG stroke-writing + particle burst + 3D ring) + the editorial overlay kit |
references/effects-menu.md |
The user-facing "à la carte" menu (视频动效清单) — a browsable list of every effect (engines · reveals · transitions · overlays · 3D · sound) with "what it looks like" + "how to ask for it". Show it to the user when they ask what's possible, or to parse a user who named specific effects |
references/beat-structure.md |
The timeline — H0…Hn, one job per beat, hook-in-1.5s (short), wordmark payoff (cinematic), narrative skeletons, making the last beat land |
references/reveals.md |
Any time text/elements enter — masked line rise, per-char/word/line, clip-path wipe, blur/focus-pull, scale-pop, stagger discipline, exit choreography |
references/sound-design.md |
Every clip that has sound (all of them) — <Audio>/<Sequence> mechanics, BGM matching + fades, the SFX→beat map, ducking, and audio-visual sync |
references/showcraft.md |
The quality rubric — the four layers (engine · rhythm · reveals · sound) + sync, a 10-point score, and the one-line test. Use during audit or when a clip "feels off" but pre-flight passes |
references/registration.md |
Writing & registering — export三件套, the <Composition> + …Cover pair, dimensions, prove-it-moves |
references/anti-cheap-motion.md |
Before any delivery — the motion + audio anti-slop blacklist |
references/assets.md |
Real imagery / fonts / audio — staticFile(), font-loading roads, objectFit discipline, generate-vs-source-vs-placeholder with its authorization step |
references/preflight.md |
Final pass/fail checklist + prove-it-moves |
templates/PosterCubeTumble.tsx |
A runnable skeleton (placeholder content, zero assets) to copy & adapt for a poster-cube clip |
scripts/check-runtime.sh |
The §0 runtime gate as a script |
Out of scope
Live-action video editing (no code), pure audio tasks, static images/posters (a design-skill job), or anything needing a video runtime the §0 gate can't find and the user won't install. frame-smith does not own the runtime — if there's no hyperframe/remotion skill and no Remotion project on disk, its job is to say so and guide install, not to fake a render.