Commit Graph

722 Commits

Author SHA1 Message Date
Jeff Emmett b64dc66d49 CI: temp deploy-test job to debug container+registry access
CI/CD / test-and-build (push) Successful in 2m58s Details
CI/CD / deploy-test (push) Failing after 4s Details
2026-04-01 00:51:50 -07:00
Jeff Emmett 5accba29fa CI: fix deploy condition syntax for Gitea Actions
CI/CD / test-and-build (push) Failing after 2m30s Details
CI/CD / deploy (push) Has been skipped Details
2026-04-01 00:42:37 -07:00
Jeff Emmett 4c648150b2 CI: add debug job to check context variables
CI/CD / test-and-build (push) Failing after 1m48s Details
CI/CD / deploy (push) Has been skipped Details
CI/CD / debug-context (push) Successful in 5s Details
2026-04-01 00:38:12 -07:00
Jeff Emmett b5b95ae5e1 CI: merge test + build into single job to avoid double npm ci
CI/CD / test-and-build (push) Successful in 2m46s Details
CI/CD / deploy (push) Has been skipped Details
Running npm ci twice in separate containers causes OOM on the shared
host. Single job: npm ci once, then tsc, vitest, and vite build
in sequence.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 00:20:41 -07:00
Jeff Emmett bfab3ce043 Fix CI: skip native scripts during npm ci to prevent OOM
CI/CD / test (push) Successful in 1m26s Details
CI/CD / build-check (push) Failing after 1m0s Details
CI/CD / deploy (push) Has been skipped Details
node-pty native compilation during npm ci uses excessive memory.
Using --ignore-scripts since tests and build don't need native
modules. Removed python3/make/g++ from install step.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 00:12:37 -07:00
Jeff Emmett cdcae789b3 CI: add capacity comment, runner reduced to 1 concurrent job
CI/CD / test (push) Failing after 1m26s Details
CI/CD / build-check (push) Successful in 2m59s Details
CI/CD / deploy (push) Has been skipped Details
Prevents OOM on shared host with <5GB free RAM when two npm ci
jobs run simultaneously.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 00:04:51 -07:00
Jeff Emmett 8c6ff05449 CI: allow worker test failures as warnings, runner mem bumped to 8GB
CI/CD / build-check (push) Failing after 1m13s Details
CI/CD / test (push) Failing after 1m16s Details
CI/CD / deploy (push) Has been skipped Details
Worker test has pre-existing string mismatch (enCryptID vs CryptID).
Runner memory increased from 4GB to 8GB for Vite build.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 23:58:45 -07:00
Jeff Emmett 4a8c8f1df8 Fix CI: install native build tools for node-pty compilation
CI/CD / test (push) Failing after 1m57s Details
CI/CD / build-check (push) Failing after 2m36s Details
CI/CD / deploy (push) Has been skipped Details
node-pty requires python3, make, g++ for node-gyp native build.
node:20-bookworm-slim doesn't include these by default.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 23:52:22 -07:00
Jeff Emmett 915068c70a Add Gitea Actions CI/CD pipeline
CI/CD / test (push) Failing after 1m22s Details
CI/CD / build-check (push) Failing after 1m21s Details
CI/CD / deploy (push) Has been skipped Details
- test job: TypeScript check, unit tests, worker tests
- build-check job: validates production build succeeds
- deploy job (main only): builds Docker image, pushes to Gitea registry,
  deploys to Netcup, runs smoke test with auto-rollback on failure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 23:48:17 -07:00
Jeff Emmett 5883228fae Remove Daily.co and Google Maps, replace maps with OpenStreetMap
Daily.co video chat replaced by Jitsi (meet.jeffemmett.com) — clean up
residual config (Dockerfile, vite.config, worker types, env vars).
Google Maps embed replaced with OpenStreetMap — no API key needed,
converts Google Maps URLs to OSM embeds automatically.

Part of TASK-CRITICAL.1: exposed API key rotation and cleanup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:42:25 -07:00
Jeff Emmett f5cf0bfb78 Add Meeting Intelligence browser shape for canvas integration
New canvas shape that connects to the self-hosted Meeting Intelligence API
(meets-api.rspace.online) to browse meetings, pull transcripts, summaries,
and speaker data onto the canvas as note shapes.

