Polyhydra Skills  /  Content & Art

learning-slides

Mid-chat, draft a quick-learning slide deck (short summary, a few slides, optional images) and push it to the learning-hub display server so it plays on a separate screen -- kiosk device or OBS Browser Source, including live on stream. Use when the user wants to quickly learn or explain a topic visually, especially while streaming, or mentions "learning-hub" or "make a slide deck for this".

Content & Art

Drop this in — save the block below as ~/.claude/skills/learning-slides/SKILL.md, or run:

mkdir -p ~/.claude/skills/learning-slides
cat > ~/.claude/skills/learning-slides/SKILL.md <<'EOF'
# (paste the full source block below into this file)
EOF

Full source

SKILL.md — copy everything inside
# Learning slides

Turns a topic into a short auto-advancing slide deck and pushes it to
`learning-hub` (`~/code/learning-hub`), a throwaway zero-dependency display
server built for this. The display page runs on a separate device from the
chat (kiosk browser tab, or an OBS Browser Source so it's visible on stream).

This is an MVP workflow being tested live on stream -- keep decks short and
the loop fast rather than over-producing content.

## Workflow

1. **Draft the deck.** 4-8 slides. Each slide: a short `title` and a `body`
   (either one sentence or 2-4 short bullet strings). Keep it skimmable --
   this plays on a timer, the viewer can't pause it.
2. **Images (mix, per slide).** For slides that benefit from a real visual,
   generate one with the `codex-art` skill. For slides that don't need
   custom art, leave `image` unset -- text-only slides render fine. Don't
   generate an image for every single slide by default; use judgment per
   slide.
3. **Narrate it.** Run
   `node ~/code/learning-hub/scripts/narrate-deck.mjs /path/to/deck.json`
   to generate British-voice (Piper, local, offline) narration per slide and
   fill in each slide's `audio` field. The display advances on narration end
   instead of a fixed timer once a slide has audio. Skip this step only if
   the user asks for silent/text-only slides.
4. **Get approval before publishing.** Publishing plays on the user's stream
   immediately and interrupts whatever is currently showing. Always confirm
   with `AskUserQuestion` (e.g. "Push this deck to the display now?") before
   calling `publish.sh` -- never publish unprompted.
5. **Publish.**
   ```bash
   ~/code/learning-hub/publish.sh /path/to/deck.json [server-url]
   ```
   If the display server's LAN address isn't already known, ask the user
   once and save it as a reference memory (e.g. "learning-hub kiosk endpoint
   is http://192.168.x.x:4173") so future sessions don't have to ask again.
   Default is `http://localhost:4173` if the server runs on the same machine
   as the chat session.
6. **Confirm it landed.** `curl -s <server-url>/state` should echo back the
   published deck.

## Deck JSON shape

```json
{
  "topic": "Short label shown top-left",
  "duration_ms": 8000,
  "slides": [
    { "title": "Slide heading", "body": "One sentence, or an array of bullets", "image": "data: URI or https URL", "audio": "/audio/<topic-slug>/slide-1.wav (filled in by narrate-deck.mjs)" }
  ]
}
```

See `~/code/learning-hub/examples/sample-deck.json` for a full example and
`~/code/learning-hub/README.md` for how the server itself works.

## Notes

- The server must already be running on the display device
  (`node ~/code/learning-hub/server.mjs`) -- this skill only drafts and
  publishes content, it doesn't manage the server process.
- No auth on publish -- fine for a trusted LAN test, not for anything public.