Commit Graph

3492 Commits

Author SHA1 Message Date
Thomas Hallock 42f55855eb fix(litefs): remove HOSTNAME env var to allow pod hostname detection
LiteFS needs the actual pod hostname for cluster communication,
but HOSTNAME=0.0.0.0 was being set in both the Dockerfile and
ConfigMap, overriding the pod's hostname.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:38:30 -06:00
Thomas Hallock 8b39673c8d fix(litefs): correct migrate.js path to dist/db/migrate.js
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:10:57 -06:00
Thomas Hallock bb9a4be6c2 fix(litefs): remove invalid primary-redirect-url config field
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 13:44:49 -06:00
Thomas Hallock e69a33838a feat(infra): add LiteFS for distributed SQLite in k8s
- Add LiteFS binary and config to Docker image for SQLite replication
- Convert k8s Deployment to StatefulSet for stable pod identities
- Pod-0 is primary (handles writes), others are replicas
- LiteFS proxy forwards write requests to primary automatically
- Add headless service for pod-to-pod communication
- Increase Node.js heap size to 4GB for Next.js build
- Exclude large Python venvs from Docker context

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 13:19:37 -06:00
Thomas Hallock 24ce7475f0 fix(web): convert Panda CSS shorthand padding/margin to separate props
Panda CSS token values in shorthand strings (e.g., `padding: '2 4'`)
silently fail. Convert all 84+ occurrences to paddingX/paddingY and
marginX/marginY properties which correctly resolve design tokens.

Affected areas:
- Flowchart pages and components
- Know Your World game components
- KidNumberInput component

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 11:38:40 -06:00
Thomas Hallock c16b70090f feat(infra): add full k8s stack mirroring docker-compose setup
Terraform now deploys a complete k8s environment:
- cert-manager with Let's Encrypt (staging + prod issuers)
- Redis deployment with persistent storage
- App deployment (2 replicas, rolling updates)
- Traefik ingress with SSL, HSTS, HTTP→HTTPS redirect

Ready for switchover by forwarding ports 80/443 to k3s VM.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 11:33:49 -06:00
Thomas Hallock 31e0c2bfee chore: remove obsolete root .claude docs
Part of agent instructions refactoring (Phase 1 deletions).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 11:19:13 -06:00
Thomas Hallock c29388df30 refactor(docs): consolidate .claude instructions (53% reduction)
- Delete 10 obsolete files (roadmaps, specs, historical artifacts)
- Merge 5 arcade docs into ARCADE_SYSTEM.md (2,274 → 309 lines)
- Condense merge conflicts (707 → 126 lines)
- Rewrite CLAUDE.md (262 → 94 lines)
- Update README.md with new structure

Before: 42 files, ~13,600 lines
After: 25 files, 6,389 lines

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 11:15:26 -06:00
Thomas Hallock 38e289f626 chore(infra): add terraform lock file for reproducible builds
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 11:04:51 -06:00
Thomas Hallock 1cac633814 feat(infra): add initial Terraform config for k3s cluster
Set up Terraform to manage k3s resources on the NAS VM:
- Kubernetes and Helm providers configured
- Created 'abaci' namespace for workloads
- Ready for BullMQ workers and future scalable services

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 11:04:07 -06:00
Thomas Hallock 87e76a514b chore: update local settings with new allowed commands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:16:11 -06:00
Thomas Hallock 367edc8f82 refactor: rename .claude/skills to .claude/procedures
Avoid terminology confusion - "skills" refers to invokable commands
like /fix-css and /porkbun-dns. The documentation files are
step-by-step procedures, not invocable skills.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:14:42 -06:00
Thomas Hallock a36303be1c refactor: agent instructions Phase 4 - add index and restore merge conflicts
- Add .claude/README.md index categorizing all 34 docs
- Restore Merge Conflict section reference to CLAUDE.md
- Categorize docs: Skills, Reference, Architecture, Specs, Settings, Ops, Research, Roadmaps

Final CLAUDE.md: 262 lines (83% reduction from 1,531)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:09:57 -06:00
Thomas Hallock 69098e3038 refactor: agent instructions Phase 2+3 - CLAUDE.md now 258 lines
Phase 2:
- Extract React Query patterns to reference/react-query-mutations.md
- Extract TensorFlow debugging to reference/tensorflow-browser-debugging.md
- Extract Abacus Visualizations to reference/abacus-react.md
- Slim Production Dependencies (73→7 lines)
- Slim Code Factoring (75→9 lines)
- Slim Data Attributes (49→9 lines)

