agentleFS
MicrosoftKnown publishermicrosoft/vscode-team-kit/pr-studio/skills/generate-video/SKILL.md

generate-video

Skill65 starsChanged 16 days agoMITView on GitHub

Make the shortest narrated video that fully explains a GitHub pull request (at most 90 seconds, captions, diagrams chosen for the PR, and real footage of the app, before and after side by side, when the change is visible) in one white Microsoft look. USE FOR: "/generate-video 12345", "make a video of this PR", "explain PR <url> in a video", "a video for my manager about this PR". DO NOT USE FOR: a screen recording on its own (no PR to explain), editing existing videos, slide decks (use generate-presentation).

7 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

13 rules. 0 are common, 5 are distinctive, and 8 are very specific to this project.

  • 0

    Common

    Most of the 5 edited versions we read keep these.

  • 5

    Distinctive

    This author's own choices. Worth a look.

  • 8

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    The engine: run node <plugin>/scripts/setup.mjs by absolute path.

    line 33
  2. Distinctive:

    If something can't be installed (no Python 3.11–3.13), stop and say what to install.

    line 36
  3. Very specific:

    Story: Write storyboard.json (below).

    line 47
  4. Distinctive:

    Footage,: when the PR changes something a user sees or does: capture.md.

    line 55
  5. Very specific:

    Voice and scenes: Start prs voice <slug> in the background, and fill every TODO of scenes.js meanwhile (below).

    line 58
  6. Very specific:

    claims: every factual statement, as { "text": "…", "evidence": [ … ] }.

    line 86
  7. Very specific:

    Don't say a code name alone (start() → "the start method").

    line 98
  8. Very specific:

    Don't respell what the voice says well (OK, UI).

    line 99
  9. Distinctive:

    Use commas only for real pauses: captions break there, and the gate checks that the voice pauses too.

    line 100
  10. Distinctive:

    Text: every string on screen says where it comes from, and the engine checks it:

    line 106
  11. Very specific:

    Follow review.md, with prs review-pack <slug> before each round.

    line 131
  12. Very specific:

    After fixes: run prs publish and prs review-pack again.

    line 138
  13. Distinctive:

    Called by another skill or agent: don't end your turn: give it the paths and what it asked for.

    line 144

“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Generate a PR video

The shortest narrated video that fully explains one pull request: at most 90 seconds, captioned, with a diagram for each idea and, when the change is visible, the real app doing it. You write the story and fill the diagrams from the PR; the engine fetches, voices, renders, and checks every word on screen against the PR. First read contract.md.

Needs: a terminal that runs commands for minutes, and file tools (reading images, subagents and chat artifacts help). macOS or Linux with Node.js 20+, Python 3.11–3.13, and access to github.com and PyPI. Commands install what they need into ~/.cache/ on first use. gh, signed in, is optional: public PRs work without it.

The fast path: setup.mjs → prs new → storyboard.json and prs check → prs direct → footage, in a subagent if you have one (prs app, the capture kit) → prs voice in the background while you fill scenes.js → prs preview until lint is clean → prs publish → prs review-pack and the review → fixes, prs publish, prs review-pack, until signed off → deliver.

