Commit Graph

17 Commits

Author SHA1 Message Date
Thomas Hallock e72018ae44 fix(server): skip migrations on LiteFS replicas
LiteFS replicas are read-only, so migrations fail with "read only replica"
error. Check LITEFS_CANDIDATE env var and skip migrations on replicas.
The primary (pod-0) will run migrations and replicate the changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 14:31:19 -06:00
Thomas Hallock e2816ae88b feat(vision): improve remote camera calibration UX
- Add dual-stream calibration: phone sends both raw and cropped preview
  frames during calibration so users can see what practice will look like
- Add "Adjust" button to modify existing manual calibration without
  resetting to auto-detection first
- Hide calibration quad editor overlay when not in calibration mode
- Fix rotation buttons to update cropped preview immediately
- Add rate limiting (10fps) for cropped preview frames during calibration
- Fix multiple bugs preventing dual-stream mode from working:
  - Don't mark calibration as complete during preview mode
  - Don't stop detection loop when receiving preview calibration
  - Sync refs properly in frame mode change effects

Also includes accumulated formatting and cleanup changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 10:51:59 -06:00
Thomas Hallock eaa1d11c65 chore: formatting and training data updates
- Apply code formatting across codebase
- Add new vision training boundary frames
- Update model configurations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 06:38:57 -06:00
Thomas Hallock be4b587520 chore: format codebase with Biome
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 16:34:42 -06:00
Thomas Hallock 73a8314ed9 refactor(worksheet-parsing): centralize state with context + reducer
Major refactoring of worksheet parsing to use centralized state management:

New architecture:
- WorksheetParsingContext: React context provider for parsing state
- state-machine.ts: Typed reducer with actions for streaming lifecycle
- sse-parser.ts: Shared SSE parsing utility for OpenAI Responses API
- usePartialJsonParser.ts: Progressive JSON extraction during streaming

Streaming UI improvements:
- ParsingProgressOverlay: Dark overlay on photo tile during parsing
- ParsingProgressPanel: Collapsible reasoning text panel
- ProgressiveHighlightOverlay: Problem boxes light up as LLM parses
- New streaming API routes: /parse/stream and /parse-selected/stream

Bug fixes during testing:
- Fix TypeScript error: cast event.response for id access in sse-parser
- Fix reparse reasoning display: preserve "processing" status for reparse
- Fix concurrent parsing: revert previous attachment status when switching
- Fix problem count: track dispatched problems to prevent duplicates

Components updated to use context:
- SummaryClient: Wrapped with WorksheetParsingProvider
- OfflineWorkSection: Uses context instead of local streaming state
- PhotoViewerEditor: Uses context for coordinated parsing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 21:40:36 -06:00
Thomas Hallock 518d9c6cb9 feat(worksheet-parsing): add cancel button for parsing and re-parsing
- Add cancel button to gallery thumbnails when parsing in progress
- Add cancel button to fullscreen PhotoViewerEditor when parsing
- Add cancel button for re-parsing in progress (fullscreen view)
- Track reparsingPhotoId to show correct status per-photo in both views
- Gallery shows "Re-parsing..." badge on specific photo being re-parsed
- DELETE endpoint resets parsing status for immediate retry

Also includes codebase-wide formatting from biome.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 12:24:28 -06:00
Thomas Hallock 111e934129 feat(worksheet-parsing): add bulk exclude/restore and improve approve flow
- Remove per-problem Exclude/Restore buttons from EditableProblemRow
- Add bulk "Exclude Selected" and "Restore Selected" buttons to selection toolbar
- Add toast notifications for approve success/failure
- Close viewer and refresh page after successful approve to show updated session
- Fix mutation to properly await res.json() before returning

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 21:39:43 -06:00
Thomas Hallock 98a22699db debug: add error handling for socket-server require to see actual failure 2025-11-20 05:51:24 -06:00
Thomas Hallock b36df3a40c fix(worksheets): ten-frames not rendering in mastery mode
Fixed two critical bugs preventing ten-frames from rendering:

1. **Mastery mode not handled** (typstGenerator.ts:61)
   - Code only checked for 'smart' | 'manual' modes
   - Mastery mode fell into manual path, tried to use boolean flags that don't exist
   - Resulted in all display options being `undefined`
   - Fix: Check for both 'smart' OR 'mastery' modes (both use displayRules)

2. **Typst array membership syntax** (already fixed in previous commit)
   - Used `(i in array)` which doesn't work in Typst
   - Changed to `array.contains(i)`