Phase 3:
- Consolidate 3 CRITICAL behavioral sections (92→12 lines)
- Slim Merge Conflict, Z-Index, Animation, Game Settings sections
- Slim Flowchart Walker, Daily Practice, Rithmomachia
- Remove duplicate package.json scripts section
- Consolidate workflow and dev server sections

Total reduction: 1,531 → 258 lines (83% smaller)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:07:09 -06:00
Thomas Hallock a3409fff38 refactor: agent instructions Phase 1 + dark mode modal fixes
Dark mode improvements:
- Fix DeploymentInfoModal background, title, footer colors
- Fix badge contrast (StatusBadge, CodeBadge) with raw rgba/hex values
- Fix padding syntax (Panda CSS gotcha: '1 2' → '4px 8px')

Agent instructions refactoring:
- Slim CLAUDE.md from 1,531 to 1,148 lines (-25%)
- Create .claude/skills/database-migrations.md (consolidated skill)
- Create .claude/reference/panda-css.md (styling gotchas)
- Delete 40+ stale plan/status docs (16k+ lines removed)
- Consolidate duplicate migration sections
- Add skills/ and reference/ directory structure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 09:49:10 -06:00
Thomas Hallock e9c4bb1ed8 fix(flowchart): implement proper task queue for concurrent example generation
Replace sequential example generation with a proper task queue system that
correctly handles concurrent requests to the Web Worker pool.

Root cause of previous issues: Each worker stored only ONE resolve/reject
callback, so concurrent requests would overwrite each other's callbacks,
causing promises to never resolve or resolve with wrong data.

Solution:
- Add unique requestId to all worker messages for request/response matching
- Implement task queue with dispatch logic for pending work
- Track pending requests in a Map keyed by requestId
- Workers echo back requestId so responses match their originating requests
- Both /flowchart page and workshop page now generate concurrently

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:51:36 -06:00
Thomas Hallock de720ab39b fix(flowchart): sequence example generation to avoid web worker conflicts
When both WorksheetDebugPanel and FlowchartExampleGrid try to generate
examples simultaneously using the shared web worker pool, the workers'
resolve/reject callbacks get overwritten, causing one request to never
complete.

This fix sequences the generation:
- WorksheetDebugPanel generates first (when worksheet tab is active)
- FlowchartExampleGrid waits until WorksheetDebugPanel signals completion
- Added onGenerationStart/onGenerationComplete callbacks to WorksheetDebugPanel
- Added waitForReady prop to FlowchartExampleGrid to defer generation
- Workshop page coordinates the sequence using isDebugPanelGenerating state

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:14:07 -06:00
Thomas Hallock 83c2f261c0 fix(flowchart): add node ID mismatch detection and graceful error handling
- Add MERM-002 doctor diagnostic to detect when JSON node IDs don't
  match mermaid node IDs
- Update loader to throw error when entry node is missing or >50% of
  nodes are missing from mermaid (prevents crash loops)
- Add flowchartLoadError state and UI display in workshop page
- Improve LLM schema documentation for display.answer vs generation.target
- Add context-aware division-by-zero suggestions in doctor

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 19:05:36 -06:00
Thomas Hallock 86fe99e5c2 fix(flowchart): unify example generation for published and draft cards
- Combine published and draft example generation into single unified effect
- Fix race condition where worker pool was cancelling requests when
  drafts and published flowcharts competed for the same workers
- Add draftMermaidContent to sessions API response (was missing)
- Remove redundant draftCardExamples state in favor of unified cardExamples
- Process all flowcharts sequentially to avoid worker pool cancellation
- Show animated backgrounds on healthy draft flowcharts, not just published

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 18:01:37 -06:00
Thomas Hallock 7c4f58b3fd fix(worksheet): correct Typst answer formatting for fractions
User fixes to worksheet-generator.ts for proper fraction display
in answer keys.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 15:01:14 -06:00
Thomas Hallock b80671ef4c fix(worksheet): use formatAnswerDisplay for custom schema answers
The worksheet generator was hardcoding answer computation for specific
schemas (two-digit-subtraction, fractions, linear equations) and
returning "?" for any unknown schema like custom flowcharts.

