Comprehensive prompt for Phase 40.3.3 (digit entry): - Context setup instructions - Complete summary of Phases 40.1, 40.2, 40.3 - Current architecture overview - Detailed implementation strategy for digit entry - Testing checklist - Agent rules and code conventions - Quick reference for current state This document allows seamless continuation in a new chat session with full context and clear next steps.
6.5 KiB
6.5 KiB
Next Session Prompt - Phase 40.3.3: Digit Entry
Context Setup
Hi! We're continuing the vim-sudoku unified API implementation. I need you to:
-
Read these files first (in order):
IMPLEMENTATION_PLAN.md- Overall roadmapIMPLEMENTATION.md- Full implementation log (read ALL iterations)AGENTS.mdin the root (../../AGENTS.md) - Code conventionsUNIFIED_API.mdin the root - Architecture reference
-
Review current state:
- We're in Phase 40.3.3 (digit entry for edit mode)
- Check latest git commits to see what's been done
- Current working directory:
/home/pastilhas/projects/vimazing/games/vim-sudoku
What We've Completed
Phase 40.1: Basic Cursor (✅ DONE)
- hjkl movement with bounds checking
- Blue cursor highlight
- Red flash on invalid moves
- All working perfectly
Phase 40.2: Complete Vim Motions (✅ DONE)
- Anchor moves: 0, ^, $, gg, G
- Count prefixes: 5j, 10l, etc.
- Repeat motion: .
- The 0 caveat solved:
if (key === '0' && countRef.current === '')→ anchor, else count - gg requires two presses (pendingGRef state)
- All tested and flawless
Phase 40.3: Edit Mode State Machine (✅ DONE)
Phase 40.3.1: Mode state (normal/edit)
ito enter edit modeEscapeto exit edit mode- Visual feedback using existing CSS classes
Phase 40.3.2: Edit mode rules
- Given cells (
.givenclass) → Red flash, edit blocked - Empty cells → Edit allowed
- User-entered cells (
.user-enteredclass) → Edit allowed - Vim motions blocked in edit mode
Visual Indicators:
- Normal mode:
.activeclass (blue glow) - Edit mode:
.editingclass (yellow/amber pulsing glow) - Invalid:
.invalid-moveclass (red flash 500ms)
Current Architecture
Key Files
src/
├── types.ts # Main type exports
├── useGame.ts # Orchestrator
├── useBoard/
│ ├── types.ts # BoardManager
│ ├── useBoard.ts # Board management
│ ├── SudokuGenerator.ts # Puzzle generation (class)
│ └── SudokuRenderer.ts # DOM rendering (class)
├── useCursor/
│ ├── types.ts # CursorManager, CursorMode, Motion
│ ├── useCursor.ts # Cursor + mode state
│ ├── useCursorRender.ts # Visual feedback
│ └── useVimMotions.ts # Vim motion processor
├── useGameStatus/
│ ├── types.ts # GameStatus, GameStatusManager
│ └── useGameStatus.ts # Game lifecycle
└── useScore/
├── types.ts # ScoreManager (mocked for now)
└── useScore.ts # Scoring (mocked for now)
Current State
- Board: 9x9 grid, puzzle generation working
- Cursor: Full vim motions + edit mode state machine
- Mode: 'normal' | 'edit' with proper validation
- Visual: All feedback working (blue/yellow/red)
Phase 40.3.3: Digit Entry (NEXT TASK)
Goal
Allow user to type digits 1-9 when in edit mode to fill cells.
Requirements
When in Edit Mode:
- User can type digits 1-9
- Digit gets written to the current cell
- Board state updates (needs board integration)
- Cell shows digit with
.user-enteredclass - Stay in edit mode after entering digit (don't auto-exit)
- Pressing Escape exits edit mode
When in Normal Mode: 7. Digits 0-9 are count prefixes (already working) 8. No digit entry allowed
Implementation Strategy
Step 1: Board State Management
useBoardneeds to track current board state (not just initial)- Add
boardRefwith current puzzle state - Add method:
setCell(row, col, value)to update board - Re-render board after cell update
Step 2: Update useCursor
- In edit mode, detect digit keys (1-9)
- Call board's
setCell()to update state - Trigger board re-render
- Stay in edit mode (don't exit)
Step 3: Integration
- Pass board methods to useCursor
- Ensure re-render updates cell classes correctly
- User-entered cells get
.user-enteredclass
Key Considerations
Board Representation:
- Board stored as 81-char string in
boardRef.current - '.' for empty, '1'-'9' for filled
initialBoardRefkeeps original puzzle (immutable)solutionRefkeeps solution (for validation later)
Cell Updates:
// In useBoard
function setCell(row: number, col: number, value: string): void {
const board = boardRef.current.split('');
const index = row * 9 + col;
board[index] = value;
boardRef.current = board.join('');
renderBoard(); // Re-render to show change
}
Passing to useCursor:
// In useGame
const cursor = useCursor(gameStatusManager, containerRef, board.setCell);
Testing Checklist
- Press i on empty cell → edit mode
- Type '5' → Cell shows 5
- Cell has
.user-enteredclass - Escape → normal mode
- Navigate to another cell → first cell still shows 5
- Press i on given cell → red flash (no edit)
- In normal mode, type '5j' → moves down 5 (count works)
Important Notes
Agent Rules (from AGENTS.md)
- No
useCallbackoruseMemo(React 19 compiler handles it) - No comments unless explicitly requested
- Type-first approach: Define types before implementation
- Follow existing patterns: Look at vim-maze and current code
- Update IMPLEMENTATION.md: After completing the phase
Code Conventions
- Plain functions, not wrapped in hooks
- Explicit
import typefor types - Refs for non-reactive state, useState for reactive
- Clean, minimal whitespace
- Descriptive names (no
data,item, etc.)
Git Workflow
- Small, focused commits
- Clear commit messages (what, why)
- Update IMPLEMENTATION.md with each phase
- Test builds before committing
How to Start
- Read the files I mentioned at the top
- Review latest git commits:
git log --oneline -10 - Confirm understanding of current state
- Ask me if anything is unclear
- Start implementing Phase 40.3.3 step by step
Let's implement digit entry slowly and carefully, testing at each step!
Quick Reference
Current Mode State: In useCursor.ts
const [mode, setMode] = useState<CursorMode>('normal');
Edit Mode Check: In keyboard handler
if (mode === 'edit') {
if (key === 'Escape') setMode('normal');
// Add digit handling here (1-9)
return;
}
Board String Format:
"52...8.4....7...4......6.....8.....3.9....8..1...2.......2....6...3....7..8...9."
// 81 characters: digits for givens, '.' for empty
Ready to continue! 🚀