diff --git a/NEXT_PROMPT.md b/NEXT_PROMPT.md new file mode 100644 index 0000000..cebda75 --- /dev/null +++ b/NEXT_PROMPT.md @@ -0,0 +1,211 @@ +# 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: + +1. **Read these files first** (in order): + - `IMPLEMENTATION_PLAN.md` - Overall roadmap + - `IMPLEMENTATION.md` - Full implementation log (read ALL iterations) + - `AGENTS.md` in the root (../../AGENTS.md) - Code conventions + - `UNIFIED_API.md` in the root - Architecture reference + +2. **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) +- `i` to enter edit mode +- `Escape` to exit edit mode +- Visual feedback using existing CSS classes + +**Phase 40.3.2:** Edit mode rules +- Given cells (`.given` class) → Red flash, edit blocked +- Empty cells → Edit allowed +- User-entered cells (`.user-entered` class) → Edit allowed +- Vim motions blocked in edit mode + +**Visual Indicators:** +- Normal mode: `.active` class (blue glow) +- Edit mode: `.editing` class (yellow/amber pulsing glow) +- Invalid: `.invalid-move` class (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:** +1. User can type digits 1-9 +2. Digit gets written to the current cell +3. Board state updates (needs board integration) +4. Cell shows digit with `.user-entered` class +5. Stay in edit mode after entering digit (don't auto-exit) +6. 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** +- `useBoard` needs to track current board state (not just initial) +- Add `boardRef` with 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-entered` class + +### Key Considerations + +**Board Representation:** +- Board stored as 81-char string in `boardRef.current` +- '.' for empty, '1'-'9' for filled +- `initialBoardRef` keeps original puzzle (immutable) +- `solutionRef` keeps solution (for validation later) + +**Cell Updates:** +```typescript +// 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:** +```typescript +// 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-entered` class +- [ ] 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 `useCallback` or `useMemo`** (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 type` for 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 + +1. Read the files I mentioned at the top +2. Review latest git commits: `git log --oneline -10` +3. Confirm understanding of current state +4. Ask me if anything is unclear +5. 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` +```typescript +const [mode, setMode] = useState('normal'); +``` + +**Edit Mode Check:** In keyboard handler +```typescript +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! 🚀