Getting Started
Install the toolchain, generate your first course with /new-course, and read it in the web viewer.
Stay Learning runs inside VS Code. There is no SDK to install and no service to sign up for — the pipeline is a set of Copilot customization files in the repository, so cloning the repo is most of the setup.
1. What you need
- VS Code with GitHub Copilot, with support for custom agents, skills, prompts, and hooks
- Python 3.9 or newer — the validator's only dependency is PyYAML
- Node.js 22.12 or newer — only if you want to run the web viewer
Pick Claude Opus 5 in the model picker before you start. Nothing in the pipeline pins a model — no agent file declares one — but a course run is a long chain of delegated stages where each agent has to hold a detailed contract in mind and write a full artefact against it in one pass. That is where the stronger model earns its keep. Lighter models will complete a run, but expect more validator failures and thinner lesson prose.
2. Set up the validator
Run the setup script once. It finds a suitable Python, creates a .venv, installs PyYAML, and then confirms the validator actually runs against the current course state.
./scripts/setup.shThis matters more than it looks. Every write the pipeline makes is checked by aPostToolUse hook that shells out to the validator, and a failed check blocks the agent. If the virtual environment is missing, the hook falls back topython3 — and if that has no PyYAML, validation silently degrades.
3. Generate a course
Open the Copilot chat panel and invoke the /new-course prompt with a brief that names both the topic and the audience:
/new-course a two-hour introduction to Docker for backend developers who have never used containersRun this from a top-level chat session. The orchestrator needs to delegate to the stage agents, and an orchestrator invoked as a subagent has no delegation tool available to it.
If the brief leaves gaps, the orchestrator asks for everything it is missing in one batch rather than interrogating you stage by stage: what the learner should be able to do afterwards, their experience level, the total time available and session length, and any constraints on tooling or environment.
4. The two approval gates
The run is not fully autonomous. It stops twice and waits for you.
After the assessment stage, once audience.yaml,curriculum.yaml, outcomes.yaml andassessment.yaml exist, it reports the module sequence, the time budget, the outcome count, and how each outcome will be assessed. This is the cheapest point to change your mind — nothing has been written yet.
After every lesson plan is written, it reports the section shape and terminology budget per module and confirms each plan carries a continuity block. Approving here dispatches the wave: lesson prose, exercises, quizzes, and the capstone all generate in parallel.
5. What lands on disk
Everything is plain YAML and Markdown under courses/<slug>/, so a course is diffable and reviewable like any other source tree:
courses/intro-to-containers/
├── course.yaml manifest — the index of truth
├── audience.yaml learner profile
├── curriculum.yaml modules, sequencing, pacing, load
├── outcomes.yaml outcomes per lesson, with Bloom level
├── assessment.yaml diagnostic, formative, summative evidence
├── project.yaml capstone brief, milestones, rubric
├── glossary.yaml terms and the lesson that introduces each
├── .state/run-log.md append-only record of the run
└── modules/
└── m01-container-foundations/
├── l01-what-a-container-is.md
├── l01-what-a-container-is.plan.yaml
├── l01-what-a-container-is.exercises.yaml
└── l01-what-a-container-is.quiz.yamlEach lesson produces exactly four files. Treat all of it as build output: regenerate rather than hand-edit, because a manual change is overwritten the next time that lesson is regenerated and will not match the plan it came from. Fix the artefact upstream of the problem and re-run.
6. Read it in the viewer
The viewer is a separate Astro app that reads courses/ directly. It needs no configuration — the courses directory is resolved relative to its own config file.
cd web
npm install
npm run devA new course appears without a rebuild while the dev server is running. Note thatassessment.yaml and the *.plan.yaml files are deliberately not rendered — those are instructor- and agent-facing, not learner-facing.
7. Checking a course by hand
The hook runs the validator automatically, but you can run it yourself at any time:
.venv/bin/python .github/skills/course-state/scripts/validate.py
.venv/bin/python .github/skills/course-state/scripts/validate.py --strictA FAIL blocks. A WARN marks a state that is legitimate midway through a write procedure but wrong once the run stops — finishing the procedure clears it. --strict promotes warnings to failures, which is what you want in CI or after a run you believe is complete.
When something fails, fix the cause rather than the symptom. Two numbers that disagree usually mean one of them is wrong, not that both need forcing into line.