Commit Graph

66 Commits

Author SHA1 Message Date
Jeff Emmett cd58b1c1cd fix: accept all valid tldraw fractional indices (b1, c10, etc.)
The index validation was incorrectly rejecting valid tldraw fractional
indices like "b1", "c10", etc. tldraw's fractional indexing uses:
- First letter (a-z) indicates integer part length (a=1 digit, b=2 digits)
- Followed by alphanumeric characters for value and jitter

This was causing ValidationError on production for Embed shapes with
index "b1". Fixed regex in all validation functions to accept any
lowercase letter prefix, not just 'a'.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 04:01:35 -08:00
Jeff Emmett d89fb4baaf Add backlog tasks from worktrees and feature branches
- task-002: RunPod AI API Integration (worktree: add-runpod-AI-API)
- task-003: MulTmux Web Integration (worktree: mulTmux-webtree)
- task-004: IO Chip Feature (worktree: feature/io-chip)
- task-005: Automerge CRDT Sync
- task-006: Stripe Payment Integration
- task-007: Web3 Integration
- task-008: Audio Recording Feature
- task-009: Web Speech API Transcription
- task-010: Holon Integration
- task-011: Terminal Tool
- task-012: Dark Mode Theme

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 21:56:54 -08:00
Jeff Emmett c396bbca85 feat: standardize tool shapes with pin functionality and UI improvements
- Add pin functionality to ImageGen and VideoGen shapes
- Refactor ImageGen to use StandardizedToolWrapper with tags support
- Update StandardizedToolWrapper: grey tags, fix button overlap, improve header drag
- Fix index validation in AutomergeToTLStore for old format indices
- Update wrangler.toml with latest compatibility date and RunPod endpoint docs
- Refactor VideoGen to use captured editor reference for consistency

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 21:14:51 -08:00
Jeff Emmett 829dd4f642 fix: increase VideoGen timeout to 6 minutes for GPU cold starts
Video generation on RunPod can take significant time:
- GPU cold start: 30-120 seconds
- Model loading: 30-60 seconds
- Generation: 60-180 seconds

Increased polling timeout from 4 to 6 minutes and updated UI
to set proper expectations for users.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 18:51:41 -08:00
Jeff Emmett f2a77580b1 feat: add default RunPod endpoints for all AI services
All RunPod API functions now have hardcoded fallback values so
every user can access AI features without needing their own keys:

- Image Generation: Automatic1111 endpoint (tzf1j3sc3zufsy)
- Video Generation: Wan2.2 endpoint (4jql4l7l0yw0f3)
- Text Generation: vLLM endpoint (03g5hz3hlo8gr2)
- Transcription: Whisper endpoint (lrtisuv8ixbtub)
- Ollama: Netcup AI Orchestrator (ai.jeffemmett.com)

This ensures ImageGen, VideoGen, Mycelial Intelligence, and
transcription work for all users of the canvas out of the box.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 18:41:21 -08:00
Jeff Emmett dba981c2af fix: improve index migration to handle all invalid formats
- Added isValidTldrawIndex() function to properly validate tldraw
  fractional indices (e.g., "a1", "a1V" are valid, "b1", "c1" are not)
- Apply migration to IndexedDB data as well as server data
- This fixes ValidationError when loading old data with invalid indices

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 16:19:30 -07:00
Jeff Emmett c070e673ad fix: migrate invalid shape indices in old data
Adds migrateStoreData() function to fix ValidationError when loading
old data with invalid index keys (e.g., 'b1' instead of fractional
indices like 'a1V'). The migration detects invalid indices and
regenerates valid ones using tldraw's getIndexAbove().

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 22:40:21 -08:00
Jeff Emmett 33ff5216cc feat: fix Holon shape H3 validation + offline persistence + geometry error handling
Holon Shape Improvements:
- Add H3 cell ID validation before connecting to Holosphere
- Extract coordinates and resolution from H3 cell IDs automatically
- Improve data rendering with proper lens/item structure display
- Add "Generate H3 Cell" button for quick cell ID creation
- Update placeholders and error messages for H3 format
- Fix HolonBrowser validation and placeholder text

Geometry Error Fix:
- Add try-catch in ClickPropagator.eventHandler for shapes with invalid paths
- Add try-catch in CmdK for getShapesAtPoint geometry errors
- Prevents "No nearest point found" crashes from corrupted draw/line shapes

