- Remove unused `and` import from VisionRecorder.ts
- Remove unused `IncomingMessage` and `ws` imports from socket-server.ts
- Add `muted` attribute to video element in ProblemVideoPlayer
- Apply code formatting across vision and practice components
- Update documentation formatting in DEPLOYMENT.md and README
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add /api/health endpoint that checks database connectivity
- Set up blue-green deployment with two containers (abaci-blue, abaci-green)
- Add docker-compose.yaml with YAML anchors for DRY config
- Add generate-compose.sh to create blue/green compose files from main
- Update deploy.sh with NAS-specific fixes (scp -O, PATH for docker)
- Fix deploy.sh to not overwrite production .env by default
The blue-green setup allows zero-downtime deployments via compose-updater,
which watches separate compose files and restarts containers independently.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add runtime crop override system for live DevCropTool updates without page reload
- Fix SVG letterboxing in DevCropTool coordinate conversion (screenToSvg/svgToScreen)
- Hide all UI (nav, GameInfoPanel) during crop mode for unobstructed drawing
- Show debug overlay (leftover/crop rectangles) even when no custom crop defined
- Use full map bounds as implicit crop when no custom crop exists
- Ensure map always fits within leftover area (not under UI elements)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add known issue section about compose-updater not reliably detecting
updates. Logs show it decides "no need to restart" without performing
docker pull to check remote registry.
Investigation ongoing (2025-11-13). Manual pull+restart is most reliable
workaround.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Recover all changes from stash including:
- Linter/formatter updates across codebase
- Settings permission updates for git checkout
This commit captures the complete state of work that was
stashed during the previous session's git operations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes production error "Cannot read properties of undefined (reading 'carryBoxes')"
that occurred when users tried to adjust difficulty settings.
Root cause: displayRules was undefined for new users or users with old V1 config
in database. Difficulty adjustment buttons accessed displayRules.carryBoxes without
checking if displayRules existed first.
Changes:
- AdditionWorksheetClient: Initialize displayRules with defaults when missing
- ConfigPanel: Use null-coalescing operators instead of non-null assertions
- ConfigPanel: Add error logging when required fields are missing
- NEW: WorksheetErrorBoundary component to catch all errors in worksheet page
- page.tsx: Wrap client component with error boundary
This ensures users see helpful error messages instead of blank pages,
and never need to open the browser console to understand what went wrong.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>