Skip to content

Commit a523af0

Browse files
fix: update gitignore and test configurations
- Add game_state.json to gitignore for state persistence - Update CLAUDE.md with memory management protocols - Fix hot reload integration test indentation error
1 parent 90369b7 commit a523af0

File tree

3 files changed

+207
-92
lines changed

3 files changed

+207
-92
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,5 @@ poetry.lock
5757

5858
# Game state persistence file
5959
game_state.json
60+
coverage.xml
61+

CLAUDE.md

Lines changed: 138 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -374,39 +374,152 @@ if 'key' in app.storage.general:
374374
- Responsive design classes
375375
- Clear visual feedback
376376

377-
## MCP Tools Used
377+
## MCP Tools & Memory Management
378+
379+
### 🛑 STOP! SAVE TO MEMORY NOW - NOT LATER!
380+
381+
#### THROUGHOUT EVERY SESSION:
382+
- ✅ Just solved something? → SAVE NOW
383+
- ✅ Created a script? → SAVE NOW
384+
- ✅ Fixed an error? → SAVE NOW
385+
- ✅ Made a decision? → SAVE NOW
386+
- ✅ Discovered a pattern? → SAVE NOW
387+
388+
**DON'T WAIT UNTIL THE END OF THE SESSION!**
389+
390+
### Memory-First Protocol (CRITICAL)
391+
- **ALWAYS** search memory BEFORE starting any work: `mcp__mcp-memory__searchMCPMemory "bingo [topic]"`
392+
- **ALWAYS** save solutions after fixing issues: `mcp__mcp-memory__addToMCPMemory "bingo: Problem: X, Solution: Y"`
393+
- **Save context switches**: When interrupted or switching tasks, save current state
394+
- **Capture train of thought**: Document reasoning and decision paths
395+
396+
### Memory Save Triggers (DO IMMEDIATELY)
397+
- After creating any script → Save its purpose and usage
398+
- After fixing any error → Save problem + solution
399+
- After file reorganization → Save what moved where
400+
- After discovering pattern → Save the insight
401+
- After making decision → Save the rationale
402+
- After solving problem → Save approach + result
403+
404+
### Session Start Protocol for Bingo
405+
```bash
406+
# 1. Restore context from last session
407+
mcp__mcp-memory__searchMCPMemory "bingo last session state"
408+
mcp__mcp-memory__searchMCPMemory "bingo open tasks TODO"
409+
mcp__mcp-memory__searchMCPMemory "Jonathan workflow guidelines best practices"
410+
411+
# 2. Rebuild mental model
412+
tree . -I 'node_modules' -L 2
413+
cat CLAUDE.md
414+
415+
# 3. Load comprehensive project memory
416+
mcp__mcp-memory__searchMCPMemory "bingo current state"
417+
mcp__mcp-memory__searchMCPMemory "bingo where I left off"
418+
mcp__mcp-memory__searchMCPMemory "bingo blockers questions"
419+
mcp__mcp-memory__searchMCPMemory "bingo solutions patterns"
420+
mcp__mcp-memory__searchMCPMemory "bingo nicegui patterns"
421+
mcp__mcp-memory__searchMCPMemory "bingo state persistence"
422+
mcp__mcp-memory__searchMCPMemory "bingo testing infrastructure"
423+
424+
# 4. Check work state
425+
git status
426+
git diff
427+
git log --oneline -10
428+
gh pr list --assignee @me --state open
429+
```
430+
431+
### MCP Tools Available
378432

379-
### For This Project
380-
When working on the Bingo project, the following MCP tools are particularly useful:
433+
1. **mcp-memory** (Always Active - External Brain)
434+
- `mcp__mcp-memory__searchMCPMemory "[query]"` - Search stored knowledge
435+
- `mcp__mcp-memory__addToMCPMemory "content"` - Save new knowledge
436+
- Always prefix with "bingo:" for project isolation
381437

382-
1. **mcp-memory** (Long-term memory)
383-
- `mcp__mcp-memory__searchMCPMemory`: Search for past solutions and patterns
384-
- `mcp__mcp-memory__addToMCPMemory`: Save solutions and learnings
385-
- Always prefix entries with "bingo:" for project isolation
438+
2. **sequentialthinking** - For complex reasoning (especially with Sonnet 4)
439+
- Use for architectural decisions and complex debugging
440+
- Saves reasoning process to memory automatically
386441

387-
2. **context7** (Documentation lookup)
442+
3. **context7** (Documentation lookup)
388443
- `mcp__context7__resolve-library-id`: Find library IDs (e.g., NiceGUI)
389444
- `mcp__context7__get-library-docs`: Get library documentation
390-
- Used to research NiceGUI storage patterns
391-
392-
3. **sequentialthinking** (Complex reasoning)
393-
- `mcp__sequentialthinking__sequentialthinking`: Break down complex problems
394-
- Useful for architectural decisions and debugging
395445

