| name | setup-course |
| description | Scaffold a new open-book-exam-prep course folder for the user. Triggers - "set me up an open-book course", "create a course for X", "scaffold a course", `/setup-course <name>`. Reads from any lecture sources the user points at and produces a complete course/ directory with course.yaml, sources/, templates/ overrides if needed, ready for `python -m pipeline.run --course <path>`. |
Setup-Course Skill
Walks a new user from "I have some lecture slides" to "I have a course
folder ready to run through the pipeline."
This skill is bundled with the open-book-exam-prep repo. Invoke it
when the user wants to start a new course.
Step 0: Gather the user's intent
Ask the user (one question at a time, multiple choice when possible):
- What is this course? (free text — name, university, level)
- How many modules / exam papers? (1, 2, 3+)
- Where are the lecture sources? (path on disk, or "I'll drop them in")
- What's the rubric? Multiple choice:
- A. UK undergraduate, mechanism-heavy (35% facts / 55% discussion / 10% organisation; First/2:1/2:2/Third bands). Default for STEM and similar.
- B. US letter-grade (something like 40% accuracy / 30% argument / 20% evidence / 10% style; A/B/C/D bands at 90/80/70/60).
- C. Custom — I'll dictate the criteria.
- D. Default to A, I'll edit later.
- Format style preference? Multiple choice:
- A. STEM-mechanism — Decision Trees, Worked Scenarios. Default; no overrides needed.
- B. Humanities — Argument Maps, Counter-positions, Source Critique. Generates a
templates/lecture_format.md override.
- C. Custom — user will write their own template later.
Step 1: Decide the course folder location
Default: <repo-root>/content/<course-slug>/. The content/ directory
is gitignored; the user's content stays out of any public clone.
Confirm with the user before writing. If they prefer a path elsewhere
(e.g. ~/my-revision/), use that instead.
Step 2: Scaffold the directory tree
<course>/
├── course.yaml <- populated from Step 0
├── sources/
│ └── <MODULE>/ <- one folder per module
├── templates/ <- empty unless user picked humanities/custom
├── vault/ <- empty (pipeline output)
├── binder/ <- empty (pipeline output)
└── papers/ <- empty (practice-paper output)
Use mkdir -p to create dirs.
Step 3: Write course.yaml
Build the YAML body from the Step 0 answers. Example for Option A
rubric + 1 module:
course:
name: "<course name from Step 0>"
university: "<university from Step 0, if given>"
level: "<level from Step 0, if given>"
description: "Open-book exam preparation."
modules:
- code: <MODULE_CODE>
display_name: "<module display name>"
sources_dir: sources/<MODULE_CODE>
header_colour: "#1F6FB8"
subheader_colour: "#0E3D6F"
rubric:
scale: 100
bands:
- { name: "First", min: 70 }
- { name: "Upper Second", min: 60 }
- { name: "Lower Second", min: 50 }
- { name: "Third", min: 40 }
- { name: "Fail", min: 0 }
criteria:
- name: "Facts, evidence, principles"
weight: 35
descriptor: |
Accuracy and coverage of lecture material — concepts, mechanisms,
named examples, evidence base.
- name: "Discussion, analysis, evaluation"
weight: 55
descriptor: |
Going beyond recall: critique, synthesis, comparison, weighing
alternatives, original thinking.
- name: "Organisation"
weight: 10
descriptor: |
Logical structure, terminology, signposting.
paper:
short_form: 4
essay: 1
target_minutes: 60
no_repeat_within: 2
Adjust per the user's answers — different rubric weights, different
modules count, different bands.
Step 4: Move/copy the user's lectures into sources/
If they pointed at a path:
cp -r <user-source-path>/* <course>/sources/<MODULE>/
If they said "I'll drop them in", show them the path and exit at Step 6.
Step 5: Apply format-style template if needed
If the user picked Option B (humanities) in Step 0.5, write a
<course>/templates/lecture_format.md with the humanities sections
(Argument Map, Key Texts, Counter-positions, Worked Critique,
Cross-References).
If they picked Option C, leave templates/ empty and tell them where
to find the default template to start from:
pipeline/templates/lecture_format.md.
Step 6: Validate and report
python -c "from pipeline.course import load_course; c = load_course('<course-path>'); print('OK:', c.name, c.module_codes); print('Sources:', [str(m.sources_dir) for m in c.modules])"
If validation fails, fix the offending field in course.yaml and re-run.
Then tell the user what to do next:
(The standalone python -m pipeline.run --course <course-path> path
is an alternative for users who'd rather run unattended via the
Anthropic API directly with ANTHROPIC_API_KEY set — useful for big
courses, CI, or batch processing. Don't suggest it unless the user
asks.)
Edge cases
| Case | Handling |
|---|
| User has no lectures yet | Scaffold the folder anyway; tell them where to drop sources |
| User's modules count > 5 | Confirm — most open-book exam prep is 1-3 modules |
| Module code clashes (duplicate) | Bump second to <CODE>2 and confirm |
| User picks a course folder that already has course.yaml | Refuse to overwrite; offer to load it instead |