This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in node_modules/next/dist/docs/ (resolved from this file's directory; in monorepos the next package may not be visible from the repo root) before writing any code. Heed deprecation notices.
This block is written and re-added by next dev — verify at node_modules/next/dist/server/lib/generate-agent-files.js. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.
Hatch is a single-user web app that teaches Python from zero to advanced practical Python. Real Python runs in the browser (Pyodide, in a module Web Worker). It is not a quiz app, not LeetCode and not an AI tutor.
npm run dev— syncs assets, compiles content (strict: fails while any unit is unfinished), starts on :2034. While authoring, useHATCH_PREVIEW=1 npm run content && npx next dev -p 2034: preview mode leaves out units whose lessons are not all written yet.npm run content/content:check/content:verify— compile, validate (schema, concept graph, prerequisite leaks, terminology, XP), and execute every solution/invalid sample through the real Python checker.HATCH_PARTIAL=1 ... --only <unit-id>validates one unit.npm run typecheck,npm run lint,npm test(Vitest),npm run test:e2e(Playwright; reuses a server on :2034).HATCH_E2E_UNITS=u01,u02 npx playwright test walkthroughplays whole lessons through the UI with their reference solutions.
python/hatch/is the ONLY implementation of running, checking, AST feature analysis and error shaping. Browser: loaded into Pyodide bypublic/hatch-worker.jsviapython/hatch/bridge.py. Node (content verification, tests):python3 -m hatch.clithroughsrc/curriculum/python.ts. Never re-implement checks in TypeScript.content/is YAML:course.yaml(tracks),achievements.yaml,units/<id>/unit.yaml(concept graph, features, terms, pitfalls) + one file per lesson.content/AUTHORING.mdis the authoring spec.scripts/build-content.tscompiles topublic/curriculum/andsrc/generated/outline.json. Do not hand-edit generated files.src/curriculum/schema (zod), loader, graph (feature ownership, prerequisite-leak detection), validators, execution verifier.src/engine/pure logic with tests: XP ledger (idempotent), evidence-based mastery + spaced review, progress, next-action resolver, achievements, review sessions. No React, no storage.src/store/zustand store +persistence.ts(zod-validated localStorage, backups, never silent about failures).src/runtime/worker client, session (terminal state),run.ts(run in terminal),explain.ts(friendly error explanations).src/components/lesson/workspace.tsxis the lesson/review orchestrator;step-views.tsxthe step renderers.
- Teach before testing; one major idea per lesson; the app, not the learner, picks the order.
- Validation is behavioural (run the program, scripted stdin, files, mocks) plus AST rules. Never match exact source text. Never hardcode outputs.
- Errors: friendly explanation first (per-unit
errorStyle), raw traceback always available; code is never erased on failure. - Mastery only rises through evidence (doing), never by reading. XP is idempotent per source.
- No fake features: unsupported things (threads, real network, a real terminal) are said plainly in lessons.
- Needs cross-origin isolation (COOP/COEP set in
next.config.ts) for SharedArrayBuffer: blockinginput()and Stop use Atomics. - Pyodide 314 requires a MODULE worker (
new Worker(url, { type: "module" }),importfrom/pyodide/pyodide.mjs). asyncio.runin the live editor uses JSPI (callPromising). Without JSPI,python/hatch/live.pyrewrites module-levelasyncio.run(x)intoawait x; hidden checks that callasyncio.runthemselves (expr/custom) are not supported there, so async lessons check stdout of the learner's whole program instead.- AST
rulesin a check apply to theentryfile only. For multi-file projects, test structure with fixtures (e.g. anh.pyhelper that parses the module withast) viacustomtests. - Shell is zsh: quote globs in commands (
--include='*.ts').