Critical fixes for core functionality:
1. Fixed grapheme-aware text splitting (app/api/nodes/route.ts)
- Changed character-based substring to grapheme-ratio calculation
- Now properly handles emojis and multi-byte characters
- Prevents posts from exceeding 300 grapheme Bluesky limit
- Added comprehensive logging for debugging
2. Automatic UMAP coordinate calculation (app/api/nodes/route.ts)
- Triggers /api/calculate-graph automatically after node creation
- Only when user has 3+ nodes with embeddings (UMAP minimum)
- Non-blocking background process
- Eliminates need for manual "Calculate Graph" button
- Galaxy visualization ready on first visit
3. Simplified galaxy route (app/api/galaxy/route.ts)
- Removed auto-trigger logic (now handled on insertion)
- Simply returns existing coordinates
- More efficient, no redundant calculations
4. Added idempotency (app/api/calculate-graph/route.ts)
- Safe to call multiple times
- Returns early if all nodes already have coordinates
- Better logging for debugging
Implementation plans documented in /plans directory.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Increase logo size (48x48 desktop, 56x56 mobile) for better visibility
- Add logo as favicon
- Add logo to mobile header
- Move user menu to navigation bars (sidebar on desktop, bottom bar on mobile)
- Fix desktop chat layout - container structure prevents voice controls cutoff
- Fix mobile bottom bar - use icon-only ActionIcons instead of truncated text buttons
- Hide Create Node/New Conversation buttons on mobile to save header space
- Make fixed header and voice controls work properly with containers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace manual OAuth implementation with official @atproto/oauth-client-node library to properly support DPoP (Demonstrating Proof of Possession) authentication.
Changes:
- Added @atproto/oauth-client-node dependency
- Created OAuth state store (SurrealDB-backed) for CSRF protection
- Created OAuth session store (SurrealDB-backed) for token persistence
- Created OAuth client singleton with localhost exception for development
- Rewrote /api/auth/login to use client.authorize()
- Rewrote /api/auth/callback to use client.callback() with DPoP
- Updated lib/auth/session.ts with getAuthenticatedAgent() for ATproto API calls
- Updated db/schema.surql with oauth_state and oauth_session tables
- Added scripts/apply-schema.js for database schema management
- Created plans/oauth-dpop-implementation.md with detailed implementation plan
- Removed legacy lib/auth/atproto.ts and lib/auth/oauth-state.ts
- Updated .env to use localhost exception (removed BLUESKY_CLIENT_ID)
The OAuth client now handles:
- PKCE code generation and verification
- DPoP proof generation and signing
- Automatic token refresh
- Session persistence across server restarts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>