course-engine
Skill0 starsChanged 2 months agoMITView on GitHub
ACC's session-driver skill, invoked by each course plugin's start command (for example /acc-claude-sdk:start). Renders the lesson catalog filtered to one course, checks the Claude Code output style and offers to set Concise, walks the learner through lesson selection, runs the picked lesson's prerequisite probes, collects personalization, then hands off to the course-conductor agent for the chapter loop. Use when the invoker says "run the ACC course engine", "start an ACC lesson", or "drive a lesson from <course>".
- Reads credentials
In this repository4 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- chapter-artifactSkill
- course-creatorSkill
- lesson-creatorSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
20 rules. About 0 are common, 1 is distinctive, and 19 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
19
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 8
Follow the six steps in order.
- Very specific: line 12
Call the start MCP tool with the user's projectRoot (the working directory).
- Very specific: line 14
Course filter: When the invoking command names a course (a per-course start.md saying "filter to acc-claude-sdk"), drop every …
- Very specific: line 39
Ask the user which lesson to take.
- Very specific: line 43
If result.ok is false, surface result.errors verbatim and stop.
- Very specific: line 45
If result.ok is true:
- Very specific: line 48
If result.workspaceCreated === true, say the workspace was seeded at result.workspacePath with the scaffold and the tests, without the …
- Very specific: line 49
If result.workspaceArchivedTo is set, say the host content changed, so an older workspace was archived and the lesson starts fresh at …
- Very specific: line 54
If result.firstRunSetup?.needsWorkspaceRoot === true, the user has never picked a workspace root on this machine.
- Very specific: line 57
Call AskUserQuestion with header: "Workspace root", question: "Where should ACC put per-course project checkouts?", options:
- Very specific: line 60
Call configureWorkspace({ workspace_root: <chosen> }).
- Very specific: line 62
If result.firstRunSetup is absent, skip this step.
- Very specific: line 70
Only when result.resumed is true:
- Very specific: line 74
Call AskUserQuestion with header: "Resume", question: "This lesson is already in progress.
- Very specific: line 78
When result.resumed is absent or false, ask nothing.
- Very specific: line 82
If result.prerequisites is a non-empty array, call runPreflightProbe({ probeId }) for each id.
- Very specific: line 90
If result.prerequisites is absent or empty, skip this step.
- Very specific: line 94
If selectLesson returned a personalizationPrompts array, walk it: ask the user for each value, or accept the default.
- Very specific: line 96
If the lesson has no personalization options, call setPersonalization({ projectRoot, values: {} }) to lock in the defaults.
- Very specific: line 98
Check result.ok. On ok: false, surface result.errors verbatim and ask the learner for the values again.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Course Engine Skill
Follow the six steps in order. Keep your narration terse.
1. Probe the session
Call the start MCP tool with the user's projectRoot (the working directory).
Course filter. When the invoking command names a course (a per-course start.md saying "filter to acc-claude-sdk"), drop every result.lessons entry whose course_name does not start with that plugin name. Without a filter, render every discovered course.
Render:
- Discovered courses: the filtered
result.courses(plugin keys). If empty after filtering, say the named course is not enabled and stop. - Lesson catalog: each filtered
result.lessonsentry withnamespaced_slug,title,summary, andchapter_count, grouped bycourse_name. If empty, renderresult.warningsand stop. - Warnings: each entry's
kind+messagewhenresult.warningsis non-empty.
start never runs probes. Probes run in step 4, only for the picked lesson.
2. Output style
result.outputStyle is { active, recommended: "Concise", ok }. ok is true when active equals recommended.
ok: true: one short confirmation, nothing more.ok: false: callAskUserQuestionwithheader: "Output style",question: "ACC works best with the Concise output style. Set it now?", options:"Yes, set Concise (Recommended)""No, keep my current style"
On yes, call
setOutputStyle({ style: "Concise" }). Tell the learner the setting is written to~/.claude/settings.json, and that/output-style Conciseswitches the current session immediately. Onok: false, surfaceerrorsverbatim, say the style was not changed, and continue. On no, continue.
The check is advisory. No tool refuses to run because of the active style.
3. Lesson selection
Ask the user which lesson to take. They refer to it by namespaced_slug (for example acc-claude-sdk@contract-hero/01-basic-agent).
Call selectLesson({ projectRoot, slug }).
If result.ok is false, surface result.errors verbatim and stop.
If result.ok is true:
- Render
result.descriptionverbatim when present. It is the lesson'sdescription.md: what the learner is about to build, prerequisites, time. - If
result.workspaceCreated === true, say the workspace was seeded atresult.workspacePathwith the scaffold and the tests, without the solution files listed inresult.workspaceStrippedFiles. - If
result.workspaceArchivedTois set, say the host content changed, so an older workspace was archived and the lesson starts fresh at chapter 1. - Render
result.warningswhen present, one line per{ kind, message }. Astate-corruptwarning means the previousstate.jsonwas unreadable. Name itsarchivedTopath when the warning carries one.
3a. First-run workspace setup
If result.firstRunSetup?.needsWorkspaceRoot === true, the user has never picked a workspace root on this machine. Run this one-time prompt before step 4:
- Surface
result.firstRunSetup.defaultWorkspaceRoot(typically~/workspace) as the recommended default. - Call
AskUserQuestionwithheader: "Workspace root",question: "Where should ACC put per-course project checkouts?", options:"Use the default (~/workspace)"(Recommended)"Pick a custom path": follow up in chat for the literal path; treat empty input as the default.
- Call
configureWorkspace({ workspace_root: <chosen> }). Onok: true, say~/.acc/config.jsonwas written. Onok: false, surface the errors and stop. - Refresh the workspace. The first
selectLessonseeded the workspace against the default config, so its.env.acc-pathsfile points at default paths. Re-callselectLesson({ projectRoot, slug })once afterconfigureWorkspacereturnsok: true.prepareWorkspaceis idempotent on the host signature, so the workspace is reused and only the env file is rewritten. Use the refreshedresultfor the rest of the session. - If
result.firstRunSetupis absent, skip this step.
Paths declared by the course default to <workspace_root>/<manifest-default>. The learner can edit ~/.acc/config.json later, or call configureWorkspace({ course_paths: {...} }) for per-id overrides. Do not prompt for those unless the user asks.
3b. Resume or start over
result.resumed is true when state already held this lesson, the lesson is not complete, and the workspace was reused. The recorded artifacts are kept.
Only when result.resumed is true:
- Say the lesson resumes at chapter
result.chapter_cursor + 1.chapter_cursoris 0-based. - Say
selectLesson({ projectRoot, slug, restart: true })starts the lesson over at chapter 1. - Call
AskUserQuestionwithheader: "Resume",question: "This lesson is already in progress. Resume or start over?", options:"Resume at chapter N"(Recommended): continue with thisresult."Start over": callselectLesson({ projectRoot, slug, restart: true })once and use thatresultfor the rest of the session.
When result.resumed is absent or false, ask nothing. The lesson starts at chapter 1.
4. Prerequisites
If result.prerequisites is a non-empty array, call runPreflightProbe({ probeId }) for each id.
pass: true: move on.pass: falsewith noaction: surfacemessageverbatim. Tell the learner to fix it, then re-run the course's start command.pass: falsewith anaction: surface the message and the action's command. Ask the learner whether to run the remediation. Only on an explicit yes, callrunPreflightProbe({ probeId, remediate: true }). If the remediation also fails, stop the session.
Block step 5 until every prerequisite returns pass: true. Print one status line per probe.
If result.prerequisites is absent or empty, skip this step.
5. Personalization
If selectLesson returned a personalizationPrompts array, walk it: ask the user for each value, or accept the default. Collect the values into one object and call setPersonalization({ projectRoot, values }).
If the lesson has no personalization options, call setPersonalization({ projectRoot, values: {} }) to lock in the defaults.
Check result.ok. On ok: false, surface result.errors verbatim and ask the learner for the values again. Do not go to step 6 until setPersonalization returns ok: true.
6. Hand off to the conductor
Once selectLesson, every runPreflightProbe, and setPersonalization have succeeded, dispatch the course-conductor agent. The conductor reads state on its own and runs the chapter loop: per chapter it tells the learner what gets built, implements the code until the chapter's tests pass, writes the chapter's HTML artifact, calls verifyChapter, and pauses.
Say one sentence: the conductor takes over from here.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