Now uses the centralized formatAnswerDisplay() function which properly
handles:
- Custom display.answer expressions defined in the flowchart
- Computed variables from the flowchart definition
- Schema-specific fallback logic
- The generation.target fallback for custom schemas

This fixes PDF worksheets showing "?" answers for teacher-created
flowcharts like "math duck maker" while the debug panel showed
correct answers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 14:46:24 -06:00
Thomas Hallock 83811b1dc5 feat(flowchart): add worksheet progressive difficulty and diagnostics
Worksheet improvements:
- Add orderByDifficulty option to sort problems easy→medium→hard
- Add typstAnswer field for proper fraction rendering in answer key
- Add WorksheetDebugPanel to preview generated examples
- Move PDF creation to modal in workshop, make worksheet tab default
- Support worksheet generation from workshop sessions

Flowchart diagnostics:
- Add doctor.ts with validation checks (DISP-002 for missing answer handlers)
- Add FlowchartDiagnostics component for displaying warnings
- Add display.answer config to fraction and linear equation flowcharts

UI refinements:
- Improve AnimatedProblemTile styling
- Enhance FlowchartCard and FlowchartModal components
- Add derived field validation tests for LLM schemas

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 14:16:14 -06:00
Thomas Hallock 269321b4c4 feat(flowchart): add animated background tiles to FlowchartCards
- Add AnimatedProblemTile component with MathDisplay for proper math rendering
- Add AnimatedBackgroundTiles grid component for card backgrounds
- Update FlowchartCard to accept flowchart + examples props
- Generate examples client-side for both hardcoded and database flowcharts
- Use same formatting system (formatProblemDisplay + MathDisplay) as modal

Also includes:
- Fix migration 0076 timestamp ordering issue (linkedPublishedId column)
- Add migration-timestamp-fix skill documenting common drizzle-kit issue
- Update CLAUDE.md with migration timestamp ordering guidance
- Various flowchart workshop and vision training improvements

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 10:10:49 -06:00
Thomas Hallock a40d136ead fix(flowchart-workshop): complete LLM processing even if client disconnects
Previously, closing the browser while the LLM was generating a flowchart
would abort the entire operation - the work would be lost because:
1. sendEvent() would throw when writing to a closed stream
2. The exception would jump to catch and skip the DB save
3. Session state would be reset to 'initial' (error state)

Now the generate and refine routes are resilient to client disconnect:
- sendEvent() catches errors silently and sets clientConnected=false
- LLM stream processing continues regardless of client state
- DB save happens AFTER the LLM loop, not inside try-catch for client errors
- Added logging to track when saves happen with disconnected client

Result: If you start generating a flowchart and close the browser, the
server will finish processing and save to DB. When you return to the
session, your flowchart will be there waiting.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 05:16:00 -06:00
Thomas Hallock 1e1a6569c5 fix(llm-client): use idle timeout instead of total timeout for streaming
The previous implementation used a single total timeout that would abort
the stream after 5 minutes regardless of whether data was actively flowing.
For thinking models that stream for long periods (thinking phase + output),
this caused timeouts even while data was being received.

Changes:
- Replace single total timeout with dual timeout system:
  - Idle timeout (2 min): resets every time data is received
  - Total timeout (15 min): absolute maximum time limit
- Reset idle timeout on each received chunk in the streaming loop
- Stream only times out if no data received for 2 minutes OR
  total time exceeds 15 minutes

This prevents flowchart generation failures when using reasoning models
that take several minutes to think before generating output.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 05:06:19 -06:00
Thomas Hallock fcc404449e feat(flowchart-workshop): complete teacher flowchart workshop implementation
This commit adds the full teacher flowchart workshop feature:

**Example Generator Fixes:**
- Fix `number` type fields (decimals) not generating examples - use preferred values directly
- Fix string-valued correctAnswer constraint checking so multiple paths generate examples
- Add diagnostic warnings for `number` fields without preferred values

**LLM Schema Updates (from sonia-math-curriculum skill):**
- Add layout rules: `flowchart TB` with `direction LR` inside subgraphs
- Add "Cue + Details" writing style for instruction boxes
- Add phase-to-phase connections only pattern
- Add WHY boxes, reminder boxes, error callouts, ready checks
- Add color coding conventions and emoji usage guidelines

