plugins/sanctum/skills/tutorial-updates/SKILL.md
Generates or updates tutorials from VHS tapes and Playwright specs with dual-tone markdown and GIF recording. Use when tutorial assets need refreshing.
npx skillsauth add athola/claude-night-market tutorial-updatesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
tutorial-updates:discovery)tutorial-updates:validation)tutorial-updates:rebuild)tutorial-updates:recording)tutorial-updates:generation)tutorial-updates:integration)Orchestrate tutorial generation with GIF recordings from VHS tape files and Playwright browser specs.
This skill coordinates the complete tutorial generation pipeline:
/update-tutorial quickstart # Single tutorial by name
/update-tutorial sync mcp # Multiple tutorials
/update-tutorial --all # All tutorials with manifests
/update-tutorial --list # Show available tutorials
/update-tutorial --scaffold # Create structure without recording
Verification: Run the command with --help flag to verify availability.
Create todos with these prefixes for progress tracking:
**Verification:** Run the command with `--help` flag to verify availability.
- tutorial-updates:discovery
- tutorial-updates:validation
- tutorial-updates:rebuild
- tutorial-updates:recording
- tutorial-updates:generation
- tutorial-updates:integration
Verification: Run the command with --help flag to verify availability.
tutorial-updates:discovery)Find tape files and manifests in the project:
# Find manifest files
find . -name "*.manifest.yaml" -type f \
-not -path "*/.venv/*" -not -path "*/__pycache__/*" \
-not -path "*/node_modules/*" -not -path "*/.git/*" \
2>/dev/null | head -20
# Find tape files
find . -name "*.tape" -type f \
-not -path "*/.venv/*" -not -path "*/__pycache__/*" \
-not -path "*/node_modules/*" -not -path "*/.git/*" \
2>/dev/null | head -20
# Find browser specs
find . -name "*.spec.ts" -path "*/browser/*" -type f \
-not -path "*/.venv/*" -not -path "*/__pycache__/*" \
-not -path "*/node_modules/*" -not -path "*/.git/*" \
2>/dev/null | head -20
Verification: Run the command with --help flag to verify availability.
For each manifest file, extract:
See modules/manifest-parsing.md for manifest schema details.
| Option | Behavior |
|--------|----------|
| --list | Display discovered tutorials and exit |
| --all | Process all discovered manifests |
| --scaffold | Create directory structure and empty files without recording |
| <names> | Process only specified tutorials |
When --list is specified:
**Verification:** Run the command with `--help` flag to verify availability.
Available tutorials:
quickstart assets/tapes/quickstart.tape
sync assets/tapes/sync.tape (manifest)
mcp assets/tapes/mcp.manifest.yaml (terminal + browser)
skill-debug assets/tapes/skill-debug.tape
Verification: Run the command with --help flag to verify availability.
tutorial-updates:validation)CRITICAL: Validate tape commands BEFORE running VHS to avoid expensive regeneration cycles.
See modules/tape-validation.md for detailed validation logic.
Check each tape file for valid VHS syntax:
# Required: Output directive exists
grep -q '^Output ' "$tape_file" || echo "ERROR: Missing Output directive"
# Check for balanced quotes in Type directives
grep '^Type ' "$tape_file" | while read -r line; do
quote_count=$(echo "$line" | tr -cd '"' | wc -c)
if [ $((quote_count % 2)) -ne 0 ]; then
echo "ERROR: Unbalanced quotes: $line"
fi
done
Verification: Run the command with --help flag to verify availability.
For each Type directive, extract the command and validate flags:
# Extract commands from Type directives
grep '^Type ' "$tape_file" | sed 's/^Type "//' | sed 's/"$//' | while read -r cmd; do
# Skip comments, clear, and echo commands
[[ "$cmd" =~ ^# ]] && continue
[[ "$cmd" == "clear" ]] && continue
# For skrills commands, validate flags exist
if [[ "$cmd" =~ ^skrills ]]; then
base_cmd=$(echo "$cmd" | awk '{print $1, $2}')
flags=$(echo "$cmd" | grep -oE '\-\-[a-zA-Z0-9-]+' || true)
for flag in $flags; do
if ! $base_cmd --help 2>&1 | grep -q -- "$flag"; then
echo "ERROR: Invalid flag '$flag' in command: $cmd"
fi
done
fi
done
Verification: Run the command with --help flag to verify availability.
If the tape uses demo data, verify it exists and is populated:
# Check SKRILLS_SKILL_DIR if set
skill_dir=$(grep '^Env SKRILLS_SKILL_DIR' "$tape_file" | sed 's/.*"\(.*\)"/\1/')
if [ -n "$skill_dir" ]; then
if [ ! -d "$skill_dir" ]; then
echo "ERROR: Demo skill directory missing: $skill_dir"
else
skill_count=$(find "$skill_dir" -name "SKILL.md" 2>/dev/null | wc -l)
if [ "$skill_count" -eq 0 ]; then
echo "ERROR: No skills in demo directory: $skill_dir"
else
echo "OK: Found $skill_count demo skills in $skill_dir"
fi
fi
fi
Verification: Run the command with --help flag to verify availability.
CRITICAL: Run each extracted command locally to verify it produces expected output:
# For each command in the tape, do a quick sanity check
# This catches issues like:
# - Commands that exit with non-zero status
# - Commands that produce no output (won't show anything in GIF)
# - Commands that require user input (will hang VHS)
for cmd in $(extract_commands "$tape_file"); do
# Run with timeout to catch hanging commands
if ! timeout 5s bash -c "$cmd" &>/dev/null; then
echo "WARNING: Command may fail or hang: $cmd"
fi
done
Verification: Run the command with --help flag to verify availability.
| Flag | Behavior |
|------|----------|
| --validate-only | Run validation without generating GIF |
| --skip-validation | Bypass validation for rapid regeneration |
If validation fails: Stop immediately, report errors, and do NOT proceed to VHS recording.
tutorial-updates:rebuild)CRITICAL: Ensure the binary being tested in tapes matches the latest source code. Stale binaries produce misleading demos.
Identify the project's build system:
# Check for Cargo (Rust)
if [ -f "Cargo.toml" ]; then
BUILD_SYSTEM="cargo"
BINARY_NAME=$(grep '^name = ' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
echo "Detected Cargo project: $BINARY_NAME"
# Check for Makefile
elif [ -f "Makefile" ]; then
BUILD_SYSTEM="make"
echo "Detected Make project"
# Unknown
else
echo "WARNING: Unknown build system, skipping binary check"
BUILD_SYSTEM="unknown"
fi
Verification: Run make --dry-run to verify build configuration.
Compare binary modification time against Git HEAD:
check_binary_freshness() {
local binary_name="$1"
# Locate binary (check cargo install location first, then PATH)
local binary_path=$(which "$binary_name" 2>/dev/null)
if [ -z "$binary_path" ]; then
echo "WARNING: Binary '$binary_name' not found in PATH"
return 1
fi
# Get binary modification time (Linux/macOS compatible)
local binary_mtime
if command -v stat >/dev/null 2>&1; then
# Linux
binary_mtime=$(stat -c %Y "$binary_path" 2>/dev/null || \
# macOS
stat -f %m "$binary_path" 2>/dev/null)
else
echo "WARNING: stat command not available, skipping freshness check"
return 2
fi
# Get Git HEAD commit time
local git_head_time=$(git log -1 --format=%ct 2>/dev/null)
if [ -z "$git_head_time" ]; then
echo "WARNING: Not a git repository, skipping freshness check"
return 2
fi
# Compare timestamps
if [ "$binary_mtime" -lt "$git_head_time" ]; then
echo "STALE: Binary is older than Git HEAD"
echo " Binary: $(date -d @$binary_mtime 2>/dev/null || date -r $binary_mtime)"
echo " HEAD: $(date -d @$git_head_time 2>/dev/null || date -r $git_head_time)"
return 1
else
echo "OK: Binary is up-to-date"
return 0
fi
}
Verification: Run git status to confirm working tree state.
Rebuild using the detected build system:
rebuild_binary() {
local build_system="$1"
local binary_name="$2"
case "$build_system" in
cargo)
echo "Rebuilding with Cargo..."
# Use cargo install for CLI binaries
if [ -d "crates/cli" ]; then
cargo install --path crates/cli --locked --quiet
else
cargo install --path . --locked --quiet
fi
;;
make)
echo "Rebuilding with Make..."
make build --quiet
;;
*)
echo "ERROR: Cannot rebuild, unknown build system"
return 1
;;
esac
echo "Build complete: $binary_name"
}
Verification: Run make --dry-run to verify build configuration.
Ensure the rebuilt binary is accessible:
verify_binary() {
local binary_name="$1"
if ! command -v "$binary_name" >/dev/null 2>&1; then
echo "ERROR: Binary '$binary_name' not found after rebuild"
echo " Check PATH includes: $HOME/.cargo/bin"
return 1
fi
# Test binary can execute
if ! "$binary_name" --version >/dev/null 2>&1; then
echo "WARNING: Binary exists but --version failed"
else
echo "OK: Binary is accessible and functional"
"$binary_name" --version
fi
}
Verification: Run pytest -v to verify tests pass.
| Flag | Behavior |
|------|----------|
| --skip-rebuild | Skip binary freshness check and rebuild |
| --force-rebuild | Force rebuild even if binary is fresh |
If rebuild fails: Stop immediately, report build errors, and do NOT proceed to tape validation or VHS recording.
tutorial-updates:recording)For each tape file component:
Skill(scry:vhs-recording) with tape file pathFor each playwright spec component:
requires field for prerequisite commands (e.g., start server)Skill(scry:browser-recording) with spec pathSkill(scry:gif-generation) to convert WebM to GIFFor manifests with combine section:
Skill(scry:media-composition) with manifesttutorial-updates:generation)Extract documentation content from tape files:
# @step Install skrills
# @docs-brief Install via cargo
# @book-detail The recommended installation method uses cargo...
Type "cargo install skrills"
Verification: Run the command with --help flag to verify availability.
Annotations:
@step - Step title/heading@docs-brief - Concise text for project docs (docs/ directory)@book-detail - Extended text for technical book (book/ directory)Generate two versions of each tutorial:
Project docs (docs/tutorials/<name>.md)
Technical book (book/src/tutorials/<name>.md)
See modules/markdown-generation.md for formatting details.
Create or update demo section in README.md:
## Demos
### Quickstart

