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 noise filtering, post-processing speed-up, and frame-level verification. Use when users want to create terminal demos, record CLI workflows as GIFs, generate animated documentation, build demo tapes for README files, or need to showcase any command-line tool visually. Also triggers on "record terminal", "VHS tape", "demo GIF", "animate my CLI", or any request to visually demonstrate shell commands.
1How It Works & Mechanism
The core of automated generation is translating a list of commands into a VHS tape file (Output/Set Theme/Set FontSize/Type/Enter/Sleep...), which is then passed to vhs to render into a GIF.
tape_lines = [ f'Output {output_gif}', f'Set Theme "{theme}"', f'Set FontSize {font_size}', f'Set Width {width}', f'Set Height {height}', f'Set Padding {padding}', 'Set TypingSpeed 10ms', 'Set Shell zsh', '', ]
Recording is live execution: Without --no-execute, main() directly calls vhs via subprocess, and the commands in the tape are genuinely typed and executed inside the vhs pseudo-terminal.
subprocess.run(['vhs', str(tape_file)], check=True)
Workarounds for VHS parser limitations: Type strings cannot contain $, double quotes, or backticks; complex commands are base64-encoded first and decoded for execution at runtime.
VHS `Type` strings cannot contain `$`, `"`, or backticks. These cause parse errors
"Audience perspective" orchestration for bootstrapping and noise filtering: The Hide block runs setup/cleanup → clear wipes the screen → Show is called before starting to record the commands meant for the audience.
tape_lines.append('Hide') … tape_lines.append('Show')
Smart pacing: Context-aware Sleep durations based on command semantics (install/build/test/deploy → 3s, ls/pwd/echo, etc. → 1s, others → 2s); gifsicle can be used for post-processing speed adjustments after recording.
if any(kw in cmd.lower() for kw in ['install', 'build', 'test', 'deploy', 'marketplace']): sleep_time = '3s' elif any(kw in cmd.lower() for kw in ['ls', 'pwd', 'echo', 'cat', 'grep']): sleep_time = '1s' else: sleep_time = '2s'
Three additional modes: Batch configuration (batch_generate.py reads YAML/JSON and invokes the auto script iteratively), interactive recording (asciinema records live sessions → converted to tape → rendered by vhs), and manual/template tape editing (assets/templates + placeholder replacement).
cmd = [sys.executable, str(script_path)] for command in commands: cmd.extend(['-c', command])
2Core Capabilities
3External Dependencies
| Kind | Dependency / Endpoint |
|---|---|
| cli | vhs(charmbracelet,必需) |
| cli | gifsicle(可选,变速) |
| cli | asciinema(可选,交互录制) |
| cli | ffmpeg/ffprobe(可选,抽帧验证) |
| package | PyYAML(可选,batch YAML 配置) |
4Recommended Governance & Evidence
- scripts/: Executes local scripts or commands: cli-demo-generator/scripts/auto_generate_demo.py (internally executes vhs/gifsicle/cp)
- 本地工作目录: File read/write and artifact output: Writes generated GIF/tape files to user-specified -o paths
5Second-Pass Verification
- [ok] 自带脚本零网络外发 — scripts/ 三文件 token 扫描(URL/curl/wget/requests/urllib/socket/API_KEY/token/secret/os.system)零命中;子进程仅 vhs/gifsicle/cp/asciinema/sed。
- [ok] 执行面:tape 命令真实执行 — auto_generate_demo.py 主流程 subprocess.run(['vhs', str(tape_file)]);tape 中 Type+Enter 在 vhs 终端内被 shell 执行(VHS 工具行为)。
- [ok] --filter 的 base64 包装实现 — wrapper f-string + base64.b64encode + 'echo <b64> | base64 -d > /tmp/cw.sh && source /tmp/cw.sh' 在 create_tape_file 中逐字存在。
- [ok] 变速后处理(gifsicle delay = 10//speed) — speed_up_gif 内 gifsicle -d{delay} tmp '#0-' 且先 cp 到 /tmp 再写回,与 SKILL.md 手写 gifsicle 命令一致。
- [ok] 自举/隐藏命令防泄漏(Hide→clear→Show) — create_tape_file 在有 bootstrap/filter 时依次 append Hide/Type/Enter/Sleep/Type "clear"/Show;SKILL.md 有同序说明。
- [ok] 批处理与交互模式调用链成立 — batch_generate 重建 auto_generate_demo argv(-c 循环);record_interactive.sh 走 asciinema rec → 写 tape → vhs < tape。
- [ok] 功能声明 vs 夸大检查 — description 八项能力全部有代码/SKILL.md 支撑;无越界承诺。依赖标注(VHS 必需、gifsicle/asciinema/ffmpeg/PyYAML 可选)与脚本内降级提示一致。
- [ok] 元数据(license/stars/commit) — 仓库级 MIT、stars=1385、pushed_at=2026-09-09T12:33:29Z;本地 HEAD==pin d5c4678cb5d4fd6acc9c922690df035dbd33d247。
6Verdict & Scenarios
9991cfcecc32bad8…