gen-motion-graphics
Skill3 starsChanged 34 days agoMITView on GitHub
Make narrated motion-graphics videos (YouTube intros, explainers, product promos) in three sequential modes. SCRIPT MODE writes a voice-over narration sized to a target duration. AUDIO MODE turns it into speech on this machine with the network blocked (Kokoro, or Qwen3-TTS or VoxCPM2 for Korean), with a choice of voice, samples and speeds. VIDEO MODE asks whether to trim the pauses (they stay by default), adds beat-matched royalty-free lo-fi music, and builds a standalone HTML animation (the default), or also a YouTube-ready MP4 when the user chooses it. Use it whenever the user runs /gen-motion-graphics, says "ENTER SCRIPT MODE", "ENTER AUDIO MODE" or "ENTER VIDEO MODE", or asks for a narration script for a video, a local text-to-speech voice-over, or an animated video made from narration audio, even if they do not name the skill.
In this repository8 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- 2020-hindsight-scalaSkill
- centralize-ai-outputSkill
- pr-analysisSkill
- riper-5Skill
- setup-metals-mcpSkill
- setup-serena-mcpSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 4 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 51
Read the reference for a mode when you enter it, not before:
- Very specific: line 63
Run sh <skill>/scripts/video-output-choices.sh from the current folder.
- Very specific: line 68
If central_error is set, show the message to the user.
- Distinctive: line 77
Do not ask, and tell the user which folder is used, when:
- Distinctive: line 109
Never paste the narration, or long parts of it, into a web search, a web fetch, or any other third-party service.
- Distinctive: line 113
Never write a key, password or token into any MCP server, the organization's own included.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
gen-motion-graphics
Turn a topic into a finished, narrated motion-graphics video through three modes that run in order:
- SCRIPT MODE writes the voice-over text. Optional: skipped when the user brings a script.
- AUDIO MODE speaks it with a local text-to-speech (TTS) model. Optional: skipped when the user brings audio.
- VIDEO MODE analyses the audio and builds the video: standalone HTML (the default), or the HTML and an MP4.
<skill> below means this skill's directory. The helper scripts are in <skill>/scripts/. The Python ones run with uv run --script (they declare their own dependencies) and print their usage with --help.
Starting
The text after /gen-motion-graphics selects the starting point. A shorthand works only here, when the skill starts. Later, modes change only through the phrases in "Modes".
| Argument | Start |
| none | Ask how to start (below) |
script, text, or narration (plus an optional prompt) | SCRIPT MODE, using the rest as the prompt |
audio (plus a text file) | AUDIO MODE. A narration text file is required. If none was given, ask for it |
video (plus an audio file and an optional script) | VIDEO MODE. An audio file is required. If none was given, ask for it |
help, --help, -h | Reply with the Markdown below the line in references/help.md, as it is (never in a code fence), and stop |
A message that says "ENTER SCRIPT MODE" (or AUDIO, VIDEO) also starts the skill, in that mode.
With an argument or a mode phrase, ask the location question alone, before the first file is written, unless "Where files go" says to skip it.
With no argument, call AskUserQuestion once with two questions. The first is "How do you want to start?" with these options:
- "Write a script (SCRIPT MODE)": a narration from a topic and a target duration.
- "I have a script": the user gives a text file, then AUDIO MODE.
- "I have an audio file": the user gives an audio file (and optionally its script), then VIDEO MODE.
- "Help": reply with the help text as for
helpabove, and stop.
The second is the location question in "Where files go". If the user picks "Help", ignore the second answer.
When a required file is missing, ask for its path. Offer any candidates found under <base>/*/sources/ when <base> is already chosen, else under ./video/*/sources/, .ai/video/*/sources/ in the project root (the Git repository root, else the current folder) and <output>/video/*/sources/ (newest first), and let the user type a path as "Other".
Modes
- While the skill is active, the very first line of every response is the current mode in brackets, before any summary:
[MODE: SCRIPT],[MODE: AUDIO]or[MODE: VIDEO]. The user then always knows which mode the session is in. - Stay in the current mode until the user says "ENTER SCRIPT MODE", "ENTER AUDIO MODE" or "ENTER VIDEO MODE". Inside a mode, take any number of revisions ("shorter", "try af_bella", "make the music calmer") without changing mode. Do not move to the next mode on your own, even when the current one is done. The user may want to edit the files first. If they ask for the next mode's work in other words ("now make the audio"), answer in one line with the phrase to say, and wait.
- Order is SCRIPT, then AUDIO, then VIDEO. A mode may be skipped only when its input exists: AUDIO MODE needs a narration text file, and VIDEO MODE needs a narration audio file. If the user asks for a mode whose input is missing, say what is missing and offer to produce it in the previous mode or to take a file from them.
- Going back is allowed. If the script changes after the audio was made, or the audio after the video, say which outputs are now out of date.
- At the end of each mode, give a short summary: what was made, where it is, and what the user should check (read the script, listen to the audio, watch the video). Then name the phrase for the next mode, for example "Edit the script if you like, then say ENTER AUDIO MODE."
Read the reference for a mode when you enter it, not before:
| Mode | Read |
| SCRIPT | references/script-mode.md |
| AUDIO | references/audio-mode.md |
| VIDEO | references/video-mode.md, which points to engine-api.md, motion-design.md and music.md when it needs them |
Where files go
Each video gets one folder, <base>/<slug>/. The user chooses <base> once, at the start, and the later modes reuse it.
Run sh <skill>/scripts/video-output-choices.sh from the current folder. Do not check the folders yourself. It prints key=value lines:
currentis<absolute current folder>/video, also in a Git repository.projectis.ai/videoin the project root, the Git repository root, else the current folder. It is empty when.aiis a symbolic link to the central folder, because then it is the same folder ascentral. Do not show it then.centralis<output>/video.<output>is the AI output folder of the current project,${AI_AGENT_OUTPUT_DIR:-~/.ai}/<project key>. The key is<host>/<owner>/<repo>from the Git remote, orlocal/<folder name>-<hash of the absolute path>when there is no remote or no Git repository. Do not calculate it yourself.- If
central_erroris set, show the message to the user. The central folder is not an option then.
Ask "Where should the video files be stored?". Show the options in the order from the script, each with the absolute path that it gives and whether the folder exists already (current_exists, project_exists, central_exists). Mark the option named by recommended with "(Recommended)". When recommended=none, mark none.
current, "Current folder":<base>iscurrent. In a Git repository, add to the description that the files can be committed by accident unlessvideo/is ignored.project, "Project.aifolder":<base>isproject. In a Git repository, add to the description that the files can be committed by accident unless.ai/is ignored.central, "Central AI output folder":<base>iscentral. Show the full path, for example/Users/me/.ai/github.com/owner/repo/video/<slug>/, and say that<slug>comes from the video's content.other, "Other": the user types a folder.<base>is that folder. Expand a leading~. A relative path is relative to the current folder. Say the resulting absolute path.
Do not ask, and tell the user which folder is used, when:
- The user's prompt names a location. That location is
<base>. - An input file is inside an existing video folder (a folder with
sources/andoutput/, under a folder namedvideo). Use that video folder again.
Ask again only if the user asks to change the location. When the first file is written for the central folder, run sh <skill>/scripts/ai-output-dir.sh once to create it. If a sandbox blocks a write, tell the user to allow writes to that folder (sh <skill>/scripts/ai-output-dir.sh --root prints the central root).
Video folders in the project are an expected place, not old files. Never offer to move them to the central folder.
<slug> is a short kebab-case summary of the video's content, for example ai-skills-intro or sourdough-basics-explainer. When starting from an audio file without a script, transcribe it first (VIDEO MODE does this anyway) and name the folder after its content. If the folder already exists for a different video, add -2, -3, and so on. If it holds the same video from an earlier session, reuse it and tell the user.
<video folder>/
├── output/ what the user asked for
│ ├── <slug>.html standalone page: plays with no other file
│ └── <slug>.mp4 YouTube-ready video (not made for "HTML only")
└── sources/ everything made along the way
├── script/ narration.txt, display.json, lexicon.json
├── audio/ narration-<voice>-<speed>x.wav
│ └── samples/ voice samples and index.html to compare them
├── music/ the downloaded track, MUSIC.md (license and credit), music.json
└── build/ narration.wav, timings, mix, video.json, scenes/, fonts/, stills/Copy files the user provides into sources/ (never move or modify their originals), so the folder is complete on its own. Do not delete or overwrite the user's own files. When regenerating something you made earlier in the same video folder, overwriting your own output is fine.
Privacy: nothing confidential goes to a third party
The narration can hold confidential information on purpose, to explain it. The user does not want it, or anything made from it, sent to a third-party service. Anthropic, which runs this conversation, is not a third party, and neither are the organization's own tools (below). Internal names and addresses may be shown and spoken in the video. This rule is only about where they are sent. So:
- Generate speech and transcribe audio only with the local models in this skill, and run those steps through
<skill>/scripts/offline.sh. This applies to every engine and every model, and no data from these steps leaves the machine.offline.shblocks all network access for the command (withsandbox-execon macOS,unshareorfirejailon Linux) and setsGEN_MOTION_GRAPHICS_NETWORK=blocked.tts_kokoro.py,tts_qwen.py,tts_voxcpm.pyandmake_timings.pyrefuse to read text or audio without it. Never set the variable yourself, and never run another speech or transcription tool outside the block. Ifoffline.shcannot block the network on this system, stop and tell the user how to make the block work (installfirejail, or allow unprivileged user namespaces). Do not run these steps without the block, even if the user asks. - The network is used only to download packages and models once (the
--setupsteps, which never include the text), to read sources the user points to, and to find and download music and fonts. - Never paste the narration, or long parts of it, into a web search, a web fetch, or any other third-party service.
- Never put a key, password, token, internal name, internal host name or internal URL into a web search, a web fetch of a site outside the organization, Claude in Chrome, or a Model Context Protocol (MCP) server of a third-party service such as context7. Internal names are project, product, team, system and customer names that are not public. If you do not know whether a name is public, treat it as internal. One word is enough to leak it.
- One exception, for pronunciation: you may look up how to say one ordinary or public word that is part of an internal name, alone. For
atlas-billing-us-2, look up "atlas", neveratlas-billing-us-2. Never look up a word that only the organization uses. When you are not sure, ask the user whether you may look the word up. If they say no, ask them how it is said. - The organization's own MCP servers, for example Jira, Slack, Notion, and GitHub for the organization's repositories, may receive the narration, internal names, internal host names and internal URLs, for example to read the ticket or the page that the video explains. Never write any of it where people outside the organization can read it: a public repository or issue, a channel shared with another company, or an email to someone outside. If you do not know whether a server belongs to the organization, ask the user.
- Never write a key, password or token into any MCP server, the organization's own included. A secret in a ticket, a message or a page spreads to everyone who can read it.
Modes in brief
SCRIPT MODE: needs a topic and a target duration (ask if the duration is missing). Writes sources/script/narration.txt: plain text, only the words to be spoken, no stage directions, sized to the duration. Spoken forms of names and symbols go in display.json so captions show the written form. Details in references/script-mode.md.
AUDIO MODE: Kokoro for English (and Kokoro's other languages). For Korean, ask the user to choose Qwen3-TTS (the default) or VoxCPM2. Check pronunciations first, ask for a voice (or make samples) and one or more speeds, then write one WAV per speed. Details in references/audio-mode.md.
VIDEO MODE: ask whether to trim the pauses (by default they stay as recorded), about the look, music and sound effects, and then whether to make only the HTML (the default) or the HTML and the MP4 (with the MP4's format) (unless already given). Then prepare the narration, time every word, and find and license-check a CC0 lo-fi track, laying a generated beat on top that is locked to it (the default), or compose an original beat in code. Mix and master to -14 LUFS, write the scenes on the bundled engine with light sound effects, check and review stills, build the HTML, and render the MP4 unless the user chose "HTML only". Captions are always on: the HTML has a CC toggle with each word highlighted as it is spoken, and the MP4 (when it is made) has them burned in unless the user says otherwise. Details in references/video-mode.md.
Scripts
| Script | Does |
offline.sh <command> | Runs a command with the network blocked |
tts_kokoro.py | Kokoro speech, voice samples, phoneme check, --setup |
tts_qwen.py | Qwen3-TTS speech for Korean, samples, --setup |
tts_voxcpm.py | VoxCPM2 speech for Korean, with a designed or cloned voice, samples, --setup. Uses the helpers in tts_qwen.py |
trim_silence.py | Cuts the silence before the first word and after the last, shortens the pauses only with --trim-pauses (any input format), writes a time map |
make_timings.py | Local Whisper word timings aligned to the script, timings.txt sheet |
fetch_music.py | Downloads a track from its FMA or OpenGameArt page, checks the license, writes MUSIC.md with proof |
compose_music.py | Composes an original lo-fi beat in code, timed to the narration, with its music.json |
analyze_music.py | Tempo, a beat grid precise to about a millisecond, the drop, per-bar drum levels, swing |
mix_audio.py | Beat-aligned music edit, a generated beat locked to a found track, ducking, synthesized sound effects, ending, mastering, mix.json |
fetch_font.py | Downloads and subsets a Google Fonts family for embedding |
build_html.py | Assembles the standalone page from assets/template.html and the scenes, and puts a space before each line that starts with ., so Slack shows the page as HTML |
render_video.py | --check lint, secret scan and Slack line check, --stills for review, --export-sfx sound-effect list, parallel MP4 render |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

