Atlas / Skills / verbodh-pte-ltd / motion-skills

motion-skillsBLOCK

skills/verbodh-pte-ltd/motion-skills

Claude Code skills: animated explainer films, web films with Motion, training guides and narrated training videos

Verdict
BLOCK
Grade
D
Trust score
69 /100
Version
—
Hosts
3 documented
License
MIT
Stars
0
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

[](https://github.com/verbodh-pte-ltd/motion-skills/actions/workflows/test.yml) [](LICENSE)

Video as code, on any Claude Code plan. Four skills for Claude Code (and Codex or any agent that reads a SKILL.md) that turn work you already do into short films and training material:

Every film is code, so a re-render gives the same film, frame for frame. Drafts are free: they use your system voice. An ElevenLabs voice is optional, for the final cut only.

Install

In Claude Code:

/plugin install motion-skills --marketplace verbodh-pte-ltd/motion-skills

Older Claude Code: /plugin marketplace add verbodh-pte-ltd/motion-skills, then /plugin install motion-skills@motion-skills. For Codex, or to copy the folders yourself: python scripts/install.py --help. All options: docs/INSTALL.md.

Check your machine

git clone https://github.com/verbodh-pte-ltd/motion-skills.git
python motion-skills/scripts/check.py

It says, per skill, ready or not ready, and prints the install command for each missing tool on your OS (macOS, Windows or Linux). It instal

Read from source at commit 028d4c9d40f1OBSERVED · 2026-10-13
02

Install

Commands as the repository documents them. They are shown, not run.

git clone https://github.com/verbodh-pte-ltd/motion-skills.git
git clone https://github.com/verbodh-pte-ltd/motion-skills.git
03

Host compatibility

What the documentation claims. We have not run a compatibility test.

HostStatusNotes
claude-codementioned
codexmentioned
copilotmentioned
04

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: motion-video
description: Make a short motion film (about 10–30 seconds) that explains one product idea — no camera footage, no voice, no video editor. Each scene is Manim code computed from the clock, the music is an original score written as notes and sound effects timed to the scenes, and one command renders the MP4. Use when the user asks for a "motion video", "motion artifact", "20-second explainer", "animated explainer", "product teaser" or a short animated clip for a social post or a landing page.
---

# Motion film for one product idea

The film is code. Every shape, line of text and movement is a Manim animation, and the score
is a list of notes in `film.json`. A re-render gives the same film, frame for frame. No
ElevenLabs, no stock music, no footage: the film costs nothing to make again.

For a walkthrough over screenshots, use the `training-video` skill. For web-style motion and
an optional voice, use `motion-web-video`. This skill is for short films without a voice.

```bash
M="${CLAUDE_SKILL_DIR}/scripts/motion.py"
```

Tools: Manim Community, `ffmpeg` and `ffprobe`. The score uses the Python standard library only.
On a Mac: `brew install ffmpeg` and `uv tool install manim`.

On Windows, install the tools like this:
- `winget install --id Gyan.FFmpeg -e` and `uv tool install manim`. Open a new shell, so that
  `ffmpeg` is on the PATH.
- Use `python`, not `python3`. Use `font="Segoe UI"`, because Windows has no Helvetica Neue.
- To play a draft, use `start <dir>\draft.mp4` instead of `open`.

## 1. Read the product first
- Read the product's own source of truth: its site, its docs, or the feature plan. Write down the one idea the film shows, in one sentence.
- Every claim on screen must be true today. A feature that is only on dev or only planned is
  not shown as live.

## 2. Ask two questions only
Ask with AskUserQuestion, both in one call. Skip any question that the request already answers.
- **Visual style:** offer 3 film ideas named after the picture, for example "Reach and fence",
  "Plan as a flow", "Before / after". Give each a one-line description of the scenes.
- **Colours:** offer the product's own palette first, then 2 others. Give hex values.

Default when nothing is said: 16:9 shape, about 20 seconds, 4 scenes.

## 3. Plan the scenes
Write the plan in 3–5 lines, one per scene: name, seconds, what moves. A common shape:
1. **Wake** (3 s): the subject appears.
2. **Problem** or **Reach** (5–6 s): what goes wrong, or what it touches.
3. **Answer** (6–7 s): the product acts on it.
4. **Close** (3–4 s): product name and tagline, held still at the end for the poster frame.

## 4. Make the folder and write the scenes
Folder: `<scratchpad>/motion-<slug>/`. Write `scenes.py`, one Manim `Scene` class per scene,
and write them one at a time. After each scene, run a draft and look at one frame.
- Set `self.camera.background_color` in every scene, and use the same colour constants.
- Each scene starts from what the last one left on screen. Re-create that state at the start
  of the next scene with no animation.
- Use `Text(..., font="Helvetica Neue")` or the product's font. The default font is a serif.
- No LaTeX (`Tex`, `MathTex`): use `Text`.
- **9:16 and 1:1 trap:** Manim keeps the frame width, so a row that fills 16:9 looks small in
  a tall frame. Stack content vertically and scale it up for 9:16.

## 5. Write the score in `film.json`
```json
{"shape": "16:9", "scenes": ["Wake", "Reach", "Fence", "Close"],
 "score": {"master": 0.8, "events": [
   {"type": "pad",  "scene": "Wake",  "at": 0,   "pitches": ["C3", "G3", "E4"], "len": "scene", "gain": 0.1},
   {"type": "hit",  "scene": "Wake",  "at": 0.2, "sound": "whoosh", "gain": 0.4},
   {"type": "note", "scene": "Reach", "at": 0.5, "pitch": "E5", "len": 0.3, "wave": "triangle"},
   {"type": "hit",  "scene": "Fence", "at": 1.2, "sound": "thud", "gain": 0.6}]}}
```
- `scenes` sets the order. `at` is seconds from the start of that scene, so a cue stays on its
  movement when an earlier scene changes length.
- `note`: one tone (`sine`, `triangle`, `square`, `saw`). `pad`: a soft chord under a scene.
  `hit`: a sound effect (`thud`, `pop`, `tick`, `whoosh`). `"len": "scene"` lasts to the scene end.
- Put a `hit` or a `note` on each thing that lands on screen. Use one pad chord per scene, and
  keep each scene's chord in one key.
- The mix is normalised to `master`, so stacked notes never clip.

## 6. Draft, then final
- Draft (half size, 15 fps, a few seconds): `python3 $M <dir> draft` → `<dir>/draft.mp4`. It
  prints each scene's start and end time.
- **Look before you report.** Take frames from the middle of each scene and view them:
  `ffmpeg -loglevel error -y -ss <sec> -i <dir>/draft.mp4 -frames:v 1 <dir>/f<sec>.png`.
- **Check that the sound is in the file:**
  `ffmpeg -i <dir>/draft.mp4 -af volumedetect -f null - 2>&1 | grep -E "Audio:|mean_volume"`.
  You need an `Audio: aac` line and a mean volume above about −40 dB.
- Then `open <dir>/draft.mp4` so the user can watch it.
- Final, only after the user says the draft is right: `python3 $M <dir> final` → `final.mp4`
  (full size, 30 fps) and `poster.png` (taken 1 second before the end).

## 7. Deliver
- Give the path to `final.mp4` and `poster.png`, the scene plan and the one re-render command.
- Give a list of any on-screen claim you are not sure is true.
- To post it, check that the channel takes video uploads before you write the post.
- To keep it, copy `scenes.py` and `film.json` next to the post or the page that uses the film,
  so that someone can render it again.

## Check the script
`python3 ${CLAUDE_SKILL_DIR}/scripts/test_motion.py` checks the pitch maths, the cue
timing, the `"len": "scene"` length, the master level and that the sound effects come out the same each time.
05

Trust audit

BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (3 observation(s))
Network
declared (9 observation(s))
Shell
declared (2 observation(s))
Dependencies
pinned
Secrets in source
none-found

Findings (9)

CRITICALObfuscation / stealth · obf.decode_then_exec · CWE-506, CWE-94
skills/training-video/scripts/guide_video.py:122
b64decode( ... subprocess.
Why it matters. decodes a payload and executes it
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
skills/motion-web-video/SKILL.md:122
node $R <dir> edit      # prints http://127.0.0.1:<port>/film.html?edit ; Ctrl+C to stop
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
skills/motion-web-video/scripts/render.mjs:80
const target = await (await fetch(`http://127.0.0.1:${port}/json/new?about:blank`, { method: "PUT" })).json();
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
skills/motion-web-video/scripts/render.mjs:141
const url = `http://127.0.0.1:${server.address().port}/film.html?render`;
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
skills/motion-web-video/scripts/render.mjs:199
await openFilm(chrome.send, `http://127.0.0.1:${server.address().port}/film.html?render`, 1);
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
skills/motion-web-video/scripts/render.mjs:209
console.log(`Open http://127.0.0.1:${server.address().port}/film.html${mode === "edit" ? "?edit" : ""}  (Ctrl+C to stop)`);
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
skills/training-guide/scripts/session_screenshots.py:51
p.write_bytes(base64.b64decode(src["data"]))
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
skills/training-video/scripts/guide_video.py:122
return base64.b64decode(res["audio_base64"]), {"text": text, "starts": a["character_start_times_seconds"], "ends": a["character_end_times_seconds"]}
INFOSupply chain · prompt.pipe_to_shell · CWE-829, CWE-1357
docs/INSTALL.md:54
| uv | `brew install uv` | `winget install --id astral-sh.uv -e` | `curl -LsSf https://astral.sh/uv/install.sh \| sh` |

Gates applied: critical_finding, no_behavioural_pass.

Audited 2026-10-13 · audit v0.4.1 · source sha 028d4c9d40f1full audit observations/trust-audit/skill/verbodh-pte-ltd__motion-skills.json · Report an issue / request a re-scan
06

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-13028d4c9d40f1BLOCKD69first audit
07

Questions

What does the motion-skills skill do?

Claude Code skills: animated explainer films, web films with Motion, training guides and narrated training videos

Is motion-skills safe to install?

No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on.

What can motion-skills access on my machine?

The audit observed that it reaches the network, runs shell commands and reads or writes files. Each of those is consistent with what it says it does. Secrets in the source: none found.

Which assistants does motion-skills work with?

Its documentation mentions claude-code, codex and copilot. That is what the text claims, not a compatibility test we ran.

How current is this page?

The grade is for one exact copy of the source (028d4c9d40f1), read on 2026-10-13. The repository is watched, and a new audit runs when it changes — this is the first audit.

Advertisement