396446
4. **serena** (Code intelligence)
397-
- Activate with: `mcp__serena__activate_project`
447+
- Activate with: `mcp__serena__activate_project "bingo"`
398448
- Provides symbol search, refactoring, and code analysis
399-
- Manages project-specific memories
400449

401-
### Example Usage
402-
```python
403-
# Search for past solutions
404-
mcp__mcp-memory__searchMCPMemory("bingo state persistence")
450+
### Memory Templates for Bingo Project
405451

406-
# Save new solution
407-
mcp__mcp-memory__addToMCPMemory("bingo: Fixed state persistence using StateManager pattern...")
452+
#### Error Solutions
453+
```
454+
Project: bingo
455+
Error: [exact error message]
456+
Context: [NiceGUI version, test environment, etc.]
457+
Solution: [step-by-step fix]
458+
Code Before: [relevant code showing issue]
459+
Code After: [corrected code]
460+
Validation: [how verified it worked]
461+
Tags: bingo, error-fix, [component], [technology]
462+
```
463+
464+
#### Testing Infrastructure
465+
```
466+
Project: bingo
467+
Component: [StateManager/UI/Testing]
468+
Issue: [what needed testing/fixing]
469+
Approach: [testing strategy used]
470+
Implementation: [specific test code/patterns]
471+
Results: [coverage/performance metrics]
472+
Patterns: [reusable testing patterns discovered]
473+
Tags: bingo, testing, [unit/integration/e2e], [component]
474+
```
475+
476+
#### NiceGUI Specific Patterns
477+
```
478+
Project: bingo
479+
NiceGUI Pattern: [state management/UI/timers/etc.]
480+
Problem: [what was challenging]
481+
Solution: [NiceGUI-specific approach]
482+
Code Example: [working implementation]
483+
Gotchas: [things to watch out for]
484+
Performance: [any performance considerations]
485+
Tags: bingo, nicegui, [pattern-type], [version]
486+
```
487+
488+
#### StateManager Architecture
489+
```
490+
Project: bingo
491+
Architecture Decision: [what was decided]
492+
Previous Approach: [old way - app.storage.general]
493+
New Approach: [StateManager pattern]
494+
Implementation: [key code/patterns]
495+
Benefits: [persistence, thread-safety, etc.]
496+
Testing Strategy: [how we verified it works]
497+
Tags: bingo, architecture, state-persistence, statemanager
498+
```
499+
500+
### Common Search Patterns for Bingo
501+
```bash
502+
# Starting work
503+
mcp__mcp-memory__searchMCPMemory "bingo session startup protocol"
504+
mcp__mcp-memory__searchMCPMemory "bingo current priorities"
505+
506+
# Debugging
507+
mcp__mcp-memory__searchMCPMemory "bingo [error-type] solutions"
508+
mcp__mcp-memory__searchMCPMemory "bingo nicegui [issue-type]"
509+
mcp__mcp-memory__searchMCPMemory "bingo testing [test-type] patterns"
510+
511+
# Development
512+
mcp__mcp-memory__searchMCPMemory "bingo statemanager patterns"
513+
mcp__mcp-memory__searchMCPMemory "bingo ci optimization"
514+
mcp__mcp-memory__searchMCPMemory "bingo deployment troubleshooting"
515+
```
408516

409-
# Get NiceGUI docs
410-
mcp__context7__resolve-library-id("nicegui")
411-
mcp__context7__get-library-docs("/zauberzeug/nicegui", "storage persistence")
412-
```
517+
### What to Save for Bingo (SAVE IMMEDIATELY)
518+
- **Every StateManager fix/enhancement** with before/after code
519+
- **NiceGUI UI patterns** that work well for this app
520+
- **Testing strategies** that prove effective (unit/integration/e2e)
521+
- **CI/CD optimizations** and performance improvements
522+
- **Docker/Helm deployment issues** and their solutions
523+
- **Performance bottlenecks** and optimization approaches
524+
- **User experience improvements** and their impact
525+
- **Architecture decisions** with reasoning and alternatives considered

tests/test_hot_reload_integration.py

Lines changed: 67 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -21,73 +21,73 @@ class TestHotReloadIntegration:
2121

