The previous validation allowed "b1" which is invalid because 'b' prefix
expects 2-digit integers (10-99), not 1-digit. This caused ValidationError
when selecting old format content.
Now validates that:
- 'a' prefix: 1 digit (a0-a9)
- 'b' prefix: 2 digits (b10-b99)
- 'c' prefix: 3 digits (c100-c999)
- etc.
Invalid indices are converted to 'a1' as a safe default.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add GOOGLE_DATA_SOVEREIGNTY.md: comprehensive plan for secure local storage
of Gmail, Drive, Photos, Calendar data with client-side encryption
- Add LOCAL_FILE_UPLOAD.md: multi-item upload tool with same encryption model
for local files (images, PDFs, documents, audio, video)
- Update OFFLINE_STORAGE_FEASIBILITY.md to reference new docs
Key features:
- IndexedDB encrypted storage with AES-256-GCM
- Keys derived from WebCrypto auth (never leave browser)
- Safari 7-day eviction mitigations
- Selective sharing to boards via Automerge
- Optional encrypted R2 backup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed auto-generated duplicates that were overwritten.
Correct tasks are now task-018 and task-019.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>
- Add ResizeObserver for reliable resize detection
- Use requestAnimationFrame for smoother fit operations
- Apply full-size styles to xterm elements after fit
- Hide tags to maximize terminal area
- Fix flex layout for proper container sizing
- Add error handling for fit operations during rapid resize
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Allow passing full system prompts (>100 chars) or personality IDs
- Auto-detect prompt type based on length
- Pass custom prompts through provider chain with retry logic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Increase default width from 500px to 650px to fit full toolbar
- Add fixed-position toggle button (top-right) that doesn't move between states
- Remove horizontal scrollbar with overflow: hidden
- Add right padding to toolbar for toggle button space
- Tighten toolbar spacing (gap: 1px, padding: 4px 6px)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace useMemo with useState + MutationObserver for isDarkMode detection
- Add MDXEditor's built-in 'dark-theme' class for proper toolbar/icon theming
- Theme now switches instantly when user toggles dark/light mode
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Traefik cannot auto-link routers when multiple services are defined.
Fixed by using a single service (canvas) that both routers explicitly
reference via the .service label.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add router rules for jeffemmett.com and www.jeffemmett.com
- Keep staging.jeffemmett.com for testing
- Preparing for migration from Cloudflare Pages to Docker deployment
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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>
- Add index sanitization in Board.tsx to fix "Expected an index key"
validation errors when selecting shapes with old format indices
- Improve RunPod error handling to properly display status messages
(IN_PROGRESS, IN_QUEUE, FAILED) instead of generic errors
- Update wrangler.toml with current compatibility date and document
RunPod endpoint configuration for reference
- Add sanitizeIndex helper function to convert invalid indices like
"b1" to valid tldraw fractional indices like "a1"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>
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>
Hardcoded fallback values for Ollama and RunPod text endpoints so
that all users have access to AI features without needing to
configure their own API keys:
- Ollama: defaults to https://ai.jeffemmett.com (Netcup AI Orchestrator)
- RunPod Text: defaults to pre-configured vLLM endpoint
This ensures Mycelial Intelligence works for everyone out of the box.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The FathomNote shape was being created by FathomMeetingsBrowserShape
but wasn't registered with tldraw, causing "No shape util found for
type FathomNote" errors when loading canvases with Fathom notes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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>
Sharp 0.33.5 has prebuilt binaries for linux-x64 while the older
0.32.x version in @xenova/transformers requires native compilation.
Using npm overrides to force 0.33.5 throughout the dependency tree.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added omit=optional to .npmrc to prevent @xenova/transformers from
trying to compile sharp with native dependencies. Sharp is only used
for server-side image processing which isn't needed in the browser.
Also added override for sharp version in package.json as fallback.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>
- Add cleanup routine on editor mount to remove corrupted draw/line shapes
that have no points/segments (these cause geometry errors)
- Add global error handler to suppress geometry errors from tldraw
instead of crashing the entire app
- Both fixes ensure old JSON data with corrupted shapes loads gracefully
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>