# Math Tasks Generator Printable math worksheet generator (A4 PDF) for children aged 7–9. Claude Code is the central orchestrator: user describes a task idea → Claude creates/edits HTML templates → optional visual editor fine-tuning → PDF via Puppeteer. ## Commands ```bash pnpm build:css # Build Tailwind CSS (minified) pnpm build:css:watch # Watch mode for CSS pnpm preview # Serve at localhost:3300 with live-reload pnpm dev # CSS watch + preview server (concurrent) pnpm pdf -- # Convert HTML file to PDF pnpm remove-bg -- # Remove white background from PNG icons ``` Generate images via `/gen-image` skill (uses Banatie API, reads `BANATIE_KEY` from `.env`). ## Directory Structure ``` tasks/ index.html — document index (Claude updates manually) {task-type}/ — one folder per task type CLAUDE.md — type-specific rules and conventions editor.html — visual editor for this task type scripts/ — type-specific scripts (validation, generation) docs/ — document instances {docId}.md — task description, problem patterns, notes (Claude reads/writes) {docId}.template.html — near-final HTML maintained by Claude {docId}.data.json — editor data layer (positions, values — may not exist) {docId}.output.html — generated from template+data (gitignored) temp/ — diffs and transient data (gitignored) src/ editor/editor-core.js — shared editor framework scripts/ generate-pdf.mjs — HTML → PDF via Puppeteer (all types) remove-bg.mjs — Remove white background from PNGs split-sprites.mjs — Split sprite sheets into icons generate-problems.mjs — Problem generation utility styles/main.css — Tailwind source with A4/print styles templates/space-base.html — Shared base template reference assets/ — images (hero, footer, icons, items, backgrounds) output/pdf/ — generated PDFs (gitignored) ``` ## Task Types Each task type lives in `tasks/{type-name}/` with its own CLAUDE.md, scripts, editor, and document instances. Current types: - **space-exploration** — math problem worksheets with hero images and icon-decorated cards - **collecting-asteroids** — match asteroids to cargo ships by weight sum - **space-route** — navigate hex graph routes with difficulty constraints **Type-specific rules** (layout details, asset conventions, generation algorithms) live in each type's own CLAUDE.md — NOT in this file. Read `tasks/{type}/CLAUDE.md` before working on any task of that type. ## Document File Set Each document instance consists of up to 4 files in `tasks/{type}/docs/`: | File | Purpose | Owner | |------|---------|-------| | `{docId}.md` | Task description, problem patterns, page notes | Claude writes, user reviews | | `{docId}.template.html` | Near-final static HTML, maintained by Claude | Claude | | `{docId}.data.json` | Editor data layer (positions, values) | Editor UI via save endpoint | | `{docId}.output.html` | Final HTML = template + data applied | generate.mjs (gitignored) | **Key:** `.data.json` may not exist — and that's fine. When it doesn't exist, `.template.html` IS the final output. **The `.md` file does NOT directly drive HTML generation.** It's context for Claude — problem patterns, non-obvious details (e.g., hero orientation per page), things Claude needs to know when editing the template. It does NOT contain titles, footers, or asset paths that are already in the HTML. ## Creating New Task Types 1. Create folder `tasks/{type-name}/` 2. Create `CLAUDE.md` with type-specific rules 3. Create `scripts/generate.mjs` — template + data → output pipeline 4. Create `editor.html` importing `src/editor/editor-core.js` + type-specific logic 5. Create `scripts/` for any validation/generation utilities 6. Add section to `tasks/index.html` ## Creating New Documents When the user asks to create a new document of an existing type: 1. Copy the previous document's files with incremented number: - `{type}-N.template.html` → `{type}-(N+1).template.html` - `{type}-N.md` → `{type}-(N+1).md` 2. Update the `.md` file with new problem patterns / page descriptions 3. Edit `.template.html` as needed (new problems, different assets, etc.) 4. Add card to `tasks/index.html` **No script for this — Claude does it manually.** `.data.json` starts empty (created only when the editor is used). ## Adding Pages to Existing Documents 1. Read the `.md` file to understand existing patterns 2. Edit `.template.html` directly — add new page markup 3. Update `.md` if new patterns were added ## Generation Pipeline ``` .template.html + .data.json (if exists) → scripts/generate.mjs → .output.html + screenshots ``` - Same pipeline for both Claude-initiated regeneration and editor-save flow - If no `.data.json` exists → template.html copied as-is to output.html - `generate.mjs` is a per-task-type script; it calls `postGenerate()` from `src/scripts/post-generate.mjs` at the end - `postGenerate()` runs `src/scripts/take-screenshots.mjs` which produces per-page PNG screenshots in `tasks/{type}/temp/{docId}-page-{N}.png` - Screenshots are automatically regenerated on every generate — old ones are deleted before new ones are written - **All new task types must include `postGenerate()` call in their `generate.mjs`** — this is part of the standard pipeline ## Editor System Each task type has its own `editor.html` in its folder. All editors share `src/editor/editor-core.js` for common functionality (drag, selection, keyboard, toolbar, save, toast). **Opening in editor:** ``` http://localhost:3300/tasks/{type}/editor.html?file={docId} ``` **Save flow:** 1. User clicks Save in editor 2. Editor POST `/api/save-edits` with `{ taskType, docId, data }` 3. Server writes `docs/{docId}.data.json` 4. Server computes diff → writes `temp/{docId}.diff.json` 5. Server runs `generate.mjs` → regenerates output.html + screenshots **Claude reviewing editor changes:** ```bash cat tasks/{type}/temp/{docId}.diff.json # see what changed # Read screenshot PNGs from tasks/{type}/temp/{docId}-page-{N}.png to verify visually ``` ## Index Page `tasks/index.html` — Claude updates manually when creating new documents. Each document has View and Edit links. Different task types can have different card styles. **Preview:** `http://localhost:3300/tasks/index.html` ## Script Principles (Orchestrator Pattern) Claude Code is the central orchestrator. Scripts are tools for Claude, not autonomous actors. **Rules:** - Scripts read input → compute → output to stdout (JSON) or write a single specific output file - Scripts NEVER chain together - Scripts NEVER auto-modify documents or make decisions - Claude runs a script, reads its output, decides what to do next **Allowed write exceptions:** - `generate.mjs` — writes `.output.html` + screenshots via `postGenerate()` (template+data→output, deterministic) - `generate-pdf.mjs` — writes PDF (final artifact) - `take-screenshots.mjs` — writes page PNGs to `temp/` (called by `postGenerate`, part of generate pipeline) - `/api/save-edits` — writes `.data.json` + `.diff.json` + runs `generate.mjs` (user-initiated from editor UI) **Example of correct flow:** ``` Claude: node tasks/collecting-asteroids/scripts/verify.mjs --ships 10,10,14 --asteroids 3,2,1,4,5 Script → stdout: { "valid": false, "errors": ["ship 2 overflow by 3"] } Claude: *reads output, decides how to fix, edits template* ``` ## Proactive Rule Saving During sessions, when the user gives feedback or instructions specific to a task type, **proactively suggest saving it as a rule**: > "Сохранить это как правило для {type}?" If confirmed → write to `tasks/{type}/CLAUDE.md`. General rules that apply to all types → root CLAUDE.md (this file). ## Visual Verification **MANDATORY for:** refactoring, new features, new task types, new documents, any significant changes to templates or generation logic. ### Automatic screenshots (passive) Every `generate.mjs` run produces per-page screenshots in `tasks/{type}/temp/{docId}-page-{N}.png`. These are always up-to-date — read them with the Read tool to verify results without asking the user. ### Chrome DevTools MCP (interactive) Use `chrome-devtools-mcp` tools (`navigate_page`, `take_screenshot`) to check pages in the live browser when the dev server is running. This is useful for: - Checking editor functionality (drag, keyboard, save) - Verifying hover/click states - Inspecting specific elements ### When to verify - **After generating a new document** — read at least page 1 screenshot to confirm images load and layout is correct - **After refactoring** — check all affected task types - **After editing template.html** — regenerate and check screenshots - **After modifying asset paths or server config** — check all types - **Do not ask the user to verify** what you can check yourself via screenshots ## HTML Generation Guidelines - **OUTPUT MUST BE STATIC HTML.** Template files must contain only static markup — no embedded `