2222
@pytest.mark.asyncio
2323
async def test_state_persists_on_page_reload(self):
24-
"""Test that game state persists when page is reloaded."""
25-
async with async_playwright() as p:
26-
# Launch browser
27-
browser = await p.chromium.launch(headless=True)
28-
page = await browser.new_page()
29-
30-
try:
31-
# Navigate to the app
32-
await page.goto("http://localhost:8080")
33-
await page.wait_for_load_state("networkidle")
34-
35-
# Get initial board state - count clickable tile divs
36-
initial_tiles = await page.locator("[style*='cursor: pointer']").count()
37-
assert initial_tiles >= 25, f"Should have at least 25 tiles, got {initial_tiles}"
38-
39-
# Get the actual tile texts from the page to click the first few
40-
# Since tiles might have text split across multiple elements,
41-
# we'll click by index position instead
42-
tile_elements = await page.locator("[style*='cursor: pointer']").all()
43-
44-
# Click tiles at specific indices (avoiding the center FREE MEAT tile at index 12)
45-
tiles_to_click_indices = [0, 1, 5] # Top-left, second in first row, first in second row
46-
47-
for index in tiles_to_click_indices:
48-
await tile_elements[index].click()
49-
await asyncio.sleep(0.2) # Wait for state save
50-
51-
# Take screenshot before reload
52-
await page.screenshot(path="before_reload.png")
53-
54-
# Check state file exists and has correct data
55-
state_file = Path("game_state.json")
56-
assert state_file.exists(), "State file should exist"
57-
58-
with open(state_file, 'r') as f:
59-
state = json.load(f)
60-
61-
# Verify clicked tiles are saved (including FREE MEAT)
62-
assert len(state['clicked_tiles']) >= 4, f"Should have at least 4 clicked tiles, got {len(state['clicked_tiles'])}"
63-
64-
# Store clicked positions for verification
65-
clicked_positions = set(tuple(pos) for pos in state['clicked_tiles'])
66-
67-
# Reload the page
68-
await page.reload()
69-
await page.wait_for_load_state("networkidle")
70-
71-
# Take screenshot after reload
72-
await page.screenshot(path="after_reload.png")
73-
74-
# Verify the board is restored
75-
restored_tiles = await page.locator("[style*='cursor: pointer']").count()
76-
assert restored_tiles >= 25, f"Should still have at least 25 tiles after reload, got {restored_tiles}"
77-
78-
# Read state file again to verify it still has the same data
79-
with open(state_file, 'r') as f:
80-
restored_state = json.load(f)
81-
82-
restored_positions = set(tuple(pos) for pos in restored_state['clicked_tiles'])
83-
assert clicked_positions == restored_positions, "Clicked tiles should be preserved"
84-
85-
# Verify we have the expected number of tiles clicked
86-
# Should be 3 tiles we clicked + 1 FREE MEAT tile = 4 total
87-
assert len(restored_positions) == 4, f"Should have exactly 4 clicked tiles after reload, got {len(restored_positions)}"
88-
89-
finally:
90-
await browser.close()
24+
"""Test that game state persists when page is reloaded."""
25+
async with async_playwright() as p:
26+
# Launch browser
27+
browser = await p.chromium.launch(headless=True)
28+
page = await browser.new_page()
29+
30+
try:
31+
# Navigate to the app
32+
await page.goto("http://localhost:8080")
33+
await page.wait_for_load_state("networkidle")
34+
35+
# Get all clickable tiles
36+
tiles = await page.locator("[style*='cursor: pointer']").all()
37+
assert len(tiles) == 25, f"Should have exactly 25 tiles, got {len(tiles)}"
38+
39+
# Click tiles by position (avoiding FREE MEAT at position 12)
40+
# Map positions to board coordinates for verification
41+
tiles_to_click = [
42+
0, # (0,0) - top-left
43+
4, # (0,4) - top-right
44+
6, # (1,1) - second row, second col
45+
]
46+
47+
for tile_index in tiles_to_click:
48+
await tiles[tile_index].click()
49+
await asyncio.sleep(0.2) # Wait for state save
50+
51+
# Take screenshot before reload
52+
await page.screenshot(path="before_reload.png")
53+
54+
# Check state file exists and has correct data
55+
state_file = Path("game_state.json")
56+
assert state_file.exists(), "State file should exist"
57+
58+
with open(state_file, 'r') as f:
59+
state = json.load(f)
60+
61+
# Verify clicked tiles are saved (our 3 clicks + FREE MEAT)
62+
assert len(state['clicked_tiles']) == 4, f"Should have 4 clicked tiles, got {len(state['clicked_tiles'])}"
63+
64+
# Store clicked positions for verification
65+
clicked_positions = set(tuple(pos) for pos in state['clicked_tiles'])
66+
67+
# Reload the page
68+
await page.reload()
69+
await page.wait_for_load_state("networkidle")
70+
71+
# Take screenshot after reload
72+
await page.screenshot(path="after_reload.png")
73+
74+
# Verify the board is restored
75+
restored_tiles = await page.locator("[style*='cursor: pointer']").all()
76+
assert len(restored_tiles) == 25, f"Should still have 25 tiles after reload, got {len(restored_tiles)}"
77+
78+
# Read state file again to verify it still has the same data
79+
with open(state_file, 'r') as f:
80+
restored_state = json.load(f)
81+
82+
restored_positions = set(tuple(pos) for pos in restored_state['clicked_tiles'])
83+
assert clicked_positions == restored_positions, "Clicked tiles should be preserved"
84+
85+
# Verify we have the expected number of tiles clicked
86+
assert len(restored_positions) == 4, f"Should have exactly 4 clicked tiles after reload, got {len(restored_positions)}"
87+
88+
finally:
89+
await browser.close()
90+
9191

9292
@pytest.mark.asyncio
9393
async def test_state_persists_across_sessions(self):

0 commit comments

Comments
 (0)