Commit Graph

232 Commits

Author SHA1 Message Date
Jeff Emmett 1f97a2ceba fix(smtp): use noreply@rmail.online as sender across all modules
Mailcow rejects noreply@rspace.online because the authenticated user
is noreply@rmail.online. Updated all SMTP_FROM and SMTP_USER defaults
to use rmail.online consistently: spaces invites, rSplat notifications,
EncryptID auth emails, and rCart payment receipts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 21:00:41 -07:00
Jeff Emmett 9b81ba70b6 feat(shell): add share button to global header with QR, copy link, email invite
Extract canvas inline share panel into reusable <rstack-share-panel> web component
and add it to the shell header between notification bell and settings gear. Canvas
now uses the component too, removing ~230 lines of inline HTML/CSS/JS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:51:21 -07:00
Jeff Emmett e5814b12c6 fix(rsplat): use fal.ai response_url for result fetch, add poll logging
The result fetch was constructing its own URL instead of using the
response_url returned by fal.ai's status poll. This caused 422 errors.
Now captures response_url from poll and uses it for result retrieval.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:51:05 -07:00
Jeff Emmett 97636235bf fix(spaces): use correct EncryptID internal URL for member operations
The spaces module was defaulting to http://localhost:3000 for EncryptID
API calls, which resolves to the rspace container itself (both run on
port 3000). Changed to http://encryptid:3000 matching server/index.ts.
Also improved error surfacing in /members/add endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:50:13 -07:00
Jeff Emmett d999c98b98 fix(rsplat): resize images with sharp before fal.ai submission
Phone photos (3-4MB, 4000px+) were failing with "Invalid image" on
fal.ai Hunyuan3D. Now resizes to max 1024px JPEG with sharp before
submitting, and uses PUBLIC_ORIGIN HTTPS URL instead of data URI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:36:59 -07:00
Jeff Emmett be81618b70 fix(tabs): prevent closed tabs from reopening via server sync race
Two race conditions caused closed tabs to resurrect:
1. syncTabsFromServer() fetch completing after a local close, merging
   the stale server response back in
2. Debounced PUT killed by page navigation when closing the active tab,
   so the server never learned about the close

Fix: track closed moduleIds per session to skip during merge, and flush
server PUT with keepalive:true before navigation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:30:11 -07:00
Jeff Emmett ad22ed7482 fix(rsplat): send image as data URI to fal.ai, fix http:// URL issue
The publicUrl helper was generating http:// URLs (x-forwarded-proto from
Traefik), causing fal.ai to fail with "Invalid image" 422 errors. Now
reads the staged image from disk and sends as base64 data URI for
reliable delivery. Also bumps poll timeout from 5 to 8 minutes and
surfaces actual fal.ai error messages to the client.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:26:36 -07:00
Jeff Emmett d5d3f09b28 feat(rvnb): add (you)rVnB — community RV & camper rental module
Peer-to-peer RV/camper rentals within community trust networks.
Forked from rBnb with vehicle-specific concepts: specs, mileage
policies, pickup/dropoff locations, and dry humor throughout.

4 seed vehicles, full CRUD API, Leaflet map with pickup/dropoff
markers, rental request flow, endorsement tags including
"suspiciously_clean" and "smells_like_adventure".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 19:26:59 -07:00
Jeff Emmett e0d976ac92 fix(tabs): track active tab correctly on close + long-press reorder
currentModuleId was a const that never updated on client-side tab
switches, causing close to either do nothing or switch to the wrong
tab. Now uses tabBar.active as source of truth and picks the nearest
remaining tab on close. Also adds touch long-press (400ms) drag
reorder for mobile tabs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 17:37:24 -07:00
Jeff Emmett 14c183b992 fix(rsplat): use request Host header for staged image URLs
fal.ai needs to download the staged image. Using hardcoded PUBLIC_ORIGIN
(rspace.online) fails because Cloudflare redirects /data/ paths and the
subdomain (jeff.rspace.online) isn't matched. Now derives the public URL
from the request's Host header. Added logging for staged image URLs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 17:02:10 -07:00
Jeff Emmett 3c1802ab07 fix(rsplat): serve staged images via /api/ path to avoid Cloudflare redirect
Cloudflare/Traefik 301-redirects /data/ paths to data.rspace.online, which
fal.ai can't follow. Staged images now served at /api/files/generated/ which
passes through correctly. Added route alias for backwards compat.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 16:59:25 -07:00
Jeff Emmett e7f0181f70 fix: stop cross-tab active tab fighting + add per-user tab persistence
activeLayerId was being written to the shared Automerge CRDT on every tab
switch, causing all open windows/devices to follow. Now active tab is
local-only. Adds REST API + server-side storage so authenticated users'
tab lists persist across sessions and devices.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 16:40:50 -07:00
Jeff Emmett 6b3fbd36b0 feat(rsplat): gallery thumbnails via model-viewer + fix 3D gen error handling
GLB models now render inline 3D previews using Google's <model-viewer> web
component with auto-rotate. AI-generated models show source image thumbnails.
Fixed fal.ai result fetch with retry logic and detailed logging for diagnosis.
Save flow now uses save-generated API with thumbnail_url passthrough.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 16:22:31 -07:00
Jeff Emmett 7da90088c4 fix(rsplat): fix GLB viewer not rendering on mobile
Defer initThreeViewer to next animation frame so the DOM has laid out
before reading container dimensions. Fall back to viewport size instead
of hardcoded 800x600 when container reports zero dimensions. Add proper
MIME types for GLB/GLTF file serving.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 23:15:24 +00:00
Jeff Emmett 2ea6fee951 feat: add CrowdSurf module — swipe-based community activity coordination
Implements the Crowdsurfing protocol (gospelofchange/Crowdsurfing) as an
rSpace module with full local-first Automerge CRDT sync. Users propose
activities with commitment thresholds, others swipe to join and declare
contributions, and activities trigger when enough people commit.

