Commit Graph

1184 Commits

Author SHA1 Message Date
Jeff Emmett 07e3c7348c feat(canvas): add Figma-style comment pin system
Overlay markers at canvas or shape-relative coords with threaded
comments, @mention notifications, and rSchedule reminder integration.
Toolbar "Leave Comment" button (/) next to Note tool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 18:47:03 -07:00
Jeff Emmett 2e3007b1df fix(flipbook): ensure 2-page spread display in StPageFlip
Add flex-shrink:0 to flipbook containers to prevent flex layout from
squishing them below pageW*2, which would trigger StPageFlip's
portrait (single-page) mode. Update rpubs page counter to show
spread page range (Pages X–Y of N) for middle pages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 18:35:25 -07:00
Jeff Emmett 9ac8cb6256 fix(flipbook): replicate StPageFlip CSS inside shadow DOM
StPageFlip injects its CSS (.stf__parent, .stf__block, .stf__item, etc.)
into document.head, which doesn't penetrate shadow DOM boundaries.
Pages rendered but were unstyled — collapsed/invisible. Replicate the
required rules inside each component's shadow root styles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 18:27:56 -07:00
Jeff Emmett df8d5f79ce fix(rmeets): align MI route handlers with actual API response shapes
- Search: use POST /search with JSON body (was GET with query params)
- Summary: add summary_text field lookup (API's actual field name)
- Speakers: add speaking_time + speaker_label fallbacks
- Transcript: add speaker_label fallback for segment speaker name
- Action items: add task field lookup (API returns {task, assignee})
- Recordings: detect transcript availability from segment_count
- Add CSS for processing status badges (transcribing, diarizing, etc)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 18:21:55 -07:00
Jeff Emmett cebad27b38 fix(auth): pass JWT secret to all SDK verify calls + add auth header to rpubs generate
evaluateSpaceAccess and authenticateWSUpgrade were calling the SDK
without the secret option, forcing remote verification. Also adds
auth header to rpubs editor generate fetch (was getting 401 on
private spaces).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 18:15:17 -07:00
Jeff Emmett cc1f09b565 feat(rmeets): integrate Meeting Intelligence API for recordings, transcripts, and search
Connect the deployed meeting-intelligence stack to the rmeets module:
- Add MI API proxy helper with 8s timeout and graceful fallback
- Add recordings list page with meeting cards showing status/transcript/summary badges
- Add recording detail page with overview/transcript/summary/speakers tabs
- Add full-text transcript search with highlighted results
- Add client-side MI API proxy route to avoid CORS issues
- Add Recordings and Search nav links to the hub page
- Update landing page: remove "Coming Soon" from transcription + rename section
- Update module export: replace recordings outputPath with custom route, add onboardingActions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 18:00:51 -07:00
Jeff Emmett 999502464f feat(prompt): add canvas tool use via Gemini function calling
folk-prompt can now spawn shapes on the canvas when Tools mode is
enabled. Gemini calls functions (create_map, create_note, create_embed,
create_image, create_bookmark, create_image_gen) and the client
executes them via window.__canvasApi. Multi-turn loop on server (max 5
rounds) with synthetic success responses. Extensible via registerCanvasTool().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 16:42:08 -07:00
Jeff Emmett 7618433498 refactor(auth): replace @encryptid/sdk imports with local auth module
Consolidates token verification into server/auth.ts, removing the
external SDK dependency. All modules now import from the local module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 16:41:59 -07:00
Jeff Emmett 2c0fbb76ac fix(canvas): add auth headers to API fetches + deduplicate sync events
- Add Authorization header to fetchTripData, fetchTripDetail, and
  fetchNotesData to prevent 401 errors on private spaces
- Add #initialSyncFired flag to CommunitySync so the "synced" event
  only fires once per connection cycle instead of on every debounce gap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 16:28:58 -07:00
Jeff Emmett 29c4f48634 feat(identity): store verified email on profile + show in account modal
Email verification wrote to the `email` column but account status read
from `profile_email` — now setUserEmail writes both. Account modal email
section displays the verified address when collapsed. Tour finale step
triggers identity setup on completion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 15:49:09 -07:00
Jeff Emmett 4c1cd21b8c fix(spaces): ensure demo space is always public in access checks
getSpaceConfig() read stored visibility without the demo override,
so the client-side access gate blocked unauthenticated users from
accessing the demo space.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 15:47:00 -07:00
Jeff Emmett 692c75ee5c fix(shell): escape apostrophe in access gate to prevent script parse failure
The single quote in "don't" broke the JS string literal inside the
inline script, causing a SyntaxError that killed the entire script
block including tab bar and header initialization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 15:39:45 -07:00
Jeff Emmett 2de61cd7ad feat(rcal): move zoom/legend below calendar, add multi-day event spans
- Reorder layout: nav → calendar → legend → zoom bars → bottom bar
- Add "Calendar Legend" heading above source badges
- Fix getEventsForDate() to support multi-day range checking
- Render colored span bars across day cells for multi-day events
- Make showAccountModal/isSignedIn public on rstack-identity
- Tour final step triggers identity setup flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 15:10:39 -07:00
Jeff Emmett 33a0f9ab04 chore(secrets): remove redundant env passthrough from docker-compose
Secrets now fetched from Infisical at container startup instead of
being passed through docker-compose from .env. Reduces .env to only
Infisical auth creds and non-Infisical container secrets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:48:20 -07:00
Jeff Emmett 4383cffb9d fix(canvas): prevent shape re-seeding after user clears canvas
Added shapesSeeded flag to community doc metadata. Once shapes are
seeded (demo, template, or campaign), deleting all shapes no longer
triggers re-seeding on server restart. The demo reset endpoint clears
the flag so it can re-seed intentionally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:40:28 -07:00
Jeff Emmett 466a0305fd fix(spaces): dedup space switcher + restructure into sections
Personal space rename only applies when isPersonal flag is set (not all
private spaces). Demo forced to public visibility. Public spaces no
longer filtered out. Sections: Private → Permissioned → Public →
✦ Discover → Create.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:35:07 -07:00
Jeff Emmett ac402c29e9 feat(canvas): replace repulsion with snap guides + drop suggestion
Remove ambient repulsion loop (shapes drifting apart at 60fps). Add
Figma-style snap alignment guides during drag with magnetic stickiness,
and ghost drop suggestion when shapes overlap after drop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:28:32 -07:00
Jeff Emmett 4b08a02851 fix(seed): prevent demo data re-seeding after user deletes content
Added a `seeded` flag to Automerge doc metadata across 6 modules
(rcal, rnotes, rtasks, rvote, rbnb, rvnb). Once demo data is seeded,
deleting all content no longer triggers re-seeding on next page load.

Also removed rcal's per-request seedDemoIfEmpty() call from the route
handler — onInit + seedTemplate already handle initial seeding.

fix(canvas): prevent bulk delete dialog from stacking

The Delete key repeat was creating multiple overlays, making the dialog
appear unclosable. Added a guard to prevent duplicate dialogs, and
Escape key support to dismiss.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:24:51 -07:00
Jeff Emmett eb470dff18 fix(auth): use client-side access gate for private spaces
Server-side HTML gates can't work because auth tokens are in
localStorage, not cookies. Replaced with:
- Client-side gate checks session, then verifies membership via
  new /api/space-access/:slug endpoint
- Shows "Sign In" for unauthenticated users
- Shows "no access + return to your space" for non-members
- Server-side gates remain for API/JSON requests and WebSocket

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:03:28 -07:00
Jeff Emmett fe7157ffe1 fix(shell): position settings/history panels below their buttons
Both panels now use position:fixed with JS-computed coordinates from
getBoundingClientRect(), ensuring they open directly below their
respective header buttons and right-aligned to the button edge.
History panel clamps left edge to prevent off-screen overflow.

Also adds missing click handlers for settings-btn and history-btn
in canvas.html (previously only wired in shell.ts module pages).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:59:44 -07:00
Jeff Emmett 7d4e6122f1 feat(auth): enforce space access control for private spaces
Non-members of private spaces are now blocked at three layers:
- WebSocket upgrade rejects with 403
- Module middleware shows access denied page (browser) or JSON 403 (API)
- Space root dashboard shows access denied page
Friendly "Private Space" page with link back to user's own space.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:49:50 -07:00
Jeff Emmett 8eb2738b65 refactor(shell): move history & settings icons next to space switcher
Both dropdown-wrap buttons now sit in header-left directly after the
space switcher, keeping space-related controls grouped together.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:29:39 -07:00
Jeff Emmett 4f9e29e5e7 fix(canvas): persist deletions immediately to prevent resurrection
Destructive operations (forget, delete, remember) now flush to
IndexedDB + localStorage immediately instead of using 2s debounce,
preventing deleted items from reappearing on page reload.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:29:33 -07:00
Jeff Emmett e0f0426e59 fix(canvas): limit separation dynamics to rApps/embeds, not drawings/slides
- Add folk-shape to pushExemptTags so wb drawings (pencil, rect, circle,
  line) are exempt from repulsion and can overlap other shapes freely
- Skip wb-drawing elements in repulsion loop and free-position placement
- Locked shapes are not pushed by repulsion (full push goes to unlocked neighbor)
- getExistingShapeRects uses pushExemptTags instead of hardcoded arrow check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:25:27 -07:00
Jeff Emmett 842ac4d67e feat(canvas): eraser works on all shapes, add lock icon for shapes
- Eraser now targets any folk-shape (not just wb-drawing), erasing whatever it touches
- Added lock property to folk-shape: locked shapes can't be moved, resized, or erased
- Lock state persisted via Automerge sync (toJSON/applyData/fromData)
- Lock icon appears beside calendar icon when shape(s) selected, toggles lock on click

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:19:54 -07:00
Jeff Emmett 0d8d42c49e fix(rcal): distinguish pinch-zoom from scroll-pan on calendar
Trackpad pinch (ctrlKey wheel) zooms granularity, two-finger scroll
navigates the timeline forward/backward instead of zooming.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 12:44:45 -07:00
Jeff Emmett 0fbf12e5f8 fix(routing): serve rspace.online/{moduleId} as app in shell instead of landing page
rspace.online/rcal was redirecting to rcal.online (standalone domain) via
the landing page proxy. Now rewrites to /demo/{moduleId} so it loads the
actual app within the rSpace shell with app/space switchers, matching the
behavior of {space}.rspace.online/{moduleId}.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 11:24:39 -07:00
Jeff Emmett 63c1b7c1e7 refactor(shell): convert settings & history panels to dropdown menus
Replace full-height slide-in panels with compact dropdowns that appear
beneath header icons. Both icons now grouped in header-right with
mutual exclusion and click-outside-to-close behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 23:17:17 -07:00
Jeff Emmett 6f066f649a fix(server): block disabled modules on subdomain routes
Ensure disabled modules redirect to space root on subdomain routing,
and pre-load community doc before checking enabled modules list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 23:17:11 -07:00
Jeff Emmett e56b4fe89c fix(canvas): hide feed toggle on mobile corner tools
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 22:31:58 -07:00
Jeff Emmett 9b0a672c7b feat(canvas): add Ctrl+Z undo / Ctrl+Shift+Z redo for shape operations
Local inverse-change stack that records before-snapshots of each mutation
and applies forward Automerge changes to restore state on undo. Batches
rapid same-shape changes (<500ms) so drags produce a single undo entry.
Supports create, move/resize, forget, remember, and hard-delete operations.
Max 50 entries, redo stack clears on new changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 22:31:22 -07:00
Jeff Emmett 6491681e3e fix(auth): force platform authenticator + redirect disabled modules
Force authenticatorAttachment: 'platform' across all WebAuthn registration
flows to prevent USB security key prompts. Redirect browser navigations to
space root when accessing disabled modules instead of returning JSON error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 22:31:13 -07:00
Jeff Emmett 15f7e759d1 fix(canvas): map shape interaction + reminder widget dismissal
Map viewer: disable MapLibre interactions when inside a folk-shape
until editing mode (double-click). Prevents map panning when trying
to select/move the shape on canvas.

Reminder widget: dismiss on Escape key and when clicking elsewhere
on canvas (deselecting shapes). Clean up schedule icon when shape
is deleted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 20:44:28 -07:00
Jeff Emmett d5e822ec7c fix(canvas): remove duplicate settings/history button handlers
Canvas.html had its own addEventListener calls for settings-btn and
history-btn, but the shell script already wires these. Both handlers
fired on click, causing double-toggle (open then immediately close).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 20:39:32 -07:00
Jeff Emmett 355b53ee17 fix(canvas): hide toolbar items for disabled modules
Inject enabledModules into client, tag 25 module-specific toolbar buttons
with data-requires-module, and filter out disabled items (plus empty groups)
at page init. Spaces with all modules enabled are unaffected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 20:36:10 -07:00
Jeff Emmett fcf4202045 fix(rmaps): remove max-height cap so map fills available space
Map container was capped at 700px, leaving blank space on most screens.
Removed the cap so calc(100vh - 220px) fills properly. Also matched
sidebar max-height to viewport.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 19:26:18 -07:00
Jeff Emmett 8b61203e17 revert: remove standalone domains we don't own
Reverts Traefik rules and removes standaloneDomain from rdesign, rvnb,
rbnb, rdocs, and crowdsurf — we don't have these domains.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:31:17 -07:00
Jeff Emmett d315375a93 fix(routing): add missing Traefik rules for 5 standalone domains
rdesign.online, rvnb.online, rbnb.online, rdocs.online, crowdsurf.online
had standaloneDomain declared in their modules but no Traefik router rules,
so {space}.r*.online subdomain redirects wouldn't reach the server.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:27:11 -07:00
Jeff Emmett ee1a791aea fix(canvas): move offline status to people badge, toolbar minimize to bottom, zoom to bottom-right
- Offline/reconnecting indicator now shows inside the "N online" people
  badge instead of the shell header (hidden on canvas via CSS override)
- Toolbar collapse/minimize button moved from top to bottom of toolbar
  stack so it sits where the last tool icon was
- Zoom controls moved from bottom-left to bottom-right; on mobile they
  sit above the bottom toolbar to avoid overlap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:22:39 -07:00
Jeff Emmett dbe60f2711 fix(onboarding): remove moduleHasData gate so live spaces show module UI
Live spaces with no CRDT data were showing a generic onboarding page
instead of the module's actual UI. Demo always bypassed this check,
causing visual parity issues between demo.rspace.online and live spaces.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:22:11 -07:00
Jeff Emmett 36e76449fa fix(canvas): prevent horizontal overflow on mobile
- Add overflow:hidden on html element for canvas-layout pages
- Bottom toolbar: constrain to viewport with right:8px, horizontal
  scroll for overflow buttons, flex-shrink:0 on items
- Context menu: clamp position to viewport bounds
- Modal panels: use min() for min-width to respect small screens

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:17:27 -07:00
Jeff Emmett 823d2c4110 fix(spaces): filter disabled modules from space dashboard
renderSpaceDashboard was showing all modules regardless of space's
enabledModules setting — both in the app cards grid and the app-switcher
dropdown. Now filters using getSpaceShellMeta, same as renderShell.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:11:51 -07:00
Jeff Emmett cc504d4a86 fix(spaces): make DID resolve endpoint public (no auth needed for profile data)
The resolve-dids endpoint was returning 401 because unsigned fallback tokens
fail HS256 verification. Since username/displayName is public profile data,
remove auth requirement from the endpoint and client call.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:06:36 -07:00
Jeff Emmett 21236ccd15 Merge branch 'dev' 2026-03-21 17:28:13 -07:00
Jeff Emmett 524356d233 feat(tours+solo): add tours to remaining modules and solo mode toggle
Add guided tours to 6 modules that were missing them:
- Shadow DOM: rsocials dashboard, crowdsurf, rdata (TourEngine)
- Light DOM: rsplat, rbnb, rvnb (new LightTourEngine class)

Add solo mode toggle to collab overlay — click the presence badge
to hide your cursor/presence from others. Persists via localStorage,
dispatches event to canvas PresenceManager.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 17:26:57 -07:00
Jeff Emmett 544e557981 fix(theme): use CSS variables for dark mode across all canvas shapes
Replace hardcoded light-mode colors (#f8fafc, #e2e8f0, white, #1e293b, etc.)
with theme-aware CSS custom properties (--rs-bg-surface, --rs-text-primary,
--rs-border, etc.) in 24 shape files. Adds color inheritance to folk-shape
base class so all shapes get correct text color in both dark and light mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 17:26:35 -07:00
Jeff Emmett e933e6238b Merge branch 'dev' 2026-03-21 17:20:48 -07:00
Jeff Emmett f08b72268b fix(spaces): filter disabled modules from both rApp dropdowns
renderExternalAppShell was passing the full unfiltered module list to
both the app-switcher and tab-bar dropdowns. Now filters by the space's
enabledModules, matching the existing renderShell behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 17:20:40 -07:00
Jeff Emmett 9859b31912 Merge branch 'dev' 2026-03-21 17:04:31 -07:00
Jeff Emmett 2ab620fcc5 feat(rpubs): polish publish flow with teal accents, SVG icons, and card layouts
Visual overhaul of the rpubs editor and publish panel to match rpubs.online/press
design language: circular step indicators with checkmarks, SVG stroke icons on all
buttons, card-based publish panel with teal accent colors, pricing tier cards,
numbered DIY guide steps, group buy progress bar, and format info chips.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 17:04:19 -07:00