Added comprehensive unit tests (tenFrames.test.ts):
- Problem analysis tests (regrouping detection)
- Display rule evaluation tests
- Full Typst template generation tests
- Mastery mode specific tests
- All 14 tests now passing

Added debug logging to trace display rules resolution:
- displayRules.ts: Shows rule evaluation per problem
- typstGenerator.ts: Shows enriched problems and Typst data
- Helps diagnose future issues

The issue was that mastery mode (which uses displayRules like smart mode)
was being treated as manual mode (which uses boolean flags), resulting in
undefined display options.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 10:06:27 -06:00
Thomas Hallock cd75df7221 chore: restore stashed work from previous session
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>
2025-11-08 14:59:40 -06:00
Thomas Hallock aafb64f3e3 fix(rithmomachia): correct makeMove parameter types for capture handling
- Fix TypeScript error: pass undefined for pyramidFace parameter
- Properly structure capture data as 5th parameter
- Add target piece lookup for capture relations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 11:02:47 -05:00
Thomas Hallock d568955d6a feat(arcade): add yjs-demo collaborative game and Yjs persistence layer
- Add yjs-demo arcade game with collaborative state management
- Add Yjs persistence layer for real-time sync
- Update socket server with Yjs support
- Update Rithmomachia game component
- Add yjs type definitions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 09:46:20 -05:00
Thomas Hallock f9af0f169e chore: biome formatting fixes 2025-10-11 07:17:38 -05:00
Thomas Hallock bda5bc6c0e fix: prevent database imports from being bundled into client code
**Problem:**
- player-ownership.ts imported drizzle-orm and @/db at top level
- When RoomMemoryPairsProvider imported client-safe utilities, Webpack bundled ALL imports including database code
- This caused hydration error: "The 'original' argument must be of type Function"
- Node.js util.promisify was being called in browser context

**Solution:**
1. Created player-ownership.client.ts with ONLY client-safe utilities
   - No database imports
   - Safe to import from 'use client' components
   - Contains: buildPlayerOwnershipFromRoomData(), buildPlayerMetadata(), helper functions

2. Updated player-ownership.ts to re-export client utilities and add server-only functions
   - Re-exports everything from .client.ts
   - Adds buildPlayerOwnershipMap() (async, database-backed)
   - Safe to import from server components/API routes

3. Updated RoomMemoryPairsProvider to import from .client.ts

**Result:**
- No more hydration errors on /arcade/room
- Client bundle doesn't include database code
- Server code can still use both client and server utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 11:40:46 -05:00
Thomas Hallock 2b7ff237cc fix: correct TypeScript build configuration to prevent .js pollution in src/
**Problem:**
- TypeScript was compiling .js files directly into src/ alongside .ts files
- This broke the app and polluted source control with build artifacts

**Solution:**
1. Moved socket-server.ts from root to src/socket-server.ts
   - Updated imports to remove './src/' prefix (now './lib/...')
2. Updated tsconfig.server.json:
   - Added rootDir: "./src" to ensure clean dist/ structure
   - Updated include path from "socket-server.ts" to "src/socket-server.ts"
3. server.js already correctly requires from ./dist/*

**Result:**
- TypeScript now compiles to dist/ with clean structure:
  - src/socket-server.ts → dist/socket-server.js ✓
  - src/db/index.ts → dist/db/index.js ✓
  - No dist/src/ subdirectory ✓
  - No .js files created in src/ ✓
- Dev server starts successfully
- Build artifacts properly separated from source code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 11:18:02 -05:00
Thomas Hallock 83b9a4d976 fix: compile TypeScript server files to JavaScript for production
- Add tsconfig.server.json to compile server-side TypeScript
- Install tsc-alias to resolve path aliases (@/*) in compiled JS
- Update build script to run tsc + tsc-alias before Next.js build
- Update dev script to compile server files before starting
- Remove tsx runtime dependencies from server.js
- Add compiled JS files for socket-server, db, and arcade modules

This enables production builds to run with pure Node.js without
requiring tsx or ts-node at runtime, as required for Docker deployment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 07:55:18 -05:00
Thomas Hallock 22541df99f fix: use UUID player IDs in session creation fallback
- Changed CreateSessionOptions.activePlayers from number[] to string[]
- Updated socket-server.ts fallback from [1] to [data.userId]
- Added debug logging to validateFlipCard to diagnose turn validation issues

This ensures that when a session is created without explicit activePlayers,
it uses the actual UUID of the requesting player instead of the numeric value 1.
2025-10-06 13:04:33 -05:00