- MeetingIntelligencePanel: React panel listing meetings with pull buttons
- MeetingIntelligenceBrowserShapeUtil: Browser shape wrapping the panel
- MeetingIntelligenceTool: Tool for placing browser on canvas
- Registered in Board.tsx, overrides.tsx, automerge stores, and all shape registries

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 18:51:18 -07:00
Jeff Emmett 007a25d3da fix: output unified transcript instead of echoed segments
The Web Speech API hook was sending each recognition result as a
separate fragment via onTranscriptUpdate, causing the transcription
shape to display fragmented/echoed conversation. Now the hook
accumulates the full transcript internally and always sends the
complete text, so the shape receives one unified conversation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:03:13 +00:00
Jeff Emmett 526a4c4b9d chore: add backlog-notify onStatusChange hook
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:31:00 -07:00
Jeff Emmett ef4574d223 fix: auto-switch to page with most content when current page has trivial shapes
Previously the page-switch logic only triggered when the current page had 0 shapes.
The R2 data has 283 shapes on page:QZw03khAAJ7jNX7zQND64 but only 1 (MycelialIntelligence)
on page:page. Since page:page is the default, users saw only the MI shape, not their content.

Now also switches when current page has <=2 shapes but another page has >10.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 18:24:54 -07:00
Jeff Emmett 01fb250d29 fix: register BlenderGen and TransactionBuilder in automerge store schema
BlenderGen and TransactionBuilder were added to Board.tsx's customShapeUtils
but never registered in useAutomergeStoreV2.ts's CUSTOM_SHAPE_TYPES, imports,
or shapeUtils array. This schema mismatch prevented tldraw's Editor from
rendering any content - the store didn't know about these shape types even
though the Tldraw component was told to use them.