Offline Persistence:
- Add IndexedDB storage adapter for Automerge documents
- Implement document ID mapping for room persistence
- Merge local and server data on reconnection
- Support offline editing with automatic sync

Other Changes:
- Update .env.example with Ollama and RunPod configuration
- Add multmux Docker configuration files
- UI styling improvements for toolbar and share zone
- Remove auto-creation of MycelialIntelligence shape (now permanent UI bar)
- Various shape utility minor fixes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 21:36:02 -08:00
Jeff Emmett 5cd36c3d3c feat: move Mycelial Intelligence to permanent UI bar + fix ImageGen RunPod API
- Mycelial Intelligence UI refactor:
  - Created permanent floating bar at top of screen (MycelialIntelligenceBar.tsx)
  - Bar stays fixed and doesn't zoom with canvas
  - Collapses when clicking outside
  - Removed from toolbar tool menu
  - Added deprecated shape stub for backwards compatibility with old boards

- ImageGen RunPod fix:
  - Changed from async /run to sync /runsync endpoint
  - Fixed output parsing for output.images array format with base64

- Other updates:
  - Added FocusLockIndicator and UserSettingsModal UI components
  - mulTmux server and shape updates
  - Automerge sync and store improvements
  - Various CSS and UI refinements

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 23:57:26 -08:00
Jeff Emmett a8c3988e3f feat: add Ollama private AI integration with model selection
- Add Ollama as priority AI provider (FREE, self-hosted)
- Add model selection UI in Settings dialog
- Support for multiple models: Llama 3.1 70B, Devstral, Qwen Coder, etc.
- Ollama server configured at http://159.195.32.209:11434
- Models dropdown shows quality vs speed tradeoffs
- Falls back to RunPod/cloud providers when Ollama unavailable

Models available:
- llama3.1:70b (Best quality, ~7s)
- devstral (Best for coding agents)
- qwen2.5-coder:7b (Fast coding)
- llama3.1:8b (Balanced)
- llama3.2:3b (Fastest)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 14:47:07 -08:00
Jeff Emmett 8ea3490fb4 feat: update mulTmux terminal tool and improve shape utilities
Updates to collaborative terminal integration and various shape
improvements across the canvas.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 04:08:08 -08:00
Jeff Emmett f4e72452f1 debug: add logging for coordinate defaults during sanitization 2025-11-19 20:25:24 -07:00
Jeff Emmett cae367db28 fix: migrate geo shapes with props.text during Automerge load
Geo shapes saved before the tldraw schema change have props.text which is
no longer valid. This causes ValidationError on page reload when shapes are
loaded from Automerge:

  "ValidationError: At shape(type = geo).props.text: Unexpected property"

The migration logic was only in JSON import (CustomMainMenu.tsx), but shapes
loading from Automerge also need migration.

This fix adds the props.text → props.richText migration to the sanitizeRecord
function in AutomergeToTLStore.ts, ensuring geo shapes are properly migrated
when loaded from Automerge, matching the behavior during JSON import.

The original text is preserved in meta.text for backward compatibility with
search and other features that reference it.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 16:25:58 -07:00
Jeff Emmett 7e09d22843 fix: preserve coordinates and convert geo shape text during JSON import
- Fix coordinate collapse bug where shapes were resetting to (0,0)
- Convert geo shape props.text to props.richText (tldraw schema change)
- Preserve text in meta.text for backward compatibility
- Add .nvmrc to enforce Node 20
- Update package.json to require Node >=20.0.0
- Add debug logging for sync and import operations

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 16:14:23 -07:00
Jeff Emmett 943162899e fix: use useMemo instead of useState for repo/adapter initialization
Fixed TypeScript error by changing from useState to useMemo for repo and
adapter initialization. This properly exposes the repo and adapter objects
instead of returning a state setter function.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 22:10:55 -07:00
Jeff Emmett e70cba82b4 fix: wait for network adapter to be ready before creating document
Added await for adapter.whenReady() to ensure WebSocket connection is
established before creating the Automerge document. This should enable
the Automerge Repo to properly send binary sync messages when document
changes occur.

Changes:
- Extract adapter from repo initialization to access it
- Wait for adapter.whenReady() before creating document
- Update useEffect dependencies to include adapter and workerUrl

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 22:07:24 -07:00
Jeff Emmett 63b19f7db8 fix: restore working Automerge sync from pre-Cloudflare version
Reverted to the proven approach from commit 90605be where each client
creates its own Automerge document with repo.create(). The Automerge
binary sync protocol handles synchronization between clients through
the WebSocket network adapter, without requiring shared document IDs.

