[Documentation] Use when generating, smart-merging or refactoring the root AI context (CLAUDE.md, AGENTS.md) and its Claude/Codex projections. Config file only: project-config.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
[User-Invoked] Use when creating, updating, or previewing Remotion videos.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
[IMPORTANT] Use
TaskCreateto break ALL work into small tasks BEFORE starting. Keep task depth proportional to the work. MUST ATTENTION wait for user approval of scene plan (Step 3.3) before writing any files — NEVER skip. MUST ATTENTION read existing project files before modifying — NEVER overwrite scenes blindly. MUST ATTENTION updatetotalChaptersin ALL existing scene files when adding/removing scenes.
Be skeptical. Apply critical thinking. Every claim needs traced proof, confidence >80% to act.
Goal: Create new Remotion video project, add/update scenes in existing one, or launch local Remotion Studio preview server.
Two Modes:
| Mode | When | Action |
|---|---|---|
| Create / Update (default) | User describes video content OR asks to update/add scenes | Scaffold new project or modify existing scenes |
| Play | User says "play", "preview", "open studio", "watch", "start server" | Find Remotion project → npm run studio |
Default project path: remotion/ (relative to workspace root). Respect any path user explicitly provides.
Key Rules:
totalChapters consistent across ALL scene filesuseCurrentFrame() — CSS transitions FORBIDDEN<Img>, <Video>, <Audio>) instead of native HTML elementsImplementing one of these? Copy from refs/ — do NOT implement from memory:
| Implementing... | Copy from |
|---|---|
{source-root}/components/Shared.tsx (new scaffold) | refs/Shared.tsx — C palette, ProgressBar, ChapterBadge, CodeBlock, Pill, AnimRow |
{source-root}/utils/animations.ts (new scaffold) | refs/animations.ts — easeOut, easeInOut, pop, staggeredEaseOut, counter |
| Typewriter or word-highlight text effect | refs/text-animations.tsx — getTypedText, Cursor, TypewriterScene, Highlight |
| TikTok-style captions with word highlight | refs/captions.tsx — CaptionedVideo, CaptionPage, delayRender, createTikTokStyleCaptions |
| Video/audio duration, dimensions, frames | refs/mediabunny-utils.ts — getVideoDuration, getAudioDuration, getVideoDimensions, canDecode, extractFrames |
| Mapbox map scene | refs/maps-mapbox.tsx — MapScene component, interactive:false, camera animation |
| ElevenLabs TTS voiceover generation | refs/generate-voiceover.ts — TTS script + calculateMetadata integration |
Classify prompt:
PLAY keywords → "play", "preview", "open studio", "start server", "watch", "launch", "dev server"
CREATE/UPDATE → everything else (default)
Ambiguous → proceed with Create/Update (safe default).
Locate Remotion project before acting:
# Check default path
ls remotion/package.json 2>/dev/null
# Check if CWD is already a Remotion project
ls package.json 2>/dev/null | xargs grep -l '"remotion"' 2>/dev/null
# Check common paths
find . -maxdepth 3 -name "package.json" -exec grep -l '"remotion"' {} \; 2>/dev/null | head -5
State after detection:
PROJECT_EXISTS = true/falsePROJECT_PATH = remotion/ (default) or detected pathHAS_STUDIO_SCRIPT = true/false (check package.json scripts.studio)When: User explicitly asks to preview / open studio / launch dev server.
If PROJECT_EXISTS = false:
"No Remotion project found. Run
/remotion <description>to create one first." Exit.
cat {PROJECT_PATH}/package.json | grep '"studio"'
# → use: npm run studio
# → fallback: npx remotion studio
cd {PROJECT_PATH} && npm run studio
Remotion Studio launches at http://localhost:3000
Server runs in background. Report URL and composition IDs visible in {source-root}/Root.tsx.
npx remotion still [composition-id] --scale=0.25 --frame=30
# At 30fps, --frame=30 = one-second mark (zero-based)
| Condition | Action |
|---|---|
PROJECT_EXISTS = false | Scaffold new project → Phase 3.2 |
PROJECT_EXISTS = true | Read existing project → Phase 3.4 |
Only when no existing Remotion project found.
# Creates {PROJECT_PATH}/ with blank template (no Tailwind)
npx create-video@latest --yes --blank --no-tailwind {PROJECT_PATH}
cd {PROJECT_PATH}
npm install @remotion/transitions # add transitions support
Replace generated {source-root}/ with project structure below (keep package.json and tsconfig.json from scaffold).
npx create-video unavailablemkdir -p {PROJECT_PATH}/{source-root}/compositions {PROJECT_PATH}/{source-root}/components {PROJECT_PATH}/{source-root}/utils
cd {PROJECT_PATH}
npm init -y
npm install remotion @remotion/cli @remotion/transitions react react-dom
npm install -D @types/react @types/react-dom typescript
{PROJECT_PATH}/
package.json ← scripts: studio, render, still
tsconfig.json
{source-root}/
index.ts ← registerRoot
Root.tsx ← register compositions
components/
Shared.tsx ← palette + reusable UI components
utils/
animations.ts ← easeOut, staggeredEaseOut, pop, counter
compositions/
{CompositionName}.tsx
package.json scripts (merge into existing after install){
"scripts": {
"studio": "remotion studio",
"render": "remotion render {CompositionId} out/video.mp4",
"still": "remotion still {CompositionId} --frame=0 out/still.png"
},
"remotion": {
"entryPoint": "{source-root}/index.ts"
}
}
tsconfig.json{
"compilerOptions": {
"target": "ES2020",
"lib": ["dom", "ES2020"],
"jsx": "react-jsx",
"module": "commonjs",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "dist"
},
"include": ["src"]
}
{source-root}/index.tsimport { registerRoot } from 'remotion';
import { Root } from './Root';
registerRoot(Root);
{source-root}/components/Shared.tsxCopy from
refs/Shared.tsx— do NOT implement from memory. Exports:C(palette),ProgressBar,ChapterBadge,CodeBlock,Pill,AnimRow. Always create; all scenes import from here.
{source-root}/utils/animations.tsCopy from
refs/animations.ts— do NOT implement from memory. Exports:easeOut,easeInOut,pop,staggeredEaseOut,counter.
MUST ATTENTION wait for user confirmation before implementing any scenes.
Plan composition before writing files:
Scene01Intro, Scene02{Topic}, etc.Present plan before writing files:
Proposed: {N} scenes, ~{total}s total
Scene 01 ({Xs}) — {topic}: {layout description}
Scene 02 ({Xs}) — {topic}: {layout description}
…
Proceed? (or adjust)
MUST ATTENTION read existing project state before any modifications.
When PROJECT_EXISTS = true:
# Read composition registry
cat {PROJECT_PATH}/{source-root}/Root.tsx
# List scene files
ls {PROJECT_PATH}/{source-root}/compositions/ 2>/dev/null || ls {PROJECT_PATH}/{source-root}/scenes/ 2>/dev/null
# Read main composition orchestrator
cat {PROJECT_PATH}/{source-root}/ClaudeAgentExplainer.tsx 2>/dev/null # or equivalent
Identify:
totalChapters / composition durationTarget only scenes affected by user's request. Preserve all unchanged scenes.
import { AbsoluteFill, useCurrentFrame, interpolate } from 'remotion';
import { C, ProgressBar, ChapterBadge } from '../components/Shared'; // adjust path
import { easeOut, staggeredEaseOut } from '../utils/animations'; // adjust path
// Data arrays at the top — keep out of component body
const ITEMS = [ ... ];
export const Scene{NN}{Name}: React.FC = () => {
const frame = useCurrentFrame();
return (
<AbsoluteFill style={{ background: C.bg, fontFamily: 'system-ui, -apple-system, sans-serif' }}>
<ChapterBadge index={NN} label="{Scene Name}" color={C.blue} />
<div style={{ position: 'absolute', inset: 0, display: 'flex', gap: 48, padding: '68px 72px 44px' }}>
{/* Content here */}
</div>
<ProgressBar chapterIndex={NN - 1} totalChapters={TOTAL} />
</AbsoluteFill>
);
};
| Element | Pattern |
|---|---|
| Eyebrow label | opacity: easeOut(frame, 0, 14) |
| Hero title | opacity: easeOut(frame, 8, 22) + translateY from 28→0 |
| Subtitle | opacity: easeOut(frame, 22, 18) |
| List items (stagger) | staggeredEaseOut(frame, i, startAt, 12, 16) |
| Cards (stagger up) | staggeredEaseOut + translateY(20→0) |
| Cards (stagger right) | staggeredEaseOut + translateX(28→0) |
| Late callout boxes | easeOut(frame, 90+, 18) |
Left/Right split (most common):
<div style={{ position: 'absolute', inset: 0, display: 'flex', gap: 48, padding: '68px 72px 44px' }}>
<div style={{ width: 400, flexShrink: 0, ... }}> {/* Left panel */}
<div style={{ flex: 1, ... }}> {/* Right panel */}
</div>
Full-width column:
<div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', padding: '68px 64px 44px', gap: 16 }}>
Centered (title/CTA scene):
<div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', padding: '72px 100px', textAlign: 'center' }}>
Card grid:
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12 }}>
| Element | fontSize | fontWeight | Notes |
|---|---|---|---|
| Eyebrow label | 14 | 700 | category color, letterSpacing: 3 |
| Hero title | 44–56 | 800 | C.text, lineHeight: 1.1 |
| Body text | 17–21 | 400 | C.dim, lineHeight: 1.6 |
| Card label | 15–16 | 700 | category color |
| Monospace detail | 12–14 | 400 | fontFamily: 'Courier New' |
| Card container | — | — | C.surface, borderLeft: 3px solid color, borderRadius: 10–12 |
import { TransitionSeries, linearTiming } from '@remotion/transitions';
import { fade } from '@remotion/transitions/fade';
import { Scene01Intro } from './compositions/Scene01Intro';
// ... other imports
const T = 18; // transition duration in frames
const D = {
s01: 210, // 7s
s02: 240 // 8s
// ...
};
const SCENES = Object.values(D).length;
export const TOTAL_DURATION_FRAMES = Object.values(D).reduce((a, b) => a + b, 0) - (SCENES - 1) * T;
const tr = () => <TransitionSeries.Transition presentation={fade()} timing={linearTiming({ durationInFrames: T })} />;
export const {
CompositionName
}: React.FC = () => (
<TransitionSeries>
<TransitionSeries.Sequence durationInFrames={D.s01}>
<Scene01Intro />
</TransitionSeries.Sequence>
{tr()}
<TransitionSeries.Sequence durationInFrames={D.s02}>
<Scene02Next />
</TransitionSeries.Sequence>
{/* ... */}
</TransitionSeries>
);
// Root.tsx
import { Composition } from 'remotion';
import { {CompositionName}, TOTAL_DURATION_FRAMES } from './{CompositionName}';
export const Root: React.FC = () => (
<Composition id="{CompositionId}" component={{{CompositionName}}} durationInFrames={TOTAL_DURATION_FRAMES} fps={30} width={1920} height={1080} />
);
// Root.tsx
import { Composition } from 'remotion';
import { MyScene } from './compositions/MyScene';
export const Root: React.FC = () => <Composition id="MyVideo" component={MyScene} durationInFrames={300} fps={30} width={1920} height={1080} />;
After creating/updating, report changed files and offer launch:
✅ Created {N} scene files in {PROJECT_PATH}/{source-root}/compositions/
Total duration: ~{X}s ({FRAMES} frames @ 30fps)
To preview: run `/remotion play` — starts Remotion Studio at http://localhost:3000
To render: cd {PROJECT_PATH} && npm run render
Root.tsx to find composition orchestrator and current scene counttotalChapters across existing scenesD.sNN entry<TransitionSeries.Sequence> blocktotalChapters in ALL existing scene files (+1){source-root}/components/Shared.tsx → C objectfontFamily in AbsoluteFill style per scene (or add global in Shared)Before implementing beyond basic scene creation, read the relevant sections of references/remotion-skill-api-recipes.md:
Keep animations frame-driven and use Remotion media components and staticFile() for public assets. Copy specialized implementations from the refs/ owners listed above.
Protocols in force (concise digest of the SYNC/shared blocks this skill carries):
totalChapters in ALL scene files when adding/removing scenes — one missed file causes visual regressionconst ITEMS inside component functionnpx create-video@latest --yes --blank --no-tailwind for scaffold — NEVER npm init unless fallback neededstaggeredEaseOut for list/card reveals — NEVER all-at-once opacityPROJECT_EXISTS before Play mode — report missing project and exituseCurrentFrame() — CSS transitions, CSS animations, Tailwind animate/transition classes FORBIDDEN<Img>, <Video>, <Audio> — NEVER native HTML elementsstaticFile() for all public/ folder assets — NEVER raw relative pathsrefs/ file — NEVER implement text animations, captions, mediabunny, maps, or voiceover from memory아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
[Documentation] Use when generating, smart-merging or refactoring the root AI context (CLAUDE.md, AGENTS.md) and its Claude/Codex projections. Config file only: project-config.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
[Code Quality] Use when a workflow step or the user asks for AI code or plan review: LLM calls, prompts, agents, RAG, evals and guardrails. --mode={code|plan}; --report-only is read-only.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
[Architecture] Use when a workflow step or the user asks for architecture design, compliance review, scalability grading or whole-project audit via --mode={design|review|scalability|full}.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
[Content] Use when a workflow step or the user asks for product/feature ideation with ranked opportunities and validation tests. --mode={roadmap|scope}.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
[Content] Use when a workflow step or the user asks for business viability: Business Model Canvas, financials, risks and go-to-market recommendation.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
[Code Quality] Use when a workflow step or the user asks for a focused code-change review: staged, unstaged, branch diff or simple pull request. --fix-loop fixes and re-reviews. Complex pull request: workflow-review-changes; rationale: why-review.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.