Create scripted terminal demo videos of Hermes Agent using the screenplay YAML pipeline. Record, render, and composite polished MP4s with camera zoom/pan, skin theming, and background compositing.
Install
npx skillscat add peteromallet/moirae Install via the SkillsCat registry.
Demo Video Pipeline
Create polished terminal demo videos from YAML screenplays. The pipeline records a scripted terminal session, renders it to GIF via agg, then composites to MP4 with camera zoom/pan effects.
Prerequisites
asciinema— terminal session recordingagg— asciinema GIF renderer (github.com/asciinema/agg)ffmpeg— video encoding- Python packages:
pillow,numpy,pyyaml,pydantic
Quick Start
# Preview in terminal (no recording)
python -m demo demo/scripts/example.yaml
# Record and render to MP4
python -m demo demo/scripts/example.yaml -o demo.mp4
# With a specific skin
python -m demo demo/scripts/example.yaml -o demo.mp4 --skin ares
# Dry run (print commands without executing)
python -m demo demo/scripts/example.yaml -o demo.mp4 --dry-runCLI Options
| Flag | Description |
|---|---|
script |
Path to YAML screenplay file (required) |
-o, --output PATH |
Output MP4 path. If omitted, defaults to --play mode |
--play |
Preview in terminal without recording |
--skin NAME |
Override skin (e.g. ares, mono, slate, poseidon) |
--typing-speed FLOAT |
Override typing speed (seconds per character) |
--dry-run |
Print pipeline commands without executing |
--debug-camera |
Print resolved camera keyframe timeline |
Screenplay YAML Schema
title: "My Demo"
skin: "default" # Skin name (default, ares, mono, slate, poseidon, sisyphus, charizard)
typing_speed: 0.04 # Seconds per character
pause_between: 1.0 # Default pause between scenes
output:
width: 2560 # Render resolution (2x for sharp text)
height: 1440
final_width: 1280 # Output resolution
final_height: 720
fps: 30
font_size: 22
font_family: "Menlo"
theme: "github-light" # agg theme override (omit to use skin default)
bg_image: "path/to/bg.jpg" # Background image (optional)
bg_color: "#fdf1de" # Background fill color (optional)
bg_opacity: 0.85 # Terminal opacity over background (0.0–1.0)
scenes:
# ... scene list (see Scene Types below)Theme and Skin Interaction
The terminal rendering theme comes from the skin's terminal_theme field by default. All built-in skins use github-light. To override for a specific video, set output.theme in the YAML — this takes precedence over the skin.
The compositor's background detection color is derived automatically from the theme via AGG_THEME_BG in skin_engine.py. Available agg themes: asciinema, dracula, github-dark, github-light, kanagawa, kanagawa-dragon, kanagawa-light, monokai, nord, solarized-dark, solarized-light, gruvbox-dark.
Scene Types
Action Scenes
# Clear terminal
- action: clear
# Type a shell command with output
- action: type_command
prefix: "~ $ "
command: "hermes"
output: "Starting Hermes Agent..." # optional
# Show the agent banner
- action: banner
model: "deephermes-3-llama-3.1-8b"
context: "128K"
session_id: "d8f2a1c4"
tools_count: 24
skills_count: 42
# Pause
- action: pause
duration: 1.5
# Print styled text
- action: print
text: "Hello world"
color: "#FFD700"
# Standalone camera move
- action: camera
zoom: 1.0
duration: 0.8
ease: "ease-out"Conversation Scenes
- user: "What are the latest developments in AI agents?"
thinking_time: 3.5
typing_speed: 0.03 # override per-scene
pre_pause: 0.5
post_pause: 0.5
tools:
- icon: "🔍"
verb: "search"
detail: '"AI agents 2026"'
duration: "2.1s"
delay: 0.3
response: |
Here are the key developments...
response_label: " ⚕ Hermes "
# Camera directives (optional)
camera:
zoom: 1.8
x: 0.5 # Normalized 0.0–1.0
y: 0.15
at: "user_start" # Timing marker
duration: 0.8
ease: "ease-in-out"
camera_response:
zoom: 1.4
y: 0.65
at: "response_start"
duration: 0.5
ease: "ease-in-out"Camera Directives
Camera directives control zoom and pan during the video. They can be:
- Attached to conversation scenes (
camera:andcamera_response:) - Standalone action scenes (
action: camera)
| Field | Default | Description |
|---|---|---|
zoom |
1.0 | Zoom multiplier (1.0 = full frame, 2.0 = 2x zoom) |
x |
0.5 | Horizontal center (0.0 = left, 1.0 = right) |
y |
0.5 | Vertical center (0.0 = top, 1.0 = bottom) |
auto_y |
false | Compute y from cursor position at marker time |
at |
"scene_start" | Timing marker (user_start, response_start, scene_start) |
duration |
0.5 | Transition time in seconds |
ease |
"ease-in-out" | Easing: linear, ease-in, ease-out, ease-in-out |
Pipeline Stages
- Record —
asciinema recruns the player in--playmode inside a PTY - Render —
aggconverts the.castrecording to a high-res GIF - Composite — Python reads GIF frames, applies camera crop per-frame, blends background, pipes to
ffmpegfor MP4 encoding
Example Screenplays
demo/scripts/example.yaml— Basic conversation demodemo/scripts/example_with_camera.yaml— Camera zoom/pan effectsdemo/scripts/hermes_capabilities.yaml— Full production demo with background image
Key Files
| File | Role |
|---|---|
demo/__main__.py |
CLI entry point |
demo/schema.py |
Pydantic models for screenplay YAML |
demo/player.py |
Terminal playback engine |
demo/pipeline.py |
Orchestrates record → render → composite |
demo/recorder.py |
asciinema + agg subprocess wrappers |
demo/compositor.py |
GIF frame reader, camera crop, ffmpeg encoding |
demo/camera.py |
Keyframe resolution and interpolation |
demo/scenes/ |
Scene handlers (conversation, action) |