math-tasks/CLAUDE.md

12 KiB
Raw Blame History

Math Tasks Generator

Printable math worksheet generator (A4 PDF) for children aged 79. 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

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 -- <file>      # Convert HTML file to PDF
pnpm remove-bg -- <file|dir>  # 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:

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 <script> that computes, generates, or modifies content at runtime. Tailwind CDN <script> tag is the only exception.
  • Page size: A4 = 210mm × 297mm
  • Page breaks: break-after: page between pages
  • Fonts: Nunito from Google Fonts via <link>
  • Images in PDF: Use local file paths. Puppeteer resolves file:// protocol. Embed as base64 data URIs when possible for reliable rendering.

Image Generation

Use the /gen-image skill to generate images via the Banatie API. Auth via BANATIE_KEY in .env. Rate limit: 100 requests/hour.

Reference Policy

When generating new assets for assets/items/, use existing images from the same subfolder as --ref to maintain visual consistency. The gen-image skill's default policy is to ask before using refs — this project overrides that: use refs automatically for items in the same asset group.

Style reference chain:

  • assets/items/asteroids/ — use any existing asteroid as ref
  • assets/items/crystals/ — use any existing crystal as ref
  • assets/icons/ — generate independently (icon packs have their own pipeline)
  • assets/hero-images/, assets/footers/, assets/backgrounds/ — generate independently

Background Removal

src/scripts/remove-bg.mjs — flood-fill white background removal from PNGs (like magic wand). Uses sharp.

node src/scripts/remove-bg.mjs <file|dir> [--threshold N] [--fuzz N]

Optional — not all icons need it. Ask user after generating/splitting new icons.

PDF Generation

node src/scripts/generate-pdf.mjs tasks/{type}/docs/{docId}.output.html

Puppeteer: A4, printBackground: true, zero margins, preferCSSPageSize: true.

Workflow Summary

  1. User describes the task idea (or runs /new-doc)
  2. Claude creates/updates .md file with patterns and notes
  3. Claude creates/edits .template.html (reading type CLAUDE.md and base references)
  4. Run generate.mjs to create .output.html
  5. (Optional) User opens editor → fine-tunes positions → Save → data.json + output.html updated
  6. Claude reviews diff if asked: cat tasks/{type}/temp/{docId}.diff.json
  7. Add card to tasks/index.html
  8. Generate PDF: node src/scripts/generate-pdf.mjs tasks/{type}/docs/{docId}.output.html
  9. Preview at http://localhost:3300/tasks/index.html