Turn any GitHub repository into a structured course — overview, tutorial, glossary, module lessons, quizzes, podcast script, validation report, and read-only post-run audit — generated by Claude Code subagents. Optionally render the result as a single interactive HTML page (Vue 3 + Tailwind, Paper & Ink design) with
/genie-render.
You point Genie Learning at a public GitHub repo, and it produces a self-contained learning package in your local content/ directory:
content/<owner>-<name>/
├── 00-overview.md # What the project is, stack, module map
├── 10-tutorial.md # Hands-on walkthrough (install → first change)
├── 20-glossary.md # Domain-specific terminology
├── 30-modules/ # One lesson per module
│ ├── 01-router.md
│ ├── 02-request.md
│ └── ...
├── 40-quizzes/ # General and module-level quizzes
│ ├── 00-general-quiz.md
│ └── 01-router-quiz.md
├── 90-validation.md # Final validation report
└── 99-podcast/ # Podcast assets
├── script.md
├── metadata.json
└── podcast.wav # Generated by scripts/gemini_podcast.py when GEMINI_API_KEY is set
Optionally, you can run a second skill to render the whole course as a single interactive HTML page at content/<owner>-<name>/index.html — sidebar nav, clickable quizzes with feedback, derived flashcards, and an <audio> player for the podcast (auto-generated via Gemini TTS when a key is present). No build step, no server.
Lessons are written in the language you choose (pt-BR, en, es, …).
-
Install Claude Code.
-
Clone this repo and
cdinto it. -
Open Claude Code in the project directory.
-
Generate the course:
/genie-learn https://github.com/sindresorhus/is-plain-obj pt-BRThe orchestrator clones the target into
repos/, dispatches subagents in parallel where possible, and writes the course intocontent/sindresorhus-is-plain-obj/. -
(Optional) Enable podcast audio generation by copying
.env.exampleto.envand fillingGEMINI_API_KEYwith your local Gemini API key. Without a key, every step still works — only the podcast audio is skipped. -
(Optional) Render the interactive HTML page:
/genie-render sindresorhus-is-plain-objThis produces
content/sindresorhus-is-plain-obj/index.html(open viafile://in any browser). The page is self-contained: Vue 3, Tailwind, and marked.js load from CDN at first open. IfGEMINI_API_KEYis set in.env, the skill first invokesscripts/gemini_podcast.pyto generate99-podcast/podcast.wav(idempotent — skips if the file already exists), then renders the HTML so the player appears in the Podcast view. Re-running overwrites the HTML without touching the learner's progress (saved in their browser'slocalStorage).The underlying render script also supports these CLI flags:
python scripts/render_course.py <owner-name> [--check] [--quiet] [--list-courses] [--version] [--output-dir <dir>]--check— validate the course structure without writing files.--quiet— suppress informational stdout (errors still go to stderr).--list-courses— list all available courses incontent/.--version— print version and exit.--output-dir <dir>— writeindex.htmlandassets/to a custom directory instead ofcontent/<owner-name>/.
/genie-learn <repo-url> [language=pt-BR] [max-workers=5]
repo-url— public GitHub URL (HTTPS or SSH form).language— IETF tag (pt-BR,en,es,fr,ja, ...). Defaultpt-BR.max-workers— cap on parallel subagents (2-10). Default5.
The command remains backwards-compatible; the additional quiz, podcast-script, and validation artifacts are generated by the same invocation.
When max-workers=2, the orchestrator keeps the run safe by generating tutorial/glossary first and then processing module lessons one at a time instead of skipping modules.
- Cartography, sequential —
repo-cartographerclones the target repo, writes00-overview.md, and returns a JSON module inventory. - Primary content, parallel —
tutorial-writer,jargon-extractor, and multiplemodule-teacherworkers generate the tutorial, glossary, and module lessons. - Enrichment, parallel —
quiz-generatorwrites quizzes andpodcast-scriptwriterwrites podcast text assets. - Validation, final —
course-validatorchecks required files, directories, module lessons, quizzes, podcast script metadata, language/safety signals, and writes90-validation.md. - Post-run audit, read-only —
post-run-course-auditorinspects generated artifacts after validation and returns a chat report without writing files. - Summary — the skill reports generated files, worker counts, audit status, and any failures.
Each subagent runs in its own context window, so the orchestrator stays lean even when generating dozens of files.
repo-cartographer— clones the repo, detects stack/modules, writes overview, returns JSON inventory.tutorial-writer— writes the hands-on tutorial from maintainer docs and manifests.jargon-extractor— writes an alphabetized glossary from docs and selected source files.module-teacher— writes one focused lesson per discovered module.quiz-generator— writes a general quiz and module quizzes based only on generated course material.podcast-scriptwriter— writes99-podcast/script.mdandmetadata.jsonwithout calling external APIs.course-validator— validates required artifacts, structure, links, language consistency signals, and potential secret leakage.post-run-course-auditor— performs a read-only post-run audit in chat aftercourse-validator.
genie-renderskill +scripts/render_course.py— a deterministic Python script (stdlib only) that readscontent/<owner>-<name>/and produces a single interactiveindex.html.- Stack (loaded from CDN at runtime, no build step): Vue 3 · Tailwind via Play CDN · marked.js · Inter from Google Fonts.
- Design system — "Paper & Ink" tokens from
DESIGN.md: warm paper tones (#FAF7EF), Instrument Serif display type, oklch accent system (moss/terracotta/indigo), per-module tint cycling across 6 hues, 14px-rounded cards, frosted-glass sticky header, hidden Tweaks panel (theme/accent/density), dark mode with inverted paper/ink palette. - Flashcards — derived automatically: each glossary term becomes a card (term/definition), each multiple-choice quiz question becomes a card (question/correct option + explanation).
- Multilingual chrome — UI labels match the course
language(pt-BR, en, es, fr, ja). - Podcast slot — auto-detects
99-podcast/podcast.{wav,mp3,m4a,ogg}and renders an<audio>player; otherwise shows an "audio coming soon" banner. The skill auto-runsscripts/gemini_podcast.pybefore rendering whenGEMINI_API_KEYis set, so the player typically appears on the first invocation of/genie-render. - Progress — quiz answers and flashcard "known/unknown" marks persist in the browser's
localStorage; safe to re-render the HTML without losing them.
Podcast audio generation is real: scripts/gemini_podcast.py calls the Gemini multi-speaker TTS API and writes 99-podcast/podcast.wav. The script is invoked automatically by /genie-render before the HTML render.
-
Copy the example file locally:
cp .env.example .env
-
Fill
GEMINI_API_KEYin.envwith your local key (get one at aistudio.google.com). -
Keep
.envprivate. It is gitignored and must never be committed. -
Keep
.env.exampleversioned. It contains only safe placeholder values.
Supported variables:
GEMINI_API_KEY— required for TTS calls. Without it, the script self-skips silently (exit 0); the rest of/genie-renderstill works.GEMINI_TTS_MODEL— defaults togemini-2.5-flash-preview-tts.GEMINI_PODCAST_OUTPUT_FORMAT— defaults towav(the only format currently emitted).
The script:
- Parses
content/<owner>-<name>/99-podcast/script.mdfor**Host A:**/**Host B:**turns. - Sends a multi-speaker prompt to Gemini using voices Kore (Host A) and Puck (Host B).
- Wraps the returned 24 kHz PCM in a WAV container via stdlib
struct— nopip installrequired. - Skips if an audio file already exists (
podcast.{wav,mp3,m4a,ogg}); delete the file to force regeneration. - Redacts the API key from any error message and never prints it on success.
Typical timings on the public free tier: a 30-turn script (~8 min audio) finishes in under a minute; a 50-turn script (~10 min audio) takes 2–4 minutes. Files are 24–30 MB.
After running /genie-learn, inspect:
content/<owner>-<name>/00-overview.mdcontent/<owner>-<name>/10-tutorial.mdcontent/<owner>-<name>/20-glossary.mdcontent/<owner>-<name>/30-modules/*.mdcontent/<owner>-<name>/40-quizzes/*.mdcontent/<owner>-<name>/90-validation.mdcontent/<owner>-<name>/99-podcast/script.mdcontent/<owner>-<name>/99-podcast/metadata.json
Then manually run the setup commands from 10-tutorial.md in a clean checkout and review 90-validation.md for blocking issues.
- No external dependencies. Pure Claude Code: subagent files in
.claude/agents/, two skills in.claude/skills/(genie-learn,genie-render), and two Python standard-library scripts (render_course.pyfor the HTML page,gemini_podcast.pyfor Gemini multi-speaker TTS). Nopip installstep anywhere. - Filesystem as contract. The cartographer returns a JSON inventory; subsequent agents communicate by reading and writing files. No mailbox, no IPC, no daemon.
- Minimum-privilege subagents. Only the cartographer has
Bash. Content, quiz, podcast-script, and validation agents use read/glob/grep/write capabilities only as needed. - Parallel where useful, sequential where necessary. Primary content and enrichment run concurrently; validation runs last.
- Inspired by
automagik-dev/genie— skills-pluggable, decentralized registry — but stripped down to what Claude Code natively offers.
- Podcast audio generation. Implemented in
scripts/gemini_podcast.py(Gemini multi-speaker TTS, stdlib-only). - MP3 conversion. Currently emits WAV (24–30 MB per 10-min episode); MP3 would shrink to ~5–8 MB but requires ffmpeg.
- Configurable TTS voices. Currently hardcoded Kore + Puck.
- Incremental updates. Currently each run regenerates everything. Cache by repo SHA.
- Private repos. Currently anonymous clones only.
- Standalone CLI. Use Claude Agent SDK to run outside Claude Code.
Bug reports, agent ideas, and PRs are welcome. See CONTRIBUTING.md for setup, project structure, how to add a new subagent or skill, code style, and the commit convention.
MIT © 2026 Rodrigo Siliunas.