Files
claude-engineering-plugin/plugins/compound-engineering/skills/ce-demo-reel/references/tier-terminal-recording.md
Trevin Chow 9ddcd22aee
Some checks failed
CI / pr-title (push) Has been cancelled
CI / test (push) Has been cancelled
Release PR / release-pr (push) Has been cancelled
Release PR / publish-cli (push) Has been cancelled
fix(ce-demo-reel): prevent secrets in recorded demos (#664)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 21:52:52 -07:00

4.6 KiB

Tier: Terminal Recording

Record a terminal session using VHS (charmbracelet/vhs) to produce a GIF demo.

Best for: CLI tools, scripts, command-line features with interaction or motion (typing, streaming output, progressive rendering). Output: GIF (direct from VHS) Label: "Demo" Required tools: vhs

Step 1: Plan the Recording

Before generating a .tape file, determine:

  • What command(s) to run -- The actual product command, not test commands. "I ran npm test" is test evidence, not a demo.
  • Expected output -- What the terminal should show when the command succeeds.
  • Terminal dimensions -- Wide enough for the longest output line, tall enough to avoid scrolling.
  • Timing -- Target 5-10 seconds total. Enough sleep after each command for output to render.
  • Secret exposure points -- Any step that could surface a credential: env exports, source .env, printenv/env/set, CLIs with --api-key/--token flags, verbose/debug flags, commands that echo tokens in output or error traces, shell prompts with env-interpolated $VAR segments. Set real credentials inside a Hide block at the top of the .tape, run clear at the end of the block to flush the buffer, then Show. Use a clean HOME (export HOME=$(mktemp -d)) inside Hide so personal dotfiles, cached CLI tokens, and env-interpolated prompts can't leak.

Step 2: Generate .tape File

Write a VHS tape file to [RUN_DIR]/demo.tape:

Output [RUN_DIR]/demo.gif

Set FontSize 16
Set Width 800
Set Height 500
Set Theme "Catppuccin Mocha"
Set TypingSpeed 40ms

# Hidden prelude: clean HOME, set real secrets, any setup that would leak.
# These commands execute for real but never appear in the GIF.
# `clear` at the end flushes the buffer so Show starts on a clean screen.
Hide
Type "export HOME=$(mktemp -d)"
Enter
Type "export API_KEY='real-secret-value'"
Enter
Type "cd /path/to/project"
Enter
Type "clear"
Enter
Show

# Visible demo: commands consume the env set above, but never re-export,
# echo, or print it. Show the feature working -- not the auth mechanism.
Type "your-cli-command --flag value"
Enter
Sleep 3s

# Let viewer read the output
Sleep 2s

Why this shape: success of the visible command is itself evidence the credential was set — no need to show the auth step. Never add a visible export SECRET=... with a fake value: it leaks the variable name and breaks the demo.

Key .tape directives:

  • Output [path] -- Where to write the GIF (must be first line)
  • Set FontSize [14-18] -- Larger for readability
  • Set Width/Height [pixels] -- Match content needs
  • Set Theme [name] -- "Catppuccin Mocha" or "Dracula" are readable defaults
  • Set TypingSpeed [ms] -- 30-50ms feels natural
  • Hide/Show -- Skip boring setup (cd, source, npm install)
  • Type [text] -- Types characters (does not execute)
  • Enter -- Presses enter (executes the typed command)
  • Sleep [duration] -- Wait for output to render

Avoid:

  • Non-deterministic output (random IDs, timestamps that change between runs)
  • Commands that require interactive input (prompts, password entry)
  • Very long output that scrolls off screen

Step 3: Run VHS

Use the capture pipeline script to execute the tape file and validate output:

python3 scripts/capture-demo.py terminal-recording --output [RUN_DIR]/demo.gif --tape [RUN_DIR]/demo.tape

The script runs VHS, validates the output exists, and reports the file size. If the GIF exceeds 10 MB, reduce by adjusting the .tape: smaller terminal dimensions (Set Width/Height), shorter recording (fewer sleeps), or lower font size. Re-run.

Step 4: Quality Check

Read the generated GIF to verify:

  1. Commands are visible and readable
  2. Output renders completely (not cut off)
  3. The feature being demonstrated is clearly shown

Secrets scan (hard gate): Scan the GIF for credential material. If any appears, discard and re-record with the leaking step wrapped in Hide/Show or replaced. Do not upload, do not blur.

Drift check: A broken visible command — 401 Unauthorized, Invalid API key, 0 credits remaining, empty output where data was expected — usually means a visible export SECRET=... after Show overwrote the real env. Fix the .tape so secrets are set in Hide only, never re-exported, and re-record.

If quality is poor, revise the .tape file and re-record.

If VHS fails (crashes, produces empty GIF, or the command being demonstrated fails): fall back to the screenshot reel tier. Write the same commands and expected output as text frames and stitch via silicon + ffmpeg. If silicon is also unavailable, fall back to static screenshots.

Proceed to references/upload-and-approval.md.