An agent skill that turns a real web workflow into a finished tutorial MP4 — verified first, narrated in Korean, captured with restrained on-screen direction, and QC'd before it ships.
Overview · Install · Safety model
Most "make me a screencast" prompts fail the same way: the agent describes a UI it never opened, guesses at timing, and hands back a video where the click misses and the last frame proves nothing. This skill closes those gaps with a single production contract (tutorial-plan.json) and validation gates between every phase.
- Preflight — routes each phase to the right browser, classifies side effects, checks tool availability.
- Reconnaissance — explores the real product without recording; finds the shortest beginner path.
- Rendered rehearsal — executes that path once in a real browser and observes the success state.
- Lock the contract — writes
tutorial-plan.json; one scene = one learner goal. - Narrate first — generates Korean Supertonic audio, then derives scene timing from measured audio duration instead of guessed reading speed.
- Capture — one clean take per scene against the locked plan, with focus rectangles, click pulses and short callouts.
- Render — FFmpeg, explicit stream mapping, H.264/AAC.
- QC — probes streams/duration/fps, extracts one review frame per scene into a contact sheet.
A script, a timing sheet and a browser plan kept in three places drift apart by the second revision. Here they are one file, validated at three stages:
python web-tutorial-video/scripts/validate_plan.py tutorial-plan.json --stage planning
python web-tutorial-video/scripts/validate_plan.py tutorial-plan.measured.json --stage narrated
python web-tutorial-video/scripts/validate_plan.py tutorial-plan.captured.json --stage capturedEvery scene must declare a learner goal, narration, one semantic action, an observable success condition, timing, and a side-effect class. A scene that cannot state how it proves itself does not pass planning.
The skill treats page content as untrusted data — DOM text, console output, network bodies and dialogs never gain authority over the task. Actions are classified before rehearsal:
| Class | Policy |
|---|---|
read_only |
execute normally |
reversible_demo |
demo/staging account, cleanup ownership recorded |
consequential |
defaults to stop_before_commit — a tutorial request is not authorization to send, publish, purchase or delete |
Copy the skill directory into whichever skills directory your harness reads:
# Claude Code
cp -R web-tutorial-video ~/.claude/skills/
# Codex CLI / OpenCode / other agents.md-compatible harnesses
cp -R web-tutorial-video ~/.agents/skills/| Tool | Needed for | Install |
|---|---|---|
ffmpeg / ffprobe |
render + QC | brew install ffmpeg |
supertonic |
Korean narration | pipx install supertonic (first run downloads the model) |
| a rendered browser | rehearsal + capture | agent-browser, Playwright, or Chrome DevTools MCP |
Check what is present before starting:
python web-tutorial-video/scripts/preflight.pypython web-tutorial-video/scripts/package_check.py web-tutorial-video # hygiene: no __pycache__, HARs, auth state, secrets
python web-tutorial-video/scripts/self_test.py # deterministic end-to-end renderDiagram scenes and SVG. FFmpeg reads SVG only when it was built with librsvg, and Homebrew's default build was not (
ffmpeg -decoders | grep svgreturns nothing).render_tutorial.pydetects this and rasterizes the SVG through the first available ofrsvg-convert,resvg, ImageMagick, or Inkscape.preflight.pyreports both the decoder and the rasterizer, so you learn about a gap before you shoot rather than at render time. With none of them installed, pointmedia.imageat a PNG.
| Script | Purpose |
|---|---|
preflight.py |
report command availability and route candidates |
validate_plan.py |
gate the plan at planning / narrated / captured |
supertonic_segments.py |
synthesize per-scene Korean WAVs, write measured timing back into the plan |
capture_cues.py |
compact cue sheet for the capture session |
make_diagram.py |
deterministic SVG explainer from a small declarative spec |
render_tutorial.py |
concat scenes to normalized H.264/AAC MP4 |
build_captions.py |
SRT sidecar from measured durations |
validate_tutorial.py |
machine QC + per-scene review frames + contact sheet |
package_check.py / self_test.py |
package hygiene and end-to-end smoke |
web-tutorial-video/
├── SKILL.md # the skill itself — workflow + invariants
├── references/ # loaded on demand
│ ├── security.md # trust boundary, side-effect classes, cleanup ledger
│ ├── browser-routing.md # which controller for which phase
│ ├── plan-contract.md # scene design + semantic targets
│ ├── narration.md # Korean TTS style + pronunciation gate
│ ├── visual-direction.md # overlay grammar, zoom discipline
│ └── verification.md # machine gate + semantic gate + audio gate
├── schemas/ # tutorial-plan JSON Schema
├── examples/ # worked plan
├── assets/tutorial-overlay.js # focus box, click pulse, callout, chapter banner
├── scripts/
└── evals/ # behavioral rubric + adversarial cases
MIT — see LICENSE.