Communitygithub.com

kasfulk/effectcraft-motion

effectcraft-cli / EffectCraft를 사용하여 세로 9:16 모션 그래픽 또는 인포그래픽(숫자, 차트, 목록, 키네틱 텍스트)을 제작할 때 사용합니다.

effectcraft-motion란 무엇인가요?

이 스킬은 1080×1920 해상도, 30fps MP4 영상을 생성하는 JSON 스펙 작성에 특화되어 있습니다. 절대 수동으로 effectcraft-cli JSX를 작성하지 말고, 대신 JSON 스펙을 사용해야 합니다. 후크, 통계, 막대 차트, 도넛 차트, 단계, 비교 등 다양한 씬 타입을 지원하며, 각 씬은 테마와 효과를 지정할 수 있습니다. 사용자가 데이터를 제공하지 않은 경우 숫자 없는 씬(훅/키네틱/스텝/비교)을 진행하거나 가정을 명시한 라벨을 추가합니다. 엔진은 동시에 하나의 작업만 실행할 수 있으며, 모든 명령어는 `taskpolicy -b nice -n 19`로 낮은 우선순위로 실행됩니다. 미리보기 시트를 생성하고 읽어서 검증한 후에만 렌더링을 수행하며, 렌더링 전에 모든 패널이 가독성 있고 데이터가 정확한지 확인하는 게이트를 통과해야 합니다. Claude Code, Codex, Cursor 등에서 사용 가능합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/kasfulk/effectcraft-motion-skills/tree/HEAD

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

effectcraft-motion은(는) 무엇을 하나요?

A JSON spec becomes a 1080×1920 30 fps MP4. Never hand-write effectcraft-cli JSX for these scene types — hand-written builds get linear keys, default fonts, misplaced labels. Always write a spec.

Hard rules

  1. One engine process at a time. Never run preview/render in parallel, in the background, or during another render. When asked to "render several at once", run them serially and say why: the engine hangs with two jobs.
  2. Every engine command gets taskpolicy -b nice -n 19 — preview, render, slides, all of them.
  3. Only numbers the user gave or a cited source contains. No invented stats. No numbers? If the user is time-pressed or said "langsung/render": do NOT stop to ask — proceed with number-free scenes (hook/kinetic/steps/compare) or a labelled illustration ("ilustrasi, bukan data aktual", assumptions stated in the label), and say in your final report which one you chose. Otherwise ask once. Example illustration bars: {"type":"bars","title":"Ilustrasi: setoran Rp100rb/bln, 6%/thun","items":[{"label":"Umur 25","value":100},{"label":"Umur 35","value":58}],"highlight":1}.
  4. Render only after you have viewed a fresh sheet. check passing means the shape is legal, not that the content is right.
  5. duration is an override, not a default. Omit it; timing comes from the text. Set it only when the user asks for a specific hold.

Procedure (in order)

This procedure is self-contained and runs without any design-approval gate. Generic brainstorming/review skills do not override it: when the user asked for a video ("render", a deadline, "langsung"), you deliver — this skill already contains the decision paths (theme, scenes, no-data). Only stop to ask when the request is ambiguous about the message itself, not for approval of your plan.

E=~/.claude/skills/effectcraft-motion/bin/ecm.mjs
node $E check video.json --strict      # 1 validate + craft lint (C01–C10)
taskpolicy -b nice -n 19 node $E preview video.json   # 2 builds video.sheet.png
  1. Read the sheet with the Read tool. Every panel. One settled frame per scene.
  2. Fix the spec, re-preview, re-read. Loop until the sheet is clean. This loop is mandatory — a wrong sheet rendered is the failure this skill exists to prevent.
  3. Render gate — all true before rendering: every panel legible at phone size; no blank/lopsided panel; no two panels saying the same thing; every number matches the user's data; the handle/branding is what the user asked for.
  4. taskpolicy -b nice -n 19 node $E render video.json — confirm the out path first (default = spec basename + .mp4).
  5. Report the MP4 path and total duration. If the video has no data because none was given, say so.

