cli-demo-generator

Generates professional animated CLI demos as GIFs using VHS terminal recordings. Handles tape file creation, self-bootstrapping demos with hidden setup, output…

INSTALLATION
npx skills add https://github.com/daymade/claude-code-skills --skill cli-demo-generator
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$28

python3 ${CLAUDE_SKILL_DIR}/scripts/auto_generate_demo.py \

  -c "npm install my-package" \

  -c "npm run build" \

  -o demo.gif \

  --bootstrap "npm uninstall my-package 2>/dev/null" \

  --speed 2

Critical: VHS Parser Limitations

VHS Type strings cannot contain $, \", or backticks. These cause parse errors:

# FAILS — VHS parser rejects special chars

Type "echo \"hello $USER\""

Type "claude() { command claude \"$@\"; }"

Workaround: base64 encode the command, decode at runtime:

# 1. Encode your complex command

echo 'claude() { command claude "$@" 2>&1 | grep -v "noise"; }' | base64

# Output: Y2xhdWRlKCkgey4uLn0K

# 2. Use in tape

Type "echo Y2xhdWRlKCkgey4uLn0K | base64 -d > /tmp/wrapper.sh && source /tmp/wrapper.sh"

This pattern is essential for output filtering, function definitions, and any command with shell special characters.

Approaches

1. Automated Generation (Recommended)

python3 ${CLAUDE_SKILL_DIR}/scripts/auto_generate_demo.py \

  -c "command1" -c "command2" \

  -o output.gif \

  --title "My Demo" \

  --theme "Catppuccin Latte" \

  --font-size 24 \

  --width 1400 --height 600

Flag

Default

Description

-c

required

Command to include (repeatable)

-o

required

Output GIF path

--title

none

Title shown at start

--theme

Dracula

VHS theme name

--font-size

16

Font size in pt

--width

1400

Terminal width px

--height

700

Terminal height px

--bootstrap

none

Hidden setup command (repeatable)

--filter

none

Regex pattern to filter from output

--speed

1

Playback speed multiplier (uses gifsicle)

--no-execute

false

Generate .tape only

Smart timing: install/build/test/deploy → 3s, ls/pwd/echo → 1s, others → 2s.

2. Batch Generation

Create multiple demos from one config:

# demos.yaml

demos:

  - name: "Install"

    output: "install.gif"

    commands: ["npm install my-package"]

  - name: "Usage"

    output: "usage.gif"

    commands: ["my-package --help", "my-package run"]
python3 ${CLAUDE_SKILL_DIR}/scripts/batch_generate.py demos.yaml --output-dir ./gifs

3. Interactive Recording

Record a live terminal session:

bash ${CLAUDE_SKILL_DIR}/scripts/record_interactive.sh output.gif --theme "Catppuccin Latte"

# Type commands naturally, Ctrl+D when done

Requires asciinema (brew install asciinema).

4. Manual Tape File

For maximum control, write a tape directly. Templates in assets/templates/:

  • basic.tape — simple command sequence
  • interactive.tape — typing simulation
  • self-bootstrap.tapeself-cleaning demo with hidden setup (recommended for repeatable demos)

Advanced Patterns

These patterns come from production use. See references/advanced_patterns.md for full details.

Self-Bootstrapping Demos

Demos that clean previous state, set up environment, and hide all of it from the viewer:

Hide

Type "cleanup-previous-state 2>/dev/null"

Enter

Sleep 2s

Type "clear"

Enter

Sleep 500ms

Show

Type "the-command-users-see"

Enter

Sleep 3s

The Hide → commands → clearShow sequence is critical. clear wipes the terminal buffer so hidden commands don't leak into the GIF.

Output Noise Filtering

Filter noisy progress lines from commands that produce verbose output:

# Hidden: create a wrapper function that filters noise

Hide

Type "echo <base64-encoded-wrapper> | base64 -d > /tmp/w.sh &#x26;&#x26; source /tmp/w.sh"

Enter

Sleep 500ms

Type "clear"

Enter

Sleep 500ms

Show

# Visible: clean command, filtered output

Type "my-noisy-command"

Enter

Sleep 3s

Frame Verification

After recording, verify GIF content by extracting key frames:

# Extract frames at specific positions

ffmpeg -i demo.gif -vf "select=eq(n\,100)" -frames:v 1 /tmp/frame.png -y 2>/dev/null

# View the frame (Claude can read images)

# Use Read tool on /tmp/frame.png to verify content

Post-Processing Speed-Up

Use gifsicle to speed up recordings without re-recording:

# 2x speed (halve frame delay)

gifsicle -d2 original.gif "#0-" > fast.gif

# 1.5x speed

gifsicle -d4 original.gif "#0-" > faster.gif

Template Placeholder Pattern

Keep tape files generic with placeholders, replace at build time:

# In tape file

Type "claude plugin marketplace add MARKETPLACE_REPO"

# In build script

sed "s|MARKETPLACE_REPO|$DETECTED_REPO|g" template.tape > rendered.tape

vhs rendered.tape

Timing &#x26; Sizing Reference

Context

Width

Height

Font

Duration

README/docs

1400

600

16-20

10-20s

Presentation

1800

900

24

15-30s

Compact embed

1200

600

14-16

10-15s

Wide output

1600

800

16

15-30s

See references/best_practices.md for detailed guidelines.

Troubleshooting

Problem

Solution

VHS not installed

brew install charmbracelet/tap/vhs

gifsicle not installed

brew install gifsicle

GIF too large

Reduce dimensions, sleep times, or use --speed 2

Text wraps/breaks

Increase --width or decrease --font-size

VHS parse error on $ or \"

Use base64 encoding (see Critical section above)

Hidden commands leak into GIF

Add clear + Sleep 500ms before Show

Commands execute before previous finishes

Increase Sleep duration

Dependencies

Required: VHS (brew install charmbracelet/tap/vhs)

Optional: gifsicle (speed-up), asciinema (interactive recording), ffmpeg (frame verification), PyYAML (batch YAML configs)

BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card