**Workshop Infrastructure:**
- API routes for workshop sessions (create, generate, refine, save)
- API routes for teacher flowcharts CRUD (list, get, update, delete)
- API routes for publishing/unpublishing
- Public flowchart browser API

**UI Components:**
- Workshop session pages with live flowchart preview
- My Flowcharts dashboard
- Public flowchart browser
- Flowchart cards and example grid components
- Create/delete modals and toasts

**Database:**
- teacher_flowcharts and workshop_sessions tables
- Migration 0072 with schema

**Additional utilities:**
- Path analysis for flowchart structure
- Grid dimensions calculation
- PDF export capability
- Flowchart validation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 20:28:50 -06:00
Thomas Hallock f29126bd67 Virtualize vision training image grid and fix selection behavior
- Add virtualization using @tanstack/react-virtual to handle thousands
  of training images without loading all at once
- Fix selection behavior: normal click now replaces selection (was toggle),
  shift+click adds range to selection
- Add independent panel scrolling with minHeight: 0 for flex layout
- Use ResizeObserver to dynamically calculate items per row

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 08:55:51 -06:00
Thomas Hallock 1b034749fb docs: add flowchart modification skill for future reference
- Create .claude/skills/FLOWCHART_MODIFICATIONS.md with patterns for:
  - Adding checkpoint nodes (variables, edges, Mermaid content)
  - Conditional skipping with skipIf and excludeSkipFromPaths
  - Understanding path enumeration and grid dimension stability
  - Working problem evolution
  - Debugging tips and modification checklist
- Add reference in CLAUDE.md under Flowchart Walker System section

This captures lessons learned from the fraction flowchart sprint where we
split CALCULATE into separate inputs and added conditional whole number skipping.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 08:29:22 -06:00
Thomas Hallock 3267dbcf55 feat(flowchart): break fraction CALCULATE into separate input checkpoints
- Split STEP4 into three checkpoints: NUMERATOR, DENOMINATOR, WHOLE NUMBER
- Add skipIf/skipTo support to CheckpointNode for conditional skipping
- Add excludeSkipFromPaths option to prevent skipIf from affecting grid dimensions
- CALC_WHOLE skips automatically when no whole numbers in problem
- Update loader.ts to handle checkpoint skipIf in path complexity and enumeration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 08:24:08 -06:00
Thomas Hallock b272cf95c3 fix(flowchart): change SKIP node type to milestone 2026-01-19 06:19:16 -06:00
Thomas Hallock 762987822e feat(flowchart): add excludeFromExampleStructure option to DecisionNode 2026-01-19 06:19:11 -06:00
Thomas Hallock 54193f6d05 chore: add chrome-devtools MCP permissions 2026-01-19 06:19:06 -06:00
Thomas Hallock d757b775a8 refactor: rename milestone to embellishment in flowchart definitions
Semantic rename only - both node types auto-advance.
No behavior change.

- linear-equations: STUCK_ADD, STUCK_MUL
- subtraction-regrouping: HAPPY, SAD, SKIP
- fraction-add-sub: READY1, READY2, READY3, GOSTEP4, GOSTEP4B, GOSTEP4C

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 05:09:22 -06:00
Thomas Hallock 1a68df6fe3 feat: Restructure FlowchartWalker with centered Time Machine layout
Major layout redesign that makes the working problem the hero:

Layout changes:
- Single centered column instead of two-column with sidebar
- TimeMachineHistory displays problem evolution as 3D perspective stack
- Instructions appear above the Time Machine
- Interaction area (checkpoints, decisions) below
- Compact phase rail in top bar
- Floating hamburger menu replaces full nav during walking

Behavior changes:
- Decision nodes rendered via FlowchartDecisionGraph (moved from separate component)
- Embellishment nodes auto-advance after 800ms with pop animation
- Milestone nodes auto-advance after 500ms
- Walking mode uses distraction-free UI with FloatingHamburgerMenu

This creates a focused, problem-centered experience where the student
sees their work evolving as they progress through the flowchart.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 04:48:23 -06:00
Thomas Hallock 20d6e96fb1 feat: Add compact mode to FlowchartPhaseRail
Add a `compact` prop that renders the phase rail as minimal pills:
- Shows only phase indicators: ✓ (completed), 📍 (current), ○ (upcoming)
- No expanded current phase section
- No decision graph in compact mode
- Suitable for top bar placement in focused walker views