*Install, validate, analyze, and serve in under a minute. [Full tutorial](docs/tutorials/quickstart.md)*
Verification: Run the command with --help flag to verify availability.
tutorial-updates:integration)Confirm all expected files exist:
# Check GIF files
for gif in assets/gifs/*.gif; do
if [[ -f "$gif" ]]; then
echo "OK: $gif ($(du -h "$gif" | cut -f1))"
else
echo "MISSING: $gif"
fi
done
# Check markdown files
ls -la docs/tutorials/*.md 2>/dev/null
ls -la book/src/tutorials/*.md 2>/dev/null
Verification: Run the command with --help flag to verify availability.
If the project has an mdBook structure, update book/src/SUMMARY.md:
- [Tutorials](./tutorials/README.md)
- [Quickstart](./tutorials/quickstart.md)
- [Sync Workflow](./tutorials/sync.md)
- [MCP Integration](./tutorials/mcp.md)
- [Skill Debugging](./tutorials/skill-debug.md)
Verification: Run the command with --help flag to verify availability.
Summarize the update:
**Verification:** Run the command with `--help` flag to verify availability.
Tutorial Update Complete
========================
Tutorials processed: 4
GIFs generated: 5
- quickstart.gif (1.2MB)
- sync.gif (980KB)
- mcp-terminal.gif (1.5MB)
- mcp-browser.gif (2.1MB)
- skill-debug.gif (890KB)
Markdown generated:
- docs/tutorials/ (4 files)
- book/src/tutorials/ (4 files)
README demo section updated
Verification: Run the command with --help flag to verify availability.
| Error | Resolution |
|-------|------------|
| VHS not installed | go install github.com/charmbracelet/vhs@latest |
| Playwright not installed | npm install -D @playwright/test && npx playwright install chromium |
| Tape file missing Output | Add Output assets/gifs/<name>.gif directive |
| Browser spec requires server | Start server before running spec |
| GIF too large | Adjust fps/scale in gif-generation |
When --scaffold is specified, create structure without recording:
assets/tapes/ directoryassets/gifs/ directoryassets/browser/ directory (if browser tutorials planned)Template tape file:
# @title: Tutorial Name
# @description: Brief description of the tutorial
Output assets/gifs/tutorial-name.gif
Set FontSize 14
Set Width 1200
Set Height 600
Set Theme "Catppuccin Mocha"
# @step Step 1 Title
# @docs-brief Brief docs text
# @book-detail Extended book text with more context and explanation
Type "command here"
Enter
Sleep 2s
Verification: Run the command with --help flag to verify availability.
research
Generate diverse solution candidates with category-spanning ideation methods and rotation. Use when stuck on a design or fighting repetitive LLM output.
tools
--- name: validate-pr description: Use when you need a diff-derived test plan for a PR: reads the diff, groups changes by area, runs targeted verifications, and proves revert-tests are genuine guards, not dead assertions. alwaysApply: false category: validation tags: - pr - validation - test-plan - diff - revert-test - evidence tools: [] usage_patterns: - diff-derived-test-plan - revert-test-quality-check - evidence-capture complexity: intermediate model_hint: standard estimated_tokens: 650
development
Contract for the project decision journal (tradeoffs and lessons-learned logs). Use when recording a decision, tradeoff, or lesson, or building a consumer hook.
development
Ramps implementation ambition a notch only after the prior increment is understood. Use when building a feature you must understand, not just ship.