Commit Graph

69 Commits

Author SHA1 Message Date
57d5405c41 feat: Move theme toggle to profile dropdown with icon-only SegmentedControl
Changes:
- Moved theme toggle from separate DesktopSidebar component into UserMenu dropdown
- Replaced simple light/dark toggle with SegmentedControl offering three options:
  - Light (sun icon)
  - Dark (moon icon)
  - System/Auto (desktop icon)
- Uses icon-only labels for compact display in dropdown menu
- Defaults to 'auto' mode (respects system preference) as configured in layout.tsx
- Removed standalone ThemeToggle component from DesktopSidebar

Benefits:
- Cleaner navigation UI with one less separate control
- Better UX with system preference option
- More compact dropdown menu layout

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 01:26:33 +00:00
e91886a1ce fix: Link creation broken due to ID vs URI mismatch
Fixed bug where links between nodes weren't being created.

Root Cause:
- UI sends node IDs in links array (e.g., "node:xxxxx")
- API query expected ATProto URIs (e.g., "at://did:plc:.../app.bsky.feed.post/...")
- Query: WHERE atp_uri IN $links never matched
- Result: Zero links created in database

Fix:
- Changed query to: WHERE id IN $links
- Now correctly matches node IDs from UI
- Added logging to track link creation
- Updated comments to clarify expected format

Impact:
Links selected in the edit UI will now be properly created and
visible as connections in the 3D thought galaxy visualization.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 01:17:54 +00:00
0c4934cf70 fix: Recalculate ALL nodes for UMAP instead of incremental
Fixed critical bug where nodes 4+ wouldn't get 3D coordinates because
UMAP manifold learning requires seeing the complete dataset together.

Root Cause:
- Previous code only calculated coords for nodes WHERE coords_3d = NONE
- When creating nodes 4-5, only those 2 nodes were passed to UMAP
- UMAP requires minimum 3 points to define a manifold
- Result: "Not enough nodes to map (2/3)" error

Why Full Recalculation is Necessary:
- UMAP is a non-linear manifold learning algorithm
- It creates relative coordinates, not absolute positions
- Each UMAP run produces different coordinate systems
- No "fixed origin" exists - positions are only meaningful relative to each other
- Adding new data changes the manifold structure

Changes:
- Updated /app/api/calculate-graph/route.ts:
  * Removed "AND coords_3d = NONE" filter from query
  * Now fetches ALL nodes with embeddings every time
  * Recalculates entire graph when triggered
  * Updated comments and logging to reflect full recalculation

- Created docs/umap-recalculation-strategy.md:
  * Comprehensive explanation of UMAP manifold learning
  * Why incremental calculation doesn't work
  * Trade-offs of full recalculation approach
  * Performance characteristics (<100 nodes: <1.5s)
  * Future optimization strategies for scale

- Added scripts/recalculate-all-coords.ts:
  * Emergency script to manually fix production database
  * Successfully recalculated all 5 nodes in production

UX Impact:
The thought galaxy now "reorganizes" when adding new nodes - existing
nodes will shift slightly. This is actually a feature, showing the
evolving structure of your knowledge graph as it grows.

Performance:
Full recalculation is O(n²) but acceptable for <100 nodes:
- 3 nodes: ~50ms
- 10 nodes: ~200ms
- 50 nodes: ~800ms
- 100 nodes: ~1.5s

For Ponderants MVP, this is perfectly acceptable. Future optimizations
documented if we reach 1000+ nodes per user.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 01:15:27 +00:00
d656b06113 feat: Make galaxy viewable without login requirement
Implemented public galaxy viewing feature that allows unauthenticated
users to view public thought galaxies via the ?user={did} parameter,
while maintaining privacy controls for node-level visibility.

Changes:
- Updated /api/galaxy/route.ts to support public access:
  * Accept ?user={did} query parameter for viewing specific user's galaxy
  * Show all nodes (including private) for authenticated user viewing own galaxy
  * Filter to only public nodes when viewing someone else's galaxy
  * Return empty state with helpful message when not authenticated
  * Filter links to only show connections between visible nodes