Module includes schemas, local-first client, swipe UI dashboard with
pointer gesture detection, landing page, seed template data, and
Vite build integration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 23:12:19 +00:00
Jeff Emmett 51da13ac46 feat(rbnb): add community hospitality module — trust-based space sharing
New rSpace module for couch surfing and space sharing within community networks.
Gift economy as first-class option, rNetwork trust graph for auto-accept,
messages embedded in CRDTs, endorsements feed back into trust graph.

- schemas.ts: Listing, StayRequest, Endorsement, AvailabilityWindow, SpaceConfig types
- mod.ts: 18 API endpoints (listings, availability, stays, endorsements, search, stats, config)
- landing.ts: Marketing page with warm amber/red/pink palette
- local-first-client.ts: Automerge sync wrapper (BnbLocalFirstClient)
- components: folk-bnb-view (grid+map), folk-listing (card shape), folk-stay-request (detail)
- bnb.css: Economy badges, status indicators, message thread styles
- Registered in server/index.ts, added r🏠 badge to app switcher under "Sharing"
- 6 demo listings (gift couch, exchange farm, suggested tent, sliding loft, gift hub, fixed cabin)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 16:01:50 -07:00
Jeff Emmett f1de3b654e fix(rsplat): handle formData parse errors in image-stage endpoint
Wrap formData() in try/catch with logging to diagnose Content-Type
issues through Cloudflare tunnel. Also fix client-side error handling
to clear progress timer and show actual error message on failure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 15:53:59 -07:00
Jeff Emmett fd63c2bc6f feat(rsplat): default to image upload + switch job queue to Hunyuan3D
- Default upload tab is now "Generate from Image"
- Entire dotted drop area is clickable to open file browser
- Update process3DGenJob to use Hunyuan3D v2.1 via fal.ai queue API
  (was still using old Trellis endpoint)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 15:48:43 -07:00
Jeff Emmett 84c3c318d8 feat: async 3D gen, calendar reminder widget, cross-module drag, subdomain URL fixes
- Make /api/3d-gen async with job queue + email notification on completion
- Add reminder mini-calendar widget to canvas (top-right on shape select)
- Make items draggable across 6 modules (rNotes, rTasks, rFiles, rSplat, rPhotos, rBooks)
- Upgrade rCal drop handler with time-picker popover instead of confirm()
- Show reminder indicators (dots + badges) on calendar days
- Fix subdomain routing: remove space slug from server-rendered sub-nav,
  tab bar, and module links in production (/{moduleId} not /{space}/{moduleId})