Also adds TransactionBuilder shape for Safe multisig transaction building
and reduces verbose error logging in automerge sync.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 18:07:37 -07:00
Jeff Emmett 43007c07f8 chore: remove CLAUDE.md from git tracking
CLAUDE.md may contain project context with credentials and is now
covered by global gitignore to prevent accidental secret commits.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:41:16 -08:00
Jeff Emmett a795207022 Add .dockerignore for optimized Docker builds
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 18:00:48 -07:00
Jeff Emmett cc19f451c5 Create task TASK-064 2026-02-21 18:00:48 -07:00
Jeff Emmett 4405e380c1 fix: redirect /board/* from jeffemmett.com to canvas.jeffemmett.com
When visiting jeffemmett.com/board/mycofi, the redirect now correctly
goes to canvas.jeffemmett.com/mycofi/ instead of jeffemmett.com/mycofi.
Localhost and canvas.jeffemmett.com still use same-domain redirects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 11:11:33 +00:00
Jeff Emmett 1d95d1f398 Replace Resend with self-hosted email relay for all email sending
- cryptidAuth.ts: sendEmail() now calls email-relay.jeffemmett.com
  instead of api.resend.com
- boardPermissions.ts: admin request emails use email relay
- types.ts: RESEND_API_KEY → EMAIL_RELAY_URL + EMAIL_RELAY_API_KEY
- wrangler.toml: updated secrets documentation
- Tests updated with new mock env vars

Email relay is a lightweight Flask service on Netcup that accepts
HTTP POST and sends via Mailcow SMTP. Needed because CF Workers
can't do TCP/SMTP directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 16:13:05 -07:00
Jeff Emmett dea24bde81 feat: migrate all presentation embeds from FlipHTML5 to self-hosted flipbook service
Replace 12 FlipHTML5 iframe URLs with slides.jeffemmett.com for full self-hosting
of all presentation decks. Zero external dependencies for presentation viewing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 09:20:33 -07:00
Jeff Emmett 35c8ae74c7 fix: add canvas.jeffemmett.com to Traefik router rule
DNS and Cloudflare tunnel were already configured but Traefik was only
routing jeffemmett.com and www.jeffemmett.com to the canvas container.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 23:18:40 -07:00
Jeff Emmett 42306eba47 fix: add canvas.jeffemmett.com to Traefik router rule
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 23:06:33 -07:00
Jeff Emmett a37ab68588 refactor: move activity log into settings dropdown, simplify permissions
Move the standalone activity log toggle button (~) into the settings
gear dropdown as a collapsible accordion section. Simplify the board
permission display by removing the verbose "Access Levels" grid and
replacing it with a compact current-permission badge + request button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 22:57:06 -07:00
Jeff Emmett 20094ea9a7 Add deployment scaffolding (Dockerfile, docker-compose, nginx)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 14:14:29 +01:00
Jeff Emmett 72043f0f12 fix: remove duplicate folder picker in Obsidian browser shape mode
Removed the purple "Connect Vault" button from shape mode rendering.
The no-vault case is now handled only by the early return section which
shows the working "Select Folder" design.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 19:21:13 +01:00
Jeff Emmett 6ed1edf82b fix: add missing BlenderGen tool definition to context menu
BlenderGen was registered as a tool but missing from overrides.tsx,
causing an empty space in the context menu between VideoGen and Markdown.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 19:15:27 +01:00
Jeff Emmett 5dbcd1cec3 fix: correct tldraw index validation to accept base-62 alphanumeric
The sanitizeIndex function was incorrectly expecting decimal digits
after the prefix letter (e.g., "b10"), but tldraw uses base-62
alphanumeric fractional indexing (e.g., "bBE6lP", "aKB7V" are valid).

This was causing all shapes to be reset to 'a1' z-index, flooding
the console with invalid index warnings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 18:29:05 +01:00
Jeff Emmett b2941333f3 feat: improve Obsidian vault storage with IndexedDB content store
- Add noteContentStore.ts for storing full note content in IndexedDB
- Avoids Automerge WASM capacity limits and localStorage quota (~5MB)
- Only metadata (id, title, tags, links) syncs via Automerge
- Full content stays local and loads on-demand
- Handle ephemeral messages in AutomergeDurableObject for cursor sync
- Improvements to ObsidianVaultBrowser component
- Enhanced obsidianImporter functionality

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:15:48 +01:00
Jeff Emmett 2030ae447d refactor: remove Daily.co, fix IndexedDB sync for stale cache
Daily.co Cleanup:
- Remove @daily-co/daily-js and @daily-co/daily-react packages
- Remove DailyProvider wrapper from App.tsx
- Remove ~380 lines of Daily API endpoints from worker.ts
- Remove DAILY_DOMAIN from wrangler configs
- Remove Daily env vars from .env.example
- Video chat now uses self-hosted Jitsi (meet.jeffemmett.com)

Sync Logic Fix:
- Fix stale IndexedDB cache preventing server data from loading
- Changed threshold from "10x more shapes" to "more shapes"
- Server data now properly updates local cache on initial load
- Keeps local-only records for offline work

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 13:21:20 +01:00
Jeff Emmett fb3edce5a9 Update task task-063 2026-01-23 09:41:04 +01:00
Jeff Emmett 0a413813a6 Create task task-063 2026-01-22 21:03:49 +01:00
Jeff Emmett 58905067f8 feat: improve Jitsi Meet interaction and room naming
- Enable pointer events on iframe for direct mouse/touch/pen interaction
- Room names now use canvas slug (e.g., mycofi-jeffsi-meet for /mycofi)
- All video chats in same canvas room share the same Jitsi room
- Support both /:slug and /board/:slug URL patterns

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 16:57:12 +00:00
Jeff Emmett 08bea8490d fix: TypeScript errors in sync version state
- Fixed variable scope issue with totalMerged counter
- Added syncVersion to return type declaration

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 18:58:24 +01:00
Jeff Emmett edb386ec3c fix: force React re-render after server sync merges data
Added syncVersion state that increments when server data is merged,
ensuring the UI updates to show the loaded board content.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 18:50:14 +01:00
Jeff Emmett 5eac403211 fix: align vitest version with coverage-v8 to fix CI
Updated vitest from 3.2.4 to 4.0.16 to match @vitest/coverage-v8 4.0.16

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 18:41:41 +01:00
Jeff Emmett 5b2de78677 fix: CORS and IndexedDB sync for canvas.jeffemmett.com
- Add canvas.jeffemmett.com to CORS allowed origins
- Fix IndexedDB sync to prefer server data when local has no shapes
- Handle case where local cache has stale/minimal data but server has full board
- Add console logging for sync debugging

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 18:32:50 +01:00
Jeff Emmett 854ce9aa50 fix: enable canvas panning when VideoChat shape not selected
Add conditional pointer-events to iframe - only enabled when shape is
selected, allowing normal canvas pan/zoom when not interacting with video.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 20:45:30 +01:00
Jeff Emmett 30daf2a8cb feat: Replace Daily.co with Jeffsi Meet for video calls
- Remove Daily.co API dependencies
- Use self-hosted Jeffsi Meet (Jitsi fork) at meet.jeffemmett.com
- Simplify room creation (Jitsi creates rooms on-the-fly)
- Add Copy Link and Pop Out buttons for sharing
- Configure Jitsi embed with custom branding settings
- No recurring per-minute costs with self-hosted solution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 19:45:50 +01:00
Jeff Emmett ed61902fab feat: add Last Visited canvases and per-board Activity Logger
- Add "Last Visited" section to Dashboard showing recent board visits
- Add per-board activity logging that tracks shape creates/deletes/updates
- Activity panel with collapsible sidebar, grouped by date
- Debounced update logging to skip tiny movements
- Full dark mode support for both features

New files:
- src/lib/visitedBoards.ts - Visit tracking service
- src/lib/activityLogger.ts - Activity logging service
- src/components/ActivityPanel.tsx - Activity panel UI
- src/css/activity-panel.css - Activity panel styles

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 00:36:43 +01:00
Jeff Emmett 4974c0e303 fix: use internal redirect for /board/:slug on staging
Changed RedirectBoardSlug to use React Router's Navigate instead of
window.location.href to a non-existent domain. Now /board/:slug
redirects to /:slug/ within the same domain.

Production (main branch) keeps /board/:slug unchanged.
Staging (dev branch) supports both /board/:slug and /:slug patterns.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 19:06:54 +01:00
Jeff Emmett 53d3620cff fix: add index signature to TLStoreSnapshot for Automerge compatibility
TypeScript requires index signature for Automerge.Doc generic constraint.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 13:53:31 +01:00
Jeff Emmett 1dc8f4f1b8 fix: correct TypeScript typing for Automerge.from() optimization
Use double type assertion for TLStoreSnapshot → Record<string, unknown>
to satisfy Automerge.from() type constraints.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 11:56:49 +01:00
Jeff Emmett 06f41e8fec style: change enCryptID security border from green to steel blue/grey
Updated the security visual indicator to use slate/steel colors (#64748b)
instead of green (#22c55e) for a more professional look.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 09:09:36 +01:00
Jeff Emmett 313033d83e fix: correct dev worker name to match frontend URL
The frontend expects jeffemmett-canvas-automerge-dev but wrangler.dev.toml
had jeffemmett-canvas-dev, causing 404 errors for wallet API endpoints.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 08:43:15 +01:00
Jeff Emmett 00aa0828c4 fix: guard Drawfast tool with feature flag in overrides
Drawfast was always included in overrides.tsx but is conditional in
Board.tsx (dev-only). This caused "l is not a function" errors when
users tried to select tools in production since the Drawfast tool
wasn't registered.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 08:32:46 +01:00
Jeff Emmett 486e75d02a fix: Simplify Web3Provider to only use injected connector
- Remove WalletConnect connector to fix TypeScript build error
- Only injected wallets (MetaMask, etc.) are supported for now
- WalletConnect can be re-added when valid project ID is configured

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 03:29:55 +01:00
Jeff Emmett 28ab62f645 fix: guard WorkflowBlock/Calendar tools with feature flags, disable WalletConnect QR modal
- Add ENABLE_WORKFLOW and ENABLE_CALENDAR flags to overrides.tsx
- Conditionally include tool menu entries only in dev mode
- Disable WalletConnect QR modal to fix web3modal initialization errors
- Users can still connect via injected wallets (MetaMask, etc.)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 21:53:08 +01:00
Jeff Emmett 5db25f3ac1 fix: Redirect /board/:slug URLs to clean /:slug/ URLs
- Old links like jeffemmett.com/board/ccc now redirect to /ccc/
- Both /board/:slug and /board/:slug/ redirect to clean URLs
- Boards served directly at /:slug/ without /board prefix

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 21:45:21 +01:00
Jeff Emmett 7debeb598f fix: Only enable WalletConnect when valid project ID is configured
- Skip WalletConnect connector if VITE_WALLETCONNECT_PROJECT_ID is not set
- MetaMask and other injected wallets still work without WalletConnect
- Add helpful console warning in dev mode when WalletConnect is disabled
- Prevents 401 errors from WalletConnect API with placeholder project ID

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 21:40:50 +01:00