skills/interactive-learner/SKILL.md
Personal AI tutoring skill that deeply researches any topic, then creates rich, interactive HTML courses with quizzes, simulators, debug challenges, explain-back exercises, real-world missions, and more. Tracks per-concept mastery across sessions with spaced repetition. Use when: (1) the user wants to learn a new topic, (2) the user says 'teach me X' or 'I want to learn X', (3) the user asks for an interactive lesson or course, (4) the user wants to study or review a subject. Works for any topic: technical, conceptual, creative, math, languages.
npx skillsauth add jwa91/agentskills interactive-learnerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create deeply researched, engaging, interactive courses on any topic. Lessons open in the browser with a mix of click-based exercises, open-ended challenges, real-world missions, and AI-evaluated responses. Every course is personalized, evidence-based, and a little adventurous.
Keep profiling fast and frictionless. The student wants to learn, not fill out forms.
Rules:
What to gather (in order of priority):
Infer (don't ask): learning pace, jargon tolerance, visual vs text preference, analogies from their domain.
See student-profiling.md for the full profiling framework.
Initialize progress:
All scripts use
uv run. Ifuvis not available, usepython3instead.Path note:
.agents/skills/and.claude/skills/are symlinked — both paths reference the same location. Examples below use.agents/.
uv run .agents/skills/interactive-learner/scripts/progress.py init <course> <name>
This is critical. Do not skip or rush this step. Before designing any curriculum, become an expert on the subject.
Deep research protocol:
Save research notes to a file the student can reference later:
# Write research to a markdown file alongside the course
# Include: key sources, recommended deep-dives, practice resources, community links
Source priorities (in order):
Connecting research to lessons:
recommended-deep-dive section linking 2-4 of your best research sourcesBased on research, plan the full course:
Save the curriculum and show it to the student as an interactive dashboard:
[
{
"session_number": 1,
"title": "How Bash Actually Works",
"description": "The mental model that changes everything",
"objectives": ["Explain what a shell does", "Break down command syntax"],
"concepts": ["shell-mental-model", "commands-and-arguments"],
"estimated_minutes": 20
}
]
uv run .agents/skills/interactive-learner/scripts/progress.py set-curriculum <course> <curriculum.json>
uv run .agents/skills/interactive-learner/scripts/build-dashboard.py --open
STOP here. Ask the student to review the curriculum in the dashboard. Let them react, reprioritize, or skip sessions they already know. Do not proceed to step 4 until the student confirms the plan.
See course-design-guide.md for topic-type → component mapping and session patterns.
Build a lesson config using only content components (no scored exercises):
uv run .agents/skills/interactive-learner/scripts/find-videos.py "topic for beginners"
Embed 1-2 if good results exist. If nothing suitable, note this and move on. The search is required; embedding is not.uv run .agents/skills/interactive-learner/scripts/build-lesson.py <explainer.json> --mode explainer --course <course-id> --open
Tell the student what the explainer covers (1-2 sentences about concepts and ideas), invite questions, and let them know you're available to explain anything in more detail. Do NOT list component types in your message — describe what they'll learn, not what components you used.
When the student comes back after reading:
Open-ended assessment (explain-back, roleplay, open-reflection) happens here in conversation, not in HTML. The agent evaluates responses in real-time.
Build a test config using only scored components + score-summary:
quiz, matching, fill-blanks, sorting-game, and/or custom componentsscore-summaryuv run .agents/skills/interactive-learner/scripts/build-lesson.py <test.json> --mode test --course <course-id> --open
Tell the student to complete the test and click "Get my result code" when done.
After the student completes the test:
BASH-7A3E-9C51-...)uv run .agents/skills/interactive-learner/scripts/progress.py decode <code>
uv run .agents/skills/interactive-learner/scripts/progress.py update <course> --session N --score S --max M --concepts '{"pod-basics": 0.9, "deployments": 0.6}'
Assign concept scores based on your knowledge of which test questions tested which concepts.uv run .agents/skills/interactive-learner/scripts/build-dashboard.py --open
uv run .agents/skills/interactive-learner/scripts/progress.py show
Check:
Generate the next session, weaving in review of weak concepts using varied component types (not just repeating the same quiz).
When concepts are fading or it's been a while:
uv run .agents/skills/interactive-learner/scripts/progress.py review <course>
This outputs concepts due for review. Build a review session that mixes these concepts into fresh contexts and varied exercise types.
uv run .agents/skills/interactive-learner/scripts/build-dashboard.py --open
Options: --progress <path> (custom progress file), --output <path> (custom output path).
Each session produces two JSON files: an explainer (content-only) and a test (scored exercises). Open-answer questions (explain-back, roleplay, open-reflection) are asked by the agent in conversation between the two phases.
--mode explainer){
"course_name": "Kubernetes",
"title": "Why Does Kubernetes Exist?",
"subtitle": "The problem before the solution",
"session": 1,
"estimated_minutes": 12,
"xp_start": 0,
"concepts": ["container-orchestration", "scaling-problem", "self-healing"],
"sections": [
{
"type": "story-card",
"variant": "blue",
"label": "The Problem",
"content": "<p>Imagine you're running 50 containers...</p>"
},
{ "type": "vocab-cards", "terms": [{ "term": "Pod", "icon": "🫛", "definition": "...", "analogy": "..." }] },
{ "type": "video-embed", "youtube_id": "dQw4w9WgXcQ", "title": "Watch This", "intro": "Quick overview." },
{
"type": "side-by-side",
"title": "Docker Alone vs With Kubernetes",
"left": { "header": "Docker Alone", "icon": "🐳", "items": ["You manage everything", "Manual restarts"] },
"right": { "header": "With Kubernetes", "icon": "☸️", "items": ["Automated management", "Self-healing"] }
},
{
"type": "real-world-mission",
"mission": "Open play-with-k8s.com and run: kubectl get nodes. How many nodes do you see?",
"url": "https://labs.play-with-k8s.com/",
"context": "This is a free Kubernetes playground — no install needed.",
"followup": "We'll discuss what you found at the start of next session."
}
]
}
--mode test){
"course_name": "Kubernetes",
"title": "Session 1 Test",
"subtitle": "Container orchestration basics",
"session": 1,
"xp_start": 0,
"sections": [
{
"type": "quiz",
"questions": [
{
"question": "What happens when a container crashes in plain Docker?",
"options": ["It auto-restarts", "Nothing — it stays dead", "Docker alerts Kubernetes", "The host reboots"],
"correct": 1,
"feedback_correct": "Exactly — without orchestration, crashed containers stay down.",
"feedback_wrong": "Not quite. Without an orchestrator, Docker won't auto-restart crashed containers."
}
]
},
{
"type": "matching",
"title": "Match Terms",
"pairs": [
{ "term": "Pod", "definition": "Smallest deployable unit in Kubernetes" },
{ "term": "Node", "definition": "A machine in the cluster" }
],
"right_order": [1, 0]
},
{
"type": "score-summary",
"learned": ["Why container orchestration exists", "Pod and Node basics"],
"next_preview": "Next: what Kubernetes actually does about these problems."
}
]
}
--mode explainer)story-card vocab-cards side-by-side video-embed timeline concept-map mind-map kanban-board radar-profile recommended-deep-dive (include at end of every explainer) debug-challenge simulator real-world-mission community-challenge custom
--mode test)quiz matching fill-blanks sorting-game score-summary custom
explain-back roleplay open-reflection — these are handled in the conversational checkpoint (Step 5), not rendered into HTML.
custom — allowed in both phases. When no template fits, invent something new.
Full JSON schemas and usage guidance: component-catalog.md
uv run .agents/skills/interactive-learner/scripts/find-videos.py "topic for beginners"
The video search script scrapes YouTube HTML and may break when YouTube changes their page structure. If it fails, ask the user to search YouTube manually and paste the URL.
Max 2 embedded videos per lesson. But you CAN recommend additional videos/resources via recommended-deep-dive components — these are optional extras, not required viewing.
--mode explainer and --mode test.See sharp-edges.md — updated with guidance on when open answers help vs hurt, and new anti-patterns around research shortcuts and stale content.
See gamification.md — dynamic achievements, XP, streaks, and the memory garden concept.
data-ai
Release the current project to the personal Homebrew tap from repo-local release config. Use when the user says "release", "ship", "cut a version", "publish", "make a new tag", or asks how to make a new version available via jwa91/tap.
tools
Use the `jwa-harden` CLI for secret-safe command execution, env-template discovery, and signing/notarization preflight checks. Trigger when a command needs secrets, when `.env.template` or 1Password references are involved, or before signed release flows.
documentation
Modify or extend the `jwa-tobrew` scaffolding system — the templates that `init` writes into target projects. Trigger when the user says "add a new scaffold kind", "change what init writes", "update the templates", or asks how the embedded templates are wired.
development
Detect and fix drift between a project and the conventions encoded in `jwa-tobrew`, prek, and the tap ADRs. Trigger when the user says "align", "any drift", "verify conventions", or asks why a particular file/symlink/script is required.