vs-explain-pr
Make a short narrated video explainer of an open PR from its base...head diff, finished body, and evidence media, then add it to the PR body.
Skill by vltansky
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/vltansky-vs-explain-pr
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: agent-building
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Node.js package
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/vs-explain-pr
What's inside
- Skill name
vs-explain-pr- Description
- Make a short narrated video explainer of an open PR from its base...head diff, finished body, and evidence media, then add it to the PR body. Composed by /vs-ship-it after the PR is open (a background agent); also direct when the user types /vs-explain-pr or asks for a video of a PR. Reuses the vs-explain-video kit; produces one 1280x720 mp4 under 10 MB in a marked body block.
- License
- MIT
- Instructions
- 194 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
Files (10)
- SKILL.md
- openai.yaml · agents/
- attach.mjs · scripts/
- finish.mjs · scripts/
- lint.mjs · scripts/
- pr-video.mjs · scripts/
- prep.mjs · scripts/
- diff-first.eval.ts · test/
- explain-pr.eval.ts · test/
- explain-pr.static.eval.ts · test/
SKILL.md (first lines)
# Explain a PR in a video
A 45-75 second narrated video of one PR: the problem in a sentence or two, then
the real example (the PR's own screenshots and recordings), what changed, the
result, and where to look in review. It runs after the PR is open, so CI and
reviewers never wait for it. The video adds to the PR body; it never replaces
the written proof.
## Flow Contract
- **Kind:** Building block
- **Inputs:** PR number and repo, head SHA, base ref (the diff is
`<base>...<head>`), the final PR body file, and the record-flow manifest(s)
or media files ship-it used. Nothing else: no conversation.
- **Outputs:** `final.mp4` (1280x720, 75 seconds or less, under 10 MB) under
`~/.vs/$PROJECT_ID/videos/pr-<N>/`, and one `<!-- vs:video -->` block in the
PR body
- **Status:** `VIDEO_ATTACHED`, `VIDEO_READY` (direct use, not attached),
`GATE_FAILED`, or `BLOCKED_TOOLING` (with the install step)
- **Consumers:** `/vs-ship-it` Step 4b (one fresh-context background agent);
direct user invocation
- **Skip conditions:** No open PR. A PR the ship-it rubric marks too small.
Run every step yourself in this agent. Do not start more agents.
## 1. Check the tools
`node <skill-dir>/../vs-explain-video/scripts/preflight.mjs "$WORK"`. Exit 2:
report `BLOCKED_TOOLING` with its `next` text and stop. The PR stays as it is.
The renderer is fframes, as in explain-video: with `fframes.warmable`, run
`fframes.mjs doctor --warm` once; when `renderer` is `playwright`, use the
fallback steps (`scenes.js`) and carry the FALLBACK warning to the handoff.
`fframes.mjs init` records the renderer in `$WORK/renderer.json`; if fframes
fails later, run `fframes.mjs fallback "$WORK" --reason "<why>"` first, so
`lint.mjs` runs the fallback's page checks. A fallback sticks: a later `init`
keeps it, and only `init --fframes` switches back.
## 2. Scaffold and bring the media in
```bash
WORK="$HOME/.vs/$PROJECT_ID/videos/pr-<N>"
node <skill-dir>/../vs-explain-video/scripts/init.mjs "$WORK"
node <skill-dir>/../vs-explain-video/scripts/fframes.mjs init "$WORK"
node <skill-dir>/scripts/prep.mjs "$WORK" --manifest before=<before manifest.json> --manifest after=<after manifest.json>
```
Use `--still <name>=<file>#<caption>` and `--clip <name>=<file>#<caption>` for
media that did not come from record-flow. `prep.mjs` copies stills, transcodes
every recording to H.264 mp4 (webm seeks badly), cuts each clip's first and
last frame, and writes `media.json`. Do not open the media files. The captions
in `media.json` say what each one shows. A PR without media gets a
motion-only video; say so in the handoff.
## 3. Write the beats from the diff, then the PR body
The diff says what changed. The body says why, and holds the proof and the
media. Ship-it writes the body from a chat that can lose context, so the body
can miss a change. Do not read the conversation. Start from the diff:
```bash
node <skill-dir>/../vs-explain-video/scripts/diff.mjs "$WORK" --base origin/<base> --head <head SHA>
```
It writes `diff.json`: each changed file, with tests, lockfiles, version
bumps, and generated files marked minor. With no checkout, save
`gh pr diff <N> --repo <owner/name>` to a file and pass `--patch <file>` (keep
`--head <head SHA>`). A blocked run deletes `diff.json`.
Read the diff of each file that is not minor and write one line per change:
what it does. Then read the body file and `media.json` for the why, the
proof, and the media. The body must not contradict the diff. Write
`script.json` (format: the explain-video example) with one scene per role, in
this order, and set `"role"` on each:
`problem` → `before` → `change` → `after` → `risk`
| Role | Source | Beats |
| --- | --- | --- |
| `problem` | Body: TL;DR line 1, What problem / scenario | 1-2 beats: who is blocked and the cost |
| `before` | Body: **Before** proof | The real example: `"still"` or `"clip"` from `media.json` |
| `change` | The diff's change list; body: What was done | One mechanism, as pseudocode or a short flow |
| `after` | Body: **After** proof | Same example, same framing: `"still"` or `"clip"` |
| `risk` | Body: Review map Risk/Review, Review focus, Still unverified | Where to look first and what is not proven |
A change the diff shows and the body does not name gets a beat in `change`,
or in `risk` as "also changes" when it is small. Set `"covers"` on each scene
to the files it explains, by the exact path in `diff.json` (no directories).
Put each file you leave out in the top-level `"skip"`, with a reason of 3 or
more words. An empty diff blocks (exit 2): get the right head, never go on.
Start with the problem, then lead with the example: from `before` on, the same
user, report, or request moves through every scene. 75 seconds or less in
total (about 150 words a minute); a beat has 24 words or fewer. Write in STE
([../vs-internal-shared/references/ste-writing.md](../vs-internal-shared/references/ste-writing.md)).
Never claim more than the diff and the body prove: cut a beat the diff does
not show. Carry `Still unverified` into `risk`.
Run `node <skill-dir>/scripts/lint.mjs "$WORK" --no-page --head <head SHA>`. It
also checks `diff.json`: it must be for that head, and a changed file that no
scene covers or skips, or a `covers` entry that is not a changed file, fails. Exit 1: fix the named problems first.
## 4. Narrate
`node <skill-dir>/../vs-explain-video/scripts/narrate.mjs "$WORK/script.json" --dry-run`,
then `check-ste.mjs` on `narration.md`, then run narrate without `--dry-run`.
Use the voice and engine it picks; no voice audition. When its summary says
the words were not checked (no whisper), you must say "words not checked" in
the handoff and pass `--words-unchecked` to `attach.mjs`. Never drop it.
## 5. Write the scenes
`ff/src/main.rs` follows the explain-video rules
([../vs-explain-video/references/motion-craft.md](../vs-explain-video/references/motion-craft.md)).
Two kit helpers show the PR's media:
- `s.still("media/<name>.png", x, y, w, h, tf)` draws a card with the screenshot
fitted inside. Animate it like any block (`s.rise`, `s.pop`, `.dim`).
- `s.clip("media/<name>.mp4", x, y, w, h, tf)` plays the recording in its slot from
0.7 s into the scene to 0.45 s before its end: its first frame before, its
last frame after. Draw chips after it to put them on top. Size the slot to the clip's aspectFrom vltansky/vs, MIT.
More from vltansky/vs
- 0.570score
vs-improve
shadcn
Survey any codebase as a senior advisor and produce prioritized, self-contained implementation plans for OTHER models/agents to execute.
SkillAFreshness: AClaude Code +9 - 0.570score
vs-disk-cleanup
vltansky
Free disk space left behind by coding agents: stale git worktrees (t3code, Codex, Claude Code), old vs session artifacts under ~/.vs, and home-folder dev…
SkillAFreshness: AClaude Code +9 - 0.570score
vs-explain-video
vltansky
Make a short narrated motion explainer video about a topic, code path, or PR.
SkillAFreshness: AClaude Code +9 - 0.569score
vs-baby-sit
vltansky
Use when asked to watch a PR, fix CI, address review comments, or keep a branch merge-ready in a loop.
SkillAFreshness: AClaude Code +9 - 0.567score
vs-internal-shared
vltansky
Internal reference for vs shared conventions: artifact paths, project ID resolution, storage preference, and skill taxonomy.
SkillAFreshness: AClaude Code +9 - 0.565score
vs-eli5
vltansky
Explain a topic like I'm a 5 year old.
SkillAFreshness: AClaude Code +9 - 0.565score
vs-before-after
vltansky
Use when asked for before and after, the functional difference, what behavior changed, or the user value of a branch, PR, commit, or working-tree diff.
SkillAFreshness: AClaude Code +9 - 0.565score
vs-explain-back
vltansky
Use when the user types /vs-explain-back, or asks you to explain back, teach back, mirror, or restate their messy multi-message explanation as a clean…
SkillAFreshness: AClaude Code +9 - 0.555score
vs-bugfix
vltansky
Use when the user says fix, bugfix, broken, or describes a bug.
SkillAFreshness: AClaude Code +9 - 0.529score
vs-architect
vltansky
Use when asked to improve a codebase's architecture, find refactoring or consolidation opportunities, deepen shallow modules, reduce coupling, clarify seams…
SkillBFreshness: BClaude Code +9 - 0.529score
vs-deslop
vltansky
Use when code works but feels AI-generated, bloated, repetitive, over-defensive, or needs cleanup before review or shipping.
SkillBFreshness: BClaude Code +9 - 0.529score
vs-fix-pr
vltansky
Primary VS workflow whenever the user asks to see, check, review, address, or fix a PR, its comments or feedback, or its failing CI; handle requested changes…
SkillBFreshness: BClaude Code +9
Signals
- Stars
- 0
- Forks
- 1
- Open issues
- 1
- Last commit (this folder)
- Oct 24, 2026 (4 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/vltansky/vs
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from vltansky
- 0.570score
vs-disk-cleanup
vltansky
Free disk space left behind by coding agents: stale git worktrees (t3code, Codex, Claude Code), old vs session artifacts under ~/.vs, and home-folder dev…
SkillAFreshness: AClaude Code +9 - 0.570score
vs-explain-video
vltansky
Make a short narrated motion explainer video about a topic, code path, or PR.
SkillAFreshness: AClaude Code +9 - 0.569score
vs-baby-sit
vltansky
Use when asked to watch a PR, fix CI, address review comments, or keep a branch merge-ready in a loop.
SkillAFreshness: AClaude Code +9 - 0.567score
vs-internal-shared
vltansky
Internal reference for vs shared conventions: artifact paths, project ID resolution, storage preference, and skill taxonomy.
SkillAFreshness: AClaude Code +9 - 0.565score
vs-eli5
vltansky
Explain a topic like I'm a 5 year old.
SkillAFreshness: AClaude Code +9 - 0.565score
vs-before-after
vltansky
Use when asked for before and after, the functional difference, what behavior changed, or the user value of a branch, PR, commit, or working-tree diff.
SkillAFreshness: AClaude Code +9
Cite this page
vs-explain-pr skill. Agent Mart. https://agentmart.dev/skills/vltansky-vs-explain-pr (last updated 2026-10-24)