tutorial
Skill0 starsChanged 34 days agoMITView on GitHub
Turn raw screen-recording takes of an app into a finished, publishable YouTube tutorial — stitch the parts, cut dead air, ramp the speed, add camera framing, fix the fumbles, then produce captions, chapters, title, description, tags and thumbnails. USE WHEN the user says "edit the tutorial", "I recorded a tutorial", "/tutorial", hands over CleanShot .mp4 paths of an app walkthrough, or asks for a YouTube upload pack from a screen recording.
- Reads credentials
10 other projects use a version of this.
Adopted by
Most recently taken up by
- egregore-labs/egregoretheir own version, first seen Nov 6, 2026
- apify/apify-docstheir own version, first seen Oct 8, 2026
- me2resh/apexyardtheir own version, first seen Oct 8, 2026
- aayushostwal/nexustheir own version, first seen Aug 10, 2026
- Q00/ouroborostheir own version, first seen Jul 31, 2026
- LilithLabs/liliththeir own version, first seen Jun 20, 2026
Used with
Projects with it also use update.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
AnthropicSkillupdate
Sync tasks and refresh memory from your current activity. Use when pulling new assignments from your project tracker into TASKS.md, triaging stale or overdue tasks, filling memory gaps for unknown people or projects, or running a comprehensive scan to catch todos buried in chat and email.
Also in 3 projects that use this
Other versions10 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 10
- Q00/ouroboros★ 6.3ksame name
- agenticnotetaking/arscontexta★ 3.5ksame name
- bitwize-music-studio/claude-ai-music-skills★ 589same name
- me2resh/apexyard★ 542same name
- egregore-labs/egregore★ 293same name
- apify/apify-docs★ 88same name
- renatoworks/strudel-claude★ 61same name
- aayushostwal/nexus★ 19same name
- NoaiRox/specialist-agent★ 2same name
- LilithLabs/lilith★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository2 other files it gives its agents.
- corpusSkill
- social-posterSkill
The file
We split this skill into the rules it gives an agent
10 rules. 0 are common, 6 are distinctive, and 4 are very specific to this project.
0
Common
Most of the 10 edited versions we read keep these.
6
Distinctive
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 23
Use it for the shape of a region table and the camera measurements.
- Very specific: line 112
Fumbles: Look for sorry, cut, again, a repeated half-sentence, a wrong modifier key named then corrected.
- Very specific: line 134
Read reference/edit-grammar.md now — it gives the speed numbers, the camera rules and the silence policy the script implements.
- Distinctive: line 169
Check on every camera: is any edge of the app window cut mid-element?
- Very specific: line 199
Read reference/ffmpeg-gotchas.md if you touch the renderer.
- Distinctive: line 202
Verify when it finishes:
- Distinctive: line 213
Only what the user alone can decide, and only once, batched:
- Distinctive: line 219
Never ask about craft: cut points, speeds, framing, caption wording.
- Distinctive: line 261
Downscale to 360 px and read it: If the hero does not survive that, it does not survive the feed.
- Distinctive: line 311
Real app pixels on thumbnails: Never redrawn UI.
“Common” is measured: kept by at least 6 in 10 of the 10 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.
Files
Tutorial — recording to upload pack
One take (or several) goes in. What comes out is a finished 1080p mp4 plus everything the YouTube upload form asks for. The user's only remaining job is picking a thumbnail and clicking through the upload list.
Read this whole file before running anything. The three reference files carry the parts that are easy to get wrong; load them at the step that names them, not before.
reference/edit-grammar.md— how fast, how tight, where the camera goesreference/ffmpeg-gotchas.md— encoder facts that cost real time to learnreference/upload-pack.md— title, description, tags, thumbnail rulesexamples/v3-tag-window-buildplan.py— the real region table from the tag-window video, as revised after the first review. Use it for the shape of a region table and the camera measurements. Its speed and silence constants are older thanscripts/buildplan.py, which is the current source of truth.
Three defects appeared in the first run and all three are now fixed in the tooling. Do not reintroduce them.
- Cuts landed on ASR word timings and clipped the attack off every word after a pause — 96% of deletions ate speech.
checkcuts.pyis now a gate; it must read 0% before you render.- Five hand-typed camera rectangles with gliding moves, three of them cutting through the app window. Now two measured cameras, hard cuts, and the window frame pillarboxes rather than crops.
- Thumbnail UI redrawn in CSS with the wrong font, and copy sitting under YouTube's duration badge. Now real pixels cropped from the take, inside a checked safe box.
Renderer: scripts/tutorialcut.py.
0 · Set up
export SK="<path to this skill folder>"
export WORK="<scratchpad>/tutorial-<slug>" # a scratch folder, not your notes or repo
mkdir -p "$WORK"Everything intermediate lives in $WORK. Only the finished mp4, the
thumbnails and the upload-pack note leave it.
Ask the user nothing yet. Watch the footage first — most questions answer themselves, and the ones that don't get asked once, at step 6.
1 · Probe and stitch order
bash "$SK/scripts/layout.sh" "$WORK" "take1.mp4" "take2.mp4"Prints resolution/duration per file and writes sample frames to
$WORK/frames/. Read those frames, then measure them.
Reading is not enough — the first run eyeballed the camera rectangles and three of five cut through the app window. Write down, in source pixels:
- the app window bounds, and the menu bar / title bar bands above it
- every pane divider
- any fixed toolbar band
- the union bounding box of the working content over a dozen frames sampled across the whole take, because panels move (an editor card that follows the selected object shifts hundreds of pixels)
Half-scale frames are fine to read off; double the numbers. Note when the layout changes for good — a divider drag, a video loading — because that is where the framing changes and nowhere else.
Wants 2880x1800. At 1440x900 the recording was made at logical
resolution: say so plainly, because every zoom will be soft and no edit
fixes it.
Order the parts by the on-screen clock in the frames (CleanShot filenames already sort correctly, but a re-take can break that).
2 · Transcribe — AssemblyAI, not local whisper
bash "$SK/scripts/transcribe.sh" "$WORK" "take1.mp4" "take2.mp4"Writes p1_aai.json … (word-level) and p1_phrases.txt … (readable, with
the gap before each phrase printed). $ASSEMBLYAI_API_KEY must be set in the
environment. This uploads the recording's audio to AssemblyAI.
Local
whisper-cliis the alternative. On a slow machine it runs slower than realtime and starves the ffmpeg renders of CPU. In my runs AssemblyAI returned 25 minutes of word-level audio in about 2 minutes.
Read *_phrases.txt end to end. This is the edit. Everything after this
step is mechanical.
3 · Mark the structure
From the phrases file, write down:
- Slates to cut — "Video one. Tag window." spoken markers, and the silence around them. Never ship a slate.
- The real first sentence and the real last one.
- Section boundaries — where the topic turns. These become both the region table and the chapter list; do them once.
- Fumbles. Look for
sorry,cut, again, a repeated half-sentence, a wrong modifier key named then corrected. For each, decide: cut the dead-end and keep the correction — the correction usually carries information the clean take never states. Get word-level timestamps from the_aai.jsonbefore cutting; phrase boundaries are too coarse. - Dead stretches with action in them — a file-open dialog, a long render. These are not cuts, they are 5–6x runs.
- Whether a cold open exists. The opening beat should be the finished thing playing. If none was recorded, lift 10–15 s of the payoff from late in the take and put it first. Flag that you did.
4 · Author the plan
Copy scripts/buildplan.py into $WORK, then edit two tables in it:
CAM— camera presets in source pixels, from the measurements in step 1. Two presets:window(whole screen,"fit": true, pillarboxed so nothing is ever cropped) andpanel(the working area, sized by content height). Nomovekeys — hard cuts only.R— one row per region:src,a,b,cam,talk,gap,tag. Mark every sped-up dialog or loadrun=andmute=True.
Read reference/edit-grammar.md now — it gives the speed numbers, the camera
rules and the silence policy the script implements. The script finds its cut
points in the waveform, not in the word timings; that is not a knob.
python3 "$WORK/buildplan.py" # writes plan.json + report
python3 "$SK/scripts/checkcuts.py" "$WORK/plan.json" # GATE: must be 0%Do not render until checkcuts.py reads 0%. It reports the share of
deletions whose edges still carry speech-level energy; anything above zero
means words are being clipped, which is the one defect the user cannot listen
past. Re-run with --verbose to see which cuts.
Then check the per-region report against the sanity targets at the end of
reference/edit-grammar.md.
5 · Render
Test-render 40 pieces first. A full pass was 45 minutes for 1138 pieces in my run; a camera mistake found afterwards costs all of it. Slice a handful of pieces from each camera into a throwaway plan, render that, and look at the frames.
python3 - <<'PY'
import json
p = json.load(open('plan.json')); ps = p['pieces']
i = next(k for k, x in enumerate(ps) if x.get('cam', {}).get('w') == 1840) # a panel piece
p['pieces'] = ps[:18] + ps[i:i+22]
json.dump(p, open('plan_test.json', 'w'), indent=1)
PY
python3 "$SK/scripts/tutorialcut.py" plan_test.json test.mp4 --workdir worktest
ffmpeg -ss 2 -i test.mp4 -frames:v 1 -y t1.png # then Read the pngsCheck on every camera: is any edge of the app window cut mid-element? Is more than a third of the frame empty? Both were true on the first run and both are visible in one frame.
Then the real thing:
python3 "$SK/scripts/tutorialcut.py" "$WORK/plan.json" \
"$WORK/<slug>.mp4" --workdir "$WORK/work" --map "$WORK/timemap.json"Budget about 2 seconds per merged piece — a 25-minute source is roughly 1000 pieces. Run it in the background and do steps 6–8 while it works.
--workdir makes it resumable, but only by index — editing the plan
renumbers everything after the change. Always cp plan.json plan_old.json
before touching buildplan.py, then carry the survivors across:
python3 buildplan.py
python3 "$SK/scripts/reuse.py" "$WORK/work" "$WORK/work2"
python3 "$SK/scripts/tutorialcut.py" "$WORK/plan.json" \
"$WORK/<slug>.mp4" --workdir "$WORK/work2" --map "$WORK/timemap.json"reuse.py matches pieces by content, not position. Adding one cut on the
first run reused 1136 of 1138 pieces and turned a 45-minute re-render into
four minutes. Without it, every note the user gives costs a full render.
Read reference/ffmpeg-gotchas.md if you touch the renderer. Every fact in
it was paid for once already.
Verify when it finishes:
ffprobe -v error -show_entries stream=codec_type,duration -of csv=p=0 "$WORK/<slug>.mp4"Video and audio durations must match to the millisecond. If they don't, the
audio pinning in tutorialcut.py broke — fix it there, not with a patch.
6 · Ask the user the one round of questions
Only what the user alone can decide, and only once, batched:
- Title, if two candidates are genuinely different bets
- Thumbnail variant
- Anything the footage left factually ambiguous
Never ask about craft: cut points, speeds, framing, caption wording.
7 · Package
python3 "$WORK/package.py" # copy from scripts/, edit the CHAPTERS tableMaps the word timings through timemap.json and writes captions.srt and
chapters.txt. Chapter titles come from the section boundaries you already
marked in step 3.
Then read reference/upload-pack.md and write the upload-pack note.
8 · Thumbnails
Two assets, both cut from the source take at full Retina resolution:
mkdir -p "$WORK/thumb" && cp "$SK/templates/thumbs.html" "$WORK/thumb/"
# ui.png - the app control the video is about, cropped tight
ffmpeg -ss <t> -i take.mp4 -frames:v 1 -vf "crop=W:H:X:Y" -y "$WORK/thumb/ui.png"
# ice.png - a 16:9 frame of real ice, used dark behind everything.
# Only from footage you own or have written permission to use,
# never a broadcast. Otherwise use a plain dark background.
ffmpeg -ss <t> -i take.mp4 -frames:v 1 -vf "crop=1580:888:170:112" -y "$WORK/thumb/ice.png"
node "$SK/scripts/thumbs.js" "$WORK/thumb" --zonesNever redraw the UI in CSS. Real pixels cannot drift from the product and cannot get the font wrong.
Then two checks, both of which the first set failed:
python3 "$SK/scripts/checkzones.py" "$WORK"/thumb/thumb_?.png # GATEcheckzones.pymust pass. It counts bright pixels below 82% height and inside the bottom-right badge block. The first set scored 5951 and 1712 there; both regions are painted over in the feed. Read the_zonesproofs to see what to move.- Downscale to 360 px and read it. If the hero does not survive that, it does not survive the feed.
Three variants, always — the user decides by reacting to something real.
reference/upload-pack.md has the full rules: four words maximum, name the
subject and say it is a tutorial, and every claim must be true of what the
video shows.
8b · Guide material (do this every time, it is nearly free)
python3 "$WORK/guide.py" "<deliverable>/guide-material" # copy from scripts/Writes a chapter-headed transcript on the edited timeline plus full- Retina figures pulled from the source takes, not the 1080p render, so they stay sharp in print. That pair is the spine of a detailed written guide later, with no rewatching and no re-recording.
Edit the FIGURES table to name the moments worth a still. Aim for one or
two per chapter and caption each with what it shows, not what it is.
Strict mapping matters here.
out_time(..., strict=True)returns None for a moment that was cut. Without it, cut words fall forward onto the next kept piece and the slate ends up glued to the first real sentence. The same trap applies to captions — a word that was cut must not appear in the SRT.
9 · Deliver
Open the mp4 and the three thumbnails for the user. State plainly: runtime, source-to-output ratio, what was cut, and anything you constructed that was not recorded (a cold open especially).
Hard rules
- Notes folders and repos never hold media. Renders and takes stay in the scratch folder; only the upload-pack note is kept.
- No invented content. Captions are the presenter's words. Chapter titles describe what was actually done. Thumbnail claims are countable from the footage.
- No em dashes in outbound copy — title, description and thumbnail text are outbound.
- No competitor names anywhere in the copy.
- Never re-record. 70% quality ships. If a section is genuinely unusable, cut it and say what is missing.
checkcuts.pyreads 0% or you do not render. Runtime is negotiable; chopped words are not.- Anything past ~3x is muted. Speech at 6x is noise.
- Nothing gets cropped off the app window. Fit and pillarbox instead.
- Real app pixels on thumbnails. Never redrawn UI.
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.

