Toastmasters Meeting Recap Video
This skill ships with the toastmasters-flow-promos kit; run it from the repo root. Read
README.md if anything here is unclear, and AGENTS.md for the prime directives.
Core rule: no AI-generated text, no AI-animated faces. All type renders locally from
templates/*.html; the photo stays untouched pixels.
Inputs to collect from the user
- Meeting theme (e.g., "Fresh Start") and word of the day, plus a one-line definition
for
WORD_DEF if they want it under the word (optional; empty hides the line)
- Meeting date: meetings are usually weekly, so use the full date ("August 5, 2026")
or recaps from the same month become indistinguishable
- Winners and their awards, one to three of them (names may repeat across awards)
- Path to the meeting photo. On macOS, screenshots land in
~/Desktop and their
filenames contain a narrow no-break space (U+202F) before "PM"; copy via glob, never
a typed name
- Whether the meeting scene should move: a Zoom recording (the gallery, or a winner
mid-speech) can play there instead of the still. Ask only if they mention having one;
the still is the default and stays fully supported
- Anything else changing this week: credit line, club URL, background clip
Club identity (name, URL, credit line, approved phrase, standing meeting time) is set
once in meeting.conf and
should already be filled in. Confirm rather than re-ask. PHRASE must be one of the eight
approved phrases listed in meeting.conf; the build rejects anything else, and picks one
at random when it is left empty.
Check the phrase against recent weeks before setting it. The build validates that a
phrase is approved, but nothing stops you repeating last week's, and the closing card is
the one frame every recap ends on. Run grep -H '^PHRASE=' *.conf | sort and pick
something the last two or three meetings did not use. This cannot be a repo check: the
dated configs are local and untracked by design, so the history only exists on the user's
machine. If the user asks for a repeat anyway, say which weeks already used it once and
then do as they ask.
Steps
- Photo. Copy to the path
GROUP_PHOTO names in meeting.conf
(default assets/group_photo.png). For a moving meeting scene instead, set
GROUP_VIDEO to the recording and GROUP_VIDEO_START to the second the good 4.6s
begins; it plays silent, and the still stays the default when GROUP_VIDEO is empty.
- Winner crops. View the photo, pick landscape ~1.89:1 crops of each winner's Zoom
tile that exclude the name-label pill (bottom-left of every tile). Crop with Pillow
to the paths
WINNER1_IMG … WINNER3_IMG name. Open each crop and confirm the face is
centered and no label survived. The same ~1.89:1 landscape crop works for both
ASPECT values: tiles stack vertically and are sized by width, not by the card's
own aspect ratio.
- Config. Edit
meeting.conf only: THEME_LINE1/THEME_LINE2, MEETING_DATE,
WORD_OF_DAY, the WINNERn_* triples, and OUTPUT. Leave a WINNERn_NAME empty to
drop that tile; the row re-centers. Never hardcode content into the templates.
ASPECT (portrait | landscape) picks the output shape and defaults to portrait;
confirm it matches what the club wants rather than re-asking every week.
- Background. Read
BG_MODE in meeting.conf. reuse (the default) means use the
existing BG_VIDEO and spend nothing. generate means the club wants a fresh clip
per meeting so no two recaps look alike; follow the google-flow skill and
flow-prompts.md, and build the prompt from BG_MOOD rather than from the theme.
Never put THEME_LINE1, THEME_LINE2 or WORD_OF_DAY into a Veo prompt. Those
are text, Veo renders text it is given, and they already reach the video through the
locally rendered cards. If BG_MOOD is empty, propose one from the theme's mood
(colour, light direction, movement speed) and get it approved before generating.
BG_MODE="generate" is not itself approval to spend: confirm the generation the same
way as any other, every time.
- Build. Run
templates/build.sh. For timing or scene-length changes, edit the
st= fade values inside it; for content, go back to meeting.conf.
- Verify (mandatory). Proofread the PNGs in
cards/, extract per-scene frames
(t = 2, 5.5, 10, 13.5) and check spelling, faces, and contrast, then
ffmpeg -af volumedetect (expect mean ≈ −15 dB; silence reads −91).
- Deliver the mp4, then remind the user: written permission from everyone shown, and
submit to brand@toastmasters.org for approval.
Guardrails
- Never put literal on-screen text or hex codes in any Veo prompt.
- Never AI-animate the group photo.
- Spend Flow credits only with explicit user approval.
- Never commit anything under
assets/, fonts/, or cards/. The logo is Toastmasters
International's property and the photos are of real people. The repo is public.
1---2name: tm-meeting-recap3description: Produce a Toastmasters club meeting recap/promo video (15s, brand-compliant, zero AI text). Use when the user asks for a meeting recap video, Toastmasters promo, or to update the recap with a new meeting's theme/winners/photo.4---56# Toastmasters Meeting Recap Video78This skill ships with the `toastmasters-flow-promos` kit; run it from the repo root. Read9`README.md` if anything here is unclear, and `AGENTS.md` for the prime directives.1011Core rule: **no AI-generated text, no AI-animated faces.** All type renders locally from12`templates/*.html`; the photo stays untouched pixels.1314## Inputs to collect from the user15161. Meeting theme (e.g., "Fresh Start") and word of the day, plus a one-line definition17 for `WORD_DEF` if they want it under the word (optional; empty hides the line)182. Meeting date: meetings are usually weekly, so use the full date ("August 5, 2026")19 or recaps from the same month become indistinguishable203. Winners and their awards, one to three of them (names may repeat across awards)214. Path to the meeting photo. On macOS, screenshots land in `~/Desktop` and their22 filenames contain a narrow no-break space (U+202F) before "PM"; copy via glob, never23 a typed name245. Whether the meeting scene should move: a Zoom recording (the gallery, or a winner25 mid-speech) can play there instead of the still. Ask only if they mention having one;26 the still is the default and stays fully supported276. Anything else changing this week: credit line, club URL, background clip2829Club identity (name, URL, credit line, approved phrase, standing meeting time) is set30once in `meeting.conf` and31should already be filled in. Confirm rather than re-ask. `PHRASE` must be one of the eight32approved phrases listed in `meeting.conf`; the build rejects anything else, and picks one33at random when it is left empty.3435**Check the phrase against recent weeks before setting it.** The build validates that a36phrase is approved, but nothing stops you repeating last week's, and the closing card is37the one frame every recap ends on. Run `grep -H '^PHRASE=' *.conf | sort` and pick38something the last two or three meetings did not use. This cannot be a repo check: the39dated configs are local and untracked by design, so the history only exists on the user's40machine. If the user asks for a repeat anyway, say which weeks already used it once and41then do as they ask.4243## Steps44451. **Photo.** Copy to the path `GROUP_PHOTO` names in `meeting.conf`46 (default `assets/group_photo.png`). For a moving meeting scene instead, set47 `GROUP_VIDEO` to the recording and `GROUP_VIDEO_START` to the second the good 4.6s48 begins; it plays silent, and the still stays the default when `GROUP_VIDEO` is empty.492. **Winner crops.** View the photo, pick landscape ~1.89:1 crops of each winner's Zoom50 tile that **exclude the name-label pill** (bottom-left of every tile). Crop with Pillow51 to the paths `WINNER1_IMG` … `WINNER3_IMG` name. Open each crop and confirm the face is52 centered and no label survived. The same ~1.89:1 landscape crop works for both53 `ASPECT` values: tiles stack vertically and are sized by width, not by the card's54 own aspect ratio.553. **Config.** Edit `meeting.conf` only: `THEME_LINE1`/`THEME_LINE2`, `MEETING_DATE`,56 `WORD_OF_DAY`, the `WINNERn_*` triples, and `OUTPUT`. Leave a `WINNERn_NAME` empty to57 drop that tile; the row re-centers. Never hardcode content into the templates.58 `ASPECT` (`portrait` | `landscape`) picks the output shape and defaults to `portrait`;59 confirm it matches what the club wants rather than re-asking every week.604. **Background.** Read `BG_MODE` in `meeting.conf`. `reuse` (the default) means use the61 existing `BG_VIDEO` and spend nothing. `generate` means the club wants a fresh clip62 per meeting so no two recaps look alike; follow the `google-flow` skill and63 `flow-prompts.md`, and build the prompt from `BG_MOOD` rather than from the theme.64 **Never put `THEME_LINE1`, `THEME_LINE2` or `WORD_OF_DAY` into a Veo prompt.** Those65 are text, Veo renders text it is given, and they already reach the video through the66 locally rendered cards. If `BG_MOOD` is empty, propose one from the theme's *mood*67 (colour, light direction, movement speed) and get it approved before generating.68 `BG_MODE="generate"` is not itself approval to spend: confirm the generation the same69 way as any other, every time.705. **Build.** Run `templates/build.sh`. For timing or scene-length changes, edit the71 `st=` fade values inside it; for content, go back to `meeting.conf`.726. **Verify (mandatory).** Proofread the PNGs in `cards/`, extract per-scene frames73 (t = 2, 5.5, 10, 13.5) and check spelling, faces, and contrast, then74 `ffmpeg -af volumedetect` (expect mean ≈ −15 dB; silence reads −91).757. **Deliver** the mp4, then remind the user: written permission from everyone shown, and76 submit to <brand@toastmasters.org> for approval.7778## Guardrails7980- Never put literal on-screen text or hex codes in any Veo prompt.81- Never AI-animate the group photo.82- Spend Flow credits only with explicit user approval.83- Never commit anything under `assets/`, `fonts/`, or `cards/`. The logo is Toastmasters84 International's property and the photos are of real people. The repo is public.