- Added is_public field to database schema:
  * Updated db/schema.surql with DEFAULT true (public by default)
  * Created migration script scripts/add-is-public-field.ts
  * Aligns with ATproto's public-by-default philosophy

- Enhanced ThoughtGalaxy component:
  * Support viewing galaxies via ?user={did} parameter
  * Display user info banner when viewing public galaxy
  * Show appropriate empty state messages based on context
  * Refetch data when user parameter changes

- Created comprehensive Magnitude tests:
  * Test public galaxy viewing without authentication
  * Verify private nodes are hidden from public view
  * Test own galaxy access requires authentication
  * Validate invalid user DID handling
  * Test user info display and navigation between galaxies

- Documented implementation plan in plans/10-public-galaxy-viewing.md

This implements the "public by default" model while allowing future
node-level privacy controls. All canonical data remains on the user's
ATproto PDS, with SurrealDB serving as a high-performance cache.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 00:36:16 +00:00
aa60098690 test: Add comprehensive theme switching tests
Added extensive Magnitude tests for light/dark mode functionality:
- Theme toggle switches between modes
- Light mode color verification
- Dark mode color verification
- Theme persistence across page refreshes
- Theme affects all UI components uniformly
- Theme toggle icon updates correctly

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 00:26:43 +00:00
d7f5988a4f refactor: Use Mantine CSS variables and modules for theme styling
Replaced all hardcoded colors and JS template literal styling with Mantine's
canonical approach using CSS modules and CSS variables. This ensures colors
transition programmatically without JS interpolation.

- Updated globals.css to use data-mantine-color-scheme selectors
- Created CSS modules for all navigation components and chat page
- Removed useComputedColorScheme/useMantineTheme hooks where not needed
- Fixed body background to properly adapt to light/dark mode
- All borders, backgrounds, and colors now use CSS variables
- Maintained full theme support across all components

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 22:54:15 +00:00
68728b2987 fix: Make ChatInterface theme-aware for light mode support
Updated ChatInterface to use dynamic colors based on color scheme:
- Added useComputedColorScheme hook
- Chat message bubbles now use gray.1/gray.0 in light mode
- Chat message bubbles use dark.6/dark.7 in dark mode
- User messages vs AI messages have different shades in both modes

This fixes the issue where chat messages had hardcoded dark backgrounds
even when the app was in light mode.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 22:24:21 +00:00
9bf16fefaf feat: Add dark/light mode theme switching with dynamic favicons
Implemented comprehensive dark/light mode support throughout the app:

- Added ColorSchemeScript to layout for auto-detection of system preference
- Updated MantineProvider to use 'auto' color scheme (respects system)
- Updated theme.ts with dynamic Paper component styles based on color scheme
- Created ThemeToggle component with sun/moon icons
- Added toggle to desktop sidebar navigation
- Created theme-specific favicons (favicon-light.svg, favicon-dark.svg)
- Made ThoughtGalaxy 3D visualization theme-aware:
  - Dynamic node colors based on theme
  - Theme-aware lighting intensity
  - Theme-aware link colors
  - Theme-aware text labels
- Added comprehensive Playwright tests for theme functionality
- Theme preference persists via localStorage

Tested manually with Playwright MCP:
-  Theme toggle switches between light and dark modes
-  Theme persists across page reloads
-  Both modes render correctly with appropriate colors
-  Icons change based on current theme (sun/moon)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 22:04:26 +00:00
482ec9fff8 fix: Prevent state machine from navigating before URL initialization
Fixed a race condition where the state machine would navigate to /chat
before initializing from the URL, causing direct navigation to /galaxy
URLs to redirect.

