agentic-community-college
CLAUDE.md0 starsChanged 2 months agoMITView on GitHub
A Claude Code plugin that turns a session into a coding tutor. ACC is the framework: it ships the MCP server, the course-conductor agent, and the authoring/runtime skills. Content lives in separate course plugins that declare accContent in their plugin.json; ACC discovers them at runtime. The user-facing onboarding doc is README.md. This file is for Claude's context when working on the code. Given a programming topic and its documentation, ACC produces a lesson (or a course of lessons) with one…
- Installs packages
In this repository4 other files it gives its agents.
- chapter-artifactSkill
- course-creatorSkill
- course-engineSkill
- lesson-creatorSkill
The file
We split this CLAUDE.md into the rules it gives an agent
9 rules. About 0 are common, 1 is distinctive, and 8 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.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 11
Phase 0 — docs: If the author gives no docs, ACC retrieves the official documentation and stores a curated snapshot inside the lesson …
- Distinctive: line 15
Close: After the last chapter the conductor runs the e2e test and writes a summary artifact with the most important learnings.
- Very specific: line 105
Every chapter carries its own mandatory verification.
- Very specific: line 219
ACC ships zero domain probes: Every probe is declared by a course plugin's plugin.json.
- Very specific: line 222
Path safety is non-negotiable: Every manifest path field is validated with pathSafety.isSafeRelPath (no .., no leading slash).
- Very specific: line 224
The output-style check is advisory: No MCP tool refuses to run because of the active output style.
- Very specific: line 229
Run pnpm build from mcp/server (the plugin runs the *built* dist/index.js, not the source).
- Very specific: line 230
Run pnpm test from the repo root.
- Very specific: line 235
Don't write lesson files by hand — invoke course-creator for a new course plugin and lesson-creator for each lesson.
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md 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
Agentic Community College (ACC) — Claude's working notes
A Claude Code plugin that turns a session into a coding tutor. ACC is the framework: it ships the MCP server, the course-conductor agent, and the authoring/runtime skills. Content lives in separate course plugins that declare accContent in their plugin.json; ACC discovers them at runtime.
The user-facing onboarding doc is README.md. This file is for Claude's context when working on the code.
North star (v0.3)
Given a programming topic and its documentation, ACC produces a lesson (or a course of lessons) with one fixed shape:
- Phase 0 — docs. If the author gives no docs, ACC retrieves the official documentation and stores a curated snapshot inside the lesson (
docs/). The implementing agent grounds every chapter in that snapshot. - Plan. The author defines the ordered steps that show what is meant to be taught. Every step becomes a chapter.
- Tests first. For every chapter the author writes the test cases that prove the step works, plus one end-to-end test that proves the whole feature. The tests are the contract; the reference solution exists to prove the tests are satisfiable.
- Runtime. For every chapter the conductor (1) tells the learner what will be implemented, (2) implements the code until that chapter's tests pass, (3) generates an HTML artifact that explains the code just written, visually, with the most significant snippets.
- Close. After the last chapter the conductor runs the e2e test and writes a summary artifact with the most important learnings.
The agent writes the code. The learner reads, asks, and confirms. There are no output modes anymore: ACC recommends the Concise Claude Code output style and offers to set it. All learning content goes into the artifacts, not the chat.
Tech Stack
- TypeScript (ESM,
"type": "module"), Node >= 18 - pnpm workspaces — only
mcp/serveris currently a workspace member @modelcontextprotocol/sdk^1.0.0zodfor tool input schemasvitestfor tests (run withpnpm testfrom the root)
Build & Test
pnpm install # root install
cd mcp/server && pnpm install && pnpm build # produces dist/index.js
pnpm test # vitest, from rootThe plugin manifest spawns node mcp/server/dist/index.js over stdio, so pnpm build is required after any change in mcp/server/src/.
Vocabulary
- ACC — the framework. This repo. Ships the MCP server + conductor + skills.
- Course — a content plugin. Declares
accContent: { lessons: "./lessons/" }inplugin.json. Discovered by ACC at runtime via~/.claude/plugins/installed_plugins.json. Published courses:acc-deepbook-courseandacc-evm-wal(both on the v0.2 section model, pending migration), andacc-claude-sdk(first v0.3 course). - Lesson — one end-to-end learning experience inside a course (
lessons/<slug>/). Always namespaced as<course-plugin-key>/<slug>when it crosses a tool boundary. - Chapter — one step of a lesson. A chapter is defined by the set of test cases it makes pass. The conductor implements a chapter, then explains it with one artifact.
- Artifact — a self-contained HTML page. One per chapter plus one summary, generated at runtime into the workspace.
- Workspace — the learner's copy of the lesson's reference app, minus the solution files, at
~/.acc/workspaces/<slug>/.
Lesson layout (v0.3)
lessons/<slug>/
├── lesson.json identity, prerequisites, workspace seeding rules
├── description.md what the learner will build, why, prerequisites, time
├── docs/ Phase 0 snapshot: curated reference docs (markdown) + INDEX.md
├── chapters.json ordered chapters, per-chapter verification, final e2e gate
├── chapters/NN-<name>.md chapter brief; NN is the position, <name> is the chapter id without its cNN- prefix
├── reference-app/ complete working solution INCLUDING every test (unit + e2e)
└── validation.json result of the authoring-time learner passlesson.json
{
"slug": "01-basic-agent",
"title": "…",
"summary": "…",
"prerequisites": ["pnpm-installed"],
"docs": "docs/",
"workspace": {
"host": "reference-app",
"host_install_command": "pnpm install",
"verification_cwd": ".",
"solution_files": ["src/agent.ts", "src/tools.ts", "src/cli.ts"],
"files": []
},
"personalization_options": [],
"personalization_ranges": {}
}workspaceis required. Every chapter-loop envelope carriesworkspace_path, and artifacts always live at<workspace_path>/artifacts/.workspace.hostis copied whole into the workspace. Then everysolution_filesentry is deleted from the copy. Thenfiles[]starters ({ starter, path }) are copied in. The learner's workspace therefore holds scaffold + tests, never the solution.docsis optional. When present it must be a lesson-relative directory;nextChapterreturns its absolute path asdocs_dir.build_command,test_command, andartifactfrom v0.2 are gone. Verification lives inchapters.json.
chapters.json
{
"schema_version": 2,
"chapters": [
{
"id": "c01-run-query",
"title": "Run a query and read the result",
"brief_md": "chapters/01-run-query.md",
"key_idea": "query() returns an async iterable of typed messages; the `result` message is the contract.",
"expected_files": ["src/agent.ts"],
"tests": ["tests/01-run-query.test.ts"],
"verification": { "mode": "test-suite", "command": "pnpm vitest run tests/01-run-query.test.ts" }
}
],
"final_verification": { "mode": "test-suite", "command": "pnpm vitest run" }
}- Every chapter carries its own mandatory
verification. Modes:compile,test-suite. Pass = exit 0. verification.commandis split on whitespace and run without a shell: one program plus its arguments. No&&,||,|,;,>,<, backticks, environment prefixes (VAR=x cmd), or single quotes. The schema rejects shell operators, and a whitespace-only command.testslists the workspace-relative test files that define the chapter (informational: the conductor reads them before implementing and lists them in the artifact).key_ideais the one concept the chapter artifact must center on.final_verificationis the e2e gate that runs once after the last chapter passes. Lessons whose e2e needs credentials skip those tests in-suite with a clear message; a skipped e2e still exits 0.
Chapter brief (chapters/NN-<name>.md)
Short markdown with three parts: What we implement (learner-facing, 3–6 lines), Done when (the test names and what each asserts), Implementation notes (for the agent: which docs file to read, pitfalls, constraints such as "do not touch package.json").
Runtime flow (v0.3)
- The course's
/<course>:startcommand invokes thecourse-engineskill with a course filter. start→ catalog +outputStylestatus. If the active style is notConcise, the skill asks the learner and, on yes, callssetOutputStyle.- Learner picks a lesson →
selectLesson(mints v5 state, seeds the workspace; resumes an in-progress lesson at itschapter_cursorunlessrestart: true) →runPreflightProbefor each prerequisite →setPersonalization(defaults when the lesson has none). - Hand-off to the
course-conductoragent. Per chapter:nextChapter→ brief, key idea, expected files, tests, resolved verification (cwdalways set),docs_dir,workspace_path,artifact_path,artifact_nav(prev/next filenames for the footer links).- Tell — a short "Chapter N of M — title: here is what we implement and which tests define done".
- Implement — read
docs_dirand the chapter's tests, edit onlyexpected_files, run the chapter's verification command with Bash until green (max 5 attempts, then ask the learner). - Explain — write the chapter artifact at
artifact_pathfollowingskills/chapter-artifact/references/conventions.md(the MCP returns the absolute path asartifact_conventions_path). verifyChapter— the official gate. On pass it advanceschapter_cursorand records the artifact path in state. On fail it returns the output; the conductor never auto-retries the gate, it asks the learner.- Pause —
AskUserQuestion: continue / I have questions / pause here. Never more than one chapter per learner turn.
- When
nextChapterreturnsdone: truewithfinal_verification, the conductor callsverifyChapteronce more (runs the e2e), then writessummary_artifact_path(chapter cards built from theartifactsmap, the most important learnings, the final architecture), callsverifyChaptera last time so the summary gets recorded, and offerspublish-htmlwhen the envelope sayspublish_available: true(toolkit@contract-heroenabled).
MCP tools (v0.3)
| Tool | Purpose |
start | Catalog across enabled courses (chapter_count per lesson) + outputStyle: { active, recommended: "Concise", ok }. Never runs probes. |
runPreflightProbe | Runs one declared probe by id, optional remediation. Unchanged. |
selectLesson | Mints v5 state, seeds the workspace (host − solution_files + starters), returns description, prerequisites, personalization prompts, workspaceStrippedFiles, first-run setup. Resumes instead of resetting when state already holds the same unfinished lesson and the workspace was reused: resumed: true plus the 0-based chapter_cursor, recorded artifacts kept. restart: true resets to chapter 1. A recreated workspace always starts fresh and says so with workspaceArchivedTo. A corrupt previous state arrives in warnings as { kind: 'state-corrupt', message, archivedTo? }. |
setPersonalization | Validates + persists personalization values. {} accepts defaults. |
setOutputStyle | Writes outputStyle into ~/.claude/settings.json (only Concise is accepted). Returns the previous value. |
nextChapter | Chapter envelope (see runtime flow) while chapters remain. Done envelope (done: true, summary_artifact_path, artifacts map, publish_available) once the cursor is past the last chapter: with final_verification while the e2e has not run, with completed: true after it passed. Returns ok: false with an error that starts Lesson state stale: when chapter_cursor is past the number of chapters in chapters.json. |
verifyChapter | Runs the current chapter's verification, or final_verification when the cursor is past the last chapter. On pass: advances the cursor (or marks completed_at), records the artifact path if the file exists. After completion a re-entrant call re-runs nothing and records summary.html once it exists. On the final gate only, skipped: true reports that the output holds skipped tests, so the e2e did not run against a live service (usually missing credentials). ok: false with errors means the gate recorded no result: a state save failure, an unparseable command, or the same Lesson state stale: error. |
configureWorkspace | Read/write ~/.acc/config.json. Unchanged. |
Retired: setOutputMode, advanceArtifact, nextSection, verifySection.
State v5
interface State {
schema_version: 5;
selected_lesson: string; // namespaced slug
personalization: Record<string, unknown>;
chapter_cursor: number; // 0-based; === chapters.length means "e2e pending or done"
history: HistoryEntry[];
artifacts: Record<string, string>; // chapter id → absolute artifact path (+ "summary")
workspace_path: string; // required; artifacts live at <workspace_path>/artifacts/
test_status?: { pass: boolean; output?: string; ts?: string; final?: boolean };
completed_at?: string; // set when final_verification passed
}State lives at <projectRoot>/.acc/state.json. Older versions surface as schema-mismatch; the learner re-runs the course's start command.
Component Map
| Path | Role |
.claude-plugin/plugin.json | Plugin manifest: name=agentic-community-college, commands/agents/skills/mcpServers registered. |
commands/create-course.md | /agentic-community-college:create-course → loads course-creator skill. |
commands/create-lesson.md | /agentic-community-college:create-lesson → loads lesson-creator skill. |
commands/list.md | /agentic-community-college:list → read-only catalog browser; calls start and renders, no state mutation. |
agents/course-conductor.md | Chapter-loop driver dispatched after course-engine sets up the session. |
skills/course-engine/SKILL.md | Session driver: discovery → output-style check → lesson selection → prerequisites → personalization → hand off to the conductor. Invoked by each course plugin's own start command. |
skills/course-creator/SKILL.md + templates/ | Scaffolds a new course plugin (plugin.json + accContent + probes + README + CLAUDE.md + start command + empty lessons/). |
skills/lesson-creator/SKILL.md + templates/ | Authors a lesson: Phase 0 docs → plan → tests + reference solution → chapters → description → learner validation pass → validation.json. |
skills/chapter-artifact/SKILL.md + references/conventions.md + templates/ | ACC-owned conventions for the per-chapter and summary artifacts. The conductor reads the conventions file at runtime. |
mcp/server/src/index.ts | MCP entry; registers the 8 tools and starts stdio transport when run as a script. |
mcp/server/src/tools/start.ts | start. |
mcp/server/src/tools/runPreflightProbe.ts | runPreflightProbe. |
mcp/server/src/tools/selectLesson.ts | selectLesson. |
mcp/server/src/tools/setPersonalization.ts | setPersonalization. |
mcp/server/src/tools/setOutputStyle.ts | setOutputStyle. |
mcp/server/src/tools/nextChapter.ts | nextChapter. |
mcp/server/src/tools/verifyChapter.ts | verifyChapter. |
mcp/server/src/tools/configureWorkspace.ts | configureWorkspace. |
mcp/server/src/tools/setupGate.ts | Shared entry sequence for chapter-loop tools, in two steps: loadSelectedState (state load + selected lesson) and resolveSelectedLesson (registry resolve); runSetupGate runs both. |
mcp/server/src/progress.ts | lessonPhase() (chapter / e2e / done, the one reading of state vs chapters) and resolveVerification() (applies workspace.verification_cwd), shared by nextChapter and verifyChapter. |
mcp/server/src/artifacts.ts | Artifact path conventions (<workspace>/artifacts/NN-<id>.html, summary.html), artifactNav() for footer links, and CONVENTIONS_PATH. |
mcp/server/src/outputStyle.ts | The one reader of ~/.claude/settings.json: readClaudeSettings(), isClaudePluginEnabled(), getOutputStyleStatus(), writeOutputStyle(). |
mcp/server/src/settings.ts | loadAccConfig / saveAccConfig / mergeAccConfig for ~/.acc/config.json. |
mcp/server/src/pathResolver.ts | resolveCoursePaths, substitutePathRefs, envVarsFor, envFileContents — the only ${paths.<id>} substitution channel. |
mcp/server/src/schemas/contentPaths.ts | Validator for accContent.paths + cross-reference check against probe ${paths.<id>} references. |
mcp/server/src/pluginsRoot.ts | discoverCourses() — scans ~/.claude/plugins/installed_plugins.json for accContent plugins. |
mcp/server/src/registry.ts | scanCourses() + loadLessonBySlug() over the discovered course plugins (lesson.json + chapters.json). |
mcp/server/src/state.ts | State load/save with atomic writes and corruption archiving. STATE_SCHEMA_VERSION = 5. State dir: .acc/. |
mcp/server/src/workspace.ts | Course-owned, idempotent workspace lifecycle at ~/.acc/workspaces/<slug>/. Host-tarball fingerprinting, solution-file stripping, archive-and-recreate on mismatch. |
mcp/server/src/personalization.ts | substitutePromptOnly() — scope-guarded {{ key }} substitution. |
mcp/server/src/verify.ts | Verification runner. Modes: compile, test-suite. Spawn injection seam preserved. |
mcp/server/src/preflight.ts | Shared probe types only. ACC ships zero hardcoded probes. |
mcp/server/src/dynamicProbes.ts | Declarative probe runner (filesystem-exists, http-get, shell-exit-zero, claude-plugin-enabled). |
mcp/server/src/schemas/courseProbes.ts | Validator for accContent.probes. |
mcp/server/src/pathSafety.ts | containedPath guard for host-side file writes, plus the shared isSafeRelPath / isFilenameSafeId predicates every manifest validator uses. |
mcp/server/src/schemas/lesson.ts | validateLesson() for <lesson>/lesson.json. |
mcp/server/src/schemas/chapters.ts | validateChapters() for <lesson>/chapters.json. |
mcp/server/src/schemas/common.ts | ValidationResult + validateRelPathList() shared by the lesson and chapters validators. |
mcp/server/src/schemas/state.ts | v5 state validator. |
mcp/server/src/schemas/workspace.ts | Per-workspace .course-state.json metadata validator. |
tests/ | Vitest suites: schemas, discovery, registry, output style, personalization, probes, verify, workspace, chapter-loop tools, skill/agent/template harnesses. |
Architectural invariants (do not break)
- Plugin discovery is read every call.
discoverCourses()doesn't memoize the registry file — a freshly-enabled course plugin shows up on the nextstartwithout an MCP-server restart. - Each lesson's slug is namespaced as
<course-plugin-key>/<lesson-slug>everywhere it crosses a tool boundary. - State writes are atomic.
state.ts:saveStatewrites to a tmp file withwx+0o600, fsyncs, then renames. Same helper (atomicWrite.ts) for every durable file ACC writes. - Corrupt state recovery is two-tier. Unreadable or invalid
state.jsonis archived to.acc/state.corrupt-<sha256-prefix>.json; if the archive write fails, the diagnostic is returned withoutarchivedTo. {{ ... }}substitution is scoped to chapter briefs only.personalization.ts:substitutePromptOnlyis the only function that performs it. Never call it onexpected_files,tests,verification.command, or any path-shaped field.- State schema versioning is on
STATE_SCHEMA_VERSION = 5. Older states surface asschema-mismatch. Never silently coerce. - Workspaces are course-owned and idempotent.
prepareWorkspacefingerprints the host tarball intohost_signatureand reuses an existing workspace iff that signature matches. Mismatch → archive to<workspace>.archive-<ts>/and recreate. Solution files are stripped at seed time; the runtime never copies them back. - Verification spawn is injectable.
runVerificationaccepts aspawnstub viaVerifyOptions.spawn. No module-level test override. startnever runs preflight probes. Probes only run viarunPreflightProbe, invoked by the course-engine afterselectLesson.- ACC ships zero domain probes. Every probe is declared by a course plugin's
plugin.json. A new probe kind requires a runtime change in ACC. runPreflightProberesolves probe IDs against the merged registry. Collisions: first-found wins with a discovery warning. Unknown IDs surface as a descriptive error.- Artifacts are written by the conductor, recorded by
verifyChapter. The MCP never generates HTML.verifyChapteronly checks that the conventional file exists and stores its path; a missing artifact is a warning, not a failure.verifyChapteralso back-fills chapter artifacts written after their gate (reconcile), so a late artifact still reaches the summary. - Path safety is non-negotiable. Every manifest path field is validated with
pathSafety.isSafeRelPath(no.., no leading slash); every host-side write under the workspace resolves throughpathSafety.containedPath; probe params go throughdynamicProbes.expandUserPath. One predicate, one guard, no local copies. - Configurable paths are a separate code path from personalization.
${paths.<id>}substitution lives inpathResolver.substitutePathRefsand runs ONLY against probe params + remediation, BEFORE the probe runner sees them. - The output-style check is advisory. No MCP tool refuses to run because of the active output style.
startreports it;setOutputStylechanges it only when the learner says yes.
When You Edit MCP Server Code
- Edit under
mcp/server/src/. - Run
pnpm buildfrommcp/server(the plugin runs the builtdist/index.js, not the source). - Run
pnpm testfrom the repo root. - Restart Claude Code if the plugin is already loaded; MCP servers don't hot-reload.
When You Author a Course or Lesson
Don't write lesson files by hand — invoke course-creator for a new course plugin and lesson-creator for each lesson. lesson-creator runs Phase 0 (docs), the plan, the tests + reference solution, the chapter briefs, and the learner validation pass, then writes validation.json.
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.

