Polyhydra Skills / Content & Art
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".
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
# 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.