- Add buildSpaceUrl() helper for correct external URL generation
- Fix rcart payment URLs for subdomain routing
- Fix rSchedule email links to use subdomain format

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:18:51 +00:00
Jeff Emmett 55b47901ab fix(rsplat): use fal.ai queue API to avoid timeout on Hunyuan3D
Synchronous fal.run endpoint times out for textured mesh generation.
Switch to queue.fal.run submit/poll/result pattern with 5-minute
deadline. Update client progress phases for longer generation time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 14:46:30 -07:00
Jeff Emmett 26c1e72bb1 feat(rsplat): switch to Hunyuan3D v2.1 for reliable image-to-3D
SAM 3D was designed for object segmentation, not full-scene
reconstruction — failed on arbitrary images. Hunyuan3D v2.1 produces
high-quality textured GLB meshes from any single image reliably.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 14:37:57 -07:00
Jeff Emmett 2813886738 fix(rsplat): use box_prompts to bypass SAM 3D grounding detection
Text prompts require Grounding DINO to detect specific objects, which
fails on arbitrary images. Using a full-image bounding box bypasses
text detection entirely and reconstructs the whole scene as a Gaussian
splat.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 14:30:32 -07:00
Jeff Emmett 67eef28f68 debug(rsplat): add logging for 3d-gen request/response
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 14:15:45 -07:00
Jeff Emmett 66d347091d fix(rsplat): bump detection_threshold to 0.1 (API minimum)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 14:12:57 -07:00
Jeff Emmett 96fd5ef756 fix(rsplat): use concrete object classes for SAM 3D grounding
SAM 3D uses Grounding DINO which needs real noun classes, not abstract
terms. Use broad multi-class prompt with very low threshold (0.05) to
detect objects in any image type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 14:10:32 -07:00
Jeff Emmett 31025c24d7 fix(rsplat): add prompt and detection_threshold for SAM 3D
SAM 3D requires a segmentation prompt — default "car" fails on
non-car images. Use "everything" with low threshold (0.2) to capture
full scenes including people and backgrounds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 14:07:19 -07:00
Jeff Emmett 0f1090db44 feat(rsplat): switch AI generation from Trellis 2 to SAM 3D
SAM 3D outputs native Gaussian splat .ply files (rendered via existing
initSplatViewer) instead of GLB meshes, with full-scene support including
people and backgrounds. Faster generation (5-30s vs 45-75s), $0.02/gen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 14:03:39 -07:00
Jeff Emmett aabc2de7d8 Fix /rtasks/check/:token 404 — bypass module rewriting for checklist routes
The bare-domain and subdomain routing intercepted /rtasks/check/* paths,
rewriting them to /demo/rtasks/check/* which didn't match any route.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:32:00 -07:00
Jeff Emmett 21b1e8fa0a feat(rsplat): image staging endpoint, viewer improvements, SW updates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:24:40 -07:00
Jeff Emmett d0fbbd2ee5 fix(rtasks): mount checklist routes at top level to bypass space auth
The checklist check/send endpoints don't need space context — the HMAC
token and API key provide their own auth. Routes are now:
  GET  /rtasks/check/:token
  POST /api/rtasks/send

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:09:37 -07:00
Jeff Emmett d008b78727 fix(rsplat): save-to-gallery, remove broken media upload, fix leaks
- Add POST /api/splats/save-generated so AI-generated 3D models persist
- Add "Save to Gallery" button in viewer after AI generation
- Remove non-functional "Upload Photos/Video" tab (no processing worker)
- Add 120s server-side timeout on fal.ai Trellis 2 fetch
- Fix GLB viewer memory leak (animation loop + resize listener on disconnect)
- Show elapsed time + phase messages during generation progress
- Bump CSS v3, JS v4 cache versions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 00:56:33 -07:00
Jeff Emmett 8a82223b6f fix: remove deprecated PWA meta tag, add 3D gen timeout, quiet WS errors
Remove apple-mobile-web-app-capable (redundant with manifest.json display),
add AbortController timeout + 524 handling for /api/3d-gen fetch, and
downgrade CommunitySync WS error to console.warn since reconnect is automatic.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 22:23:00 -07:00
Jeff Emmett 9008640f79 perf(rnetwork): optimize 3D graph rendering + fix cross-platform mobile PWA
Graph performance: seed node positions to prevent NaN geometry warnings,
cache sprite textures, reduce simulation ticks (120→50 warmup, 300→150
cooldown), cap particles at 2, lower sphere segments, halve label canvas
size, add sessionStorage graph data cache with 60s TTL.

Mobile PWA: add both mobile-web-app-capable (Chrome/Android) and
apple-mobile-web-app-capable (iOS), viewport-fit=cover for notch support,
apple-mobile-web-app-title, safe-area CSS insets on header/body, fix
admin.html missing all mobile meta tags.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 22:08:22 -07:00
Jeff Emmett 88b20f13f5 feat(rsplat): upgrade to Trellis 2 for higher quality 3D generation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 21:07:45 -07:00
Jeff Emmett e4ea11a91f Merge branch 'dev' 2026-03-15 17:20:38 -07:00
Jeff Emmett 668c239cf3 feat(shell): add "Manage rApps" catalog to app switcher sidebar
Extends <rstack-app-switcher> with an expandable "Manage rApps" panel
at the bottom of the sidebar. Space owners can:
- See all available modules (enabled + disabled) in one place
- Toggle modules on/off with + / − buttons
- Changes persist via PATCH /api/spaces/:slug/modules
- Local toggle fallback for demo mode
- Busy state disables buttons during API calls

Shell changes:
- renderShell() now builds allModulesJSON with `enabled` flags
- Calls setAllModules() on the app switcher alongside setModules()
- Dispatches 'modules-changed' event for shell reactivity

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 17:20:31 -07:00
Jeff Emmett 51fcf93df7 Merge branch 'dev' 2026-03-15 17:04:15 -07:00
Jeff Emmett c5f757d050 fix(rsplat): resize images client-side before 3D generation, pass through fal.ai errors
Mobile photos (12MP+) were causing generation failures due to large base64 payloads.
Now resizes to max 1024px before sending. Server now returns actual fal.ai error
messages instead of generic "3D generation failed".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 16:56:35 -07:00
Jeff Emmett 4b47cc8340 Merge branch 'dev' 2026-03-15 15:52:17 -07:00
Jeff Emmett cab80f30e7 refactor(rnetwork): move Open CRM to sub-nav header
Remove standalone "Open CRM" button from graph view body and add
"Open Twenty CRM" as an external link in the module sub-nav bar,
next to Community CRM. Dashed border + margin-left:auto pushes it
to the right edge for visual distinction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 15:52:10 -07:00
Jeff Emmett 6cd1066e57 Merge branch 'dev' 2026-03-12 22:44:43 -07:00
Jeff Emmett 2532efd6cc fix(shell): align subnav/tabbar directly below tab row (top: 92px)
The subnav and tabbar had top: 128px which left a 36px gap below the
tab row. Changed to 92px (56px header + 36px tab row) and removed
extra margin-bottom. Added sibling rule so tabbar stacks below subnav
when both are present.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:44:36 -07:00
Jeff Emmett 6e5ddaface Merge branch 'dev' 2026-03-12 20:25:40 -07:00
Jeff Emmett aa6f04e45e fix: resolve all 127 TypeScript errors with Hono type augmentation
Add types/hono.d.ts declaring effectiveSpace, spaceRole, and isOwner
on Hono's ContextVariableMap. Remove 127 "as any" casts across 18
files. Fix ParticipantStatus type in rmaps SyncMessage union.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:25:29 -07:00
Jeff Emmett cc9a58b702 Move rforum, rtube, rtrips, rbooks to bottom of app switcher
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 03:08:33 +00:00
Jeff Emmett 9343dc13ab fix(routing): proxy /encryptid/* to encryptid container
The encryptid API routes live on the separate encryptid container, not
rspace. Clients on space subdomains (jeff.rspace.online) fetch
/encryptid/* relative to the rspace server. Add a catch-all proxy that
forwards these requests to the internal encryptid service.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:47:39 -07:00
Jeff Emmett 058592f5e3 fix(rwallet): fix stuck loading, auth, and add Sepolia ERC20 tokens
- Add /encryptid/ to subdomain routing passthrough (was 404 on demo.rspace.online)
- Replace rwallet's custom JWT verify with SDK's verifyEncryptIDToken (supports
  remote fallback when JWT_SECRET unavailable in rspace container)
- Fix CRDT balance loading stuck spinner (early return skipped crdtLoading=false)
- Add Sepolia testnet ERC20 tokens (USDC, WETH, LINK)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:40:02 -07:00
Jeff Emmett 81fb92284b fix(shell): move subnav/tabbar below tab row (top: 128px)
The subnav and tabbar were sticking at top: 92px which overlapped
with the tab row (header 56px + tab row ~36px = 92px). Bumped to
128px so they sit cleanly below the tab row.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:39:24 -07:00
Jeff Emmett 5f63e51a2f fix(shell): responsive subnav and tabbar on mobile
- Tab row: set top: 0 on mobile (was inheriting top: 56px from desktop
  fixed positioning while being sticky on mobile)
- Subnav + tabbar: switch from sticky to relative on mobile so they
  scroll naturally instead of fighting with the sticky header
- Smaller pill padding/font on ≤480px screens

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:00:56 -07:00
Jeff Emmett a8b99d3462 fix(shell): hide subnav bar on rspace canvas page
The rspace module's outputPaths caused renderModuleSubNav to render an
unwanted "rspace | Canvases" bar across the canvas. Skip subnav for the
root rspace module since the canvas has its own chrome.

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