Skip to content
Back to skills

Episode

ASecurity

Produce one complete episode for a shadowcast channel. Covers research, fact sheet, script, approval gate, voice-over, photos, word-synced motion graphics, layout audit, render, two native Shorts, thumbnails and the upload package. It resumes from the episode's saved status. Use for "make the next video", "new episode about X", or to continue an unfinished one.

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 6, 2026
developmentpython

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned October 6, 2026

npx -y skills add generalizingai/shadowcast --skill episode --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Episode?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Episode
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/generalizingai-episode/badge)](https://www.skillsdirectory.com/skills/generalizingai-episode)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: episode
description: Produce one complete episode for a shadowcast channel. Covers research, fact sheet, script, approval gate, voice-over, photos, word-synced motion graphics, layout audit, render, two native Shorts, thumbnails and the upload package. It resumes from the episode's saved status. Use for "make the next video", "new episode about X", or to continue an unfinished one.
argument-hint: <channel slug> [topic or episode ID]
---

# Episode pipeline

```
T="${CLAUDE_PLUGIN_ROOT}/tools"
W="${SHADOWCAST_HOME:-$HOME/Shadowcast}/<slug>"
```

Read these before starting:
- `W/channel.json`
- `W/STYLE.md`
- `${CLAUDE_PLUGIN_ROOT}/skills/episode/references/RULES.md`
- `${CLAUDE_PLUGIN_ROOT}/skills/episode/references/KIT.md`

Then run `python3 "$T/ep.py" list <slug>`.
- If an episode ID is given, or one is unfinished, **resume it at its status**.
- Otherwise start a new one.

After each stage, record it with `python3 "$T/ep.py" set <slug> <ID> <status>` so a crash or a new session continues where it stopped.

## 1. planned → researched
1. **Pick the topic.**
   - If none was given, take the best unused idea from STYLE.md "Topics".
   - Check it isn't a repeat: compare against the existing episode titles.
   - Use WebSearch to check it's timely or evergreen.
2. **Create the episode.** Run `python3 "$T/ep.py" new <slug> "<working title>"`. It prints `{id, dir, src}`.
3. **Research.**
   - Use WebSearch/WebFetch on primary and reputable sources: court records, major outlets, official stats, the person's own statements.
   - Record 2+ sources for any serious claim.
4. **Fill `dir/FACTSHEET.md`.** Every claim, its exact status, and its source; a "Never say" list; numbers with units; the Sources list (outlet, "headline", date, URL).
5. Set status `researched`.

## 2. researched → scripted → awaiting_approval
1. **Write `dir/SCRIPT.md`** from the template.
   - Sections are `## ` headings, and every voiced line starts with `**VO:**`.
   - Section names drive the rail:
     - countdown: `COLD OPEN`, `#10 NAME` … `#1 NAME`, `OUTRO`
     - chapters: `COLD OPEN`, `CHAPTER 1: TITLE` …, `OUTRO`
   - Length = minutes × wpm words.
2. **Self-check against FACTSHEET line by line.** Every sentence must be supported; fix or cut anything that isn't.
3. If `meta.feedback` exists, this is a rewrite: address every point, then clear it with `python3 "$T/ep.py" set <slug> <ID> scripted feedback=`.
4. **Approval gate.** Set `awaiting_approval`, then run `python3 "$T/notify.py" <slug> "Script ready: <ID>" "<title>. Approve with /shadowcast:approve <slug> <ID>"`. What happens next depends on the session:
   - **Interactive session:** show the user the title, a 5-line summary, the claim count and the path. Ask whether to approve now.
   - **Autopilot:** stop work on this episode. `ep.py next` decides when it may continue: after the approval window in `optional` mode; never automatically when `real_people` is true or mode is `required`.
5. When approved: set `approved`.

## 3. approved → voiced
1. `python3 "$T/tts.py" "<dir>"`: one ElevenLabs request per section, with timestamps.
   - Add pronunciation fixes to `channel.json voice.respell` (e.g. `[["Nguyen","Win"]]`).
2. `python3 "$T/tighten.py" "<dir>" <tempo>`: caps pauses at 0.32 s, tempo from `voice.tempo` (default 1.1).
   - It writes `audio/vo_tight.wav`, `words_tight.json` and `sections_tight.json`.
3. Listen-check by reading `words_tight.json` around tricky names. Check the total duration is within ±15% of the target.
4. Set `voiced`.

## 4. voiced → built
1. **Photos.** Start fetching people and backgrounds early. For each item, follow the RULES "Assets" section:
   - Search: `python3 "$T/commons.py" search "<query>"`.
   - Fetch: `python3 "$T/commons.py" fetch "<dir>/assets/web" p_<name> "File:<title>"`.
   - Cut out: `python3 "$T/cutout.py" "<dir>/assets/web/p_<name>.jpg" "<dir>/assets/cut/<name>.png"`.
   - **Look at every cut-out.**
   - Run several fetches in a background agent if it's slow. Build with stand-ins meanwhile.
2. **Long video shots.** Write `src/shots.tsx`, splitting into `shots1.tsx`/`shots2.tsx` past ~40 shots.
   - One shot per beat, every 4-8 s, word-anchored with marks for each reveal.
   - Vary the components and follow the STYLE visual grammar.
   - Cold open: `TitleCard`, or a `Lineup`/`Teasers` hook. Each countdown item opens with `Countdown`. Outro ends with `Choices` then `EndCard`.
3. **Shorts.** Pick 2 sections (strongest hook; #1 or payoff) and write `short1.tsx` / `short2.tsx` with fresh 9:16 shots for that section.
4. **Thumbnails.** Write `thumbs.tsx` with ThumbA/B/C (see RULES).
5. **`index.tsx`.** Use `makeEpisode({ words: W_, sections: S_, shots: SHOTS, rail, total })` and the EpisodeEntry ids `<ID>`, `<ID>Short1`, `<ID>Short2`, `<ID>ThumbA/B/C`.
   - `rail` is `"countdown"` with `total` = item count, or `"chapters"`.
6. **Register and typecheck.** Run `python3 "$T/ep.py" register <slug> <ID>`, then `cd "$W/studio" && npx tsc --noEmit -p .`, and fix every error.
7. Set `built`.

## 5. built → audited (do not skip)
1. Run `python3 "$T/audit_layout.py" "$W/studio" "<dir>" <ID>`.
2. Open **every** sheet it prints with Read. Check each frame against the RULES "Layout" list.
3. Fix, re-run, and look again until a full pass is clean.
4. Also view the thumbnails: `npx remotion still` each one into the scratchpad.
5. Set `audited`.

## 6. audited → rendered
1. Check the disk with `df -h ~`. You need about 3 GB free.
2. Run `python3 "$T/render.py" episode <slug> <ID>`. It writes `out/long.mp4`, `short1.mp4`, `short2.mp4` and `thumb_A/B/C.jpg`. A 10-minute video takes about 10-25 minutes.
3. Verify: `ffprobe` the durations, extract and view about 6 frames from the long video and 3 per Short (`ffmpeg -ss <t> -i <f> -frames:v 1 <scratch>.jpg`), and view the thumbnails.
4. Set `rendered`.

## 7. rendered → packaged
1. Add a `"package"` section to `dir/meta.json`. The format is in `tools/package.py`'s docstring:
   - 3-4 title options (main first, under 70 characters, following the STYLE title formula)
   - summary (2-3 sentences, keyword-rich, accurate), cta, 12-18 tags
   - chapter_names if the section names need prettifying
   - accuracy notes, the thumbnail letter
   - the two shorts: role, title with `#shorts`, hook, social caption, sources
2. Run `python3 "$T/package.py" <slug> <ID>`.
3. Set `packaged`.

## 8. packaged → scheduled
Hand off to the publish skill (`/shadowcast:publish <slug> <ID>`), or follow its steps directly.

Files in this skill

  • SKILL.md6.4 KB
  • references/KIT.md6.5 KB
  • references/RULES.md4.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…