apogee-demo

Record terminal sessions, extract highlights with Claude on Vertex AI, and render annotated demo videos with subtitles and TTS narration.

MCP surface: CLI only — no MCP tools.
Install: cargo install --path demo/ (Rust binary)

Synopsis

# Record a session and auto-annotate
apogee-demo demo --project $GOOGLE_CLOUD_PROJECT -- opencode

# Record only (stores in session library)
apogee-demo record -- opencode

# Annotate an existing .cast file
apogee-demo annotate --cast recording.cast --project $GOOGLE_CLOUD_PROJECT

# Render from a script file
apogee-demo render --script script.json --highlights-only

# List recorded sessions
apogee-demo list

Subcommands

Subcommand

Description

Key flags

record

Record a CLI session to .cast file

--output, --project, trailing cmd

annotate

Analyze recording with Claude, extract highlights

--cast, --output, --project, --region, --model, --theme, --save-script

demo

Record + annotate in one shot

--project, --region, trailing cmd

render

Render from a script.json file

--script, --highlights-only, --format, --subsystem

list

List sessions in the library

--project, --user

info

Show session metadata by ID

<session-id>

delete

Remove a session from the library

<session-id>

scan

Show project feature context from AGENTS.md

<project-dir>

auth

Test Vertex AI authentication

--project, --region

Global flag: --library-dir overrides the session library path.

Session library

Sessions are stored in OS-conventional directories:

  • macOS: ~/Library/Application Support/apogee-demo/sessions/

  • Linux: ~/.local/share/apogee-demo/sessions/

  • Windows: %APPDATA%/apogee-demo/sessions/

Override with --library-dir or APOGEE_DEMO_LIBRARY.

Each session is a directory containing recording.cast and meta.json with fields: session_id, created_at, user, hostname, project, git_branch, git_remote, command, working_directory, duration_seconds, terminal dimensions, tags, and notes.

Session IDs follow the format YYYYMMDD-HHMMSS-{user}.

Script format

script.json is the source of truth for demo production. Two variants, distinguished by type:

Single — one recording session:

{
  "version": 1,
  "type": "single",
  "title": "Feature Walkthrough",
  "cast_path": "recording.cast",
  "entries": [
    {
      "highlight": { "timestamp": 12.5, "duration": 5.0, ... },
      "include_in_cut": true,
      "narration": "The MCP server comes online.",
      "transition": "Cut"
    }
  ]
}

Compilation — multiple sessions stitched together:

{
  "version": 1,
  "type": "compilation",
  "title": "Daily Highlights",
  "sources": [
    {
      "session_id": "20260503-091500-alice",
      "entries": [ ... ],
      "transition": { "Fade": { "duration_ms": 500 } }
    }
  ]
}

Compilations support script_path references to other single-type scripts (meta-reel), with a recursion guard preventing nested compilations.

Highlight pipeline

When Claude analyzes a recording, highlights pass through a configurable filter pipeline:

  1. Merge — combine chunk results, deduplicate within 5s window

  2. Normalize subsystems — assign "general" to untagged highlights

  3. Apply weights — sort by category_priority * subsystem_weight

  4. User overrides — suppress highlights near “remove this” / “skip that” typed during recording

  5. Subsystem filter--subsystem security keeps only matching highlights

  6. Error filterinclude_errors = false removes Error + paired Resolution highlights

  7. Duration budgetmax_duration greedy selection by weight

  8. Diversity dedup — cap at 30, guaranteeing at least one highlight per represented subsystem

Highlight categories: Breakthrough, Error, Resolution, Discovery, ToolUse.

Subsystem taxonomy: security, testing, build, deployment, configuration, general.

Configuration

Layered TOML configuration with merge precedence:

  1. Built-in defaults

  2. User config: ~/.config/apogee-demo/config.toml

  3. Project config: .apogee-demo.toml (searched upward)

  4. CLI flags

Key sections:

[output]
directory = "~/Videos/apogee-demo"

[render]
theme = "monokai"
font_size = 14
fps = 30

[highlights]
include_errors = true
max_duration = 120
narration_style = "brief"

[recording]
capture_input = false
override_phrases = ["remove this", "skip this", "ignore this"]

Output formats

  • MP4 — H.264 via ffmpeg, CRF-controlled quality (default)

  • GIF — palettegen/paletteuse with diff-mode dithering, configurable max width

  • WebP — libwebp encoding, quality-controlled, requires ffmpeg with WebP support

Render with --format mp4,gif,webp or set output_formats in the script.

Requirements

  • Rust (build from source)

  • ffmpeg (video encoding — must be on PATH)

  • Google Cloud credentials (for Vertex AI and Cloud TTS)

  • GOOGLE_CLOUD_PROJECT environment variable

Source layout

demo/
+-- src/
|   +-- main.rs          CLI entry point (clap)
|   +-- record.rs        PTY-based terminal recording
|   +-- cast.rs          Asciicast v2 parser + thread-safe writer
|   +-- vertex.rs        Vertex AI / Claude API client
|   +-- highlights.rs    Highlight extraction, filtering, pipeline
|   +-- terminal_render.rs  VT100 emulation + RGBA frame rendering
|   +-- cut.rs           Highlights-only cut engine
|   +-- script.rs        DemoScript format, load/save, meta-reel resolve
|   +-- compilation.rs   Multi-session compilation renderer
|   +-- tts.rs           Google Cloud TTS client + WAV assembly
|   +-- library.rs       Session library with OS-conventional paths
|   +-- config.rs        Layered TOML configuration
|   +-- output.rs        Output path resolution
|   +-- weights.rs       Subsystem priority weights
|   +-- overrides.rs     User override detection + suppression
|   +-- context.rs       Project context scanner (AGENTS.md)
|   +-- error.rs         Error types
+-- assets/
|   +-- JetBrainsMono-Regular.ttf
+-- Cargo.toml

See Also