Also integrates FlowchartDecisionGraph for inline decision rendering
when not in compact mode.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 04:26:46 -06:00
Thomas Hallock ce210406b9 feat: Add TimeMachineHistory component with 3D perspective stack
New component that displays problem evolution as an Apple Time Machine-style
stack of cards:
- Current problem is prominent (full opacity, full scale) at the front
- Previous problems are stacked behind with perspective depth
- Each layer: translateZ, scale down, fade opacity
- Clicking past layers triggers navigation to rewind
- Smooth animation when new entries are added

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 04:24:32 -06:00
Thomas Hallock 97fdcd9484 fix: Exclude test files and KidNumberInput from Panda CSS parsing
Add exclusions for test files and KidNumberInput.tsx to prevent Panda CSS
from attempting to parse special patterns like {bksp} and {enter} that
confuse the parser.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 04:19:18 -06:00
Thomas Hallock a889102fe6 feat: add FloatingHamburgerMenu component
A standalone hamburger menu that floats in the corner of the screen.
Use this for distraction-free modes where you want to hide the full
app nav but still provide access to navigation, settings, and theme.

Features:
- Configurable position (top-left, top-right, bottom-left, bottom-right)
- Optional exit button with custom label
- Navigation links to main app areas
- Fullscreen toggle
- Theme toggle (light/dark)
- App info access
- Mobile: full-screen overlay
- Desktop: Radix dropdown menu

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 04:09:40 -06:00
Thomas Hallock 83d8846b5e feat(flowchart): extract FlowchartDecisionGraph component
Extract the decision graph visualization into a standalone component.
Renders a flowchart-style diamond with option buttons, showing the
decision point visually with connecting lines to choices.

Features:
- Diamond shape for decision question
- Option buttons arranged around the diamond
- SVG connecting lines between diamond and options
- Wrong answer feedback with shake animation
- Dark mode support

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 04:09:33 -06:00
Thomas Hallock 2e299a9523 feat(flowchart): add embellishment handling and skipIf/skipTo support
Two related improvements to flowchart path analysis:

1. Embellishment node support:
   - Add case handlers in getNextNode, calculatePathComplexity,
     enumerateAllPaths, and getNextNodeForAnalysis
   - Embellishment nodes auto-advance like milestones

2. skipIf/skipTo for decision nodes:
   - Allow decisions to be automatically skipped based on a condition
   - In calculatePathComplexity: evaluate skipIf and skip to target
     without counting as a decision
   - In enumerateAllPaths: enumerate both skip path (skipIf=true)
     and option paths (skipIf=false) as alternatives

This enables conditional decision nodes like WHOLE_CHECK that only
appear when relevant (e.g., when fractions have whole numbers).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 04:09:25 -06:00
Thomas Hallock 2e82ff041b feat(flowchart): add EmbellishmentNode type for decorative moments
Add a new node type for showing animated emoji/celebration moments
that auto-advance. Unlike milestones (which are for success markers),
embellishments are purely decorative moments like 👍, 😎, 💪 between
substantive steps.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 04:09:15 -06:00
Thomas Hallock 5ebd3008f6 Add visual debug mode and documentation for flowchart system
- Add DebugMermaidDiagram component to visualize flowchart with current
  node highlighted in debug mode
- Add DebugStepTimeline for undo/redo navigation through flowchart steps
- Add rawMermaid field to ExecutableFlowchart schema for debug rendering
- Add comprehensive README.md documenting the flowchart walker system
- Add JSDoc comments to parser.ts, loader.ts, definitions/index.ts
- Add flowchart section to .claude/CLAUDE.md
- Add PageWithNav hamburger menu to flowchart page
- Fix MathDisplay to show implicit coefficient of 1 (1x → x)
- Install mermaid dependency for flowchart visualization

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 09:24:28 -06:00
Thomas Hallock f67b39f315 Add crossfade animation to example problems synced with dice roll
- Create AnimatedMathDisplay component with opacity crossfade transitions
- Use CSS Grid to stack old/new expressions independently (no layout shift)
- Update examples at roll start (handleRoll) instead of roll complete
- Set crossfade duration to 700ms to match dice animation timing
- Both animations now end together for smooth visual experience

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 06:19:34 -06:00
Thomas Hallock bb192c5e20 Add session generation benchmark and fix test expectations
- Add sessionGenerationBenchmark.test.ts to measure real-world session
  generation time with memoization (result: 311ms for 60 problems)