**The Problem:**
1. Component mounts, state machine starts in 'convo' state (default)
2. State-to-URL effect fires: "state is convo → navigate to /chat"
3. URL-to-state initialization fires: "we're on /galaxy → NAVIGATE_TO_GALAXY"
4. State transitions to 'galaxy'
5. State-to-URL effect fires again: "state is galaxy → navigate to /galaxy"

This caused a brief redirect to /chat before settling on /galaxy.

**The Solution:**
- Don't mark as initialized immediately after sending the initial event
- Add a second effect that watches for state to match the URL
- Only mark as initialized once state matches the target state for the URL
- This prevents the state-to-URL effect from running before initialization

**Changes:**
- Modified URL-to-state initialization to not mark as initialized immediately
- Added new effect to mark as initialized once state matches URL target
- Added console log: "State initialized from URL, marking as ready"

**Testing:**
Verified with Playwright MCP that navigating directly to /galaxy?node=xxx
no longer redirects to /chat.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 21:49:42 +00:00
cde66978cd fix: Fix galaxy node clicking and navigation bugs
This commit fixes two critical bugs in the galaxy navigation:

**Bug #1: Direct node URLs redirected to /chat**
- Updated AppStateMachine to recognize /galaxy/* paths (including query params) as galaxy state
- Changed line 55 from `pathname === '/galaxy'` to `pathname === '/galaxy' || pathname.startsWith('/galaxy/')`
- Changed line 89 to compare pathname instead of lastNavigatedPathRef to preserve query params

**Bug #2: Modal closed when clicking nodes**
- Refactored ThoughtGalaxy to use URL query params (?node=xxx) instead of route params (/galaxy/node:xxx)
- This prevents component unmounting when switching between nodes
- Deleted app/galaxy/[node-id]/page.tsx (no longer needed)
- Updated app/galaxy/page.tsx with documentation comment
- Modified ThoughtGalaxy to:
  - Use useSearchParams() hook
  - Get selectedNodeId from query params
  - Update URL with query params on node click (doesn't cause remount)
  - Clear query params when modal closes

**Testing:**
- Verified manually with Playwright MCP that /galaxy?node=xxx preserves query params
- Verified state machine correctly recognizes galaxy state
- Created comprehensive Playwright test suite in tests/playwright/galaxy.spec.ts

**Files changed:**
- components/AppStateMachine.tsx: Fixed state machine to handle /galaxy/* paths and preserve query params
- components/ThoughtGalaxy.tsx: Refactored to use query params instead of route params
- app/galaxy/page.tsx: Added documentation
- app/galaxy/[node-id]/page.tsx: Deleted (replaced with query param approach)
- tests/playwright/galaxy.spec.ts: Added comprehensive test suite

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 21:28:07 +00:00
baddf4f09d chore: Remove backup and old page files
Deleted unused backup files:
- app/chat/page.tsx.backup
- app/chat/page.tsx.old

Keeps codebase clean and reduces confusion. Current page.tsx is the
canonical implementation.

Resolves plan: 07-delete-backup-files.md

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 21:15:47 +00:00
4967ce3cd1 feat: Add Playwright testing scaffolding infrastructure
Implements complete Playwright testing infrastructure for manual MCP testing and
as foundation for Magnitude tests.

Created:
- playwright.config.ts - Main configuration with setup project
- tests/playwright/auth.setup.ts - Authentication setup (placeholder)
- tests/playwright/fixtures.ts - Custom fixtures for authenticated/page contexts
- tests/playwright/helpers/chat.ts - Chat interaction helpers
- tests/playwright/helpers/galaxy.ts - Galaxy visualization helpers
- tests/playwright/helpers/node.ts - Node creation/management helpers
- tests/playwright/smoke.spec.ts - Basic smoke tests
- .env.test - Environment variables template

Updated:
- package.json - Added test:playwright scripts
- .gitignore - Added tests/playwright/.auth/ exclusion

Ready for manual Playwright MCP testing and Magnitude test creation.

Resolves plan: 01-playwright-scaffolding.md

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 21:14:35 +00:00
b96159ec02 docs: Add comprehensive implementation plans for all todo items
Created detailed markdown plans for all items in todo.md:

1. 01-playwright-scaffolding.md - Base Playwright infrastructure
2. 02-magnitude-tests-comprehensive.md - Complete test coverage
3. 03-stream-ai-to-deepgram-tts.md - TTS latency optimization
4. 04-fix-galaxy-node-clicking.md - Galaxy navigation bugs
5. 05-dark-light-mode-theme.md - Dark/light mode with dynamic favicons
6. 06-fix-double-border-desktop.md - UI polish
7. 07-delete-backup-files.md - Code cleanup
8. 08-ai-transition-to-edit.md - Intelligent node creation flow
9. 09-umap-minimum-nodes-analysis.md - Technical analysis

Each plan includes:
- Detailed problem analysis
- Proposed solutions with code examples
- Manual Playwright MCP testing strategy
- Magnitude test specifications
- Implementation steps
- Success criteria

Ready to implement in sequence.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 21:07:42 +00:00
346326e31f fix: Add migration script to fix coords_3d field in production
Created a migration script that removes and redefines the coords_3d field
to make it optional (TYPE option<array<number>>) in production database.

This fixes the issue where coords_3d was required but should be NONE
until UMAP coordinates are calculated.

Migration successfully executed on production database.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 20:42:15 +00:00
6cce6403fb fix: Sync pnpm-lock.yaml with package.json React Three Fiber versions
Updates lockfile to match the specific versions of @react-three/drei,
@react-three/fiber, and three specified in package.json. This resolves
the ERR_PNPM_OUTDATED_LOCKFILE error during Vercel deployment.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 20:27:53 +00:00
d8a975122f feat: Fix grapheme splitting and add automatic UMAP calculation
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>
2025-11-09 20:19:20 +00:00
6bd0fe65e2 debug: Add logging for grapheme limit errors
Added detailed logging when posts exceed 300 grapheme limit to help
debug the discrepancy between calculated and actual grapheme counts.

Logs now include:
- Post content preview
- Detail URL being used
- Link suffix grapheme count

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 19:50:43 +00:00
12d26c9d14 fix: Make coords_3d optional in schema to support UMAP workflow
The proper architecture is:
1. Nodes are created with coords_3d = NONE
2. User manually triggers /api/calculate-graph
3. UMAP calculates 3D coordinates from embeddings
4. Coordinates are updated in batch

Changed coords_3d TYPE from array<number> to option<array<number>>
to allow NONE values. This fixes production error:
"Found NONE for field coords_3d but expected array<number>"

Schema has been deployed to production.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 19:48:56 +00:00
49b12a2933 fix: Provide coords_3d field required by schema
Production SurrealDB schema requires coords_3d to be array<number>,
which means it cannot be NONE despite the ASSERT allowing it.
TYPE enforcement happens before ASSERT validation.

This fixes the production error:
"Found NONE for field coords_3d but expected array<number>"

New nodes are initialized at origin [0, 0, 0] for galaxy visualization.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 19:46:29 +00:00
1e423a9bb5 fix: Use RecordId for node creation and pin React Three Fiber versions
- Fix node creation to use RecordId object instead of string format
- This prevents creation of schemaless tables instead of proper node records
- Pin @react-three/fiber and @react-three/drei to specific versions
- Fix semver validation errors with "latest" package versions

Verified working locally with successful node creation in proper table.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 19:26:49 +00:00
3119d27c0d fix: Correct SurrealDB record creation to use table+ID array format
The SurrealDB JavaScript client was interpreting "node:uuid" as a table name
instead of a record ID, creating separate schemaless tables for each node.

Changed from:
  db.create("node:uuid", data)

To:
  db.create(['node', 'uuid'], data)

This ensures nodes are created as records in the main 'node' table with the
specified UUID, not as separate tables.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 19:11:09 +00:00
d0978f5f7f fix: Update embedding dimensions to 3072 and add Vercel Analytics
- Updated GOOGLE_EMBEDDING_DIMENSIONS to 3072 to match gemini-embedding-001 output
- Updated database schema embedding index from 768 to 3072 dimensions
- Recreated production database index with correct dimensions
- Added @vercel/analytics package for production analytics
- Added Analytics component to root layout

This fixes the galaxy visualization issue caused by dimension mismatch between
the embedding model output (3072) and the database index (768).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 19:00:37 +00:00
e4bd3282fd chore: Clean up unused files and add .claude settings to gitignore
- Add .claude/settings.local.json to gitignore (user-specific settings)
- Remove unused history.txt (SurrealDB query history)
- Remove unused .env.test.example (testing template no longer used)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:37:48 +00:00
8b40350d56 chore: Add .playwright-mcp to .gitignore
- Exclude Playwright MCP screenshot cache from version control

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:30:39 +00:00
e036698e70 fix: Initialize atp_uri and atp_cid variables for TypeScript strict mode
- Initialize atp_uri and atp_cid with empty strings to satisfy TypeScript strict mode
- Resolves "variable used before being assigned" compilation error

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:29:42 +00:00
34106f9301 fix: Resolve TypeScript error with atp_cid used before assignment
- Added rootPost variable to store first post's URI and CID
- Fixed thread reply references to use rootPost instead of atp_cid before it's assigned
- Resolves production build TypeScript error

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:28:23 +00:00
9aa9035d78 fix: Correct OAuth localhost/127.0.0.1 config and fix grapheme counting for Bluesky posts
- Fixed OAuth client configuration to properly use localhost for client_id and 127.0.0.1 for redirect_uris per RFC 8252 and ATproto spec
- Added proper grapheme counting using RichText API instead of character length
- Fixed thread splitting to account for link suffix and thread indicators in grapheme limits
- Added GOOGLE_EMBEDDING_DIMENSIONS env var to all env files
- Added clear-nodes.ts utility script for database management
- Added galaxy node detail page route

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:26:39 +00:00
4b3da74f79 fix: Correct logo orientation with vertical flip and rotation
Applied transform to flip logo vertically then rotate clockwise 90 degrees

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 16:51:33 +00:00
7fe7ee314b fix: Implement proper fonts and visible logo
Font fixes:
- Added Title component styles in theme.ts to apply Forum font
- Body uses Zalando Sans via theme fontFamily
- All headings (h1-h6) now use Forum via Title component styles

Logo fixes:
- Rewrote SVG with simplified paths at larger scale
- Removed complex transforms causing content to be outside viewBox
- Logo now renders at 32x32px with clearly visible wave graphic
- Save button now generates draft from conversation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 16:41:23 +00:00
b51cb1b516 wip: Font and logo fixes in progress
- Reverted logo SVG to original viewBox
- Applied forum.variable to body for CSS variable
- Updated Save button to generate draft from conversation
- Logo size and font variables still need fixes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 16:35:46 +00:00
2b47231e16 fix: Reduce logo scale to prevent overlap with app title
- Changed logo scale from 3.5x to 1.5x in MobileHeader
- Changed logo scale from 3.5x to 1.5x in DesktopSidebar
- Prevents logo from overlapping with "Ponderants" title text
- Maintains proper spacing and visual hierarchy

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 16:03:59 +00:00
1f2969ddf7 feat: Add Save/Save Draft button to chat interface
- Add dynamic button that shows "Save" when no draft exists
- Changes to "Save Draft" when a pending draft is in progress
- Uses floppy disk icon (IconDeviceFloppy) for visual consistency
- Clicking "Save" creates empty draft and navigates to edit page
- Clicking "Save Draft" navigates to edit page with existing draft
- Reactive state tracking using useSelector for draft state

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 15:57:26 +00:00
d56e19c561 feat: Add production schema deployment scripts
- Create apply-schema-prod.js for deploying schema to any SurrealDB instance
- Create deploy-schema.sh to easily deploy using .prod.env
- Add npm scripts: schema:apply (local) and schema:deploy (production)

Usage:
  pnpm schema:deploy  # Deploy to production using .prod.env

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 15:44:05 +00:00
740d819622 fix: Resolve TypeScript build errors for production deployment
- Add type assertion for SurrealDB query results in debug/nodes route
- Install @types/three for Three.js type definitions
- Exclude tests directory from TypeScript compilation
- Wrap useSearchParams in Suspense boundary on login page (Next.js 16 requirement)

All routes now build successfully for production deployment.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 15:27:13 +00:00
cbb8a8249a fix: Correct .gitignore to match both .env prefix and .env suffix patterns
- .env - matches the base .env file
- .env.* - matches .env.local, .env.production, etc.
- *.env - matches .prod.env, .test.env, etc. (suffix pattern)
- !.example.env - explicitly allow .example.env

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 15:11:15 +00:00
1a4db93ac1 chore: Simplify .gitignore to exclude all .env files except .example.env
- Use .env* pattern to catch all environment files
- Explicitly allow .example.env with negation pattern
- Removes need to list individual .env variants

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 15:10:31 +00:00
5247c142a4 feat: Make OAuth configuration environment-aware via NEXT_PUBLIC_APP_URL
- Convert client-metadata.json to dynamic API route reading from env vars
- Remove BLUESKY_CLIENT_ID and BLUESKY_REDIRECT_URI env vars
- All OAuth URLs now derived from NEXT_PUBLIC_APP_URL
- Implement production OAuth client (removes TODO/placeholder)
- Update .prod.env with production settings for www.ponderants.com
- Use https:// for production URLs
- Simplify environment configuration (single source of truth)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 15:08:04 +00:00
95eeef0deb feat: Add ATproto OAuth client metadata for production
- Create client-metadata.json for production OAuth configuration
- Configure redirect URIs for www.ponderants.com
- Enable DPoP-bound access tokens for enhanced security

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 15:04:53 +00:00
2087596ce1 chore: Remove .next from git tracking and add .prod.env to gitignore
- Remove .next folder from git tracking (build artifacts should not be versioned)
- Add .prod.env to gitignore for production environment configuration

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 15:04:43 +00:00
032f6bc4be feat: Improve UI navigation and logo visibility
- Update navigation labels: 'Navigation' → 'Ponderants', 'Edit Node' → 'Manual', 'Conversation' → 'Convo', 'Galaxy View' → 'Galaxy'
- Improve logo visibility with CSS transform scale(3.5) and higher contrast colors (#E0E0E0, #909296)
- Make logo square (viewBox 60x60) for better favicon display
- Enhance mobile UX with vertical navigation buttons and text labels
- Add 'Profile' label to user menu in navigation
- Improve sidebar highlighting with blue color, bold font, and rounded corners
- Fix layout issues: adjust chat padding for sidebar (260px) and bottom bar (90px)
- Make borders more subtle (#373A40 instead of #dee2e6)
- Increase sidebar width to 260px to accommodate logo and text
- Remove desktop top bar for cleaner layout
- Use IconChartBubbleFilled for galaxy navigation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 15:00:52 +00:00
0ed2d6c0b3 feat: Improve UI layout and navigation
- 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>
2025-11-09 14:43:11 +00:00
47b35b9caf fix: Implement working voice transcription with Deepgram API key
After testing, discovered that temporary tokens from grantToken() fail
with WebSocket connections. Switched to using API key directly, which
is the standard approach for client-side Deepgram WebSocket connections.

Changes:
- Simplified voice-token route to return API key directly
- Added comprehensive logging to MicrophoneRecorder for debugging
- Documented security considerations and mitigation strategies
- Verified working end-to-end voice transcription

This matches Deepgram's official Next.js starter pattern and is the
recommended approach for client-side real-time transcription.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 06:13:45 +00:00
8046c20342 fix: Use Deepgram grantToken() for secure temporary voice tokens
Updated the voice-token API route to use deepgram.auth.grantToken()
consistently in all environments. This generates secure 30-second
temporary tokens instead of exposing the main API key.

- Removed development/production split for consistency
- Now uses grantToken() method in all environments
- Requires API key with "Member" or higher permissions
- Improved security by using short-lived tokens
- Updated documentation to reflect new requirements

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 05:59:45 +00:00
5eec01a9d6 feat: Add user profile menu with logout functionality
Implemented user profile display in the chat interface:
- Created UserMenu component with avatar, handle display, and dropdown
- Added /api/user/profile endpoint to fetch user data from Bluesky
- Added /api/auth/logout endpoint to clear auth cookie
- Integrated UserMenu into chat page header
- Shows user's ATproto avatar with initials fallback
- Dropdown menu displays user info and logout option
- Fixed JWT import to use verifySurrealJwt

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 05:11:54 +00:00
7dd917b2be feat: Fix typing indicator and add New Conversation button
- Fixed typing indicator to use correct AI SDK status values (submitted/streaming)
- Added "New Conversation" button to clear chat and start fresh
- Updated all loading states to use status instead of undefined isLoading
- Disabled input and send button while AI is responding

The typing indicator now properly shows "AI Thinking..." while waiting for
responses, and the New Conversation button allows users to reset the chat.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 05:00:55 +00:00
4571a6f1cc feat: Add typing indicator while AI is thinking
Added a visual typing indicator that displays while the AI is generating
a response. Shows "AI Thinking..." with a loading spinner to give users
feedback that their message is being processed.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 04:57:24 +00:00
a73b454a72 feat: Add authentication redirects for / and /chat routes
Implemented server-side authentication redirects:
- Root (/) redirects to /chat if authenticated, /login if not
- /chat route requires authentication via layout component
- Removed deprecated middleware file in favor of Next.js server components

This ensures users are properly directed based on their authentication state.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 04:55:52 +00:00
9a2c0f9a96 fix: Preserve original host in OAuth callback redirects
Fixed OAuth callback to preserve the original host (localhost vs 127.0.0.1)
by using request headers instead of request.url as the base URL for redirects.

This ensures that if a user accesses the app via 127.0.0.1, they will be
redirected back to 127.0.0.1 after OAuth, and vice versa for localhost.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 04:50:47 +00:00
b22931f393 feat: Upgrade chat to Gemini Pro with configurable model
- Update Google AI model to gemini-pro-latest via env var
- Add GOOGLE_AI_MODEL environment variable for easy model switching
- Add initial greeting message explaining Ponderants features
- Re-add tool call handling to display node suggestions
- Fix chat authentication and streaming responses

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 04:34:48 +00:00
95bcae6e3d fix: Migrate chat to AI SDK 5.0 and fix form submission
Critical fixes to get chat functionality working:

1. **Migrate to AI SDK 5.0 API**:
   - Replace deprecated `handleSubmit`, `input`, `handleInputChange` from useChat
   - Use manual state management with `useState` for input
   - Use `sendMessage({ text })` instead of form submission
   - Update API route to use `toUIMessageStreamResponse()` instead of `toAIStreamResponse()`
   - Add `convertToModelMessages()` for proper message conversion
   - Update message rendering to use `parts` array instead of `content` string

2. **Fix Mantine hydration error**:
   - Change `forceColorScheme="dark"` to `defaultColorScheme="dark"` in layout
   - Add `suppressHydrationWarning` to html and body tags
   - This was preventing React from attaching event handlers to the form

3. **Preserve existing features**:
   - Keep input padding fix
   - Keep microphone recorder integration
   - Keep persona parameter in API route

The form now successfully submits and makes POST requests to /api/chat.
Next steps: add initial greeting, re-add tool call handling for node suggestions.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 04:07:17 +00:00