1. Find the PR and the engine

  • The PR:

    • a URL or <owner>/<repo>#<n>: use it;
    • a number alone: a PR of the workspace's GitHub repo;
    • nothing: ask.

    A calling skill may pass a brief (a code walkthrough's groups): follow it as the contract says. For a brief about a branch, use its PR (gh pr view <branch> --json url, in that repository); if it has none, say that a video needs a pull request, and stop.

  • The engine: run node <plugin>/scripts/setup.mjs by absolute path; <plugin> is two folders above this file.
    • Its last line is STUDIO=<folder>. Below, prs <x> means node <studio>/cli/prs.mjs <x>, and prs help lists every command.
    • If something can't be installed (no Python 3.11–3.13), stop and say what to install.
    • The voice is MAI-Voice-2 when AZURE_SPEECH_KEY is set or ~/.cache/pr-studio/config.json names an Azure resource (voice.mai.azResource), otherwise the offline Kokoro; prs doctor says which.

2. Make the video

About 10 minutes, or 25 with footage, reviews included. Post a one-line update after each step.

  1. Fetch. prs new <url> writes <studio>/videos/<slug>/ (the slug is <owner>-<repo>-<n>; pass it to every command): brief.md, pr.diff, the changed files, and a storyboard skeleton. If the change is visible in VS Code, start prs app <slug> --before in the background now: the builds download while you write the story.
  2. Story. Write storyboard.json (below). Run prs check <slug> until it passes, then apply the cut test.
  3. Direct. prs direct <slug> picks a diagram treatment for each beat, different from recent videos. It scaffolds scenes.js with each pick's fields and a note on how to narrate it ("names the aspects in order"): fit each say to its pick.
    • Keep the picks.
    • To re-pick one that can't show its beat: prs direct <slug> --use <beat>=<treatment> --reason "…", then prs direct <slug> --force to rewrite the scaffold (before you fill it; the picks stay). prs catalog lists the treatments. If none fits, say so in your answer.
  4. Footage, when the PR changes something a user sees or does: capture.md. It needs only the storyboard. With subagents, hand it to one now (capture.md, the slug, <studio>, and the footage beat's say and cues), and go on with the next steps while it records.
  5. Voice and scenes. Start prs voice <slug> in the background, and fill every TODO of scenes.js meanwhile (below). The voice prints what a listener hears in each beat. Fix a word "heard differently" with pronounce or other words, then run prs voice <slug> --redo <beat>.
  6. Preview. prs preview <slug> renders key frames and build/stills/contact.png, then lints. Look at the sheet, then the frames that matter, and fix until lint reports 0 problems. Lint times the screen too: text up too briefly to read is a problem (give the beat a hold, or say less), and an element named before it shows is a warning worth a look.
  7. Publish. prs publish <slug> renders, encodes, and checks the audio against the captions (the sync gate; a failure says what to fix). It then delivers the video.

The storyboard

A beat is one idea, in one to three sentences, with one diagram. Merge or drop the skeleton's beats that add no answer: a before and after can show both what changes and why.

  • id: a short word.
  • need: the kind of diagram.
    • concept: a problem, or ideas side by side;
    • exchange: messages between parties;
    • flow: steps;
    • rules: a rule applied to cases;
    • compare: before and after;
    • architecture: where it reaches;
    • code, numbers, state, ui, status.
  • say: plain sentences. The voice says why and how; numbers, names and lists go on screen. A number it must say is a placeholder: {{facts.additions}}.
  • cues: names for the phrases where things appear: "step2": "Two", or { "phrase", "nth", "offset" } (nth counts from 0: a phrase said twice cues the first time unless nth is 1).
  • claims: every factual statement, as { "text": "…", "evidence": [ … ] }. prs check verifies each piece of evidence: { "file", "anchor" } (text or a regex at the head commit; "removed": true for a removed line), { "body" }, { "commit" } or { "review" } (exact words), or { "fact": "additions" }. A count you make is a claim: anchor each thing counted.
  • "footage": true: on the beat that shows the real app.
  • "hold": 1.5: seconds (up to 5) the beat stays after its last word, when its screen needs time to be read.

The first beat (title) says what the PR does in one sentence; its card shows the number, author, size and state. The last (status) says what matters most before review or merge; its screen lists scope, tests and where to start reading.

Pronunciation. The voice splits camelCase, spells short capitals and says "dot". Anything else goes in the top-level pronounce ({ "scm": "S C M", "mcumming": "M Cumming" }).

  • Don't say a code name alone (start() → "the start method"); name a file in words and show its path on screen.
  • Don't respell what the voice says well (OK, UI). A one-word entry also works inside names; add plurals you say.
  • Use commas only for real pauses: captions break there, and the gate checks that the voice pauses too.

scenes.js

Beat keys are the storyboard ids. The engine lays everything out. Never open another video's scenes.js.

  • Text: every string on screen says where it comes from, and the engine checks it:

    • label('…'): your words (numbers in it are flagged);
    • fact('additions', { format: 'n' }): from pr.json (formats n, date, state, review, lower);
    • quote('…'): exact PR text (the body, commits, review, any diff line);
    • ident('name'): a name in the changed files;
    • path(file): a changed file.

    Mix them in an array.

  • Code: code(file, { from, to }), { anchor } (one line), { anchor, block: true } (the function), or { diff: true, anchor } (its hunk); add occurrence: n when the anchor matches several lines. Avoid long lines: the font fits the longest.
  • Time: an at is a cue name, cue('step2', 0.4), word('401', { offset: -0.2 }), or seconds into the beat. Without one, items spread over the beat.
  • Icons: prs catalog --icons lists the names.
  • Footage: a "footage": true beat gets ui.footage.
    • after: { src: 'footage/after.webm', marks: { open: 'open', click: 'click' } } plays each action marked in the recording (k.mark('click')) at the cue it maps to, at real speed, and holds its result until the next; before is the same for the app without the change. Optional: crop: [x, y, w, h], label, note, and layout: 'rows' for a wide, short part. A clip without marks takes from, to, at (its cue) and speed.
    • Narrate what happens as it happens, with a cue on each action and its result. A before and after is one beat: say the action once, then the difference ("press Save: the old build drops the selection, the new one keeps it").
    • Voicing again moves the cues, and the actions follow them: record once.

3. Review

Follow review.md, with prs review-pack <slug> before each round.

  • Reviewer inputs:
    • the PR URL, the slug and <studio>;
    • the pack's pack.md (prs review-pack prints its path);
    • from <studio>/videos/<slug>/: brief.md, pr.diff, storyboard.json, scenes.js and footage/;
    • the delivered mp4.
  • Review file: build/review.md.
  • After fixes: run prs publish and prs review-pack again.

4. Deliver

prs publish prints where it delivered the mp4 (~/Downloads/pr-videos/<slug>/ by default). That folder holds the mp4, a webm (VS Code's chat plays it in place of the mp4), the captions and contact.png.

  • Called by another skill or agent: don't end your turn: give it the paths and what it asked for. It records the artifacts.
  • With a chat-artifact tool: record the mp4 (Video: #<n> <PR title>, plus (self-reviewed) if it was) and contact.png (Key frames: #<n>), by absolute path. End your turn there.
  • Otherwise: end with the mp4's path and length, a line per beat, the verdict, and what you couldn't check.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.