- Fix provenance.test.ts: TenComplement operations produce "-5" step, not "5"
- Fix termPositionBuilder.test.ts: subtraction formatted as "10 - 5" not "10 + -5"

Benchmark shows Phase 2 (worker parallelization) is not needed -
98x speedup from Phase 1 memoization is sufficient.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 21:03:01 -06:00
Thomas Hallock a9a5e7861d Add memoization for analyzeStepSkills() - 98x speedup
Problem generation was calling analyzeStepSkills() ~432,000 times per
session, with many duplicate (currentValue, term) pairs. Since skill
detection is deterministic, we can memoize results.

Changes:
- Add stepSkillsCache Map with key `${currentValue}:${term}`
- Add analyzeStepSkillsMemoized() wrapper function
- Add clearStepSkillsCache() and getStepSkillsCacheStats() for testing
- Wire up memoized version in collectValidTerms() hot path

Performance (A/B benchmark with 46,000 operations):
- Non-memoized: 452.5ms average
- Memoized: 4.6ms average
- Speedup: 98.8x faster
- Cache hit rate: 99.9%
- Only 46 unique states for 46,000 operations

Tests:
- 33 new tests for correctness, cache behavior, determinism
- All existing skill detection/extraction tests pass

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 20:54:49 -06:00
github-actions[bot] 6c383b603c 🎨 Update template examples and crop mark gallery
Auto-generated fresh SVG examples and unified gallery from latest templates.
Includes comprehensive crop mark demonstrations with before/after comparisons.

Files updated:
- packages/templates/gallery-unified.html

🤖 Generated with GitHub Actions

Co-Authored-By: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-18 02:47:32 +00:00
Thomas Hallock 8fd0606f34 Add per-field validation and smart keypad visibility to FlowchartCheckpoint
- Add expectedValues prop for immediate per-field validation
- Show green/red feedback as user types (based on digit count match)
- Auto-advance to second field when first is correct
- Auto-submit when both fields are correct (400ms delay)
- Add smart keypad visibility using device detection hooks
- Only show on-screen keypad on touch devices without physical keyboard
- Compute expected values in FlowchartWalker from checkpoint definitions
- Support orderMatters prop for order-agnostic two-numbers validation
- Fix isNaN() to Number.isNaN() for lint compliance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 18:46:09 -06:00
Thomas Hallock 7e98a01a41 Add unit tests for KidNumberInput and FlowchartCheckpoint
Tests for KidNumberInput component:
- Rendering with different props and states
- Feedback state styling (correct/incorrect/none)
- Disabled state behavior
- Keypad interaction

Tests for useKidNumberInput hook:
- Initial state
- Adding/removing digits
- Auto-validation on max digits
- Correct/incorrect callbacks
- Clear on correct/incorrect options

Tests for FlowchartCheckpoint:
- KidNumberInput integration for number input type
- Native input preserved for text type
- Two-numbers input mode
- Feedback display
- Keyboard input handling
- Disabled state

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 15:57:53 -06:00
Thomas Hallock 7c597e9079 Integrate KidNumberInput into FlowchartCheckpoint
- Replace native number inputs with KidNumberInput for kid-friendly touch targets
- Add global keyboard handler for physical keyboard support
- Support focused input switching for two-numbers mode with Tab/click
- Display inline keypad for number entry with visual feedback
- Keep native text input for text-type checkpoints

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 15:52:27 -06:00
Thomas Hallock 45ce9a2a20 Add KidNumberInput component for kid-friendly number entry
- Extract reusable number input from complement race game concept
- Support both game mode (auto-clear) and form mode (persist answer)
- Auto-validation when correct digit count is reached
- Touch-friendly on-screen keypad with fixed/inline modes
- Keyboard input support with global listener option
- Visual feedback states: none, correct (pulse), incorrect (shake)
- Multiple display sizes (sm/md/lg/xl)
- Dark/light theme support via CSS custom properties
- Comprehensive Storybook stories for all use cases
- Full documentation in README.md

Also fix Storybook CSS imports to use styles.css directly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 15:44:37 -06:00