Skip to content
Development
Command

/presentation-video

Generate a presentation video from a structured markdown document. Each numbered section becomes a scene with real browser screenshots, text overlays, transitions, and optional voiceover narration.

From plugin
jat
24836 skills36 commands
Install
$ npx -y skills add joewinke/jat --agent claude-code

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/presentation-video

Context preview

What this command does when you run it.

Generate a presentation video from a structured markdown document. Each numbered section becomes a scene with real browser screenshots, text overlays, transitions, and optional voiceover narration.

Command definition

presentation-video.md
argument-hint: <presentation.md path> [--dry-run] [--no-voice] [--port PORT]

Generate a presentation video from a structured markdown document. Each numbered section becomes a scene with real browser screenshots, text overlays, transitions, and optional voiceover narration.

Presentation Video: Markdown → Storyboard → Screenshots → Voiceover → Video

**Use this command when:**

  • You have a `presentation.md` with numbered sections describing product features
  • You want to generate a walkthrough/demo video for a client or stakeholder
  • Each section should show real app screenshots with narration

**What this does:** 1. Parses `presentation.md` into numbered scenes 2. Creates a Remotion storyboard config (one scene per section) 3. Captures real browser screenshots for each scene using CLI browser tools 4. Generates voiceover narration via ElevenLabs TTS (unless `--no-voice`) 5. Renders a single MP4 video with all scenes stitched together

**Usage:**

/jat:presentation-video presentation.md                    # Full pipeline
/jat:presentation-video docs/pitch.md --dry-run            # Parse + storyboard only
/jat:presentation-video presentation.md --no-voice          # Skip voiceover
/jat:presentation-video presentation.md --port 3200         # App runs on port 3200

**Output:**

docs/videos/
├── presentation-storyboard.json     ← Remotion config with all scenes
├── presentation-narration.txt       ← Full narration script
└── screenshots/                     ← Captured app screenshots
    ├── scene-01.png
    ├── scene-02.png
    └── ...

static/videos/
├── presentation.mp4                 ← Final rendered video
├── presentation-poster.jpg          ← Poster frame
└── presentation-narration.mp3       ← Voiceover audio (if generated)

video/                               ← Remotion project (reusable)
├── package.json
├── src/
│   ├── Root.tsx
│   ├── PresentationVideo.tsx
│   ├── theme.ts
│   └── scenes/
│       ├── TitleScene.tsx
│       ├── ContentScene.tsx
│       └── ClosingScene.tsx
└── public/                          ← Screenshots + audio copied here

---

Architecture: Subagent Pipeline

Orchestrator (this command)
  │
  ├─ Phase 1: Parse presentation.md → scenes array
  │    Orchestrator does this directly (no subagent needed)
  │
  ├─ Phase 2: Storyboard Subagent (sonnet)
  │    Input:  scenes array + project context
  │    Output: docs/videos/presentation-storyboard.json
  │
  ├─ Phase 3: Assets (2 subagents, parallel)
  │    ├─ Screenshot Subagent (sonnet)
  │    │    Input:  storyboard + CLI browser tools
  │    │    Output: docs/videos/screenshots/scene-*.png
  │    │
  │    └─ Voiceover Subagent (sonnet) [skip if --no-voice]
  │         Input:  narration script + ElevenLabs API
  │         Output: static/videos/presentation-narration.mp3
  │
  ├─ Phase 4: Video Render Subagent (sonnet)
  │    Input:  storyboard JSON + screenshots + audio
  │    Output: static/videos/presentation.mp4 + poster
  │
  └─ Report

---

STEP 1: Parse Arguments + Read Presentation

Parse `$ARGUMENTS` for the presentation file path and flags:

  • First positional argument: path to presentation markdown file (required)
  • `--dry-run` — stop after Phase 2 (storyboard only, no rendering)
  • `--no-voice` — skip voiceover generation
  • `--port PORT` — dev server port (default: auto-detect from projects.json or try common ports)

**The presentation file path is required.** If not provided, show usage and exit.

Resolve project context

# Get project path (current working directory)
PROJECT_DIR=$(pwd)
PROJECT_NAME=$(basename "$PROJECT_DIR")

# Read presentation file
cat "$PRESENTATION_PATH"

# Get brand color from projects.json (if configured)
cat ~/.config/jat/projects.json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for k, v in data.get('projects', {}).items():
    import os
    if os.path.expanduser(v.get('path', '')).rstrip('/') == '$PROJECT_DIR':
        print(v.get('active_color', '#3b82f6'))
        sys.exit()
print('#3b82f6')"

# Get dev server port
cat ~/.config/jat/projects.json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for k, v in data.get('projects', {}).items():
    import os
    if os.path.expanduser(v.get('path', '')).rstrip('/') == '$PROJECT_DIR':
        print(v.get('port', '5173'))
        sys.exit()
print('5173')"

# Create output directories
mkdir -p "$PROJECT_DIR/docs/videos/screenshots"
mkdir -p "$PROJECT_DIR/static/videos"

Parse the presentation markdown

Parse the markdown file into structured scenes. Look for `## N.` headers (numbered sections).

Each section becomes a scene:

  • **number**: The section number (1, 2, 3, ...)
  • **title**: The heading text after the number
  • **oldWay**: Text under "The old way:" (if present) — becomes the "challenge" portion
  • **withProduct**: Bullet points under "With [Product]:" — becomes the feature highlights
  • **fullText**: The complete section text (used for narration)

Non-numbered sections like "The Big Picture", "What You're Getting", and "Next Steps" become special scenes:

  • "The Big Picture" or intro text → title/opening scene
  • "What You're Getting" or summary → summary scene
  • "Next Steps" → closing/CTA scene

Store the parsed scenes as a JSON array. Write it to `docs/videos/presentation-scenes.json`.

**Example output for one scene:**

{
  "number": 1,
  "title": "No More Paper, No More Lost Invoices",
  "slug": "no-more-paper",
  "oldWay": "Plumbers fill out paper invoices in the field...",
  "highlights": [
    "Invoices are created digitally in the field",
    "One click to email the invoice to the customer",
    "No more filing — every invoice is searchable",
    "No more 'the plumber didn't turn in paperwork'",
    "Better documentation than paper ever was"
  ],
  "fullText": "The complete section text...",
  "screenshotHint": "An invoice management screen or digital invoice creation interface"
}

The `screenshotHint` should be inferred fro

Read more
Ships withjat

Agents ship, suggest, repeat. You supervise — or they run on their own. JAT is the complete, self-contained environment for agentic development. Task management, agent orchestration, code editor, git integration, terminal access—all unified in a single IDE.

Get the whole plugin