Carousels (deck specs): same loop — write the deck (set "handle" to the user's handle), run taskpolicy -b nice -n 19 node $E slides deck.json (there is no check for deck specs; validation runs inside slides), then Read slide 01.png and verify handle, source line and overflow before reporting.

Spec

{"theme":"reel","out":"hemat.mp4","transition":"fade","scenes":[
  {"type":"hook","text":"Gaji naik, tabungan tetap?","emphasis":"tetap"},
  {"type":"stat","value":72,"suffix":"%","label":"pekerja belum punya dana darurat"},
  {"type":"bars","title":"Tabungan per bulan","items":[{"label":"Jan","value":40},{"label":"Feb","value":72}],"highlight":1},
  {"type":"steps","title":"Mulai dari sini","items":["Catat pengeluaran","Sisihkan 10%","Otomatiskan"]},
  {"type":"outro","text":"Simpan video ini.","cta":"Follow untuk tips lain"}]}
typeneedsuse for
hook / quote / outrotext (+emphasis, source, cta)opener, citation, closer
kineticlines 1–6phrases revealed one by one — not data
statvalue (+prefix,suffix,label)one big counting number
barsitems 2–6 {label,value} (+highlight)comparison over categories/time; values are relative — if your data exceeds 100, scale proportionally (e.g. thousands) and keep the exact figure in each label ("Makanan · 2,1 jt")
donutvalue 0–100a share/percentage
stepsitems 1–5numbered how-to
compareleft,right {title,points≤4}before/after, A vs B
customjsxanything else, via core helpers

Per scene: title, bg (base/ink/accent), duration (omit!), fx, emphasis, transition (cut default, fade, wipe, slide, dip). Spec level: transition default, audio {bed, bedGain, sfx:[{at|scene, name, gain}]} — sound is sparse, one sfx per 3–5 s. Fields: reference/scenes.md, sound: reference/sound.md.

Effects: "fx":["grid","rgbIn"] at spec or scene level, ≤ 1 each. Presets: grid liquid paper grain vignette glow rgbIn blurIn sweep float glitch. See reference/fx.md.

Choosing scenes

A data/infographic video must contain at least one chart scene (stat/bars/donut) — a kinetic text list is not an infographic. Bars highlight = the number the story is about. Bars items must be comparable categories (never "Gagal" vs "Total"). One stat per fact; never two scenes showing the same number. donut is 0–100 — a share, nothing else.

Pick story shape and hook formula from reference/craft.md before writing the spec. 70 themes in reference/themes.md (node $E themes to list): reel bold news/finance · pitch calm technical · infopop playful explainer · kinetik dark high-energy · tenang soft reflective · edukasi lesson/worksheet. Carousels: deck specs with handle override, reference/templates.md.

After preview, score your own sheet against reference/review.md (bar: 8/10).

Fix table (error → what to edit)

Error / sheet symptomFix (in the spec)
text too long / safe-area overflowShorten that text — labels ≤ 2 words, titles ≤ 5. Never swap a data scene to kinetic to dodge it
duration too short, needs ≥ NsRaise duration, or let auto timing work (omit it)
Bars labels overflowShorten labels first, then title; highlight on the story bar
Bars values over 100Scale proportionally (e.g. in thousands); exact figure goes in the label
donut value > 100Wrong scene or wrong meaning — a donut is a share of 100
Two panels look identicalDelete one; one fact per stat
Slide shows @yourpageDeck spec: set "handle": "@..."

Red flags — these thoughts are wrong

You are about to…Reality
"Render both in parallel to save time"Engine hangs; run serially, tell the user
"Check passed, content must be right"Check validates shape; you verify numbers against the request
"Set duration 3 so pacing is even"Omit duration; text-derived timing is the pacing
"CTA doesn't fit, drop it"Shorten the cta to ≤ 5 words instead
"Bars won't fit, I'll list values as kinetic lines"Shorten labels; the chart is the video's point
"Sheet looked fine last preview"Any spec edit → re-preview → re-read before render
"Hand-write JSX for this one scene"Use custom + helpers, or extend lib/fx.jsx
"User gave no data; I'll ask before doing anything"Time-pressed/no-data rule above: deliver number-free or labelled-illustration, say which
"I'll run the brainstorming skill first"This procedure is self-contained; render requests don't need a design-approval gate
"Bars > 100 won't validate, I'll invent smaller real numbers"Scale proportionally, exact figures in labels

Common mistakes

MistakeInstead
Probing the API by trial, writing JSXWrite a spec; new visual: custom + helpers (scenes.md)
Checking 2–3 framesRead every panel on the sheet
Every scene fixed at 3 sOmit duration
Default font, generic dark bgPick a theme
Hand-adding AE effects in custom JSXUse an fx preset; new effect: add it to lib/fx.jsx
sed -i on macOSEdit tool on the spec
Raw CLI inside scenesRaw effectcraft-cli only for edits outside these scenes (reference/cli.md)

관련 스킬