This commit implements iOS/Android mobile app support using Capacitor
and adds a comprehensive opening training feature with LLM-powered
explanations.
## Mobile App Infrastructure
- Add Capacitor configuration for iOS/Android builds
- Create mobile build script that excludes API routes
- Update Next.js config for conditional static export
- Add layout components with generateStaticParams for static builds
- Generate 500+ static pages for offline mobile use
## Chess Engine Abstraction
- Create ChessEngine interface for pluggable implementations
- Add LocalEngine (GPL - uses stockfish.js in browser)
- Add RemoteEngine (proprietary - calls API server)
- Factory pattern selects engine based on environment
- Enables GPL compliance for web, proprietary for mobile
## Opening Training Feature
- Interactive opening repertoire training
- Move validation with engine-backed feedback
- LLM explanations using Gemini API
- Wikipedia integration for opening context
- Opening family grouping (e4, d4, c4, etc.)
- Session state management
- Real-time move feedback with evaluation
Components:
- OpeningSelector: Browse and select openings by family
- OpeningTrainer: Main training interface with chessboard
- MoveFeedback: Display move quality and LLM explanations
- WikipediaSummary: Show opening history and context
- ErrorBoundary: Graceful error handling
Services:
- openingLoader: Load and filter opening database
- engineService: Engine evaluation wrapper
- moveValidator: Validate moves against repertoire
- feedbackGenerator: Generate contextual feedback
- wikipediaService: Fetch and cache Wikipedia data
- sessionManager: Track training session state
## Wikipedia Integration
- Automatic Wikipedia article fetching for openings
- Client-side and server-side caching
- Sanitized summaries with proper formatting
- Link opening database to Wikipedia slugs
- API endpoints for on-demand fetching
## Docker Improvements
- Add entrypoint script for automatic data setup
- Fetch Wikipedia data on first container startup
- Generate opening move index automatically
- Remove generated data from git (public/openings/*.json, public/wikipedia/*.json)
- Add READMEs explaining data requirements
- Update .gitignore for generated files
## Dual Licensing Strategy
- Add LICENSING.md explaining dual licensing approach
- GPL-3.0 for web builds (includes Stockfish)
- Proprietary option for mobile builds (no GPL code)
- Single codebase, multiple licensing models
- Legal compliance documented
## API Endpoints
- POST /api/v1/llm/opening-explanation - Get LLM move explanations
- GET /api/v1/wikipedia/summary - Fetch Wikipedia summaries
## Type Updates
- Add openingTraining types
- Update Tutor component to use ChessEngine interface
- Add Gemini error handling types
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add comprehensive API documentation section
- Document Stockfish evaluation endpoint (POST /api/v1/stockfish)
- Document LLM chat endpoint (POST /api/v1/llm/chat)
- Document personalities endpoint (GET /api/v1/personalities)
- Include request/response examples and usage with curl
- Link to detailed API docs in docs/ folder
- No mention of specific use cases, just general API availability
- Replace window.confirm() with a custom styled modal dialog
- Match existing modal styling (header, content, footer pattern)
- Add Flag icon and AlertTriangle warning icon
- Use localized Cancel button text from common translations
- Improved UX with X close button and proper button styling
- Add window.confirm() before resigning to prevent accidental resignation
- Add 'resignConfirm' translation key in all 5 languages (EN, DE, FR, IT, PL)
- Messages are localized and warn that the action cannot be undone
- Fix page.test.tsx: Use stable mock router reference to prevent infinite loop
The useRouter mock was returning a new object on every render, causing
the useEffect with router dependency to re-run infinitely
- Update README to document resign button and analyze game features
- Add Polish language to multi-language support
- Document game export feature (PGN/FEN download)
- Add saved games and game continuation feature
- Document settings management and Clear All Data feature
- Add comprehensive User Experience Features section covering:
- Game management (save/resume/export)
- Customization options (languages, personalities, colors)
- Analysis tools (evaluation bar, opening explorer, position analysis)
- Modern interface features (responsive design, dark mode)
- Update typical game flow to include new features
- Improve feature descriptions with more detail
- Add download button to game history section with modal
- Support downloading game as PGN or current position as FEN
- Add translations for download feature in all 5 languages (EN, DE, FR, IT, PL)
- Fix bug where first moves were missing from history: now wait for evalP0 (pre-analysis) before allowing player moves
- This ensures all moves are properly tracked with evaluations and tactics detection
- Add 'Clear All Data' button in Danger Zone section
- Implement confirmation dialog before clearing
- Clear all localStorage and redirect to onboarding
- Add translations for clearAllData, clearAllDataConfirm, and clearAllDataDescription in all 5 languages (EN, DE, FR, IT, PL)
- Style with red theme to indicate destructive action
- Reorganize StartScreen: Start New Game button always visible at top
- Move unfinished games section below the start button
- Remove '2.' prefix from startGame translations (all languages)
- Update startNewGame translations to be button-appropriate
- Fix TypeScript errors: Update GameImportModal, GameAnalysisModal, and GameOverModal to use SupportedLanguage type instead of hardcoded language union
- Delete local branches: codex/add-polish-as-ui-language and codex/add-option-to-continue-game-from-position
Added comprehensive documentation for the debug mode feature including:
- Environment variable configuration (NEXT_PUBLIC_DEBUG)
- What debug mode shows (prompts, responses, timestamps)
- How to use the debug panel (copy, clear, expand)
- Why it's useful (troubleshooting, learning, bug reports)
- Example use cases (verify positions, check evaluations, etc.)
- Warning about production usage
This helps users understand how to enable and use debug mode to
troubleshoot AI behavior and understand how the system works.
When Stockfish detects a forced mate, it sets the mate field and resets
the score to 0. The previous code was showing '0 cp' which was misleading.
Changes:
- Format evaluation strings to show 'Mate in X' when mate is detected
- Only show delta (centipawn change) when neither position has a mate
- Update eval instruction to specifically mention mate situations
- Add explanation of mate notation in the prompt
Example output now:
- Pre-Eval: -326 cp
- Post-Eval: Mate in 3
(instead of showing '0 cp' which was confusing)
The previous implementation tried to use undo() on a Chess object created from
a FEN string, which has no move history. This resulted in all three FEN positions
being identical.
Now we use the game object's PGN (which contains full move history) and load it
into temporary Chess objects before undoing moves. This correctly generates:
- FEN before user's move (undo both computer and user moves)
- FEN after user's move (undo only computer move)
- FEN after computer's reply (current position)
This ensures the LLM receives accurate position context for each stage of the
move exchange.
- Return exact match first (e.g., King's Pawn Game for 1.e4 e5)
- Fill remaining slots with common continuations (Ruy Lopez, Italian Game, etc.)
- Look up to 4 moves deeper to find important opening variations
- Prioritize by depth (closer continuations first), then ECO root flag, then ECO code
- Avoid duplicate ECO families (e.g., don't show multiple C6x openings)
- Add isEcoRoot field to OpeningMetadata interface
- Add test script to verify opening lookup logic
Example: After 1.e4 e5, now returns:
1. King's Pawn Game (C20) - exact match
2. King's Gambit (C30) - continuation
3. King's Knight Opening (C40) - continuation
4. Ruy Lopez (C60) - continuation
5. Italian Game (C50) - continuation
This gives users context about what openings are still possible.
- Include FEN before user's move, after user's move, and current position
- Ensures LLM has complete position context to understand piece locations
- Fixes issue where LLM could 'forget where pieces are' during move analysis
- Add instruction to use FEN data for piece location understanding
- Change from getByText to getByLabelText for navigation buttons
- Buttons now use icon-only display with aria-labels for accessibility
- Fixes tests after UI simplification in previous commit
- Import ArrowLeft icon and useRouter from Next.js
- Add back button below header that navigates to home (/)
- Simplify Previous/Next buttons to show only chevron icons
- Remove text labels from navigation buttons for cleaner UI
- Add aria-labels for accessibility
- Consistent with play page navigation pattern
- Import lookupPossibleOpenings and buildMoveSequenceFromSteps
- Build move sequence from steps array up to currentIndex
- Lookup up to 5 possible openings per position
- Update prompt to include all possible openings
- Update UI to show single opening name or count of possibilities
- Consistent with play page opening detection
- Import ChatSession from @google/generative-ai
- Add chatSession state to maintain conversation history
- Initialize chat session with personality and language context
- Replace stateless generateContent() with chatSession.sendMessage()
- Add FEN before/after to move analysis prompts
- Chat history is preserved when navigating between moves
- LLM can now provide context-aware commentary across the game
- Change openingData from single to array in ChessGame.tsx
- Update all opening lookups to use lookupPossibleOpenings()
- Extract move sequence from PGN for opening lookup
- Update Tutor.tsx to accept array of openings
- Add smart opening instructions based on count:
- 1 opening: Confident identification with metadata
- Multiple: List possibilities, suggest general principles
- None: Focus on position without inventing names
- Pass up to 5 possible openings to LLM in all prompts
- Add lookupPossibleOpenings() to find multiple openings from move sequence
- Add extractMoveSequenceFromPGN() to parse PGN strings
- Add buildMoveSequenceFromSteps() for analysis page
- Import moveIndex.json for fast lookup
- Returns up to 5 possible openings per sequence
- Create buildOpeningIndex.js script to generate moveIndex.json
- Generate moveIndex.json with 12,377 unique move sequences
- Index maps move sequences to arrays of opening metadata
- Sorted by move length then alphabetically
- File size: 4.07 MB
- Enables fast lookup of multiple possible openings from move sequences
- Add FEN and opening data to all user question types (best move, hint, general)
- Prevents LLM from losing track of piece positions during conversation
- Ensures accurate responses based on actual board state
- Fixes issue where tutor would forget piece locations in general questions
- Fix TypeScript errors in analysis page with non-null assertions
- Fix Chessboard component API usage to use options prop
- Fix Analyze Game button placement to be always visible
This adds comprehensive tactical analysis to the chess tutor:
- Detects missed tactical opportunities (pins, forks, skewers, checks, etc.)
- Provides real-time feedback through the AI tutor
- Includes comprehensive test suite (20 tests)
- All tests passing (50/50)
- Add comprehensive test suite (20 tests) for tactic detection
- Fix pawn detection threshold bug (200 -> 100 centipawns)
- Add error handling to uciToSan for invalid moves
- Integrate tactical data into Tutor component for real-time feedback
- Pass missedTactics from ChessGame to Tutor via props
- Update LLM prompt to explain missed tactical opportunities
- Fix Jest configuration to handle react-markdown ESM issues
- All 50 tests passing
Bug Fixes:
- Fix turn validation: Players can now only move their own pieces
- Fix computer not moving when player moves too quickly (before evalP0 ready)
- Add safety check: Computer move triggered when chat messages sent
- Computer now always responds even if evalP0 is missing (only move history skipped)
New Personalities:
- Add 'Friendly Motivator' - encouraging, positive coach focused on building confidence
- Add 'Bloody Pirate' - theatrical trash-talker with Monkey Island style humor
Personality Reordering:
- Reordered from serious to playful:
1. Opening Professor (most serious)
2. Professional Coach
3. Friendly Motivator
4. Speedrun Super GM
5. Hype Streamer
6. Angry Prodigy
7. Drunk Russian GM
8. Bloody Pirate (most playful)
- Added section headers for clarity (Serious/Professional, Balanced/Entertaining, Spicy/Trash-talking)
Technical Details:
- ChessGame: Added checkAndMakeComputerMove() callback
- Tutor: Calls onCheckComputerMove after sending messages
- Both fixes ensure robust gameplay even with race conditions