Key changes:
- Each client calls repo.create() to get a unique document
- Initial content loaded from server via HTTP/R2
- Binary sync messages broadcast between clients keep documents in sync
- No need for shared document ID storage/retrieval

This fixes the "Document unavailable" errors and enables real-time
collaboration across multiple board instances.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 21:59:59 -07:00
Jeff Emmett c18d204814 fix: simplify Automerge document creation for concurrent access
Removed document ID storage/retrieval logic that was causing "Document unavailable"
errors. Each client now creates its own Automerge document handle and syncs content
via WebSocket binary protocol. This allows multiple boards to load the same room
simultaneously without conflicts.

- Removed /room/:roomId/documentId endpoints usage
- Each client creates document with repo.create()
- Content syncs via Automerge's native binary sync protocol
- Initial content still loaded from server via HTTP

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 21:40:15 -07:00
Jeff Emmett 3231720004 fix: add await to repo.find() call
repo.find() returns a Promise<DocHandle>, not DocHandle directly.
Added missing await keyword to fix TypeScript build error.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 21:26:42 -07:00
Jeff Emmett ca9f250de8 fix: handle concurrent Automerge document access with try-catch
When multiple clients try to load the same room simultaneously, repo.find()
throws "Document unavailable" error if the document isn't in the repo yet.
Wrapped repo.find() in try-catch to create a new handle when document isn't
available, allowing multiple boards to load the same page concurrently.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 21:15:56 -07:00
Jeff Emmett 6ab966cc95 fix: use proper Automerge URL format for repo.find()
The issue was that repo.find() was creating a NEW document instead of
waiting for the existing one to sync from the network.

Changes:
- Use 'automerge:{documentId}' URL format for repo.find()
- Remove try-catch that was creating new documents
- Let repo.find() properly wait for network sync

This ensures all clients use the SAME document ID and can sync in real-time.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 21:00:18 -07:00
Jeff Emmett 02808d170e fix: handle Document unavailable error with try-catch in repo.find()
When repo.find() is called for a document that exists on the server but not
locally, it throws 'Document unavailable' error. This fix:

- Wraps repo.find() in try-catch block
- Falls back to creating new handle if document not found
- Allows sync adapter to merge with server state via network

This handles the case where clients join existing rooms and need to sync
documents from the network.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 20:33:31 -07:00
Jeff Emmett 2cc7c52755 refactor: remove OddJS dependency and fix Automerge sync
Major Changes:
- Fix Automerge "Document unavailable" error by awaiting repo.find()
- Remove @oddjs/odd package and all related dependencies (205 packages)
- Remove location sharing features (OddJS filesystem-dependent)
- Simplify auth to use only CryptoAuthService (WebCryptoAPI-based)

Auth System Changes:
- Refactor AuthService to remove OddJS filesystem integration
- Update AuthContext to remove FileSystem references
- Delete unused auth files (account.ts, backup.ts, linking.ts)
- Delete unused auth components (Register.tsx, LinkDevice.tsx)

Location Features Removed:
- Delete all location components and routes
- Remove LocationShareShape from shape registry
- Clean up location references across codebase

Documentation Updates:
- Update WEBCRYPTO_AUTH.md to remove OddJS references
- Correct component names (CryptoLogin → CryptID)
- Update file structure and dependencies
- Fix Automerge README WebSocket path documentation

Build System:
- Successfully builds without OddJS dependencies
- All TypeScript errors resolved
- Production bundle size optimized

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 20:19:02 -07:00
Jeff Emmett 1e68150b60 fix: implement real-time Automerge sync across clients
- Add document ID coordination via server to ensure all clients sync to same document
- Add new endpoints GET/POST /room/:roomId/documentId for document ID management
- Store automergeDocumentId in Durable Object storage
- Add enhanced logging to CloudflareAdapter send() method for debugging
- Add sharePolicy to Automerge Repo to enable document sharing
- Fix TypeScript errors in useAutomergeSyncRepo

This fixes the issue where each client was creating its own Automerge document
with a unique ID, preventing real-time sync. Now all clients in a room use the
same document ID, enabling proper real-time collaboration.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 19:45:36 -07:00
Jeff Emmett 48dac00f59 fix: use repo.create() instead of invalid document ID format
Change from repo.find('automerge:patricia') to repo.create() because
Automerge requires proper UUID-based document IDs, not arbitrary strings.

