Initial commit
This commit is contained in:
12
.claude-plugin/plugin.json
Normal file
12
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "cli-demo-generator",
|
||||||
|
"description": "Generate professional animated CLI demos and terminal recordings with VHS. Supports automated generation, batch processing, and interactive recording for documentation and tutorials",
|
||||||
|
"version": "0.0.0-2025.11.28",
|
||||||
|
"author": {
|
||||||
|
"name": "daymade",
|
||||||
|
"email": "daymadev89@gmail.com"
|
||||||
|
},
|
||||||
|
"skills": [
|
||||||
|
"./skills/cli-demo-generator"
|
||||||
|
]
|
||||||
|
}
|
||||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# cli-demo-generator
|
||||||
|
|
||||||
|
Generate professional animated CLI demos and terminal recordings with VHS. Supports automated generation, batch processing, and interactive recording for documentation and tutorials
|
||||||
76
plugin.lock.json
Normal file
76
plugin.lock.json
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||||
|
"pluginId": "gh:daymade/claude-code-skills:cli-demo-generator",
|
||||||
|
"normalized": {
|
||||||
|
"repo": null,
|
||||||
|
"ref": "refs/tags/v20251128.0",
|
||||||
|
"commit": "a61c1c0a6cef51175ef20b1ab79dd94b709e3587",
|
||||||
|
"treeHash": "1174fabdad379545d4c549c3de45d01219fa705f94fe3ee24f901deec24b97c6",
|
||||||
|
"generatedAt": "2025-11-28T10:16:14.043857Z",
|
||||||
|
"toolVersion": "publish_plugins.py@0.2.0"
|
||||||
|
},
|
||||||
|
"origin": {
|
||||||
|
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||||
|
"branch": "master",
|
||||||
|
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||||
|
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||||
|
},
|
||||||
|
"manifest": {
|
||||||
|
"name": "cli-demo-generator",
|
||||||
|
"description": "Generate professional animated CLI demos and terminal recordings with VHS. Supports automated generation, batch processing, and interactive recording for documentation and tutorials"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "README.md",
|
||||||
|
"sha256": "be775890dc5e2455d4137b89f8d94714a3a2a38140d11171815f40c5c3e9cd94"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".claude-plugin/plugin.json",
|
||||||
|
"sha256": "4994fbeee0762b3c746163a0c8a546b69577f535dbea2d9420cc25a492bf65e7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/cli-demo-generator/SKILL.md",
|
||||||
|
"sha256": "8d518ff535d7377575573f479c1ab061eedc9db7e42430c58d35f54f8cecdbc8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/cli-demo-generator/references/vhs_syntax.md",
|
||||||
|
"sha256": "d49f06de9345b586b0b1755a7d26220aa89a5dd9b4154fbb7c6039b25e8717af"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/cli-demo-generator/references/best_practices.md",
|
||||||
|
"sha256": "4f2b5991e8070335fbb6245880e3b1eb02789fc68fafe84d08833f876167c9ae"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/cli-demo-generator/scripts/record_interactive.sh",
|
||||||
|
"sha256": "cd5807a9edc5774bfe1afca1c31d23b4bea3432ee231bc4a0a06815db9607b8d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/cli-demo-generator/scripts/auto_generate_demo.py",
|
||||||
|
"sha256": "ba7d6a1e7c70d76cadd582fc1eae9b279932c9af67834255d26857b7c46ac27d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/cli-demo-generator/scripts/batch_generate.py",
|
||||||
|
"sha256": "c7275ae65b0f5aa3ecd2813c10b1c316ba2cac2cf7b42a1c8b375ed120d5f87c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/cli-demo-generator/assets/examples/batch-config.yaml",
|
||||||
|
"sha256": "181e7d003b1bc14de549f9dd07bf1d36a6943d7810ca183ec3f8b60845a398b5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/cli-demo-generator/assets/templates/interactive.tape",
|
||||||
|
"sha256": "7af6348a6cfe1915424ab684ed1231bbfb5d1de6d83e6abe0d24a0648266cea7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/cli-demo-generator/assets/templates/basic.tape",
|
||||||
|
"sha256": "f3fd16bca14aba2b08f91f9bca13ab91291eae3fd9ede46604c03fd20125e3f1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dirSha256": "1174fabdad379545d4c549c3de45d01219fa705f94fe3ee24f901deec24b97c6"
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"scannedAt": null,
|
||||||
|
"scannerVersion": null,
|
||||||
|
"flags": []
|
||||||
|
}
|
||||||
|
}
|
||||||
346
skills/cli-demo-generator/SKILL.md
Normal file
346
skills/cli-demo-generator/SKILL.md
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
---
|
||||||
|
name: cli-demo-generator
|
||||||
|
description: This skill should be used when users want to create animated CLI demos, terminal recordings, or command-line demonstration GIFs. It supports both manual tape file creation and automated demo generation from command descriptions. Use when users mention creating demos, recording terminal sessions, or generating animated GIFs of CLI workflows.
|
||||||
|
---
|
||||||
|
|
||||||
|
# CLI Demo Generator
|
||||||
|
|
||||||
|
Generate professional animated CLI demos with ease. This skill supports both automated generation from command descriptions and manual control for custom demos.
|
||||||
|
|
||||||
|
## When to Use This Skill
|
||||||
|
|
||||||
|
Trigger this skill when users request:
|
||||||
|
- "Create a demo showing how to install my package"
|
||||||
|
- "Generate a CLI demo of these commands"
|
||||||
|
- "Make an animated GIF of my terminal workflow"
|
||||||
|
- "Record a terminal session and convert to GIF"
|
||||||
|
- "Batch generate demos from this config"
|
||||||
|
- "Create an interactive typing demo"
|
||||||
|
|
||||||
|
## Core Capabilities
|
||||||
|
|
||||||
|
### 1. Automated Demo Generation (Recommended)
|
||||||
|
|
||||||
|
Use the `auto_generate_demo.py` script for quick, automated demo creation. This is the easiest and most common approach.
|
||||||
|
|
||||||
|
**Basic Usage:**
|
||||||
|
```bash
|
||||||
|
scripts/auto_generate_demo.py \
|
||||||
|
-c "npm install my-package" \
|
||||||
|
-c "npm run build" \
|
||||||
|
-o demo.gif
|
||||||
|
```
|
||||||
|
|
||||||
|
**With Options:**
|
||||||
|
```bash
|
||||||
|
scripts/auto_generate_demo.py \
|
||||||
|
-c "command1" \
|
||||||
|
-c "command2" \
|
||||||
|
-o output.gif \
|
||||||
|
--title "Installation Demo" \
|
||||||
|
--theme "Dracula" \
|
||||||
|
--width 1400 \
|
||||||
|
--height 700
|
||||||
|
```
|
||||||
|
|
||||||
|
**Script Parameters:**
|
||||||
|
- `-c, --command`: Command to include (can be specified multiple times)
|
||||||
|
- `-o, --output`: Output GIF file path (required)
|
||||||
|
- `--title`: Demo title (optional, shown at start)
|
||||||
|
- `--theme`: VHS theme (default: Dracula)
|
||||||
|
- `--font-size`: Font size (default: 16)
|
||||||
|
- `--width`: Terminal width (default: 1400)
|
||||||
|
- `--height`: Terminal height (default: 700)
|
||||||
|
- `--no-execute`: Generate tape file only, don't execute VHS
|
||||||
|
|
||||||
|
**Smart Features:**
|
||||||
|
- Automatic timing based on command complexity
|
||||||
|
- Optimized sleep durations (1-3s depending on operation)
|
||||||
|
- Proper spacing between commands
|
||||||
|
- Professional defaults
|
||||||
|
|
||||||
|
### 2. Batch Demo Generation
|
||||||
|
|
||||||
|
Use `batch_generate.py` for creating multiple demos from a configuration file.
|
||||||
|
|
||||||
|
**Configuration File (YAML):**
|
||||||
|
```yaml
|
||||||
|
demos:
|
||||||
|
- name: "Install Demo"
|
||||||
|
output: "install.gif"
|
||||||
|
title: "Installation"
|
||||||
|
theme: "Dracula"
|
||||||
|
commands:
|
||||||
|
- "npm install my-package"
|
||||||
|
- "npm run build"
|
||||||
|
|
||||||
|
- name: "Usage Demo"
|
||||||
|
output: "usage.gif"
|
||||||
|
commands:
|
||||||
|
- "my-package --help"
|
||||||
|
- "my-package run"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
```bash
|
||||||
|
scripts/batch_generate.py config.yaml --output-dir ./demos
|
||||||
|
```
|
||||||
|
|
||||||
|
**When to Use Batch Generation:**
|
||||||
|
- Creating a suite of related demos
|
||||||
|
- Documenting multiple features
|
||||||
|
- Generating demos for tutorials or documentation
|
||||||
|
- Maintaining consistent demo series
|
||||||
|
|
||||||
|
### 3. Interactive Recording
|
||||||
|
|
||||||
|
Use `record_interactive.sh` for recording live terminal sessions.
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
```bash
|
||||||
|
scripts/record_interactive.sh output.gif \
|
||||||
|
--theme "Dracula" \
|
||||||
|
--width 1400
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recording Process:**
|
||||||
|
1. Script starts asciinema recording
|
||||||
|
2. Type commands naturally in your terminal
|
||||||
|
3. Press Ctrl+D when finished
|
||||||
|
4. Script auto-converts to GIF via VHS
|
||||||
|
|
||||||
|
**When to Use Interactive Recording:**
|
||||||
|
- Demonstrating complex workflows
|
||||||
|
- Showing real command output
|
||||||
|
- Capturing live interactions
|
||||||
|
- Recording debugging sessions
|
||||||
|
|
||||||
|
### 4. Manual Tape File Creation
|
||||||
|
|
||||||
|
For maximum control, create VHS tape files manually using templates.
|
||||||
|
|
||||||
|
**Available Templates:**
|
||||||
|
- `assets/templates/basic.tape` - Simple command demo
|
||||||
|
- `assets/templates/interactive.tape` - Typing simulation
|
||||||
|
|
||||||
|
**Example Workflow:**
|
||||||
|
1. Copy template: `cp assets/templates/basic.tape my-demo.tape`
|
||||||
|
2. Edit commands and timing
|
||||||
|
3. Generate GIF: `vhs < my-demo.tape`
|
||||||
|
|
||||||
|
Consult `references/vhs_syntax.md` for complete VHS syntax reference.
|
||||||
|
|
||||||
|
## Workflow Guidance
|
||||||
|
|
||||||
|
### For Simple Demos (1-3 commands)
|
||||||
|
|
||||||
|
Use automated generation for quick results:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scripts/auto_generate_demo.py \
|
||||||
|
-c "echo 'Hello World'" \
|
||||||
|
-c "ls -la" \
|
||||||
|
-o hello-demo.gif \
|
||||||
|
--title "Hello Demo"
|
||||||
|
```
|
||||||
|
|
||||||
|
### For Multiple Related Demos
|
||||||
|
|
||||||
|
Create a batch configuration file and use batch generation:
|
||||||
|
|
||||||
|
1. Create `demos-config.yaml` with all demo definitions
|
||||||
|
2. Run: `scripts/batch_generate.py demos-config.yaml --output-dir ./output`
|
||||||
|
3. All demos generate automatically with consistent settings
|
||||||
|
|
||||||
|
### For Interactive/Complex Workflows
|
||||||
|
|
||||||
|
Use interactive recording to capture real behavior:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scripts/record_interactive.sh my-workflow.gif
|
||||||
|
# Type commands naturally
|
||||||
|
# Ctrl+D when done
|
||||||
|
```
|
||||||
|
|
||||||
|
### For Custom Timing/Layout
|
||||||
|
|
||||||
|
Create manual tape file with precise control:
|
||||||
|
|
||||||
|
1. Start with template or generate base tape with `--no-execute`
|
||||||
|
2. Edit timing, add comments, customize layout
|
||||||
|
3. Generate: `vhs < custom-demo.tape`
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
Refer to `references/best_practices.md` for comprehensive guidelines. Key recommendations:
|
||||||
|
|
||||||
|
**Timing:**
|
||||||
|
- Quick commands (ls, pwd): 1s sleep
|
||||||
|
- Standard commands (grep, cat): 2s sleep
|
||||||
|
- Heavy operations (install, build): 3s+ sleep
|
||||||
|
|
||||||
|
**Sizing:**
|
||||||
|
- Standard: 1400x700 (recommended)
|
||||||
|
- Compact: 1200x600
|
||||||
|
- Presentations: 1800x900
|
||||||
|
|
||||||
|
**Themes:**
|
||||||
|
- Documentation: Nord, GitHub Dark
|
||||||
|
- Code demos: Dracula, Monokai
|
||||||
|
- Presentations: High-contrast themes
|
||||||
|
|
||||||
|
**Duration:**
|
||||||
|
- Target: 15-30 seconds
|
||||||
|
- Maximum: 60 seconds
|
||||||
|
- Create series for complex topics
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### VHS Not Installed
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# macOS
|
||||||
|
brew install vhs
|
||||||
|
|
||||||
|
# Linux (via Go)
|
||||||
|
go install github.com/charmbracelet/vhs@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Asciinema Not Installed
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# macOS
|
||||||
|
brew install asciinema
|
||||||
|
|
||||||
|
# Linux
|
||||||
|
sudo apt install asciinema
|
||||||
|
```
|
||||||
|
|
||||||
|
### Demo File Too Large
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
1. Reduce duration (shorter sleep times)
|
||||||
|
2. Use smaller dimensions (1200x600)
|
||||||
|
3. Consider MP4 format: `Output demo.mp4`
|
||||||
|
4. Split into multiple shorter demos
|
||||||
|
|
||||||
|
### Output Not Readable
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
1. Increase font size: `--font-size 18`
|
||||||
|
2. Use wider terminal: `--width 1600`
|
||||||
|
3. Choose high-contrast theme: `--theme "Dracula"`
|
||||||
|
4. Test on target display device
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Example 1: Quick Install Demo
|
||||||
|
|
||||||
|
User request: "Create a demo showing npm install"
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scripts/auto_generate_demo.py \
|
||||||
|
-c "npm install my-package" \
|
||||||
|
-o install-demo.gif \
|
||||||
|
--title "Package Installation"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 2: Multi-Step Tutorial
|
||||||
|
|
||||||
|
User request: "Create a demo showing project setup with git clone, install, and run"
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scripts/auto_generate_demo.py \
|
||||||
|
-c "git clone https://github.com/user/repo.git" \
|
||||||
|
-c "cd repo" \
|
||||||
|
-c "npm install" \
|
||||||
|
-c "npm start" \
|
||||||
|
-o setup-demo.gif \
|
||||||
|
--title "Project Setup" \
|
||||||
|
--theme "Nord"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 3: Batch Generation
|
||||||
|
|
||||||
|
User request: "Generate demos for all my CLI tool features"
|
||||||
|
|
||||||
|
1. Create `features-demos.yaml`:
|
||||||
|
```yaml
|
||||||
|
demos:
|
||||||
|
- name: "Help Command"
|
||||||
|
output: "help.gif"
|
||||||
|
commands: ["my-tool --help"]
|
||||||
|
|
||||||
|
- name: "Init Command"
|
||||||
|
output: "init.gif"
|
||||||
|
commands: ["my-tool init", "ls -la"]
|
||||||
|
|
||||||
|
- name: "Run Command"
|
||||||
|
output: "run.gif"
|
||||||
|
commands: ["my-tool run --verbose"]
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Generate all:
|
||||||
|
```bash
|
||||||
|
scripts/batch_generate.py features-demos.yaml --output-dir ./demos
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 4: Interactive Session
|
||||||
|
|
||||||
|
User request: "Record me using my CLI tool interactively"
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scripts/record_interactive.sh my-session.gif --theme "Tokyo Night"
|
||||||
|
# User types commands naturally
|
||||||
|
# Ctrl+D to finish
|
||||||
|
```
|
||||||
|
|
||||||
|
## Bundled Resources
|
||||||
|
|
||||||
|
### scripts/
|
||||||
|
- **`auto_generate_demo.py`** - Automated demo generation from command lists
|
||||||
|
- **`batch_generate.py`** - Generate multiple demos from YAML/JSON config
|
||||||
|
- **`record_interactive.sh`** - Record and convert interactive terminal sessions
|
||||||
|
|
||||||
|
### references/
|
||||||
|
- **`vhs_syntax.md`** - Complete VHS tape file syntax reference
|
||||||
|
- **`best_practices.md`** - Demo creation guidelines and best practices
|
||||||
|
|
||||||
|
### assets/
|
||||||
|
- **`templates/basic.tape`** - Basic command demo template
|
||||||
|
- **`templates/interactive.tape`** - Interactive typing demo template
|
||||||
|
- **`examples/batch-config.yaml`** - Example batch configuration file
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
**Required:**
|
||||||
|
- VHS (https://github.com/charmbracelet/vhs)
|
||||||
|
|
||||||
|
**Optional:**
|
||||||
|
- asciinema (for interactive recording)
|
||||||
|
- PyYAML (for batch YAML configs): `pip install pyyaml`
|
||||||
|
|
||||||
|
## Output Formats
|
||||||
|
|
||||||
|
VHS supports multiple output formats:
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Output demo.gif # GIF (default, best for documentation)
|
||||||
|
Output demo.mp4 # MP4 (better compression for long demos)
|
||||||
|
Output demo.webm # WebM (smaller file size)
|
||||||
|
```
|
||||||
|
|
||||||
|
Choose based on use case:
|
||||||
|
- **GIF**: Documentation, README files, easy embedding
|
||||||
|
- **MP4**: Longer demos, better quality, smaller size
|
||||||
|
- **WebM**: Web-optimized, smallest file size
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
This skill provides three main approaches:
|
||||||
|
|
||||||
|
1. **Automated** (`auto_generate_demo.py`) - Quick, easy, smart defaults
|
||||||
|
2. **Batch** (`batch_generate.py`) - Multiple demos, consistent settings
|
||||||
|
3. **Interactive** (`record_interactive.sh`) - Live recording, real output
|
||||||
|
|
||||||
|
Choose the approach that best fits the user's needs. For most cases, automated generation is the fastest and most convenient option.
|
||||||
31
skills/cli-demo-generator/assets/examples/batch-config.yaml
Normal file
31
skills/cli-demo-generator/assets/examples/batch-config.yaml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Example batch configuration for generating multiple demos
|
||||||
|
# Usage: batch_generate.py batch-config.yaml --output-dir ./output
|
||||||
|
|
||||||
|
demos:
|
||||||
|
- name: "Installation Demo"
|
||||||
|
output: "install.gif"
|
||||||
|
title: "Package Installation"
|
||||||
|
theme: "Dracula"
|
||||||
|
width: 1400
|
||||||
|
height: 700
|
||||||
|
commands:
|
||||||
|
- "npm install my-package"
|
||||||
|
- "npm run build"
|
||||||
|
|
||||||
|
- name: "Usage Demo"
|
||||||
|
output: "usage.gif"
|
||||||
|
title: "Basic Usage"
|
||||||
|
theme: "Nord"
|
||||||
|
commands:
|
||||||
|
- "my-package --help"
|
||||||
|
- "my-package init"
|
||||||
|
- "my-package run"
|
||||||
|
|
||||||
|
- name: "Quick Start"
|
||||||
|
output: "quickstart.gif"
|
||||||
|
theme: "Tokyo Night"
|
||||||
|
commands:
|
||||||
|
- "git clone https://github.com/user/repo.git"
|
||||||
|
- "cd repo"
|
||||||
|
- "npm install"
|
||||||
|
- "npm start"
|
||||||
18
skills/cli-demo-generator/assets/templates/basic.tape
Normal file
18
skills/cli-demo-generator/assets/templates/basic.tape
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
Output demo.gif
|
||||||
|
|
||||||
|
Set FontSize 16
|
||||||
|
Set Width 1400
|
||||||
|
Set Height 700
|
||||||
|
Set Theme "Dracula"
|
||||||
|
Set Padding 20
|
||||||
|
|
||||||
|
Type "# Demo Title" Sleep 500ms Enter
|
||||||
|
Sleep 1s
|
||||||
|
|
||||||
|
Type "command1" Sleep 500ms
|
||||||
|
Enter
|
||||||
|
Sleep 2s
|
||||||
|
|
||||||
|
Type "command2" Sleep 500ms
|
||||||
|
Enter
|
||||||
|
Sleep 2s
|
||||||
21
skills/cli-demo-generator/assets/templates/interactive.tape
Normal file
21
skills/cli-demo-generator/assets/templates/interactive.tape
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
Output demo.gif
|
||||||
|
|
||||||
|
Set FontSize 16
|
||||||
|
Set Width 1400
|
||||||
|
Set Height 700
|
||||||
|
Set Theme "Dracula"
|
||||||
|
Set Padding 20
|
||||||
|
Set TypingSpeed 100ms
|
||||||
|
|
||||||
|
Type "# Interactive Demo" Sleep 500ms Enter
|
||||||
|
Sleep 1.5s
|
||||||
|
|
||||||
|
Type "# Type commands naturally..." Sleep 500ms Enter
|
||||||
|
Sleep 1s
|
||||||
|
|
||||||
|
Type "echo 'Hello World'" Sleep 500ms
|
||||||
|
Enter
|
||||||
|
Sleep 2s
|
||||||
|
|
||||||
|
Type "# Typing simulation makes it feel real" Sleep 500ms Enter
|
||||||
|
Sleep 2s
|
||||||
372
skills/cli-demo-generator/references/best_practices.md
Normal file
372
skills/cli-demo-generator/references/best_practices.md
Normal file
@@ -0,0 +1,372 @@
|
|||||||
|
# CLI Demo Best Practices
|
||||||
|
|
||||||
|
Guidelines for creating effective, professional CLI demos.
|
||||||
|
|
||||||
|
## General Principles
|
||||||
|
|
||||||
|
### 1. Keep It Short
|
||||||
|
- **Target**: 15-30 seconds per demo
|
||||||
|
- **Maximum**: 60 seconds (unless documenting complex workflows)
|
||||||
|
- **Reason**: Short demos maintain viewer attention and are easier to consume
|
||||||
|
|
||||||
|
### 2. Show, Don't Tell
|
||||||
|
- Focus on visual demonstration over textual explanation
|
||||||
|
- Let the commands and output speak for themselves
|
||||||
|
- Add brief comment-style titles when needed
|
||||||
|
|
||||||
|
### 3. One Concept Per Demo
|
||||||
|
- Each demo should illustrate a single feature or workflow
|
||||||
|
- For complex topics, create a series of short demos
|
||||||
|
- Better to have multiple focused demos than one lengthy tutorial
|
||||||
|
|
||||||
|
## Technical Guidelines
|
||||||
|
|
||||||
|
### Timing and Pacing
|
||||||
|
|
||||||
|
**Command Entry Timing:**
|
||||||
|
```
|
||||||
|
Type "command" Sleep 500ms # Fast enough to feel natural
|
||||||
|
Enter # Immediate
|
||||||
|
```
|
||||||
|
|
||||||
|
**Post-Command Sleep (based on operation):**
|
||||||
|
- **Quick commands** (ls, pwd, echo): 1s
|
||||||
|
- **Standard commands** (grep, cat, git status): 1.5-2s
|
||||||
|
- **Heavy operations** (install, build, test): 3s+
|
||||||
|
- **Final command**: 2-3s for viewers to see result
|
||||||
|
|
||||||
|
**Between Sections:**
|
||||||
|
- Add 1-1.5s between related commands
|
||||||
|
- Add 2s+ between different concepts
|
||||||
|
|
||||||
|
### Terminal Dimensions
|
||||||
|
|
||||||
|
**Standard Sizes:**
|
||||||
|
```tape
|
||||||
|
# Compact (for narrow contexts)
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 600
|
||||||
|
|
||||||
|
# Standard (recommended default)
|
||||||
|
Set Width 1400
|
||||||
|
Set Height 700
|
||||||
|
|
||||||
|
# Wide (for complex output)
|
||||||
|
Set Width 1600
|
||||||
|
Set Height 800
|
||||||
|
|
||||||
|
# Presentation (for slides)
|
||||||
|
Set Width 1800
|
||||||
|
Set Height 900
|
||||||
|
```
|
||||||
|
|
||||||
|
**Choosing Dimensions:**
|
||||||
|
- Consider the output width (avoid wrapping)
|
||||||
|
- Test with longest expected line
|
||||||
|
- Standard 1400x700 works for most cases
|
||||||
|
|
||||||
|
### Font Sizing
|
||||||
|
|
||||||
|
**Recommended Sizes:**
|
||||||
|
```tape
|
||||||
|
# Documentation (small, information-dense)
|
||||||
|
Set FontSize 14
|
||||||
|
|
||||||
|
# Standard demos (readable)
|
||||||
|
Set FontSize 16
|
||||||
|
|
||||||
|
# Presentations (clear from distance)
|
||||||
|
Set FontSize 20-24
|
||||||
|
```
|
||||||
|
|
||||||
|
**Choosing Font Size:**
|
||||||
|
- Smaller fonts allow more output visibility
|
||||||
|
- Larger fonts improve readability on mobile
|
||||||
|
- Test on target display devices
|
||||||
|
|
||||||
|
### Theme Selection
|
||||||
|
|
||||||
|
**By Context:**
|
||||||
|
|
||||||
|
**Documentation/Tutorials:**
|
||||||
|
- Nord - Clean, professional
|
||||||
|
- GitHub Dark - Familiar to developers
|
||||||
|
- Catppuccin - Easy on eyes for long reading
|
||||||
|
|
||||||
|
**Code Demos:**
|
||||||
|
- Dracula - Popular, high contrast
|
||||||
|
- Monokai - Classic, widely recognized
|
||||||
|
- Tokyo Night - Modern, vibrant
|
||||||
|
|
||||||
|
**Presentations:**
|
||||||
|
- High-contrast themes for visibility
|
||||||
|
- Avoid very dark themes in bright rooms
|
||||||
|
- Test on actual projection equipment
|
||||||
|
|
||||||
|
**Brand Alignment:**
|
||||||
|
- Match company/project color schemes
|
||||||
|
- Custom themes can be defined
|
||||||
|
|
||||||
|
## Content Guidelines
|
||||||
|
|
||||||
|
### Command Structure
|
||||||
|
|
||||||
|
**Clear Sequencing:**
|
||||||
|
```tape
|
||||||
|
# Good - Shows logical flow
|
||||||
|
Type "# Step 1: Setup"
|
||||||
|
Sleep 500ms Enter
|
||||||
|
Type "mkdir project && cd project"
|
||||||
|
Sleep 500ms Enter
|
||||||
|
Sleep 2s
|
||||||
|
|
||||||
|
Type "# Step 2: Install"
|
||||||
|
Sleep 500ms Enter
|
||||||
|
Type "npm install"
|
||||||
|
Sleep 500ms Enter
|
||||||
|
Sleep 3s
|
||||||
|
```
|
||||||
|
|
||||||
|
**Avoid:**
|
||||||
|
```tape
|
||||||
|
# Bad - No context, rushed
|
||||||
|
Type "mkdir project"
|
||||||
|
Enter
|
||||||
|
Type "cd project"
|
||||||
|
Enter
|
||||||
|
Type "npm install"
|
||||||
|
Enter
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adding Context
|
||||||
|
|
||||||
|
**Title Slides:**
|
||||||
|
```tape
|
||||||
|
Type "# Demo: Package Installation"
|
||||||
|
Sleep 500ms Enter
|
||||||
|
Sleep 1.5s
|
||||||
|
```
|
||||||
|
|
||||||
|
**Section Headers:**
|
||||||
|
```tape
|
||||||
|
Type "## Installing dependencies..."
|
||||||
|
Sleep 500ms Enter
|
||||||
|
Sleep 1s
|
||||||
|
```
|
||||||
|
|
||||||
|
**Comments:**
|
||||||
|
```tape
|
||||||
|
Type "npm install # This may take a moment"
|
||||||
|
Sleep 500ms Enter
|
||||||
|
```
|
||||||
|
|
||||||
|
### Output Visibility
|
||||||
|
|
||||||
|
**Ensure Key Output is Visible:**
|
||||||
|
- Let important output display fully before next command
|
||||||
|
- For long output, consider showing excerpts
|
||||||
|
- Use `Sleep` to give viewers time to read
|
||||||
|
|
||||||
|
**Managing Long Output:**
|
||||||
|
```tape
|
||||||
|
# Option 1: Show beginning only
|
||||||
|
Type "npm install"
|
||||||
|
Enter
|
||||||
|
Sleep 2s # Shows first part of output
|
||||||
|
Ctrl+C # Stop before it scrolls too much
|
||||||
|
|
||||||
|
# Option 2: Use commands that limit output
|
||||||
|
Type "git log --oneline -5" # Show last 5 commits only
|
||||||
|
Enter
|
||||||
|
```
|
||||||
|
|
||||||
|
## File Size Optimization
|
||||||
|
|
||||||
|
### Target Sizes
|
||||||
|
- **Small demos** (<500KB): Ideal for documentation
|
||||||
|
- **Medium demos** (500KB-1MB): Acceptable for most uses
|
||||||
|
- **Large demos** (>1MB): Consider compression or shorter duration
|
||||||
|
|
||||||
|
### Reducing File Size
|
||||||
|
|
||||||
|
**1. Shorter Duration:**
|
||||||
|
```tape
|
||||||
|
# Reduce unnecessary sleep time
|
||||||
|
Sleep 1s # Instead of Sleep 3s
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Smaller Dimensions:**
|
||||||
|
```tape
|
||||||
|
# Use compact size for simple demos
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 600
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Appropriate Format:**
|
||||||
|
```tape
|
||||||
|
Output demo.mp4 # Better compression for longer demos
|
||||||
|
Output demo.webm # Smaller file size than GIF
|
||||||
|
Output demo.gif # Good for short demos
|
||||||
|
```
|
||||||
|
|
||||||
|
## Accessibility
|
||||||
|
|
||||||
|
### Consider All Viewers
|
||||||
|
|
||||||
|
**Color Choices:**
|
||||||
|
- High contrast improves readability
|
||||||
|
- Avoid color-only distinctions
|
||||||
|
- Test with color-blind simulators
|
||||||
|
|
||||||
|
**Font Size:**
|
||||||
|
- 16pt minimum for web documentation
|
||||||
|
- 20pt minimum for presentations
|
||||||
|
- Test on mobile devices
|
||||||
|
|
||||||
|
**Pacing:**
|
||||||
|
- Allow time to read output
|
||||||
|
- Avoid rapid command sequences
|
||||||
|
- Provide clear visual breaks
|
||||||
|
|
||||||
|
## Testing and Quality Assurance
|
||||||
|
|
||||||
|
### Before Publishing
|
||||||
|
|
||||||
|
**1. Watch the Entire Demo:**
|
||||||
|
- Verify all commands execute as expected
|
||||||
|
- Check for timing issues
|
||||||
|
- Ensure output is visible
|
||||||
|
|
||||||
|
**2. Test on Different Displays:**
|
||||||
|
- Desktop monitors
|
||||||
|
- Mobile devices
|
||||||
|
- Projection screens (if for presentations)
|
||||||
|
|
||||||
|
**3. Check File Size:**
|
||||||
|
- Optimize if necessary
|
||||||
|
- Consider alternative formats
|
||||||
|
|
||||||
|
**4. Verify Accessibility:**
|
||||||
|
- Readable fonts
|
||||||
|
- Clear contrast
|
||||||
|
- Appropriate pacing
|
||||||
|
|
||||||
|
**5. Get Feedback:**
|
||||||
|
- Show to someone unfamiliar with the content
|
||||||
|
- Ask if the flow is clear
|
||||||
|
- Adjust based on feedback
|
||||||
|
|
||||||
|
## Common Mistakes to Avoid
|
||||||
|
|
||||||
|
### ❌ Too Fast
|
||||||
|
```tape
|
||||||
|
Type "command1" Enter Sleep 0.5s
|
||||||
|
Type "command2" Enter Sleep 0.5s
|
||||||
|
Type "command3" Enter Sleep 0.5s
|
||||||
|
# Viewers can't process this
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✅ Appropriate Pacing
|
||||||
|
```tape
|
||||||
|
Type "command1" Sleep 500ms Enter
|
||||||
|
Sleep 2s
|
||||||
|
|
||||||
|
Type "command2" Sleep 500ms Enter
|
||||||
|
Sleep 2s
|
||||||
|
```
|
||||||
|
|
||||||
|
### ❌ No Context
|
||||||
|
```tape
|
||||||
|
Type "npm install"
|
||||||
|
Enter
|
||||||
|
# What are we installing? Why?
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✅ With Context
|
||||||
|
```tape
|
||||||
|
Type "# Installing dependencies"
|
||||||
|
Sleep 500ms Enter
|
||||||
|
Sleep 1s
|
||||||
|
|
||||||
|
Type "npm install"
|
||||||
|
Sleep 500ms Enter
|
||||||
|
```
|
||||||
|
|
||||||
|
### ❌ Output Scrolls Too Fast
|
||||||
|
```tape
|
||||||
|
Type "long-running-command"
|
||||||
|
Enter
|
||||||
|
Sleep 1s # Output still scrolling!
|
||||||
|
Type "next-command"
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✅ Allow Output to Complete
|
||||||
|
```tape
|
||||||
|
Type "long-running-command"
|
||||||
|
Enter
|
||||||
|
Sleep 3s # Let it finish
|
||||||
|
|
||||||
|
Type "next-command"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples of Good Demos
|
||||||
|
|
||||||
|
### Simple Feature Demo (15 seconds)
|
||||||
|
```tape
|
||||||
|
Output feature-demo.gif
|
||||||
|
Set FontSize 16
|
||||||
|
Set Width 1400
|
||||||
|
Set Height 700
|
||||||
|
Set Theme "Dracula"
|
||||||
|
|
||||||
|
Type "# Demo: Quick Start" Sleep 500ms Enter
|
||||||
|
Sleep 1.5s
|
||||||
|
|
||||||
|
Type "npm install my-tool" Sleep 500ms Enter
|
||||||
|
Sleep 2.5s
|
||||||
|
|
||||||
|
Type "my-tool --help" Sleep 500ms Enter
|
||||||
|
Sleep 2s
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Step Workflow (30 seconds)
|
||||||
|
```tape
|
||||||
|
Output workflow-demo.gif
|
||||||
|
Set FontSize 16
|
||||||
|
Set Width 1400
|
||||||
|
Set Height 700
|
||||||
|
Set Theme "Nord"
|
||||||
|
|
||||||
|
Type "# Demo: Complete Workflow" Sleep 500ms Enter
|
||||||
|
Sleep 1.5s
|
||||||
|
|
||||||
|
Type "# 1. Create project" Sleep 500ms Enter
|
||||||
|
Type "mkdir my-project && cd my-project" Sleep 500ms Enter
|
||||||
|
Sleep 2s
|
||||||
|
|
||||||
|
Type "# 2. Initialize" Sleep 500ms Enter
|
||||||
|
Type "npm init -y" Sleep 500ms Enter
|
||||||
|
Sleep 2s
|
||||||
|
|
||||||
|
Type "# 3. Install package" Sleep 500ms Enter
|
||||||
|
Type "npm install express" Sleep 500ms Enter
|
||||||
|
Sleep 3s
|
||||||
|
|
||||||
|
Type "# 4. Ready to code!" Sleep 500ms Enter
|
||||||
|
Sleep 2s
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary Checklist
|
||||||
|
|
||||||
|
Before publishing a demo, verify:
|
||||||
|
|
||||||
|
- [ ] Duration is appropriate (15-30s ideal)
|
||||||
|
- [ ] Timing allows reading output
|
||||||
|
- [ ] Commands are clear and purposeful
|
||||||
|
- [ ] Context is provided where needed
|
||||||
|
- [ ] Output is fully visible
|
||||||
|
- [ ] File size is reasonable
|
||||||
|
- [ ] Theme and fonts are readable
|
||||||
|
- [ ] Tested on target devices
|
||||||
|
- [ ] Accessible to all viewers
|
||||||
|
- [ ] Demonstrates one clear concept
|
||||||
241
skills/cli-demo-generator/references/vhs_syntax.md
Normal file
241
skills/cli-demo-generator/references/vhs_syntax.md
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
# VHS Tape File Syntax Reference
|
||||||
|
|
||||||
|
VHS (Video Home System) is a tool for creating terminal recordings as code. This reference covers the complete tape file syntax.
|
||||||
|
|
||||||
|
## Basic Structure
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Output demo.gif
|
||||||
|
|
||||||
|
Set FontSize 16
|
||||||
|
Set Width 1400
|
||||||
|
Set Height 700
|
||||||
|
Set Theme "Dracula"
|
||||||
|
|
||||||
|
Type "echo Hello"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Commands
|
||||||
|
|
||||||
|
### Output
|
||||||
|
|
||||||
|
Specify the output file path and format:
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Output demo.gif # GIF format (default)
|
||||||
|
Output demo.mp4 # MP4 video
|
||||||
|
Output demo.webm # WebM video
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set Commands
|
||||||
|
|
||||||
|
Configure the terminal appearance:
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Set FontSize 16 # Font size (10-72)
|
||||||
|
Set Width 1400 # Terminal width in pixels
|
||||||
|
Set Height 700 # Terminal height in pixels
|
||||||
|
Set Theme "Dracula" # Color theme
|
||||||
|
Set Padding 20 # Padding around terminal (pixels)
|
||||||
|
Set TypingSpeed 50ms # Speed of typing animation
|
||||||
|
Set Shell bash # Shell to use (bash, zsh, fish)
|
||||||
|
Set FontFamily "MonoLisa" # Font family name
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interaction Commands
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
Simulate typing text:
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Type "ls -la" # Type the command
|
||||||
|
Type "Hello World" # Type any text
|
||||||
|
```
|
||||||
|
|
||||||
|
### Enter
|
||||||
|
|
||||||
|
Press the Enter key:
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Enter
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backspace
|
||||||
|
|
||||||
|
Delete characters:
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Backspace # Delete one character
|
||||||
|
Backspace 5 # Delete 5 characters
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sleep
|
||||||
|
|
||||||
|
Pause execution:
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Sleep 1s # Sleep for 1 second
|
||||||
|
Sleep 500ms # Sleep for 500 milliseconds
|
||||||
|
Sleep 2.5s # Sleep for 2.5 seconds
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ctrl+C
|
||||||
|
|
||||||
|
Send interrupt signal:
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Ctrl+C
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key combinations
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Ctrl+D # End of transmission
|
||||||
|
Ctrl+L # Clear screen
|
||||||
|
Tab # Tab completion
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Features
|
||||||
|
|
||||||
|
### Play (asciinema integration)
|
||||||
|
|
||||||
|
Play back an asciinema recording:
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Play recording.cast
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hide/Show
|
||||||
|
|
||||||
|
Control terminal visibility:
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Hide
|
||||||
|
Type "secret command"
|
||||||
|
Show
|
||||||
|
```
|
||||||
|
|
||||||
|
### Screenshot
|
||||||
|
|
||||||
|
Take a screenshot at specific point:
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Screenshot demo-screenshot.png
|
||||||
|
```
|
||||||
|
|
||||||
|
## Available Themes
|
||||||
|
|
||||||
|
Popular built-in themes:
|
||||||
|
|
||||||
|
- **Dracula** - Dark purple theme
|
||||||
|
- **Monokai** - Classic dark theme
|
||||||
|
- **Nord** - Arctic-inspired cool theme
|
||||||
|
- **Catppuccin** - Soothing pastel theme
|
||||||
|
- **GitHub Dark** - GitHub's dark theme
|
||||||
|
- **Tokyo Night** - Vibrant dark theme
|
||||||
|
- **Gruvbox** - Retro groove colors
|
||||||
|
|
||||||
|
## Example Templates
|
||||||
|
|
||||||
|
### Basic Command Demo
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Output demo.gif
|
||||||
|
|
||||||
|
Set FontSize 16
|
||||||
|
Set Width 1400
|
||||||
|
Set Height 700
|
||||||
|
Set Theme "Dracula"
|
||||||
|
|
||||||
|
Type "# Demo Title" Sleep 500ms Enter
|
||||||
|
Sleep 1s
|
||||||
|
|
||||||
|
Type "command1" Sleep 500ms Enter
|
||||||
|
Sleep 2s
|
||||||
|
|
||||||
|
Type "command2" Sleep 500ms Enter
|
||||||
|
Sleep 2s
|
||||||
|
```
|
||||||
|
|
||||||
|
### Interactive Typing Demo
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Output demo.gif
|
||||||
|
|
||||||
|
Set FontSize 16
|
||||||
|
Set Width 1400
|
||||||
|
Set Height 700
|
||||||
|
Set Theme "Dracula"
|
||||||
|
Set TypingSpeed 100ms
|
||||||
|
|
||||||
|
Type "npm install my-package"
|
||||||
|
Enter
|
||||||
|
Sleep 3s
|
||||||
|
|
||||||
|
Type "npm start"
|
||||||
|
Enter
|
||||||
|
Sleep 2s
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Step Tutorial
|
||||||
|
|
||||||
|
```tape
|
||||||
|
Output tutorial.gif
|
||||||
|
|
||||||
|
Set FontSize 16
|
||||||
|
Set Width 1400
|
||||||
|
Set Height 700
|
||||||
|
Set Theme "Tokyo Night"
|
||||||
|
|
||||||
|
Type "# Step 1: Clone the repository" Enter
|
||||||
|
Sleep 1s
|
||||||
|
Type "git clone https://github.com/user/repo.git" Enter
|
||||||
|
Sleep 3s
|
||||||
|
|
||||||
|
Type "# Step 2: Install dependencies" Enter
|
||||||
|
Sleep 1s
|
||||||
|
Type "cd repo && npm install" Enter
|
||||||
|
Sleep 3s
|
||||||
|
|
||||||
|
Type "# Step 3: Run the app" Enter
|
||||||
|
Sleep 1s
|
||||||
|
Type "npm start" Enter
|
||||||
|
Sleep 2s
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Timing**: Use appropriate sleep durations
|
||||||
|
- Quick commands: 1s
|
||||||
|
- Medium commands: 2s
|
||||||
|
- Long commands (install, build): 3s+
|
||||||
|
|
||||||
|
2. **Width/Height**: Standard sizes
|
||||||
|
- Compact: 1200x600
|
||||||
|
- Standard: 1400x700
|
||||||
|
- Wide: 1600x800
|
||||||
|
|
||||||
|
3. **Font Size**: Readability
|
||||||
|
- Small terminals: 14-16
|
||||||
|
- Standard: 16-18
|
||||||
|
- Presentations: 20-24
|
||||||
|
|
||||||
|
4. **Theme Selection**: Consider context
|
||||||
|
- Code demos: Dracula, Monokai
|
||||||
|
- Documentation: Nord, GitHub Dark
|
||||||
|
- Presentations: High-contrast themes
|
||||||
|
|
||||||
|
5. **Title Slides**: Add context
|
||||||
|
```tape
|
||||||
|
Type "# Demo: Project Setup" Enter
|
||||||
|
Sleep 1s
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **Cleanup**: Show clear ending
|
||||||
|
```tape
|
||||||
|
Sleep 2s
|
||||||
|
Type "# Demo complete!" Enter
|
||||||
|
```
|
||||||
151
skills/cli-demo-generator/scripts/auto_generate_demo.py
Executable file
151
skills/cli-demo-generator/scripts/auto_generate_demo.py
Executable file
@@ -0,0 +1,151 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Auto-generate CLI demos from command descriptions.
|
||||||
|
|
||||||
|
This script creates VHS tape files and generates GIF demos automatically.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
|
|
||||||
|
def create_tape_file(
|
||||||
|
commands: List[str],
|
||||||
|
output_gif: str,
|
||||||
|
title: Optional[str] = None,
|
||||||
|
theme: str = "Dracula",
|
||||||
|
font_size: int = 16,
|
||||||
|
width: int = 1400,
|
||||||
|
height: int = 700,
|
||||||
|
padding: int = 20,
|
||||||
|
) -> str:
|
||||||
|
"""Generate a VHS tape file from commands."""
|
||||||
|
|
||||||
|
tape_lines = [
|
||||||
|
f'Output {output_gif}',
|
||||||
|
'',
|
||||||
|
f'Set FontSize {font_size}',
|
||||||
|
f'Set Width {width}',
|
||||||
|
f'Set Height {height}',
|
||||||
|
f'Set Theme "{theme}"',
|
||||||
|
f'Set Padding {padding}',
|
||||||
|
'',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add title if provided
|
||||||
|
if title:
|
||||||
|
tape_lines.extend([
|
||||||
|
f'Type "# {title}" Sleep 500ms Enter',
|
||||||
|
'Sleep 1s',
|
||||||
|
'',
|
||||||
|
])
|
||||||
|
|
||||||
|
# Add commands with smart timing
|
||||||
|
for i, cmd in enumerate(commands, 1):
|
||||||
|
# Type the command
|
||||||
|
tape_lines.append(f'Type "{cmd}" Sleep 500ms')
|
||||||
|
tape_lines.append('Enter')
|
||||||
|
|
||||||
|
# Smart sleep based on command complexity
|
||||||
|
if any(keyword in cmd.lower() for keyword in ['install', 'build', 'test', 'deploy']):
|
||||||
|
sleep_time = '3s'
|
||||||
|
elif any(keyword in cmd.lower() for keyword in ['ls', 'pwd', 'echo', 'cat']):
|
||||||
|
sleep_time = '1s'
|
||||||
|
else:
|
||||||
|
sleep_time = '2s'
|
||||||
|
|
||||||
|
tape_lines.append(f'Sleep {sleep_time}')
|
||||||
|
|
||||||
|
# Add spacing between commands
|
||||||
|
if i < len(commands):
|
||||||
|
tape_lines.append('')
|
||||||
|
|
||||||
|
return '\n'.join(tape_lines)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Auto-generate CLI demos from commands',
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
epilog='''
|
||||||
|
Examples:
|
||||||
|
# Generate demo from single command
|
||||||
|
%(prog)s -c "npm install" -o demo.gif
|
||||||
|
|
||||||
|
# Generate demo with multiple commands
|
||||||
|
%(prog)s -c "git clone repo" -c "cd repo" -c "npm install" -o setup.gif
|
||||||
|
|
||||||
|
# Custom theme and size
|
||||||
|
%(prog)s -c "ls -la" -o demo.gif --theme Monokai --width 1200
|
||||||
|
|
||||||
|
# With title
|
||||||
|
%(prog)s -c "echo Hello" -o demo.gif --title "My Demo"
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument('-c', '--command', action='append', required=True,
|
||||||
|
help='Command to include in demo (can be specified multiple times)')
|
||||||
|
parser.add_argument('-o', '--output', required=True,
|
||||||
|
help='Output GIF file path')
|
||||||
|
parser.add_argument('--title', help='Demo title (optional)')
|
||||||
|
parser.add_argument('--theme', default='Dracula',
|
||||||
|
help='VHS theme (default: Dracula)')
|
||||||
|
parser.add_argument('--font-size', type=int, default=16,
|
||||||
|
help='Font size (default: 16)')
|
||||||
|
parser.add_argument('--width', type=int, default=1400,
|
||||||
|
help='Terminal width (default: 1400)')
|
||||||
|
parser.add_argument('--height', type=int, default=700,
|
||||||
|
help='Terminal height (default: 700)')
|
||||||
|
parser.add_argument('--no-execute', action='store_true',
|
||||||
|
help='Generate tape file only, do not execute VHS')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Generate tape file content
|
||||||
|
tape_content = create_tape_file(
|
||||||
|
commands=args.command,
|
||||||
|
output_gif=args.output,
|
||||||
|
title=args.title,
|
||||||
|
theme=args.theme,
|
||||||
|
font_size=args.font_size,
|
||||||
|
width=args.width,
|
||||||
|
height=args.height,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Write tape file
|
||||||
|
output_path = Path(args.output)
|
||||||
|
tape_file = output_path.with_suffix('.tape')
|
||||||
|
|
||||||
|
with open(tape_file, 'w') as f:
|
||||||
|
f.write(tape_content)
|
||||||
|
|
||||||
|
print(f"✓ Generated tape file: {tape_file}")
|
||||||
|
|
||||||
|
if not args.no_execute:
|
||||||
|
# Check if VHS is installed
|
||||||
|
try:
|
||||||
|
subprocess.run(['vhs', '--version'], capture_output=True, check=True)
|
||||||
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||||
|
print("✗ VHS is not installed!", file=sys.stderr)
|
||||||
|
print("Install it with: brew install vhs", file=sys.stderr)
|
||||||
|
print(f"✓ You can manually run: vhs < {tape_file}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Execute VHS
|
||||||
|
print(f"Generating GIF: {args.output}")
|
||||||
|
try:
|
||||||
|
subprocess.run(['vhs', str(tape_file)], check=True)
|
||||||
|
print(f"✓ Demo generated: {args.output}")
|
||||||
|
print(f" Size: {output_path.stat().st_size / 1024:.1f} KB")
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"✗ VHS execution failed: {e}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
||||||
175
skills/cli-demo-generator/scripts/batch_generate.py
Executable file
175
skills/cli-demo-generator/scripts/batch_generate.py
Executable file
@@ -0,0 +1,175 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Batch generate multiple CLI demos from a configuration file.
|
||||||
|
|
||||||
|
Supports YAML and JSON formats for defining multiple demos.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
try:
|
||||||
|
import yaml
|
||||||
|
YAML_AVAILABLE = True
|
||||||
|
except ImportError:
|
||||||
|
YAML_AVAILABLE = False
|
||||||
|
|
||||||
|
|
||||||
|
def load_config(config_file: Path) -> Dict:
|
||||||
|
"""Load demo configuration from YAML or JSON file."""
|
||||||
|
suffix = config_file.suffix.lower()
|
||||||
|
|
||||||
|
with open(config_file) as f:
|
||||||
|
if suffix in ['.yaml', '.yml']:
|
||||||
|
if not YAML_AVAILABLE:
|
||||||
|
print("Error: PyYAML not installed. Install with: pip install pyyaml", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
return yaml.safe_load(f)
|
||||||
|
elif suffix == '.json':
|
||||||
|
return json.load(f)
|
||||||
|
else:
|
||||||
|
print(f"Error: Unsupported config format: {suffix}", file=sys.stderr)
|
||||||
|
print("Supported formats: .yaml, .yml, .json", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_demo(demo_config: Dict, base_path: Path, script_path: Path) -> bool:
|
||||||
|
"""Generate a single demo from configuration."""
|
||||||
|
name = demo_config.get('name', 'unnamed')
|
||||||
|
output = demo_config.get('output')
|
||||||
|
commands = demo_config.get('commands', [])
|
||||||
|
|
||||||
|
if not output or not commands:
|
||||||
|
print(f"✗ Skipping '{name}': missing output or commands", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Build command
|
||||||
|
cmd = [sys.executable, str(script_path)]
|
||||||
|
|
||||||
|
for command in commands:
|
||||||
|
cmd.extend(['-c', command])
|
||||||
|
|
||||||
|
cmd.extend(['-o', str(base_path / output)])
|
||||||
|
|
||||||
|
# Optional parameters
|
||||||
|
if 'title' in demo_config:
|
||||||
|
cmd.extend(['--title', demo_config['title']])
|
||||||
|
if 'theme' in demo_config:
|
||||||
|
cmd.extend(['--theme', demo_config['theme']])
|
||||||
|
if 'width' in demo_config:
|
||||||
|
cmd.extend(['--width', str(demo_config['width'])])
|
||||||
|
if 'height' in demo_config:
|
||||||
|
cmd.extend(['--height', str(demo_config['height'])])
|
||||||
|
|
||||||
|
print(f"\n{'='*60}")
|
||||||
|
print(f"Generating: {name}")
|
||||||
|
print(f"Output: {output}")
|
||||||
|
print(f"Commands: {len(commands)}")
|
||||||
|
print(f"{'='*60}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run(cmd, check=True)
|
||||||
|
return True
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"✗ Failed to generate '{name}': {e}", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Batch generate CLI demos from configuration file',
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
epilog='''
|
||||||
|
Configuration file format (YAML):
|
||||||
|
demos:
|
||||||
|
- name: "Install Demo"
|
||||||
|
output: "install.gif"
|
||||||
|
title: "Installation"
|
||||||
|
theme: "Dracula"
|
||||||
|
commands:
|
||||||
|
- "npm install my-package"
|
||||||
|
- "npm run build"
|
||||||
|
|
||||||
|
- name: "Usage Demo"
|
||||||
|
output: "usage.gif"
|
||||||
|
commands:
|
||||||
|
- "my-package --help"
|
||||||
|
- "my-package run"
|
||||||
|
|
||||||
|
Configuration file format (JSON):
|
||||||
|
{
|
||||||
|
"demos": [
|
||||||
|
{
|
||||||
|
"name": "Install Demo",
|
||||||
|
"output": "install.gif",
|
||||||
|
"commands": ["npm install"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument('config', type=Path,
|
||||||
|
help='Configuration file (.yaml, .yml, or .json)')
|
||||||
|
parser.add_argument('--output-dir', type=Path, default=Path.cwd(),
|
||||||
|
help='Output directory for generated demos')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if not args.config.exists():
|
||||||
|
print(f"Error: Config file not found: {args.config}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Load configuration
|
||||||
|
config = load_config(args.config)
|
||||||
|
demos = config.get('demos', [])
|
||||||
|
|
||||||
|
if not demos:
|
||||||
|
print("Error: No demos defined in configuration", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Create output directory
|
||||||
|
args.output_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
# Find auto_generate_demo.py script
|
||||||
|
script_path = Path(__file__).parent / 'auto_generate_demo.py'
|
||||||
|
if not script_path.exists():
|
||||||
|
print(f"Error: auto_generate_demo.py not found at {script_path}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Generate demos
|
||||||
|
total = len(demos)
|
||||||
|
successful = 0
|
||||||
|
failed = 0
|
||||||
|
|
||||||
|
print(f"\n{'='*60}")
|
||||||
|
print(f"Starting batch generation: {total} demos")
|
||||||
|
print(f"Output directory: {args.output_dir}")
|
||||||
|
print(f"{'='*60}\n")
|
||||||
|
|
||||||
|
for i, demo in enumerate(demos, 1):
|
||||||
|
print(f"\n[{i}/{total}] Processing: {demo.get('name', 'unnamed')}")
|
||||||
|
if generate_demo(demo, args.output_dir, script_path):
|
||||||
|
successful += 1
|
||||||
|
else:
|
||||||
|
failed += 1
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
print(f"\n{'='*60}")
|
||||||
|
print(f"Batch generation complete!")
|
||||||
|
print(f"{'='*60}")
|
||||||
|
print(f"✓ Successful: {successful}")
|
||||||
|
if failed > 0:
|
||||||
|
print(f"✗ Failed: {failed}")
|
||||||
|
print(f"Total: {total}")
|
||||||
|
print(f"{'='*60}\n")
|
||||||
|
|
||||||
|
return 0 if failed == 0 else 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
||||||
136
skills/cli-demo-generator/scripts/record_interactive.sh
Executable file
136
skills/cli-demo-generator/scripts/record_interactive.sh
Executable file
@@ -0,0 +1,136 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Record interactive CLI demos using asciinema and convert to GIF
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# record_interactive.sh output.gif
|
||||||
|
# record_interactive.sh output.gif --theme Dracula --width 1200
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# Default values
|
||||||
|
OUTPUT=""
|
||||||
|
THEME="Dracula"
|
||||||
|
WIDTH=1400
|
||||||
|
HEIGHT=700
|
||||||
|
FONT_SIZE=16
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
--theme)
|
||||||
|
THEME="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--width)
|
||||||
|
WIDTH="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--height)
|
||||||
|
HEIGHT="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--font-size)
|
||||||
|
FONT_SIZE="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
OUTPUT="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$OUTPUT" ]; then
|
||||||
|
echo -e "${RED}Error: Output file required${NC}" >&2
|
||||||
|
echo "Usage: $0 output.gif [--theme Theme] [--width 1200] [--height 700]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check dependencies
|
||||||
|
if ! command -v asciinema &> /dev/null; then
|
||||||
|
echo -e "${RED}Error: asciinema not installed${NC}" >&2
|
||||||
|
echo "Install it with:"
|
||||||
|
echo " macOS: brew install asciinema"
|
||||||
|
echo " Linux: sudo apt install asciinema"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v vhs &> /dev/null; then
|
||||||
|
echo -e "${RED}Error: VHS not installed${NC}" >&2
|
||||||
|
echo "Install it with: brew install vhs"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate temp files
|
||||||
|
CAST_FILE="${OUTPUT%.gif}.cast"
|
||||||
|
TAPE_FILE="${OUTPUT%.gif}.tape"
|
||||||
|
|
||||||
|
echo -e "${GREEN}===========================================================${NC}"
|
||||||
|
echo -e "${GREEN}Interactive Demo Recording${NC}"
|
||||||
|
echo -e "${GREEN}===========================================================${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}Instructions:${NC}"
|
||||||
|
echo "1. Type your commands naturally"
|
||||||
|
echo "2. Press ENTER after each command"
|
||||||
|
echo "3. Press Ctrl+D when finished"
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}Output:${NC} $OUTPUT"
|
||||||
|
echo -e "${YELLOW}Theme:${NC} $THEME"
|
||||||
|
echo -e "${YELLOW}Size:${NC} ${WIDTH}x${HEIGHT}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}Starting recording in 3 seconds...${NC}"
|
||||||
|
sleep 3
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Record with asciinema
|
||||||
|
asciinema rec "$CAST_FILE"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}✓ Recording saved to: $CAST_FILE${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}Converting to GIF...${NC}"
|
||||||
|
|
||||||
|
# Convert asciinema cast to VHS tape format
|
||||||
|
cat > "$TAPE_FILE" << EOF
|
||||||
|
Output $OUTPUT
|
||||||
|
|
||||||
|
Set FontSize $FONT_SIZE
|
||||||
|
Set Width $WIDTH
|
||||||
|
Set Height $HEIGHT
|
||||||
|
Set Theme "$THEME"
|
||||||
|
Set Padding 20
|
||||||
|
|
||||||
|
Play $CAST_FILE
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ Generated tape file: $TAPE_FILE${NC}"
|
||||||
|
|
||||||
|
# Generate GIF with VHS
|
||||||
|
vhs < "$TAPE_FILE"
|
||||||
|
|
||||||
|
if [ -f "$OUTPUT" ]; then
|
||||||
|
FILE_SIZE=$(du -h "$OUTPUT" | cut -f1)
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}===========================================================${NC}"
|
||||||
|
echo -e "${GREEN}✓ Demo generated successfully!${NC}"
|
||||||
|
echo -e "${GREEN}===========================================================${NC}"
|
||||||
|
echo -e "${YELLOW}Output:${NC} $OUTPUT"
|
||||||
|
echo -e "${YELLOW}Size:${NC} $FILE_SIZE"
|
||||||
|
echo ""
|
||||||
|
echo "Generated files:"
|
||||||
|
echo " - $CAST_FILE (asciinema recording)"
|
||||||
|
echo " - $TAPE_FILE (VHS tape file)"
|
||||||
|
echo " - $OUTPUT (GIF demo)"
|
||||||
|
echo ""
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ Failed to generate GIF${NC}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user