Each client creates a local document, loads initial data from server,
and syncs via WebSocket. The server syncs documents by room ID, not
by Automerge document ID.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 05:13:37 -07:00
Jeff Emmett 776526c65e fix: add type cast for currentDoc to fix TypeScript error
Cast handle.doc() to any to fix TypeScript error about missing 'store' property.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 05:04:54 -07:00
Jeff Emmett 64d4a65613 fix: await repo.find() to fix TypeScript build errors
repo.find() returns a Promise<DocHandle>, so we need to await it.
This fixes the TypeScript compilation errors in the build.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 05:00:04 -07:00
Jeff Emmett 432e90d9ef fix: enable production logging for R2 persistence debugging
Add console logs in production to debug why shapes aren't being saved to R2.
This will help identify if saves are:
- Being triggered
- Being deferred/skipped
- Successfully completing

Logs added:
- 💾 When persistence starts
-  When persistence succeeds
- 🔍 When shape patches are detected
- 🚫 When saves are skipped (ephemeral/pinned changes)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 04:56:32 -07:00
Jeff Emmett 71e7e5de05 fix: remove ImageGen references to fix build
Remove ImageGenShape import and references from useAutomergeStoreV2.ts
to fix TypeScript build error. ImageGen feature files are not yet committed.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 04:17:49 -07:00
Jeff Emmett 90605bee09 fix: enable real-time multiplayer sync for automerge
Add manual sync triggering to broadcast document changes to other peers in real-time.
The Automerge Repo wasn't auto-broadcasting because the WebSocket setup doesn't use peer discovery.

Changes:
- Add triggerSync() helper function to manually trigger sync broadcasts
- Call triggerSync() after all document changes (position updates, eraser changes, regular changes)
- Pass Automerge document to patch handlers to prevent coordinate loss
- Add ImageGenShape support to schema

This fixes the issue where changes were being saved to Automerge locally but not
broadcast to other connected clients until page reload.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 04:00:31 -07:00
Jeff Emmett 7a17b0944a fix custom shape type validation errors
Add case normalization for custom shape types to prevent validation errors when loading shapes with lowercase type names (e.g., "chatBox" → "ChatBox"). The TLDraw schema expects PascalCase type names for custom shapes.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 03:13:07 -07:00
Jeff Emmett f5582fc7d1 prevent coordinate collapse on reload
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 03:03:39 -07:00
Jeff Emmett 4d7b05efa2 update obsidian shape deployment 2025-11-12 16:23:08 -08:00
Jeff Emmett ab1d0344a5 fix cloudflare deployment glitches 2025-11-11 22:47:36 -08:00
Jeff Emmett 2528ad4726 update cloudflare errors 2025-11-11 22:38:24 -08:00
Jeff Emmett ffef04df50 pin object, fix fathom, and a bunch of other things 2025-11-11 22:32:36 -08:00
Jeff Emmett ef4a84e8f1 remove coordinate reset 2025-11-11 00:53:55 -08:00
Jeff Emmett d1179169cc fix coordinates 2025-11-10 23:54:54 -08:00
Jeff Emmett 0e90e2d097 preserve coordinates 2025-11-10 23:51:53 -08:00
Jeff Emmett eafbf6c9fe shape rendering on prod 2025-11-10 23:36:12 -08:00
Jeff Emmett edbe76ebda fix coordinates 2025-11-10 23:25:44 -08:00
Jeff Emmett ef39328d95 preserve coordinates 2025-11-10 23:17:16 -08:00
Jeff Emmett 229f4d6b41 fix coordinates 2025-11-10 23:04:52 -08:00
Jeff Emmett 0fa1652f72 prevent coordinate reset 2025-11-10 23:01:35 -08:00
Jeff Emmett 1b172d7529 update x & y coordinates 2025-11-10 22:42:52 -08:00
Jeff Emmett c1df50c49b fix prod 2025-11-10 22:27:21 -08:00
Jeff Emmett 73ac456e17 update dev and prod shape render 2025-11-10 20:16:45 -08:00
Jeff Emmett 92cac8dee5 fix prod shape render 2025-11-10 20:05:07 -08:00
Jeff Emmett b8fb64c01b update prod shape render 2025-11-10 19:54:20 -08:00
Jeff Emmett 680b6a5359 update prod 2025-11-10 19:44:49 -08:00